/* Life in the UK Test 2026 - marketing and legal pages.

   The palette, the type and the shapes come out of LiUKPrep/DesignSystem.swift
   so the page a customer lands on looks like the thing they came from. Nothing
   is fetched from a third party: no web fonts, no CDN, no analytics. The
   display face is the system sans, rounded and bold — the app dropped New York
   for exactly that, and this page followed it rather than keeping a serif the
   product no longer sets a word in.

   The page is set like printed matter rather than a stack of cards. Hairlines
   and columns carry the structure; a surface is used only where the app itself
   uses one, which is the Premium tier and the specimen question.

   Three rules, followed everywhere:
   - Colour: ink navy is the only interactive accent. Brass appears only where
     the app uses it, which is Premium. Green appears only on the mark scale,
     which is the one place the app uses it too. The five chapter colours are
     content, not decoration: they arrive from Content.json and appear once, in
     the syllabus index, tinting the same drawn glyphs the app puts on a
     chapter card and by the same rule.
   - Shape: buttons 18px, surfaces 22px, phone frames 34px, which are the app's
     own radii. Nothing else is rounded.
   - Motion: transform and opacity only, and none of it if the reader has asked
     for less. */

/* ---------- Tokens ----------
   Every value here is the app's own, from Palette in DesignSystem.swift, so a
   colour is changed in one place and the site cannot drift from the product it
   is selling. The site used to run a warm paper palette against the app's cool
   navy one; they are one palette now.

   Two values are the site's alone, and both are additions rather than
   departures. --rule is a divider a shade stronger than --hairline, because a
   web page sets sections apart with a line where the app uses a card edge.
   --brass-strong is the app's gold darkened until small text on it clears AA:
   the gold sits on large numerals and card edges in the app, and the site asks
   it to carry an 11px capsule as well. */

:root {
  --canvas: #f1f3f6;        /* Palette.canvas */
  --surface: #ffffff;       /* Palette.surface */
  --sunken: #e7ebf1;        /* Palette.surfaceSunken */
  --ink: #0f1b2d;           /* Palette.ink */
  --ink-soft: #5a6678;      /* Palette.inkSoft */
  --hairline: #dfe4eb;      /* Palette.hairline */
  --rule: #c7cfda;
  --accent: #0a2e6e;        /* Palette.accent */
  --accent-soft: #e4ebf7;   /* Palette.accentSoft */
  --accent-deep: #061e4a;   /* Palette.accentDeep */
  --accent-ink: #ffffff;    /* Palette.onFill */
  --brass: #a07500;         /* Palette.premium */
  --brass-strong: #8a6400;
  --brass-edge: color-mix(in srgb, var(--brass) 38%, transparent);
  --pass: #00693e;          /* Palette.success */
  --pass-soft: #e0f0e8;     /* Palette.successSoft */
  --hero-top: #0a2e6e;      /* Palette.heroTop */
  --hero-bottom: #061e4a;   /* Palette.heroBottom */
  --on-hero: #ffffff;       /* Palette.onHero */

  /* Palette.shadow is black at 6%, thrown 14/5 under a card. */
  --shadow: 0 1px 2px rgba(15, 27, 45, 0.05), 0 5px 14px rgba(15, 27, 45, 0.06);

  /* The app's corner radii: 22 on a card, 18 on a button. */
  --r-button: 18px;
  --r-surface: 22px;
  --r-phone: 34px;

  /* The app's display face is the system sans, rounded and bold — it dropped
     New York for exactly this, so the site does not get to keep the serif. */
  --display: ui-rounded, "SF Pro Rounded", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --gutter: 24px;
  --page: 1120px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --canvas: #0b0f16;
    --surface: #151a22;
    --sunken: #10151c;
    --ink: #f2f4f7;
    --ink-soft: #98a2b3;
    --hairline: #232b36;
    --rule: #313a47;
    --accent: #8fb4f5;
    --accent-soft: #132139;
    --accent-deep: #0b1832;
    --accent-ink: #0b0f16;
    --brass: #d9ac61;
    --brass-strong: #d9ac61;
    --brass-edge: color-mix(in srgb, var(--brass) 34%, transparent);
    --pass: #57c79a;
    --pass-soft: #0d2a1e;
    --hero-top: #0c2350;
    --hero-bottom: #071734;
    /* Palette.shadow resolves to nothing on the dark canvas; the hairline on
       each card does the separating instead. */
    --shadow: 0 0 0 1px var(--hairline);
  }
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font: 17px/1.65 var(--sans);
  font-synthesis-weight: none;
}

img { max-width: 100%; height: auto; display: block; }

a { color: var(--accent); text-underline-offset: 3px; }
a:hover { text-decoration-thickness: 2px; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

button { font: inherit; color: inherit; }

/* ---------- Layout ---------- */

.wrap { width: 100%; max-width: var(--page); margin-inline: auto; padding-inline: var(--gutter); }

.section { padding-block: 76px; }
.section-tight { padding-block: 56px; }
.section-sunken { background: var(--sunken); border-block: 1px solid var(--hairline); }

@media (min-width: 768px) {
  .section { padding-block: 112px; }
  .section-tight { padding-block: 72px; }
}

/* ---------- Type ---------- */

h1, h2, h3 { font-family: var(--display); font-weight: 700; margin: 0; letter-spacing: -0.015em; }

/* Sized against the hero column it has to fit in, not against the viewport:
   at 66px the headline broke to three lines in a half-width column, which is a
   font-size error rather than a copy-length one. */
h1 {
  font-size: clamp(38px, 4.4vw, 56px);
  line-height: 1.06;
  letter-spacing: -0.02em;
  font-weight: 700;
}

h2 {
  font-size: clamp(28px, 3.5vw, 40px);
  line-height: 1.12;
  letter-spacing: -0.015em;
}

h3 { font-size: 19px; line-height: 1.3; }

p { margin: 0; }

.lede { font-size: clamp(18px, 1.55vw, 20px); line-height: 1.55; color: var(--ink-soft); max-width: 44ch; }
.body { color: var(--ink-soft); max-width: 58ch; }
.stack > * + * { margin-top: 18px; }

/* The only small-caps label on the page, used twice. */
.label {
  font: 600 12px/1 var(--sans);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  min-height: 50px;
  padding: 0 26px;
  border-radius: var(--r-button);
  font: 600 16px/1 var(--sans);
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.18s, border-color 0.18s;
}

.btn-primary { background: var(--accent); color: var(--accent-ink); }
.btn-primary:hover { background: color-mix(in srgb, var(--accent) 86%, var(--ink)); }
.btn-primary:active { transform: translateY(1px); }

/* The outline is what makes this read as a control, so it is drawn in the
   accent rather than in a hairline grey: --rule against the canvas is 1.5:1,
   under the 3:1 that a control boundary needs. */
.btn-quiet {
  background: transparent;
  color: var(--accent);
  border-color: var(--accent);
}
.btn-quiet:hover { background: var(--accent-soft); }
.btn-quiet:active { transform: translateY(1px); }

@media (prefers-reduced-motion: reduce) {
  .btn { transition: none; }
  .btn:active { transform: none; }
}

/* ---------- Masthead ---------- */

.masthead {
  position: sticky;
  top: 0;
  z-index: 20;
  height: 68px;
  display: flex;
  align-items: center;
  background: color-mix(in srgb, var(--canvas) 86%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--hairline);
}

@supports not (backdrop-filter: blur(1px)) { .masthead { background: var(--canvas); } }

.masthead .wrap { display: flex; align-items: center; justify-content: space-between; gap: 16px; }

.mark {
  display: flex;
  align-items: center;
  gap: 11px;
  text-decoration: none;
  color: var(--ink);
  font-family: var(--display);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.mark img { width: 30px; height: 30px; border-radius: 7px; }

/* Hit areas are padded to 44px without changing what is drawn, so a thumb has
   something to land on even though the labels are only 25px tall. */
.mark { min-height: 44px; }

.masthead nav { display: flex; align-items: center; gap: 22px; font-size: 15px; }
.masthead nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--ink-soft);
  text-decoration: none;
  white-space: nowrap;
}
.masthead nav a:hover { color: var(--ink); }

@media (max-width: 620px) {
  .mark span { display: none; }
  .masthead nav { gap: 18px; }
}

/* Four labels plus the wordmark stop fitting on one line well before the
   smallest phone, and a nav that wraps to two lines is broken. The two
   anchors go first: they are shortcuts to content the reader will scroll
   past anyway, while Support is the one thing they may have come for. */
@media (max-width: 470px) {
  .masthead nav a[href="#syllabus"], .masthead nav a[href="#pricing"] { display: none; }
}

/* ---------- Phone frame ---------- */

.phone {
  border-radius: var(--r-phone);
  border: 1px solid var(--hairline);
  background: var(--surface);
  padding: 6px;
  box-shadow: var(--shadow);
  width: fit-content;
}
.phone img { border-radius: calc(var(--r-phone) - 7px); }

/* ---------- Hero ---------- */

.hero { padding-top: 52px; padding-bottom: 60px; }

@media (min-width: 940px) {
  .hero { padding-top: 84px; padding-bottom: 88px; }
  .hero .wrap {
    display: grid;
    grid-template-columns: 1.06fr 0.94fr;
    gap: 60px;
    align-items: center;
  }
}

.hero-copy { display: flex; flex-direction: column; align-items: flex-start; gap: 22px; }
/* Wide enough to hold the headline to two lines at every width it is set at.
   Narrower and it breaks to three, which is a font-size error, not a copy
   length one. */
.hero-copy h1 { max-width: 15ch; }
.hero-copy .label + h1 { margin-top: -4px; }

.hero-art { margin-top: 44px; display: flex; justify-content: center; }
.hero-art .phone img { max-height: min(58vh, 570px); width: auto; }

@media (min-width: 940px) { .hero-art { margin-top: 0; justify-content: flex-end; } }

/* ---------- The paper: exam format strip ---------- */

.paper {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.paper div { padding: 20px 4px; }
.paper div:nth-child(n+3) { border-top: 1px solid var(--hairline); }
.paper div:nth-child(even) { border-left: 1px solid var(--hairline); padding-left: 20px; }

@media (min-width: 720px) {
  .paper { grid-template-columns: repeat(4, 1fr); }
  .paper div { padding: 22px 4px; }
  .paper div:nth-child(n+3) { border-top: 0; }
  .paper div + div { border-left: 1px solid var(--hairline); padding-left: 24px; }
}

.paper b {
  display: block;
  font-family: var(--display);
  font-size: 27px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
}
.paper span { display: block; margin-top: 7px; font-size: 14px; color: var(--ink-soft); }

/* ---------- Specimen question ----------
   The product, working, rather than described. The questions are the app's
   own, pulled from the same bundle it ships. */

/* Stacked, not a headline on the left with a small paragraph floating off to
   the right. One message, read top to bottom. */
.specimen-head h2 { max-width: 16ch; }
.specimen-head .body { margin-top: 14px; max-width: 52ch; }

/* Card on the left, and the app's own drawn guard standing beside it at
   desktop, which is where the card would otherwise leave a hole. Decorative,
   so it is hidden from assistive technology and dropped on narrow screens
   rather than pushed above the question. */
.specimen-row { display: grid; gap: 36px; margin-top: 36px; align-items: end; }

@media (min-width: 1000px) {
  .specimen-row { grid-template-columns: minmax(0, 760px) 1fr; gap: 48px; }
}

.specimen {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-surface);
  padding: 28px 24px;
}

@media (min-width: 720px) { .specimen { padding: 36px 40px; } }

.specimen-art { display: none; }

@media (min-width: 1000px) {
  .specimen-art { display: flex; justify-content: center; align-items: flex-end; }
  .specimen-art img { height: 300px; width: auto; }
}

.specimen-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--hairline);
  font: 500 13px/1 var(--sans);
  color: var(--ink-soft);
}
.specimen-meta .counter { font-family: var(--mono); font-variant-numeric: tabular-nums; }

.specimen-q {
  font-family: var(--display);
  font-size: clamp(21px, 2.2vw, 27px);
  font-weight: 700;
  line-height: 1.28;
  letter-spacing: -0.01em;
  margin: 24px 0 22px;
}

.options { display: grid; gap: 10px; }

.option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  width: 100%;
  min-height: 56px;
  padding: 12px 18px;
  text-align: left;
  background: var(--canvas);
  border: 1px solid var(--hairline);
  border-radius: var(--r-button);
  cursor: pointer;
  font-size: 16px;
  transition: border-color 0.18s, background-color 0.18s;
}
.option:hover:not(:disabled) { border-color: var(--accent); }
.option:disabled { cursor: default; }

/* State is never carried by colour alone: every marked option also gets a
   word. */
.option .verdict { font: 600 12px/1 var(--sans); letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap; }
.option-right { border-color: var(--pass); background: var(--pass-soft); }
.option-right .verdict { color: var(--pass); }
.option-wrong { border-color: var(--rule); }
.option-wrong .verdict { color: var(--ink-soft); }
.option-dim { opacity: 0.65; }

.explain {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--hairline);
  color: var(--ink-soft);
  font-size: 16px;
  line-height: 1.6;
}
.explain p { margin-bottom: 18px; }
.explain[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) { .option { transition: none; } }

/* ---------- Syllabus index ---------- */

.index { margin-top: 40px; border-top: 1px solid var(--rule); }

.chapter {
  display: grid;
  grid-template-columns: 34px 30px minmax(0, 1fr);
  gap: 6px 16px;
  align-items: center;
  padding: 20px 0;
  border-bottom: 1px solid var(--hairline);
}

@media (min-width: 860px) {
  .chapter {
    grid-template-columns: 40px 34px minmax(0, 1fr) 130px 150px;
    gap: 24px;
    padding: 24px 0;
  }
}

.chapter-no {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* The chapter's own drawn glyph, the same one the app puts on the chapter card:
   the Tudor rose for values, the flag for the UK, the Tower of London for
   history, the Royal Albert Hall for society, Big Ben for government. The app
   imports them as template images and tints them with the chapter's colour, so
   the web does the same thing with a mask rather than shipping five
   pre-coloured copies.

   Content.json authors one hex per chapter, chosen against paper, and
   Palette.chapter(_:) darkens it for light mode and lifts it for dark. Those
   two derived values are what the rows carry, so the glyphs clear 3:1 in both
   themes exactly as they do in the app. Raw authored hexes would not: the
   orange chapter lands at 2.45:1 on paper and the blue at 2.85:1 on the dark
   canvas. */
.chapter-glyph { width: 30px; height: 30px; }

@supports (mask-image: url("assets/glyphs/uk.png")) or (-webkit-mask-image: url("assets/glyphs/uk.png")) {
  .chapter-glyph {
    background: var(--chapter-light, var(--ink-soft));
    -webkit-mask: var(--glyph) center / contain no-repeat;
    mask: var(--glyph) center / contain no-repeat;
  }

  @media (prefers-color-scheme: dark) {
    .chapter-glyph { background: var(--chapter-dark, var(--ink-soft)); }
  }
}

.chapter-title { font-family: var(--display); font-size: clamp(19px, 2vw, 24px); font-weight: 700; line-height: 1.2; }

.chapter-count { font-size: 15px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }

@media (max-width: 859px) {
  .chapter-count { grid-column: 3; margin-top: -4px; }
}

@media (min-width: 860px) { .chapter-count { text-align: right; } }

.index-total {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding-top: 20px;
  font-size: 15px;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* ---------- Split rows ---------- */

.split { display: grid; gap: 40px; align-items: center; }

@media (min-width: 940px) {
  .split { grid-template-columns: 1fr 1fr; gap: 76px; }
  .split-flip .split-art { order: -1; }
}

.split-art { display: flex; justify-content: center; }
.split-art .phone img { max-height: 580px; width: auto; }

/* ---------- Revision tools: a list, not a row of boxes ---------- */

.tools { margin-top: 30px; border-top: 1px solid var(--rule); max-width: 54ch; }

.tool {
  display: grid;
  grid-template-columns: 92px 1fr;
  gap: 4px 20px;
  padding: 18px 0;
  border-bottom: 1px solid var(--hairline);
}

.tool b {
  font-family: var(--display);
  font-size: 19px;
  font-weight: 700;
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
}
.tool h3 { line-height: 1.35; }
.tool p { grid-column: 2; color: var(--ink-soft); font-size: 15.5px; line-height: 1.55; }

@media (max-width: 559px) {
  .tool { grid-template-columns: 1fr; }
  .tool p { grid-column: 1; }
}

/* ---------- Mark scale ----------
   The scale the test is actually marked on, drawn rather than described:
   24 marks with the pass line standing at 18. Green is used here and nowhere
   else, which is also how the app uses it. */

.scale { margin-top: 40px; max-width: 760px; }

.scale-track {
  display: grid;
  grid-template-columns: repeat(24, 1fr);
  gap: 3px;
  align-items: end;
  height: 62px;
}

.scale-track i {
  display: block;
  height: 26px;
  background: var(--hairline);
  border-radius: 2px;
}
.scale-track i.is-pass { height: 62px; background: var(--pass); }
/* The marks you would score, against the empty ones above the pass line. On
   the app's palette successSoft and hairline land within a hundredth of each
   other in lightness, which left the two halves of the scale telling the same
   story; deepening this one inside the success hue separates them again. */
.scale-track i.is-under { height: 40px; background: color-mix(in srgb, var(--pass) 40%, var(--pass-soft)); }

/* The pass label has to stand under the mark it names, not in the middle of
   the row: 18 of 24 is three quarters along, and a centred label pointed at
   the wrong bar. */
.scale-legend {
  position: relative;
  display: flex;
  justify-content: space-between;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--hairline);
  font-size: 14px;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.scale-legend b {
  position: absolute;
  top: 12px;
  left: 75%;
  transform: translateX(-50%);
  color: var(--pass);
  font-weight: 600;
  white-space: nowrap;
}

/* Below about 520px the three labels collide, so the pass label drops to its
   own line under the ends rather than overlapping them. */
@media (max-width: 519px) {
  .scale-legend { flex-wrap: wrap; padding-bottom: 24px; }
  .scale-legend b { top: auto; bottom: 0; left: 75%; }
}

/* ---------- Pricing ---------- */

.tiers { display: grid; gap: 22px; margin-top: 40px; align-items: start; }

@media (min-width: 860px) { .tiers { grid-template-columns: 1fr 1.05fr; gap: 30px; } }

.tier { border-top: 2px solid var(--rule); padding-top: 26px; }

/* The paid tier is the app's own Premium card: the navy fill from
   Palette.premiumFillTop/Bottom with the gold on top of it. It used to be a
   white card with a faint gold wash, which read as a footnote to the free
   column beside it — in the app this is the one surface that fills with
   colour, and that is the whole point of it. */
.tier-premium {
  border: 1px solid var(--brass-edge);
  border-radius: var(--r-surface);
  background: linear-gradient(160deg, var(--hero-top), var(--hero-bottom));
  padding: 30px 28px;
  color: var(--on-hero);
  box-shadow: var(--shadow);
}

.tier h3 { font-size: 24px; }
.tier .price { margin-top: 6px; color: var(--ink-soft); font-size: 15px; }
.tier ul { list-style: none; margin: 22px 0 0; padding: 0; }
.tier li { padding: 11px 0 11px 0; border-top: 1px solid var(--hairline); color: var(--ink-soft); font-size: 16px; }
.tier li:first-child { border-top: 0; }

/* On the navy fill the neutral tokens would vanish, so the card restates them
   against its own ground rather than dimming into it. */
.tier-premium h3 { color: var(--on-hero); }
.tier-premium .price { color: rgba(255, 255, 255, 0.82); }
.tier-premium li { color: rgba(255, 255, 255, 0.82); border-top-color: rgba(255, 255, 255, 0.16); }
.tier-premium .badge { background: #d9ac61; color: var(--accent-deep); }

.badge {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  background: var(--brass-strong);
  color: #ffffff;
  font: 700 11px/1 var(--sans);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 7px 13px;
  margin-bottom: 16px;
}

@media (prefers-color-scheme: dark) {
  /* Brass lightens in dark mode, so a capsule on a light ground takes dark
     text. The one inside .tier-premium sits on navy and sets its own pair. */
  .badge { color: var(--accent-ink); }
}

/* ---------- Independence note ---------- */

.note { display: grid; gap: 26px; border-top: 2px solid var(--rule); padding-top: 34px; }

@media (min-width: 900px) { .note { grid-template-columns: 0.92fr 1.08fr; gap: 56px; } }

.note h2 { font-size: clamp(24px, 2.4vw, 30px); }
.note p { color: var(--ink-soft); max-width: 62ch; }
.note p + p { margin-top: 16px; }

/* ---------- Legal and support pages ---------- */

.page-head { padding-block: 56px 32px; border-bottom: 1px solid var(--rule); }
.page-head h1 { font-size: clamp(34px, 4.4vw, 48px); }
.page-head .updated { margin-top: 12px; font-size: 14px; color: var(--ink-soft); }

.prose { max-width: 660px; padding-block: 44px 76px; }
.prose h2 { font-size: 23px; margin: 40px 0 12px; }
.prose h2:first-child { margin-top: 0; }
.prose p { margin-bottom: 16px; color: var(--ink); }
.prose ul { padding-left: 22px; margin: 0 0 16px; }
.prose li { margin-bottom: 8px; }

.callout {
  border-top: 2px solid var(--rule);
  border-bottom: 1px solid var(--hairline);
  padding: 22px 0 24px;
  margin-bottom: 38px;
}
.callout .label { display: block; margin-bottom: 12px; }

/* ---------- Footer ---------- */

.site-footer {
  border-top: 1px solid var(--hairline);
  padding-block: 44px 60px;
  font-size: 14px;
  color: var(--ink-soft);
}
.site-footer .wrap { display: grid; gap: 18px; }
.site-footer p { max-width: 72ch; }
.site-footer nav { display: flex; flex-wrap: wrap; gap: 4px 20px; margin-block: -10px; }
.site-footer nav a { display: inline-flex; align-items: center; min-height: 44px; }

@media (min-width: 760px) {
  .site-footer .wrap { grid-template-columns: 1fr auto; align-items: start; gap: 40px; }
  .site-footer nav { justify-content: flex-end; }
}

/* ---------- Scroll reveal ----------
   One job: sections arrive in reading order rather than all at once, which is
   the only hierarchy a long page has. Hidden only under .js, which the inline
   snippet in the head sets, so with scripting off the page is plain static
   content rather than a blank column. */

.js .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.js .reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; transition: none; }
}
