/* ═══════════════════════════════════════════════════════════════════════════
   SageX - primitives
   Button · Pill · Card · Section
   ═══════════════════════════════════════════════════════════════════════════

   Requires tokens.css. Load it first:
     <link rel="stylesheet" href="/assets/css/tokens.css">
     <link rel="stylesheet" href="/assets/css/primitives.css">

   ───────────────────────────────────────────────────────────────────────────
   PROVENANCE - every rule is one of two things, and says which
   ───────────────────────────────────────────────────────────────────────────
   [LIFTED]    Traits copied from sagex-component-showcase.html, the locked
               SGX-* look-and-behaviour contract. Gradient angles, hover,
               active scale, shadows and animation are unchanged. Only the
               token NAMES were translated (mapping below).
   [COMPOSED]  No showcase rule existed to lift. Built from tokens.css values
               plus the "Ready-made parts" spec in sagex-design-system.md.
               Flagged so it is obvious what was not inherited.

   ───────────────────────────────────────────────────────────────────────────
   TOKEN TRANSLATION - showcase name -> tokens.css name
   ───────────────────────────────────────────────────────────────────────────
     --sans          ->  --font-display      --bg-2          ->  --surface-section
     --fg-0          ->  --ink-heading       --bg-3          ->  --surface-card
     --fg-1          ->  --ink-high          --indigo        ->  --brand-fill
     --fg-3          ->  --ink-subtle        --indigo-text   ->  --brand-text
     --accent-color  ->  --accent            --line-2 / -3   ->  --hairline
     --mono          ->  --font-mono         --ease-out      ->  defined here, GAP 1
     --bitter        ->  omitted entirely - the italic line needs a 4th font
                         the token set does not carry. See GAP 2.

   ───────────────────────────────────────────────────────────────────────────
   ONE DELIBERATE DEPARTURE FROM THE SHOWCASE
   ───────────────────────────────────────────────────────────────────────────
   The showcase defines SGX-BTN-ENH as linear-gradient(135deg, indigo, #06b6d4).
   That gradient was RETIRED in the capital-markets production build for a
   measured accessibility failure - white-on-cyan reads 2.43:1, and 2.88:1 at
   the worst point under the label. No single ink clears 4.5:1 across
   #4C4CFF -> #06B6D4, so a stop had to move rather than the ink.
   This file uses the corrected --cta-gradient-from -> --cta-gradient-to ramp.
   The showcase is the contract for TRAITS; a documented contrast fix
   outranks it on VALUES.

   ───────────────────────────────────────────────────────────────────────────
   GAPS - real, not hidden
   ───────────────────────────────────────────────────────────────────────────
   1. CLOSED 2026-08-07. --ease-out moved to tokens.css, value unchanged
      (cubic-bezier(0.2, 0, 0, 1)). --ease-in-out added there alongside it.
      There is no local copy in this file any more.
   2. The showcase's italic "frustration" line uses a Bitter serif. tokens.css
      carries three fonts (--font-display, --font-body, --font-mono), not four.
      That rule is omitted rather than substituted with a wrong face.
   3. No nav, footer or trust bar here. Those are assembly, not styling -
      they belong in partials.

   4. CLOSED 2026-08-07 (Ram approved the resolution). The capital-markets base
      had adopted the sgx-* contract but defined NINE names differently from
      this file. Resolved by giving each variant its own true lineage rather
      than overwriting either side:

        .sgx-card       -> stays the .advantage-card lift, as it was.
                           The CM cards became .sgx-sqc* (SGX-SQC Status-Quo
                           Cost Card) - a different showcase component, now
                           promoted below under its own name.
        .sgx-pill       -> stays the animated conic-sweep pill.
                           The CM chip became .sgx-tag*, promoted below.
        .sgx-btn--reg   -> the CM hero's "reg" was transparent + border, i.e.
                           THIS file's --ghost. Renamed there to
                           .sgx-btn--ghost; the two rules were already
                           byte-identical, so nothing moved.
        .sgx-card__icon -> stays the 52px card part. The CM 38px one is
                           .sgx-sqc__icon.
        .sgx-section    -> base is shared again. The CM page's translucency
                           (it mounts a fixed ambient backdrop) moved onto a
                           `.has-ambient` body flag, so it no longer redefines
                           what this file declares. Pages with no backdrop are
                           unaffected.
        --ease-out      -> reconciled to THIS value; see GAP 1, now closed.

      The .sgx-btn base was aligned too (padding 14px 22px, gap 8px), which
      took the CM buttons 44px -> 48px tall. Deliberate: adopting the shared
      contract is the point.

      ONE DELIBERATE DIVERGENCE REMAINS, and it is not drift. This file's
      .sgx-btn--enh:hover uses filter:brightness(1.07) with the note "glow,
      never transform - so :active scale still reads". The capital-markets lane
      is under a standing instruction from Ram that motion is TRANSFORM AND
      OPACITY ONLY, so that page keeps translateY(-1px) on enh hover instead of
      animating a filter. Both are correct in their own lane; do not "fix"
      either into the other without checking which lane you are in.

      The single-dash `.sgx-btn.btn-enh` / `.btn-reg` aliases further down are
      now unused by the capital-markets page (it moved to the -- forms). They
      are kept only for any other surface still on the old markup.
   ═══════════════════════════════════════════════════════════════════════════ */


/* GAP 1 CLOSED 2026-08-07 - --ease-out moved to tokens.css (same value,
   cubic-bezier(0.2, 0, 0, 1), the [LIFTED] showcase curve). No local copy here
   any more, so there is exactly one definition. --ease-in-out lives there too. */


/* ═══════════════════════════════════════════════════════════════
   SECTION  [COMPOSED]
   sagex-design-system.md: "Max width 1320px, generous vertical
   padding, light/dark variants". All four values are tokens.
   ═══════════════════════════════════════════════════════════════ */
.sgx-section{
  padding:var(--pad-y) var(--pad-x);
  background:var(--surface-page);
  position:relative;
}
.sgx-section--base{ background:var(--surface-deep); }
.sgx-section--alt { background:var(--surface-section); }

/* ═══════════════════════════════════════════════════════════════════════════
   BREAKOUT GRID  [COMPOSED]  -  D-2026-0807-09, opt-in via .sgx-section--grid.

   One grid declaration replaces per-component max-widths plus their media
   queries. A block picks a band with ONE line (`grid-column: cards`) instead of
   a width plus two breakpoint overrides.

   THE PART THAT FIXES TABLET. Every inner track is `minmax(0, step)` - it may
   grow to the step, and it collapses to NOTHING when there is no room. So the
   ladder dissolves on its own as the screen narrows and the grid degrades to
   gutter-content-gutter with no media query anywhere. The hand-set-inset version
   of this could not do that: measured, it still took 48px per side at 640px and
   produced 199px cards. A minmax(0,…) track cannot, by arithmetic.

   The gutter track is `minmax(var(--gutter), 1fr)`: --gutter is the FLOOR, and
   1fr means that above 1320px the gutters absorb everything, so the bands stop
   growing rather than sprawling on a large monitor.

   THE NARROW TRACK subtracts the gutters (`100% - var(--gutter)*2`) so the
   innermost band can never push past its own breathing room on a phone.

   WHY NOT subgrid FOR NESTED BLOCKS. `.sgx-flow` sits inside `.how-block`, not
   directly on the wrap, so it cannot take a grid-column from this grid. It gets
   `max-width:var(--band-comp); margin-inline:auto` instead, which lands on the
   identical pixel because its parent is centred too. Same TOKEN, so there is
   still one source of truth for the number - only the delivery differs.
   ═══════════════════════════════════════════════════════════════════════════ */
.sgx-section--grid{ padding-inline:0; }      /* the gutter track replaces --pad-x */

.sgx-section--grid > .sgx-wrap{
  display:grid;
  max-width:none;
  margin-inline:0;
  grid-template-columns:
    [full-start]   minmax(var(--gutter), 1fr)
    [page-start]   minmax(0, var(--step-page))
    [cards-start]  minmax(0, var(--step-cards))
    [comp-start]   minmax(0, var(--step-comp))
    [narrow-start] min(var(--band-narrow), 100% - var(--gutter) * 2) [narrow-end]
                   minmax(0, var(--step-comp))  [comp-end]
                   minmax(0, var(--step-cards)) [cards-end]
                   minmax(0, var(--step-page))  [page-end]
                   minmax(var(--gutter), 1fr)   [full-end];
}
/* Default band. Everything sits on `page` unless it says otherwise, so adding a
   block to a section can never accidentally land it full-bleed. */
.sgx-section--grid > .sgx-wrap > *{ grid-column:page; }
.sgx-section--grid > .sgx-wrap > .band-cards { grid-column:cards; }
.sgx-section--grid > .sgx-wrap > .band-comp  { grid-column:comp; }
.sgx-section--grid > .sgx-wrap > .band-narrow{ grid-column:narrow; }
.sgx-section--grid > .sgx-wrap > .band-full  { grid-column:full; }

/* NESTED COMPONENTS RIDE THE REAL GRID, VIA subgrid.
   The first cut gave these `max-width:var(--band-comp); margin-inline:auto` and it
   was WRONG below about 1050px, caught by rubric #2. Reason: the ladder's step
   tracks are minmax(0,…), so they compress proportionally as space runs out - but
   a max-width does not compress, it just stops binding. Below 1050 the flow filled
   its parent and rendered WIDER than the card row above it. Measured at 1024:
   cards 814px, flow 891px. The ladder was upside down and no screenshot showed it.

   `grid-template-columns:subgrid` makes a block adopt its parent's tracks AND their
   line names, so a child two levels down can sit on `comp` and compress in step
   with everything else. Subgrid: Chrome 117+, Safari 16+, Firefox 71+.

   The block itself stays on `page`, so its heading still aligns with the section's
   own intro copy. Only the diagram inside it pulls in. That alignment is the reason
   this is not simply `.how-block{grid-column:comp}`. */
.sgx-section--grid > .sgx-wrap > .how-block{
  display:grid;
  grid-template-columns:subgrid;
  align-content:start;
}
/* :where() so this default carries ZERO specificity and any band class beats it.
   Written the obvious way first - `.sgx-section--grid > .sgx-wrap > .how-block > *`
   at (0,3,0) - it out-specified `.in-comp` at (0,2,0) and silently pinned every
   nested component back to the page band. The rubric caught it: comp read 1320px
   against cards 1152px at every width. A default must never out-rank an opt-in. */
:where(.sgx-section--grid > .sgx-wrap > .how-block) > *{ grid-column:page; }
.sgx-section--grid .in-comp{ grid-column:comp; }

/* COMPONENT ROWS RESPOND TO THEIR BAND, NOT THE VIEWPORT.
   `auto-fit` + a minimum is the container-aware mechanism for a grid: the row
   fits as many columns as it can at >= the floor and drops one when it cannot.
   It is why the rubric's 260px starvation floor is enforced by construction here
   rather than checked after the fact. This REPLACES the two viewport media
   queries these rows used to carry - those could not see that the row now sits
   in a narrower band, which is precisely how the 199px card happened.
   `min(260px,100%)` keeps it from overflowing a phone narrower than the floor. */
.sgx-section--grid .row-fit{
  grid-template-columns:repeat(auto-fit, minmax(min(260px, 100%), 1fr));
}

/* UNDER-NAV  [COMPOSED]
   The header is sticky, so it occupies flow and the first section starts at the
   header's bottom edge. .sgx-section carries `overflow:hidden`, so anything the
   section paints - its background, and any .bloom inside it - is CLIPPED on that
   line. The band the bar sits on is therefore bare body colour with no glow,
   and the hero's glow does not fade in, it STARTS, at a hard horizontal edge.
   Measured 2026-08-07 on capital-markets: flat rgb(20,16,9) above the line,
   ramping to rgb(73,52,27) within 22px below it.

   This pulls the section's box up by exactly the header's height so the clip box
   starts at y=0 and the section paints behind the bar, then gives the same amount
   back as padding so NOTHING MOVES - content stays on the same pixel and the page
   height is unchanged. Only what is painted behind the bar changes.

   Opt-in, not baked into .sgx-section: a page whose first section is a plain band
   with no glow does not need it, and a page with an opaque header must not have it.
   Put it on the FIRST section only - on a later one it would slide the page up.

   --sgx-hdr-h is published by chrome.css, which owns the header. */
.sgx-section--under-nav{
  margin-top:calc(-1 * var(--sgx-hdr-h));
  padding-top:calc(var(--pad-y) + var(--sgx-hdr-h));
}

.sgx-wrap{
  max-width:var(--max-width);
  margin:0 auto;
  position:relative;
  z-index:2;
}


/* ═══════════════════════════════════════════════════════════════
   BUTTON  -  SGX-BTN-REG / ENH / SPC / NUDGE
   Base + :active [LIFTED] from showcase .btn
   ═══════════════════════════════════════════════════════════════ */
.sgx-btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:8px;
  font-family:var(--font-display);
  font-weight:600;
  font-size:var(--text-button);
  line-height:1.2;
  letter-spacing:-0.01em;
  padding:14px 22px;
  min-height:44px;              /* touch target - do not shrink */
  border-radius:var(--radius-pill);
  border:1px solid transparent;
  cursor:pointer;
  text-decoration:none;
  position:relative;
  transition:transform 160ms var(--ease-out),
             background 200ms var(--ease-out),
             box-shadow 200ms var(--ease-out),
             border-color 200ms var(--ease-out),
             filter 200ms var(--ease-out);
}
.sgx-btn:active{ transform:scale(0.985); }

/* ── REG - general use  [LIFTED] ── */
.sgx-btn--reg{
  background:var(--brand-fill);
  color:#fff;
}
.sgx-btn--reg:hover{ background:color-mix(in srgb, var(--brand-fill) 86%, #000); }

/* ── REG-GHOST - outline  [LIFTED] ── */
.sgx-btn--ghost{
  background:transparent;
  color:var(--ink-high);
  border-color:var(--hairline);
}
.sgx-btn--ghost:hover{
  color:var(--ink-heading);
  border-color:var(--brand-text);
}

/* ── ENH - primary CTA  [LIFTED traits, CORRECTED values - see header] ── */
.sgx-btn--enh{
  background:linear-gradient(135deg, var(--cta-gradient-from), var(--cta-gradient-to));
  color:var(--cta-text);
  box-shadow:0 10px 26px -12px color-mix(in srgb, var(--cta-gradient-from) 75%, transparent);
}
.sgx-btn--enh:hover{
  filter:brightness(1.07);      /* glow, never transform - so :active scale still reads */
  box-shadow:0 9px 26px -8px color-mix(in srgb, var(--cta-gradient-from) 70%, transparent);
}

/* ── SPC / GLOW - hero tier, pulsing halo  [LIFTED] ── */
.sgx-btn--glow{
  background:color-mix(in srgb, var(--brand-fill) 4%, transparent);
  color:var(--ink-heading);
  border:1px solid color-mix(in srgb, var(--brand-text) 35%, transparent);
  padding:18px 30px;
  font-size:16px;
  overflow:visible;
  isolation:isolate;
}
.sgx-btn--glow::before{
  content:"";
  position:absolute; inset:-2px;
  border-radius:inherit;
  background:radial-gradient(60% 120% at 50% 50%,
             color-mix(in srgb, var(--brand-fill) 45%, transparent), transparent 70%);
  filter:blur(14px);
  z-index:-1;
  animation:sgx-glow-pulse 2.6s ease-in-out infinite;
}
.sgx-btn--glow::after{
  content:"";
  position:absolute; inset:0;
  border-radius:inherit;
  background:linear-gradient(180deg,
             color-mix(in srgb, var(--brand-text) 14%, transparent),
             color-mix(in srgb, var(--brand-text) 3%, transparent));
  z-index:-1;
}
.sgx-btn--glow:hover{
  border-color:color-mix(in srgb, var(--brand-text) 70%, transparent);
  background:color-mix(in srgb, var(--brand-fill) 10%, transparent);
}
/* Stop the pulse once the user has engaged - it has done its job */
.sgx-btn--glow.is-interacted::before{ animation:none; opacity:0; }
.sgx-btn--glow .sgx-arrow{ display:inline-flex; transition:transform 200ms var(--ease-out); }
.sgx-btn--glow:hover .sgx-arrow{ transform:translateX(3px); }

/* ── NUDGE - try-it invitation, breathing ring  [LIFTED] ── */
.sgx-btn--nudge{
  background:var(--surface-section);
  color:var(--ink-heading);
  border:1px solid var(--hairline);
  animation:sgx-nudge-ring 2.2s ease-in-out infinite;
}
.sgx-btn--nudge:hover{
  background:var(--surface-card);
  border-color:color-mix(in srgb, var(--brand-fill) 55%, var(--hairline));
}

/* Aliases - the capital-markets hero uses single-dash names.
   Kept so existing markup does not break. Prefer the -- forms. */
.sgx-btn.btn-enh{
  background:linear-gradient(135deg, var(--cta-gradient-from), var(--cta-gradient-to));
  color:var(--cta-text);
  box-shadow:0 10px 26px -12px color-mix(in srgb, var(--cta-gradient-from) 75%, transparent);
}
.sgx-btn.btn-reg{
  background:transparent;
  color:var(--ink-high);
  border-color:var(--hairline);
}


/* ═══════════════════════════════════════════════════════════════
   PILL  -  SGX-PILL-REG / ENH / SPC
   [LIFTED] from .advantage-pill. SPC reuses this verbatim per the
   showcase's own note. Set --accent per instance to recolour.
   ═══════════════════════════════════════════════════════════════ */
.sgx-pill{
  display:inline-flex;
  align-items:center;
  gap:10px;
  padding:10px 16px;
  border-radius:var(--radius-pill);
  position:relative;
  z-index:1;
  isolation:isolate;
  background:linear-gradient(135deg,
             color-mix(in srgb, var(--accent) 20%, transparent),
             color-mix(in srgb, var(--accent) 6%, transparent));
  box-shadow:0 2px 12px -2px color-mix(in srgb, var(--accent) 32%, transparent);
}
/* Conic sweep around the edge - masked to a 1.5px ring */
.sgx-pill::before{
  content:"";
  position:absolute; inset:-1px;
  border-radius:inherit;
  padding:1.5px;
  --sgx-pill-angle:0deg;
  background:conic-gradient(from var(--sgx-pill-angle),
             color-mix(in srgb, var(--accent) 28%, transparent) 0%,
             color-mix(in srgb, var(--accent) 28%, transparent) 60%,
             color-mix(in srgb, var(--accent) 90%, white) 76%,
             var(--accent) 84%,
             color-mix(in srgb, var(--accent) 28%, transparent) 100%);
  -webkit-mask:linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor;
          mask-composite:exclude;
  animation:sgx-pill-sweep 3.2s linear infinite;
  pointer-events:none;
  z-index:-1;
}
.sgx-pill__icon{ display:inline-flex; }
.sgx-pill__icon svg{ width:16px; height:16px; display:block; color:var(--accent); }
.sgx-pill__text{ font-family:var(--font-display); font-size:14.22px; color:var(--ink-high); }
.sgx-pill__text strong{ color:var(--ink-heading); }


/* ═══════════════════════════════════════════════════════════════
   CARD
   Base [COMPOSED] - the showcase has no .advantage-card base rule
   to lift, so it is built from tokens. Using --panel-* means the
   card follows data-material automatically: solid or glass, no
   second class needed. That is the whole point of the axis.
   Accent line, glow, hover [LIFTED] verbatim.
   ═══════════════════════════════════════════════════════════════ */
.sgx-card{
  position:relative;
  isolation:isolate;
  overflow:hidden;
  padding:var(--space-lg);
  border-radius:var(--radius-card);
  background:var(--panel-bg);
  backdrop-filter:var(--panel-blur);
  -webkit-backdrop-filter:var(--panel-blur);
  border:1px solid color-mix(in srgb, var(--hairline) calc(var(--panel-edge) * 100%), transparent);
  box-shadow:var(--shadow);
  transition:transform 200ms var(--ease-out),
             border-color 200ms var(--ease-out),
             box-shadow 200ms var(--ease-out);
}
/* Top accent hairline  [LIFTED] */
.sgx-card::before{
  content:"";
  position:absolute; top:0; left:12%; right:12%;
  height:1px;
  background:linear-gradient(90deg, transparent,
             color-mix(in srgb, var(--brand-text) 55%, transparent), transparent);
}
/* Upward glow behind the card  [LIFTED] */
.sgx-card::after{
  content:"";
  position:absolute; top:-40%; left:-20%;
  width:140%; height:80%;
  background:radial-gradient(50% 60% at 50% 100%,
             color-mix(in srgb, var(--brand-fill) 18%, transparent), transparent 70%);
  opacity:.55;
  pointer-events:none;
  z-index:-1;
}
/* Hover lift  [LIFTED] */
.sgx-card:hover{
  transform:translateY(-4px);
  border-color:color-mix(in srgb, var(--brand-fill) 40%, transparent);
  box-shadow:0 28px 56px -22px color-mix(in srgb, var(--brand-fill) 40%, transparent);
}

/* Card parts  [LIFTED] */
.sgx-card__icon{
  width:52px; height:52px;
  border-radius:14px;
  display:flex; align-items:center; justify-content:center;
  margin:0 0 28px;
  position:relative; z-index:1;
  color:var(--accent);
  background:linear-gradient(135deg,
             color-mix(in srgb, var(--accent) 28%, transparent),
             color-mix(in srgb, var(--accent) 8%, transparent));
  border:1px solid color-mix(in srgb, var(--accent) 38%, transparent);
}
.sgx-card__icon svg{ width:30px; height:30px; display:block; }

.sgx-card__title{
  font-family:var(--font-display);
  font-weight:600;
  font-size:clamp(20px, 2.2vw, 26px);
  line-height:1.25;
  letter-spacing:-0.018em;
  color:var(--ink-heading);
  margin:0 0 24px;
  position:relative; z-index:1;
}
.sgx-card__divider{
  height:1px;
  margin:0 0 20px;
  position:relative; z-index:1;
  background:linear-gradient(90deg, transparent,
             color-mix(in srgb, var(--brand-text) 45%, transparent), transparent);
}
.sgx-card__body{
  font-family:var(--font-body);
  font-size:var(--text-body);
  line-height:1.65;
  color:var(--ink-body);
  position:relative; z-index:1;
}


/* ═══════════════════════════════════════════════════════════════
   PANEL  [COMPOSED]  - added 2026-08-07
   A raised, interactive SURFACE. Distinct from .sgx-card: a card is a
   self-contained content unit with its own accent line and glow; a panel
   is a container that HOLDS interaction (a run that replays, a chip that
   flips, a button that fires).

   Rule this encodes: ELEVATION ENCODES INTERACTIVITY, NOT IMPORTANCE.
   The capital-markets page had this inverted - blocks that invited a click
   were painted the page's own colour at 85% with no shadow, while static
   hero cards got the lift. A panel therefore sits on --surface-card, takes
   the shadow, and carries a brighter-than-hairline border.
   Note it does NOT set cursor:pointer - a panel is not itself a click
   target; the control inside it is.
   ═══════════════════════════════════════════════════════════════ */
.sgx-panel{
  position:relative;
  padding:var(--space-md);
  border-radius:var(--radius-card);
  background:var(--surface-card);
  border:1px solid color-mix(in srgb, var(--ink-heading) 12%, var(--hairline));
  box-shadow:var(--shadow);
}


/* ═══════════════════════════════════════════════════════════════
   ICON  [COMPOSED]  - added 2026-08-07
   A standalone icon chip. NOT .sgx-card__icon - that one is a card PART
   (52px, accent-filled, 28px bottom margin) and belongs to a card. This
   one is used inside panels, rows and list beats, where a __card parent
   would be a false BEM ancestor.
   Two sizes; stroke colour is the tone axis.
   ═══════════════════════════════════════════════════════════════ */
.sgx-icon{
  flex:0 0 30px;
  width:30px; height:30px;
  border-radius:9px;
  display:inline-flex; align-items:center; justify-content:center;
  background:var(--surface-card);
  border:1px solid var(--hairline);
}
.sgx-icon svg{
  width:17px; height:17px;
  fill:none;
  stroke:var(--ink-body);
  stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round;
}
.sgx-icon--sm{ flex:0 0 22px; width:22px; height:22px; border-radius:7px; }
.sgx-icon--sm svg{ width:13px; height:13px; }
.sgx-icon--warn svg{ stroke:var(--cta-gradient-from); }
.sgx-icon--who { color:var(--brand-text); }
.sgx-icon--who svg{ stroke:var(--brand-text); }


/* ═══════════════════════════════════════════════════════════════
   LABEL  [COMPOSED]  - added 2026-08-07
   Bare mono uppercase micro-copy: lane tags, band labels, unit lines,
   roster captions, document heads. NOT a pill - it has no border, no
   radius and no padding, so folding it into .sgx-pill would have been a
   naming lie. This is the .14em cluster that a tracking audit of the
   capital-markets page found repeated across seven separate classes.
   ═══════════════════════════════════════════════════════════════ */
.sgx-label{
  font-family:var(--font-mono);
  font-size:var(--text-mono);
  letter-spacing:var(--tracking-caps);
  text-transform:uppercase;
  color:var(--ink-body);
}
.sgx-label--brand  { color:var(--brand-text); }
.sgx-label--subtle { color:var(--ink-subtle); }
.sgx-label--sm     { letter-spacing:var(--tracking-caps-sm); }
.sgx-label--centred{ text-align:center; }


/* ═══════════════════════════════════════════════════════════════
   SQC - STATUS-QUO COST CARD   [LIFTED from SGX-SQC]  - added 2026-08-07
   A DIFFERENT showcase component from .sgx-card above (which is the
   .advantage-card lift). Both are cards; neither is the other. SQC states a
   cost the reader is paying today: 3px top gradient strip, hover lift with a
   coloured glow, one gradient-clipped emphasis line, and a door-foot that
   resolves it.

   The strip colour is the SEMANTIC axis, per the success register:
   amber = cost / brand attention, green = gained outcome.
   ═══════════════════════════════════════════════════════════════ */
.sgx-sqc{
  position:relative;
  overflow:hidden;
  contain:paint;
  /* Ram, twice: "even more padding needed here - inside the cards". Sides and
     bottom move --space-md -> --space-lg (20->32 desktop). The top keeps its +6
     lift over the side value so the icon still sits off the edge. Deliberately
     NOT a new token - --space-lg is already ratified and already the paragraph
     step, so the card's inner rhythm now matches the page's. */
  padding:calc(var(--space-lg) + 6px) var(--space-lg) var(--space-lg);
  border-radius:14px;
  background:var(--panel-bg);
  backdrop-filter:var(--panel-blur);
  -webkit-backdrop-filter:var(--panel-blur);
  border:1px solid var(--hairline);
  box-shadow:var(--shadow);
  will-change:transform;
  /* OPACITY IS LISTED HERE ON PURPOSE  -  added 2026-08-08.
     `.rv` (the page's scroll-reveal utility) and `.sgx-sqc` are BOTH (0,1,0), and
     primitives loads last, so this rule won the tie and `.rv`'s opacity transition
     never reached these six cards. Measured result: the card's opacity FLIPPED
     instantly while everything else on the page faded over --dur-slow.
     Fixing it here rather than by out-specifying `.rv` on the page, because the
     collision is the component's fault, not the utility's.
     Opacity gets --dur-slow (it only ever changes on reveal); transform keeps
     --dur-micro so the HOVER lift stays snappy. Verified: no hover, :active or
     .is-demo rule touches opacity, so this cannot affect any interaction state. */
  transition:opacity var(--dur-slow) var(--ease-in-out),
             transform var(--dur-micro) var(--ease-out),
             box-shadow var(--dur-micro) var(--ease-out),
             border-color var(--dur-micro) var(--ease-out);
}
.sgx-sqc::before{
  content:"";
  position:absolute; inset:0 0 auto 0;
  height:3px;
  opacity:.9;
}
.sgx-sqc:hover{
  transform:translateY(-4px);
  border-color:color-mix(in srgb, var(--ink-heading) 14%, transparent);
  box-shadow:0 20px 48px -20px rgba(0,0,0,.6);
}
.sgx-sqc--problem::before{ background:linear-gradient(90deg, var(--cta-gradient-from), var(--cta-gradient-to)); }
.sgx-sqc--problem:hover, .sgx-sqc--problem.is-demo { box-shadow:0 20px 48px -20px rgba(0,0,0,.6), 0 0 80px -30px var(--cta-gradient-from); }
.sgx-sqc--outcome::before{ background:linear-gradient(90deg, var(--signal-ok-bright), var(--signal-ok)); }
.sgx-sqc--outcome:hover, .sgx-sqc--outcome.is-demo { box-shadow:0 20px 48px -20px rgba(0,0,0,.6), 0 0 80px -30px var(--signal-ok); }

/* FTUX - the card shows the visitor what it does, once, without being touched.
   Ram: play the hover state about 2s after load, "All three cards in sequence."
   Same declarations as :hover so there is exactly one definition of the state -
   a second copy would drift the moment the hover is retuned. Transform and
   box-shadow only, per the motion rule; nothing that triggers layout. */
.sgx-sqc.is-demo{
  transform:translateY(-4px);
  border-color:color-mix(in srgb, var(--ink-heading) 14%, transparent);
  box-shadow:0 20px 48px -20px rgba(0,0,0,.6);
}

.sgx-sqc__icon{
  width:38px; height:38px;
  border-radius:10px;
  display:grid; place-items:center;
  background:var(--well-bg);
  border:1px solid var(--hairline);
}
/* A DEFAULT stroke is required, not optional. A page may override it with an
   SVG paint-server (the capital-markets page strokes these with a brand
   gradient via stroke:url(#dg)), but without a default here an icon on a page
   that defines no gradient renders as an empty box - fill:none + stroke:none
   is invisible. */
.sgx-sqc__icon svg{ width:20px; height:20px; fill:none; stroke:var(--brand-text);
                    stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }
/* The emphasis line. Its gradient END STOP is --cta-gradient-to LIGHTENED 35%
   toward --cta-gradient-from: the pure stop measured 3.94:1 against card glass
   over the bloom peak, and 18px bold needs 4.5. The mixed stop measures ~4.8:1.
   Do not revert it to a plain var(--cta-gradient-to). */
.sgx-sqc__emph{
  font-family:var(--font-display);
  font-weight:var(--weight-bold);
  font-size:18px;
  line-height:1.3;
  letter-spacing:var(--tracking-tight);
  color:var(--brand-text);
  margin:2px 0 0;
}
@supports (background-clip:text) or (-webkit-background-clip:text){
  .sgx-sqc__emph{
    background:linear-gradient(135deg, var(--cta-gradient-from),
               color-mix(in srgb, var(--cta-gradient-to) 65%, var(--cta-gradient-from)));
    -webkit-background-clip:text; background-clip:text;
    -webkit-text-fill-color:transparent; color:transparent;
  }
}
/* Door foot. The anchor stretches over the whole card via ::after, so the card
   is one click target with one accessible name - which is also why the card is
   interactive and therefore correctly elevated. */
.sgx-sqc__foot{ margin-top:auto; padding-top:14px; border-top:1px solid var(--hairline); }
.sgx-sqc__foot a{
  display:inline-flex; align-items:center; gap:8px;
  font-family:var(--font-display);
  font-weight:var(--weight-semibold);
  font-size:var(--text-small);
  color:var(--ink-heading);
  text-decoration:none;
}
.sgx-sqc__foot a::after{ content:""; position:absolute; inset:0; }
.sgx-sqc__foot a:focus-visible{ outline:none; }
.sgx-sqc:has(.sgx-sqc__foot a:focus-visible){ outline:2px solid var(--accent-bright); outline-offset:3px; }
.sgx-sqc:active{ transform:translateY(-2px) scale(.99); }

.sgx-sqc__figure{
  font-family:var(--font-display);
  font-weight:var(--weight-bold);
  font-size:46.19px;
  line-height:1;
  letter-spacing:var(--tracking-display);
  color:var(--signal-ok);
  font-variant-numeric:tabular-nums;
}
@supports (background-clip:text) or (-webkit-background-clip:text){
  .sgx-sqc__figure{
    background:linear-gradient(135deg, var(--signal-ok-bright), var(--signal-ok));
    -webkit-background-clip:text; background-clip:text;
    -webkit-text-fill-color:transparent; color:transparent;
  }
}
/* the unit line under a figure - compose with .sgx-label */
.sgx-sqc__unit{ margin:12px 0 0; }


/* ═══════════════════════════════════════════════════════════════
   TAG  [COMPOSED]  - added 2026-08-07
   A bare bordered chip. NOT .sgx-pill above - that one is the animated
   conic-sweep advantage pill with __icon/__text children and an --accent
   gradient fill. This is data chrome: a border, a pill radius, small type.
   Two different components; folding them would have been a naming lie.
   ═══════════════════════════════════════════════════════════════ */
.sgx-tag{
  display:inline-flex;
  align-items:center;
  border:1px solid var(--hairline);
  border-radius:var(--radius-pill);
}
.sgx-tag--chip { font-family:var(--font-mono); font-size:var(--text-small);
                 color:var(--ink-heading); background:var(--surface-card); padding:7px 14px; }
.sgx-tag--ask  { color:var(--ink-high); border-style:dashed; }
.sgx-tag--data { font-family:var(--font-mono); font-size:14.22px;
                 letter-spacing:var(--tracking-micro); padding:2px 9px;
                 font-weight:var(--weight-regular); color:var(--ink-body); }
.sgx-tag--data-sm{ font-family:var(--font-mono); font-size:14.22px;
                 letter-spacing:var(--tracking-micro); padding:2px 8px;
                 font-weight:var(--weight-regular); color:var(--ink-body); }
.sgx-tag--ruled{ font-family:var(--font-mono); font-size:14.22px;
                 letter-spacing:var(--tracking-micro); padding:2px 9px;
                 color:var(--signal-ok);
                 border-color:color-mix(in srgb, var(--signal-ok) 45%, transparent); }
.sgx-tag--ghost{ font-size:14.22px; color:var(--ink-body); border-style:dashed; padding:2px 10px; }
.sgx-tag--dest { gap:7px; font-size:14.22px; font-weight:var(--weight-medium);
                 letter-spacing:var(--tracking-micro); padding:3px 12px;
                 color:var(--cta-gradient-from);
                 border-color:color-mix(in srgb, var(--cta-gradient-from) 40%, transparent); }
.sgx-tag--dest svg{ width:13px; height:13px; fill:none; stroke:currentColor;
                    stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }
/* WRAPPING GEOMETRY  -  added 2026-08-08 with the larger type scale.
   At 12.64px mono these statement tags run ~37 characters and cannot fit one
   line on a 334px card, so they wrap - and a pill radius on a two-line box
   renders as a stretched stadium. A 10px radius reads as a deliberate block at
   two lines and still reads fine at one. Mobile only: measured, they do not
   wrap above 640px, so the pill stays a pill everywhere it still works. */
@media (max-width:639px){
  .sgx-tag--data,.sgx-tag--data-sm,.sgx-tag--ruled{
    align-items:flex-start; border-radius:10px; padding:6px 10px; line-height:1.5;
  }
}

/* success recolour, composable with any tag variant */
.sgx-tag.is-ok{ color:var(--signal-ok);
                border-color:color-mix(in srgb, var(--signal-ok) 40%, transparent); }


/* ═══════════════════════════════════════════════════════════════
   KEYFRAMES  [LIFTED] - values verbatim from the showcase
   ═══════════════════════════════════════════════════════════════ */
@keyframes sgx-glow-pulse{
  0%,100%{ opacity:.55; transform:scale(1); }
  50%    { opacity:1;   transform:scale(1.04); }
}
@keyframes sgx-nudge-ring{
  0%,100%{ box-shadow:0 0 0 0 color-mix(in srgb, var(--brand-fill) 0%, transparent); }
  50%    { box-shadow:0 0 0 4px color-mix(in srgb, var(--brand-fill) 30%, transparent); }
}
@property --sgx-pill-angle{ syntax:'<angle>'; initial-value:0deg; inherits:false; }
@keyframes sgx-pill-sweep{
  from{ --sgx-pill-angle:0deg; }
  to  { --sgx-pill-angle:360deg; }
}


/* ═══════════════════════════════════════════════════════════════
   MOTION SAFETY  [COMPOSED]
   The showcase kills these animations in its own print/static
   context. Same intent, driven by the user's stated preference.
   ═══════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion:reduce){
  .sgx-btn,
  .sgx-btn--glow::before,
  .sgx-btn--nudge,
  .sgx-pill::before,
  .sgx-card{
    animation:none !important;
    transition:none !important;
  }
  .sgx-card:hover{ transform:none; }
}

/* MOBILE STEP-DOWN FOR THE SMALLEST CHROME  -  ratified 2026-08-08.
   Ram set two floors: 14px at >=900px, 12px below. These are the roles that take
   the lower one - data chips, doc names, flow captions, micro-labels. The step is
   12.64px, one scale stop under 14.22, so nothing lands ON 12.
   Restated here because the collapse rewrote declarations in place and there was
   no mobile rule to rewrite: without this block they inherit 14.22 everywhere,
   which is larger than what was reviewed and leaves mobile chrome split across
   two sizes for one role. */
@media (max-width:639px){
  .sgx-tag--data,
  .sgx-tag--data-sm,
  .sgx-tag--ruled,
  .sgx-tag--ghost{font-size:12.64px}
}
