/* Tokens. Single source of truth, imported first. Three layers:
   primitives, semantic, component. Components never reach past layer 2. */

/* Layer 1 — primitives */
:root {
  /* ---------- COULEUR : fonds chauds ---------- */
  --ink-950: #0E0B09;   /* fond de page */
  --ink-900: #16110E;   /* surface de base */
  --ink-800: #1E1813;   /* window, card */
  --ink-700: #2A211A;   /* barre de titre, chrome */
  --ink-600: #3A2E24;   /* bordures */
  --ink-500: #5A4A3C;   /* active borders, disabled text */

  /* ---------- COULEUR : texte ---------- */
  --paper:      #F7F0E6;
  --paper-dim:  #C9BCAC;
  --paper-mute: #94867A;
  --cream:      #EFE1C8;  /* full-width inverted sections */

  /* ---------- COULEUR : orange signature ---------- */
  --orange-core:  #FF6A1F;  /* CTA fills, gauges, active state */
  --orange-lift:  #FF8C42;  /* accent text, icons, focus */
  --orange-deep:  #C2410C;  /* hard shadow, pressed state */
  --orange-ghost: rgba(255, 106, 31, 0.12);
  /* Accent rules, on the current orange. D-114. */
  --orange-veil:  rgba(255, 106, 31, 0.30);
  --orange-halo:  rgba(255, 106, 31, 0.45);

  /* ---------- COULEUR : voiles, filets d'un pixel ---------- */
  --paper-veil: rgba(247, 240, 230, 0.36);  /* thin rule over ink */
  --ink-veil:   rgba(14, 11, 9, 0.42);      /* the same rule over cream */

  /* ---------- COULEUR : accents pop ---------- */
  --mustard: #F2B33C;
  --teal:    #2FB6A8;
  --cherry:  #E4483C;
  --cobalt:  #3B5BD4;

  /* ---------- OMBRES : blur 0 partout ---------- */
  --shadow-sm:      3px 3px 0 var(--orange-deep);
  --shadow-md:      5px 5px 0 var(--orange-deep);
  --shadow-lg:      8px 8px 0 var(--orange-deep);
  /* Offset registration in warm ink: never pure black, never cold grey. */
  --shadow-plate:   6px 6px 0 var(--ink-600);
  --shadow-pressed: 1px 1px 0 var(--orange-deep);

  /* ---------- RAYONS : deux vocabulaires ---------- */
  --radius-os:   4px;     /* instrument layer: windows, badges, fields */
  --radius-pop:  9999px;  /* couche monde : pills, formes, pastilles */
  --radius-none: 0;       /* sections pleine largeur, bandes */

  /* SPACE: one scale */
  --space-1: 4px;   --space-2: 8px;   --space-3: 12px;
  --space-4: 16px;  --space-5: 24px;  --space-6: 32px;
  --space-7: 48px;  --space-8: 64px;  --space-9: 96px;
  --space-10: 144px;

  /* vertical rhythm, three values, never more */
  --rhythm-intra:   var(--space-5);   /* dans un bloc */
  --rhythm-inter:   var(--space-8);   /* entre blocs */
  --rhythm-section: var(--space-10);  /* entre sections */

  /* ---------- DURÉES : quatre valeurs, jamais davantage ---------- */
  --dur-press:   90ms;   /* feedback d'appui */
  --dur-state:  180ms;   /* hover, state change */
  --dur-struct: 380ms;   /* window opening, structural transition */
  --dur-theatre: 700ms;  /* theatrical moments, 3 max site-wide */

  /* ---------- COURBES : trois, jamais davantage ---------- */
  --ease-out:   cubic-bezier(0.16, 1, 0.30, 1);     /* entries */
  --ease-back:  cubic-bezier(0.34, 1.56, 0.64, 1);  /* release, one overshoot */
  --ease-in:    cubic-bezier(0.50, 0, 0.75, 0);     /* sorties, plus rapides */

  /* ---------- TYPO ---------- */
  /* Four families, under names that collide with nothing: style.css also
 * declares --font-display, --font-body and --font-mono. */
  --type-family-display: "Archivo Expanded", "Archivo", system-ui, sans-serif;
  --type-family-body:    "Switzer", -apple-system, "Segoe UI", sans-serif;
  --type-family-mono:    "JetBrains Mono", ui-monospace, monospace;
  --type-family-system:  "Departure Mono", "JetBrains Mono", monospace;

  /* Legacy aliases. style.css overrides them on real pages; used by the styleguide. */
  --font-display: var(--type-family-display);
  --font-body:    var(--type-family-body);
  --font-mono:    var(--type-family-mono);
  --font-system:  var(--type-family-system);

  --type-hero:    clamp(3rem, 8vw, 6.5rem);
  --type-section: clamp(2rem, 4vw, 3.5rem);
  --type-card:    1.375rem;
  /* Lead card title: same object as --type-card, one step up. D-206. */
  --type-card-lead: clamp(1.375rem, 2vw, 2rem);
  --type-lead:    1.125rem;
  --type-body:    1.0625rem;
  --type-small:   0.9375rem;
  --type-meta:    0.75rem;
  --type-chrome:  0.8125rem;

  /* ---------- LAYOUT ---------- */
  --grid-cols: 12;
  --grid-gap: var(--space-5);
  --measure: 68ch;         /* largeur de lecture maximale */
  --gutter-inspect: 220px; /* left gutter, inspection panel */
  /* 1680 since D-104: at 1440 the body started at 233 while the header starts at 24. */
  --page-max: 1680px;

  /* Fixed header height. Anything sitting under it references this. */
  --header-h: 60px;

  /* ---------- Z-INDEX ---------- */
  --z-taskbar: 700;
  --z-header: 800;
  /* Childhood-photo windows sit above the header: they are dragged. */
  --z-window: 850;
  --z-window-front: 851;
  --z-toast: 9000;
  --z-cursor: 9999;

  /* Required elsewhere in the brief, outside the 1.3 list. */

  /* Archivo width axis: 125 hero, 115 sections, 100 mobile. One media query. */
  --wdth-hero:    125;
  --wdth-section: 115;
  --wdth-body:    100;

  /* display metrics from the brief */
  --display-leading: 0.92;
  --display-tracking: -0.02em;

  /* mono metadata is always caps and tracked */
  --meta-tracking: 0.08em;

  /* focus ring is dotted, a period-OS artefact */
  --focus-width: 2px;
  --focus-style: dotted;
  --focus-offset: 3px;

  /* Illustration face. Locked to .annot-text in index.html. D-003. */
  --font-annot: "Caveat", cursive;
}

/* Layer 2 — semantic. References primitives only. */
:root {
  /* Surfaces */
  --surface-page:      var(--ink-950);
  --surface-base:      var(--ink-900);
  --surface-raised:    var(--ink-800);
  --surface-chrome:    var(--ink-700);
  --surface-inverted:  var(--cream);

  /* Bordures */
  --border-default:    var(--ink-600);
  --border-strong:     var(--ink-500);
  --border-accent:     var(--orange-lift);
  --border-accent-soft: var(--orange-veil);
  --border-accent-hv:   var(--orange-halo);

  /* Filet d'un pixel, lisible sans peser. Le curseur au repos est le seul usage. */
  --border-veil:          var(--paper-veil);
  --border-veil-inverted: var(--ink-veil);

  /* Texte */
  --text-primary:      var(--paper);
  --text-secondary:    var(--paper-dim);
  --text-meta:         var(--paper-mute);
  --text-on-action:    var(--ink-950);
  --text-on-inverted:  var(--ink-950);
  --text-accent:       var(--orange-lift);

  /* Action and states */
  --action-default:    var(--orange-core);
  --action-hover:      var(--orange-lift);
  --action-pressed:    var(--orange-deep);
  --action-ghost:      var(--orange-ghost);
  --state-active:      var(--orange-core);
  --state-disabled:    var(--ink-500);
  /* Disabled ink cannot grey an image; opacity is the only shared channel. */
  --state-disabled-veil: 0.55;
  --focus-ring:        var(--orange-lift);

  /* Elevation */
  --elevation-subtle:  var(--shadow-sm);
  --elevation-rest:    var(--shadow-md);
  --elevation-hover:   var(--shadow-lg);
  --elevation-pressed: var(--shadow-pressed);
  --elevation-window:  var(--shadow-plate);
  /* Same value as the window: a raised surface has depth, not chrome. */
  --elevation-surface: var(--shadow-plate);

  /* Plate ink alone: --shadow-plate is composed and unusable on type. */
  --plate-ink:         var(--ink-600);

  /* Mouvement */
  --motion-feedback:   var(--dur-press) var(--ease-back);
  --motion-state:      var(--dur-state) var(--ease-out);
  --motion-structural: var(--dur-struct) var(--ease-out);
  --motion-exit:       var(--dur-state) var(--ease-in);

  /* semantic additions, same reason as layer 1 */

  /* Pop accents, one per project family. */
  --accent-a: var(--mustard);
  --accent-b: var(--teal);
  --accent-c: var(--cherry);
  --accent-d: var(--cobalt);

  /* focus, assembled once so nobody rewrites it */
  --focus-outline: var(--focus-width) var(--focus-style) var(--focus-ring);
}

/* Layer 3 — component. References semantic only. */
:root {
  /* Bouton primaire */
  --btn-primary-bg:        var(--action-default);
  --btn-primary-text:      var(--text-on-action);
  --btn-primary-shadow:    var(--elevation-rest);
  --btn-primary-shadow-hv: var(--elevation-hover);
  --btn-primary-shadow-ac: var(--elevation-pressed);
  --btn-radius:            var(--radius-os);

  /* Bouton secondaire — quatre primitives d'interactif, §2.3 */
  --btn-secondary-bg:      transparent;
  --btn-secondary-text:    var(--text-primary);
  --btn-secondary-border:  var(--border-strong);
  --btn-secondary-bg-hv:   var(--action-ghost);

  /* Lien inline */
  --link-color:            var(--text-primary);
  --link-underline:        var(--border-strong);
  --link-underline-hv:     var(--action-hover);

  /* System control */
  --ctrl-size:             14px;
  --ctrl-border:           var(--border-strong);
  --ctrl-bg-hv:            var(--action-ghost);

  /* Inspection window */
  --window-bg:          var(--surface-raised);
  --window-titlebar-bg: var(--surface-chrome);
  --window-border:      var(--border-default);
  --window-shadow:      var(--elevation-window);
  /* --text-meta gave 4.47:1 on --surface-chrome, below AA. D-069. */
  --window-label-color: var(--text-secondary);
  --window-radius:      var(--radius-os);
  /* WIP window: rest shadow on hover, which is what keeps it from lifting. */
  --window-wip-shadow-hv: var(--elevation-window);
  --window-wip-veil-hv:   var(--state-disabled-veil);

  /* Project figure frame. Shared ratio, so it is a token. */
  --pp-figure-ratio:    16 / 9;

  /* Page scrollbar. Same vocabulary as the pre blocks in dungeon.css. */
  --scrollbar-w:        var(--space-3);
  --scrollbar-track:    var(--surface-base);
  --scrollbar-thumb:    var(--border-strong);
  --scrollbar-thumb-hv: var(--text-meta);

  /* Hero bio measure. Composition, not reading comfort. */
  --hero-bio-measure:   720px;

  /* Childhood photo, inspection zones. Instrument layer. D-106. */
  --photo-zone-border:  var(--text-primary);
  --photo-label-bg:     var(--surface-chrome);
  --photo-label-border: var(--border-default);
  --photo-label-text:   var(--text-primary);

  /* Childhood photo windows. Chrome comes from .win; these add width and margin. */
  --annot-win-boxart-w:    212px;
  --annot-win-honeytree-w: 400px;
  --annot-win-barbatos-w:  270px;
  --annot-win-workbench-w: 250px;
  /* Default only: the JS measures and writes the real width. */
  --annot-win-concert-w:   475px;
  /* Legibility floor. D-199. */
  --annot-win-concert-min-w: 300px;
  --annot-win-margin:   var(--space-4);

  /* Past this the window comments on nothing. Near and taken beats far and free. */
  --annot-win-reach:    200px;

  /* Badge et tag */
  --badge-border: var(--border-default);
  --badge-text:   var(--text-meta);
  --badge-bg:     transparent;

  /* Cursor: an exact dot, and a ring that reacts around it. No lag, no trail. D-255. */
  --cursor-dot-size:   6px;
  --cursor-ring-size: 30px;  /* even: the dot is 6px, both must land on the grid together */
  --cursor-ring-line:  2px;

  --cursor-dot-color:  var(--text-primary);
  --cursor-ring-color: var(--border-veil);
  /* On cream both fall under 1.5:1, so they invert with the surface. D-028. */
  --cursor-dot-color-inverted:  var(--text-on-inverted);
  --cursor-ring-color-inverted: var(--border-veil-inverted);
  /* Hover fills the same ink in: it has to read on ink, on cream AND on an
     orange fill, where an orange ring would sit at 1.2:1 on the main CTA. */
  --cursor-ring-color-active:          var(--text-primary);
  --cursor-ring-color-active-inverted: var(--text-on-inverted);
  /* Orange is kept for the press alone: the moment there is an action. D-027. */
  --cursor-ring-color-pressed: var(--action-pressed);

  /* Ink edge. No single colour reads on every ground: paper falls to 1.13:1 on a
     light photo, ink to 1.00:1 on the page. Carrying both at once holds 4.97:1 at
     worst, over the 91 covers included, and needs nothing declared per section. */
  --cursor-edge-size:           1px;
  --cursor-edge-color:          var(--text-on-inverted);
  --cursor-edge-color-inverted: var(--text-primary);

  /* Ring travel per state. Scale only: an animated size would ask for layout.
     EVERY scale here is chosen so the rendered diameter is an EVEN whole number.
     The dot and the ring must share pixel parity or their edges round in opposite
     directions and the dot reads as off-centre inside the ring. 30px base. */
  --cursor-ring-control: 0.400000; /* 12px */
  --cursor-ring-hover:   0.533333; /* 16px */
  --cursor-ring-card:    0.600000; /* 18px */
  --cursor-ring-press:   0.666667; /* 20px */
  --cursor-dot-press:    1.333333; /* 8px, the dot swells on the press */
  /* Scroll: the ring steps back, the dot never does. */
  --cursor-ring-scroll:  0.3;

  /* Inspection gutter */
  --gutter-label:    var(--text-meta);
  --gutter-progress: var(--state-active);

  /* Achievement toast */
  --toast-bg:     var(--surface-chrome);
  --toast-border: var(--border-accent);
  --toast-text:   var(--text-primary);
}

/* Type breakpoint: wdth to 100 on mobile, one media query for all three axes. */
@media (max-width: 767px) {
  :root {
    --wdth-hero:    100;
    --wdth-section: 100;
  }
}

/* Reduced motion, handled once here. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-press:   0ms;
    --dur-state:   0ms;
    --dur-struct:  0ms;
    --dur-theatre: 0ms;
  }
}
