/* =============================================================================
   guide-system.css  ·  THE PUBLIC DOCUMENT COMPONENT LAYER        (2026-08-07)
   =============================================================================
   WHAT THIS IS
   -----------------------------------------------------------------------------
   The shared component vocabulary behind /guides, its three sub-pages and
   /how-to-access. Prefix `gs-`. It exists because guides.css (1,341 lines) and
   how-to-access.css (1,112 lines) were two copies of the same design: after
   normalising the `gd-` / `hta-` prefixes, 50 rule blocks were BYTE-IDENTICAL,
   occupying 371 lines in one file and 375 in the other, with a further 17
   selectors present in both and differing only by a value or two. Two copies of
   one design is two places for it to rot, and it already had: the two files'
   `--*-text-3` both carry rgba(255,255,255,.45), which measures 4.48:1 on
   #070a1c — the exact value site-tokens.css raised to .46 for exactly this
   reason (see its W5.2 note), re-introduced from scratch by files that stopped
   reading the contract.

   (The brief for this work said the overlap was 887 identical lines. Measured,
   it is ~371/375. The claim overstates it; the duplication is still the whole
   design and still worth collapsing.)

   WHAT IT IS NOT
   -----------------------------------------------------------------------------
   Not a page. Page-specific layout stays in guides.css (the 3-up guides grid)
   and how-to-access.css (the two-path layout with its OR divider, the features
   row, the notes card, the hero icon cluster). If a rule is used by exactly one
   page, it does not belong here.

   COLOUR
   -----------------------------------------------------------------------------
   Every colour in this file comes from THE SEMANTIC COLOUR SYSTEM block in
   site-tokens.css. There are no pigments below this docblock — not one hex that
   is a hue. The five semantic roles are surfaced here as ONE modifier family,
   `.gs-lv--*`, which sets a `--lvl-*` group that every component reads:

     .gs-lv--entry     ladder 1 · arriving        · cyan
     .gs-lv--build     ladder 2 · working         · violet
     .gs-lv--master    ladder 3 · mastered / ok   · mint
     .gs-lv--caution   interrupt · read first     · amber
     .gs-lv--halt      interrupt · this failed    · rose

   So a card, a sub-page hero, a chip and a callout all take their colour from
   the same one class, and a level can never be half-applied.

   THE SECOND CHANNEL IS STRUCTURAL, NOT OPTIONAL
   -----------------------------------------------------------------------------
   Hue alone fails WCAG 1.4.1. Three non-colour channels are built into the
   components themselves so a call site cannot drop them:

     · .gs-pips   the ladder is ORDERED and hue cannot express order. One / two
                  / three filled discs against hollow rings. Countable, and a
                  disc-vs-ring difference is pure shape.
     · glyph+word every .gs-chip carries an icon and a literal label; the
                  interrupt glyphs are shape-distinct (triangle, x-circle) from
                  the ladder's round ones.
     · rule weight ladder accents render at --sem-rule-ladder (3px), interrupts
                  at --sem-rule-interrupt (5px), and interrupt chips take a 2px
                  border where ladder chips take 1px.

   NO backdrop-filter on any card in this file. The old `.gd-card` /
   `.hta-card` / `.gd-content__card` / `.hta-notes__card` each carried
   `backdrop-filter: blur(12-20px)`; they now sit on the contract's --sf-*
   scale, which is translucent by design and needs no blur to avoid punching a
   rectangle through the section gradient behind it.

   NO `!important` anywhere in this file, including the reduced-motion block —
   it is the last thing in the file and its selectors match the specificity of
   what they override, so source order is enough. The old files needed
   `animation: none !important` only because their reduced-motion rules were
   interleaved with the rules they were fighting.
   ============================================================================= */

/* ─────────────────────────────────────────────────────────────────────────────
   0 · LOCAL SHAPE TOKENS
   The radii and easing this page family uses. Deliberately NOT reusing the
   contract's --r-* here: this surface is drawn at a softer radius (28px cards)
   than the landing's 16px maximum, and quietly repointing it would change the
   look of every card on the four pages. Named locally so the difference is a
   decision on the record rather than a drift.
   ───────────────────────────────────────────────────────────────────────────── */
:root {
    --gs-r-xl:   28px;
    --gs-r-lg:   20px;
    --gs-r-md:   14px;
    --gs-r-sm:   10px;
    --gs-r-pill: 999px;
    --gs-ease:   cubic-bezier(0.22, 1, 0.36, 1);
    --gs-dur:      .4s;
    --gs-dur-slow: .6s;

    /* Text ladder for this surface. Reads the CONTRACT's ink scale instead of
       the private .7/.45 pair the two old files each carried; --ink-4 is .46,
       which is the smallest step that clears 4.5:1 on #070a1c (4.66:1). The
       old .45 measured 4.48:1 and failed. */
    --gs-ink-1: var(--ink-1);
    --gs-ink-2: var(--ink-2);
    --gs-ink-3: var(--ink-3);
    --gs-ink-4: var(--ink-4);

    /* THE DEFAULT LEVEL lives at :root, not on the components, and that is
       load-bearing. Custom properties INHERIT, so a default declared here is
       beaten by a .gs-lv--* on any ancestor — which is how a sub-page sets its
       whole level with one class on <body> — and by a .gs-lv--* on the element
       itself, which is how one callout inside that page can still be a caution.
       Declaring the same defaults on `.gs-card` etc. instead would have made
       every component immune to its own page's level, because a direct
       declaration always beats an inherited one however far up it sits. */
    --lvl:        var(--sem-entry);
    --lvl-2:      var(--sem-entry-2);
    --lvl-wash:   var(--sem-entry-wash);
    --lvl-line:   var(--sem-entry-line);
    --lvl-edge:   var(--sem-entry-edge);
    --lvl-glow:   var(--sem-entry-glow);
    --lvl-grad:   var(--grad-entry);
    --lvl-rule:   var(--sem-rule-ladder);
    --lvl-chip-border: 1px;
}

/* ─────────────────────────────────────────────────────────────────────────────
   1 · THE LEVEL MODIFIER  ·  the whole palette, expressed as five classes
   Every component below reads --lvl-*. Nothing reads --sem-* directly, so
   re-pointing a level is a five-line change here.
   ───────────────────────────────────────────────────────────────────────────── */
.gs-lv--entry {
    --lvl:        var(--sem-entry);
    --lvl-2:      var(--sem-entry-2);
    --lvl-wash:   var(--sem-entry-wash);
    --lvl-line:   var(--sem-entry-line);
    --lvl-edge:   var(--sem-entry-edge);
    --lvl-glow:   var(--sem-entry-glow);
    --lvl-grad:   var(--grad-entry);
    --lvl-rule:   var(--sem-rule-ladder);
    --lvl-chip-border: 1px;
}

.gs-lv--build {
    --lvl:        var(--sem-build);
    --lvl-2:      var(--sem-build-2);
    --lvl-wash:   var(--sem-build-wash);
    --lvl-line:   var(--sem-build-line);
    --lvl-edge:   var(--sem-build-edge);
    --lvl-glow:   var(--sem-build-glow);
    --lvl-grad:   var(--grad-build);
    --lvl-rule:   var(--sem-rule-ladder);
    --lvl-chip-border: 1px;
}

.gs-lv--master {
    --lvl:        var(--sem-master);
    --lvl-2:      var(--sem-master-2);
    --lvl-wash:   var(--sem-master-wash);
    --lvl-line:   var(--sem-master-line);
    --lvl-edge:   var(--sem-master-edge);
    --lvl-glow:   var(--sem-master-glow);
    --lvl-grad:   var(--grad-master);
    --lvl-rule:   var(--sem-rule-ladder);
    --lvl-chip-border: 1px;
}

/* The two interrupts take the HEAVIER rule and a doubled chip border. That is
   the non-colour half of "this is not a step on the path, this is a stop". */
.gs-lv--caution {
    --lvl:        var(--sem-caution);
    --lvl-2:      var(--sem-caution-2);
    --lvl-wash:   var(--sem-caution-wash);
    --lvl-line:   var(--sem-caution-line);
    --lvl-edge:   var(--sem-caution-edge);
    --lvl-glow:   var(--sem-caution-glow);
    --lvl-grad:   var(--grad-caution);
    --lvl-rule:   var(--sem-rule-interrupt);
    --lvl-chip-border: 2px;
}

.gs-lv--halt {
    --lvl:        var(--sem-halt);
    --lvl-2:      var(--sem-halt-2);
    --lvl-wash:   var(--sem-halt-wash);
    --lvl-line:   var(--sem-halt-line);
    --lvl-edge:   var(--sem-halt-edge);
    --lvl-glow:   var(--sem-halt-glow);
    --lvl-grad:   var(--grad-halt);
    --lvl-rule:   var(--sem-rule-interrupt);
    --lvl-chip-border: 2px;
}

/* ─────────────────────────────────────────────────────────────────────────────
   2 · CHIP  ·  the legend for the whole system
   Never colour alone: glyph + word + (on the ladder) a pip count.
   ───────────────────────────────────────────────────────────────────────────── */
.gs-chip {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .34rem .9rem;
    font-size: var(--type-m2);
    font-weight: 700;
    letter-spacing: var(--track-data);
    text-transform: uppercase;
    color: var(--lvl);
    background: var(--lvl-wash);
    border: var(--lvl-chip-border) solid var(--lvl-edge);
    border-radius: var(--gs-r-pill);
}

.gs-chip i { font-size: .72em; }

/* PIPS — the ordered channel. One filled disc per rung reached, hollow rings
   for the rungs above it. Shape, not hue: a filled disc next to a ring is
   unambiguous in greyscale, at 1-bit, and to every kind of colour blindness. */
.gs-pips {
    display: inline-flex;
    align-items: center;
    gap: var(--sem-pip-gap);
    margin-left: .15rem;
}

.gs-pip {
    width: var(--sem-pip);
    height: var(--sem-pip);
    border-radius: var(--r-full);
    border: 1.5px solid var(--lvl-edge);
    background: transparent;
    flex-shrink: 0;
}

.gs-pip--on {
    background: var(--lvl);
    border-color: var(--lvl);
}

/* ─────────────────────────────────────────────────────────────────────────────
   3 · BUTTONS
   Primary is a saturated FILL carrying --sem-ink-on-fill; glass is an OUTLINE
   carrying light ink. That inversion is itself a second channel: which of the
   two is the primary action survives greyscale as a light-block vs dark-block
   difference, independent of hue.
   ───────────────────────────────────────────────────────────────────────────── */
.gs-btn {
    display: inline-flex;
    align-items: center;
    gap: .55rem;
    padding: .9rem 2rem;
    font-size: var(--type-u5);
    font-weight: 600;
    border-radius: var(--gs-r-md);
    text-decoration: none;
    border: none;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition:
        transform var(--gs-dur) var(--gs-ease),
        box-shadow var(--gs-dur) var(--gs-ease),
        background var(--gs-dur) var(--gs-ease),
        border-color var(--gs-dur) var(--gs-ease);
}

.gs-btn--primary {
    /* --sem-ink-on-fill measures 13.67:1 on the near stop and 8.85:1 on the far
       stop of --grad-entry. The value this replaces put #0a1220 on a #7b5cff
       far stop at 4.30:1, i.e. below the 4.5:1 floor for a 14px button label. */
    color: var(--sem-ink-on-fill);
    background: var(--grad-entry);
    box-shadow: 0 5px 20px var(--sem-entry-glow);
}

.gs-btn--primary::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,.2), transparent);
    transform: translateX(-100%);
    transition: transform var(--gs-dur-slow) var(--gs-ease);
}

.gs-btn--primary:hover {
    transform: translateY(-3px) scale(1.02);
    box-shadow: 0 15px 40px var(--sem-entry-glow);
    color: var(--sem-ink-on-fill);
    text-decoration: none;
}

.gs-btn--primary:hover::after { transform: translateX(100%); }

.gs-btn--glass {
    color: var(--ink-1);
    background: var(--sf-2);
    border: 1px solid var(--sem-entry-edge);   /* 3.09:1 — this border IS the
                                                  component's only boundary */
}

.gs-btn--glass:hover {
    border-color: var(--sem-entry);
    background: var(--sf-3);
    transform: translateY(-3px);
    box-shadow: 0 10px 30px var(--sem-entry-glow);
    color: var(--ink-1);
    text-decoration: none;
}

.gs-btn--sm {
    padding: .7rem 1.5rem;
    font-size: var(--type-u5);
    border-radius: var(--gs-r-sm);
}

/* ─────────────────────────────────────────────────────────────────────────────
   4 · AMBIENT DECORATION  ·  orbs, mesh, grid
   Decorative only. Never carries meaning, so it is exempt from the
   second-channel rule and from any contrast floor. aria-hidden at the call site.
   ───────────────────────────────────────────────────────────────────────────── */
.gs-page-orb {
    position: fixed;
    border-radius: var(--r-full);
    pointer-events: none;
    z-index: 0;
    filter: blur(80px);
    opacity: .18;
}

.gs-page-orb--1 {
    width: 320px;
    height: 320px;
    top: 22%;
    left: -8%;
    background: radial-gradient(circle, var(--sem-build-glow) 0%, transparent 70%);
    animation: gsOrb1 22s ease-in-out infinite;
}

.gs-page-orb--2 {
    width: 260px;
    height: 260px;
    top: 55%;
    right: -5%;
    background: radial-gradient(circle, var(--sem-entry-glow) 0%, transparent 70%);
    animation: gsOrb2 28s ease-in-out infinite;
}

@keyframes gsOrb1 {
    0%, 100% { transform: translate(0, 0); }
    33%      { transform: translate(25px, -35px); }
    66%      { transform: translate(-20px, 20px); }
}

@keyframes gsOrb2 {
    0%, 100% { transform: translate(0, 0); }
    50%      { transform: translate(-30px, 20px); }
}

.gs-mesh {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
}

.gs-mesh__orb {
    position: absolute;
    border-radius: var(--r-full);
    filter: blur(100px);
    will-change: transform;
}

/* The three mesh orbs walk the LADDER in order: build behind the top-left,
   entry behind the bottom-right, build again small and central. The atmosphere
   is the same palette as the content, not a separate decorative one. */
.gs-mesh__orb--1 {
    width: 700px;
    height: 700px;
    top: -30%;
    left: -15%;
    background: radial-gradient(circle, var(--sem-build-glow) 0%, transparent 70%);
    animation: gsMesh1 16s ease-in-out infinite alternate;
}

.gs-mesh__orb--2 {
    width: 550px;
    height: 550px;
    bottom: -20%;
    right: -10%;
    background: radial-gradient(circle, var(--sem-entry-glow) 0%, transparent 70%);
    animation: gsMesh2 20s ease-in-out infinite alternate;
}

.gs-mesh__orb--3 {
    width: 400px;
    height: 400px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: radial-gradient(circle, var(--sem-master-glow) 0%, transparent 70%);
    animation: gsMesh3 14s ease-in-out infinite alternate;
}

@keyframes gsMesh1 {
    0%   { transform: translate(0, 0) scale(1);       opacity: .5; }
    50%  { transform: translate(40px, -30px) scale(1.15); opacity: .35; }
    100% { transform: translate(-30px, 20px) scale(.9);   opacity: .5; }
}

@keyframes gsMesh2 {
    0%   { transform: translate(0, 0) scale(1);        opacity: .4; }
    50%  { transform: translate(-35px, 25px) scale(1.1); opacity: .3; }
    100% { transform: translate(25px, -20px) scale(.95); opacity: .45; }
}

@keyframes gsMesh3 {
    0%   { transform: translate(-50%, -50%) scale(1);   opacity: .22; }
    100% { transform: translate(-45%, -55%) scale(1.2); opacity: .12; }
}

.gs-grid-veil {
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(var(--sem-entry-wash) 1px, transparent 1px),
        linear-gradient(90deg, var(--sem-entry-wash) 1px, transparent 1px);
    background-size: 60px 60px;
    mask-image: radial-gradient(ellipse 70% 60% at 50% 40%, black 30%, transparent 80%);
    -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 40%, black 30%, transparent 80%);
    opacity: .3;
    pointer-events: none;
    z-index: 0;
}

/* ─────────────────────────────────────────────────────────────────────────────
   5 · HERO  ·  full page hero (guides hub, how-to-access)
   ───────────────────────────────────────────────────────────────────────────── */
.gs-hero {
    position: relative;
    padding: clamp(7rem, 14vh, 12rem) 0 clamp(4rem, 8vh, 6rem);
    text-align: center;
    overflow: hidden;
}

.gs-hero__inner {
    position: relative;
    z-index: 1;
    max-width: 820px;
    margin: 0 auto;
    padding: 0 1.5rem;
}

.gs-hero__icon {
    width: 72px;
    height: 72px;
    margin: 0 auto 2rem;
    border-radius: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.75rem;
    color: var(--ink-1);
    background: linear-gradient(135deg, var(--sem-entry-wash) 0%, var(--sem-build-wash) 100%);
    border: 1px solid var(--sem-entry-edge);
    box-shadow: 0 8px 32px var(--sem-entry-glow);
    transition: transform var(--gs-dur) var(--gs-ease);
}

.gs-hero__icon:hover { transform: translateY(-4px) scale(1.08); }

.gs-hero__title {
    font-family: var(--font-display);
    font-size: clamp(2.4rem, 5.5vw, 3.8rem);
    font-weight: 800;
    line-height: var(--lh-display);
    letter-spacing: var(--track-display);
    margin-bottom: 1.25rem;
    color: var(--ink-1);
}

/* The wordmark gradient runs the ladder end to end: entry -> build. It is
   DISPLAY text at 38-61px, so the 3:1 large-text floor applies, and the
   darkest stop (--sem-build, #b388ff) measures 7.37:1 on #070a1c. The value
   this replaces ended at #764ba2, which is 3.08:1 — legal for display, and the
   reason the old file could never reuse that stop anywhere smaller. */
.gs-hero__title span,
.gs-gradient {
    background: linear-gradient(135deg, var(--sem-entry) 0%, var(--sem-build) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

.gs-hero__subtitle {
    font-size: var(--type-u3);
    line-height: var(--lh-read);
    color: var(--gs-ink-2);
    max-width: 640px;
    margin: 0 auto 2.5rem;
}

.gs-hero__ctas {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    flex-wrap: wrap;
}

/* ─────────────────────────────────────────────────────────────────────────────
   6 · SUB-PAGE HERO  ·  compact, and LEVEL-COLOURED
   This is where the ladder first pays for itself: the sub-page hero of the
   Beginner guide is entry-cyan, Intermediate is build-violet, Advanced is
   master-mint, and the chip under it carries the matching pip count. A reader
   who lands on /guides/workspace from search knows which rung they are on
   before reading a word.
   ───────────────────────────────────────────────────────────────────────────── */
.gs-subhero {
    position: relative;
    padding: clamp(6rem, 12vh, 9rem) 0 clamp(3rem, 6vh, 4.5rem);
    text-align: center;
    overflow: hidden;
}

.gs-subhero__inner {
    position: relative;
    z-index: 1;
    max-width: 780px;
    margin: 0 auto;
    padding: 0 1.5rem;
}

.gs-subhero__back {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    font-size: var(--type-u5);
    font-weight: 500;
    color: var(--gs-ink-3);
    text-decoration: none;
    margin-bottom: 2rem;
    transition: color var(--gs-dur) var(--gs-ease);
}

.gs-subhero__back:hover {
    color: var(--lvl);
    text-decoration: none;
}

.gs-subhero__icon {
    width: 60px;
    height: 60px;
    margin: 0 auto 1.5rem;
    border-radius: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    color: var(--sem-ink-on-fill);
    background: var(--lvl-grad);
    box-shadow: 0 6px 24px var(--lvl-glow);
}

.gs-subhero__title {
    font-family: var(--font-display);
    font-size: clamp(2rem, 4.5vw, 3rem);
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: var(--track-display);
    margin: 1.25rem 0 1rem;
    color: var(--ink-1);
}

/* On a sub-page the headline gradient runs THAT page's level, not the generic
   entry -> build. It is the same signal as the icon and the chip, a third time. */
.gs-subhero__title span {
    background: linear-gradient(135deg, var(--lvl) 0%, var(--lvl-2) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

.gs-subhero__subtitle {
    font-size: var(--type-u3);
    line-height: var(--lh-read);
    color: var(--gs-ink-2);
    max-width: 560px;
    margin: 0 auto;
}

/* ─────────────────────────────────────────────────────────────────────────────
   7 · SECTION HEADER
   ───────────────────────────────────────────────────────────────────────────── */
.gs-section-header {
    text-align: center;
    margin-bottom: 3.5rem;
}

.gs-section-title {
    font-family: var(--font-display);
    font-size: clamp(1.9rem, 4vw, 2.6rem);
    font-weight: 700;
    color: var(--ink-1);
    margin: 1.25rem 0 .75rem;
    letter-spacing: var(--track-tight);
}

.gs-section-subtitle {
    font-size: var(--type-u3);
    color: var(--gs-ink-2);
    max-width: 560px;
    margin: 0 auto;
    line-height: var(--lh-read);
}

/* The rule under a section header runs the full ladder, left to right. It is
   the page's legend in miniature: three colours in a fixed order. */
.gs-section-line {
    width: 96px;
    height: var(--sem-rule-ladder);
    margin: 2rem auto 0;
    background: linear-gradient(90deg,
        var(--sem-entry) 0%, var(--sem-build) 50%, var(--sem-master) 100%);
    border-radius: var(--r-xs);
    opacity: .75;
}

/* ─────────────────────────────────────────────────────────────────────────────
   8 · CARD
   ───────────────────────────────────────────────────────────────────────────── */
.gs-card {
    position: relative;
    background: var(--sf-1);
    border: 1px solid var(--line-1);
    border-radius: var(--gs-r-xl);
    padding: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    transition:
        transform var(--gs-dur) var(--gs-ease),
        border-color var(--gs-dur) var(--gs-ease),
        box-shadow var(--gs-dur) var(--gs-ease),
        background var(--gs-dur) var(--gs-ease);
}

/* The level rule. ALWAYS visible, not hover-only: it is the card's level
   signal, and a signal you have to hover to see is not a signal. (The old
   .gd-card::before sat at opacity 0 until hover, which meant the whole accent
   system was invisible on touch devices.) */
.gs-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: var(--lvl-rule);
    background: var(--lvl-grad);
    z-index: 3;
}

.gs-card__glow {
    position: absolute;
    inset: 0;
    background: radial-gradient(600px circle at var(--mx, 50%) var(--my, 50%),
                                var(--lvl-wash), transparent 50%);
    opacity: 0;
    transition: opacity var(--gs-dur-slow) ease;
    pointer-events: none;
    z-index: 0;
}

@media (hover: hover) and (pointer: fine) {
    .gs-card:hover {
        transform: translateY(-8px);
        border-color: var(--lvl-edge);
        box-shadow: 0 30px 60px rgba(0, 0, 0, .35), 0 0 60px var(--lvl-glow);
        background: var(--sf-2);
    }

    .gs-card:hover .gs-card__glow { opacity: 1; }

    .gs-card:hover .gs-card__icon {
        transform: scale(1.08) rotate(-3deg);
        box-shadow: 0 12px 32px var(--lvl-glow);
    }

    .gs-card:hover .gs-card__cta {
        box-shadow: 0 8px 24px var(--lvl-glow);
    }
}

.gs-card__head {
    position: relative;
    z-index: 1;
    padding: 2rem 2rem 0;
}

.gs-card__icon {
    width: 56px;
    height: 56px;
    border-radius: var(--gs-r-md);
    background: var(--lvl-grad);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem;
    color: var(--sem-ink-on-fill);
    margin: 1.1rem 0;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .3);
    transition: transform var(--gs-dur) var(--gs-ease), box-shadow var(--gs-dur) var(--gs-ease);
}

/* --type-u2 (18>21px), not --type-u1 (24>32px): u1 is the contract's
   FEATURE-card title and it wraps "Workspace Guide" onto two lines in a
   three-up grid at 1440, which knocks the three cards' bullet lists out of
   alignment with each other. u2 is the contract's card-title step and is what
   this component actually is. */
.gs-card__name {
    font-size: var(--type-u2);
    font-weight: 700;
    color: var(--gs-ink-1);
    margin: 0 0 .5rem;
    letter-spacing: var(--track-tight);
}

.gs-card__desc {
    font-size: var(--type-u5);
    line-height: var(--lh-snug);
    color: var(--gs-ink-2);
    margin: 0;
}

.gs-card__body {
    position: relative;
    z-index: 1;
    padding: 1.75rem 2rem 2rem;
    margin-top: auto;
}

.gs-card__highlights {
    list-style: none;
    padding: 0;
    margin: 0 0 1.75rem;
}

.gs-card__highlights li {
    display: flex;
    align-items: flex-start;
    gap: .7rem;
    padding: .45rem 0;
    font-size: var(--type-u5);
    line-height: var(--lh-snug);
    color: var(--gs-ink-2);
}

/* Bullet markers are DECORATIVE reinforcement, not a distinction: every one of
   these lists sits inside a card that already names its level in words, in a
   glyph and in a pip count. They carry no meaning that is lost if hue is. */
.gs-card__highlights li i {
    font-size: .55rem;
    color: var(--lvl);
    margin-top: 7px;
    flex-shrink: 0;
}

.gs-card__cta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    width: 100%;
    padding: .85rem 1.25rem;
    font-size: var(--type-u5);
    font-weight: 600;
    color: var(--sem-ink-on-fill);
    background: var(--lvl-grad);
    border: none;
    border-radius: var(--gs-r-sm);
    text-decoration: none;
    transition: box-shadow var(--gs-dur) var(--gs-ease);
    position: relative;
    overflow: hidden;
}

.gs-card__cta::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,.2), transparent);
    transform: translateX(-100%);
    transition: transform .5s var(--gs-ease);
}

.gs-card__cta:hover {
    text-decoration: none;
    color: var(--sem-ink-on-fill);
}

.gs-card__cta:hover::after { transform: translateX(100%); }

/* Secondary action beside a .gs-card__cta — outline, light ink. */
.gs-card__cta-alt {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    padding: .85rem 1.25rem;
    font-size: var(--type-u5);
    font-weight: 600;
    color: var(--ink-1);
    background: var(--sf-2);
    border: 1px solid var(--line-3);
    border-radius: var(--gs-r-sm);
    text-decoration: none;
    transition: border-color var(--gs-dur) var(--gs-ease), background var(--gs-dur) var(--gs-ease);
}

.gs-card__cta-alt:hover {
    border-color: var(--lvl-edge);
    background: var(--sf-3);
    color: var(--ink-1);
    text-decoration: none;
}

.gs-card__actions {
    display: flex;
    gap: .75rem;
}

.gs-card__actions .gs-card__cta { flex: 1; }

/* ─────────────────────────────────────────────────────────────────────────────
   9 · TIMELINE  ·  numbered steps
   The number in the dot is the ordering channel; the level hue is decoration
   on top of it. Works with no colour at all.
   ───────────────────────────────────────────────────────────────────────────── */
.gs-timeline {
    list-style: none;
    padding: 0;
    margin: 0;
    position: relative;
}

.gs-timeline::before {
    content: '';
    position: absolute;
    top: 20px;
    bottom: 20px;
    left: 19px;
    width: 2px;
    background: linear-gradient(180deg, var(--lvl-edge) 0%, var(--lvl-line) 100%);
    border-radius: 2px;
}

.gs-timeline__step {
    display: flex;
    align-items: flex-start;
    gap: 1.5rem;
    padding: 1.1rem 0;
    position: relative;
}

.gs-timeline__dot {
    width: 40px;
    height: 40px;
    border-radius: var(--r-full);
    background: var(--lvl-wash);
    border: 2px solid var(--lvl-edge);
    color: var(--lvl);
    font-family: var(--font-mono);
    font-size: var(--type-u6);
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    position: relative;
    z-index: 1;
    transition: transform var(--gs-dur) var(--gs-ease), box-shadow var(--gs-dur) var(--gs-ease),
                background var(--gs-dur) var(--gs-ease), border-color var(--gs-dur) var(--gs-ease);
}

.gs-timeline__step:hover .gs-timeline__dot {
    background: var(--lvl-wash);
    border-color: var(--lvl);
    box-shadow: 0 0 20px var(--lvl-glow);
    transform: scale(1.08);
}

.gs-timeline__text {
    font-size: var(--type-u4);
    line-height: var(--lh-read);
    color: var(--gs-ink-2);
    padding-top: .45rem;
    flex: 1;
    transition: color var(--gs-dur) ease;
}

.gs-timeline__step:hover .gs-timeline__text { color: var(--gs-ink-1); }

/* Inline links keep an underline as well as the hue — a link that is only a
   colour is the textbook 1.4.1 failure. */
.gs-timeline__text a,
.gs-content__list a {
    color: var(--lvl);
    text-decoration: underline;
    text-underline-offset: 3px;
    font-weight: 500;
    transition: color var(--gs-dur) var(--gs-ease);
}

.gs-timeline__text a:hover,
.gs-content__list a:hover { color: var(--ink-1); }

/* ─────────────────────────────────────────────────────────────────────────────
   10 · CONTENT BLOCK
   ───────────────────────────────────────────────────────────────────────────── */
.gs-content { position: relative; padding: 0; }

.gs-content__container {
    max-width: 1060px;
    margin: 0 auto;
    padding: 0 2rem;
}

.gs-content__card {
    background: var(--sf-1);
    border: 1px solid var(--line-1);
    border-radius: var(--gs-r-xl);
    padding: clamp(2.5rem, 4vw, 3.5rem) clamp(2.5rem, 5vw, 4rem);
    margin-bottom: 2rem;
}

.gs-content__card:last-child { margin-bottom: 0; }
.gs-content + .gs-content { padding-top: clamp(1rem, 2vh, 2rem); }

.gs-content__heading {
    font-family: var(--font-display);
    font-size: var(--type-u2);
    font-weight: 700;
    color: var(--gs-ink-1);
    margin: 0 0 1.25rem;
    padding-bottom: .65rem;
    border-bottom: 1px solid var(--line-1);
    letter-spacing: var(--track-tight);
}

.gs-content__list { list-style: none; padding: 0; margin: 0; }

.gs-content__list li {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    padding: .65rem 0;
    font-size: var(--type-u4);
    line-height: var(--lh-snug);
    color: var(--gs-ink-2);
}

.gs-content__list li i {
    font-size: .5rem;
    color: var(--lvl);
    margin-top: 9px;
    flex-shrink: 0;
}

.gs-content__list li strong { color: var(--gs-ink-1); font-weight: 600; }

/* ─────────────────────────────────────────────────────────────────────────────
   11 · CALLOUT  ·  the one component that replaces .gd-tip, .hta-notes__card
        and .gd-access__card
   Level-coloured, and the level's RULE WEIGHT is what separates a tip you can
   skip from a caution you cannot. --sem-rule-ladder is 3px, interrupt is 5px.
   ───────────────────────────────────────────────────────────────────────────── */
.gs-callout {
    position: relative;
    background: var(--sf-1);
    border: 1px solid var(--line-1);
    border-left: var(--lvl-rule) solid var(--lvl);
    border-radius: var(--gs-r-lg);
    padding: 1.75rem 2rem;
    overflow: hidden;
}

.gs-callout__head {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin-bottom: .65rem;
}

.gs-callout__icon {
    width: 34px;
    height: 34px;
    border-radius: var(--gs-r-sm);
    background: var(--lvl-wash);
    border: 1px solid var(--lvl-edge);
    color: var(--lvl);
    font-size: .85rem;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.gs-callout__label {
    font-family: var(--font-mono);
    font-size: var(--type-m2);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--lvl);
}

.gs-callout__text {
    font-size: var(--type-u4);
    line-height: var(--lh-read);
    color: var(--gs-ink-2);
    margin: 0;
}

.gs-callout__text strong { color: var(--gs-ink-1); font-weight: 600; }

.gs-callout__list { list-style: none; padding: 0; margin: 0; }

.gs-callout__list li {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    padding: .55rem 0;
    font-size: var(--type-u5);
    line-height: var(--lh-snug);
    color: var(--gs-ink-2);
}

.gs-callout__list li i {
    font-size: .7rem;
    color: var(--lvl);
    margin-top: 5px;
    flex-shrink: 0;
}

.gs-callout__list li a {
    color: var(--lvl);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.gs-callout__list li a:hover { color: var(--ink-1); }

/* Split layout: text on the left, an action on the right. */
.gs-callout--split {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
}

.gs-callout__content {
    display: flex;
    align-items: center;
    gap: .75rem;
    flex: 1;
    min-width: 0;
}

/* ─────────────────────────────────────────────────────────────────────────────
   12 · SCREENSHOT FRAME
   The three window dots are the ONE place on these pages where mint / amber /
   rose appear without meaning anything, so they are deliberately drawn at the
   -line alpha (~.24) rather than at full hue: quiet enough to read as chrome
   rather than as three status lights.
   ───────────────────────────────────────────────────────────────────────────── */
.gs-screenshot { margin: 0; }

.gs-screenshot__frame {
    position: relative;
    border-radius: var(--gs-r-lg);
    overflow: hidden;
    background: var(--sf-1);
    border: 1px solid var(--line-2);
    box-shadow: 0 8px 32px rgba(0, 0, 0, .3);
    transition: border-color var(--gs-dur) var(--gs-ease), box-shadow var(--gs-dur) var(--gs-ease);
}

.gs-screenshot__frame:hover {
    border-color: var(--sem-entry-edge);
    box-shadow: 0 12px 48px rgba(0, 0, 0, .4), 0 0 80px var(--sem-entry-glow);
}

.gs-screenshot__bar {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: .65rem 1rem;
    background: var(--bg-deep);
    border-bottom: 1px solid var(--line-1);
}

.gs-screenshot__bar-dot {
    width: 10px;
    height: 10px;
    border-radius: var(--r-full);
    background: var(--line-2);
}

.gs-screenshot__bar-dot--r { background: var(--sem-halt-line); }
.gs-screenshot__bar-dot--y { background: var(--sem-caution-line); }
.gs-screenshot__bar-dot--g { background: var(--sem-master-line); }

.gs-screenshot__img { display: block; width: 100%; height: auto; }

.gs-screenshot__caption {
    text-align: center;
    margin-top: .85rem;
    font-size: var(--type-u5);
    color: var(--gs-ink-4);   /* .46 = 4.66:1. The .45 it replaces was 4.48:1. */
    font-style: italic;
}

/* ─────────────────────────────────────────────────────────────────────────────
   13 · GUIDE NAVIGATION  ·  prev / next
   Each link is tinted with the level of the guide it goes TO, so the ladder is
   visible in the navigation as well as on the page.
   ───────────────────────────────────────────────────────────────────────────── */
.gs-guide-nav { position: relative; padding: clamp(2rem, 4vh, 3rem) 0; }

.gs-guide-nav__container {
    max-width: 1060px;
    margin: 0 auto;
    padding: 0 1.5rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
}

.gs-guide-nav__link {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .75rem 1.5rem;
    font-size: var(--type-u5);
    font-weight: 600;
    color: var(--gs-ink-2);
    background: var(--sf-1);
    border: 1px solid var(--line-1);
    border-radius: var(--gs-r-md);
    text-decoration: none;
    transition:
        color var(--gs-dur) var(--gs-ease),
        border-color var(--gs-dur) var(--gs-ease),
        box-shadow var(--gs-dur) var(--gs-ease),
        transform var(--gs-dur) var(--gs-ease);
}

.gs-guide-nav__link:hover {
    color: var(--ink-1);
    border-color: var(--lvl-edge);
    box-shadow: 0 8px 24px var(--lvl-glow);
    transform: translateY(-2px);
    text-decoration: none;
}

.gs-guide-nav__link--next { margin-left: auto; }
.gs-guide-nav__link--prev { margin-right: auto; }

.gs-guide-nav__label-sm {
    font-family: var(--font-mono);
    font-size: var(--type-m3);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--gs-ink-4);
    font-weight: 400;
}

/* ─────────────────────────────────────────────────────────────────────────────
   14 · BOTTOM CTA BANNER
   ───────────────────────────────────────────────────────────────────────────── */
.gs-cta-banner {
    position: relative;
    padding: clamp(4rem, 8vh, 6rem) 0;
    text-align: center;
    overflow: hidden;
}

.gs-cta-banner__bg {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 0;
}

.gs-cta-banner__orb {
    position: absolute;
    border-radius: var(--r-full);
    filter: blur(80px);
    opacity: .2;
}

.gs-cta-banner__orb--1 {
    width: 350px;
    height: 350px;
    top: -30%;
    left: 20%;
    background: radial-gradient(circle, var(--sem-entry-glow) 0%, transparent 70%);
}

.gs-cta-banner__orb--2 {
    width: 300px;
    height: 300px;
    bottom: -30%;
    right: 15%;
    background: radial-gradient(circle, var(--sem-build-glow) 0%, transparent 70%);
}

.gs-cta-banner__inner {
    position: relative;
    z-index: 1;
    max-width: 680px;
    margin: 0 auto;
    padding: 0 1.5rem;
}

.gs-cta-banner__title {
    font-family: var(--font-display);
    font-size: clamp(1.7rem, 3.5vw, 2.4rem);
    font-weight: 700;
    color: var(--gs-ink-1);
    margin-bottom: .75rem;
    letter-spacing: var(--track-tight);
}

.gs-cta-banner__text {
    font-size: var(--type-u3);
    line-height: var(--lh-read);
    color: var(--gs-ink-2);
    margin-bottom: 2.25rem;
}

.gs-cta-banner__actions {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    flex-wrap: wrap;
}

/* ─────────────────────────────────────────────────────────────────────────────
   15 · SCROLL REVEAL
   ───────────────────────────────────────────────────────────────────────────── */
.gs-reveal {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity var(--dur-5) var(--gs-ease), transform var(--dur-5) var(--gs-ease);
}

.gs-reveal--visible { opacity: 1; transform: translateY(0); }
.gs-reveal--d1 { transition-delay: 100ms; }
.gs-reveal--d2 { transition-delay: 200ms; }
.gs-reveal--d3 { transition-delay: 300ms; }
.gs-reveal--d4 { transition-delay: 400ms; }

/* ─────────────────────────────────────────────────────────────────────────────
   16 · RESPONSIVE
   ───────────────────────────────────────────────────────────────────────────── */
@media (max-width: 768px) {
    .gs-hero__ctas,
    .gs-cta-banner__actions {
        flex-direction: column;
        align-items: center;
    }

    .gs-hero__ctas .gs-btn,
    .gs-cta-banner__actions .gs-btn {
        width: 100%;
        max-width: 320px;
        justify-content: center;
    }

    .gs-content__card {
        padding: clamp(1.5rem, 3vw, 2rem);
        border-radius: var(--gs-r-lg);
    }

    .gs-content__container { padding: 0 1.25rem; }

    .gs-timeline__step { gap: 1rem; }
    .gs-timeline__dot { width: 34px; height: 34px; font-size: var(--type-m3); }
    .gs-timeline::before { left: 16px; }

    .gs-card__actions { flex-direction: column; }

    .gs-guide-nav__container { flex-direction: column; }

    .gs-guide-nav__link--next,
    .gs-guide-nav__link--prev {
        margin: 0;
        width: 100%;
        justify-content: center;
    }

    .gs-callout--split {
        flex-direction: column;
        align-items: flex-start;
        text-align: left;
    }
}

@media (max-width: 480px) {
    .gs-card__head,
    .gs-card__body {
        padding-left: 1.5rem;
        padding-right: 1.5rem;
    }

    .gs-content__card { padding: 1.25rem; }
    .gs-callout { padding: 1.5rem 1.25rem; }

    .gs-screenshot__bar { padding: .5rem .75rem; }
    .gs-screenshot__bar-dot { width: 8px; height: 8px; }

    /* The chip label can wrap on a narrow phone; keep the pips on the label's
       line rather than orphaned underneath it. */
    .gs-chip { flex-wrap: wrap; row-gap: .2rem; }
}

/* ─────────────────────────────────────────────────────────────────────────────
   17 · REDUCED MOTION  ·  last block in the file, on purpose
   Every selector here matches the specificity of the rule it overrides, and it
   is the last thing in the file, so source order decides. No `!important`.
   ───────────────────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .gs-page-orb--1,
    .gs-page-orb--2,
    .gs-mesh__orb--1,
    .gs-mesh__orb--2,
    .gs-mesh__orb--3 {
        animation: none;
    }

    .gs-reveal {
        opacity: 1;
        transform: none;
        transition: none;
    }

    .gs-card,
    .gs-btn,
    .gs-card__icon,
    .gs-card__cta,
    .gs-card__cta-alt,
    .gs-timeline__dot,
    .gs-timeline__text,
    .gs-screenshot__frame,
    .gs-guide-nav__link,
    .gs-hero__icon,
    .gs-subhero__back {
        transition: none;
    }

    /* The glow follows the pointer; with motion off it is noise. The level rule
       is a static border and stays — it is a signal, not an animation. */
    .gs-card__glow { display: none; }

    .gs-btn--primary::after,
    .gs-card__cta::after { display: none; }
}
