/* ==================================================================
   MEM TANZANIA: DESIGN SYSTEM
   One stylesheet. Every page. Document-native: rules, registers,
   tabular figures, report-cover layout.

   Palette locked: navy / carbon / off-white. Type locked: Outfit + DM Sans.
   ================================================================== */

/* ── RESET ───────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  scroll-behavior: smooth;
  text-size-adjust: 100%;
}

img, svg { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }

/* ══════════════════════════════════════════════════════════════════
   TOKENS
   Colour in OKLCH. Every neutral carries the navy hue (252) so the
   greys sit with the brand instead of beside it. No pure black or white.
════════════════════════════════════════════════════════════════════ */
:root {
  /* Brand */
  --navy:        oklch(0.29 0.062 252);
  --navy-deep:   oklch(0.24 0.056 252);
  --navy-wash:   oklch(0.962 0.013 252);
  --carbon:      oklch(0.17 0.013 252);   /* near-black, hue-tinted */
  --carbon-lift: oklch(0.23 0.014 252);

  /* Text. The quiet tones are re-scoped per ground further down: a tone
     that clears 4.5:1 on --canvas does not clear it on --sunk or --deep. */
  --ink:         oklch(0.22 0.028 252);
  --ink-body:    oklch(0.44 0.021 252);
  --ink-quiet:   oklch(0.50 0.022 252);
  --ink-faint:   oklch(0.552 0.020 252);   /* graphical marks only: held to 3:1, never body text */

  /* Ground */
  /* Four light grounds, all drawn from the navy hue so the page reads as
     one family. Chroma climbs as lightness falls, which is what keeps the
     darker tints looking like tinted paper rather than dirty grey. */
  --canvas:      oklch(0.986 0.005 252);   /* primary page ground */
  --surface:     oklch(0.999 0.002 252);   /* inputs and raised panels */
  --sunk:        oklch(0.944 0.017 252);   /* pale navy wash, alternating sections */
  --deep:        oklch(0.902 0.026 252);   /* deepest light tint, closes the page */

  /* Rules: the primary structural device */
  --rule:        oklch(0.905 0.008 252);
  --rule-soft:   oklch(0.940 0.006 252);
  --rule-strong: oklch(0.820 0.011 252);

  /* On dark */
  --on-dark:        oklch(0.98 0.003 252);
  --on-dark-body:   oklch(0.78 0.010 252);
  --on-dark-quiet:  oklch(0.62 0.012 252);
  --rule-dark:      oklch(0.30 0.014 252);
  --rule-dark-soft: oklch(0.24 0.012 252);

  /* Type */
  --display: 'Outfit', system-ui, -apple-system, sans-serif;
  --body:    'DM Sans', system-ui, -apple-system, sans-serif;

  /* Scale: 1.25+ ratio between steps */
  --t-2xs:  0.6875rem;
  --t-xs:   0.75rem;
  --t-sm:   0.875rem;
  --t-base: 1rem;
  --t-md:   1.0625rem;
  --t-lg:   1.375rem;
  --t-xl:   1.75rem;
  --t-2xl:  clamp(2rem, 3.4vw, 2.75rem);
  --t-3xl:  clamp(2.4rem, 5vw, 3.5rem);

  /* Space */
  --s1: 0.25rem;  --s2: 0.5rem;   --s3: 0.75rem;  --s4: 1rem;
  --s5: 1.5rem;   --s6: 2rem;     --s7: 3rem;     --s8: 4rem;
  --s9: 6rem;     --s10: 8rem;

  /* Motion: ease-out quart / expo. No bounce anywhere. */
  --out:      cubic-bezier(0.165, 0.84, 0.44, 1);
  --out-soft: cubic-bezier(0.22, 1, 0.36, 1);

  --nav-h: 68px;
  --edge:  2rem;
  --measure: 68ch;

}

/* ══════════════════════════════════════════════════════════════════
   BASE
════════════════════════════════════════════════════════════════════ */
body {
  font-family: var(--body);
  font-size: var(--t-md);
  line-height: 1.65;
  color: var(--ink-body);
  background-color: var(--canvas);
  overflow-x: hidden;
}

/* ══════════════════════════════════════════════════════════════════
   TERRAIN
   A survey contour field of the ground MEM actually works on: Moshi
   sits at the foot of Kilimanjaro. Drawn once as a mask so a single
   asset can be painted any colour, fixed behind the page, and drifting
   slowly enough that you notice it only if you stop and look.
   z-index -1 sits above the canvas the body background paints and below
   every piece of content, so nothing is ever laid over the text.
════════════════════════════════════════════════════════════════════ */
body::before {
  content: '';
  position: fixed;
  inset: -12vmax;
  z-index: -1;
  pointer-events: none;
}
@supports (mask-image: url(#m)) or (-webkit-mask-image: url(#m)) {
  body::before {
    background-color: var(--navy);
    opacity: 0.07;
    -webkit-mask: url(contours.svg) center / cover no-repeat;
    mask: url(contours.svg) center / cover no-repeat;
    animation: terrainDrift 80s ease-in-out infinite alternate;
    will-change: transform;
  }
}
@keyframes terrainDrift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(-2.2%, 1.6%, 0) scale(1.07); }
}
/* Scroll parallax rides on `translate`, which is its own property and
   composes with the keyframe `transform` instead of fighting it. The map
   lags the page, so you read as moving across terrain rather than past a
   picture of it. */
body::before { translate: 0 var(--terrain-y, 0px); }
/* Dark bands read the terrain in reverse, lifted out of the ground */
.band::after,
.masthead::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}
@supports (mask-image: url(#m)) or (-webkit-mask-image: url(#m)) {
  .band::after,
  .masthead::after {
    background-color: var(--on-dark);
    opacity: 0.055;
    -webkit-mask: url(contours.svg) center / cover no-repeat;
    mask: url(contours.svg) center / cover no-repeat;
  }
}
.band > *,
.masthead > * { position: relative; z-index: 1; }

/* On an inner page the contour field settles into focus as the sheet
   loads, the way a survey resolves when it is laid down flat. */
@media (prefers-reduced-motion: no-preference) {
  .masthead::after { animation: surveyIn 1700ms var(--out) both; }
}
@keyframes surveyIn {
  from { opacity: 0; transform: scale(1.06); }
  to   { opacity: 0.055; transform: scale(1); }
}

/* Tracking is size-specific. A single letter-spacing is wrong somewhere. */
h1, h2, h3, h4 {
  font-family: var(--display);
  color: var(--ink);
  font-weight: 700;
  text-wrap: balance;
}
h1 { font-size: var(--t-3xl); line-height: 1.03; letter-spacing: -0.032em; }
h2 { font-size: var(--t-2xl); line-height: 1.08; letter-spacing: -0.024em; }
h3 { font-size: var(--t-lg);  line-height: 1.2;  letter-spacing: -0.014em; }
h4 { font-size: var(--t-base);line-height: 1.35; letter-spacing: -0.006em; }

p { max-width: var(--measure); text-wrap: pretty; }
strong { color: var(--ink); font-weight: 600; }

::selection { background: var(--navy); color: var(--on-dark); }

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

/* Numbers are data. Always tabular. */
.tabular, .figure__num, .register__ref, .stat__num,
.hours__time, .particulars__value { font-variant-numeric: tabular-nums; }

/* ══════════════════════════════════════════════════════════════════
   LAYOUT
════════════════════════════════════════════════════════════════════ */
.container {
  max-width: 1240px;
  margin-inline: auto;
  padding-inline: var(--edge);
}
.container--narrow { max-width: 940px; }

.section        { padding-block: var(--s9); }
.section--tall  { padding-block: var(--s10); }
.section--tight { padding-block: var(--s8); }
/* Light sections stay transparent so the terrain reads through all of
   them. Blocking them in as flat tints was the wrong answer. */
.section--deep, .site-footer {
  --ink-quiet: oklch(0.44 0.024 252);
  --ink-faint: oklch(0.495 0.022 252);
}
.section--deep    { background-color: var(--deep); }
.section--surface { background-color: var(--surface); }

/* Rhythm: consecutive same-ground sections share one gap, not two. */
.section + .section:not([class*="--"]) { padding-top: 0; }

.rule { height: 1px; background: var(--rule); border: 0; }
.rule--strong { background: var(--rule-strong); }

/* Section header: a document section break. One rule spans the whole
   block, the label sits beneath it in the left margin, the heading beside
   it. Never centred, and never a stub rule floating over the label alone. */
.head {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 12rem) minmax(0, 1fr);
  gap: var(--s7);
  align-items: start;
  padding-top: var(--s7);
  margin-bottom: var(--s8);
}
/* The section rule is a scalable element rather than a border, so it can
   draw itself in from the left as the section arrives. */
.head::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: var(--rule);
  transform: scaleX(1);
  transform-origin: left;
}
.head__label {
  font-family: var(--display);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-quiet);
  line-height: 1.5;
}
.head__body > p {
  margin-top: var(--s5);
  color: var(--ink-body);
  max-width: 58ch;
}
.head--flush { margin-bottom: 0; }

.head--onDark::before { background: var(--rule-dark); }
.head--onDark .head__label { color: var(--on-dark-quiet); }

/* Active-section cue: shared.js flags the header the reader is level
   with. The label lifts to full ink and a short filing underline wipes
   in, the same mark the nav gives the current page. Without JS no
   header is ever flagged, so this stays dormant. */
.head__label { position: relative; transition: color 240ms var(--out); }
.head.is-current .head__label { color: var(--ink); }
.head__label::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -0.4rem;
  width: 1.75rem;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 320ms var(--out);
}
.head.is-current .head__label::after { transform: scaleX(1); }
.head--onDark.is-current .head__label { color: var(--on-dark); }

/* Standalone eyebrow */
.eyebrow {
  display: block;
  font-family: var(--display);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-quiet);
  margin-bottom: var(--s4);
}
.eyebrow--onDark { color: var(--on-dark-quiet); }

/* ══════════════════════════════════════════════════════════════════
   ACTIONS
   No container, no border, no fill. The affordance is colour and weight,
   the way a link reads; a thick rule wipes in underneath on hover.

   The rule is currentColor, so it is navy on the light pages and
   off-white inside the dark bands without a second set of rules. Padding
   still carries a 44px touch target even though nothing is drawn around it.
════════════════════════════════════════════════════════════════════ */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-family: var(--display);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: -0.004em;
  line-height: 1.4;
  padding: 0.75rem 0;
  min-height: 44px;      /* padding alone lands at 43.6px */
  background: none;
  border: 0;
  border-radius: 0;
  color: var(--navy);
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
  transition: color 180ms var(--out), opacity 90ms var(--out);
}
.btn::after {
  content: '';
  position: absolute;
  inset: auto 0 0.4rem 0;
  height: 3px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 340ms var(--out);
}
.btn:hover::after,
.btn:focus-visible::after { transform: scaleX(1); }
/* On press the rule stays put and the label dips, so the action still
   answers on pointer-down without anything moving out from under it. */
.btn:active { opacity: 0.7; transition-duration: 60ms; }

.btn-primary:hover { color: var(--navy-deep); }

.btn-ghost { color: var(--ink); }
.btn-ghost:hover { color: var(--navy); }

/* Inside the dark bands */
.btn-onDark,
.btn-solid { color: var(--on-dark); }
.btn-onDark:hover,
.btn-solid:hover { color: var(--on-dark); }

.btn[aria-busy="true"]::after { transform: scaleX(1); opacity: 0.4; }

/* ══════════════════════════════════════════════════════════════════
   NAVIGATION
   Translucent material. Content scrolls under it. The bottom edge is
   a soft fade, not a hard divider.
════════════════════════════════════════════════════════════════════ */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  background: oklch(0.982 0.004 252 / 0.72);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  transition: background 260ms var(--out);
}
.nav::after {
  content: '';
  position: absolute;
  inset: 100% 0 auto 0;
  height: 1px;
  background: var(--rule);
  opacity: 0;
  transition: opacity 260ms var(--out);
}
.nav.is-scrolled { background: oklch(0.982 0.004 252 / 0.88); }
.nav.is-scrolled::after { opacity: 1; }

.nav__inner {
  width: 100%;
  max-width: 1240px;
  margin-inline: auto;
  padding-inline: var(--edge);
  display: flex;
  align-items: center;
  gap: var(--s5);
}
.nav__logo { flex-shrink: 0; display: flex; align-items: center; }
.nav__logo img { height: 28px; width: auto; }

.nav__links {
  display: flex;
  align-items: center;
  gap: 0.125rem;
  margin-left: auto;
  list-style: none;
}
.nav__links a {
  position: relative;
  display: block;
  font-family: var(--display);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--ink-body);
  padding: 0.5rem 0.75rem;
  transition: color 150ms var(--out);
}
.nav__links a:hover { color: var(--ink); }
.nav__links a::after {
  content: '';
  position: absolute;
  left: 0.75rem; right: 0.75rem; bottom: 0.2rem;
  height: 1px;
  background: var(--navy);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 240ms var(--out);
}
.nav__links a:hover::after { transform: scaleX(1); }
.nav__links a[aria-current="page"] { color: var(--ink); font-weight: 600; }
.nav__links a[aria-current="page"]::after { transform: scaleX(1); }

.nav__cta { flex-shrink: 0; margin-left: var(--s5); }

.nav__toggle {
  display: none;
  margin-left: auto;
  width: 44px; height: 44px;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  padding: 0;
  color: var(--ink);
  cursor: pointer;
}

/* ── MENU ICON ──────────────────────────────────────────────────────
   The bars are a single continuous path, revealed through a dash window.
   Closed, the window is short and shows two strokes; opened, it widens
   and slides along the path so the same line unrolls into the hook, and
   the whole glyph rotates -45deg to land it. One path, no crossfade.
─────────────────────────────────────────────────────────────────── */
.menu-icon {
  width: 26px;
  height: 26px;
  overflow: visible;
  transition: transform 500ms ease-in-out;
}
.menu-icon__morph {
  stroke-dasharray: 12 63;
  transition: stroke-dasharray 500ms ease-in-out,
              stroke-dashoffset 500ms ease-in-out;
}
.nav__toggle[aria-expanded="true"] .menu-icon { transform: rotate(-45deg); }
.nav__toggle[aria-expanded="true"] .menu-icon__morph {
  stroke-dasharray: 20 300;
  stroke-dashoffset: -32.42px;
}

/* Mobile sheet: enters and exits along the same path */
.nav__sheet {
  position: fixed;
  inset: var(--nav-h) 0 0 0;
  z-index: 99;
  background: var(--canvas);
  display: flex;
  flex-direction: column;
  padding: var(--s5) var(--edge) var(--s8);
  overflow-y: auto;
  opacity: 0;
  transform: translateY(-8px);
  pointer-events: none;
  transition: opacity 220ms var(--out), transform 300ms var(--out);
}
.nav__sheet.is-open { opacity: 1; transform: translateY(0); pointer-events: auto; }
.nav__sheet a:not(.btn) {
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
  padding: var(--s4) 0;
  border-bottom: 1px solid var(--rule);
  transition: color 150ms var(--out);
}
.nav__sheet a:not(.btn):hover { color: var(--navy); }
.nav__sheet .btn { margin-top: var(--s6); }

/* ══════════════════════════════════════════════════════════════════
   REGISTER: the core component
   An indexed row list. Hairlines, no boxes, no shadows, no lift.
════════════════════════════════════════════════════════════════════ */
/* The top rule is a scalable element, not a border, so it can be drawn
   in as the section arrives (see REVEAL). Without JS it just sits at
   scaleX(1) and reads as the border it replaces. */
.register { position: relative; }
.register::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: var(--rule);
  transform-origin: left;
}

.register__row {
  position: relative;
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--s5);
  padding: var(--s6) var(--s4);
  margin-inline: calc(var(--s4) * -1);
  border-bottom: 1px solid var(--rule);
  transition: background-color 180ms var(--out);
}
a.register__row, .register__row--link { cursor: pointer; }
a.register__row:hover, .register__row--link:hover { background: var(--navy-wash); }

/* Selection marker: a rule is drawn down the left margin of the row
   you point at, the way a line gets picked out in a ledger. Held while
   an entry stays open. */
.register__row::before,
.entry > summary::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--navy);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 240ms var(--out);
}
a.register__row:hover::before,
a.register__row:focus-visible::before,
.register__row--link:hover::before,
.entry > summary:hover::before,
.entry > summary:focus-visible::before,
.entry[open] > summary::before { transform: scaleY(1); }

.register__ref {
  font-family: var(--display);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--ink-quiet);
  transition: color 180ms var(--out), transform 300ms var(--out);
}
/* The filing reference steps aside as the row takes focus */
a.register__row:hover .register__ref,
.entry > summary:hover .register__ref { color: var(--navy); transform: translateX(3px); }

.register__body { display: block; min-width: 0; }
.register__name {
  display: block;
  font-family: var(--display);
  font-size: var(--t-base);
  font-weight: 600;
  letter-spacing: -0.008em;
  color: var(--ink);
  margin-bottom: 0.3rem;
}
.register__desc {
  display: block;
  font-size: var(--t-sm);
  line-height: 1.6;
  color: var(--ink-quiet);
  max-width: 62ch;
}
.register__mark {
  align-self: center;
  color: var(--ink-faint);
  transition: transform 240ms var(--out), color 180ms var(--out);
}
a.register__row:hover .register__mark { transform: translateX(4px); color: var(--navy); }

/* Expandable variant: native <details>, works without JS */
.entry { border-bottom: 1px solid var(--rule); }
.entry > summary {
  position: relative;
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--s5);
  padding: var(--s6) var(--s4);
  margin-inline: calc(var(--s4) * -1);
  cursor: pointer;
  list-style: none;
  transition: background-color 180ms var(--out);
}
.entry > summary::-webkit-details-marker { display: none; }
.entry > summary:hover { background: var(--navy-wash); }
/* An open record keeps its filing reference pulled out and inked in,
   so the number stays the anchor the panel hangs off. */
.entry[open] > summary .register__ref,
.entry > summary:hover .register__ref { color: var(--navy); }
.entry[open] > summary .register__ref { transform: translateX(4px); }

.entry__sign {
  align-self: center;
  position: relative;
  width: 13px; height: 13px;
  flex-shrink: 0;
}
.entry__sign::before, .entry__sign::after {
  content: '';
  position: absolute;
  inset: 50% 0 auto 0;
  height: 1.5px;
  background: var(--ink-quiet);
  transition: transform 300ms var(--out), background-color 180ms var(--out);
}
.entry__sign::after { transform: rotate(90deg); }
.entry[open] .entry__sign::after { transform: rotate(0deg); }
.entry[open] .entry__sign::before,
.entry[open] .entry__sign::after { background: var(--navy); }

.entry__panel {
  padding: var(--s2) var(--s4) var(--s7) 3.5rem;
  animation: entryOpen 320ms var(--out);
}
/* When JS eases the height open it owns the motion: drop the mount
   keyframe so the two do not run on the same element at once. */
.entry--eased .entry__panel { animation: none; }
@keyframes entryOpen {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.entry__meta {
  font-family: var(--display);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--navy);
  margin-bottom: var(--s4);
}

/* Unindexed variant: questions, where a reference number would be noise */
.entry--plain > summary { grid-template-columns: minmax(0, 1fr) auto; }
.entry--plain .entry__panel { padding-left: var(--s3); max-width: 68ch; }
.entry__q {
  font-family: var(--display);
  font-size: var(--t-base);
  font-weight: 600;
  letter-spacing: -0.008em;
  color: var(--ink);
  line-height: 1.4;
}
.entry--plain .entry__panel p {
  font-size: var(--t-sm);
  line-height: 1.7;
  color: var(--ink-body);
}
.entry__list {
  list-style: none;
  columns: 2;
  column-gap: var(--s7);
  margin-bottom: var(--s5);
}
.entry__list li {
  break-inside: avoid;
  font-size: var(--t-sm);
  line-height: 1.55;
  color: var(--ink-body);
  padding: 0.4rem 0 0.4rem 1.1rem;
  position: relative;
}
.entry__list li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.95em;
  width: 5px; height: 1px;
  background: var(--rule-strong);
}

/* ══════════════════════════════════════════════════════════════════
   FIGURES: numbers without boxes
════════════════════════════════════════════════════════════════════ */
.figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--s8);
  border-top: 1px solid var(--rule);
  padding-top: var(--s7);
}
.figure__num {
  font-family: var(--display);
  font-size: var(--t-xl);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ink);
  margin-bottom: 0.7rem;
}
.figure__label {
  font-size: var(--t-sm);
  color: var(--ink-quiet);
  line-height: 1.45;
  max-width: 24ch;
}
.figures--onDark { border-top-color: var(--rule-dark); }
.figures--onDark .figure__num { color: var(--on-dark); }
.figures--onDark .figure__label { color: var(--on-dark-quiet); }

/* ══════════════════════════════════════════════════════════════════
   PARTICULARS: a record block (key/value rows)
════════════════════════════════════════════════════════════════════ */
.particulars { border-top: 1px solid var(--rule); }
.particulars__row {
  display: grid;
  grid-template-columns: minmax(0, 8.5rem) minmax(0, 1fr);
  gap: var(--s5);
  padding: 1.4rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.particulars__key {
  font-family: var(--display);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-quiet);
  padding-top: 0.2rem;
}
.particulars__value {
  font-size: var(--t-sm);
  color: var(--ink);
  line-height: 1.5;
  min-width: 0;
  /* An email address is one unbreakable token and will happily push a
     narrow column past the viewport. It breaks before the layout does. */
  overflow-wrap: anywhere;
}

/* ══════════════════════════════════════════════════════════════════
   POLICY: long-form legal content (privacy, cookies). Shared because
   both pages carry the identical rhythm: each numbered section opens
   on its own hairline, the way figures and steps do.
════════════════════════════════════════════════════════════════════ */
.policy__section {
  border-top: 1px solid var(--rule);
  padding-top: var(--s7);
}
.policy__section + .policy__section { margin-top: var(--s8); }
.policy__section h2 {
  font-size: var(--t-xl);
  margin-bottom: var(--s5);
}
.policy__section h3 {
  font-size: var(--t-base);
  margin-top: var(--s6);
  margin-bottom: var(--s3);
}
.policy__section p {
  color: var(--ink-body);
  margin-bottom: var(--s4);
}
.policy__section code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.9em;
  color: var(--ink);
}
.policy__section p:last-child,
.policy__section > :last-child { margin-bottom: 0; }
.policy__list { list-style: none; max-width: var(--measure); margin: var(--s4) 0 var(--s5); }
.policy__list li {
  position: relative;
  font-size: var(--t-sm);
  line-height: 1.6;
  color: var(--ink-body);
  padding: 0.35rem 0 0.35rem 1.1rem;
}
.policy__list li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.95em;
  width: 5px; height: 1px;
  background: var(--rule-strong);
}

/* ══════════════════════════════════════════════════════════════════
   BANDS: dark full-bleed sections. Used sparingly, on purpose.
════════════════════════════════════════════════════════════════════ */
.band {
  position: relative;
  overflow: hidden;
  background-color: var(--carbon);
  color: var(--on-dark-body);
  padding-block: var(--s10);
}
/* Navy is far lighter than carbon, so its quiet tone has to lift to hold
   contrast: the carbon value only reaches 3.9:1 here. */
.band--navy {
  background-color: var(--navy);
  --on-dark-quiet: oklch(0.72 0.013 252);
}
.band--tight { padding-block: var(--s9); }
.band h1, .band h2, .band h3 { color: var(--on-dark); }
.band p { color: var(--on-dark-body); }

/* Page masthead: the top of every inner page */
.masthead {
  position: relative;
  overflow: hidden;
  background-color: var(--carbon);
  padding-top: calc(var(--nav-h) + var(--s9));
  padding-bottom: var(--s9);
}
.masthead__label {
  font-family: var(--display);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--on-dark-quiet);
  padding-bottom: var(--s4);
  margin-bottom: var(--s6);
  border-bottom: 1px solid var(--rule-dark);
}
.masthead__title { color: var(--on-dark); margin-bottom: var(--s5); }
.masthead__sub {
  font-size: var(--t-md);
  line-height: 1.7;
  color: var(--on-dark-body);
  max-width: 56ch;
}

/* ══════════════════════════════════════════════════════════════════
   QUOTE
════════════════════════════════════════════════════════════════════ */
.quote { max-width: 60ch; }
.quote__text {
  font-family: var(--display);
  font-size: clamp(1.375rem, 2.6vw, 1.875rem);
  font-weight: 400;
  line-height: 1.38;
  letter-spacing: -0.018em;
  color: var(--on-dark);
  margin-bottom: var(--s5);
}
.quote__attr {
  font-family: var(--display);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--on-dark-quiet);
  font-style: normal;
}
.quote--light .quote__text { color: var(--ink); }
.quote--light .quote__attr { color: var(--ink-quiet); }

/* ══════════════════════════════════════════════════════════════════
   STEPS: process, as a numbered sequence
════════════════════════════════════════════════════════════════════ */
.steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s8);
  border-top: 1px solid var(--rule);
  padding-top: var(--s7);
}
.step__ref {
  font-family: var(--display);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.09em;
  color: var(--navy);
  margin-bottom: var(--s6);
}
.step__title {
  font-family: var(--display);
  font-size: var(--t-base);
  font-weight: 600;
  letter-spacing: -0.008em;
  color: var(--ink);
  margin-bottom: var(--s3);
}
.step__desc {
  font-size: var(--t-sm);
  line-height: 1.65;
  color: var(--ink-quiet);
  max-width: 40ch;
}

/* ══════════════════════════════════════════════════════════════════
   MARQUEE: a quiet client band
════════════════════════════════════════════════════════════════════ */
.clients {
  padding-block: var(--s8);
  border-top: 1px solid var(--rule);
  overflow: hidden;
}
.clients__label {
  font-family: var(--display);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-quiet);
  margin-bottom: var(--s5);
}
.marquee { position: relative; overflow: hidden; }
.marquee::before, .marquee::after {
  content: '';
  position: absolute;
  inset-block: 0;
  width: 5rem;
  z-index: 2;
  pointer-events: none;
}
.marquee::before { left: 0;  background: linear-gradient(90deg, var(--canvas), transparent); }
.marquee::after  { right: 0; background: linear-gradient(270deg, var(--canvas), transparent); }
.marquee__track {
  display: flex;
  align-items: center;
  gap: 3rem;
  width: max-content;
  animation: marquee 52s linear infinite;
}
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee__item {
  font-family: var(--display);
  font-size: var(--t-sm);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--ink-quiet);
  white-space: nowrap;
}
@keyframes marquee { to { transform: translateX(-50%); } }

/* ══════════════════════════════════════════════════════════════════
   FORMS
════════════════════════════════════════════════════════════════════ */
.field { display: flex; flex-direction: column; gap: 0.45rem; margin-bottom: var(--s5); }
.field label {
  font-family: var(--display);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink);
}
.field input, .field select, .field textarea {
  font-family: var(--body);
  font-size: var(--t-base);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--rule-strong);
  border-radius: 4px;
  padding: 0.75rem 0.875rem;
  min-height: 46px;
  width: 100%;
  transition: border-color 160ms var(--out), background-color 160ms var(--out);
}
.field textarea { min-height: 130px; resize: vertical; line-height: 1.6; }
.field input::placeholder, .field textarea::placeholder { color: var(--ink-faint); }
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--ink-faint); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: inset 0 0 0 1px var(--navy);
}
.field__hint { font-size: var(--t-xs); color: var(--ink-quiet); }
.field__error {
  font-size: var(--t-xs);
  color: oklch(0.50 0.16 27);
  display: none;
}
.field.has-error input,
.field.has-error select,
.field.has-error textarea { border-color: oklch(0.55 0.17 27); }
.field.has-error .field__error { display: block; }

.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); }

.form__submit { display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap; margin-top: var(--s6); }
.form__note { font-size: var(--t-xs); color: var(--ink-quiet); }
.btn[aria-busy="true"] { opacity: 0.7; pointer-events: none; }

.form__done {
  display: none;
  border-top: 2px solid var(--navy);
  padding-top: var(--s5);
}
.form__done.is-visible { display: block; animation: entryOpen 400ms var(--out); }

/* ══════════════════════════════════════════════════════════════════
   FOOTER
════════════════════════════════════════════════════════════════════ */
/* The footer sits on the deepest light tint. Keeping it light means the
   footer carries the same logo.png the nav does, with no reversal and no
   second asset to drift out of sync. */
.site-footer {
  background-color: var(--deep);
  padding-top: var(--s9);
  padding-bottom: var(--s6);
}
.site-footer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.2fr);
  gap: var(--s7);
  padding-bottom: var(--s7);
  border-bottom: 1px solid var(--rule-strong);
}
.site-footer__logo { margin-bottom: var(--s5); }
.site-footer__logo a { display: inline-block; transition: opacity 150ms var(--out); }
.site-footer__logo a:hover { opacity: 0.7; }
.site-footer__logo img { height: 32px; width: auto; }
.site-footer__tagline {
  font-size: var(--t-sm);
  line-height: 1.65;
  color: var(--ink-body);
  max-width: 30ch;
  margin-bottom: var(--s5);
}
.site-footer__contact { display: flex; flex-direction: column; gap: 0.4rem; }
.site-footer__contact a, .site-footer__contact span {
  font-size: var(--t-sm);
  color: var(--ink-body);
  transition: color 150ms var(--out);
}
.site-footer__contact a:hover { color: var(--navy); }
.site-footer__title {
  font-family: var(--display);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-quiet);
  margin-bottom: var(--s5);
}
.site-footer__list { list-style: none; display: flex; flex-direction: column; gap: 0.7rem; }
.site-footer__list a {
  font-size: var(--t-sm);
  color: var(--ink-body);
  transition: color 150ms var(--out);
}
.site-footer__list a:hover { color: var(--navy); }
.site-footer__blurb {
  font-size: var(--t-sm);
  color: var(--ink-quiet);
  line-height: 1.6;
  margin-bottom: var(--s5);
  max-width: 30ch;
}
.site-footer__bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s4);
  padding-top: var(--s5);
  font-size: var(--t-xs);
  color: var(--ink-quiet);
}
.site-footer__bottom a { transition: color 150ms var(--out); }
.site-footer__bottom a:hover { color: var(--navy); }
.site-footer__bottom nav { display: flex; gap: var(--s5); }

/* ══════════════════════════════════════════════════════════════════
   REVEAL: short, quiet, once

   Armed only by the inline head script, which adds .js-reveal. Without
   JavaScript the content is simply visible: a failed script must never
   be able to blank the page.
════════════════════════════════════════════════════════════════════ */
.js-reveal [data-reveal] {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 620ms var(--out), transform 620ms var(--out);
}
.js-reveal [data-reveal].is-in { opacity: 1; transform: none; }
.js-reveal [data-reveal="1"] { transition-delay: 70ms; }
.js-reveal [data-reveal="2"] { transition-delay: 140ms; }
.js-reveal [data-reveal="3"] { transition-delay: 210ms; }
.js-reveal [data-reveal="4"] { transition-delay: 280ms; }

/* The section rule draws in from the left */
.js-reveal .head[data-reveal]::before {
  transform: scaleX(0);
  transition: transform 1000ms var(--out) 60ms;
}
.js-reveal .head[data-reveal].is-in::before { transform: scaleX(1); }

/* The register's own rule is laid down first; the rows then file into
   the space it opens (their cascade, below, overlaps the draw). */
.js-reveal .register[data-reveal]::before {
  transform: scaleX(0);
  transition: transform 760ms var(--out) 40ms;
}
.js-reveal .register[data-reveal].is-in::before { transform: scaleX(1); }

/* Headings wipe up from their own baseline rather than just fading.
   -8% on the bottom edge keeps descenders from being sheared. */
.js-reveal .head[data-reveal] :is(h1, h2) {
  clip-path: inset(0 0 100% 0);
  transition: clip-path 900ms var(--out) 180ms;
}
.js-reveal .head[data-reveal].is-in :is(h1, h2) { clip-path: inset(0 0 -8% 0); }

/* Register rows and entries cascade instead of arriving as one block */
.js-reveal [data-reveal] :is(.register__row, .entry, .step, .figure, .model, .reason) {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 520ms var(--out), transform 520ms var(--out);
}
.js-reveal [data-reveal].is-in :is(.register__row, .entry, .step, .figure, .model, .reason) {
  opacity: 1;
  transform: none;
}
.js-reveal [data-reveal].is-in > :nth-child(1),
.js-reveal [data-reveal].is-in :is(.register__row, .entry):nth-child(1) { transition-delay: 40ms; }
.js-reveal [data-reveal].is-in :is(.register__row, .entry, .step, .figure, .model, .reason):nth-child(2) { transition-delay: 100ms; }
.js-reveal [data-reveal].is-in :is(.register__row, .entry, .step, .figure, .model, .reason):nth-child(3) { transition-delay: 160ms; }
.js-reveal [data-reveal].is-in :is(.register__row, .entry, .step, .figure, .model, .reason):nth-child(4) { transition-delay: 220ms; }
.js-reveal [data-reveal].is-in :is(.register__row, .entry):nth-child(5) { transition-delay: 280ms; }
.js-reveal [data-reveal].is-in :is(.register__row, .entry):nth-child(6) { transition-delay: 340ms; }
.js-reveal [data-reveal].is-in :is(.register__row, .entry):nth-child(7) { transition-delay: 400ms; }
.js-reveal [data-reveal].is-in :is(.register__row, .entry):nth-child(8) { transition-delay: 460ms; }

/* ══════════════════════════════════════════════════════════════════
   BETWEEN PAGES
   Five files, one document. The nav and footer are held in place while
   the body is carried through: no white flash, no reload jolt. Native
   cross-document view transitions; browsers without them just navigate.
════════════════════════════════════════════════════════════════════ */
@view-transition { navigation: auto; }

.nav         { view-transition-name: site-nav; }
.site-footer { view-transition-name: site-footer; }

::view-transition-old(root) { animation: pageOut 180ms var(--out) both; }
::view-transition-new(root) { animation: pageIn  260ms var(--out) 40ms both; }
@keyframes pageOut { to   { opacity: 0; transform: translateY(-5px); } }
@keyframes pageIn  { from { opacity: 0; transform: translateY(7px);  } }

/* ── SCROLL PROGRESS ────────────────────────────────────────────────
   A hairline under the nav tracking how far through the page you are.
   Written straight to a custom property from rAF, never to width. */
.nav__progress {
  position: absolute;
  inset: auto 0 0 0;
  height: 2px;
  background: var(--navy);
  transform: scaleX(var(--progress, 0));
  transform-origin: left;
  opacity: 0.9;
}

/* ══════════════════════════════════════════════════════════════════
   RESPONSIVE
   Asymmetry collapses to one honest column below 900px.
════════════════════════════════════════════════════════════════════ */
@media (max-width: 1024px) {
  .steps { grid-template-columns: 1fr 1fr; gap: var(--s7); }
  .site-footer__grid { grid-template-columns: 1fr 1fr; gap: var(--s6); }
}

@media (max-width: 900px) {
  :root { --edge: 1.25rem; }

  .head {
    grid-template-columns: 1fr;
    gap: var(--s4);
    padding-top: var(--s5);
    margin-bottom: var(--s7);
  }

  .nav__links, .nav__cta { display: none; }
  .nav__toggle { display: flex; }

  .register__row, .entry > summary { grid-template-columns: 2.5rem minmax(0, 1fr) auto; gap: var(--s4); }
  .entry__panel { padding-left: 0; }
  .entry__list { columns: 1; }

  .steps { grid-template-columns: 1fr; gap: var(--s7); }
  .field-row { grid-template-columns: 1fr; gap: 0; }
}

@media (max-width: 620px) {
  .section { padding-block: var(--s8); }
  .section--tall { padding-block: var(--s9); }
  .band, .masthead { padding-block: var(--s8); }
  .masthead { padding-top: calc(var(--nav-h) + var(--s7)); }

  .figures { grid-template-columns: 1fr 1fr; gap: var(--s6); }

  /* Key over value: a 8.5rem label column leaves too little for the value */
  .particulars__row { grid-template-columns: 1fr; gap: var(--s2); }
  .particulars__key { padding-top: 0; }

  .site-footer__grid { grid-template-columns: 1fr; gap: var(--s6); }
  .site-footer__bottom { flex-direction: column; align-items: flex-start; }
}

/* ══════════════════════════════════════════════════════════════════
   ACCESSIBILITY PREFERENCES
   Reduced motion is not "no feedback": it is gentler feedback.
════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .js-reveal [data-reveal] { opacity: 1; transform: none; }
  .js-reveal [data-reveal] :is(.register__row, .entry, .step, .figure, .model, .reason) {
    opacity: 1; transform: none;
  }
  .js-reveal .head[data-reveal] :is(h1, h2) { clip-path: none; }
  .js-reveal .head[data-reveal]::before,
  .js-reveal .register[data-reveal]::before { transform: scaleX(1); }
  .marquee__track { animation: none; transform: none; }
  body::before { animation: none; translate: none; }
  .menu-icon, .menu-icon__morph { transition: none; }
  a.register__row:hover .register__ref,
  .entry > summary:hover .register__ref,
  .entry[open] > summary .register__ref { transform: none; }
  .btn:active { transform: none; }

  /* Pages swap with no cross-fade rather than a moving one */
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none !important; }
}

@media (prefers-reduced-transparency: reduce) {
  .nav, .nav.is-scrolled {
    background: var(--canvas);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .nav::after { opacity: 1; }
}

@media (prefers-contrast: more) {
  /* Texture costs a little contrast, so it goes when contrast is asked for */
  :root {
    --ink-body:  oklch(0.32 0.024 252);
    --ink-quiet: oklch(0.40 0.022 252);
    --ink-faint: oklch(0.48 0.020 252);
    --rule:        oklch(0.72 0.014 252);
    --rule-soft:   oklch(0.78 0.012 252);
    --rule-strong: oklch(0.55 0.018 252);
    --on-dark-body:  oklch(0.90 0.006 252);
    --on-dark-quiet: oklch(0.80 0.008 252);
    --rule-dark:     oklch(0.48 0.016 252);
  }
  .nav, .nav.is-scrolled { background: var(--canvas); backdrop-filter: none; }
}

@media print {
  .nav, .nav__sheet, .clients, .btn { display: none; }
  body { background: #fff; color: #000; }
  .band, .masthead, .site-footer { background: #fff; color: #000; }
}
