/* ==========================================================================
   Cascade layers

   Precedence is declared here, once, instead of being an accident of the order
   in which each page lists its stylesheets. Later layers win over earlier ones
   regardless of selector specificity, so a page rule no longer needs to
   out-specify a component rule to override it.

   Two consequences worth knowing before editing:
     · a more specific rule in an earlier layer now loses to a weaker rule in a
       later layer — the reverse of unlayered CSS;
     · for !important declarations the order is inverted, so an !important in
       an earlier layer beats one in a later layer.

   @font-face rules stay outside the layers: they are not cascade participants.
   ========================================================================== */

@layer tokens, base, media, components, motion, pages;

/* ==========================================================================
   DELVANO — Design tokens
   Source of truth: DELVANO_MASTER_BUILD_SPEC.md §5 (identity), §6 (grid & spacing)
   Nothing in this file may be overridden ad hoc in page CSS.
   ========================================================================== */

/* Font faces are intentionally unlayered — @font-face does not take part
   in the cascade, so a layer would add nothing but a constraint. */
@font-face {
  font-family: "Instrument Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/instrument-serif-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Instrument Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/instrument-serif-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Instrument Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/instrument-serif-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 300 500;
  font-display: swap;
  src: url("../fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 300 500;
  font-display: swap;
  src: url("../fonts/inter-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@layer tokens {
/* --------------------------------------------------------------------------
   Fonts — self-hosted, SIL Open Font License
   -------------------------------------------------------------------------- */







/* Inter is served as a variable font: one file covers 300–500. */




:root {
  /* ------------------------------------------------------------------------
     Colour — spec §5
     Obsidian and Ivory dominate. Stone is secondary information.
     Bronze is an accent only, never a surface.
     ------------------------------------------------------------------------ */
  --obsidian: #0b0b0a;
  --ivory: #f2efe8;
  --stone: #a6a198;
  --bronze: #b5966d;

  /* The same four colours as channel triplets. Any translucent use composes
     from these rather than re-typing the numbers — a palette change is then a
     single edit here instead of 23 scattered literals. */
  --obsidian-rgb: 11 11 10;
  --ivory-rgb: 242 239 232;
  --stone-rgb: 166 161 152;
  --bronze-rgb: 181 150 109;

  /* Derived neutrals — tonal steps between Obsidian and Ivory.
     Used for elevation, hairlines and material surfaces only. */
  --obsidian-raised: #100f0e;
  --obsidian-elevated: #151412;
  --obsidian-deep: #060605;
  --ivory-recessed: #e8e4da;
  --ivory-hairline: #d9d4c8;

  /* Semantic surface roles — dark context is the default */
  --surface: var(--obsidian);
  --surface-raised: var(--obsidian-raised);
  --ink: var(--ivory);
  --ink-muted: var(--stone);
  --accent: var(--bronze);

  /* Form feedback. Deliberately outside the brand palette: an error is not a
     brand moment. Tuned to clear AA on Obsidian. */
  --error-line: #d98a72;
  --error-ink: #e0a08c;
  --hairline: rgb(var(--ivory-rgb) / 0.11);
  --hairline-strong: rgb(var(--ivory-rgb) / 0.2);

  /* ------------------------------------------------------------------------
     Typography — spec §5
     Fluid across the whole range: mobile is recomposed, not scaled down.
     ------------------------------------------------------------------------ */
  --font-display: "Instrument Serif", "Iowan Old Style", "Palatino Linotype",
    Palatino, Georgia, serif;
  --font-ui: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    Helvetica, Arial, sans-serif;

  --text-display-xl: clamp(3.25rem, 1.6rem + 7vw, 8rem); /* 52 → 128 */
  --text-h1: clamp(2.75rem, 1.55rem + 5.1vw, 6rem); /* 44 → 96 */
  --text-h2: clamp(2.125rem, 1.3rem + 3.5vw, 4.5rem); /* 34 → 72 */
  --text-h3: clamp(1.625rem, 1.25rem + 1.6vw, 2.75rem); /* 26 → 44 */
  --text-h4: clamp(1.25rem, 1.09rem + 0.7vw, 1.75rem); /* 20 → 28 */
  --text-body-lg: clamp(1.0625rem, 1rem + 0.25vw, 1.25rem); /* 17 → 20 */
  --text-body: 1rem;
  --text-small: 0.875rem;
  --text-eyebrow: 0.6875rem; /* 11 */
  --text-ui: 0.75rem; /* 12 */

  --leading-display: 0.94;
  --leading-tight: 1.06;
  --leading-heading: 1.14;
  --leading-body: 1.6;
  --leading-relaxed: 1.7;

  --tracking-display: -0.015em;
  --tracking-tight: -0.01em;
  --tracking-normal: 0;
  --tracking-wide: 0.06em;
  --tracking-eyebrow: 0.18em;
  --tracking-wordmark: 0.22em;

  /* ------------------------------------------------------------------------
     Spacing — spec §6 : 8 / 16 / 24 / 32 / 48 / 64 / 96 / 128 / 160
     ------------------------------------------------------------------------ */
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2rem;
  --space-5: 3rem;
  --space-6: 4rem;
  --space-7: 6rem;
  --space-8: 8rem;
  --space-9: 10rem;

  /* Fixed chrome. The header height is consumed by the header itself and by
     the mobile menu's top padding; anchors and stacked heroes clear it. */
  --header-h: 5.25rem;
  --header-clearance: 7rem;
  --hero-top: 8.5rem;
  --hero-top-compact: 7.5rem;
  --sticky-top: 8rem;

  /* Section rhythm: 80–96px mobile → 128–160px large desktop */
  --section-y: clamp(5rem, 2.2rem + 7vw, 10rem);
  --section-y-tight: clamp(4rem, 2.4rem + 4vw, 6.5rem);

  /* ------------------------------------------------------------------------
     Grid — spec §6
     12 col / max 1440 / 48–64 margins · 8 col / 32 · 4 col / 20 + 16 gutter
     ------------------------------------------------------------------------ */
  --content-max: 1440px;
  --gutter: 1.5rem; /* 24px desktop */
  --margin-x: clamp(1.25rem, 0.55rem + 2.6vw, 4rem); /* 20 → 64 */
  --columns: 12;

  /* Measure caps keep editorial copy readable at any width */
  --measure: 62ch;
  --measure-narrow: 46ch;
  --measure-tight: 34ch;

  /* ------------------------------------------------------------------------
     Motion — spec §15
     Micro 180–300 · Interface 350–600 · Editorial 700–1000 max
     ------------------------------------------------------------------------ */
  --dur-micro: 220ms;
  --dur-micro-slow: 300ms;
  --dur-ui: 420ms;
  --dur-ui-slow: 600ms;
  --dur-editorial: 700ms;
  --dur-cinematic: 900ms;

  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-editorial: cubic-bezier(0.16, 1, 0.3, 1);

  /* Stagger unit for line-by-line title reveals */
  --stagger: 80ms;

  /* ------------------------------------------------------------------------
     Breakpoints.

     CSS custom properties cannot be used inside @media, so these are a
     contract rather than tokens. Every media query in the codebase must use a
     value from one of the two lists below; tools/qa.mjs fails the build on any
     other. The two lists are not interchangeable.

     LAYOUT — the control ranges of spec §18, plus the point where the desktop
     navigation gives way to the mobile menu. These describe the device, and a
     new one should not be invented.

       under 768    mobile          @media (max-width: 767px)
       768–1023     tablet          @media (max-width: 1023px)
       1024–1439    desktop         @media (max-width: 1439px)
       1440+        large desktop   no query
       899          nav changeover  @media (max-width: 899px)

     COMPONENT — driven by the content of a single component rather than by a
     device class: the width at which that component's own composition stops
     working. Each is listed with what it governs, and none is used elsewhere.

       519   .principles      four columns collapse to one
       599   .approach        two columns collapse to one
             .field-row       paired fields stack
       639   .section-head    the label row stacks above the action

     Adding a component breakpoint means adding it here and to the list in
     tools/qa.mjs, with the component it serves. An undocumented value is
     indistinguishable from an accident.
     ------------------------------------------------------------------------ */

  --z-header: 100;
  --z-menu: 200;
  --z-lens: 50;
}

/* --------------------------------------------------------------------------
   Light context — the Ivory inversion used by the Start-a-Project block,
   the VERIDA case study and any section marked data-tone="light".
   Semantic roles flip; raw brand tokens never change.
   -------------------------------------------------------------------------- */
[data-tone="light"] {
  --surface: var(--ivory);
  --surface-raised: var(--ivory-recessed);
  --ink: var(--obsidian);
  --ink-muted: #6f6a61; /* Stone darkened for AA on Ivory */
  --hairline: rgb(var(--obsidian-rgb) / 0.13);
  --hairline-strong: rgb(var(--obsidian-rgb) / 0.26);
}

/* Reduced motion is honoured globally; JS also reads the same query. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-micro: 1ms;
    --dur-micro-slow: 1ms;
    --dur-ui: 1ms;
    --dur-ui-slow: 1ms;
    --dur-editorial: 1ms;
    --dur-cinematic: 1ms;
    --stagger: 0ms;
  }
}
}
