/* THE ?v= ON THE STYLESHEET LINK. Every page asks for /styles.css?v=<hash>,
   not /styles.css, and the hash is the first 8 characters of this file's md5.
   Without it a visitor gets today's HTML with a stylesheet up to four hours
   old: the server sends max-age=3600 and Cloudflare holds it for 14400. On
   23 October 2026 that shipped a /pricing page whose markup was new and whose
   stylesheet had none of the pricing rules in it, so it rendered unstyled for
   everyone, not only for people who had visited before.

   AFTER ANY CHANGE TO THIS FILE the hash must be restamped, or the change
   reaches nobody until the cache expires. The command is in LAUNCH.md under
   "Restamping the stylesheet". NOTHING CHECKS THIS AUTOMATICALLY: making
   `npm test` fail on a stale stamp is four lines in check.mjs, which is
   James's file, and is asked for in issue #38.

   The proper fix is one line in server.mjs and belongs to James
   (Gttr-uk/altoguru-website issue #38). This works without touching it. */
/* ==========================================================================
   Alto Guru website: design tokens and system styles.

   PORTED 29 September 2026 from the unreleased Alto Australia website
   (Alto-Maths-Progress, artifacts/alto-website, public/styles.css), at
   Esther's direction. That file carries the reasoning behind each decision at
   length; this one carries the decisions and the two rules that govern them,
   so a change here does not quietly undo one.

   TWO RULES, and they are the point of the palette:

     1. CORAL APPEARS ON THINGS YOU CAN CLICK, AND NOWHERE ELSE. Decorative
        rules and card edges are aqua or the warm rule colour. A page with
        eight coral marks and one coral button has no primary action. The
        placeholder broke this: its one "live" card had a coral edge while
        nothing clickable on the page was coral at all.

     2. AQUA IS NEVER TEXT AND NEVER A BUTTON GROUND. It is too pale. Anything
        that has to be read in aqua uses the deep aqua.

   Contrast, measured against the real page background rather than pure white,
   carried over from the Australian file:

     logo aqua     #4FC9DA on cream     1.82:1   large fields only, never text
     ink on aqua   #211F1C on aqua      8.38:1   so dark text on an aqua band
     deep aqua     #0E7284 on cream     5.18:1   passes AA
     action coral  white on #CB4728     4.70:1   passes AA
     brand coral   white on #F06445     3.18:1   fails, hence two coral tokens
     ink           #211F1C on cream    15.5:1
     ink secondary #5A554D on cream     6.85:1   passes AA

   NO DARK MODE, and that is a change from the placeholder, which had one.
   Every ratio above is measured against cream. A dark scheme needs its own
   measured values, and inventing them here would break the discipline this
   file exists to keep. Recorded in PENDING.md. Ask, and it can be measured
   properly rather than guessed.

   NOTHING IS DOWNLOADED. No font CDN, no third-party stylesheet, nothing from
   another site. That is a house rule here and it was a requirement there too,
   because these pages are reachable from a child's device.
   ========================================================================== */

:root {
  /* -- Colour roles ----------------------------------------------------- */
  --aqua: #4fc9da;            /* the logo aqua. Large fields only, never text */
  --aqua-deep: #0e7284;       /* text, links, focus. Passes AA on cream */
  --aqua-deep-hover: #0b5c6a;
  --aqua-soft: #9fe1eb;
  --aqua-wash: #e8f7fa;
  --aqua-hint: #eef8fa;       /* the washed band that opens every page */

  --coral: #f06445;           /* brand coral: large elements only */
  --coral-action: #eb5636;    /* a call to action at 19px and weight 700 */
  --coral-action-small: #cb4728; /* a small coral control, where AA needs 4.5:1 */
  --coral-wash: #fdf0ec;

  --ink: #211f1c;
  --ink-secondary: #5a554d;
  --ink-tertiary: #77716a;

  --cream: #faf9f6;
  --surface: #ffffff;
  --surface-sunken: #f4f2ee;

  --rule: #e3ded4;
  --rule-strong: #cfc8ba;
  /* A warmer, heavier line than a hairline grey. A 1px hairline around every
     rounded card is the most recognisable default in generated design, because
     it is what every component library ships with. A heavier warm line reads
     as drawn rather than defaulted, and it costs no restraint. */
  --rule-brand: #dad3c3;
  --border-card: 2px;

  /* The four nation colours, matched to GTTR so a teacher who has seen the race
     map recognises this one (Esther, 29 September 2026). The soft tint fills the
     country; the full colour fills the label pill, with white text on it. */
  --nation-england: #3b7ca6;            --nation-england-soft: #bde3f7;
  --nation-scotland: #7c3aed;           --nation-scotland-soft: #dcd3fc;
  --nation-wales: #1d7a4a;              --nation-wales-soft: #b5ecc9;
  --nation-northern-ireland: #a84a6b;   --nation-northern-ireland-soft: #f3d6e1;
  /* A mid tone for the selected country's shape, and a dark one for the edge of
     the selected panel. A highlighted nation deepens in its own colour; it never
     borrows the site's aqua (Esther, 29 September 2026). */
  --nation-england-mid: #96cdec;        --nation-england-dark: #2b5d7d;
  --nation-scotland-mid: #c3b4f8;       --nation-scotland-dark: #5b28b0;
  --nation-wales-mid: #8fdfaf;          --nation-wales-dark: #135935;
  --nation-northern-ireland-mid: #e9bccd; --nation-northern-ireland-dark: #7e364f;

  /* A dark blue for navigation and the call to action (Esther, 29 September
     2026). It tones with the deep aqua and with England's blue on the map
     without being either. 6.5:1 on the washed aqua band, and white on it is
     6.5:1, so it carries text either way round. */
  --ink-blue: #2b5d7d;
  --ink-blue-deep: #1f4a63;

  /* THE SUBJECT COLOURS. One per subject, used on the subject's card edge and
     on its sample question, and meant to hold across the site and the app
     (Esther, 30 September 2026).

     Anchored on the logo, which is multi-coloured precisely because Alto is
     multi-subject. Its aqua goes to MATHS, because maths is the hero product
     and aqua is Alto's own colour (Esther, 30 September 2026). Its lime goes to
     times tables, the subject schools actually meet first through the Race. The
     rest extend that family: number facts takes a blue beside them, the two
     literacy subjects take warm tones so they read as a pair against the maths
     ones, and French takes a green.

     Coral is not among them, because coral is reserved for things you can click
     and a subject is not one. The maths aqua is deliberately brighter than the
     link colour so a card edge does not read as a link.

     Each is a pair: the deeper value carries the card edge and any text, the
     soft one fills the sample box. Ink on every soft fill, which is legible on
     all of them, so no subject needs its own text colour. */
  --subject-maths: #0e9ab0;       --subject-maths-soft: #d8f1f6;
  --subject-tables: #6b8f00;      --subject-tables-soft: #ecf5cc;
  --subject-facts: #2f6fb0;       --subject-facts-soft: #dcebf8;
  --subject-facts2: #1b3f73;      --subject-facts2-soft: #d3dcea;
  --subject-mentals: #6b4fc9;     --subject-mentals-soft: #e5e0fa;
  --subject-spelling: #c06a10;    --subject-spelling-soft: #fbead3;
  --subject-grammar: #b04a63;     --subject-grammar-soft: #fadfe6;
  --subject-french: #1d8a68;      --subject-french-soft: #d8f0e6;

  --gold: #f2b705;            /* the pre-launch marks only, below */
  --focus: var(--aqua-deep);

  /* -- Typography ------------------------------------------------------- */
  --font-body: Inter, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  /* HEADINGS ARE A SERIF. A serif heading over a sans body is the oldest
     editorial pairing there is: it makes a page easier to scan because the two
     levels stop looking alike, and on a product sold to schools it reads as a
     publisher rather than a startup. Inter for absolutely everything is the
     strongest tell that nobody chose anything.
     System faces only. Iowan Old Style and Charter cover macOS and iOS,
     Palatino Linotype and Book Antiqua cover Windows, Georgia covers
     everything else. To revert, set this to var(--font-body); nothing else on
     the site changes, which is what this token is for. */
  --font-heading: 'Iowan Old Style', Charter, 'Palatino Linotype', 'Book Antiqua', Georgia, serif;

  --text-h1: clamp(2rem, 1.4rem + 2.2vw, 2.75rem);
  --text-h2: clamp(1.5rem, 1.2rem + 1.1vw, 1.9rem);
  --text-body-lg: 1.1875rem;
  --text-body: 1.0625rem;     /* 17px */
  --text-small: 0.9375rem;
  --text-caption: 0.8125rem;
  --text-micro: 0.6875rem;    /* the trial's card-details line, and nothing larger */

  --measure: 34rem;           /* roughly 70 characters at the body size */
  /* THE FRAME. Nav, content and footer all use this, so their left edges line
     up on a wide screen instead of stepping in and out. Prose inside a card is
     capped at --measure separately, because 46rem of 17px text is about 95
     characters a line, which is too wide to read comfortably. */
  --measure-wide: 46rem;

  /* -- Space ------------------------------------------------------------ */
  --s2: 0.5rem;
  --s3: 0.75rem;
  --s4: 1rem;
  --s5: 1.5rem;
  --s6: 2rem;
  --s7: 3rem;
  --gutter: clamp(1.25rem, 0.75rem + 2vw, 2.5rem);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  padding: 0 0 var(--s7);
}

h1, h2, h3 {
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: -0.01em;
}

a { color: var(--aqua-deep); text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { color: var(--aqua-deep-hover); }
a:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 3px; }

/* ---------------------------------------------------------------------------
   The navigation. A washed aqua band, so the first thing on every page is
   Alto's colour and the reading field below it stays quiet. The Alto logo sits
   top left (Esther, 29 September 2026).
   ------------------------------------------------------------------------- */

.nav {
  background: var(--aqua-hint);
  border-bottom: 1px solid var(--rule);
  padding: var(--s4) var(--gutter);
  margin-bottom: var(--s6);
}
/* The logo sits over at the left on every page (Esther, 22 October 2026). The
   bar was capped at --measure-wide, the reading measure, which lined it up
   with the older .page shell and left it well inside the page on everything
   else: on a 1440px screen the logo started at 352px while /schools and its
   two pathway pages began at 144px and the home page's hero at 48px.

   84rem is the widest thing on the site, the home page's hero band
   (calc(50vw - 42rem) is the same cap said the other way round). Matching it
   puts the logo level with the hero and to the left of every other shell, so
   it is the leftmost thing on the page wherever you are, and it still stops
   short of sprawling across a very wide monitor. */
.nav__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s3) var(--s5);
  width: 100%;
  max-width: 84rem;
  margin: 0 auto;
}
/* The logo alone, with no wordmark beside it (Esther, 29 September 2026). Its
   alt text still reads "Alto Guru", so the name is not lost to a screen reader
   or to a reader with images off. */
.nav .brand { display: inline-flex; align-items: center; text-decoration: none; }
.nav .brand img { height: 32px; width: auto; }
.nav ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s5);
  /* Esther, 29 September 2026: the links sit to the right, not beside the
     wordmark, with the call to action beyond them. */
  margin: 0 0 0 auto;
  padding: 0;
}

/* The one call to action on the site. It is small, so it takes the small coral
   rather than the bright one: white on #eb5636 is 3.55:1, which is fine at 19px
   bold and not fine here. See the note on the coral tokens above. */

/* On a phone the brand and the call to action share the first row and the four
   links take their own below it, so the action is never pushed out of sight.
   The tighter gap is what lets four links sit on one row at 375px rather than
   two, which takes a whole row off the bar. There is no menu button, because a
   menu button needs script and this site runs none. */
@media (max-width: 40rem) {
  .nav { padding: var(--s3) var(--gutter); margin-bottom: var(--s5); }
  .nav__inner { gap: var(--s2) var(--s4); }
  .nav .brand { font-size: 1.1rem; }
  .nav .brand img { height: 28px; }
  .nav .nav__actions { order: 2; margin-left: auto; gap: var(--s3); }
  .nav a.btn--primary { padding: 0.35rem 0.8rem; }
  /* One action on the phone bar, not two: Get Started is the one that
     matters, and signing in is a tap away inside it. */
  .nav a.nav__signin { display: none; }
  .nav ul { order: 3; flex-basis: 100%; margin-left: 0; gap: var(--s2) var(--s3); }
  .nav a { font-size: 0.9rem; }
}
.nav a { color: var(--ink-blue); text-decoration: none; font-size: var(--text-small); font-weight: 700; }
.nav a:hover { color: var(--ink-blue-deep); text-decoration: underline; }
/* The page you are on is marked for everyone, not only for a screen reader. */
/* The page you are on, marked by weight and a rule rather than by a second
   colour, since every link is already bold. */
.nav a[aria-current="page"] { color: var(--ink-blue-deep); text-decoration: underline; text-underline-offset: 0.35em; }

/* --- page shells ---------------------------------------------------------- */

.home {
  max-width: calc(var(--measure) + 2 * var(--gutter));
  margin: 0 auto;
  padding: 0 var(--gutter);
  text-align: center;
}
.page {
  max-width: calc(var(--measure-wide) + 2 * var(--gutter));
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.mast { display: flex; flex-direction: column; align-items: center; gap: var(--s2); }
.mast .logo { height: 56px; width: auto; }
.name {
  margin: 0;
  font-family: var(--font-heading);
  font-size: clamp(2.4rem, 10vw, 3.4rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.05;
}
.guru { height: 150px; width: auto; margin-top: var(--s3); }

.home h1 { font-size: var(--text-body-lg); font-weight: 600; margin: var(--s5) 0 0; }
.page h1 { font-size: var(--text-h1); margin: 0 0 var(--s3); line-height: 1.15; }
.page h2 { font-size: var(--text-h2); }

.eyebrow {
  margin: 0 0 var(--s2);
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-tertiary);
}
.lead {
  font-size: var(--text-body-lg);
  color: var(--ink-secondary);
  margin: 0 0 var(--s5);
  max-width: var(--measure);
}
.crumb { margin: 0 0 var(--s3); font-size: var(--text-small); }

/* A state label. Grey, because a thing that is not running is not a call to
   action and must not wear the action colour. */
.page .soon { margin: 0 0 var(--s5); }

/* The words, then the photograph under them. */
.hero { margin: 0 0 var(--s5); }
.hero .lead { margin-bottom: 0; }

/* The hero puts the words and the photograph side by side, each about half the
   screen, once there is room for both (Esther, 30 September 2026). It has to
   break out of .page to do that: "half the screen" means the screen, not the
   46rem column the prose is capped at. Below 62rem the headline starts
   breaking to four lines against a shrinking photograph, so under that it
   stays a single column with the photograph underneath. */
.hero-band { margin: 0 0 var(--s6); }

@media (min-width: 62rem) {
  .hero-band {
    /* Out to the full window, then back in on its own padding, which also
       caps the pair at 84rem so it does not sprawl on a very wide monitor. */
    margin-inline: calc(50% - 50vw);
    padding-inline: max(var(--gutter), calc(50vw - 42rem));
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: var(--s6);
  }
  /* The eyebrow runs above both columns, so the headline and the top of the
     photograph start on the same line (Esther, 30 September 2026). */
  .hero-band .eyebrow { grid-column: 1 / -1; }
  /* The photograph keeps its full half-screen width, so it is the photograph
     that sets how tall the row is. The words then spread to match it: headline
     at the top, on the same line as the top of the photograph, paragraph at the
     foot, on the same line as its bottom edge, and the extra air falls between
     the two rather than above or below them (Esther, 30 September 2026). */
  .hero-band .hero {
    grid-column: 1;
    margin: 0;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }
  .hero-band .hero-shot { grid-column: 2; margin: 0; }
    /* The claims run under both columns, below the button, as they do on
       /schools (Esther, 23 October 2026). */
    .hero-band .pills--spread { grid-column: 1 / -1; margin-top: var(--s5); }
  /* The photograph fills its half of the row, so it finishes level with the
     words instead of leaving a gap beneath itself. It was a letterbox file at
     2.10:1, which came out 100px short of the words at a 1440px window
     (Esther, 12 October 2026). The file is now the full uncropped frame and
     the crop happens here, so it matches the words at every width rather than
     at one. figure is a stretched grid item, so 100% is a real height. */
  .hero-band .hero-shot img { height: 100%; object-fit: cover; }
}

/* width and height are on the tag so the browser reserves the space before the
   file arrives and the page does not jump. */
.hero-shot { margin: 0 0 var(--s6); }
.hero-shot img { display: block; width: 100%; height: auto; border-radius: 14px; }

/* --- cards ---------------------------------------------------------------- */

.card {
  background: var(--surface);
  border: var(--border-card) solid var(--rule-brand);
  border-radius: 14px;
  padding: var(--s5);
  margin: 0 0 var(--s4);
}
/* A sample question, tilted over the card's top right corner (Esther,
   30 September 2026). Absolute and rotated once there is room; upright and
   above the heading on a phone, where a box hanging off the corner lands on the
   heading rather than beside it. */
.card { position: relative; }
.sample {
  background: var(--aqua-wash);
  border: 2px solid var(--aqua-soft);
  border-radius: 12px;
  /* Everything inside is sized in em off this, so the box, its text and its
     padding all came down 15% together (Esther, 30 September 2026). */
  font-size: 0.85rem;
  padding: 0.75em 1em;
  text-align: center;
}
/* The questions centre as a block, but keep their own alignment inside it, so
   the maths equals signs stay under each other. */
.sample__qs { display: inline-block; text-align: left; }
.sample__label {
  /* A fifth less air under the label (Esther, 30 September 2026). Most of that
     space was the label's own leading rather than the margin, so the line
     height does the work. */
  margin: 0 0 0.2em;
  line-height: 1.35;
  font-size: 0.8125em;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-tertiary);
}
/* Stacked fractions in the sample questions. The rule sits close under the
   numerator by default at this size, so it gets a little air. */
.sample__q math { font-size: 1em; }
.sample__q mfrac { padding: 0 0.06em; }

.card .sample__q {
  margin: 0;
  font-size: 1.1875em;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  max-width: none;
}
.card .sample__q + .sample__q { margin-top: 0.15em; }
/* A display-style fraction stands taller than its own line box, so the two
   maths lines were overlapping. Margin between them does not fix that; the line
   box has to be tall enough to hold the fraction in the first place. */
.subject--maths .sample__q { line-height: 2.6; }
.subject--maths .sample__q + .sample__q { margin-top: 0.2em; }
@media (min-width: 40rem) {
  .sample {
    position: absolute;
    /* Rotated 35deg, which is 45 less the 10 Esther asked for: the FOR EXAMPLE
       end drops as the angle comes DOWN, not up.
       top:0 right:0 puts the box's own top right corner on the card's, which
       leaves the whole box inside. The shift then slides it out along the
       diagonal, but only a little: the card's corner clears the diamond's edge
       only while the diamond's centre stays about 45px inside the corner, and
       past that the corner disappears under it (Esther, 30 September 2026:
       move in so the corner pokes out). */
    top: 0;
    right: 0;
    transform: translate(10%, -10%) rotate(30deg);
    transform-origin: center;
    box-shadow: 0 2px 10px rgb(33 31 28 / 0.08);
  }
  /* so a long heading can never run under it */
  .subject h2 { padding-right: 11rem; }
  /* room above each subject card for the diamond hanging off its corner, so it
     never touches the card above */
  /* The diamond hangs about 40px above its own card, so this is that plus air. */
  .subject + .subject, .card + .subject { margin-top: 4rem; }
}
@media (max-width: 39.999rem) {
  .sample { display: inline-block; margin: 0 0 var(--s4); text-align: left; }
}

/* Each subject's own colour, on its card edge and its sample box. */
.subject--tables { border-color: var(--subject-tables); }
.subject--tables .sample { background: var(--subject-tables-soft); border-color: var(--subject-tables); }
.subject--facts { border-color: var(--subject-facts); }
.subject--facts .sample { background: var(--subject-facts-soft); border-color: var(--subject-facts); }
.subject--maths { border-color: var(--subject-maths); }
.subject--maths .sample { background: var(--subject-maths-soft); border-color: var(--subject-maths); }
/* The two maths lines are different lengths, so ranging them right lines the
   equals signs up under each other. The others stay left (Esther, 30 September
   2026: keep the spelling as it is). */
.subject--maths .sample__qs { text-align: right; }
.subject--spelling { border-color: var(--subject-spelling); }
.subject--spelling .sample { background: var(--subject-spelling-soft); border-color: var(--subject-spelling); }
/* Spelling and grammar ask a question in a sentence rather than setting a sum,
   so they need a width to wrap inside and a little less weight than the bare
   sums, which stay bold. */
.subject--spelling .sample,
.subject--grammar .sample { max-width: 8rem; }
.subject--spelling .sample__q,
.subject--grammar .sample__q { font-weight: 500; font-size: 1em; line-height: 1.4; }
.sample__audio { vertical-align: -0.12em; margin-right: 0.15em; opacity: 0.75; }

.subject--grammar { border-color: var(--subject-grammar); }
.subject--grammar .sample { background: var(--subject-grammar-soft); border-color: var(--subject-grammar); }

/* A card about something that is actually running. RULE 1: the accent is aqua,
   not coral. Coral is for things you can click. */
.card.live-card { border-color: var(--aqua); }
.card h2 { font-size: var(--text-body-lg); margin: 0 0 var(--s3); }
.card p { margin: 0 0 var(--s3); color: var(--ink-secondary); max-width: var(--measure); }
.card p:last-child { margin-bottom: 0; }
.card strong { color: var(--ink); }

/* A person's role, under their name on the About page. */
.role {
  margin: -0.4rem 0 var(--s3);
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--ink-blue);
}

.facts { margin: 0; display: grid; grid-template-columns: minmax(7rem, 11rem) 1fr; gap: var(--s2) var(--s4); }
.facts dt { font-weight: 600; color: var(--ink); font-size: var(--text-small); }
.facts dd { margin: 0; color: var(--ink-secondary); }
@media (max-width: 40rem) {
  .facts { grid-template-columns: 1fr; gap: 0.1rem; }
  .facts dd { margin-bottom: var(--s2); }
}

/* Where a fact came from. Every curriculum claim on this site carries one. */
.source {
  margin: var(--s4) 0 0;
  font-size: var(--text-caption);
  color: var(--ink-tertiary);
  line-height: 1.5;
}

.ask { color: var(--ink-secondary); max-width: var(--measure); }
.steps { margin: 0 0 var(--s3); padding-left: var(--s5); color: var(--ink-secondary); max-width: var(--measure); }
.steps li { margin-bottom: var(--s2); }
.steps strong { color: var(--ink); }
.plain { margin: 0 0 var(--s3); padding-left: var(--s4); color: var(--ink-secondary); }
.plain li { margin-bottom: 0.35rem; }

/* --- the subjects list on the home page ----------------------------------- */

.subjects { margin-top: var(--s6); text-align: left; }
.subjects h2 {
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-tertiary);
  margin: 0 0 var(--s3);
}
.subjects ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); }
.subjects li {
  background: var(--surface);
  border: var(--border-card) solid var(--rule-brand);
  border-radius: 14px;
}
.subjects li:not(.live) {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--s4);
  padding: var(--s3) var(--s4);
}
.subjects li.live { border-color: var(--aqua); }
.subjects li.live a {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--s4);
  padding: var(--s3) var(--s4);
  color: inherit;
  text-decoration: none;
  border-radius: 12px;
}
.subjects li.live a:hover .note { text-decoration: underline; }
.subject { font-weight: 600; }
.note { color: var(--ink-secondary); font-size: var(--text-small); text-align: right; }
.live .note { color: var(--aqua-deep); font-weight: 600; }

/* --- the two phase panels ------------------------------------------------- */

.phases { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); margin: 0 0 var(--s4); }
@media (max-width: 40rem) { .phases { grid-template-columns: 1fr; } }
/* A column, so the way out can be pushed to the foot of the card. Both cards
   are the same height and their text is not, so without this the two pills sit
   at different heights and the pair looks accidental (Esther, 22 October 2026:
   the link goes at the bottom of the card). */
.phase { background: var(--aqua-wash); border-radius: 14px; padding: var(--s5);
  display: flex; flex-direction: column;
  /* The pill inside sizes itself from this card's width, not the window's.
     The card is what actually constrains it, and the two part company: the
     window can be wide while the card is narrow (Esther, 22 October 2026). */
  container-type: inline-size; }
.phase h2 { font-size: var(--text-body-lg); margin: 0 0 var(--s2); }
.phase p { margin: 0 0 var(--s2); color: var(--ink-secondary); font-size: var(--text-small); }
.phase p:last-child { margin: 0; }
/* After `.phase p:last-child`, not before it. The two selectors weigh the
   same, so the later one wins, and while this sat above it the pill kept the
   margin of 0 and stopped wherever the text ended instead of dropping to the
   foot of the card. */
.phase p.phase-cta { margin: auto 0 0; padding-top: var(--s4); }
/* The opening line of each phase box states what the phase is for, and the
   paragraphs under it fill that in. It takes the same treatment the subject
   inset on /subjects gives the same shape of sentence: full-strength ink and
   a heavier weight, at the size of the text around it, so it reads as the
   box's opening line rather than as a second heading. */
.phase .phase-lead { color: var(--ink); font-weight: 600; }

/* ---------------------------------------------------------------------------
   What Alto covers: the catalogue on the homepage.

   Lifted from the Australian site, where this section already exists, so the
   two read as one product rather than as two websites that happen to share a
   logo. The construction is copied rule for rule; only the tokens are ours, so
   it takes this site's aqua and its corner radii, and only the copy and the
   list of subjects differ. If the Australian one is reworked, this is the
   place to follow it.

   Each group is its own white panel with an aqua left edge rather than the
   groups being divided by a rule, so a reader can see at a glance that Maths
   and Literacy are two separate things rather than one long list.
   ------------------------------------------------------------------------- */

.catalogue-group {
  padding: var(--s5);
  background: var(--surface);
  border: var(--border-card) solid var(--rule-brand);
  border-left: 3px solid var(--aqua);
  border-radius: var(--radius-card);
}
.catalogue-group + .catalogue-group {
  margin-top: var(--s5);
}
/* The group name is aqua and the subjects under it are ink, so the hierarchy
   is carried by colour as well as by size. */
.catalogue-group h3 {
  margin: 0;
  color: var(--aqua-deep);
  padding-bottom: var(--s2);
  border-bottom: 1px solid var(--rule);
}

/* The panel inside a group that says where that group's curriculum stands.
   Maths has one because the England alignment needs saying; Literacy does
   not. */
.curriculum-inset {
  margin: var(--s4) 0 var(--s5);
  padding: var(--s4);
  background: var(--aqua-wash);
  border-radius: var(--radius-control);
}
.curriculum-inset p {
  max-width: var(--measure);
  margin: 0;
  font-size: var(--text-small);
  color: var(--ink-secondary);
}
.curriculum-inset-headline {
  margin-bottom: var(--s2) !important;
  font-weight: 650;
  font-size: var(--text-body) !important;
  color: var(--ink) !important;
}

/* Two columns of subjects once there is room, one on a phone. The name and the
   years share a baseline, and the note drops to its own full-width line under
   them, which is what flex-basis: 100% is doing. */
.catalogue-list {
  list-style: none;
  padding: 0;
  margin: 0;
  max-width: none;
  display: grid;
  gap: 0;
}
@media (min-width: 700px) {
  .catalogue-list {
    grid-template-columns: repeat(2, 1fr);
    column-gap: var(--s6);
  }
}
.catalogue-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s2) var(--s3);
  margin: 0;
  padding-block: var(--s3);
  border-bottom: 1px solid var(--rule);
}
.catalogue-name {
  font-weight: 600;
}
.catalogue-years {
  color: var(--ink-secondary);
  font-size: var(--text-small);
}
.catalogue-note {
  flex-basis: 100%;
  color: var(--ink-secondary);
  font-size: var(--text-small);
  line-height: 1.5;
}
/* The link out to the page that lists everything. It sits below the groups
   with the space a third group would have had above it, so it reads as the end
   of the list rather than as a stray line under the last panel. */
.catalogue-more {
  margin: var(--s5) 0 0;
  font-weight: 600;
}

/* The head of the band: the heading, then the one-sentence claim, then the
   line that fills it in. The claim is the same size as the line under it but
   full-strength ink and heavier, so it reads as the second half of the heading
   rather than as the first line of the paragraph. Both are the Australian
   site's treatment. */
.band-head {
  max-width: var(--measure-wide);
  margin-bottom: var(--s6);
}
.band-head h2 {
  margin: 0 0 var(--s3);
}
.band-head p {
  margin: 0;
  color: var(--ink-secondary);
  font-size: var(--text-body-lg);
  max-width: var(--measure);
}
.band-head p.band-statement {
  color: var(--ink);
  font-weight: 600;
  margin-bottom: var(--s3);
}
.phase a { font-weight: 600; }

.trust { background: var(--surface-sunken); border-radius: 14px; padding: var(--s5); margin: 0 0 var(--s4); }
.trust h2 { font-size: var(--text-body-lg); margin: 0 0 var(--s3); }
.trust ul {
  list-style: none; margin: 0 0 var(--s4); padding: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s2) var(--s4);
}
@media (max-width: 40rem) { .trust ul { grid-template-columns: 1fr; } }
.trust li { color: var(--ink-secondary); font-size: var(--text-small); }
.trust p { margin: 0; color: var(--ink-secondary); font-size: var(--text-small); }

/* ---------------------------------------------------------------------------
   PRE-LAUNCH MARKS. These exist so that what is not settled cannot be read as
   settled. Every one of them comes off before the site is shown to anybody
   outside, and PENDING.md is the checklist.

   They deliberately do not use the brand colours: gold and dashed edges read
   as scaffolding rather than design, which is the point. Nothing here should
   survive to launch.
   ------------------------------------------------------------------------- */

.needs {
  display: inline-block;
  background: var(--gold);
  color: #2b2000;
  border-radius: 999px;
  padding: 0.05rem 0.5rem;
  font-size: var(--text-caption);
  font-weight: 700;
  white-space: nowrap;
}

/* A subject that ships at launch but is not open yet. Deliberately not the grey
   badge above: grey is for something nobody has built, and these are built. */

.gap {
  border: 2px dashed var(--rule-strong);
  border-radius: 14px;
  padding: var(--s5);
  margin: var(--s5) 0 0;
}
.gap h2 {
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-tertiary);
  margin: 0 0 var(--s3);
}
.gap ul { margin: 0; padding-left: var(--s4); color: var(--ink-secondary); max-width: var(--measure); }
.gap li { margin-bottom: var(--s2); }
.gap-note { margin: var(--s4) 0 0; font-size: var(--text-caption); color: var(--ink-tertiary); }
.gap.research { border-color: var(--aqua-soft); }
.gap.research h2 { color: var(--aqua-deep); }

/* A price that is proposed rather than agreed. */
.card.proposed { border-color: var(--gold); }

/* ---------------------------------------------------------------------------
   IMAGE PLACEHOLDERS. A box saying what picture belongs here and why, so the
   page can be reviewed without inventing a screenshot of something that does
   not exist yet.

   Deliberately not a grey rectangle. A grey rectangle gets mistaken for an
   image that failed to load, and then it ships. This one states the brief.
   The strategy is explicit that placeholder blocks must not reach a real
   visitor, so these are listed in PENDING.md and come off with the dashed
   boxes.
   ------------------------------------------------------------------------- */

.shot {
  border: 2px dashed var(--aqua-soft);
  background: var(--aqua-wash);
  border-radius: 14px;
  padding: var(--s5);
  margin: 0 0 var(--s4);
}
/* Specificity note: .shot p below would otherwise win over a bare
   .shot__label and repaint this dark text on a dark ground. */
.shot p.shot__label {
  display: inline-block;
  background: var(--aqua-deep);
  color: #ffffff;
  border-radius: 999px;
  padding: 0.15rem 0.7rem;
  font-size: var(--text-caption);
  font-weight: 700;
  letter-spacing: 0.04em;
  margin: 0 0 var(--s3);
}
.shot h3 { font-size: var(--text-body-lg); margin: 0 0 var(--s2); font-family: var(--font-heading); }
.shot p { margin: 0 0 var(--s2); color: var(--ink-secondary); font-size: var(--text-small); }
.shot p:last-child { margin: 0; }
.shot ul { margin: 0 0 var(--s2); padding-left: var(--s4); color: var(--ink-secondary); font-size: var(--text-small); }
.shot li { margin-bottom: 0.3rem; }
.shot__why { font-style: italic; color: var(--ink-tertiary); }

/* --- footer --------------------------------------------------------------- */

.site-footer {
  margin: var(--s7) 0 0;
  padding: var(--s5) 0 0;
  border-top: 1px solid var(--rule);
  font-size: var(--text-small);
  color: var(--ink-tertiary);
}
.home .site-footer { text-align: center; }
.site-footer ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s5);
  margin: 0 0 var(--s4);
  padding: 0;
}
.home .site-footer ul { justify-content: center; }
.site-footer p { margin: 0.3rem 0; }

/* ---------------------------------------------------------------------------
   THE UK MAP. The geometry is real: a NUTS 1 outline, generated for GTTR from
   a source Esther supplied, and reused here (Gttr-uk/gttr
   apps/marketing/src/content/uk-outline.js).

   Inline rather than an <img>, because each nation is a link to its own panel
   and an <img> cannot be clicked nation by nation. That is also why it needs no
   script: an anchor jump is a browser feature.

   The map is not the interface. Every fact on it is repeated in the panels
   below, in more detail and in an order a screen reader can move through.
   ------------------------------------------------------------------------- */

.ukmap {
  display: block;
  width: 100%;
  /* 1.30 is the map's own height-to-width ratio with the left gutter that makes
     room for Northern Ireland's pill (996 / 765), so this caps the drawing at
     roughly 56% of the window height however narrow the window is. Width alone
     was not enough: on a phone it filled two thirds of the screen. */
  max-width: min(23rem, calc(56vh / 1.30));
  height: auto;
  margin: 0 auto var(--s5);
}
/* The Republic of Ireland: drawn muted and unlabelled, because without it
   Northern Ireland reads as a fragment floating beside Scotland. */
.ukmap__context { fill: var(--surface-sunken); stroke: var(--rule); stroke-width: 1; }

.ukmap__nation path { stroke: var(--cream); stroke-width: 2; transition: fill 0.12s ease; }
.ukmap__nation--england path { fill: var(--nation-england-soft); }
.ukmap__nation--scotland path { fill: var(--nation-scotland-soft); }
.ukmap__nation--wales path { fill: var(--nation-wales-soft); }
.ukmap__nation--northern-ireland path { fill: var(--nation-northern-ireland-soft); }
.ukmap__nation:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* The label pill: the nation's own colour with white text, so it always reads
   against the country beneath it, which is a pale tint of the same colour. */
.ukmap__pill rect { stroke: #ffffff; stroke-width: 3; }
.ukmap__nation--england .ukmap__pill rect { fill: var(--nation-england); }
.ukmap__nation--scotland .ukmap__pill rect { fill: var(--nation-scotland); }
.ukmap__nation--wales .ukmap__pill rect { fill: var(--nation-wales); }
.ukmap__nation--northern-ireland .ukmap__pill rect { fill: var(--nation-northern-ireland); }

.ukmap__name { text-anchor: middle; fill: #ffffff; font-family: var(--font-body); }
.ukmap__name { font-size: 26px; font-weight: 700; }

/* Hovering, tabbing to, or selecting a nation deepens the country itself. No
   script: clicking sets the URL fragment to that nation's panel, so
   #card-scotland:target matches and :has() on the body lets the map respond. */
.ukmap__nation--england:hover path, .ukmap__nation--england:focus-visible path,
body:has(#card-england:target) .ukmap__nation--england path { fill: var(--nation-england-mid); }
.ukmap__nation--scotland:hover path, .ukmap__nation--scotland:focus-visible path,
body:has(#card-scotland:target) .ukmap__nation--scotland path { fill: var(--nation-scotland-mid); }
.ukmap__nation--wales:hover path, .ukmap__nation--wales:focus-visible path,
body:has(#card-wales:target) .ukmap__nation--wales path { fill: var(--nation-wales-mid); }
.ukmap__nation--northern-ireland:hover path, .ukmap__nation--northern-ireland:focus-visible path,
body:has(#card-northern-ireland:target) .ukmap__nation--northern-ireland path { fill: var(--nation-northern-ireland-mid); }

/* THE NATION PANELS take the same four colours as the map, so the two halves of
   the page are obviously the same four things. Selecting one deepens its edge to
   the dark tone of its OWN colour: a highlighted nation never borrows the site's
   aqua (Esther, 29 September 2026). */
#card-england { border-color: var(--nation-england); }
#card-scotland { border-color: var(--nation-scotland); }
#card-wales { border-color: var(--nation-wales); }
#card-northern-ireland { border-color: var(--nation-northern-ireland); }

#card-england h2, #card-england .more summary { color: var(--nation-england-dark); }
#card-scotland h2, #card-scotland .more summary { color: var(--nation-scotland-dark); }
#card-wales h2, #card-wales .more summary { color: var(--nation-wales-dark); }
#card-northern-ireland h2, #card-northern-ireland .more summary { color: var(--nation-northern-ireland-dark); }

.card:target { border-width: 3px; }

/* ---------------------------------------------------------------------------
   One nation at a time, with a tab per subject.

   Esther, 21 October 2026: choose a country on the map, get that country's
   card, click through the subject tabs inside it, and go back to the map to
   see another country. The card and its tabs wear the country's own colour.

   Two CSS mechanisms, no script, because this site has none:

   1. WHICH NATION. The map links are already #card-england and friends, and
      the stylesheet already used :target and :has() to light the chosen nation
      up on the map, so the same hash now decides which card is shown. Nothing
      is shown until a nation is chosen; the prompt stands in its place.

   2. WHICH SUBJECT. A radio per subject inside each card, one group per
      nation. Radios rather than ARIA tabs on purpose: arrow-key movement
      between them is the browser's own, which an ARIA tablist would have to
      rebuild in JavaScript that this site is not allowed to load.

   The seven display rules below are shared by all four nations, because the
   radio and its panel carry matching classes and :has() is scoped to the card
   the reader is in.
   ------------------------------------------------------------------------- */

/* All four nations stay on the page, and choosing one on the map brings it to
   the top of the list rather than hiding the other three (Esther, 21 October
   2026). That settles the two defaults the page needs: England leads, because
   it is first in the source, and every card opens on Times Tables, because
   that is the only subject mapped.

   Two declarations do the reordering. The chosen card takes order 1 and every
   other card order 2, and flex leaves cards with equal order in source order,
   so the other three keep their usual sequence underneath. Nothing is removed
   from the page, so find-in-page and a screen reader still reach all four,
   which hiding them would have cost. */
.nations { display: flex; flex-direction: column; }
/* The column is ordered rather than written in order, because the chosen
   nation rises to the top. Everything else has to be pinned around it: the
   subject tabs and the subject's opening line first, the four cards next with
   the chosen one leading, and what they share last. */
.subject-choice, .subject-intro { order: 0; }
.nation { order: 2; }
.nation:target { order: 1; }
.everywhere { order: 3; }

.subtabs { border: 0; padding: 0; margin: 0; min-width: 0; }
.subtabs__strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin: 0 0 var(--s5);
  padding: 0 0 var(--s4);
  border-bottom: 1px solid var(--rule);
}
/* Off-screen rather than display:none, so the radio keeps its place in the tab
   order and can still be reached and moved between with the keyboard. */
.subtabs__radio {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%);
  white-space: nowrap;
}
.subtabs__label {
  cursor: pointer;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-secondary);
  font-size: var(--text-small);
  font-weight: 600;
  line-height: 1.3;
}
.subtabs__label:hover { border-color: var(--rule-strong); color: var(--ink); }

/* The radios sit once at the top of .nations, so every rule that used to look
   inside one nation's fieldset now looks at .nations. One choice moves all four
   cards, which is the point: the nations are on the page together to be
   compared (Esther, 21 October 2026). */
.subject-choice { border: 0; padding: 0; margin: 0; min-width: 0; }

.subtabs__panel { display: none; }
.nations:has(.r-times-tables:checked)   .p-times-tables   { display: block; }
.nations:has(.r-number-facts:checked)   .p-number-facts   { display: block; }
.nations:has(.r-number-facts-2:checked) .p-number-facts-2 { display: block; }
.nations:has(.r-maths:checked)          .p-maths          { display: block; }
.nations:has(.r-mentals:checked)        .p-mentals        { display: block; }
.nations:has(.r-spelling:checked)       .p-spelling       { display: block; }
.nations:has(.r-grammar:checked)        .p-grammar        { display: block; }

/* The chosen tab still takes the nation's own colour, the same one its card
   edge and its heading take, so each card still reads as one object. The
   colour comes from the card rather than the rule, so this is seven selectors
   and four declarations rather than twenty-eight rules. */
#card-england          { --tab: var(--nation-england);          --tab-edge: var(--nation-england-dark); }
#card-scotland         { --tab: var(--nation-scotland);         --tab-edge: var(--nation-scotland-dark); }
#card-wales            { --tab: var(--nation-wales);            --tab-edge: var(--nation-wales-dark); }
#card-northern-ireland { --tab: var(--nation-northern-ireland); --tab-edge: var(--nation-northern-ireland-dark); }

.nations:has(.r-times-tables:checked)   .l-times-tables,
.nations:has(.r-number-facts:checked)   .l-number-facts,
.nations:has(.r-number-facts-2:checked) .l-number-facts-2,
.nations:has(.r-maths:checked)          .l-maths,
.nations:has(.r-mentals:checked)        .l-mentals,
.nations:has(.r-spelling:checked)       .l-spelling,
.nations:has(.r-grammar:checked)        .l-grammar {
  background: var(--tab); border-color: var(--tab-edge); color: #ffffff;
}

/* The radio is off-screen, so its focus ring has to show on the labels that
   drive it. All four light at once, which is honest: one press moves them all. */
.nations:has(.r-times-tables:focus-visible)   .l-times-tables,
.nations:has(.r-number-facts:focus-visible)   .l-number-facts,
.nations:has(.r-number-facts-2:focus-visible) .l-number-facts-2,
.nations:has(.r-maths:focus-visible)          .l-maths,
.nations:has(.r-mentals:focus-visible)        .l-mentals,
.nations:has(.r-spelling:focus-visible)       .l-spelling,
.nations:has(.r-grammar:focus-visible)        .l-grammar {
  outline: 2px solid var(--focus); outline-offset: 2px;
}

/* A subject with no research behind it yet. Said plainly, in the quiet tone
   the rest of the page uses for what is not settled. */
.not-mapped { margin: 0; color: var(--ink-secondary); max-width: var(--measure); }
/* A "Coming soon" inside a row of facts is part of the sentence, not a block
   above the next thing, so it drops the standing margin that version carries
   when it sits under a heading. Without this it opens a gap mid-paragraph. */
.facts dd .soon { margin: 0; }

/* Off-screen but available to a screen reader. */
.vh {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%);
  white-space: nowrap;
}
#card-england:target { border-color: var(--nation-england-dark); background: #f7fcff; }
#card-scotland:target { border-color: var(--nation-scotland-dark); background: #fbfaff; }
#card-wales:target { border-color: var(--nation-wales-dark); background: #f7fdf9; }
#card-northern-ireland:target { border-color: var(--nation-northern-ireland-dark); background: #fffafb; }

@media (max-width: 40rem) {
}

.mapblock {
  display: grid;
  gap: var(--s4) var(--s6);
  align-items: center;
  margin: 0 0 var(--s6);
}
@media (min-width: 46rem) {
  .mapblock { grid-template-columns: 17rem 1fr; }
  .mapblock .ukmap { margin: 0; max-width: 100%; }
  .mapblock .map-note { text-align: left; margin: 0; max-width: none; }
}

/* The notes beside the map are one grid item, not two, or the second one drops
   into the map's column and sits under it in a narrow strip. */
.map-notes { display: grid; gap: var(--s3); }
.map-note {
  max-width: var(--measure);
  margin: 0 auto;
  font-size: var(--text-small);
  color: var(--ink-secondary);
  text-align: center;
}

/* --- "Tell me more" ------------------------------------------------------- */
/* A plain <details>. It opens with no script, it is keyboard operable, and its
   contents are in the page for a screen reader and for find-in-page whether it
   is open or not. */

.more { margin: var(--s4) 0 0; border-top: 1px solid var(--rule); padding-top: var(--s4); }
.more summary {
  cursor: pointer;
  color: var(--aqua-deep);
  font-weight: 600;
  font-size: var(--text-small);
  list-style-position: outside;
}
.more summary:hover { color: var(--aqua-deep-hover); text-decoration: underline; }
.more summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 3px; }
.more[open] summary { margin-bottom: var(--s4); }
.more .facts { margin-bottom: var(--s3); }

/* The four ways a department can use Alto, on the secondary maths page. One
   symbol each, all drawn in the maths subject colour because that is the
   product this page is for. The symbols are inline SVG rather than image
   files, so nothing loads from another site and they inherit the text colour
   if the palette ever changes. */
.uses { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s5) var(--s4); margin: 0; }
@media (max-width: 40rem) { .uses { grid-template-columns: 1fr; } }
.use h3 {
  margin: 0 0 var(--s2);
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: var(--s3);
}
.use p { margin: 0; color: var(--ink-secondary); }
.use__icon {
  flex: none;
  width: 2.25rem;
  height: 2.25rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--subject-maths-soft);
  color: var(--subject-maths);
}
.use__icon svg { width: 1.25rem; height: 1.25rem; display: block; }

/* One step back, above the heading, on every page but the homepage. The Alto
   mark top left always goes home; this goes to the page above, which on a
   child page is the more useful of the two. Small and quiet, because it is a
   way out rather than something to read. */
/* IT BELONGS TO THE BAR, NOT TO THE HEADING (Esther, 23 October 2026). It sat
   32px under the bar and 12px above the text on a plain page, and 110px under
   the bar on a page built from bands, because the first band's own top padding
   fell between them. Either way it read as a label on the heading rather than
   a way back out of the page.

   Measured, not guessed: the bar's margin is 32px, a band's top padding 78px.
   Pulling up by that plus --s4 leaves about 16px under the bar in both cases,
   and the bottom margin doubles so the heading sits clear of it. */
.back {
  /* A block box, not inline-block. A negative margin-top on an inline-block is
     computed and then ignored for layout: the line box it sits in stays put
     inside the parent's padding, so the link did not move. width: fit-content
     keeps the hit area to the words, which is what inline-block was for. */
  display: block;
  width: fit-content;
  margin: calc(var(--s4) * -1) 0 var(--s5);
  font-size: var(--text-small);
  text-decoration: none;
}
.band .back { margin-top: calc((var(--band) + var(--s4)) * -1); }
.back:hover { text-decoration: underline; }
.back:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 3px; }

/* ---------------------------------------------------------------------------
   Layout pieces taken from the Alto site, so altoguru.uk reads as the same
   product (Esther, 9 October 2026). The colour and type tokens were already
   shared: 37 of them are identical in both stylesheets, because this site's
   CSS was ported from Alto's at the start. What was missing was the layout
   scale and the control shapes, which is what this block adds.

   Nothing here loads from another site, and none of it needs JavaScript.
   --------------------------------------------------------------------------- */

:root {
  --s1: 0.25rem;
  --s8: 4rem;
  --s9: 6rem;
  --band: clamp(3rem, 2rem + 5vw, 5.5rem);
  --content-max: 72rem;
  --text-display: clamp(2.25rem, 1.5rem + 3vw, 3.25rem);
  --radius-card: 0.75rem;
  --radius-control: 0.5rem;
  --radius-pill: 999px;
  --coral-action-hover: #d1452a;
}

/* A full-width band that re-pads itself, so a section can sit on its own
   ground without the page wrapper fighting it. */
.band {
  margin-inline: calc(50% - 50vw);
  padding-inline: max(var(--gutter), calc(50vw - (var(--content-max) / 2)));
  padding-block: var(--band);
}
.band--sunken { background: var(--surface-sunken); }
.band--wash { background: var(--aqua-wash); }

/* --- controls ------------------------------------------------------------- */
/* Coral is the action colour and appears only on things you can click, which
   is the rule the palette was built around. The outlined button is the quieter
   second choice beside it. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.7rem 1.15rem;
  border-radius: var(--radius-control);
  border: 2px solid transparent;
  font-family: var(--font-body);
  font-size: var(--text-small);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
}
.btn--primary { background: var(--coral-action); border-color: var(--coral-action); color: #fff; }
.btn--primary:hover { background: var(--coral-action-hover); border-color: var(--coral-action-hover); color: #fff; }
.btn--secondary { background: transparent; border-color: var(--aqua-deep); color: var(--aqua-deep); }
.btn--secondary:hover { background: var(--aqua-wash); color: var(--aqua-deep-hover); }
.btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--s3); margin: var(--s5) 0 0; }

/* --- hero pills ----------------------------------------------------------- */
/* Three short facts under the hero paragraph. Not links, so they carry no
   coral: an outline and the body colour, which keeps clickable things
   distinct from stated ones. */
.pills { display: flex; flex-wrap: wrap; gap: var(--s2); margin: var(--s4) 0 0; padding: 0; list-style: none; }
.pills li {
  padding: 0.3rem 0.7rem;
  /* The palest aqua this file carries, the one the opening band of every page
     uses (Esther, 22 October 2026). The border comes down to the soft aqua so
     the edge belongs to the fill rather than fencing it. Text measures 6.84:1
     on it, so it passes AA as ordinary text, which at 13px it is. */
  background: var(--aqua-hint);
  border: 1px solid var(--aqua-soft);
  border-radius: var(--radius-pill);
  font-size: var(--text-caption);
  color: var(--ink-secondary);
}

/* --- the four-point strip under the hero ---------------------------------- */
/* Four statements, each with a rule down its left edge. They are claims about
   the product, so every one has to be supportable; see PENDING.md. */
.points {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s5);
  margin: 0;
  padding: 0;
  list-style: none;
}
@media (max-width: 62rem) { .points { grid-template-columns: repeat(2, 1fr); gap: var(--s4); } }
@media (max-width: 34rem) { .points { grid-template-columns: 1fr; } }
.points li {
  border-left: 2px solid var(--aqua);
  padding-left: var(--s3);
  font-size: var(--text-small);
  color: var(--ink-secondary);
  line-height: 1.45;
}

/* --- two columns, for "two ways in" --------------------------------------- */
/* Narrower than the band it sits in, and tighter inside, so the two doors read
   as a pair of choices rather than two full-width slabs (Esther, 10 October
   2026). .split is used only here, so the padding is set on the component
   rather than overriding .card for everyone. */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s6); }
.split .card { padding: var(--s4); }
/* The two doors are a matched pair, so their buttons should sit on the same
   line however much copy each card carries (Esther, 21 October 2026: keep the
   cards balanced, with consistent CTA placement). The grid already stretches
   both cards to the same height; making each card a column and letting the
   button row take the slack above it pushes both buttons to the foot of their
   card rather than leaving them to float wherever the copy happens to end.

   The families card still carries its card-details line under its button, so
   that button sits one small line higher than the schools one. That is the
   disclosure winning over the alignment, which is the right way round: a free
   trial that needs a card has to be said before the button is pressed. */
.split .card { display: flex; flex-direction: column; }
.split .card .btn-row { margin-top: auto; }
/* The heading above and the line below have to sit on the same edges as the
   cards, so the whole band narrows rather than just the grid inside it. */
.band--narrow > * { max-width: 52rem; margin-inline: auto; }

/* A marker in the card's top right corner. .card is already position:relative.
   It sits after the heading in the source so a screen reader hears the door's
   name and then that it is not open yet, which is the order that makes sense
   read aloud, whatever the corner does visually. */
.soon--corner { position: absolute; top: var(--s4); right: var(--s4); margin: 0; }
/* The marker and the heading share a horizontal band, so the heading is kept
   clear of the corner. "For schools" comes nowhere near it, but a longer one
   would run underneath without this. */
.split .card h3 { padding-right: 8.5rem; }

/* The trial's terms. Small, but not hidden: a free trial that needs a card is
   a thing a parent has to be told before they press it, not after. Esther,
   21 October 2026: smaller again, hence --text-micro, which exists for this
   line and should not be borrowed for body copy. */
.terms { margin: var(--s2) 0 0; color: var(--ink-tertiary);
  font-size: var(--text-micro); max-width: none; }
/* On the homepage doors it sits ABOVE the button rather than under it, so that
   the button is the last thing in both cards and the two buttons land on the
   same line (Esther, 21 October 2026: level buttons). Reading it before
   reaching the button is if anything truer to why the line is there.

   It is also never wider than the button it belongs to (Esther, same day), so
   the small print reads as part of the button rather than as a line sprawling
   across the card. Fitting the sentence on ONE line inside the button's width
   would need about 9px type, which is too small for a line telling a parent
   that a card is required, so it wraps to two lines instead.

   How the width is held without hard-coding the button's size: the wrapper is
   fit-content, so it is as wide as the widest thing that counts towards its
   width, which is the button. The terms line is taken out of that calculation
   by width: 0, then filled back out to the wrapper by min-width: 100%. Change
   the button's words and the small print follows, with nothing to update. */
.split .card .door-cta { margin-top: auto; width: fit-content; }
.split .card .door-cta .btn-row { margin-top: 0; }
.split .card .terms { width: 0; min-width: 100%; margin: 0 0 var(--s2); }

/* The line under the two doors, for the reader who belongs to neither because
   their child already has Alto through school. It is a box rather than a quiet
   line because it was easy to miss, and it names its reader so they know it is
   for them (Esther, 10 October 2026). Aqua wash is a field, not text, so rule 2
   at the top of this file holds. */
.parents-note {
  background: var(--aqua-wash);
  border: 1px solid var(--aqua-soft);
  border-radius: 12px;
  padding: var(--s3) var(--s4);
  margin: var(--s5) auto 0;
  color: var(--ink-secondary);
  text-align: center;
}
.parents-note__label {
  font-size: var(--text-caption);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--aqua-deep);
}
@media (max-width: 52rem) { .split { grid-template-columns: 1fr; gap: var(--s5); } }

/* --- the closing band ----------------------------------------------------- */
.closer { text-align: center; }
.closer h2 { font-size: var(--text-h2); margin: 0 0 var(--s3); }
.closer .btn-row { justify-content: center; }

/* --- nav right-hand side --------------------------------------------------- */
/* Two actions: Sign in stays a quiet link for people who already have an
   account, and Get Started carries the coral, because it is the one we want
   pressed. Both go to the same place today, the adult sign-in. */
/* Both selectors are qualified with .nav deliberately. `.nav a` further up
   sets colour and font-weight: 700 on every link in the bar, so an unqualified
   .nav__signin or .btn loses to it, and the result is a bold blue Sign in and a
   coral button with blue text in it. That has caught this nav out before. */
.nav .nav__actions { display: flex; align-items: center; gap: var(--s4); }
.nav a.nav__signin {
  font-size: var(--text-small);
  font-weight: 400;
  color: var(--ink-secondary);
  text-decoration: none;
}
.nav a.nav__signin:hover { color: var(--ink); text-decoration: underline; }

/* White text, and the darker coral rather than the ordinary one: the label is
   small, and --coral-action is only rated for 19px at weight 700. The small
   variant is the one that clears 4.5:1 at this size. */
.nav a.btn--primary {
  background: var(--coral-action-small);
  border-color: var(--coral-action-small);
  color: #ffffff;
  font-weight: 600;
  text-decoration: none;
}
.nav a.btn--primary:hover {
  background: var(--coral-action-hover);
  border-color: var(--coral-action-hover);
  color: #ffffff;
  text-decoration: none;
}
.btn--small { padding: 0.45rem 0.85rem; font-size: var(--text-caption); }

/* The one marker for anything not running yet (Esther, 9 October 2026).
   The site is written as though it has launched, and everything that is not
   live yet carries this and nothing else. That is the whole point of it: on
   launch day the sweep is one find-and-replace for `soon`, not a hunt through
   three class names that happened to mean the same thing. It replaced .soon,
   .planned and .tag-soon, which were an inline grey pill, an inline aqua pill
   and a block grey pill, all saying the same thing in three ways.

   Aqua wash rather than grey, because grey reads as disabled and this is not
   broken, it is not here yet. Coral is never used here: coral means you can
   click it, and you cannot click this.

   What cannot carry a marker, such as a claim about the business or a legal
   statement, is listed in LAUNCH.md instead. */
.soon {
  display: inline-block;
  vertical-align: middle;
  margin-left: var(--s2);
  background: var(--aqua-wash);
  color: var(--aqua-deep);
  border: 1px solid var(--aqua-soft);
  border-radius: var(--radius-pill);
  padding: 0.1rem 0.6rem;
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: 600;
  white-space: nowrap;
}
/* On its own line rather than beside a heading. */
.soon--block { display: inline-block; margin: var(--s4) 0 0; vertical-align: baseline; }
/* --- "How Alto works", the three steps ------------------------------------- */
/* Alto's own layout on its home page: each step is a heading, its words, and
   then one picture or diagram beneath. The numbers are a CSS counter rather
   than typed into the headings, so a step can be reordered or removed without
   anybody renumbering by hand. Coral on the number because it is the accent,
   and the circle is a wash rather than solid so it does not read as a button. */
.steps-band h2 { font-size: var(--text-h2); margin: 0 0 var(--s3); }
/* .lead is capped at the reading measure everywhere. Here the opening line
   keeps that cap and the paragraph under it is released to the full width of
   the band (Esther, 9 October 2026), so the override has to undo the cap
   rather than restate it. */
.steps-band > .lead + .lead { max-width: none; }

.steps-three { display: grid; gap: var(--s7); margin: var(--s6) 0 0; counter-reset: step; }
@media (min-width: 62rem) {
  /* The three pictures line up with each other, not with the words above them.
     Each step has the same four parts in the same order (heading, two
     paragraphs, picture), so the steps lay their parts on the band's own rows
     with subgrid: every heading shares a row, every picture shares a row, and
     a longer paragraph in one column pushes all three pictures down together
     rather than only its own. Without subgrid support this falls back to each
     column being its own height, which is what it did before. */
  .steps-three { grid-template-columns: repeat(3, 1fr); gap: var(--s6); grid-template-rows: repeat(4, auto); }
  .steps-three .step { display: grid; grid-row: span 4; grid-template-rows: subgrid; gap: 0; }
  .steps-three .step > p { margin: 0 0 var(--s3); }
  /* All three visuals are the same shape, so they finish level with each other
     as well as starting level. They were align-self: start and each kept its
     own height: the diagram came out 239px against 337px photographs, 98px
     short (Esther, 12 October 2026).

     The shape is the diagram's own 16:10, which is also a letterbox rather
     than the near-square the photographs are. At 1050px they were 307 by 285,
     tall enough to overpower the words beside them (Esther, 22 October 2026).
     One ratio on all three both levels them and brings them down, and holds
     when the columns stack. The photographs crop rather than squash. */
  .steps-three .step img,
  .steps-three .step .step-diagram { align-self: start; }
}

.step > p { color: var(--ink-secondary); margin: 0 0 var(--s3); }
.step h3 {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin: 0 0 var(--s3);
  font-size: var(--text-h3, 1.1875rem);
}
.step h3::before {
  counter-increment: step;
  content: counter(step);
  flex: none;
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: var(--coral-wash);
  color: var(--coral-action);
  font-family: var(--font-body);
  font-size: var(--text-small);
  font-weight: 700;
}
.step img,
.step .step-diagram {
  display: block;
  width: 100%;
  margin: var(--s4) 0 0;
  border-radius: var(--radius-card);
  /* 16:10, at every width. The photographs are near square and ran to 312px
     tall stacked on a phone, taller than the words above them (Esther,
     22 October 2026, "especially when it wraps"). This was set inside the
     three-column media query first, which left the stacked case, the one that
     needed it most, untouched. */
  aspect-ratio: 16 / 10;
}
.step img { object-fit: cover; height: auto; }
.step .step-diagram { background: var(--surface-sunken); padding: var(--s4);
  display: grid; align-content: center; overflow: hidden; }
.step .step-diagram svg { display: block; width: 100%; height: auto; max-height: 100%; }

/* --- what a subject costs -------------------------------------------------- */
/* Two pills that say how a subject is paid for, sitting beside its heading
   next to the Coming soon marker (Esther, 9 October 2026).

   They are deliberately not coral: coral means you can click it, and these are
   statements. "Free" borrows the green already defined for Wales rather than
   inventing an eighth hue, because the palette is crowded enough and green is
   not otherwise spoken for here. "Subscription" is the quiet ink pill, since it
   is information rather than an offer.

   These are claims about price, so they cannot carry a Coming soon badge and
   must be true the day they go up. LAUNCH.md part 2b has them. */
.pill-free,
.pill-sub {
  display: inline-block;
  vertical-align: middle;
  margin-left: var(--s2);
  border-radius: var(--radius-pill);
  padding: 0.1rem 0.6rem;
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: 600;
  white-space: nowrap;
}
.pill-free {
  background: var(--nation-wales-soft);
  color: var(--nation-wales-dark);
  border: 1px solid var(--nation-wales);
}
.pill-sub {
  background: var(--surface-sunken);
  color: var(--ink-secondary);
  border: 1px solid var(--rule-strong);
}

/* A second number facts card, distinct from the first without leaving the
   palette: the deeper end of the same blue family, so the two read as a pair
   rather than as unrelated subjects. */
.subject--facts2 { border-color: var(--subject-facts2); }
.subject--facts2 .sample { background: var(--subject-facts2-soft); border-color: var(--subject-facts2); }

/* Mentals is a strategy subject sitting among recall ones, so it takes the
   violet rather than another blue: it should not read as a third number-facts
   card. Facts are recalled, strategies are worked, and the colour says so. */
.subject--mentals { border-color: var(--subject-mentals); }
.subject--mentals .sample { background: var(--subject-mentals-soft); border-color: var(--subject-mentals); }

/* --- the subjects page -----------------------------------------------------
   /subjects follows the shape of the Australian site: a section heading, a
   tinted panel saying what the section is for, then a two-column grid of
   subject cards, with the two sections on alternating backgrounds.

   The UK difference is the card itself. Australia puts a small line icon to
   the left of the title; here the subject's own guru sits in the top right
   with its example box below, which is what Esther asked for on 19 October.

   The rules are scoped to this page on purpose, so /primary keeps the tilted
   diamond it was tuned to on 30 September. */
.band--white { background: var(--surface); }

.subjects-page .group { margin: 0 0 var(--s2); font-size: var(--text-h2); }
/* The one-line proposition under a heading: bold rather than another size, so
   it does not read as a second heading in the outline. */
.subjects-page .deck {
  max-width: var(--measure);
  margin: 0 0 var(--s2);
  font-weight: 700;
  font-size: var(--text-body-lg);
}

.subjects-page .subject-inset {
  background: var(--aqua-wash);
  border-radius: 12px;
  padding: var(--s5);
  margin: 0 0 var(--s5);
}
.subjects-page .subject-inset p { margin: 0; max-width: var(--measure); }
.subjects-page .subject-inset-headline {
  font-weight: 700;
  margin: 0 0 var(--s2) !important;
}

/* Two columns, fixed, not auto-fit. Auto-fit gave three on a wide screen and
   squeezed the text column to nothing once the guru and example box had taken
   their share. Australia has two, and two is what the card was drawn for. */
.subjects-page .subject-cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4);
  margin: 0 0 var(--s4);
}
@media (min-width: 52rem) {
  .subjects-page .subject-cards { grid-template-columns: 1fr 1fr; }
}

/* White card, light rule, and the subject's own colour as a left edge rather
   than the whole border: a ring of colour on every card at once reads as a
   warning, where an edge reads as a label. */
.subjects-page .subject-card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--rule-strong);
  border-radius: 12px;
  padding: var(--s5);
}
/* The cards carry a lot of copy, and at full body size the seven of them ran
   a long way down the page. A step down to the small size takes the height out
   without making the text hard to read, and it also holds the line length in
   the text column closer to something comfortable now that the card is
   narrower than a full measure (Esther, 21 October 2026: a bit more compact). */
.subjects-page .subject-card > p { margin: 0 0 var(--s3); max-width: none; font-size: var(--text-small); }
.subjects-page .subject-card > p:last-child { margin-bottom: 0; }

/* Title and its pills share one wrapping row, so a card with four pills drops
   them to a second line instead of pushing the heading out of the card. */
.subjects-page .subject-card-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
  margin: 0 0 var(--s2);
}
.subjects-page .subject-card-title h3 { margin: 0; }
.subjects-page .subject-card-title .pill-timed,
.subjects-page .subject-card-title .soon { margin-left: 0; }

.subjects-page .subject-card-sub {
  margin: 0 0 var(--s1) !important;
  color: var(--ink-secondary);
}
/* What a subject costs, as the last line of its card rather than a pill on the
   heading. Esther, 19 October 2026: the cost belongs at the end of the box.

   It sits inside the text column, so on a wide card it stops short of the
   guru's column rather than running under it. That is why it is set off by
   weight and space rather than by a rule across the card, which would stop in
   an odd place. */
.subjects-page .subject-cost {
  margin: var(--s4) 0 0 !important;
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--ink-secondary);
}

.subjects-page .subject-card-meta {
  margin: 0 0 var(--s3) !important;
  color: var(--ink-tertiary);
  font-size: var(--text-small);
}

/* The bite-sized subjects are marked by the croc, not by a word, which is what
   the Australian page does: its bite-sized cards carry the croc where the
   other subjects carry their own icon.

   Worth keeping straight, because /pricing draws the line carefully and this
   page should not blur it. Bite-sized means a fixed set a pupil either recalls
   instantly or does not, which is Times Tables, Number Facts and Number Facts
   2. Spelling is also free for schools but is NOT bite-sized: it runs all the
   way through school, so it has no croc.

   The croc carries meaning rather than decorating, so its alt says what it
   means. The guru in the corner is the opposite case and keeps an empty alt. */
.subjects-page .bite-croc {
  width: auto;
  height: 2rem;
  flex: none;
}

/* The other subjects take their own icon in the same slot, lifted from the
   Australian page so the two sites read as one product. They are inline SVG
   rather than files: the site may not load anything from another origin, and
   an inline icon also cannot 404. */
.subjects-page .subject-icon {
  width: 1.75rem;
  height: 1.75rem;
  flex: none;
}

.subjects-page .pill-timed {
  display: inline-block;
  border-radius: var(--radius-pill);
  padding: 0.1rem 0.6rem;
  font-family: var(--font-body);
  font-size: var(--text-caption);
  font-weight: 600;
  white-space: nowrap;
}
.subjects-page .pill-timed {
  background: var(--surface);
  color: var(--ink-secondary);
  border: 1px solid var(--rule-strong);
}

/* The line that explains why three subjects are timed and the rest are not. */
.subjects-page .subject-note {
  max-width: var(--measure-wide);
  margin: 0;
  color: var(--ink-secondary);
  font-size: var(--text-small);
}
.subjects-page .subject-note strong { color: var(--ink); }

.subjects-page .next-links {
  list-style: none;
  margin: 0 0 var(--s3);
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3) var(--s5);
}
.subjects-page .next-links a { font-weight: 600; }

/* The guru is decorative: each one has its subject written on it and the
   heading beside it says the same word, so alt is empty rather than a second
   copy of the heading read out loud.

   Sized by HEIGHT, not width. The gurus are different shapes: Times Tables is
   a wide drawing, most are upright, and Mentals is tall and narrow because
   its word sits in a thought bubble over the guru's head. Giving them one
   width made the wide one small and the tall one enormous; one height keeps
   the figures the same size and lets each drawing take the width it needs,
   within the column. */
.subjects-page .guru { display: block; width: auto; height: 7rem; max-width: 100%; margin: 0 auto var(--s3); }

@media (min-width: 40rem) {
  /* Guru and example box share one column down the right of the card.
  
     Placing them separately is what went wrong first time: the guru sat at the
     top and the box at half height, and on a short card the two met. Making
     the column a flex box and giving the box `margin: auto 0` centres it in
     whatever room is left under the guru, so it is halfway down by
     construction and cannot collide however short the card is. */
  .subjects-page .subject-card { padding-right: 8.75rem; }
  .subjects-page .subject__aside {
    position: absolute;
    top: var(--s5);
    right: var(--s5);
    bottom: var(--s5);
    width: 6.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  /* height: auto with a ceiling rather than a fixed height, so the wide
     Times Tables guru is held by the column's width and the upright ones by
     the ceiling, and neither is stretched past the drawing's own size */
  .subjects-page .guru { width: auto; height: auto; max-height: 8.5rem; margin: 0; }
  /* Upright and inside the card. Overrides the tilted, hanging placement that
     /primary uses, which is why every one of these is restated. */
  .subjects-page .sample {
    position: static;
    transform: none;
    margin: auto 0;
    width: 100%;
    max-width: none;
    font-size: 0.58rem;
    box-shadow: 0 2px 10px rgb(33 31 28 / 0.08);
  }
  .subjects-page .subject-card h3 { padding-right: 0; }
}

/* Less air down the sides of the example box than the tilted one on /primary
   has: under a third of it (Esther, 21 October 2026, twice). The box sits in a
   narrow column, so the padding was taking a real share of the room the
   question had to sit in. It buys most on Spelling and Grammar, whose
   questions are sentences that wrap: a wrapped line that now fits is a line
   off the height of the box. Top and bottom are unchanged, because the box is
   not short of height.

   Worth knowing if this is revisited: on a wide screen the box is as wide as
   the column it shares with the guru, so trimming the padding gives the
   question more room rather than making the box narrower. Narrowing the box
   means narrowing that column, and the guru comes down with it. */
.subjects-page .sample { padding-left: 0.3em; padding-right: 0.3em; }

/* The Maths box keeps a little less side padding than the rest (Esther,
   21 October 2026). Worth knowing before anyone trims it again: on this page
   almost none of the space either side of the fractions is padding. The box is
   as wide as the column it shares with the guru, the FOR EXAMPLE label is
   wider than the two fractions are, and the fractions are centred in what is
   left, which is where the roughly thirty pixels either side of them comes
   from. Closing that gap means larger fractions or a smaller label, not less
   padding.

   Spelling and Grammar are the opposite case and are deliberately left alone:
   their questions are sentences that wrap to the full width, so the padding is
   the whole of the gap and it is already even on both sides. */
.subjects-page .subject--maths .sample { padding-left: 0.15em; padding-right: 0.15em; }

@media (max-width: 39.999rem) {
  /* On a phone the column unwinds into the flow: guru first, example box under
     it, both upright and the full width of the card. */
  .subjects-page .subject-card { padding-right: var(--s5); }
  .subjects-page .subject__aside { margin: 0 0 var(--s4); }
  .subjects-page .sample { display: block; width: auto; max-width: none; margin: 0; }
}

/* Each subject's colour on its card edge and its example box. */
.subjects-page .subject--tables { border-left-color: var(--subject-tables); }
.subjects-page .subject--facts { border-left-color: var(--subject-facts); }
.subjects-page .subject--facts2 { border-left-color: var(--subject-facts2); }
.subjects-page .subject--mentals { border-left-color: var(--subject-mentals); }
.subjects-page .subject--maths { border-left-color: var(--subject-maths); }
.subjects-page .subject--spelling { border-left-color: var(--subject-spelling); }
.subjects-page .subject--grammar { border-left-color: var(--subject-grammar); }
/* --- a borrowed finding ---------------------------------------------------- */
/* Alto's own treatment for research that is somebody else's: set apart from
   our own voice by a sunken panel and a heavier rule down the left, so a
   reader can see at a glance which words are Ofsted's and which are ours.

   The quotations are verbatim and were checked against the two Ofsted
   documents before they went up, which is why the citation links to both
   rather than to a summary of them. */
.borrowed {
  max-width: var(--measure-wide);
  margin: 0 0 var(--s4);
  padding: var(--s6);
  background: var(--surface-sunken);
  border: var(--border-card) solid var(--rule-brand);
  border-left: 4px solid var(--rule-strong);
  border-radius: var(--radius-card);
}
.borrowed .eyebrow { color: var(--ink-tertiary); margin: 0 0 var(--s2); }
.borrowed h2 { font-size: var(--text-h2); margin: 0 0 var(--s4); }
.borrowed p { color: var(--ink-secondary); margin: 0 0 var(--s3); }
.borrowed blockquote {
  margin: 0 0 var(--s4);
  padding-left: var(--s4);
  border-left: 3px solid var(--aqua);
}
.borrowed blockquote p { margin: 0; color: var(--ink); font-size: var(--text-body-lg); }
.borrowed cite {
  display: block;
  margin-top: var(--s4);
  font-size: var(--text-small);
  font-style: normal;
  color: var(--ink-secondary);
}

/* --- The Great Times Tables Race panel ------------------------------------ */
/* GTTR's mark, lifted from the app (Gttr-uk/gttr apps/app/index.html, .hub-arc)
   so the two draw the same thing: the name on an arc, the racer tucked into its
   dip, both standing on the pale green dome. Same path data, same proportions.

   TWO DELIBERATE DEPARTURES FROM THE RULES AT THE TOP OF THIS FILE. Both are
   written down here so a later tidy-up does not quietly undo them:

   1. Coral on something you cannot click, which rule 1 forbids. This is GTTR's
      logotype, not Alto furniture, and a mark recoloured to fit a host palette
      stops being the mark. It is the only coral on this page that is not a
      control, and the licence does not extend past this panel.

   2. The app sets the arc in Nunito. Nothing here is downloaded, so it falls
      back to Arial Rounded MT Bold where that exists and to the body stack
      everywhere else. GTTR's shape, not always GTTR's letterforms.

   ON THE ARC'S CONTRAST, measured rather than assumed. #e8453c on white is
   3.93:1. The 36px in the viewBox is not 36px on screen: the mark caps at
   19rem centred and 17rem floated, against a 620-unit box, so the type
   renders at about 17.6px and 15.8px. Both are under the 18.66px that would
   let bold text pass AA on that ratio. It is
   sound anyway, for a reason that has to hold if this markup is changed:
   the mark is aria-hidden and purely decorative, and WCAG exempts a logotype,
   while the same five words sit beside it in the h2 as ordinary ink at 15.5:1.
   Expose the arc to assistive tech, or drop that heading, and this stops being
   true. */

/* Narrow: an emblem centred over the words, because there is no width to run
   anything alongside. Wide: the mark sits in the top right and the words run
   around it (Esther, 10 October 2026). A two column grid was tried first and
   was wrong, because the mark is only about 130px tall against a much taller
   column of text, so it left a long empty gap down one side. A float has no
   such column to leave empty. `flow-root` on the panel contains the float so
   the card's bottom border still closes underneath the mark. */
.gttr__mark { display: grid; justify-items: center; width: min(100%, 19rem);
  margin: 0 auto var(--s4); }
@media (min-width: 52rem) {
  .gttr { display: flow-root; }
  .gttr__mark { float: right; width: 17rem; margin: 0 0 var(--s3) var(--s5); }
}
.gttr-arc { width: 100%; height: auto; display: block; overflow: visible; }
.gttr-arc text { font-family: 'Arial Rounded MT Bold', var(--font-body);
  font-weight: 900; font-size: 36px; fill: #e8453c; }
.gttr-arc-dot { fill: #e8453c; }
.gttr-arc-dome { fill: #e3eeca; }
/* the racer sits inside the arc, tucked up into its dip so the name wraps over
   the head rather than floating above a gap */
.gttr__mark img { width: 47%; height: auto; display: block; margin-top: -30%; }

.gttr__text > h2:first-child { margin-top: 0; }
.gttr__more { margin: var(--s4) 0 0; }
.gttr__more a { font-weight: 600; }

/* The age or year band under a subject heading on /subjects: a label for the
   description that follows, not a sentence in its own right. */
.note-span { margin: calc(var(--s2) * -1) 0 var(--s2); color: var(--ink-tertiary);
  font-size: var(--text-caption); font-weight: 600; }

/* A price. The figure carries the weight and the period is the quiet half, so
   "10 a month" reads as one thing rather than two. */

/* --- the flag under the mark ----------------------------------------------- */
/* A small flying Union Jack tucked under the logo's bottom right corner, so a
   visitor can tell at a glance this is the UK site and not the Australian one
   (Esther, 22 October 2026). Decorative: the brand link is already named "Alto
   Guru, home", so the flag carries alt="" and says nothing a second time.
   `.nav .brand img` sets height 32px on every image in the brand, so the width
   here has to beat it, and the height goes back to auto. */
.nav .brand { position: relative; }
.nav .brand .brand__flag {
  /* Off the top left corner of the mark and tilted, so it reads as a flag
     flying from the A rather than a sticker laid on top (Esther, 22 October
     2026). It leans out to the left only as far as the nav's own gutter
     allows, so it is never cut off at the edge of a phone.

     It is inside the brand link and takes pointer events, so pressing the
     flag goes home like pressing the mark does. It was pointer-events: none,
     which left a piece of the mark that looked pressable and was not. */
  /* 30% closer to the mark than it was (Esther, 23 October 2026): the
     offsets are the gap, so each is 70% of what it was, -0.24 and -0.44. */
  position: absolute; left: -0.17rem; top: -0.31rem;
  width: 20px; height: auto;
  /* -26deg, not -16: the left edge was already the lower one, so dropping it
     a further 10 degrees steepens the same lean rather than reversing it
     (Esther, 22 October 2026). The offsets came in by a fifth in the same
     breath, which is what pulls it against the A. */
  transform: rotate(-26deg);
  transform-origin: left bottom;
}
@media (max-width: 40rem) {
  .nav .brand .brand__flag { width: 17px; left: -0.11rem; top: -0.25rem; }
}

/* --- a link that reads as a pill ------------------------------------------- */
/* The way out of a phase card on /subjects. The flag before the words is the
   bullet: it says which curriculum without spending a word on it, and it is
   the flat flag rather than the flying one, because at this size the wave
   would be mud. Decorative, so it is a background rather than an <img>, and a
   screen reader hears only the link's words. */
.pill-link {
  display: inline-flex;
  align-items: center;
  /* Never wraps. It shrinks instead (Esther, 22 October 2026), which is only
     safe because the size is tied to the card rather than guessed: cqi is a
     percentage of the card's own width, so the pill gets smaller exactly when
     the card does, and nowrap can never push it out of a box too small for it.
     The subtracted pixels are the parts that do not scale, the padding, the
     gap and the border. Lower bound 11px so it stays readable; upper bound the
     18% step, so it never grows past what was asked for. */
  white-space: nowrap;
  gap: 0.45rem;
  padding: 0.34rem 0.8rem 0.34rem 0.58rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--surface);
  color: var(--aqua-deep);
  /* 18% over the caption size (Esther, 22 October 2026), as the ceiling. */
  font-size: calc(var(--text-caption) * 1.18);
  font-size: clamp(10px, calc(6.35cqi - 4.3px), calc(var(--text-caption) * 1.18));
  font-weight: 600;
  text-decoration: none;
}
.pill-link::before {
  content: "";
  flex: none;
  width: 1.2em;
  height: 0.6em;
  border-radius: 1px;
  background: url(/m/union-jack.svg) center / contain no-repeat;
}
.pill-link:hover {
  border-color: var(--rule-strong);
  background: var(--aqua-wash);
  color: var(--aqua-deep-hover);
}
.pill-link:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* --- /schools, ported from the Australian For Schools page ----------------- */
/* Same structure and the same tokens, which is why this is short: the two
   stylesheets were already 37 colours out of 38 in common. Only --teal differs,
   and it is this site's --aqua-deep. */

/* The hero: words beside the photograph once there is room, stacked below it
   where there is not. */
/* The hero band closes up underneath, so the claims sit low in the section
   rather than floating in the middle of it (Esther, 22 October 2026). They had
   32px above and 85px below; the band's own bottom padding was most of that
   85. The next band brings its own top padding, so the two do not touch. */
.hero-band-schools { padding-bottom: var(--s6); }

.hero-split { display: grid; gap: var(--s6); margin: 0 0 var(--s5); }
@media (min-width: 52rem) {
  .hero-split { grid-template-columns: 1.05fr 0.95fr; align-items: center; gap: var(--s7); }
}
.hero-split__media { margin: 0; }

/* The three claims run under the hero, across both the words and the picture
   (Esther, 22 October 2026). Each pill is the width of its own words, so a
   short claim gets a short pill, with the same gap between every pair. They
   were equal thirds first, which gave "Developed in Australia" the same box
   as a claim three times its length.

   Nothing wraps inside a pill. They wrap as a group instead, falling to a
   second and third row as the screen narrows. */
.pills--spread {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  /* Wider than the usual pill gap, so three claims across a full-width row
     read as three things rather than one run-on strip (Esther, 22 October
     2026). */
  gap: var(--s5);
  margin: var(--s7) 0 0;
}
/* One line each, which the longest claim cannot manage on a phone at the
   normal pill size: at 375px it measured 385px wide inside a 335px row and
   hung out of it. So the type comes down with the screen instead, and the
   pill still holds its line. Below 23rem even that is not enough at a size
   anyone would read, so there it wraps rather than running off the edge:
   overflow is worse than two lines. */
.pills--spread li {
  white-space: nowrap;
  font-size: clamp(10.5px, 2.9vw, var(--text-caption));
}
@media (max-width: 23rem) {
  .pills--spread li { white-space: normal; }
}
.hero-split__media img {
  display: block; width: 100%; height: auto;
  border-radius: var(--radius-card); border: 1px solid var(--rule);
}

/* The two doors into the page, above everything else. */
.entry-cards { display: grid; gap: var(--s4); margin: 0 0 var(--s4); }
@media (min-width: 40rem) { .entry-cards { grid-template-columns: 1fr 1fr; } }
.entry-card {
  display: block; padding: var(--s4) var(--s5);
  background: var(--surface);
  border: var(--border-card) solid var(--rule-brand);
  border-radius: var(--radius-card);
  text-decoration: none; color: inherit;
}
.entry-card:hover { border-color: var(--aqua-deep); }
.entry-card strong { display: block; color: var(--aqua-deep); margin-bottom: 0.1rem; }
.entry-card span { display: block; color: var(--ink-secondary); font-size: var(--text-small); }

/* The level, with the number carrying the weight. */
.level {
  background: var(--surface);
  border: var(--border-card) solid var(--rule-brand);
  border-left: 4px solid var(--aqua-deep);
  border-radius: var(--radius-card);
  padding: var(--s5);
  margin: var(--s4) 0;
  /* Narrow, like the Australian page's compact variant. Full band width makes
     it read as another section rather than an aside about one number. */
  max-width: calc(var(--measure) + 2 * var(--s5));
}
.level h3 { margin: 0 0 var(--s2); }
.level__number {
  font-family: var(--font-heading);
  font-size: clamp(2rem, 1.6rem + 1.4vw, 2.6rem);
  font-weight: 700; line-height: 1; letter-spacing: -0.03em;
  color: var(--aqua-deep);
  margin: 0 0 var(--s3);
}
.level p { max-width: none; }

/* Four ways teachers use it. Two up on a tablet, four across when there is
   room, so the cards stay a readable width rather than four thin columns. */
.grid-4 { display: grid; gap: var(--s4); margin: var(--s4) 0 0; }
@media (min-width: 40rem) { .grid-4 { grid-template-columns: 1fr 1fr; } }
@media (min-width: 64rem) { .grid-4 { grid-template-columns: repeat(4, 1fr); } }
.use-card {
  background: var(--surface-sunken);
  border-radius: var(--radius-card);
  padding: var(--s4);
}
.use-card h3 { margin: 0 0 var(--s2); font-size: var(--text-body-lg); }
.use-card p { margin: 0 0 var(--s2); color: var(--ink-secondary); font-size: var(--text-small); max-width: none; }
.use-card p:last-child { margin: 0; }

/* What teachers say. The aqua rule down the left is the site's borrowed-words
   treatment, the same one the Ofsted panel uses on the home page. */
figure.quote { margin: var(--s5) 0; max-width: var(--measure-wide); }
figure.quote blockquote {
  margin: 0 0 var(--s4); padding-left: var(--s5);
  border-left: 3px solid var(--aqua);
  font-size: var(--text-body-lg); line-height: 1.5; color: var(--ink);
}
figure.quote figcaption {
  padding-left: calc(var(--s5) + 3px);
  font-size: var(--text-small); color: var(--ink-secondary);
}
figure.quote .quote-role { display: block; font-weight: 650; color: var(--ink); }

/* The Race, with its own picture beside it. */
/* The Race, in a box of its own with the picture small and tucked into the top
   right corner (Esther, 22 October 2026). Floated rather than placed in a
   column, so the words close under it instead of leaving a tall empty gap
   beside a small picture. flow-root keeps the float inside the box. */
.race-box {
  display: flow-root;
  background: var(--surface);
  border: var(--border-card) solid var(--rule-brand);
  border-radius: var(--radius-card);
  padding: var(--s5);
}
.race-box__art { float: right; width: 9rem; margin: 0 0 var(--s4) var(--s5); }
.race-box__art img { display: block; width: 100%; height: auto; }
.race-box h2 { margin-top: 0; }
@media (max-width: 34rem) {
  .race-box__art { float: none; width: 7.5rem; margin: 0 0 var(--s3); }
}

/* Get started: the two scales, side by side. */
/* The two routes in, at the top of the page and again at the foot. Both are
   the Australian page's door: a white card whose words grow to fill it so the
   button sits on the floor of the card, the same height in both columns
   (Esther, 22 October 2026, asking for the top to match the bottom). */
.door-grid { display: grid; gap: var(--s5); margin: var(--s4) 0 0; }
@media (min-width: 40rem) { .door-grid { grid-template-columns: 1fr 1fr; } }
.door {
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-card);
  padding: var(--s5);
}
.door h3 { margin: 0 0 var(--s3); font-size: var(--text-body-lg); }
.door p { margin: 0 0 var(--s4); color: var(--ink-secondary); max-width: none; flex-grow: 1; }
.door .door-sub { font-size: var(--text-small); color: var(--ink-tertiary); flex-grow: 0; }
/* Centred on the floor of the card, not stretched across it (Esther,
   22 October 2026). The paragraph above grows, which is what puts the button
   on the floor; align-self centres it there. All four doors, top and bottom. */
.door .btn { align-self: center; text-align: center; }

.note-ask { color: var(--ink-secondary); font-size: var(--text-small); margin: var(--s5) 0 0; }

/* The sections on /schools are bands, not cards. The first attempt boxed every
   section in a bordered card, which is not what the Australian page does: its
   headings and prose sit straight on alternating full-width bands, and only
   the use-case tiles and the two doors are cards. The bands already carry
   --content-max, so the page needs no width of its own. */

/* A list whose marker is a drawn tick rather than a disc: two borders on a
   square, rotated. The same mark the Australian page uses. */
.fact-list { list-style: none; padding: 0; margin: var(--s4) 0; max-width: var(--measure-wide);
  display: grid; gap: var(--s3); }
.fact-list li { position: relative; margin: 0; padding-left: 1.9rem; color: var(--ink-secondary); }
.fact-list li::before {
  content: ""; position: absolute; left: 0; top: 0.45em;
  width: 0.75rem; height: 0.4rem;
  border-left: 2.5px solid var(--aqua-deep);
  border-bottom: 2.5px solid var(--aqua-deep);
  transform: rotate(-45deg);
}

/* The small line drawing at the top of each use-case tile. */
.usage-icon { width: auto; height: 1.75rem; color: var(--aqua-deep);
  margin: 0 0 var(--s3); display: block; }

.grid { display: grid; gap: var(--s4); }
@media (min-width: 40rem) { .grid--4 { grid-template-columns: 1fr 1fr; } }
/* Four across only when each tile is still wide enough to read. The Australian
   page has three, which fit at 64rem; a fourth at that width gives columns too
   narrow for the words, so these stay two by two until 78rem. */
@media (min-width: 78rem) { .grid--4 { grid-template-columns: repeat(4, 1fr); } }

/* The caveat inside the level box, set quieter than the claim above it. */
.level__note { background: var(--surface-sunken); border-radius: 10px;
  padding: var(--s3) var(--s4); color: var(--ink-secondary);
  font-size: var(--text-small); margin: var(--s3) 0 0; }
.muted { color: var(--ink-secondary); font-size: var(--text-small); }

/* --- a picture that is not taken yet --------------------------------------- */
/* The Australian site's own placeholder, kept rather than invented: a dashed
   box carrying the id the picture will be filed under, one sentence saying
   what it shows, and what the shot needs. It is deliberately visible. A blank
   space says nothing; this says a picture is owed and what of. Delete the
   figure when the real image lands. */
.shot-slot { margin: var(--s5) 0; max-width: var(--measure-wide); }
/* .shot-slot held only placeholders until /how-alto-works put a real picture
   in one. An unconstrained 1000px image overflowed a 735px window sideways. */
.shot-slot img { display: block; width: 100%; height: auto; border-radius: var(--radius-card); }

/* The class dashboard picture sits in line with the bullets it illustrates,
   taking two fifths of the row, rather than running the full width below them
   (Esther, 22 October 2026). Stacked below 52rem, where two columns would
   leave both too narrow to read. */
.dash-split { display: grid; gap: var(--s5); align-items: start; }
@media (min-width: 52rem) { .dash-split { grid-template-columns: 3fr 2fr; gap: var(--s6); } }
.dash-split .fact-list { margin: 0; }
.shot-slot--beside { margin: 0; max-width: none; }
.image-slot {
  aspect-ratio: var(--ratio, 16 / 10);
  width: 100%;
  border: 1px dashed var(--rule-strong);
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, var(--surface-sunken), var(--cream));
  display: grid; align-content: center; justify-items: start;
  gap: var(--s2); padding: var(--s5);
}
.ph-kind {
  display: inline-block; margin-right: var(--s2);
  padding: 0.1rem 0.4rem; border-radius: 3px;
  background: var(--coral-action); color: #ffffff;
  font-size: var(--text-caption); font-weight: 700; letter-spacing: 0.04em;
}
.ph-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-caption); color: var(--ink-tertiary);
}
.ph-sentence { display: block; max-width: var(--measure);
  font-size: var(--text-small); line-height: 1.4; color: var(--ink); }
.ph-need { display: block; font-size: var(--text-caption); color: var(--ink-secondary); }

/* --- the teacher pathway page ---------------------------------------------- */
/* The Australian page's three steps are an ordered list with a number in a
   circle beside each heading. The home page's steps already draw exactly that
   (.step, with the number as a CSS counter), so this borrows them rather than
   inventing a second numbered step. What it does not borrow is .steps-three:
   that lays four rows of subgrid for a heading, two paragraphs and a picture,
   and these steps have no picture, so its empty rows would open a --s6 gap
   under every one. */
.stepper {
  list-style: none;
  padding: 0;
  margin: var(--s5) 0 0;
  display: grid;
  gap: var(--s6);
  counter-reset: step;
}
/* Three across sooner than the home page's steps, which hold off until 62rem
   because each carries a picture. These are a heading and a short paragraph,
   so they read fine in a third of a 52rem band, and a laptop at 960px gets
   the three-up layout the Australian page has rather than a stack. */
@media (min-width: 52rem) {
  .stepper { grid-template-columns: repeat(3, 1fr); gap: var(--s5); }
}
.stepper .step > p:last-child { margin: 0; }

/* "Pass this on". The Australian block has three controls: Share, Copy link
   and Email this page. The first two are JavaScript (navigator.share and the
   clipboard) and this site has none, so the row keeps the one that is a plain
   link and the address is printed below it to be copied by hand. A button that
   did nothing would be worse than no button. */
.share-block {
  background: var(--surface);
  border: var(--border-card) solid var(--rule-brand);
  border-radius: var(--radius-card);
  padding: var(--s5);
}
.share-block h2 { margin-top: 0; }
.share-row { display: flex; flex-wrap: wrap; gap: var(--s3); margin: var(--s4) 0 0; }
.share-url { margin: var(--s4) 0 0; }
.share-url code {
  display: inline-block;
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  background: var(--surface-sunken);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-small);
  color: var(--ink-secondary);
  word-break: break-all;
}

/* The state marker stays inline wherever it labels a heading, a paragraph or a
   question. `.page .soon` sets `margin: 0 0 var(--s5)` for the block marker
   that stands on its own line under an h1; inherited by an inline one it drops
   the gap before the words and opens a --s5 hole after them.

   The child combinator is what keeps the two apart: the block form is a `<p
   class="soon">`, the element itself, so `p > .soon` never matches it. `dd` is
   left out on purpose, because /curriculum's markers sit in one and have their
   own rule. */
.page h1 > .soon,
.page h2 > .soon,
.page h3 > .soon,
.page p > .soon,
.page summary > .soon { margin: 0 0 0 var(--s2); }

/* --- the school leaders page ----------------------------------------------- */
/* Five stages rather than three. The Australian page sets five across and
   stacks them on anything narrower; five columns of our 72rem band are about
   200px each, which only works on a wide screen, so this waits until 78rem,
   the same width .grid--4 waits for. Below that it is one column, which is a
   fair way to read a five-step sequence anyway. The base .stepper goes to
   three columns at 52rem, so that has to be undone first. */
@media (min-width: 52rem) {
  .stepper--five { grid-template-columns: 1fr; gap: var(--s5); }
}
@media (min-width: 78rem) {
  .stepper--five { grid-template-columns: repeat(5, 1fr); gap: var(--s5); }
}

/* The line above the closing band's heading. Serif, like the Australian one,
   and quiet: it is a refrain, not a heading, and it must not compete with the
   h2 underneath it. */
.tagline {
  margin: 0 0 var(--s3);
  font-family: var(--font-heading);
  font-size: var(--text-body-lg);
  font-weight: 650;
  color: var(--ink-secondary);
}

/* "Have a question first?", under a rule inside the closing band. */
.enquiry-question {
  margin: var(--s6) 0 0;
  padding: var(--s5) 0 0;
  border-top: 1px solid var(--rule);
}
.enquiry-question h3 { margin: 0 0 var(--s3); font-size: var(--text-body-lg); }
.enquiry-question p:last-child { margin-bottom: 0; }

/* A quote we do not have yet. The same dashed box as a missing picture, since
   it says the same thing: something is owed here and this is what of. It has
   no aspect ratio, because words are as tall as they are. Never filled with
   an invented testimonial; see LAUNCH.md. */
.quote-slot {
  margin: var(--s5) 0;
  max-width: var(--measure-wide);
  border: 1px dashed var(--rule-strong);
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, var(--surface-sunken), var(--cream));
  display: grid;
  gap: var(--s2);
  justify-items: start;
  padding: var(--s5);
}

/* --- the families page ------------------------------------------------------ */
/* The four facts under the hero. The Australian page sets them in a white
   strip ruled top and bottom, in ordinary ink at body size rather than as
   pills: they are statements, and pills are already doing other work on
   /schools. Four across when there is room, two up on a tablet, one on a
   phone. */
.proof-bar {
  margin-inline: calc(50% - 50vw);
  padding: var(--s5) max(var(--gutter), calc(50vw - (var(--content-max) / 2)));
  background: var(--surface);
  border-block: 1px solid var(--rule);
}
.proof-bar ul {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--s4);
}
.proof-bar li { font-weight: 650; color: var(--ink); }
@media (min-width: 40rem) { .proof-bar ul { grid-template-columns: 1fr 1fr; } }
@media (min-width: 64rem) { .proof-bar ul { grid-template-columns: repeat(4, 1fr); } }

/* Words beside a picture or a drawing, in roughly equal halves. The schools
   pages' .dash-split gives the picture two fifths, which is right for a wide
   screenshot sitting beside a list; here the pictures are near square and the
   Australian page splits them evenly, so this is its own rule rather than a
   variant of that one. */
.showcase { display: grid; gap: var(--s5); align-items: center; }
@media (min-width: 52rem) {
  .showcase { grid-template-columns: 1fr 1fr; gap: var(--s6); }
  /* The picture first on the page, the words first in the source, so the
     reading order is unchanged for a screen reader and for a phone. */
  .showcase--reverse > :first-child { order: 2; }
}
.showcase__media { margin: 0; }
.showcase__media img {
  display: block; width: 100%; height: auto;
  border-radius: var(--radius-card);
}

/* A drawing rather than a photograph: the two line marks borrowed from the
   Australian page. Sunken ground so a line drawing on white does not float,
   and the same card radius as a picture would have. */
.inline-mark {
  background: var(--surface-sunken);
  border-radius: var(--radius-card);
  padding: var(--s5);
}
.inline-mark svg { display: block; width: 100%; height: auto; }

/* The note about whose curriculum the maths is built for. Tinted rather than
   boxed, so it reads as an aside to the prices above it. */
.curriculum-note {
  background: var(--aqua-wash);
  border-radius: 12px;
  padding: var(--s4) var(--s5);
  margin: var(--s5) 0;
  max-width: none;
}

/* "If your child already uses Alto at school", with the link mark beside it. */
.school-access {
  display: grid; gap: var(--s5);
  background: var(--surface);
  border: var(--border-card) solid var(--rule-brand);
  border-radius: var(--radius-card);
  padding: var(--s5);
  margin: var(--s6) 0;
}
@media (min-width: 52rem) {
  .school-access { grid-template-columns: 1.4fr 1fr; align-items: center; gap: var(--s6); }
}
.school-access h3 { margin: 0 0 var(--s3); }
.school-access p { max-width: none; }
.school-access__mark .inline-mark { background: var(--aqua-wash); }

/* --- pricing, the agreed figures (Esther, 23 October 2026) ------------------ */
/* Three boxes down the page rather than two side by side: Families, then
   Schools, then Partnerships (Esther, 23 October 2026). The full width lets
   the three family plans sit across the Families box as a proper price table
   instead of being squeezed into a column. */
.pricing-grid { display: grid; gap: var(--s5); margin: var(--s6) 0 0; }
.pricing-card { margin: 0; }
.pricing-card h2 { margin-top: 0; }
.pricing-card h3 { margin: var(--s5) 0 var(--s2); font-size: var(--text-body-lg); }
.pricing-card p { max-width: none; }
/* Schools is prose, so it keeps the reading measure inside its full-width box.
   A line of text running the whole 72rem is not readable. */
.pricing-card--schools p { max-width: var(--measure-wide); }

/* The three plans, across the box on a desktop and stacked on a phone. */
.plans {
  display: grid; gap: var(--s4);
  margin: var(--s5) 0;
}
@media (min-width: 52rem) {
  /* No align-items: start here. Boxes that sit side by side finish level
     with each other (Esther, 23 October 2026); the grid stretches them and
     .plan__what grows inside each one to fill the difference. */
  .plans { grid-template-columns: repeat(3, 1fr); gap: var(--s5); }
}
/* On /families the plans sit one above another rather than across (Esther,
   23 October 2026). That page is a column of bands carrying a lot of prose,
   and three price boxes in a row there read as a second, competing page. The
   dedicated /pricing page keeps them across, where they are the point. */
.plans--stacked { grid-template-columns: 1fr !important; }
@media (min-width: 52rem) {
  .plans--stacked { max-width: var(--measure-wide); }
}
.plan {
  display: flex; flex-direction: column;
  padding: var(--s5);
  background: var(--surface-sunken);
  border-radius: var(--radius-card);
}
.plan h3 { margin: 0 0 var(--s2); font-size: var(--text-body-lg); }
.plan__price {
  margin: 0; white-space: nowrap;
  font-family: var(--font-heading);
  font-size: clamp(1.6rem, 1.2rem + 1.4vw, 2.1rem);
  font-weight: 700; line-height: 1; letter-spacing: -0.02em;
  color: var(--ink);
}
.plan__price span {
  font-family: var(--font-body); font-weight: 600;
  font-size: var(--text-small); letter-spacing: 0;
  color: var(--ink-secondary);
}
.plan__alt {
  margin: var(--s2) 0 0;
  font-size: var(--text-small); color: var(--ink-secondary);
}
.plan__who { margin: var(--s4) 0 0; font-weight: 650; }
/* The last line grows, so the boxes finish level whatever the words do. */
.plan__what {
  flex-grow: 1;
  margin: var(--s2) 0 0;
  font-size: var(--text-small); color: var(--ink-secondary);
}
/* The Family plan carries a little more weight: a tinted ground and the brand
   edge. Not coral, which means you can click it, and no "most popular" flash. */
.plan--feature {
  background: var(--aqua-wash);
  border-left: 3px solid var(--aqua-deep);
}

/* The partnerships box. Its own box, as Esther asked, but the quietest of the
   three: it sits under the prices and must not compete with them. */
.partnerships-card {
  margin: 0;
  background: var(--surface-sunken);
  border: 1px solid var(--rule);
  padding: var(--s4) var(--s5);
}
.partnerships-card h2 {
  margin: 0 0 var(--s2);
  font-size: var(--text-body-lg);
  color: var(--ink-secondary);
}
.partnerships-card p {
  margin: 0; max-width: var(--measure-wide);
  font-size: var(--text-small); color: var(--ink-secondary);
}

/* --- how Alto works --------------------------------------------------------- */
/* The reasoning block on its sunken band: prose at the reading measure, then
   the one sentence it is all for, set larger and in the heading face so it
   lands as a conclusion rather than another paragraph. */
.reasoning { max-width: var(--measure-wide); }
.reasoning h2 { margin-top: 0; }
.statement {
  margin: var(--s5) 0 0;
  padding-left: var(--s5);
  border-left: 3px solid var(--aqua);
  max-width: var(--measure-wide);
  font-family: var(--font-heading);
  font-size: var(--text-body-lg);
  font-weight: 650;
  line-height: 1.45;
  color: var(--ink);
}

/* Two or three onward links in a row, each with its own arrow. They wrap to
   their own lines on a phone rather than running together. */
.more-links {
  display: flex; flex-wrap: wrap;
  gap: var(--s3) var(--s6);
  margin: var(--s6) 0 0;
  max-width: none;
}
.more-links a { font-weight: 650; }

/* The walkthrough, with its caption under it. */
.video-block { margin: var(--s5) 0 0; max-width: var(--measure-wide); }
.video-block figcaption {
  margin: var(--s3) 0 0;
  font-size: var(--text-small);
  color: var(--ink-secondary);
}
