/* =========================================================================
   photo.teamdct.ca — portrait studio, Brampton
   Built on the Team DCT public-site design system (team-dct/src/styles/tokens.css).

   THE THESIS
   The gallery shell holds no colour of its own, so the only colour in the room
   arrives inside the photographs. That is already the house rule: mono chrome,
   colour entering only inside a scoped container. On a photographer's site the
   scoped container is the frame, which makes this the one product where the
   system's own discipline IS the art direction.

   THE STRUCTURAL BET: the contact sheet.
   What is sold is a narrowing. Twenty to thirty frames go in, three or five
   edited photographs come out. So each session states itself as a real proof
   sheet, and the keeper is not marked with an accent colour: it is the frame
   that still HAS its colour while the rest of the sheet sits in grey. The mark
   and the mono rule turn out to be the same decision.

   ANTI-THESIS (what this must never become)
   A moody dark photographer template with a red accent, a full-bleed stock
   hero, and type floating on a mid-luminance photograph.
   ========================================================================= */

/* ------------------------------------------------------------------ fonts */
/* Metrics read from the actual files: ascent 100.5%, descent 29.5%, gap 0,
   average lowercase advance 0.5338em against Arial's 0.5561em, hence
   size-adjust 96%. The fallback is metrically identical, so the swap costs
   zero layout shift. */
@font-face {
  font-family: "Geist";
  src: url("/fonts/geist-latin.woff2") format("woff2");
  font-weight: 100 900; font-display: swap; font-style: normal;
}
@font-face {
  font-family: "Geist Mono";
  src: url("/fonts/geist-mono-latin.woff2") format("woff2");
  font-weight: 100 900; font-display: swap; font-style: normal;
}
@font-face {
  font-family: "Geist Fallback";
  src: local("Arial"), local("Helvetica Neue"), local("Liberation Sans");
  size-adjust: 96%; ascent-override: 100.5%; descent-override: 29.5%; line-gap-override: 0%;
}
@font-face {
  font-family: "Geist Mono Fallback";
  src: local("Consolas"), local("Courier New"), local("Liberation Mono");
  size-adjust: 100%; ascent-override: 100.5%; descent-override: 29.5%; line-gap-override: 0%;
}

/* ---------------------------------------------------------- house tokens */
/* Values taken verbatim from team-dct/src/styles/tokens.css. Light and dark
   are both authored; dark is not an inversion of light. */
:root,
:root[data-resolved-theme="light"] {
  --surface: #fafaf6;
  --surface-2: #f4f3ee;
  --surface-3: #efece4;
  --surface-inverse: #0a0907;

  --ink-strong: #0a0907;
  --ink: #1a1815;
  --ink-2: #5d5a52;
  --ink-3: #8b857a;
  --ink-4: #c0bcb3;
  --ink-inverse: #fafaf6;

  --border-hairline: #e8e4dc;
  --border-strong: #4a4742;
  --focus-ring: #0a0907;

  /* The hero treatment. In light mode the veil IS the cream surface, so the
     photographs frost rather than dim and the hero still reads as a light
     room. Same gradient, opposite behaviour, one token. */
  --veil: 250 250 246;
  --veil-1: 0.16; --veil-2: 0.42; --veil-3: 0.92; --veil-4: 0.985;
  --sheet-rest: 0.42;
  --wall-brightness: 1.10;
  --wall-saturate: 0.88;

  /* Borders recede as translucent ink, darker than the surface. */
  --line: color-mix(in srgb, var(--ink-strong) 9%, transparent);
  --line-2: color-mix(in srgb, var(--ink-strong) 16%, transparent);

  /* Borders before shadows; shadow only where a surface genuinely floats. */
  --lift-1:
    0 1px 1px color-mix(in srgb, var(--ink-strong) 5%, transparent),
    0 2px 6px color-mix(in srgb, var(--ink-strong) 5%, transparent),
    0 10px 28px color-mix(in srgb, var(--ink-strong) 5%, transparent);
  --lift-2:
    0 1px 2px color-mix(in srgb, var(--ink-strong) 7%, transparent),
    0 8px 20px color-mix(in srgb, var(--ink-strong) 7%, transparent),
    0 26px 64px color-mix(in srgb, var(--ink-strong) 8%, transparent);
}

:root[data-resolved-theme="dark"] {
  --surface: #0a0907;
  --surface-2: #131210;
  --surface-3: #1a1816;
  --surface-inverse: #fafaf6;

  --ink-strong: #fafaf6;
  --ink: #e8e4dc;
  --ink-2: #b6b0a4;
  --ink-3: #7a756c;
  --ink-4: #4a4742;
  --ink-inverse: #0a0907;

  --border-hairline: #1f1d1a;
  --border-strong: #5a5750;
  --focus-ring: #fafaf6;

  --veil: 10 9 7;
  --veil-1: 0.10; --veil-2: 0.30; --veil-3: 0.86; --veil-4: 0.97;
  --sheet-rest: 0.5;
  --wall-brightness: 0.98;
  --wall-saturate: 1;

  --line: color-mix(in srgb, var(--ink-strong) 10%, transparent);
  --line-2: color-mix(in srgb, var(--ink-strong) 18%, transparent);

  --lift-1:
    0 1px 1px rgb(0 0 0 / 0.34),
    0 2px 6px rgb(0 0 0 / 0.26),
    0 10px 28px rgb(0 0 0 / 0.20);
  --lift-2:
    0 1px 2px rgb(0 0 0 / 0.40),
    0 8px 20px rgb(0 0 0 / 0.32),
    0 26px 64px rgb(0 0 0 / 0.26);
}

/* ----------------------------------------------------- rhythm and motion */
:root {
  --font-sans: "Geist", "Geist Fallback", ui-sans-serif, system-ui, sans-serif;
  --font-mono: "Geist Mono", "Geist Mono Fallback", ui-monospace, monospace;

  --type-display-size: clamp(2.75rem, 8vw, 5.5rem);
  --type-display-line: 1.05;
  --type-display-track: -0.035em;

  --type-h2-size: clamp(2rem, 4vw, 3.25rem);
  --type-h2-line: 1.1;
  --type-h2-track: -0.025em;

  --type-h3-size: 1.5rem;
  --type-h3-line: 1.2;
  --type-h3-track: -0.015em;

  --type-body-l: 1.125rem;
  --type-body: 1rem;
  --type-caption: 0.75rem;
  --type-caption-track: 0.18em;
  --type-ordinal: 0.875rem;
  --type-ordinal-track: 0.04em;

  --space-section: clamp(96px, 12vw, 192px);
  --space-h2-to-body: clamp(24px, 3vw, 48px);
  --space-eyebrow-to-h2: 12px;
  --space-body-to-cta: clamp(32px, 4vw, 64px);
  --space-card-gap: clamp(20px, 2.5vw, 32px);
  --space-gutter: clamp(20px, 4vw, 48px);

  --container-wide: 1280px;
  --container-content: 1040px;
  --container-reading: 720px;

  --duration-snap: 120ms;
  --duration-base: 240ms;
  --duration-lift: 400ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out-strong: cubic-bezier(0.16, 1, 0.3, 1);
  --duration-reveal: 760ms;
  --reveal-stagger: 72ms;
  --reveal-shift: 18px;
}

/* ------------------------------------------------------------------ base */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scrollbar-gutter: stable;
  overscroll-behavior-y: none;
  color-scheme: light;
}
:root[data-resolved-theme="dark"] { color-scheme: dark; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  position: relative;               /* atmosphere anchors here, never fixed */
  background: var(--surface);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--type-body);
  line-height: 1.55;
  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

img { display: block; max-width: 100%; height: auto; }
button { font: inherit; color: inherit; background: none; border: none; }

::selection { background: var(--ink-strong); color: var(--ink-inverse); }
:root { accent-color: var(--ink-strong); caret-color: var(--ink-strong); }
* { -webkit-tap-highlight-color: transparent; }
a, button { touch-action: manipulation; }

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: var(--surface-2); }
::-webkit-scrollbar-thumb { background: var(--ink-4); border-radius: 99px; border: 3px solid var(--surface-2); }
::-webkit-scrollbar-thumb:hover { background: var(--ink-3); }

:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; border-radius: 2px; }
:focus:not(:focus-visible) { outline: none; }
[id] { scroll-margin-top: 5.5rem; }

/* ------------------------------------------------------------ typography */
h1, h2, h3 { margin: 0; text-wrap: balance; text-box: trim-both cap alphabetic; }
p { margin: 0; text-wrap: pretty; }

.display {
  font-size: var(--type-display-size);
  line-height: var(--type-display-line);
  letter-spacing: var(--type-display-track);
  font-weight: 700;
  color: var(--ink-strong);
}
.h2 {
  font-size: var(--type-h2-size);
  line-height: var(--type-h2-line);
  letter-spacing: var(--type-h2-track);
  font-weight: 600;
  color: var(--ink-strong);
}
.h3 {
  font-size: var(--type-h3-size);
  line-height: var(--type-h3-line);
  letter-spacing: var(--type-h3-track);
  font-weight: 600;
  color: var(--ink-strong);
}
.lede { font-size: var(--type-body-l); line-height: 1.6; color: var(--ink-2); max-width: 36ch; }
@media (min-width: 48rem) { .lede { max-width: 52ch; } }
.body { color: var(--ink-2); max-width: 64ch; }

.caption {
  font-family: var(--font-mono);
  font-size: var(--type-caption);
  text-transform: uppercase;
  letter-spacing: var(--type-caption-track);
  line-height: 1.35;
  color: var(--ink-2);
  font-weight: 500;
}
.ordinal {
  font-family: var(--font-mono);
  font-size: var(--type-ordinal);
  letter-spacing: var(--type-ordinal-track);
  font-weight: 500;
  color: var(--ink-2);
}
.num { font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }

.shell { width: 100%; max-width: var(--container-wide); margin-inline: auto; padding-inline: var(--space-gutter); }

/* ------------------------------------------------------------------- nav */
.nav {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--surface) 86%, transparent);
  backdrop-filter: blur(14px) saturate(1.4);
  border-bottom: 1px solid var(--line);
}
.nav-in { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 4rem; }
.wordmark {
  display: inline-flex; align-items: center; gap: 0.6rem; min-height: 2.75rem;
  color: var(--ink-strong); text-decoration: none; font-weight: 600; letter-spacing: -0.018em;
}
.wordmark .mk { display: block; width: 1.6rem; height: 1.6rem; }
.nav-right { display: flex; align-items: center; gap: 0.5rem; }
.nav-links { display: none; gap: 1.5rem; margin-right: 0.5rem; }
@media (min-width: 60rem) { .nav-links { display: flex; } }
.nav-links a {
  display: inline-flex; align-items: center; min-height: 2.75rem;
  color: var(--ink-2); text-decoration: none; font-size: 0.9375rem;
  transition: color var(--duration-snap) var(--ease-out);
}
.nav-links a:hover { color: var(--ink-strong); transition-duration: var(--duration-base); }

/* Theme control: system / light / dark, the same three-state choice the
   public site offers. Never a single toggle, because "follow the system" is a
   real preference and dropping it is a regression. */
.theme {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 3px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface-2);
}
.theme button {
  display: grid; place-items: center; width: 2rem; height: 2rem; border-radius: 999px;
  color: var(--ink-2); cursor: pointer;
  transition: background-color var(--duration-snap) var(--ease-out), color var(--duration-snap) var(--ease-out);
}
.theme button:hover { color: var(--ink-strong); transition-duration: var(--duration-base); }
.theme button[aria-pressed="true"] { background: var(--surface); color: var(--ink-strong); box-shadow: var(--lift-1); }
.theme svg { width: 15px; height: 15px; }

/* --------------------------------------------------------------- buttons */
/* Five states on every control: rest, hover, focus-visible, active, disabled.
   Nothing moves on hover; feedback is fill, border and shadow. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  min-height: 3rem; padding: 0 1.5rem; border-radius: 999px; border: 1px solid transparent;
  font-size: 0.9375rem; font-weight: 550; letter-spacing: -0.004em; text-decoration: none; cursor: pointer;
  transition: background-color var(--duration-snap) var(--ease-out),
              border-color var(--duration-snap) var(--ease-out),
              color var(--duration-snap) var(--ease-out),
              box-shadow var(--duration-snap) var(--ease-out);
}
.btn:hover { transition-duration: var(--duration-base); }    /* in fast, out slow */
.btn-primary { background: var(--ink-strong); color: var(--ink-inverse); box-shadow: var(--lift-1); }
.btn-primary:hover { background: var(--ink); box-shadow: var(--lift-2); }
.btn-primary.is-press { background: var(--ink-2); box-shadow: var(--lift-1); }
.btn-ghost { border-color: var(--line-2); color: var(--ink-strong); }
.btn-ghost:hover { background: color-mix(in srgb, var(--ink-strong) 5%, transparent); border-color: var(--border-strong); }
.btn-ghost.is-press { background: color-mix(in srgb, var(--ink-strong) 9%, transparent); }
.btn[aria-disabled="true"] { opacity: 0.45; pointer-events: none; }
.btn .arw { transition: transform var(--duration-base) var(--ease-out); }
.btn:hover .arw { transform: translateX(3px); }

/* ------------------------------------------------------------------ hero */
/* THE COMPOSITION. One centred axis at every width. The wall covers the whole
   frame; the type sits on the centre line beneath it.
   Measured across 63 frames the median mean-luminance is 0.498, squarely in
   the band where no treatment rescues text without wrecking the photograph.
   So the treatment is not a rescue, it is the composition: the wall is clear
   at the top where the eye lands, the sides fall away so the grid vignettes
   into the page instead of being sliced by the viewport edge, and a deep pool
   of the page's own surface gathers under the type. */
.hero { position: relative; isolation: isolate; background: var(--surface); border-bottom: 1px solid var(--line); overflow: clip; }
.hero-wall { position: absolute; inset: 0; z-index: 0; display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px; }
.hero-wall .t { overflow: hidden; background: var(--surface-2); }
.hero-wall img {
  width: 100%; height: 100%; object-fit: cover;
  filter: saturate(var(--wall-saturate)) brightness(var(--wall-brightness));
}
@media (max-width: 47.99rem) { .hero-wall .t:nth-child(n + 9) { display: none; } }
@media (min-width: 48rem) { .hero-wall { grid-template-columns: repeat(6, 1fr); } }

.hero-veil { position: absolute; inset: 0; z-index: 1; }
/* Vertical: the wall reads at the top, the field gathers under the type. */
.hero-veil::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(
    to bottom,
    rgb(var(--veil) / var(--veil-1)) 0%,
    rgb(var(--veil) / var(--veil-2)) 15%,
    rgb(var(--veil) / var(--veil-3)) 34%,
    rgb(var(--veil) / var(--veil-4)) 55%,
    rgb(var(--veil) / 1) 78%
  );
}
/* Horizontal: the sides fall away, so the collage resolves into the page. */
.hero-veil::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(
    to right,
    rgb(var(--veil) / 0.94) 0%,
    rgb(var(--veil) / 0.34) 15%,
    rgb(var(--veil) / 0) 34%,
    rgb(var(--veil) / 0) 66%,
    rgb(var(--veil) / 0.34) 85%,
    rgb(var(--veil) / 0.94) 100%
  );
}

.hero-in {
  position: relative; z-index: 3;
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding-block: clamp(8rem, 30vw, 13rem) clamp(3.5rem, 8vw, 6rem);
}
@media (min-width: 62rem) { .hero-in { padding-block: clamp(9rem, 21vw, 15rem) clamp(4rem, 7vw, 7rem); } }
.hero-eyebrow { display: inline-flex; align-items: center; gap: 0.6rem; margin-bottom: var(--space-eyebrow-to-h2); }
.hero-eyebrow .rule { display: block; width: 20px; height: 1px; background: var(--ink-3); }
.hero h1 { max-width: 17ch; margin-bottom: var(--space-h2-to-body); }
.hero .lede { margin-bottom: var(--space-body-to-cta); max-width: 46ch; }
.hero-cta { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.75rem; }
.hero-cta .btn { flex: 1 1 auto; min-width: 14rem; }
@media (min-width: 30rem) { .hero-cta .btn { flex: 0 0 auto; } }

.hero-facts {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem 2rem;
  margin: clamp(3rem, 6vw, 4.5rem) auto 0; padding-top: 1.75rem;
  border-top: 1px solid var(--line); width: 100%; max-width: var(--container-content);
}
@media (min-width: 52rem) { .hero-facts { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.hero-facts div { text-align: center; }
.hero-facts dt { margin-bottom: 0.45rem; }
.hero-facts dd { margin: 0; font-size: 1.0625rem; font-weight: 550; color: var(--ink-strong); }

/* --------------------------------------------------------------- section */
.section { padding-block: var(--space-section); }
.section + .section { border-top: 1px solid var(--line); }
.section-head { margin-bottom: clamp(2.5rem, 5vw, 4rem); max-width: var(--container-reading); }
.section-head .caption { display: block; margin-bottom: var(--space-eyebrow-to-h2); }
.section-head h2 { margin-bottom: var(--space-h2-to-body); }
.section-centered { margin-inline: auto; text-align: center; }
.section-centered .body { margin-inline: auto; }

/* ---------------------------------------------------------- the sessions */
.paths { display: grid; gap: var(--space-card-gap); }
@media (min-width: 56rem) { .paths { grid-template-columns: 1fr 1fr; } }
.path {
  display: flex; flex-direction: column; padding: clamp(1.75rem, 3vw, 2.5rem);
  border: 1px solid var(--line); border-radius: 20px; background: var(--surface-2); text-align: left;
  transition: border-color var(--duration-base) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out),
              background-color var(--duration-base) var(--ease-out);
}
.path:hover { border-color: var(--line-2); box-shadow: var(--lift-1); background: var(--surface-3); }
.path-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 1.5rem; margin-bottom: 1.25rem; }
.path h3 { margin-bottom: 0.4rem; }
.path .amount { font-size: clamp(2.25rem, 4vw, 2.75rem); font-weight: 700; line-height: 1; letter-spacing: -0.03em; color: var(--ink-strong); }
.path .per { display: block; margin-top: 0.4rem; }
.path .body { margin-bottom: 1.75rem; }

/* The contact sheet. The keeper is the frame that KEEPS its colour; the rest
   of the sheet sits in grey. No accent hue is needed, because the photograph
   is the accent. Concentric radii: inner = outer − padding. */
.sheet { margin-bottom: 1.75rem; }
.sheet-strip {
  display: grid; grid-template-columns: repeat(10, 1fr); gap: 2px;
  padding: 6px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-3);
}
.sheet-strip .cell { position: relative; aspect-ratio: 4 / 5; overflow: hidden; border-radius: 2px; background: var(--surface-3); }
.sheet-strip .cell img {
  width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(1) opacity(var(--sheet-rest));
  transition: filter var(--duration-base) var(--ease-out);
}
.sheet-strip .cell.keep img { filter: none; }
.sheet-strip .cell.keep::after { content: ""; position: absolute; inset: 0; border: 1.5px solid var(--ink-strong); border-radius: 2px; }
.sheet-note { display: flex; justify-content: space-between; gap: 1rem; margin-top: 0.75rem; }
.sheet-note .kept { color: var(--ink-strong); }

.path ul { list-style: none; margin: 0 0 2rem; padding: 0; display: grid; gap: 0.7rem; }
.path li { display: grid; grid-template-columns: 1rem 1fr; gap: 0.7rem; align-items: start; color: var(--ink-2); }
.path li svg { margin-top: 0.36rem; color: var(--ink-strong); }
.path .btn { margin-top: auto; width: 100%; }

/* -------------------------------------------------------------- the work */
.work-nav { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 2rem; }
.chip {
  min-height: 2.75rem; padding: 0 1.15rem; border-radius: 999px; border: 1px solid var(--line);
  color: var(--ink-2); font-size: 0.9375rem; cursor: pointer;
  transition: background-color var(--duration-snap) var(--ease-out),
              color var(--duration-snap) var(--ease-out),
              border-color var(--duration-snap) var(--ease-out);
}
.chip:hover { color: var(--ink-strong); border-color: var(--border-strong); transition-duration: var(--duration-base); }
.chip[aria-pressed="true"] { background: var(--ink-strong); color: var(--ink-inverse); border-color: var(--ink-strong); }

.grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
@media (min-width: 40rem) { .grid { grid-template-columns: repeat(3, 1fr); gap: 10px; } }
@media (min-width: 64rem) { .grid { grid-template-columns: repeat(4, 1fr); gap: 12px; } }
.frame {
  position: relative; overflow: hidden; border-radius: 12px; margin: 0;
  background: var(--surface-2); border: 1px solid var(--line); aspect-ratio: 4 / 5;
}
.frame img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--duration-lift) var(--ease-out-strong); }
.frame:hover img { transform: scale(1.03); }
.frame figcaption {
  position: absolute; inset-inline: 0; bottom: 0; padding: 2.5rem 0.85rem 0.7rem;
  background: linear-gradient(to top, rgb(10 9 7 / 0.88), transparent);
  color: #fafaf6;                      /* always light: it sits on a photograph */
  opacity: 0; transition: opacity var(--duration-base) var(--ease-out);
}
.frame:hover figcaption, .frame:focus-within figcaption { opacity: 1; }
.frame.is-hidden { display: none; }

/* ------------------------------------------------------------------ steps */
.steps { display: grid; gap: 2rem; }
@media (min-width: 52rem) { .steps { grid-template-columns: repeat(3, 1fr); gap: var(--space-card-gap); } }
.step { padding-top: 1.25rem; border-top: 1px solid var(--border-strong); }
.step .ordinal { display: block; margin-bottom: 0.85rem; }
.step h3 { margin-bottom: 0.55rem; }

/* ------------------------------------------------------------------ about */
.about { display: grid; gap: 2.5rem; align-items: start; }
@media (min-width: 52rem) { .about { grid-template-columns: 18rem 1fr; gap: clamp(2.5rem, 5vw, 4.5rem); } }
.portrait {
  position: relative; aspect-ratio: 4 / 5; border-radius: 16px; overflow: hidden;
  border: 1px solid var(--line); background: var(--surface-2); max-width: 18rem;
}
.portrait img { width: 100%; height: 100%; object-fit: cover; }
.portrait-plate {
  position: absolute; inset: 0; display: grid; place-content: center; gap: 0.7rem;
  text-align: center; padding: 1.5rem; background: var(--surface-2);
}
.portrait-plate .mono {
  font-family: var(--font-mono); font-size: clamp(2.5rem, 8vw, 3.25rem);
  font-weight: 600; letter-spacing: -0.03em; color: var(--ink-strong); line-height: 1;
}
.about-body p + p { margin-top: 1rem; }

/* ------------------------------------------------------------------- book */
.book {
  border: 1px solid var(--line); border-radius: 24px; background: var(--surface-2);
  padding: clamp(2rem, 5vw, 3.5rem); text-align: center;
}
.book .lede { margin-inline: auto; }
.book-cta { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.75rem; margin: var(--space-body-to-cta) 0 2rem; }
.book-cta .btn { flex: 1 1 auto; min-width: 13rem; }
@media (min-width: 34rem) { .book-cta .btn { flex: 0 0 auto; } }
.terms { display: grid; gap: 0.6rem; padding-top: 1.75rem; border-top: 1px solid var(--line); max-width: var(--container-reading); margin-inline: auto; }
.terms p { font-size: 0.9375rem; color: var(--ink-2); }

/* ----------------------------------------------------------------- footer */
.footer { border-top: 1px solid var(--line); padding-block: 2.5rem 3rem; }
.footer-in { display: flex; flex-wrap: wrap; gap: 0.5rem 2rem; justify-content: space-between; align-items: center; }
.footer-links { display: flex; flex-wrap: wrap; gap: 0.35rem 1.25rem; }
.footer-links a {
  display: inline-flex; align-items: center; min-height: 2.75rem;
  color: var(--ink-2); text-decoration: none; font-size: 0.9375rem;
  transition: color var(--duration-snap) var(--ease-out);
}
.footer-links a:hover { color: var(--ink-strong); transition-duration: var(--duration-base); }

/* -------------------------------------------------- scroll-reveal system */
/* The house language: [data-rise] settles into place once, gated behind
   html.js-reveal-ready which an inline head script sets before first paint.
   If the script never runs the class is never added and nothing is ever
   trapped invisible. */
html.js-reveal-ready [data-rise] {
  opacity: 0;
  transform: translate3d(0, var(--reveal-shift), 0);
  transition: opacity var(--duration-reveal) var(--ease-out-strong),
              transform var(--duration-reveal) var(--ease-out-strong);
  transition-delay: calc(var(--rise-i, 0) * var(--reveal-stagger));
  will-change: opacity, transform;
}
html.js-reveal-ready [data-rise].is-inview { opacity: 1; transform: none; }
html.js-reveal-ready [data-rise].is-settled { will-change: auto; }

/* ------------------------------------------------------- reduced motion */
/* A variant, not a kill switch: the movement becomes a cross-fade, so the
   visitor still perceives that something arrived. */
@media (prefers-reduced-motion: reduce) {
  html.js-reveal-ready [data-rise] { transform: none; }
  .frame:hover img, .btn:hover .arw { transform: none; }
}

/* --------------------------------------------------------- forced colors */
@media (forced-colors: active) {
  .hero-veil::before, .hero-veil::after { display: none; }
  .btn, .chip, .frame, .path, .book, .theme { border: 1px solid CanvasText; }
}
