/* ==========================================================================
   ALEX IN MALTA — DESIGN TOKENS
   Single source of truth. Nothing below this file may hard-code a value.
   WP Phase 2: enqueue first, before every other stylesheet.
   ========================================================================== */

:root {

  /* ------------------------------------------------------------------
     1. PALETTE — strict 3-hue maximum
     STONE  : Valletta / Mdina globigerina limestone (the paper)
     SLATE  : deep-sea Mediterranean slate at depth (the ink)
     GOLD   : the trim painted on a luzzu's bow (the single accent)
     Every other value below is a step within these three hues only.
     ------------------------------------------------------------------ */

  --stone-50:   #FAF7F1;
  --stone-100:  #F2ECE1;
  --stone-200:  #E5DBC9;
  --stone-300:  #D2C4AB;
  --stone-400:  #B3A183;

  --slate-950:  #0A0E10;
  --slate-900:  #11171A;
  --slate-800:  #1A2328;
  --slate-700:  #26333A;
  --slate-500:  #4C5F69;
  --slate-300:  #8A9AA3;


  /* ------------------------------------------------------------------
     THE LUZZU PALETTE
     Sampled from a photograph of a luzzu's bow, not invented: the values
     below are the actual paint, quantised out of the image.

         hull      #012870   23.5% of the painted area
         gold trim #FEC401    4.8%, and the brightest thing in the frame
         ochre     #FAB00C
         red trim  #B4230F

     The GOLD is the accent. On the dark page it reads 11.3:1, and dark ink
     on a gold fill reads 12.1:1 — it is the only colour on that boat that
     is legible both as text and as a surface against near-black.

     The HULL BLUE is 1.3:1 on the dark page. That makes it a surface, never
     an accent: it can hold white text (12.8:1) but it cannot be text.
     ------------------------------------------------------------------ */

  --luzzu-gold-700: #7A5502;  /* small text on limestone      — 6.3:1  */
  --luzzu-gold-600: #D99B00;  /* a fill under the cursor      — ink 8.0:1 */
  --luzzu-gold-500: #FEC401;  /* the paint: fills, large display        */
  --luzzu-gold-400: #FFD24A;  /* small text on slate          — 12.6:1 */

  /* The other three hues off the same boat. Each is the painted colour
     lifted in value until it clears 4.5:1 on near-black, because the paint
     itself does not: the hull reads 1.3:1 there and the trim red 2.8:1.
     The deep originals survive as the -900 step, which is a surface. */

  --luzzu-blue-900: #012870;  /* the hull as painted. A surface, never text. */
  --luzzu-blue-700: #14508F;  /* small text on limestone      — 7.6:1  */
  --luzzu-blue-600: #1F6FA8;  /* a fill under the cursor, on limestone */
  --luzzu-blue-500: #4FA8E8;  /* fills + text on slate — ink 7.5:1, dark 7.0:1 */
  --luzzu-blue-400: #7CC4F2;  /* a fill under the cursor, on slate     */

  --luzzu-green-900: #1B5C40;
  --luzzu-green-700: #1F6B4A;  /* small text on limestone     — 6.0:1  */
  --luzzu-green-600: #2E7D5B;
  --luzzu-green-500: #3FBF83;  /* ink 8.3:1, on dark 7.7:1             */
  --luzzu-green-400: #63D69E;

  --luzzu-red-900:  #B4230F;  /* the trim line as painted             */
  --luzzu-red-700:  #A8261A;  /* small text on limestone      — 6.6:1 */
  --luzzu-red-600:  #D63A22;
  --luzzu-red-500:  #F0564C;  /* ink 5.7:1, on dark 5.3:1             */
  --luzzu-red-400:  #FF6F5E;

  /* PRE-INVERSION PAIR
     Two colours that exist only to be flipped. The Calendly iframe cannot be
     styled (see consult.css), so it is handed a light palette and the whole
     frame is inverted. invert() + hue-rotate(180deg) keeps the hue and flips
     the lightness, which means a WARM light input lands on a warm dark — and
     the section it sits in is cool slate.

     So the plate handed over is cool and the ink handed over is warm: each
     one inverts onto the colour actually wanted.

         --invert-plate  #EAF1F6  cool light  -> lands near --slate-900
         --invert-ink    #0D0A06  warm dark   -> lands near --stone-50
     ------------------------------------------------------------------ */

  --invert-plate: #EAF1F6;
  --invert-ink:   #0D0A06;

  /* ------------------------------------------------------------------
     2. SEMANTIC SURFACE TOKENS
     Default scope = "paper" (light editorial page).
     Any element can flip the whole subtree with [data-scheme="ink"].
     ------------------------------------------------------------------ */

  --c-bg:            var(--stone-50);
  --c-bg-alt:        var(--stone-100);
  --c-bg-sunk:       var(--stone-100);
  --c-bg-raised:     #FFFFFF;
  --c-surface:       var(--stone-50);

  --c-ink:           var(--slate-950);
  --c-ink-soft:      var(--slate-700);
  --c-ink-muted:     var(--slate-500);

  --c-accent:        var(--luzzu-gold-500);
  --c-accent-hover:  var(--luzzu-gold-600);
  /* --c-accent-text is the SAME hue stepped down until it clears 4.5:1 against
     the paper. Use it for any accent-coloured text below display size;
     --c-accent stays the fill and the large-display colour. */
  --c-accent-text:   var(--luzzu-gold-700);
  /* Whatever sits ON an accent fill. Gold is a light colour, so this is ink,
     not paper — and it is a token so that changing the accent again can
     never silently break the contrast of a button's label. */
  --c-accent-on:     var(--slate-950);

  --c-line:          color-mix(in oklab, var(--slate-950) 14%, transparent);
  --c-line-strong:   color-mix(in oklab, var(--slate-950) 32%, transparent);

  --c-selection-bg:  var(--slate-950);
  --c-selection-fg:  var(--stone-50);

  /* ------------------------------------------------------------------
     3. TYPEFACES
     Display : Fraunces      — high-contrast editorial serif, optical sizing
     Body    : Inter         — clean, neutral, ruthlessly legible
     Meta    : JetBrains Mono— raw geometric mono for indices + metadata
     Fallback stacks are real, so a font-load failure still renders on-brand.
     ------------------------------------------------------------------ */

  --ff-display: "Fraunces", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --ff-body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --ff-mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* ------------------------------------------------------------------
     4. FLUID TYPE SCALE — locked between 360px and 1600px viewports
     ------------------------------------------------------------------ */

  --fs-mono-xs:  clamp(0.6694rem, 0.6694rem + 0.0806vw, 0.75rem);
  --fs-mono-sm:  clamp(0.75rem,   0.7319rem + 0.0806vw, 0.8125rem);
  --fs-xs:       clamp(0.8125rem, 0.7944rem + 0.0806vw, 0.875rem);
  --fs-sm:       clamp(0.9375rem, 0.9194rem + 0.0806vw, 1rem);
  --fs-md:       clamp(1rem,      0.9637rem + 0.1613vw, 1.125rem);
  --fs-lg:       clamp(1.125rem,  1.0524rem + 0.3226vw, 1.375rem);
  --fs-xl:       clamp(1.375rem,  1.2298rem + 0.6450vw, 1.875rem);
  --fs-2xl:      clamp(1.75rem,   1.4597rem + 1.2900vw, 2.75rem);
  --fs-3xl:      clamp(2.25rem,   1.7420rem + 2.2580vw, 4rem);
  --fs-4xl:      clamp(3rem,      2.1290rem + 3.8710vw, 6rem);
  --fs-display:  clamp(3.25rem,   1.4355rem + 8.0650vw, 9.5rem);

  /* Line heights — display type is set tight, body type is set generous. */
  --lh-display:  0.88;
  --lh-tight:    1.04;
  --lh-snug:     1.22;
  --lh-body:     1.62;
  --lh-loose:    1.75;

  /* Tracking — optical compensation, serif tightens up, mono opens out. */
  --tr-display:  -0.035em;
  --tr-tight:    -0.02em;
  --tr-normal:   0em;
  --tr-mono:     0.14em;
  --tr-mono-wide:0.24em;

  --fw-light:    300;
  --fw-regular:  400;
  --fw-medium:   500;
  --fw-semi:     600;
  --fw-bold:     700;

  /* ------------------------------------------------------------------
     5. SPACE SCALE — small steps fixed, large steps fluid
     ------------------------------------------------------------------ */

  --sp-1:  0.25rem;
  --sp-2:  0.5rem;
  --sp-3:  0.75rem;
  --sp-4:  1rem;
  --sp-5:  1.5rem;
  --sp-6:  2rem;
  --sp-7:  2.5rem;
  --sp-8:  clamp(2rem, 1.2000rem + 3.5000vw, 4rem);
  --sp-9:  clamp(3rem, 1.8000rem + 5.2000vw, 6rem);
  --sp-10: clamp(4rem, 2.2000rem + 7.7000vw, 9rem);
  --sp-11: clamp(5rem, 2.4000rem + 11.600vw, 14rem);

  /* ------------------------------------------------------------------
     6. LAYOUT RAILS — the 12-column editorial grid
     .l-shell exposes named lines: full-start | content-start .. content-end | full-end
     ------------------------------------------------------------------ */

  --grid-columns:  12;
  --gutter:        clamp(0.75rem, 0.35rem + 1.6vw, 1.75rem);
  --margin:        clamp(1.25rem, 0.4rem + 3.4vw, 5rem);
  --content-max:   96rem;

  /* ------------------------------------------------------------------
     7. MEDIA ASPECTS — one vocabulary, reused by every media frame
     ------------------------------------------------------------------ */

  --ar-cinema:   21 / 9;
  --ar-wide:     16 / 9;
  --ar-square:    1 / 1;
  --ar-portrait:  4 / 5;
  --ar-classic:   3 / 2;
  --ar-panorama:  2 / 1;

  /* ------------------------------------------------------------------
     8. MOTION — restrained. Nothing bounces. Nothing glows.
     ------------------------------------------------------------------ */

  --ease-out:   cubic-bezier(0.16, 1, 0.3, 1);

  /* For big, slow movements — currently only the relocation card opening.
     --ease-out is an exponential: it covers 90% of the distance in the first
     quarter of the time and then crawls. On a 20px nudge that reads as
     crisp. On a 450px panel of copy arriving it reads as a SNAP followed by
     a long settle, and everything below it gets yanked down before the eye
     has found what moved.

     This one starts and stops gently and spends its time in the middle,
     where the movement is actually legible. Same duration, and it is the
     curve rather than the duration that was making it feel abrupt. */
  --ease-panel: cubic-bezier(0.33, 0, 0.15, 1);
  --ease-inout: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast:   160ms;
  --dur-base:   340ms;
  --dur-slow:   720ms;

  /* ------------------------------------------------------------------
     9. BORDERS + ELEVATION — hairlines only, no soft drop-shadow blobs
     ------------------------------------------------------------------ */

  --bw-hair:  1px;
  --bw-rule:  2px;
  --radius-0: 0;
  --radius-1: 2px;
  --radius-pill: 100vmax;


  /* ------------------------------------------------------------------
     10. MEDIA SCRIMS — full-bleed photography and video need a consistent
     legibility layer. These are the only overlays allowed anywhere.
     ------------------------------------------------------------------ */

  --scrim-flood:  color-mix(in oklab, var(--slate-950) 70%, transparent);
  --scrim-read:  color-mix(in oklab, var(--slate-950) 82%, transparent);
  --scrim-hero-deep:  color-mix(in oklab, var(--slate-950) 50%, transparent);
  --scrim-hero-mid:  color-mix(in oklab, var(--slate-950) 34%, transparent);
  --scrim-hero-edge:  color-mix(in oklab, var(--slate-950) 38%, transparent);
  --scrim-deep:   color-mix(in oklab, var(--slate-950) 90%, transparent);
  --scrim-mid:    color-mix(in oklab, var(--slate-950) 58%, transparent);
  --scrim-veil:   color-mix(in oklab, var(--slate-950) 20%, transparent);

  --grade-media:  saturate(0.92) contrast(1.04) brightness(0.94);

  /* Chrome */
  --header-h:     4.25rem;

  /* ------------------------------------------------------------------
     11. SECTION RHYTHM
     One value, used by every section, so the page breathes evenly instead
     of stacking one section's generous bottom padding on the next one's
     generous top padding and leaving a hole between them.
     ------------------------------------------------------------------ */

  /* NOTE: consecutive sections each contribute this, so the visible gap
     between two of them is DOUBLE the value. Tuned so that doubled figure
     lands around 128px on a desktop, not 212px. */
  --section-pad:  clamp(2.25rem, 1.2rem + 3vw, 4rem);
  --section-gap:  clamp(1.75rem, 1.1rem + 2.4vw, 3rem);

  --z-base:    1;
  --z-media:   2;
  --z-overlap: 3;
  --z-nav:     50;
  --z-drawer:  80;
}

/* ==========================================================================
   INK SCOPE — dark editorial sections (hero, footer, media wells).
   Flips semantics only; the three hues never change.
   ========================================================================== */

[data-scheme="ink"] {
  --c-bg:           var(--slate-950);
  --c-bg-alt:       var(--slate-900);
  --c-bg-sunk:      #060909;
  --c-bg-raised:    var(--slate-900);
  --c-surface:      var(--slate-900);

  --c-ink:          var(--stone-50);
  --c-ink-soft:     var(--stone-300);
  --c-ink-muted:    var(--slate-300);

  --c-accent:       var(--luzzu-gold-500);
  --c-accent-hover: var(--luzzu-gold-400);
  --c-accent-text:  var(--luzzu-gold-500);
  --c-accent-on:    var(--slate-950);

  --c-line:         color-mix(in oklab, var(--stone-50) 16%, transparent);
  --c-line-strong:  color-mix(in oklab, var(--stone-50) 38%, transparent);

  --c-selection-bg: var(--stone-50);
  --c-selection-fg: var(--slate-950);
}

/* Respect the operating-system preference for reduced motion globally. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 1ms;
    --dur-base: 1ms;
    --dur-slow: 1ms;
  }
}


/* ==========================================================================
   AUTO DARK MODE
   The paper scope re-maps to slate; the ink scope is already dark and does
   not move, so sections that were designed black stay black and the page
   keeps its light/dark rhythm instead of flattening into one tone.

   Three states, deliberately: system preference by default, and explicit
   [data-theme] overrides so a manual toggle wins in either direction.
   ========================================================================== */

:root { color-scheme: light; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
  color-scheme: dark;

  --c-bg:            var(--slate-950);
  --c-bg-alt:        var(--slate-900);
  --c-bg-sunk:       #060909;
  --c-bg-raised:     var(--slate-800);
  --c-surface:       var(--slate-900);

  --c-ink:           var(--stone-50);
  --c-ink-soft:      var(--stone-300);
  --c-ink-muted:     var(--slate-300);

  --c-accent:       var(--luzzu-gold-500);
  --c-accent-hover: var(--luzzu-gold-400);
  --c-accent-text:  var(--luzzu-gold-500);
  --c-accent-on:    var(--slate-950);

  --c-line:          color-mix(in oklab, var(--stone-50) 16%, transparent);
  --c-line-strong:   color-mix(in oklab, var(--stone-50) 38%, transparent);

  --c-selection-bg:  var(--stone-50);
  --c-selection-fg:  var(--slate-950);

  --scrim-flood:     color-mix(in oklab, var(--slate-950) 66%, transparent);
  --scrim-read:     color-mix(in oklab, var(--slate-950) 82%, transparent);
  --scrim-hero-deep:     color-mix(in oklab, var(--slate-950) 50%, transparent);
  --scrim-hero-mid:     color-mix(in oklab, var(--slate-950) 34%, transparent);
  --scrim-hero-edge:     color-mix(in oklab, var(--slate-950) 38%, transparent);
  --scrim-deep:      color-mix(in oklab, var(--slate-950) 88%, transparent);
  }
}

/* Manual override — the toggle in the masthead sets this. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --c-bg:            var(--slate-950);
  --c-bg-alt:        var(--slate-900);
  --c-bg-sunk:       #060909;
  --c-bg-raised:     var(--slate-800);
  --c-surface:       var(--slate-900);

  --c-ink:           var(--stone-50);
  --c-ink-soft:      var(--stone-300);
  --c-ink-muted:     var(--slate-300);

  --c-accent:       var(--luzzu-gold-500);
  --c-accent-hover: var(--luzzu-gold-400);
  --c-accent-text:  var(--luzzu-gold-500);
  --c-accent-on:    var(--slate-950);

  --c-line:          color-mix(in oklab, var(--stone-50) 16%, transparent);
  --c-line-strong:   color-mix(in oklab, var(--stone-50) 38%, transparent);

  --c-selection-bg:  var(--stone-50);
  --c-selection-fg:  var(--slate-950);

  --scrim-flood:     color-mix(in oklab, var(--slate-950) 66%, transparent);
  --scrim-read:     color-mix(in oklab, var(--slate-950) 82%, transparent);
  --scrim-hero-deep:     color-mix(in oklab, var(--slate-950) 50%, transparent);
  --scrim-hero-mid:     color-mix(in oklab, var(--slate-950) 34%, transparent);
  --scrim-hero-edge:     color-mix(in oklab, var(--slate-950) 38%, transparent);
  --scrim-deep:      color-mix(in oklab, var(--slate-950) 88%, transparent);
}

:root[data-theme="light"] { color-scheme: light; }

/* ==========================================================================
   SECTION ACCENTS
   A section may swap the accent for another colour off the same boat by
   declaring data-accent. Only the accent tokens move; the surfaces, the ink
   and the type scale do not, so a section reads as the same page in a
   different key rather than as a different site.

   Nothing here is a new colour rule: --c-accent is still the fill,
   --c-accent-text is still the type, --c-accent-on is still what sits on a
   fill. Every component already reads those three, so no component knows
   this feature exists.
   ========================================================================== */

/* BLUE — the hull */
[data-accent="blue"] {
  --c-accent:        var(--luzzu-blue-500);
  --c-accent-hover:  var(--luzzu-blue-600);
  --c-accent-text:   var(--luzzu-blue-700);
  --c-accent-on:     var(--slate-950);
}

/* On a dark ground the type takes the lifted step and the hover goes lighter,
   not darker. Three selectors because a section can be dark for three
   different reasons: it declared itself so, the system asked for dark, or the
   visitor chose dark. */
[data-scheme="ink"][data-accent="blue"],
[data-scheme="ink"] [data-accent="blue"],
[data-theme="dark"] [data-accent="blue"] {
  --c-accent-text:   var(--luzzu-blue-500);
  --c-accent-hover:  var(--luzzu-blue-400);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) [data-accent="blue"] {
    --c-accent-text: var(--luzzu-blue-500);
    --c-accent-hover: var(--luzzu-blue-400);
  }
}

/* GREEN — the scroll on the bow */
[data-accent="green"] {
  --c-accent:        var(--luzzu-green-500);
  --c-accent-hover:  var(--luzzu-green-600);
  --c-accent-text:   var(--luzzu-green-700);
  --c-accent-on:     var(--slate-950);
}

/* On a dark ground the type takes the lifted step and the hover goes lighter,
   not darker. Three selectors because a section can be dark for three
   different reasons: it declared itself so, the system asked for dark, or the
   visitor chose dark. */
[data-scheme="ink"][data-accent="green"],
[data-scheme="ink"] [data-accent="green"],
[data-theme="dark"] [data-accent="green"] {
  --c-accent-text:   var(--luzzu-green-500);
  --c-accent-hover:  var(--luzzu-green-400);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) [data-accent="green"] {
    --c-accent-text: var(--luzzu-green-500);
    --c-accent-hover: var(--luzzu-green-400);
  }
}

/* RED — the trim line */
[data-accent="red"] {
  --c-accent:        var(--luzzu-red-500);
  --c-accent-hover:  var(--luzzu-red-600);
  --c-accent-text:   var(--luzzu-red-700);
  --c-accent-on:     var(--slate-950);
}

/* On a dark ground the type takes the lifted step and the hover goes lighter,
   not darker. Three selectors because a section can be dark for three
   different reasons: it declared itself so, the system asked for dark, or the
   visitor chose dark. */
[data-scheme="ink"][data-accent="red"],
[data-scheme="ink"] [data-accent="red"],
[data-theme="dark"] [data-accent="red"] {
  --c-accent-text:   var(--luzzu-red-500);
  --c-accent-hover:  var(--luzzu-red-400);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) [data-accent="red"] {
    --c-accent-text: var(--luzzu-red-500);
    --c-accent-hover: var(--luzzu-red-400);
  }
}
