/* ═════════════════════════════════════════════════════════════════════════════
   AIU GLASS MATERIAL + HOVER RULING — the PUBLIC-SITE port
   ═════════════════════════════════════════════════════════════════════════════
   THE RULE: docs/design/AIU-STYLE-GUIDE.md v1.3 §10a (the material) · §10b (the
   hover ruling) · §10c (the fence register).
   THE SOURCE OF RECORD: the FOUNDER-accepted specimen
   docs/design/prototypes/glass-material-2026-07-27.html (commit fc7e76568).
   THE SHIPPED IMPLEMENTATION this file is transcribed FROM, mechanically:
   the "AIU GLASS MATERIAL — ROUND 5 · SITE-WIDE" block in intel/app/globals.css
   on branch intel-e2e-pregoal — which is the register FOUNDER accepted RENDERED
   on the Intel Today page, and which carries the round-6 corrections that
   postdate the prototype.

   WHY THIS FILE EXISTS. FOUNDER, 2026-07-30, on the Intel sweep: the Today page
   standard is "today standard across the board" — the whole estate, not Intel.
   The style guide already says the same thing in §10a ("this block is the
   AIU-wide standard, not an Intel one ... lifting it to another app is copying
   the light model + the token pair + re-pointing the surface list"). Until this
   file, the only place the material EXISTED was one Next app is stylesheet, on a
   branch the public site does not build from. A standard that lives in one
   app is CSS is a standard the next site does not inherit — which is the exact
   failure §10a was written after.

   HOW IT WAS PORTED — and why you can trust the numbers. Every value below was
   EXTRACTED from the shipped block by script, not retyped: the token blocks were
   sliced by line range and the class set was produced by parsing the shipped
   rules and filtering each selector list down to its `.gl` members. Nothing was
   re-derived, re-tuned or eyeballed. Three deliberate differences, all of them
   scope rather than value:

     1 · SCOPE. Intel scopes the material to `.aiu` (its app wrapper) and names
         its own surfaces alongside `.gl` in every selector list. The public site
         has no app wrapper and no Intel surfaces, so the tokens sit on `:root`
         and the ONLY selector is `.gl` and its variants. This is the guide is own
         instruction — a new glass surface adds the CLASS, it does not become a
         14th entry in a stylesheet is migration list.

     2 · THE ACCENT. Intel is hover glow reads `--c-op` (its own accent token).
         Here it reads `--gl-accent`, which each page points at its own brand
         token. The material itself is still luminance-only; the accent rides ON
         TOP, on hover only (§10a property 4).

     3 · `.gl--bar` IS A REAL CLASS HERE. Intel implements the bar variant
         directly on `.aiu-mast`; the guide is §10a variant table names it
         `.gl--bar`. The public site needs the variant on a masthead that is not
         called `.aiu-mast`, so the class exists and carries the shipped
         masthead is token overrides verbatim, including the (i)-(vi) exceptions
         and the 28px/20px blur pair.

   WHAT IS NOT PORTED, named rather than silently dropped: `--intel-shelf` /
   `--intel-shelf-edge` (Intel is nav shelf — a surface the public site does not
   have), and Intel is own surface names. `.gl--lens` IS included but nothing on
   the public site opts into it yet; it costs a second backdrop-filter pass and
   is capped at 1-2 elements per page.

   THE FIVE CHECKABLE FACTS a review looks for (§10a) — a raised object either has
   all five or it is not wearing the material: backdrop film · masked ::before rim
   on the border box · a five-rung shadow ladder · no drawn border (the only legal
   one is an accent TOP-rule) · five interior layers, never one flat sheen.
   Checked, never claimed: `node scripts/global-style-audit.mjs`.

   THE TRAP, restated because it recurred once already and every computed value
   still reads correct when it fires: `overflow: hidden` on a card DELETES the rim
   (a ::before pulled out to the border box) and the hover glow (a z-index:-1
   ::after whose whole content is shadow OUTSIDE the box). A computed-style-only
   check green-lights it. If a clip is genuinely unavoidable, state the surface as
   an exception with its reason; the lift alone is the CVD-safe cue that survives.

   CVD (FOUNDER is red/green colourblind, binding): every token here is white or
   neutral-warm black. Nothing in the material carries meaning by hue, and the
   hover cue is GEOMETRY (the lift), legible in greyscale and under deuteranope
   and protanope simulation. The accent glow is decoration and carries no
   information.
   ═════════════════════════════════════════════════════════════════════════════ */

/* The accent the hover glow borrows, and the neutral hover edge for the chip
   class (§10b). A page overrides `--gl-accent` with its own brand token; the
   fallback is the site is azure interactive register. */
:root {
  --gl-accent: var(--accent, #1B4F8A);
  --gl-edge: rgba(20, 23, 29, 0.20);
}
html[data-theme="dark"] {
  --gl-edge: rgba(222, 232, 245, 0.24);
}

/* ── SPEC BLOCK 1 of 3 — THE LIGHT MODEL ── */
:root {
  /* THE one authored value. 0deg = directly above the page, clockwise.
     332deg = above and to the left — the reading light every physical-object
     convention assumes. */
  --gl-az: 332deg;
  /* derived — do not hand-edit */
  --gl-dx: calc(-1 * sin(var(--gl-az)));   /* shadow direction, x (+0.469) */
  --gl-dy: calc(cos(var(--gl-az)));        /* shadow direction, y (+0.883) */
  --gl-sweep: calc(var(--gl-az) - 180deg); /* the direction the light TRAVELS */
  --gl-drop: 1.55;                         /* the one honest bias: shadows fall
                                              further down than pure azimuth,
                                              because the page has a floor. */
  /* geometry */
  --gl-radius: 22px;
  --gl-rim-w: 1.6px;
  --gl-blur: 22px;
  --gl-sat: 1.7;

  /* THE RIM'S ANCHOR. `inset:0` on an absolutely-positioned pseudo resolves to the
     PADDING box, so on any surface with a border the ring lands INSIDE the
     silhouette wearing the border-box radius — two circles, equal radius,
     different centres, which do not nest. These tokens pull the ring back out to
     the border box. Each surface declares its OWN border widths below; the
     default is 0 so `.gl` (which has `border:0`) is unaffected. */
  --gl-ins-t: 0px; --gl-ins-r: 0px; --gl-ins-b: 0px; --gl-ins-l: 0px;

  /* THE CORNER TERMS, DERIVED FROM THE CORNER THEY DESCRIBE (round 6, F6). Radii on
     the register run 12 / 14 / 22 / 26px while these were hard-coded at values tuned
     for 22 and every surface silently inherited `--gl-radius: 22px` regardless of
     what it renders. `--gl-bloom` reproduces the benched 30px EXACTLY at the
     canonical 22px radius, by construction — nothing about the specimen's verified
     corner changes — and then scales honestly: 14 -> 22px, 26 -> 34px, 12 -> 20px.

     THIS DECLARATION IS THE DEFAULT FOR `.gl` ONLY, AND THE DERIVATION IS REPEATED
     ON EVERY SURFACE THAT DECLARES ITS OWN `--gl-radius`. That repetition is not
     redundancy, it is the only thing that works: a custom property substitutes its
     `var()` references at COMPUTED-VALUE TIME ON THE ELEMENT THAT DECLARES IT, and
     then inherits the RESOLVED token stream. Declared only here, `--gl-bloom`
     resolves against THIS block's 22px and every descendant inherits the literal
     `calc(22px + 8px)` — so a 14px card would silently wear a 30px bloom and the
     "derived from the corner it describes" claim would be false everywhere except
     `.gl`. Verified rendered, not assumed. Re-declaring the SAME expression next to
     each surface's own `--gl-radius` makes it re-resolve per element.
     Guarded by e2e/glass-rim-geometry.spec.ts, which asserts the arithmetic per
     surface so a new surface added without this line fails rather than drifts. */
  --gl-bloom: calc(var(--gl-radius) + 8px);   /* the lit-corner thickness bloom */
  --gl-glint-r: 46px;                          /* the counter-glint's radius */
  --gl-glint-off: 15px;                        /* …held this far inboard (a LENGTH) */
}

/* Engines without CSS trig (pre-2023) get the same numbers, statically. */
@supports not (top: calc(sin(30deg) * 1px)) {
    :root { --gl-dx: 0.469; --gl-dy: 0.883; }
}


/* ── THE HOVER RULING — one grammar, six tokens (§10b) ── */
:root {
  --hv-lift:   -3px;                                  /* the ONE lift. -2px and 0px are retired. */
  --hv-dur:    0.24s;
  --hv-ease:   cubic-bezier(0.2, 0.7, 0.15, 1);       /* the existing house spring */
  --hv-accent: color-mix(in oklab, var(--gl-accent) 45%, transparent);
  --hv-wash:   color-mix(in oklab, var(--gl-accent) 6%, transparent);  /* the ONE wash: 4/7/14% retired */
  --hv-edge:   var(--gl-edge);                    /* the ONLY legal hover border — neutral, never accent */
}


/* ── SPEC BLOCK 2 of 3 — THE MATERIAL TOKENS, per theme ── */
/* ═══════════════════════════════════════════════════════════════════════════════
   `.gl--reversed` — THE OBJECT WHOSE GROUND IS NOT THE PAGE'S GROUND
   ═══════════════════════════════════════════════════════════════════════════════
   The two token sets below are keyed to the THEME. That is right for almost every
   surface and WRONG for one real case, which this site has: a REVERSED section — a
   dark band inside a light page (and, because this site is an inverted-pair system,
   a light band inside a dark page). Measured, not assumed: `.cmap-major-card` on
   /courses and `.career-card` on a /majors page sit on rgb(20,23,29) in LIGHT theme
   and rgb(237,241,247) in DARK theme, with their text colour inverting to match.

   WHY IT MATTERS, and how it was found: by rendering it. Given the light token set
   on a dark band, the material's white sheen (0.88) and pool (0.97) paint a bright
   diagonal smear, and the section's white type then sits ON that smear. It is not a
   cosmetic mismatch, it is a contrast failure — the exact thing §10a's own
   MEASUREMENT note budgets for, defeated by handing the wrong budget to the right
   card. Nothing in the computed style looks wrong; you have to look at it.

   THE FIX IS THE MATERIAL'S OWN PHYSICS, NOT A NEW ONE. §10a spec block 2: "the
   load-bearing difference is a SIGN FLIP — on a light ground the away-side edges are
   DARK (refraction); on a dark ground they are a dim grazing return. Same physics,
   opposite ground." An object on a reversed ground simply takes the OTHER set. So
   `.gl--reversed` is added to each token block's SELECTOR LIST rather than existing
   as a third copy of ~40 numbers: light applies to `:root` and to a reversed object
   in dark theme; dark applies in dark theme and to a reversed object in light theme.

   THE CASCADE, stated because it is doing real work here:
     · `.gl--reversed` (0,1,0) ties `:root` (0,1,0) and wins on SOURCE ORDER — which
       is why the dark block must stay second. Moving it above the light block
       silently reverts every reversed card.
     · `html[data-theme="dark"] .gl--reversed` (0,2,1) beats `html[data-theme="dark"]`
       (0,1,1) on specificity, so it holds wherever it is placed.
   ═══════════════════════════════════════════════════════════════════════════════ */
:root,
html[data-theme="dark"] .gl--reversed {
  /* body + interior */
  --gl-body:  rgba(255, 255, 255, 0.52);  /* translucent fill — ground bleeds through */
  --gl-lip:   rgba(255, 255, 255, 0.98);  /* tight glow just inside the top edge     */
  --gl-pool:  rgba(255, 255, 255, 0.97);  /* interior pool where the light enters    */
  --gl-sheen: rgba(255, 255, 255, 0.88);  /* diagonal body sheen — a band, not a fill*/
  --gl-tint:  rgba(58, 48, 36, 0.072);    /* falloff AWAY from the light. CAP 0.072  */
  --gl-glint: rgba(255, 255, 255, 0.42);  /* counter-glint, in the body (property 3) */
  --gl-rim-1: rgba(255, 255, 255, 0.70);  /* lit-corner thickness bloom              */

  /* ROUND 6 — the face ramp gained a knee, so the decay is a SWEEP across the
     whole face and not a corner smudge. CAP AMENDED .050 -> .072 by measurement
     (hard wall .086 = --accent-txt 12px bold, bottom-right footer; 16% headroom). */
  --gl-tint-mid: rgba(58, 48, 36, 0.028);
  --gl-fall-in:  6%;    /* where the face STARTS to decay (was a flat 40%) */
  --gl-fall-mid: 44%;   /* the knee */

  /* ROUND 6 — THE THICKNESS SHOULDER, lit edges only. Full rim depth, low value,
     UNDER the crest. THIS is the term that closes the transparent gap that made
     the lit edge read as two strokes: across the edge width the profile becomes
     crest -> shoulder -> face, which is a falloff, which is thickness. */
  --gl-sh-top:  rgba(255, 255, 255, 0.42);
  --gl-sh-left: rgba(255, 255, 255, 0.30);

  /* ROUND 6 — the entry pool's extent is now a TOKEN, so a full-bleed bar can
     re-express it in LENGTH instead of inheriting a half-window wash (root cause B). */
  --gl-pool-w: 64%;
  --gl-pool-h: 22%;

  /* THE EDGE, in two terms — the way a real specular works.
     --gl-lip-* is the AMBIENT floor: continuous, follows the radius, guarantees
       the silhouette never breaks at any aspect ratio.
     --gl-run-* is the DIRECTIONAL term: it fades ALONG the length of its own
       edge, peaking at the end nearest the light.
     Floor + run is why no single edge is one flat value — and four DIFFERENT
     floors is why this is not a uniform ring.
     The two AWAY floors are cut to a continuity minimum (round 5) so the run
     takes the weight back and the shadow-side edge GATHERS at the away corner
     (11.5:1 bottom, 10.3:1 right) instead of reading as a ruled line. That is
     safe here because the outer contour crescent sits immediately outside
     exactly those two edges at full strength. */
  --gl-lip-top:    rgba(255, 255, 255, 0.52);  --gl-run-top:    rgba(255, 255, 255, 0.90);
  --gl-lip-left:   rgba(255, 255, 255, 0.34);  --gl-run-left:   rgba(255, 255, 255, 0.66);
  --gl-lip-right:  rgba(48, 40, 30, 0.045);    --gl-run-right:  rgba(48, 40, 30, 0.42);
  --gl-lip-bottom: rgba(48, 40, 30, 0.055);    --gl-run-bottom: rgba(48, 40, 30, 0.58);

  /* shadow ladder — contour (a DIRECTIONAL pair, never one even ring), contact,
     mid, ambient. The ground is occluded hard where the object shades it and
     barely at all on the lit side. */
  --gl-contour-away: rgba(52, 44, 34, 0.17);
  --gl-contour-lit:  rgba(52, 44, 34, 0.075);
  --gl-contact: rgba(46, 38, 28, 0.17);
  --gl-mid:     rgba(50, 40, 28, 0.155);
  --gl-amb:     rgba(56, 44, 26, 0.30);
  --intel-shelf-edge: rgba(48, 40, 30, 0.10);
}

html[data-theme="dark"],
.gl--reversed {
  --gl-body:  rgba(34, 32, 30, 0.50);
  --gl-lip:   rgba(255, 255, 255, 0.34);
  --gl-pool:  rgba(255, 255, 255, 0.055);  /* CAPPED — contrast budget, see below */
  --gl-sheen: rgba(255, 255, 255, 0.022);  /* CAPPED — contrast budget, see below */
  --gl-tint:  rgba(0, 0, 0, 0.36);
  --gl-glint: rgba(255, 255, 255, 0.030);  /* CAPPED — spatially disjoint from sheen */
  --gl-rim-1: rgba(255, 255, 255, 0.70);

  /* ROUND 6 — DARK IS PINNED. The knee is SHARED structure, so dark gets stop
     positions + a mid value that REPRODUCE round 5's straight line rather than a
     new curve:  round 5 (40%,0)->(100%,.36) ;  round 6 (38%,0)->(70%,.18)->(100%,.36).
     At 70% the old line is (70-40)/60 x .36 = .18 — the knee sits exactly ON it, so
     the second half is identical and the first half deviates by at most .006 alpha
     of black, under one 8-bit step. Unchanged by arithmetic, not by hope. */
  --gl-tint-mid: rgba(0, 0, 0, 0.18);
  --gl-fall-in:  38%;
  --gl-fall-mid: 70%;

  /* The shoulder is a LIGHT-MODE term: on a near-black ground the crest has no
     white page to compete with, so there is no gap to close. Zero, declared as a
     TOKEN rather than as an absent layer — the STRUCTURE stays identical across
     themes (STD-001, one mixin) and only the VALUE differs. */
  --gl-sh-top:  transparent;
  --gl-sh-left: transparent;

  /* Dark KEEPS its away floors: on a near-black ground the floor is the only
     thing separating the away edge from the ground at all, because the outer
     contour there is BLACK and cannot draw that boundary the way it does on
     light. The runs carry ~15% more so the away corner holds the same weight
     while the mid-span gets quieter. Falloff top-run 0.82 : bottom-lip 0.045
     is ~18:1 — nothing about that is a uniform border. */
  --gl-lip-top:    rgba(255, 255, 255, 0.34);  --gl-run-top:    rgba(255, 255, 255, 0.82);
  --gl-lip-left:   rgba(255, 255, 255, 0.20);  --gl-run-left:   rgba(255, 255, 255, 0.38);
  --gl-lip-right:  rgba(255, 255, 255, 0.048); --gl-run-right:  rgba(255, 255, 255, 0.145);
  --gl-lip-bottom: rgba(255, 255, 255, 0.045); --gl-run-bottom: rgba(255, 255, 255, 0.155);

  --gl-contour-away: rgba(0, 0, 0, 0.66);
  --gl-contour-lit:  rgba(0, 0, 0, 0.10);
  --gl-contact: rgba(0, 0, 0, 0.56);
  --gl-mid:     rgba(0, 0, 0, 0.48);
  --gl-amb:     rgba(0, 0, 0, 0.64);
  --intel-shelf-edge: rgba(255, 255, 255, 0.07);
}


/* ── SPEC BLOCK 3 of 3 — THE CLASS SET ── */
.gl {
  background:
    /* 1 · the lip glow. Tight. Dies inside the top padding, above any text. */
    linear-gradient(180deg, var(--gl-lip) 0%, transparent 4.5%),
    /* 2 · the pool where the light enters — a soft corner bloom, off-canvas centre */
    radial-gradient(var(--gl-pool-w) var(--gl-pool-h) at 3% -2%, var(--gl-pool) 0%, transparent 68%),
    /* 3 · the sheen — a diagonal BAND running with the light, not a fill */
    linear-gradient(var(--gl-sweep), transparent 3%, var(--gl-sheen) 16%, transparent 43%),
    /* 3b · THE COUNTER-GLINT, in the body and held a fixed 15px inboard of the
       away corner (property 3 above). A LENGTH, so it lands in the same physical
       place on a 300x300 tile and a 1440x64 bar. */
    radial-gradient(circle var(--gl-glint-r)
      at calc(100% - var(--gl-glint-off)) calc(100% - var(--gl-glint-off)),
      var(--gl-glint) 0%, transparent 100%),
    /* 4 · falloff away from the light — the interior is never uniform. ROUND 6 gave
       this ramp a KNEE, so the decay is a sweep across the whole face rather than a
       corner smudge. The gradient's GEOMETRY is deliberately untouched (same size,
       same off-canvas centre) so nothing about the light's placement moves and dark
       inherits no new shape — only the stops changed. */
    radial-gradient(132% 112% at 3% -5%,
      transparent   var(--gl-fall-in),
      var(--gl-tint-mid) var(--gl-fall-mid),
      var(--gl-tint) 100%),
    /* 5 · the body */
    var(--gl-body);
  /* MINIFIER ORDER — LOAD-BEARING, DO NOT SWAP. lightningcss collapses the
     prefixed/unprefixed pair to the LAST-WRITTEN form; standard-property-LAST is
     the form it preserves. Written the other way round, Chromium ships with no
     blur at all (the S94 masthead defect; see the note on `.aiu .aiu-mast`).
     Guarded against the BUILT output by scripts/intel-built-css-backdrop-check.mjs. */
  -webkit-backdrop-filter: blur(var(--gl-blur)) saturate(var(--gl-sat));
  backdrop-filter: blur(var(--gl-blur)) saturate(var(--gl-sat));
  /* THE SHADOW LADDER — five rungs, all offset along the light vector. The
     contour is two OPPOSED hairlines rather than one even ring; the lit term is
     kept non-zero on purpose (a lit glass edge on a white page genuinely
     vanishes, which is correct optics but risks losing the top-left entirely). */
  box-shadow:
    calc(var(--gl-dx) * 1px) calc(var(--gl-dy) * 1px) 0 0.5px var(--gl-contour-away),
    /* ROUND 6 — this rung is the SECOND of FOUNDER's two lines. As written it was a
       HARD-edged dark band ~1.1px tall standing clear of the rim with hard
       boundaries on BOTH sides — a stroke, regardless of being derived from a light
       vector. Blurred over 1.2px and pulled in to 0.5px it becomes the ground
       darkening as it passes under a thick edge, and runs continuously into the
       rim's own shoulder. `--gl-contour-lit` goes UP (.055 -> .075) WHILE the line
       goes away, because blur spreads the same ink thinner. */
    calc(var(--gl-dx) * -0.5px) calc(var(--gl-dy) * -0.5px) 1.2px 0.1px var(--gl-contour-lit),
    calc(var(--gl-dx) * 2px) calc(var(--gl-dy) * var(--gl-drop) * 2px) 3px -1px var(--gl-contact),
    calc(var(--gl-dx) * 8px) calc(var(--gl-dy) * var(--gl-drop) * 8px) 18px -9px var(--gl-mid),
    calc(var(--gl-dx) * 26px) calc(var(--gl-dy) * var(--gl-drop) * 26px) 58px -28px var(--gl-amb);
  /* The material never draws a border. `border-color` (not `border`) so the box
     model each surface authored is untouched, and so the accent/gilt top-rules —
     which are INFORMATION, not material — can re-assert on their own selectors
     immediately below. */
  border-color: transparent;
}

.gl { border: 0; border-radius: var(--gl-radius);
}

/* A CARD NEEDS A POSITIONING CONTEXT FOR ITS RIM AND ITS LIFT. A BAR ALREADY HAS
   ONE, AND MUST NOT BE GIVEN THIS.
   `.gl--bar` is excluded, and the exclusion is load-bearing rather than tidy. The
   shipped implementation carries the same carve-out with the same reason ("the
   masthead keeps position:sticky, which is already a containing block, and is
   deliberately excluded — overriding it would unstick the shell"); the mechanical
   extraction that produced this file could not see it, because Intel's masthead is
   named `.aiu-mast` and only `.gl` selectors survived the filter.
   The symptom, caught by measuring the rendered geometry and not by reading the
   CSS: `.gl` (0,1,0) beats `nav`/`header` (0,0,1), so every fixed masthead silently
   became `position: relative`, dropped back into flow, and pushed the whole page
   down by exactly the bar's height — 80px at 1280, 60px at 375, on every page on
   the site. Nothing about it looks wrong in a computed-style dump; the layout just
   moves.
   THE CONTRACT this states: a `.gl--bar` host must ALREADY be positioned (fixed or
   sticky — every masthead is). That is what supplies the containing block its rim
   pseudo needs. A static `.gl--bar` would leak its rim, which is why the class is
   for mastheads and caption bars, not for arbitrary wide boxes. */
.gl:not(.gl--bar) {
  position: relative;
}

.gl::before {
  content: "";
  position: absolute;
  /* THE RIM IS THE OBJECT'S SILHOUETTE, so it goes on the BORDER box — always.
     `inset:0` resolves to the PADDING box, which on any surface carrying a border
     (even a transparent 1px spacer) draws the ring 1-3px INSIDE the silhouette
     while `border-radius: inherit` hands it the BORDER-box radius: two circles,
     equal radius, different centres, which do not nest. That non-concentricity is
     the accent-card fray, the hero-brain double arc, and half the masthead's
     bottom-edge offset. Negating the insets to each surface's own border widths
     makes the pseudo's box BE the border box, at which point the inherited radius
     is exactly right. Where a surface carries an accent strip its `--gl-ins-t`
     stays 0 DELIBERATELY — the coloured strip CAPS the glass panel, the material
     never paints over an information channel — and those surfaces take the
     elliptical top-corner radius below. */
  inset: calc(-1 * var(--gl-ins-t)) calc(-1 * var(--gl-ins-r))
         calc(-1 * var(--gl-ins-b)) calc(-1 * var(--gl-ins-l));
  border-radius: inherit;
  padding: var(--gl-rim-w);
  background:
    /* (c) THE FOUR DIRECTIONAL RUNS — the whole directional story. Each fades
       along ITS OWN length, peaking at the end nearest the light and settling
       onto that edge's floor at the far end. Parameterised in x/y, so no aspect
       ratio can crease them.
       QUADRANT NOTE (see --gl-az): these four directions encode "light from the
       upper-left". To move the light to another quadrant, mirror them HERE —
       four lines, no other change anywhere in the material. */
    linear-gradient(90deg, var(--gl-run-top) 0%, transparent 96%) top / 100% 1px no-repeat,
    linear-gradient(180deg, var(--gl-run-left) 0%, transparent 66%) left / 1px 100% no-repeat,
    /* the two AWAY runs start LATE — absent along the lit half, emerging over the
       last ~55%, so the shadow-side edge gathers at the away corner instead of
       holding constant weight and reading as a drawn rule. The start stop is a
       slope change at a point where the value is still ZERO, so it can never show
       as an edge (unlike the deleted conic, whose breaks were value changes at a
       pole). */
    linear-gradient(180deg, transparent 40%, var(--gl-run-right) 100%) right / 1px 100% no-repeat,
    linear-gradient(90deg, transparent 44%, var(--gl-run-bottom) 100%) bottom / 100% 1px no-repeat,
    /* (c2) THE THICKNESS SHOULDER — ROUND 6, and the term that answers "why the
       double lines." The four runs above are each 1px tall inside a 1.6px rim, so
       on the lit edges round 5 painted a 1px crest and then left 0.6px of the ring
       TRANSPARENT before the face began: face, gap, hard bright band, boundary,
       hard dark band, paper — two thin hard strokes of opposite sign with a gap
       between them. Two lines, exactly as reported. This layer fills the FULL rim
       depth underneath the crest at roughly half its value. Lit edges only: the
       away edges are refraction lines and a refraction line is genuinely thin.
       Parameterised in LENGTH like everything else since iteration 3.
       ORDER IS LOAD-BEARING — earlier background layers paint ON TOP, so the
       shoulders go AFTER the four runs (under the crest) and BEFORE the bloom. */
    linear-gradient(90deg,  var(--gl-sh-top)  0%, transparent 88%) top  / 100% var(--gl-rim-w) no-repeat,
    linear-gradient(180deg, var(--gl-sh-left) 0%, transparent 58%) left / var(--gl-rim-w) 100% no-repeat,
    /* (b) corner thickness at the LIT corner only — you look through more
       material diagonally. The AWAY corner's glint lives in the body, which is
       what breaks the bright-against-dark bevel pairing. The bloom is DERIVED from
       the radius it describes (F6) — `--gl-bloom` is radius + 8px, which is the
       benched 30px exactly at the canonical 22px. */
    radial-gradient(circle var(--gl-bloom) at 0% 0%, var(--gl-rim-1) 0%, transparent 74%);
  /* (d) the ambient floor — low, continuous, unbroken round every corner arc, so
     the silhouette can never break where a gradient layer thins out. The runs
     above sit on top of this; floor + run = a specular, not a stroke. */
  box-shadow:
    inset 0 1px 0 var(--gl-lip-top),
    inset 1px 0 0 var(--gl-lip-left),
    inset -1px 0 0 var(--gl-lip-right),
    inset 0 -1px 0 var(--gl-lip-bottom);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  -webkit-mask-repeat: no-repeat;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  mask-repeat: no-repeat;
  pointer-events: none;
  z-index: 2;
}

.gl {
  isolation: isolate;
  /* 60fps: ONLY transform animates. box-shadow is never transitioned. */
  transition: transform var(--hv-dur) var(--hv-ease);
}

.gl::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  /* two luminance rungs from the material + ONE accent rung. The accent glow is
     the shipped R-202/M5 "accent-lit hover" affordance, KEPT: it is brand colour
     riding on top of the material, on hover only, never in the resting state —
     the material itself stays luminance-only. */
  box-shadow:
    calc(var(--gl-dx) * 5px) calc(var(--gl-dy) * var(--gl-drop) * 5px) 11px -4px var(--gl-contact),
    calc(var(--gl-dx) * 14px) calc(var(--gl-dy) * var(--gl-drop) * 32px) 64px -22px var(--gl-amb),
    /* REQ-138: the accent rung, DIALLED DOWN to --hv-accent (45%). It was full
       alpha, which on a fourteen-cover shelf read as a red halo. One token, one
       place — a fifth surface can never re-pick this number. */
    calc(var(--gl-dx) * 18px) calc(var(--gl-dy) * var(--gl-drop) * 30px) 58px -26px var(--hv-accent);
  opacity: 0;
  transition: opacity var(--hv-dur) ease;
  pointer-events: none;
  z-index: -1;
}

@media (hover: hover) {
  .gl:hover {
    transform: translateY(var(--hv-lift));
    will-change: transform;
  }
  .gl:hover::after { opacity: 1;
  }
}

.gl--sm {
  --gl-rim-w: 1.1px;
  --gl-blur: 16px;
  --gl-bloom: var(--gl-radius);   /* the bloom describes the corner, not a third of the face */
  --gl-glint: transparent;        /* see the MEASUREMENT note — the disjointness premise
                                     fails below ~120px and the two white terms sum to
                                     .052 against a .035 budget. Structural + a11y. */
}

.gl--lg { --gl-rim-w: 2.2px;
}

.gl--cap {
  /* (0) THE BAR CAPS THE CARD. Square corners: the card's own radius + its
     `overflow: hidden` cut the two bottom corners, so a radius here would draw a
     SECOND, smaller corner inside the first — the "floating pill inside the
     card" read. Same reasoning as the masthead's `--gl-radius: 0px`. */
  --gl-radius: 0px;
  --gl-bloom: calc(var(--gl-radius) + 8px);
  --gl-rim-w: 1.1px;
  --gl-blur: 16px;
  /* (i) NO LEFT OR RIGHT EDGE — the card clips the bar; the object continues past
     both sides. `--gl-sh-left` is the round-6 shoulder under the absent left edge
     and must go with it, or the exception re-introduces the hairline it deletes. */
  --gl-lip-left: transparent;   --gl-run-left: transparent;   --gl-sh-left: transparent;
  --gl-lip-right: transparent;  --gl-run-right: transparent;
  /* (ii) NO BOTTOM EDGE — it lands ON the card's own bottom edge. Two coincident
     boundaries drawn twice is the double line, not a thicker one. */
  --gl-lip-bottom: transparent; --gl-run-bottom: transparent;
  /* (iii) NO CORNERS — both blooms are anchored to corners the bar does not have. */
  --gl-rim-1: transparent;
  --gl-glint: transparent;
  /* (iv) THE TOP IS THE ONE REAL BOUNDARY, AND IT IS A CONTAINMENT BOUNDARY: it
     separates the caption from the illustration along their whole shared length,
     so it may not fade along it (the masthead's (v), mirrored). The directional
     run goes; the ambient floor, uniform by construction, carries it — and drops
     to a value that reads as a seam rather than as a drawn white rule. */
  --gl-run-top: transparent;
  --gl-sh-top: transparent;
  --gl-lip-top: rgba(255, 255, 255, 0.30);
  /* (v) THE ENTRY POOL IN LENGTH — an entry bloom, not most of the bar. */
  --gl-pool-w: 200px;
  --gl-pool-h: 30px;
}

html[data-theme="dark"] .gl--cap {
  /* Dark keeps its top floor for the reason every away-edge flips on this
     material: on a near-black ground the only direction left is lighter. */
  --gl-lip-top: rgba(255, 255, 255, 0.16);
}

.gl--still { --hv-lift: 0px;
}

.gl--still::after { content: none;
}

.gl--lens::before {
  -webkit-backdrop-filter: brightness(1.22) saturate(1.9);
  backdrop-filter: brightness(1.22) saturate(1.9);
}

html[data-theme="dark"] .gl--lens::before {
  -webkit-backdrop-filter: brightness(1.34) saturate(1.7);
  backdrop-filter: brightness(1.34) saturate(1.7);
}

@media (prefers-reduced-transparency: reduce) {
  .gl { -webkit-backdrop-filter: none; backdrop-filter: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .gl, .gl::after { transition: none;
  }
  .gl:hover { transform: none;
  }
}

@media (max-width: 640px) {
  .gl { --gl-blur: 14px;
  }
}


/* ── `.gl--bar` — THE FULL-BLEED, VIEWPORT-BOUNDED VARIANT (§10a BAR RULE) ── */
html .gl--bar {
  /* SQUARE. The style guide's §10a variant table lists `--gl-radius: 0` as the
     first thing `.gl--bar` changes, and this line is where the port earned it the
     hard way: the shipped implementation does NOT carry it inside its bar block,
     because there the variant is applied to `.aiu-mast`, whose own base rule was
     already square. Lifting the block alone therefore produced a full-width
     masthead with 22px rounded bottom corners floating over the page — caught by
     rendering it, not by reading it. A variant that only works on the one surface
     it was extracted from is not a variant; it is that surface's rule with a new
     name. `--gl-bloom` is re-derived beside it because a custom property resolves
     its var()s on the element that DECLARES it. */
  --gl-radius: 0px;
  --gl-bloom: calc(var(--gl-radius) + 8px);
  border-radius: 0;
  /* (i) NO LEFT OR RIGHT EDGE — the window clips the bar, the object continues
     past both sides. A specular on a boundary that does not exist. Rendered at 4x
     the left run drew a bright vertical hairline hard against x=0 and the right
     run one against the viewport's right. `--gl-sh-left` is the round-6 shoulder
     under that same absent edge and MUST be here too, or the port re-introduces
     the exact hairline this exception was written to delete. */
  --gl-lip-left: transparent;   --gl-run-left: transparent;   --gl-sh-left: transparent;
  --gl-lip-right: transparent;  --gl-run-right: transparent;
  /* (ii) NO CORNERS — both blooms are anchored to corners the bar does not have. */
  --gl-rim-1: transparent;
  --gl-glint: transparent;
  /* (iii) NO FAR CORNER — the face falloff is a corner term sized in PERCENT, so
     on 1440x64 it becomes a wash across the whole window. Same class as (i)/(ii). */
  --gl-tint: transparent;
  --gl-tint-mid: transparent;
  /* (iv) THE ENTRY POOL IN LENGTH, not percent — an entry bloom, not half a window.
     At 64% of 1440 the pool is a 922px white smear; at round 6's .97 it is a
     BRIGHT 922px smear. */
  --gl-pool-w: 420px;
  --gl-pool-h: 46px;
  /* (v) THE BOTTOM BOUNDARY IS UNIFORM. A specular may fade along a length; a
     CONTAINMENT boundary may not — its whole job is to separate two surfaces
     along their entire shared length, and a term that is absent for the first 44%
     of that length simply fails to separate them there (the invisible-left /
     dark-right report). The directional run goes; the ambient floor, which is
     uniform by construction, carries it. The TOP run stays: it is a specular,
     physically correct, and has never been flagged. */
  --gl-run-bottom: transparent;
  --gl-lip-bottom: rgba(48, 40, 30, 0.22);
  /* (vi) THE FILM. This bar repaints on every scroll frame over ARBITRARY content
     and is the only glass on 8 of 14 pages. 52%/14px does not destroy glyph edges,
     it SMEARS them — worse than either honest option, and why scrolled text ghosts
     through hard-edged over photos and dark blocks. Acceptance is MEASURED, not
     asserted: 10.5px mono --ink-soft scrolled under the bar must be non-resolvable
     at 4x, at 1440 and 375, both themes, over the /map hero photo and the dark
     front hero. Do NOT compensate by raising blur past 32px (paint cost on a
     scroll-repaint surface). */
  --gl-body: rgba(255, 255, 255, 0.84);
  --gl-blur: 28px;
  --gl-sat: 1.25;   /* over-saturating an arbitrary photo pushes a colour cast INTO
                       the bar; on a near-opaque film the saturation buys nothing. */
}

html[data-theme="dark"] .gl--bar {
  --gl-body: rgba(20, 19, 18, 0.86);
}

/* ═════════════════════════════════════════════════════════════════════════════
   THE FLOORS THE EXTRACTION COULD NOT CARRY — restored by hand, values verbatim.
   ═════════════════════════════════════════════════════════════════════════════
   The port above was produced by filtering each shipped selector list down to its
   `.gl` members. That is exactly right for the rules that NAME surfaces, and
   exactly wrong for three rules that carry no `.gl` at all because they set TOKENS
   on the scope (`.aiu`) and let inheritance do the rest. Filtering dropped them
   silently — which is the whole reason they are written out here with their
   reason, rather than left as a gap nobody would see until a browser without
   `backdrop-filter` rendered a transparent card.

   Values are the shipped ones, unchanged (intel/app/globals.css, the degradation
   + media blocks at the end of the material). ═════════════════════════════════ */

/* §10a floor — DEGRADATION DEGRADES IN TRANSLUCENCY, NEVER IN PHYSICALITY. Where
   the engine has no backdrop-filter the body goes near-opaque; the rim, the
   five-rung ladder and the whole interior model still render. A card that loses
   its film must still read as an OBJECT, not as a transparent hole. */
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  :root { --gl-body: rgba(255, 255, 255, 0.94); }
  html[data-theme="dark"] { --gl-body: rgba(26, 25, 23, 0.95); }
  html .gl--bar { --gl-body: rgba(255, 255, 255, 0.94); }
  html[data-theme="dark"] .gl--bar { --gl-body: rgba(26, 25, 23, 0.95); }
}

/* Same floor for a reader who has ASKED for less transparency. The film is
   switched off above (the extracted block); these are the body values that make
   that honest instead of see-through. */
@media (prefers-reduced-transparency: reduce) {
  :root { --gl-body: rgba(255, 255, 255, 0.96); }
  html[data-theme="dark"] { --gl-body: rgba(26, 25, 23, 0.97); }
  html .gl--bar { --gl-body: rgba(255, 255, 255, 0.96); }
  html[data-theme="dark"] .gl--bar { --gl-body: rgba(26, 25, 23, 0.97); }
  html .gl--bar { -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* The phone's bar blur. SPECIFICITY, and this is why it is written `html .gl--bar`
   and not `.gl--bar`: the bar block above declares `--gl-blur: 28px` at that same
   specificity, a media query adds NONE, and a plainer selector here would silently
   lose and ship the desktop 28px to a 375px phone. Matched exactly and placed
   LATER in source order, so it wins by order rather than by accident. */
@media (max-width: 640px) {
  html .gl--bar { --gl-blur: 20px; }
}
