/* ============================================================
   Tokens — single source of truth.
   Every colour, font, space, ease, motion, glass recipe in the
   project flows from here. Aligned to the institutional brief.
   ============================================================ */

:root {

  /* ============================================================
     COLOUR
     Base is bluish-grey dark. Never pure black, never pure white.
     Pearl is a warm off-white — institutional, restrained, never
     clinical. Navy is sampled from the fish silhouette in the
     Algamar logo, teal from its wave gradient (use teal sparingly
     — it is the accent of accents).
     ============================================================ */
  --abyssal:          #0a0f1a;
  --deep:             #131a26;
  --surface:          #1a2330;
  --surface-elevated: #222d3d;

  --pearl:            #f5f3ee;
  --pearl-muted:      #c8c5be;
  --pearl-quiet:      #8a8780;

  --navy:             #1e3a8a;
  --teal:             #2d8576;

  /* Legacy aliases — existing components reference these. Mapped
     onto the new palette so a single edit sweep moves the site. */
  --color-bg:           var(--abyssal);
  --color-bg-elevated:  var(--surface);
  --color-text:         var(--pearl);
  --color-text-muted:   var(--pearl-muted);
  --color-text-subtle:  var(--pearl-quiet);
  /* Each color-mix() is preceded by a plain rgba() of the same value.
     color-mix is Safari 16.2+ / Chrome 111+ / Firefox 113+; on anything
     older the var() substitution is Invalid At Computed-Value Time and
     the declaration is dropped — which killed the tint while leaving
     backdrop-filter painting, i.e. pearl text on raw sunlit video. A
     preceding same-property declaration is the one mechanism that
     survives IACVT, so every glass/divider token is doubled below.
     Keep the pairs in sync when editing. */
  --color-divider:      rgba(245, 243, 238, 0.12);
  --color-divider:      color-mix(in srgb, var(--pearl) 12%, transparent);
  --color-brand:        var(--navy);
  --color-brand-hover:  var(--teal);
  --color-overlay:      rgba(10, 15, 26, 0.55);
  --color-overlay:      color-mix(in srgb, var(--abyssal) 55%, transparent);


  /* ============================================================
     TYPOGRAPHY
     Gambetta (display serif) + Author (humanist sans), both via
     Fontshare — load via each page's <link> element. (The prior
     "Editorial New"/"General Sans" pairing never actually loaded:
     Editorial New isn't a real Fontshare family, and requesting it
     made the whole combined stylesheet request 500 — every page was
     silently rendering in OS system-default fonts. Author also
     replaces General Sans on its own merits: a distinctive editorial
     humanist grotesk, not the geometric-sans look now associated
     with generic templated/AI-generated sites.)
     ============================================================ */
  --font-display: "Gambetta", "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --font-sans:    "Author", "Söhne", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  /* Hero display face. Kept as its own token rather than reusing
     --font-display, because the hero is now a geometric sans while
     every other heading on the site stays on Gambetta — they are
     deliberately different roles, not an inconsistency. */
  /* Avenir's lineage: a geometric sans with humanist proportions —
     round bowls, a single-storey a, generous counters, and the open
     apertures that keep it warm rather than clinical. General Sans is
     the closest thing to that on Fontshare, which is already the
     site's only font host, so this costs no new connection and four
     faces instead of the seven Plus Jakarta Sans was pulling.

     General Sans is named FIRST, ahead of Avenir itself, deliberately.
     Avenir Next ships on every Mac and iPhone and on no Windows or
     Android device, so leading with it would set the headline in one
     typeface for the client and a different one for half their
     customers. A brand line has to be the same line everywhere.
     Avenir sits just behind it, so if the webfont ever fails to load
     the hero falls back to the real thing rather than to system-ui. */
  --font-hero:    "General Sans", "Avenir Next", "Avenir", "Author", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  /* No monospace face in this project — by explicit instruction. The
     token is retired rather than redefined so nothing can quietly
     opt back into a mono stack. Data that needs column alignment
     uses font-variant-numeric: tabular-nums on the sans face. */
  --font-numeric: "Gambetta", "Fraunces", Georgia, serif;

  /* ------------------------------------------------------------
     TYPE SCALE — every step is a SET: size + tracking + leading.
     Tracking is size-specific, never one value reused across sizes:
     a serif set at 96px needs the letters pulled together, the same
     face at 17px needs them left alone. Leading runs inversely to
     size — tight on display, open on body. (Apple, WWDC "The Details
     of UI Typography".) Pair each size token with the tracking and
     leading token of the same name; do not mix steps.
     ------------------------------------------------------------ */
  --type-display-xl: clamp(2.5rem, min(6.4vw, 9.5vh), 5.25rem);     /* hero headline  */
  --tr-display-xl:   -0.035em;
  --lh-display-xl:   0.98;

  --type-display-l:  clamp(2rem, min(4vw, 6vh), 3.25rem); /* section titles */
  --tr-display-l:    -0.028em;
  --lh-display-l:    1.04;

  --type-display-m:  clamp(1.5rem, min(2.6vw, 4vh), 2.15rem);     /* sub-sections   */
  --tr-display-m:    -0.02em;
  --lh-display-m:    1.12;

  --type-display-s:  clamp(1.25rem, 1.8vw, 1.5rem);   /* card headings  */
  --tr-display-s:    -0.012em;
  --lh-display-s:    1.2;

  --type-body-l:     1.3125rem;                        /* lead paragraph */
  --tr-body-l:       -0.005em;
  --lh-body-l:       1.6;

  --type-body:       1.1875rem;                        /* body           */
  --tr-body:         0;
  --lh-body-text:    1.65;

  --type-caption:    1.0625rem;
  --tr-caption:      0.005em;
  --lh-caption:      1.5;

  --type-eyebrow:    0.8125rem;                        /* small caps need
                                                          POSITIVE tracking */
  --tr-eyebrow-t:    0.16em;
  --lh-eyebrow:      1;

  /* Legacy aliases mapped onto the new scale. */
  --fs-xs:    var(--type-eyebrow);
  --fs-sm:    var(--type-caption);
  --fs-base:  var(--type-body);
  --fs-md:    var(--type-body-l);
  --fs-lg:    var(--type-display-m);
  --fs-xl:    calc(var(--type-display-m) * 1.2);
  --fs-2xl:   var(--type-display-l);
  --fs-3xl:   var(--type-display-xl);
  --fs-hero:  var(--type-display-xl);
  --fs-stat:  var(--type-display-l);
  --fs-tag:   var(--type-display-m);

  --lh-display: 1.05;
  --lh-tight:   1.2;
  --lh-ui:      1.3;
  --lh-body:    1.7;

  --tr-tight:    -0.04em;   /* largest display */
  --tr-display:  -0.02em;   /* general display */
  --tr-normal:   0;
  --tr-label:    0.15em;
  --tr-eyebrow:  0.18em;


  /* ============================================================
     SPACING — 8px grid (brief §3.3)
     Canonical scale: 4 8 16 24 32 48 64 96 128 192 256.
     ============================================================ */
  --space-0_5: 0.25rem;     /* 4  */
  --space-1:   0.5rem;      /* 8  */
  --space-2:   1rem;        /* 16 */
  --space-3:   1.5rem;      /* 24 */
  --space-4:   2rem;        /* 32 */
  --space-6:   3rem;        /* 48 */
  --space-8:   4rem;        /* 64 */
  --space-12:  6rem;        /* 96 */
  --space-16:  8rem;        /* 128 */
  --space-24:  12rem;       /* 192 */
  --space-32:  16rem;       /* 256 */

  /* Legacy aliases. */
  --space-5:   2.5rem;
  --space-10:  5rem;

  --container-max:  1440px;
  --container-pad:  clamp(2rem, 5vw, 6rem);
  /* Was clamp(6rem, 12vw, 12rem) — 172px top AND bottom on a 13"
     laptop, i.e. 345px of padding per section on a 900px screen.
     Halved, and made height-aware. */
  --section-pad-y:  clamp(3rem, min(5.5vw, 8vh), 6.5rem);
  --reading-max:    66ch;

  --section-y:      var(--section-pad-y);
  --gutter-x:       var(--container-pad);
  --content-max:    var(--container-max);


  /* ============================================================
     MOTION (brief §3.4)
     Never use default ease / ease-in-out.
     ============================================================ */
  --ease-out-expo:     cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out-cubic: cubic-bezier(0.65, 0, 0.35, 1);

  /* Legacy aliases. */
  --ease-hero:   var(--ease-in-out-cubic);
  --ease-out:    var(--ease-out-expo);
  --ease-micro:  var(--ease-out-expo);
  --ease-in:     cubic-bezier(0.55, 0, 1, 0.45);

  --dur-instant: 120ms;
  --dur-micro:   240ms;
  --dur-short:   360ms;
  --dur-base:    600ms;
  --dur-long:    900ms;
  --dur-hero:    1200ms;
  --dur-count:   1800ms;
  --dur-fade:    1500ms;


  /* ============================================================
     GLASS — three variants (brief §3.5)
     Whisper (header, nav)
     Card    (content cards, metric tiles, contact cards)
     Modal   (overlays, expanded states)
     Each glass surface gets a 1px top inner highlight — applied
     via a ::before pseudo in pages.css.
     ============================================================ */

  /* Whisper — almost invisible, earns its presence on scroll. */
  --glass-whisper-bg:     rgba(10, 15, 26, 0.60);
  --glass-whisper-bg:     color-mix(in srgb, var(--abyssal) 60%, transparent);
  --glass-whisper-filter: blur(12px) saturate(140%);
  --glass-whisper-border: 1px solid rgba(245, 243, 238, 0.08);
  --glass-whisper-border: 1px solid color-mix(in srgb, var(--pearl) 8%, transparent);

  /* Card — workhorse content surface. NOTE: cards sit ON the section
     pane, which is already blurred. Stacking a second backdrop-filter
     buys nothing (there is no un-blurred backdrop left to blur) and
     costs a whole extra composited layer, so .glass--card now uses
     tint + edge only. Material hierarchy comes from tint weight and
     shadow depth, not from more blur. */
  --glass-card-bg:        rgba(26, 35, 48, 0.50);
  --glass-card-bg:        color-mix(in srgb, var(--surface) 50%, transparent);
  --glass-card-filter:    blur(20px) saturate(160%);
  --glass-card-border:    1px solid rgba(245, 243, 238, 0.06);
  --glass-card-border:    1px solid color-mix(in srgb, var(--pearl) 6%, transparent);
  --glass-card-shadow:    0 24px 64px -16px rgba(0, 0, 0, 0.40);

  /* Modal — overlays, full-screen surfaces. */
  --glass-modal-bg:       rgba(19, 26, 38, 0.70);
  --glass-modal-bg:       color-mix(in srgb, var(--deep) 70%, transparent);
  --glass-modal-filter:   blur(32px) saturate(180%);
  --glass-modal-border:   1px solid rgba(245, 243, 238, 0.10);
  --glass-modal-border:   1px solid color-mix(in srgb, var(--pearl) 10%, transparent);

  /* Section — the entire editorial canvas is one deep pane of glass
     over the fixed ocean video. Tint is strong enough that pearl body
     copy keeps ~10:1 contrast even over the brightest water, but the
     ocean's colour and motion visibly bleed through. */
  --glass-section-bg:     rgba(10, 15, 26, 0.84);
  --glass-section-bg:     color-mix(in srgb, var(--abyssal) 84%, transparent);
  --glass-section-filter: blur(28px) saturate(130%);

  /* Legibility scrim — the answer to "clear water AND readable text".
     Rather than tinting the whole hero (which kills the clarity) or
     leaving it raw (measured 1.03:1 on the homepage eyebrow), text
     blocks over open video carry their own local gradient scrim. It
     is anchored to the text, invisible as a shape, and leaves the
     surrounding water untouched.

     Stop values are derived, not eyeballed. Sampling the brightest
     specular pixel of the hero footage and solving for the composite
     ratio against --pearl gives: alpha 0.48 => 3:1, alpha 0.60 => 4.5:1.
     WCAG needs 3:1 for large text (the 109px title) and 4.5:1 for
     normal text (the 19px sub), so the gradient sits at ~0.50 across
     the title band and deepens to ~0.64 by the sub. Deepening downward
     is also simply what water does, so the fix reads as depth rather
     than as a panel. Re-derive these if the footage changes. */
  --scrim-text:  linear-gradient(180deg,
                   rgba(10, 15, 26, 0)    0%,
                   rgba(10, 15, 26, 0.50) 14%,
                   rgba(10, 15, 26, 0.58) 70%,
                   rgba(10, 15, 26, 0.64) 88%,
                   rgba(10, 15, 26, 0.68) 100%);

  /* (Page-hero glass tokens removed — heroes are now completely
     clear; the fade into the section pane lives on main::before.) */

  /* Inner top-edge highlight (the magic detail). */
  --glass-highlight:      linear-gradient(90deg,
                            transparent 0%,
                            color-mix(in srgb, var(--pearl) 30%, transparent) 50%,
                            transparent 100%);


  /* ============================================================
     LAYOUT CHROME
     ============================================================ */
  --header-h:        72px;
  --header-h-mobile: 60px;
  --hairline:        1px;


  /* ============================================================
     Z-INDEX
     Note: do NOT use negative z-index on position:fixed background
     layers. Safari and some mobile browsers render negatively-
     stacked fixed elements behind the document's background-color,
     which hides them entirely. Bg layer uses z-index 0 and content
     uses z-index 1+ so layering is portable across every browser.
     ============================================================ */
  --z-bg:       0;
  --z-grain:    1;
  --z-content:  2;
  --z-header:  50;
  --z-overlay: 90;
  --z-modal:  100;
}

@media (max-width: 640px) {
  :root {
    --type-body:    1.0625rem;
    /* The lead steps down with the body on narrow screens; 21px
       lead on a 375px phone reads as shouting. */
    --type-body-l:  1.1875rem;
    --fs-base:      1rem;
  }
}

/* Reduced motion — keep functionality, kill long durations.
   Brief §8: respects prefers-reduced-motion. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-micro:   120ms;
    --dur-short:   140ms;
    --dur-base:    160ms;
    --dur-long:    160ms;
    --dur-hero:    160ms;
    --dur-count:    1ms;
    --dur-fade:    160ms;
  }
}

/* ------------------------------------------------------------------
   REDUCED TRANSPARENCY — a whole design language built on translucency
   has to have an answer for people who switch translucency off. Every
   glass token goes near-opaque and every blur is dropped, so the
   surfaces stay legible as flat panels rather than disappearing.
   ------------------------------------------------------------------ */
@media (prefers-reduced-transparency: reduce) {
  :root {
    --glass-whisper-bg:     rgba(10, 15, 26, 0.97);
    --glass-card-bg:        rgba(26, 35, 48, 0.97);
    --glass-modal-bg:       rgba(19, 26, 38, 0.99);
    --glass-section-bg:     rgba(10, 15, 26, 0.98);
    --glass-whisper-filter: none;
    --glass-card-filter:    none;
    --glass-modal-filter:   none;
    --glass-section-filter: none;
    --scrim-text:           linear-gradient(180deg,
                              rgba(10, 15, 26, 0.92) 0%,
                              rgba(10, 15, 26, 0.96) 100%);
  }
}

/* ------------------------------------------------------------------
   INCREASED CONTRAST — solid surfaces, defined borders, and the quiet
   greys promoted so nothing relies on a low-contrast tint to be read.
   ------------------------------------------------------------------ */
@media (prefers-contrast: more) {
  :root {
    --pearl-muted:          #e4e2dc;
    --pearl-quiet:          #c9c6bf;
    --color-divider:        rgba(245, 243, 238, 0.34);
    --glass-whisper-bg:     rgba(10, 15, 26, 0.98);
    --glass-card-bg:        rgba(26, 35, 48, 0.98);
    --glass-modal-bg:       rgba(19, 26, 38, 1);
    --glass-section-bg:     rgba(10, 15, 26, 0.99);
    --glass-card-border:    1px solid rgba(245, 243, 238, 0.42);
    --glass-whisper-border: 1px solid rgba(245, 243, 238, 0.42);
    --glass-modal-border:   1px solid rgba(245, 243, 238, 0.48);
  }
}

/* ------------------------------------------------------------------
   FORCED COLORS (Windows High Contrast) — hand the page to the user's
   palette: drop decorative glass/blur so their colours actually win.
   ------------------------------------------------------------------ */
@media (forced-colors: active) {
  :root {
    --glass-whisper-filter: none;
    --glass-card-filter:    none;
    --glass-modal-filter:   none;
    --glass-section-filter: none;
  }
  .hero-bg,
  .hero-video,
  .hero-overlay { display: none !important; }
}
