/* DORN design tokens. The contract: canon/brand-system.md explains these
   values; dorn-tokens.json mirrors them exactly. Any change updates all
   three files together, via the strategy session.
   Naming: semantic tokens are the working vocabulary; raw palette tokens
   exist so the palette is auditable. Never introduce a literal value where
   a token exists. */

:root {

  /* ---------- Raw palette ---------- */
  --dorn-paper: #F4F2EC;
  --dorn-off-black: #1A1916;
  --dorn-umber-grey: #3E3A33;
  --dorn-warm-mid: #8A857A;
  --dorn-warm-light: #E7E4DB;
  --dorn-slate: #56646F;
  --dorn-ochre: #A67C3D; /* reserved; not deployed on the site */

  /* ---------- Semantic colour ---------- */
  --color-bg: var(--dorn-paper);
  --color-bg-alt: var(--dorn-warm-light);
  --color-text-primary: var(--dorn-off-black);
  --color-text-secondary: var(--dorn-umber-grey);
  --color-text-tertiary: var(--dorn-warm-mid); /* disabled and hairline duty only; below body-contrast threshold */
  --color-hairline: var(--dorn-warm-mid);
  --color-accent: var(--dorn-slate); /* interactive states only, never headings, never at scale */

  /* ---------- Inverted (dark-band) semantic colour ---------- */
  /* The footer closing band's inverted colours (§BS-8a, founder-ratified
     25 July 2026). Every invert token aliases an existing palette colour;
     no new hex. Scoped to that band only, never a general dark mode. */
  --color-bg-invert: var(--dorn-off-black);
  --color-text-primary-invert: var(--dorn-paper);
  --color-text-secondary-invert: var(--dorn-warm-light);

  /* ---------- Typefaces and weights ---------- */
  --font-display: 'Marcellus', serif; /* caps, letterspaced, never below 28px, never running copy */
  --font-body: 'Geist', sans-serif;   /* 400 and 500 only */
  --weight-regular: 400;
  --weight-structural: 500;

  /* ---------- Type scale ---------- */
  /* These are the SITE rungs. Document type is separate and lives in the
     --doc-* block at the foot of this file; the two scales diverged on
     27 July 2026 and neither tracks the other (§BS-1, §BS-6). */
  --text-micro: 0.75rem;     /* site footer legal line. Was 0.8rem, which was the document value; flattened to one site value 27 July 2026 (§BS-1). Document footers/page numbers use --doc-micro-size (8pt), unaffected */
  --text-label: 0.85rem;
  --text-body-sm: 0.9rem;    /* DEPLOYED: the tagline's compact-breakpoint size (§BS-1 body-lg row, "reuses the existing body-sm rung"). Marked "retired" here until 27 July 2026 while the build shipped the value as a literal - the rung cannot be both retired and reused, and it is reused */
  --text-body: 0.85rem;      /* site running copy. Was 1rem, which was the document value; flattened to one site value 27 July 2026 (§BS-1). Document body uses --doc-body-size (10pt), unaffected. Equal to --text-label by coincidence of value, not of meaning - do not collapse them */
  --text-body-lg: 1.125rem;
  --text-display-2: clamp(1.75rem, 4vw, 2.5rem); /* reserved; not deployed (§BS-1). Floor equals the 28px Marcellus minimum */
  --text-display-1: clamp(4rem, 12vw, 7rem);     /* wordmark only */

  /* ---------- Line-heights ---------- */
  --lh-solid: 1;      /* wordmark */
  --lh-display: 1.15; /* display-2 headings */
  --lh-tight: 1.2;    /* labels, captions, tagline */
  --lh-heading: 1.3;  /* document headings */
  --lh-doc: 1.45;     /* document body */
  --lh-body: 1.65;    /* site body */

  /* ---------- Letter-spacing ---------- */
  --ls-body: normal;
  --ls-emphasis: 0.02em;  /* Marcellus headlines, Geist 500 emphasis lines */
  --ls-wordmark: 0.03em;  /* interim live-text value; final value set by the SVG wordmark task */
  --ls-caps: 0.06em;      /* every all-caps Geist string */

  /* ---------- Measure ---------- */
  /* --measure-min is a LAYOUT value, consumed by --column-width-short below.
     Its `ch` resolves against the consuming element's own font-size - in
     practice .about-content's inherited 1rem, not the paragraph's 0.85rem -
     so it is 583.4px, unchanged by the 27 July 2026 type flattening. Do not
     "correct" it downward (§BS-3).
     There is deliberately no --measure-max token (removed 27 July 2026). The
     site's measure ceiling is a measured rendered-character count, 126, set
     against real shipped prose at a recorded reference viewport (§BS-1) - it
     cannot be expressed as a `ch` value, and the 70ch token that used to sit
     here invited exactly the ch-for-characters substitution §BS-1 now
     forbids. Documents keep the 55-70ch cap (§BS-6). */
  --measure-min: 55ch;

  /* ---------- Spacing ---------- */
  --space-xs: 0.5rem;   /*  8px */
  --space-sm: 0.75rem;  /* 12px, the single half-step */
  --space-md: 1rem;     /* 16px; reserved, not deployed (§BS-2) */
  --space-lg: 1.5rem;   /* 24px */
  --space-xl: 2rem;     /* 32px */
  --space-2xl: 2.5rem;  /* 40px; reserved, not deployed (§BS-2, formerly the footer rhythm; superseded by --space-xl 25 July 2026) */
  --space-3xl: 3rem;    /* 48px */
  --space-4xl: 4rem;    /* 64px */
  --space-caption-pair: 0.125rem; /* component constant: project name to location */

  /* ---------- Layout ---------- */
  /* Breakpoints cannot be consumed inside media queries as custom
     properties; these are the reference values every query must match. */
  --bp-compact: 640px;
  --bp-caption: 900px;
  /* Height-based breakpoints (§BS-8a viewport-fit amendment, 25 July 2026;
     fallback thresholds corrected the same day). The closing section cannot hold
     its content in one 100vh box below --bp-fit-height, and cannot hold it with
     acceptable margin below --bp-fallback-height at any width, or below
     --bp-fallback-height-compact on viewports --bp-compact or narrower. Reference
     only, like every other breakpoint here. The former --bp-fallback-width (340px)
     was removed 25 July 2026: the width clause did no work. */
  --bp-fit-height: 750px;
  --bp-fallback-height: 576px;
  --bp-fallback-height-compact: 624px;
  --content-max: 760px;
  --frame-width: min(56vw, 760px);
  --frame-height-max: 68vh;
  --frame-height-max-compact: 60vh; /* the image frame's own cap at <=640px (§BS-3, "Breakpoint: compact"). Tokenised 27 July 2026: it had always shipped as a bare literal with no token to conform to, so checklist item 17's "pre-existing conforming literals" carve-out never covered it - 60vh conformed to nothing */
  --column-width: min(56vw, 760px, calc(68vh * 2 / 3)); /* matches a rendered 2:3 portrait */
  /* Footer-column floor, short-wide viewports (§BS-3, §BS-8a). A purely
     height-derived column narrows as the viewport shortens, lengthening the
     paragraph on exactly the viewports with least room, so it floors at
     --measure-min instead, which also restores most of the 55-character measure
     the stock formula loses there. Best-effort, not a guarantee: the 56vw and
     760px terms can still bind below it (§BS-3). */
  --column-floor-compact: 280px; /* reserved; not deployed. Retired 25 July 2026 by the phone alignment rule (§BS-8a) */
  /* Phone alignment rule (§BS-8a, 25 July 2026): the column spans margin to
     margin against the wordmark's own 2rem offset, so its left edge lands on the
     wordmark instead of floating with the width formula's binding term. */
  --column-width-compact: calc(100vw - 4rem);
  --column-width-short: min(56vw, 760px, max(calc(68vh * 2 / 3), var(--measure-min)));
  --side-margin-desktop: var(--space-3xl);
  --side-margin-compact: var(--space-lg);

  /* ---------- Motion ---------- */
  --motion-scroll-duration: 1000ms;
  --motion-scroll-ease: cubic-bezier(0.25, 0.1, 0.25, 1);
  --motion-top-duration: 650ms;    /* back-to-top, same curve as the stack; founder-tuned in the build */
  --motion-intro-hold: 900ms;      /* first-scroll clay intro hold before reverting */
  --motion-reveal-duration: 200ms; /* clay-model crossfade */
  --motion-reveal-ease: ease-in-out;
  --motion-lightbox-duration: 300ms; /* trial: image lightbox. Same curve as the
    clay crossfade but held slightly longer - a full-screen image arriving is a
    bigger visual jump than the clay swap, so a flat 200ms read as a flicker
    rather than a reveal in testing. Not yet ratified into canon (§BE); this
    mechanic is a founder trial, ratify or remove once tested. */
  --motion-lightbox-ease: ease-in-out;
  --motion-ui-duration: 150ms;    /* all colour state changes */
  --motion-ui-ease: ease;
  /* Footer closing-band wordmark colour swap, entering the band (§BS-8a,
     founder-ratified 25 July 2026). Steeper ease-in than
     --motion-scroll-ease: keeps the wordmark's colour close to
     its start value for most of the footer-band transition, then swaps
     rapidly right at the end, so it doesn't go pale against paper before
     its position has actually reached the dark band. */
  --motion-wordmark-invert-ease: cubic-bezier(0.8, 0, 1, 1);
  /* Mirror of the above, for the reverse direction (leaving the footer
     band): CSS transitions take their timing-function from the *ending*
     state's rule, so entering and leaving need separate curves, not one
     shared value. Entering stays pale-then-snaps (ease-in); leaving needs
     the opposite shape - snap dark early, then hold - since the wordmark
     exits the dark zone almost immediately on the way back up. */
  --motion-wordmark-invert-ease-out: cubic-bezier(0, 0, 0.2, 1);
  --swipe-threshold: 50px;        /* touch swipe distance to trigger a section move */

  /* ---------- Focus ---------- */
  --focus-width: 2px;             /* solid, accent colour */
  --focus-offset-text: 2px;
  --focus-offset-control: 4px;
  --focus-offset-display: 8px;

  /* ---------- Rules and layers ---------- */
  --hairline: 1px;
  --z-content: 1;
  --z-lightbox: 15; /* trial: image lightbox overlay - stays below --z-chrome
    so the fixed wordmark shows on top of an enlarged image, per founder
    direction (no separate exit control; the wordmark closes it like anywhere
    else on screen) */
  --z-chrome: 20;   /* fixed wordmark */
  --z-overlay: 100; /* skip-link */

  /* ---------- Document layout (quotes, invoices, terms one-pager) ---------- */
  /* Not consumed by the site build; carried here so this file and
     dorn-tokens.json stay in parity per brand-system.md §BS-8. */
  --doc-page: A4 portrait;
  --doc-margin-top: 24mm;
  --doc-margin-side: 20mm;
  --doc-margin-bottom: 24mm;
  --doc-wordmark-cap-height: 8mm;
  --doc-body-size: 10pt;
  --doc-heading-size: 11pt;
  --doc-title-size: 13pt;
  --doc-label-size: 8.5pt;
  --doc-micro-size: 8pt;
  --doc-line-height: 1.45;
  --doc-table-rule: 0.5pt;
  /* Numeric figures: tabular. No Marcellus in documents; the wordmark
     carries the serif. No vertical table rules, no fills. */
}
