/* ============================================================================
   Grosso University — brand tokens
   Source of truth: theme/source/Grosso Brand Guidelines.png
   Contrast figures: measured by theme/docs/contrast.mjs — re-run it before
   changing ANY color below. Nothing here is a guess.
   ============================================================================ */

:root {
  /* ── 1. The corporate color system, verbatim ──────────────────────────────
     These six are the brand. They are never redefined, never tinted in place,
     and never used as text without checking the table in §3. */
  --gu-blue:   #4d6fa2;   /* Primary  R77  G111 B162 */
  --gu-ink:    #171717;   /* Primary  R23  G23  B23  */
  --gu-paper:  #e7e7e8;   /* Primary  R231 G231 B232 */
  --gu-deep:   #144da3;   /* Accent   R20  G77  B162 */
  --gu-steel:  #565757;   /* Accent   R86  G87  B87  */
  --gu-gold:   #a3814e;   /* Accent   R163 G129 B78  */
  --gu-white:  #ffffff;

  /* ── 2. Accessible derivatives ────────────────────────────────────────────
     Three of the six brand colors CANNOT carry body text on the surfaces they
     are naturally paired with. These are the minimum on-brand corrections that
     reach WCAG AA (4.5:1) — each is the first passing 1% step away from the
     guideline color, so it is as close to brand as accessibility allows.

       --gu-blue  on --gu-ink   = 3.51:1  FAIL  ->  --gu-blue-on-dark   4.56:1
       --gu-blue  on --gu-paper = 4.13:1  FAIL  ->  --gu-blue-on-light  4.52:1
       --gu-gold  on --gu-paper = 2.93:1  FAIL  ->  --gu-gold-on-light  4.51:1
       --gu-steel on --gu-ink   = 2.47:1  FAIL  ->  --gu-steel-on-dark  4.59:1  */
  --gu-blue-on-dark:  #6482ae;   /* blue  13% -> white */
  --gu-blue-hi:       #8fa4c4;   /* blue  37% -> white — AAA 7.06:1 on ink */
  --gu-blue-on-light: #496998;   /* blue   7% -> ink   */
  --gu-gold-on-light: #7d643f;   /* gold  27% -> ink   */
  --gu-gold-on-white: #8f7246;   /* gold  14% -> ink   */
  --gu-steel-on-dark: #808181;   /* steel 29% -> paper */

  /* ── 3. Typography ────────────────────────────────────────────────────────
     Font 1 Montserrat = display. Font 2 Roboto = text.
     The guidelines set every display string in caps with open tracking; that
     treatment lives in --gu-display-* rather than being retyped per component. */
  --gu-font-display: "Montserrat", ui-sans-serif, system-ui, sans-serif;
  --gu-font-text:    "Roboto", ui-sans-serif, system-ui, sans-serif;
  --gu-font-mono:    ui-monospace, "Cascadia Code", "Source Code Pro", monospace;

  --gu-display-transform: uppercase;
  --gu-display-tracking:  0.06em;   /* the guideline's wide caps */
  --gu-display-weight:    800;
  --gu-display-leading:   1.04;

  /* Fluid modular scale, ratio 1.2 at 360px growing to 1.25 at 1440px.
     Every step is clamp()ed so nothing needs a media query to be readable.

     ⚠️ The MINIMUMS are set by what fits a 360px viewport, not by taste. At
     360px the content box is 328px, and display text is Montserrat 800 in caps
     at 0.06em tracking — roughly 0.76em of advance per character. A 3rem (48px)
     minimum on --gu-text-5xl therefore cannot fit any word past ~9 characters,
     and the battery caught exactly that: "conviction" measured 355px against a
     328px box and pushed the page 13px sideways. 2.5rem clears ~11 characters;
     `overflow-wrap` in base.css catches whatever is longer. Do not raise a
     minimum without re-running the 360px battery. */
  --gu-text-xs:   clamp(0.75rem,  0.72rem + 0.15vw, 0.8125rem);
  --gu-text-sm:   clamp(0.875rem, 0.85rem + 0.16vw, 0.9375rem);
  --gu-text-base: clamp(1rem,     0.96rem + 0.20vw, 1.125rem);
  --gu-text-lg:   clamp(1.125rem, 1.06rem + 0.32vw, 1.375rem);
  --gu-text-xl:   clamp(1.25rem,  1.16rem + 0.42vw, 1.75rem);
  --gu-text-2xl:  clamp(1.5rem,   1.32rem + 0.80vw, 2.25rem);
  --gu-text-3xl:  clamp(1.75rem,  1.46rem + 1.30vw, 3rem);
  --gu-text-4xl:  clamp(2.125rem, 1.68rem + 1.98vw, 4rem);
  --gu-text-5xl:  clamp(2.5rem,   1.83rem + 2.98vw, 5.5rem);

  --gu-leading-tight: 1.12;
  --gu-leading-snug:  1.32;
  --gu-leading-body:  1.62;
  --gu-measure:       66ch;   /* the line length body copy is capped at */

  /* ── 4. Space, radius, elevation ──────────────────────────────────────────
     One 4px-rooted scale. Section padding is fluid so the rhythm survives the
     jump from a 360px phone to a 2560px monitor without a breakpoint. */
  --gu-space-3xs: 0.25rem;  --gu-space-2xs: 0.5rem;   --gu-space-xs: 0.75rem;
  --gu-space-sm:  1rem;     --gu-space-md:  1.5rem;   --gu-space-lg: 2rem;
  --gu-space-xl:  3rem;     --gu-space-2xl: 4rem;     --gu-space-3xl: 6rem;
  --gu-section-y: clamp(3rem, 2rem + 5vw, 7.5rem);
  --gu-gutter:    clamp(1rem, 0.5rem + 2.5vw, 3rem);
  --gu-max-width: 78rem;

  --gu-radius-sm: 2px;   --gu-radius-md: 4px;
  --gu-radius-lg: 8px;   --gu-radius-pill: 999px;

  /* The brand is angular — a Spartan shield, not a rounded app chip. Shadows
     are tight and low-spread so cards read as plates, not as floating cards. */
  --gu-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.28);
  --gu-shadow-md: 0 2px 8px rgb(0 0 0 / 0.32);
  --gu-shadow-lg: 0 8px 32px rgb(0 0 0 / 0.42);

  /* ── 5. Motion ────────────────────────────────────────────────────────────
     Every duration below is overridden to 1ms under prefers-reduced-motion at
     the bottom of this file, so a component never has to check the query. */
  --gu-ease:      cubic-bezier(0.22, 0.61, 0.36, 1);
  --gu-ease-out:  cubic-bezier(0.16, 1, 0.3, 1);
  --gu-dur-fast:  140ms;
  --gu-dur-base:  240ms;
  --gu-dur-slow:  420ms;

  --gu-focus-width:  3px;
  --gu-focus-offset: 2px;
}

/* ============================================================================
   6. SURFACES — the palette combinations
   ----------------------------------------------------------------------------
   A surface is a background plus every foreground that is legal on it, INCLUDING
   the logo's four layer colors. Set `data-surface` on any element and everything
   inside it — text, links, rules, buttons, and the SVG logo — resolves to the
   guideline-approved combination for that plate. This is why the logo never
   needs a per-variant file: it recolors from the surface it sits on.

   Ratios in the comments are measured against that surface's own background.
   ============================================================================ */

[data-surface] {
  color: var(--gu-fg);
  background-color: var(--gu-bg);
}

/* ── ink — the primary plate. The brand's default. ────────────────────────── */
[data-surface="ink"] {
  --gu-bg:        var(--gu-ink);
  --gu-bg-raised: #1f1f1f;
  --gu-fg:        var(--gu-paper);        /* 14.51:1  AAA */
  --gu-fg-strong: var(--gu-white);        /* 17.93:1  AAA */
  --gu-fg-muted:  var(--gu-steel-on-dark);/*  4.59:1  AA  */
  --gu-accent:    var(--gu-gold);         /*  4.96:1  AA  */
  --gu-link:      var(--gu-blue-hi);      /*  7.06:1  AAA */
  --gu-link-hover:var(--gu-white);
  --gu-rule:      #303030;
  --gu-focus:     var(--gu-gold);
  /* LOGO A — gold crest, blue helmet. The guidelines' primary dark variant. */
  --gu-logo-helmet: var(--gu-blue);
  --gu-logo-crest:  var(--gu-gold);
  --gu-logo-ink:    var(--gu-ink);
  --gu-logo-steel:  var(--gu-steel);
  --gu-logo-white:  var(--gu-white);
}

/* ── midnight — ink with a white crest. For hero plates over imagery. ─────── */
[data-surface="midnight"] {
  --gu-bg:        #0d0d0d;
  --gu-bg-raised: #1a1a1a;
  --gu-fg:        var(--gu-white);
  --gu-fg-strong: var(--gu-white);
  --gu-fg-muted:  var(--gu-steel-on-dark);
  --gu-accent:    var(--gu-gold);
  --gu-link:      var(--gu-blue-hi);
  --gu-link-hover:var(--gu-white);
  --gu-rule:      #2a2a2a;
  --gu-focus:     var(--gu-gold);
  --gu-logo-helmet: var(--gu-blue);
  --gu-logo-crest:  var(--gu-white);
  --gu-logo-ink:    #0d0d0d;
  --gu-logo-steel:  var(--gu-steel-on-dark);
  --gu-logo-white:  var(--gu-white);
}

/* ── paper — the light plate for long-form reading. ───────────────────────── */
[data-surface="paper"] {
  --gu-bg:        var(--gu-paper);
  --gu-bg-raised: var(--gu-white);
  --gu-fg:        var(--gu-ink);          /* 14.51:1  AAA */
  --gu-fg-strong: var(--gu-ink);
  --gu-fg-muted:  var(--gu-steel);        /*  5.87:1  AA  */
  --gu-accent:    var(--gu-gold-on-light);/*  4.51:1  AA  — NOT raw --gu-gold */
  --gu-link:      var(--gu-deep);         /*  6.49:1  AA  */
  --gu-link-hover:var(--gu-ink);
  --gu-rule:      #cfcfd2;
  --gu-focus:     var(--gu-deep);
  /* LOGO B — full-color mark reads correctly on light; the shield's steel
     outline is what separates it from the plate. */
  --gu-logo-helmet: var(--gu-blue);
  --gu-logo-crest:  var(--gu-gold);
  --gu-logo-ink:    var(--gu-ink);
  --gu-logo-steel:  var(--gu-steel);
  --gu-logo-white:  var(--gu-white);
}

/* ── white — maximum-contrast plate for dense content and forms. ──────────── */
[data-surface="white"] {
  --gu-bg:        var(--gu-white);
  --gu-bg-raised: var(--gu-paper);
  --gu-fg:        var(--gu-ink);          /* 17.93:1  AAA */
  --gu-fg-strong: var(--gu-ink);
  --gu-fg-muted:  var(--gu-steel);        /*  7.25:1  AAA */
  --gu-accent:    var(--gu-gold-on-white);/*  4.50:1  AA  */
  --gu-link:      var(--gu-deep);         /*  8.01:1  AAA */
  --gu-link-hover:var(--gu-ink);
  --gu-rule:      #dcdce0;
  --gu-focus:     var(--gu-deep);
  --gu-logo-helmet: var(--gu-blue);
  --gu-logo-crest:  var(--gu-gold);
  --gu-logo-ink:    var(--gu-ink);
  --gu-logo-steel:  var(--gu-steel);
  --gu-logo-white:  var(--gu-white);
}

/* ── blue — the brand-blue plate. LOGO C: all-white mark. ───────────────────
   🔴 CONSTRAINT: this plate has NO ROOM for a secondary text tier. White is
   5.11:1 on #4d6fa2 and is the CEILING — every tint darker than white measured
   below 4.5:1 (the obvious muted choice, #e2e8f2, came out at 4.15:1, and
   --gu-paper as a hover color at 4.13:1). So --gu-fg-muted and --gu-link-hover
   are both plain white here, and hover is signalled by the underline weight in
   base.css rather than by color.
   Use this surface for SHORT, high-contrast content — a CTA band, a pull quote,
   a stat row. It cannot carry an article with captions and secondary notes. */
[data-surface="blue"] {
  --gu-bg:        var(--gu-blue);
  --gu-bg-raised: #587cb3;
  --gu-fg:        var(--gu-white);        /*  5.11:1  AA  */
  --gu-fg-strong: var(--gu-white);
  --gu-fg-muted:  var(--gu-white);        /*  5.11:1  — no muted tier exists */
  --gu-accent:    var(--gu-white);
  --gu-link:      var(--gu-white);
  --gu-link-hover:var(--gu-white);
  --gu-rule:      #6a8bb8;
  --gu-focus:     var(--gu-white);
  /* ⚠️ On this plate the mark MUST go monochrome white. The gold crest against
     brand blue measures 1.41:1 — it disappears. */
  --gu-logo-helmet: var(--gu-white);
  --gu-logo-crest:  var(--gu-white);
  --gu-logo-ink:    var(--gu-white);
  --gu-logo-steel:  var(--gu-white);
  --gu-logo-white:  var(--gu-white);
}

/* ── deep — the accent-blue plate for high-emphasis CTA bands. ────────────── */
[data-surface="deep"] {
  --gu-bg:        var(--gu-deep);
  --gu-bg-raised: #1a5cbd;
  --gu-fg:        var(--gu-white);        /*  8.01:1  AAA */
  --gu-fg-strong: var(--gu-white);
  --gu-fg-muted:  #cfdcf2;                /*  5.79:1  AA  */
  /* ⚠️ NOT raw --gu-gold: it measures 2.22:1 on this plate — below even the 3:1
     non-text bar, so it fails as an accent AND as the logo's crest. This is
     --gu-gold mixed 50% toward white, the first step that clears AA. */
  --gu-accent:    #d1c0a7;                /*  4.51:1  AA  */
  --gu-link:      var(--gu-white);
  --gu-link-hover:var(--gu-paper);
  --gu-rule:      #3c6cb5;
  --gu-focus:     var(--gu-white);
  --gu-logo-helmet: var(--gu-white);
  --gu-logo-crest:  #d1c0a7;
  --gu-logo-ink:    var(--gu-deep);
  --gu-logo-steel:  var(--gu-white);
  --gu-logo-white:  var(--gu-white);
}

/* ── steel — the neutral plate that separates two dark sections. ──────────── */
[data-surface="steel"] {
  --gu-bg:        var(--gu-steel);
  --gu-bg-raised: #646565;
  --gu-fg:        var(--gu-white);        /*  7.25:1  AAA */
  --gu-fg-strong: var(--gu-white);
  --gu-fg-muted:  #d6d6d6;
  --gu-accent:    var(--gu-white);
  --gu-link:      var(--gu-white);
  --gu-link-hover:var(--gu-paper);
  --gu-rule:      #6e6f6f;
  --gu-focus:     var(--gu-white);
  --gu-logo-helmet: var(--gu-white);
  --gu-logo-crest:  var(--gu-white);
  --gu-logo-ink:    var(--gu-ink);
  --gu-logo-steel:  var(--gu-white);
  --gu-logo-white:  var(--gu-white);
}

/* ── gold — a decorative band. Short strings only, never body copy. ─────────
   🔴 SAME CONSTRAINT AS blue, from the other direction: --gu-ink at 4.96:1 is
   the FLOOR, and every step darker (including #000 at 5.50:1) is a change too
   small to perceive while every step lighter fails — the obvious muted choice
   #3d3223 measured 3.46:1. No secondary tier here either. */
[data-surface="gold"] {
  --gu-bg:        var(--gu-gold);
  --gu-bg-raised: #b18f5b;
  --gu-fg:        var(--gu-ink);          /*  4.96:1  AA  */
  --gu-fg-strong: var(--gu-ink);
  --gu-fg-muted:  var(--gu-ink);          /*  4.96:1  — no muted tier exists */
  --gu-accent:    var(--gu-ink);
  --gu-link:      var(--gu-ink);
  --gu-link-hover:var(--gu-ink);
  --gu-rule:      #8c6f43;
  --gu-focus:     var(--gu-ink);
  --gu-logo-helmet: var(--gu-ink);
  --gu-logo-crest:  var(--gu-ink);
  --gu-logo-ink:    var(--gu-ink);
  --gu-logo-steel:  var(--gu-ink);
  --gu-logo-white:  var(--gu-ink);
}

/* ============================================================================
   7. Logo
   ============================================================================ */

/* Size the WRAPPER, never the <svg>. The svg fills its wrapper and its own
   viewBox + preserveAspectRatio does the fitting, so the same markup works
   whether the slot is width-constrained (a nav bar) or height-constrained (a
   fixed-height card). Setting width/height inline on the <svg> defeats this —
   inline styles beat these rules and a tall mark then overflows its box. */
.gu-logo { display: block; }

/* Default: the mark fills the wrapper's WIDTH and its height follows the
   aspect ratio. This is what a nav bar, a footer, or a hero wants. */
.gu-logo > svg { display: block; width: 100%; height: auto; }

/* `--fit` is for a slot with a FIXED HEIGHT — a card row, an icon strip — where
   marks of very different aspect ratios (2.9:1 lockup vs 0.8:1 shield) must
   occupy the same box. The svg then fills the box in both axes and its own
   viewBox + preserveAspectRatio letterboxes the mark inside it.
   ⚠️ Two explicit classes, not a heuristic. An earlier version tried to detect
   a height-constrained slot with `:not([style*="height"])`; a wrapper sized by
   a stylesheet rather than an inline style slipped straight through it and the
   shields overflowed their cards. */
.gu-logo--fit > svg { width: 100%; height: 100%; }
/* The traced SVGs paint each layer with `fill: var(--gu-logo-<role>, #hex)`,
   so a logo dropped into any [data-surface] adopts that surface's approved
   variant with no per-variant asset and no JS. The literal hex in each fill is
   the guideline color, which is what renders if the SVG is opened standalone. */

/* Forced-colors (Windows High Contrast) flattens the mark to system colors;
   without this the helmet and crest collapse into one silhouette. */
@media (forced-colors: active) {
  .gu-logo .gu-logo__helmet { fill: CanvasText; }
  .gu-logo .gu-logo__crest  { fill: Highlight; }
  .gu-logo .gu-logo__ink,
  .gu-logo .gu-logo__steel,
  .gu-logo .gu-logo__white  { fill: Canvas; }
}

/* ============================================================================
   8. Reduced motion — one place, not per component
   ============================================================================ */

@media (prefers-reduced-motion: reduce) {
  :root {
    --gu-dur-fast: 1ms;
    --gu-dur-base: 1ms;
    --gu-dur-slow: 1ms;
  }
}
