/* ============================================================================
   experience_card.css — "Experience your journey" — the cinematic STAGE.

   A single immersive console that houses two entry cards so visitors click
   straight to what they want:
     01  The building blocks → stages you assemble into a journey
                               (motion: .exp-orbit ring of stage ICONS; the focal
                                one expands to reveal its name — see the block below)
     02  See it Live         → pick your industry, run the real demo (the gallery)
                               (motion: .exp-feed vertical infinite-scroll of real
                                gallery cards, rising bottom→top)

   The two cards read as one object split by a glowing center SEAM (a pulse
   travels between them: stages → journey → industry). Each card is a layered-
   glass panel that reacts to the pointer with a real 3D tilt + a spotlight that
   follows the cursor (--rx/--ry/--mx/--my are set by experience_modal.js — pure
   GPU transform/opacity, no per-frame layout). An "01 / 02" index chip rhymes
   with the scroll-jacked beats' "01 CREATE" step motif so this section belongs
   to the same page.

   The full server-rendered gallery grid (~689 crawlable SEO links) lives in the
   Experience modal, step 3 — never JS-ify or drop it. All motion is pure CSS,
   all styling is external (PUBLIC_CSP forbids inline style/script — see
   tasks/lessons/general/..._public_pages_no_inline_styles_csp). Matches index_v6
   tokens (--blurple, --main/--inv-bg-color, glass, fonts, --sector-*).

   PERF/CSP CONTRACT (do not break):
     • Card motion touches ONLY transform + opacity (compositor-only).
     • The orbit + feed @keyframes at the END of this file are MECHANICALLY
       DERIVED and perf-critical — do not hand-edit; see their block comments.
     • Sector accents come from a per-card class (never inline style).
   ========================================================================== */

.exp-kicker {
    display: block;
    font-family: var(--font-main, 'Satoshi', sans-serif);
    font-size: .8rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
    color: var(--blurple); margin-bottom: .9rem;
}

/* ── The stage: NO outer frame (that framed box nested around the panel was the
   "double border" / wedding-cake look). This element only positions the single
   floating console below and holds the ambient aurora "lake": a soft colour
   glow that pools BEHIND and BENEATH the panel and bleeds into the page — no
   border, no box, no clip, so there's only ever one edge (the console's). */
.exp-stage {
    position: relative;
    margin: 2.5rem 0 3rem;
    padding: clamp(1rem, 2.6vw, 2.2rem) 0;
}
/* External aurora removed — the console is its own restrained dark surface now
   (the footer carries its glow internally too). Kept in the DOM, not painted. */
.exp-stage-bg { display: none; }
/* Three soft colour blobs drift on a slow, offset loop — GPU transform/opacity.
   Sized/placed to read as one integrated pool of light under the console. */
.exp-stage-aurora,
.exp-stage-aurora::before,
.exp-stage-aurora::after {
    content: ''; position: absolute; border-radius: 50%;
    filter: blur(56px); will-change: transform, opacity;
}
.exp-stage-aurora {
    top: 8%; left: 12%; width: 62%; height: 84%;
    background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--blurple) 46%, transparent), transparent 66%);
    opacity: .5; animation: exp-aurora-a 26s ease-in-out infinite;
}
.exp-stage-aurora::before {
    top: 14%; right: 2%; left: auto; width: 52%; height: 80%;
    background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--sector-cyan, #0fa8c0) 40%, transparent), transparent 66%);
    opacity: .34; animation: exp-aurora-b 32s ease-in-out infinite;
}
.exp-stage-aurora::after {
    bottom: -4%; top: auto; left: 26%; width: 56%; height: 66%;
    background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--sector-magenta, #9d4edd) 32%, transparent), transparent 64%);
    opacity: .24; animation: exp-aurora-a 30s ease-in-out infinite reverse;
}
@keyframes exp-aurora-a {
    0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
    50%      { transform: translate3d(6%, 5%, 0) scale(1.12); }
}
@keyframes exp-aurora-b {
    0%, 100% { transform: translate3d(0, 0, 0) scale(1.05); }
    50%      { transform: translate3d(-7%, -4%, 0) scale(.92); }
}

/* ── One immersive PANEL — a single connected scene (no two-card grid) ────────
   The section is ONE glass surface. Inside, the stages (a large orbital
   "engine", zone 01) sit beside a live wall of industry journeys (zone 02), so
   the whole thing reads as one system: assemble the stages, watch them
   personalise into every industry. The PANEL (not the zones) tilts to the
   cursor and a
   spotlight follows it (--rx/--ry/--mx/--my set by experience_modal.js — pure
   GPU transform/opacity). The two .exp-c zones are transparent hit-targets (each
   opens the right modal step); there is no second box, no divider. */
.exp-cards {
    /* THEME-AWARE glass — a light pane on the light theme, a dark pane on the
       dark theme (it follows the page, never forced). The footer's craft rides
       on top: a text scale (ink→text→muted→faint) that flips with the theme,
       the accent-rule + luminous-edge brand colours, and its restraint. */
    --rx: 0deg; --ry: 0deg; --mx: 50%; --my: -6%;
    --exp-ink: var(--inv-bg-color);
    --exp-text: color-mix(in srgb, var(--inv-bg-color) 68%, transparent);
    --exp-muted: color-mix(in srgb, var(--inv-bg-color) 50%, transparent);
    --exp-faint: color-mix(in srgb, var(--inv-bg-color) 38%, transparent);
    --fv2-purple: #7873f5; --fv2-blue: #60a5fa; --fv2-pink: #d490ff;
    position: relative; z-index: 1; isolation: isolate;
    display: flex; flex-direction: column;
    padding: clamp(1.6rem, 3vw, 2.5rem) clamp(1.5rem, 2.8vw, 2.4rem) clamp(1.6rem, 2.8vw, 2.3rem);
    border-radius: 22px; overflow: hidden;
    transform: perspective(1600px) rotateX(var(--rx)) rotateY(var(--ry));
    transition: transform .35s var(--surface-ease, ease), box-shadow .55s ease, border-color .55s ease;
    /* Real frosted glass (backdrop blur = the "flat-screen TV" quality) over the
       theme's glass substrate, with ONE subtle top-centre glow. No heavy fills. */
    background:
        radial-gradient(115% 130% at 50% -15%, color-mix(in srgb, var(--blurple) 10%, transparent) 0%, transparent 60%),
        var(--surface-glass-bg);
    -webkit-backdrop-filter: blur(14px) saturate(1.1);
    backdrop-filter: blur(14px) saturate(1.1);
    border: 1px solid var(--surface-glass-border);
    box-shadow:
        0 24px 48px -28px rgba(10, 14, 44, .34),
        var(--surface-glass-shadow),
        inset 0 1px 0 color-mix(in srgb, #fff 14%, transparent);
    color: var(--exp-text);
}
/* The two zones ride a 2-col grid INSIDE the pane, beneath the integrated title. */
.exp-flow {
    position: relative; z-index: 3;
    display: grid; grid-template-columns: 1.08fr 0.92fr; align-items: stretch;
    gap: clamp(1rem, 3vw, 2.8rem);
}
.exp-cards:hover {
    border-color: color-mix(in srgb, var(--blurple) 30%, var(--surface-glass-border));
    box-shadow:
        0 30px 60px -32px rgba(10, 14, 44, .36),
        var(--surface-glass-shadow-active-hover),
        inset 0 1px 0 color-mix(in srgb, #fff 16%, transparent);
}
/* Luminous top-edge signature — mirrors footer.footer-v2::before (the surface
   the brand considers exceptionally polished): a glowing purple→blue→pink 1px
   line that fades at both ends, so the console's top edge reads as the same
   premium lit bezel as the footer. */
.exp-cards::before {
    content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px; z-index: 5;
    pointer-events: none;
    background: linear-gradient(90deg,
        rgba(120, 115, 245, 0) 0%,
        rgba(120, 115, 245, 0.55) 24%,
        rgba(96, 165, 250, 0.6) 52%,
        rgba(212, 144, 255, 0.5) 78%,
        rgba(120, 115, 245, 0) 100%);
    box-shadow: 0 0 14px rgba(120, 115, 245, 0.35);
}
/* (No cursor spotlight — the footer has no such gradient; the 3D tilt is the
   hover event, and restraint is the point.) */

/* ── Title integrated INTO the glass ────────────────────────────────────────
   The section header lives inside the pane so the console reads as one
   self-contained device. Sized down from the standalone section heading and
   sitting above content (z above the specular glaze). */
/* ── Masthead: the console's integrated header ───────────────────────────────
   Title dominant; the section label sits as a baseline-aligned tag to the right.
   Left edge aligns with the zone text below it. No divider — the header spacing
   alone separates it from the content. */
.exp-cards .tg-header {
    position: relative; z-index: 4;
    display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap;
    column-gap: 1.5rem; row-gap: .3rem;
    margin: 0 0 clamp(1.5rem, 2.8vw, 2.1rem);
    padding: 0;
}
.exp-cards .tg-headline {
    font-family: var(--brand-font, 'Space Grotesk', sans-serif);
    font-size: clamp(1.6rem, 2.6vw, 2.2rem); font-weight: 600;
    color: var(--exp-ink); letter-spacing: -.02em; line-height: 1.05; margin: 0;
}
/* No gradient, no accent colour (both were "trying hard" tells). Presence comes
   from scale + weight + tracking — footer brand-name discipline. */
.exp-cards .exp-kicker {
    font-family: var(--brand-font, 'Space Grotesk', sans-serif);
    font-size: .7rem; font-weight: 600; text-transform: uppercase; letter-spacing: .16em;
    color: var(--exp-muted); margin: 0; white-space: nowrap;
}

/* ── Zone: a transparent hit-target over the engine / the industries ─────────
   `a.exp-c` (element+class) outranks landing_base.css's anchor underline. It is
   NOT a card: no border, no fill, no shadow — the panel is the surface. */
a.exp-c {
    position: relative; z-index: 3; display: flex; flex-direction: column;
    text-decoration: none; color: inherit;
    opacity: 0;   /* entrance: zones power on when the stage reveals */
    transition: opacity .9s ease;
}
.exp-stage.is-visible a.exp-c { opacity: 1; }
.exp-stage.is-visible a.exp-c:nth-of-type(1) { transition-delay: .1s; }
.exp-stage.is-visible a.exp-c:nth-of-type(2) { transition-delay: .24s; }
/* Transparent layout column (the tilt lives on the panel now). */
.exp-c-tilt {
    position: relative; z-index: 1; display: flex; flex-direction: column; height: 100%;
}

/* Header row: the footer-style eyebrow + the corner arrow. */
.exp-c-head {
    position: relative; z-index: 4;
    display: flex; align-items: baseline; gap: .7rem;
    padding: 0;
}
.exp-c-kicker {
    font-family: var(--brand-font, 'Space Grotesk', sans-serif);
    font-size: .7rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
    color: var(--exp-muted);
}
/* The whole zone IS the click target — one minimal corner arrow, footer-faint at
   rest, footer-blue on hover. */
.exp-c-arrow {
    margin-left: auto; flex: none; align-self: center;
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px;
    color: var(--exp-faint);
    transition: color .3s ease, transform .4s var(--surface-ease);
}
.exp-c-arrow svg { width: 17px; height: 17px; display: block; }
a.exp-c:hover .exp-c-arrow { color: var(--fv2-blue); transform: translate(3px, -3px); }

/* The motion "viewport" — a framed window the orbit / feed play inside. Fixed
   height (not aspect-ratio) so both graphics render at the same size across
   breakpoints. Card-specific overrides (padding/mask) live in the motion blocks
   at the end of this file. */
/* Frameless: the orbit + feed float directly in the shared panel (one open
   scene, not two boxed "screens"), over a soft blurple wash for depth. Keeps a
   fixed px height + border-box so both sides align (guard). */
.exp-c-media {
    position: relative; z-index: 1;
    flex: none; box-sizing: border-box; height: 262px; overflow: hidden;
    margin: .9rem 0 .2rem; border-radius: 14px;
    display: grid; place-items: center;
    background: transparent;
}

.exp-c-body { position: relative; z-index: 4; padding: 1.1rem 0 0; display: flex; flex-direction: column; flex: 1; }
.exp-c-title {
    font-family: var(--brand-font, 'Space Grotesk', sans-serif);
    font-size: 1.3rem; font-weight: 600; color: var(--exp-ink);
    letter-spacing: -.02em; line-height: 1.14; margin: 0 0 .5rem;
}
.exp-c-copy {
    font-family: var(--font-main, 'Satoshi', sans-serif);
    font-size: .85rem; line-height: 1.65; margin: 0;
    color: var(--exp-text);
}

/* ── Responsive ─────────────────────────────────────────────────────────────
   ≤900px: the pair stacks; the seam (a vertical connector) is meaningless when
   stacked, so it's removed and the grid drops to one column. */
@media (max-width: 900px) {
    .exp-flow { grid-template-columns: 1fr; row-gap: 1.6rem; }
}
/* ≤640px: the industry feed drops to one column so journey names stay readable
   instead of ellipsis-truncating in a squeezed 2-up grid. */
@media (max-width: 640px) {
    .exp-stage { border-radius: 22px; }
    .exp-feed { grid-template-columns: 1fr; }
    .exp-feed-col--b { display: none; }
    .exp-c-title { font-size: 1.28rem; }
}

/* ── Reduced motion: no drift, no tilt, no pulse; land assembled + legible. ──
   (The orbit + feed blocks below carry their own reduced-motion freezes.) */
@media (prefers-reduced-motion: reduce) {
    .exp-stage-aurora, .exp-stage-aurora::before, .exp-stage-aurora::after { animation: none; }
    a.exp-c { opacity: 1; }
    .exp-cards { transform: none; }
}

/* ── 02 Stages = orbital ring (a circular carousel) ─────────────────────────
   8 stage chips ride ONE elliptical orbit; a single exp-orbit keyframe set is a
   full lap, chips phase-offset by negative animation-delay. --ry is large (a
   tall vertical radius) so the path reads as a CIRCLE tilted toward the viewer.
   PACING dwells with each stage centred in focus, then smoothersteps the next
   one in ("stages click into place"). A FIXED elliptical track sits on that path.

   ICON-RING + NAME REVEAL: chips ride the ring ICON-ONLY (the exp-orbit opacity
   profile carries a floor so back/side chips stay visible as icons, not blank).
   Only the chip in the front focal slot expands to reveal its NAME — its
   .exp-orb-label morphs the pill open (max-width) while the ink fades in, driven
   by a second animation (exp-label) that SHARES the orbit's 26s clock + per-chip
   delay, so the reveal peaks exactly as the stage lands. The open plateau is
   narrower than the 12.5% inter-chip gap → only one name shows at a time, with a
   brief opacity-led crossfade at each hand-off (outgoing ink fades before its
   pill finishes closing, so no clipped-text flash).

   PREMIUM FOCUS: the front position is a lit STAGE. .exp-orbit-belt is a soft
   pool of BRAND light that BREATHES in sync with the rhythm (exp-focus) — it
   blooms as a stage lands and fades during the hand-off, so the focal chip
   visibly ignites each step. Each chip also carries a brand-tinted colored float
   shadow, scaled for free by its animated opacity — so the fully-opaque front
   chip reads brightest with NO per-chip class. Theme-robust: the colored shadow
   reads as a glow on dark and a soft coloured shadow on light.

   PERF-CRITICAL: the orbit + focus motion touches ONLY transform + opacity
   (GPU-composited). Depth READS via scale+opacity, OCCLUSION via translateZ in
   .exp-orbit-stage { transform-style: preserve-3d }. The exp-orbit keyframes are
   MECHANICALLY DERIVED — do not hand-edit; the opacity floor was applied by a
   uniform remap, not by touching the geometry. (exp-label animates max-width on
   ONE mid-reveal chip at a time — not the perf-critical orbit — so its layout
   cost is trivial.) Geometry (--rx/--ry/--orbit-shift) is live-tunable. */
.exp-c-media--orbit {
    aspect-ratio: auto; height: 262px; padding: 0; overflow: hidden; container-type: inline-size;
    transition: opacity .55s ease;  /* eases the recede when the loop pauses (hover) */
}
.exp-orbit {
    position: relative; width: 100%; height: 100%;
    --rx: clamp(120px, 38cqw, 186px); --ry: 100px; --orbit-shift: -85px;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}
/* The fixed track: a thin ellipse on the chips' exact path, masked to melt away
   upward so it reads as the arc the stages ride, not a closed oval. */
.exp-orbit::before {
    content: ''; position: absolute; left: 50%; top: calc(50% + var(--orbit-shift));
    width: calc(var(--rx) * 2); height: calc(var(--ry) * 2);
    transform: translate(-50%, -50%); border-radius: 50%;
    border: 1px solid color-mix(in srgb, var(--inv-bg-color) 16%, transparent);
    pointer-events: none;
    -webkit-mask-image: linear-gradient(to top, #000 24%, color-mix(in srgb,#000 34%,transparent) 44%, transparent 64%);
    mask-image: linear-gradient(to top, #000 24%, color-mix(in srgb,#000 34%,transparent) 44%, transparent 64%);
}
.exp-orbit-belt {
    position: absolute; left: 50%; top: calc(50% + 8px);
    width: calc(var(--rx) * 1.05); height: 96px;
    transform: translate(-50%, -50%); border-radius: 50%;
    /* A TIGHT brand pool that sits right under the focal chip (no broad grey floor
       — that read as a blob hanging in the middle). The exp-focus curve drops it
       to ZERO during the hand-off, so it only glows while a stage is actually
       parked in front, never on empty space between transitions. Blur is STATIC. */
    background:
        radial-gradient(ellipse 50% 66% at 50% 46%,
            color-mix(in srgb, var(--blurple) 30%, transparent),
            color-mix(in srgb, var(--purple) 16%, transparent) 46%,
            transparent 72%);
    filter: blur(12px); pointer-events: none;
    /* 3.25s stays LOCKED to the stage cadence (26s / 8 chips) so the bloom peaks
       exactly as each stage lands in front — do not desync. */
    animation: exp-focus 3.25s ease-in-out infinite; will-change: opacity, transform;
    /* Eases the pool to its calm ambient level when the loop pauses (see hover). */
    transition: opacity .5s ease;
}

/* 3D context so chips depth-sort by translateZ (compositor paint order). */
.exp-orbit-stage { position: absolute; inset: 0; transform-style: preserve-3d; transform: translateY(var(--orbit-shift)); }
/* A stage chip = a premium floating GLASS MODULE: top specular highlight, crisp
   lit edge, deep layered float shadow. Biggest/frontmost chip catches the most. */
.exp-orb {
    position: absolute; left: 50%; top: 50%;
    display: inline-flex; align-items: center; gap: 0; white-space: nowrap;
    padding: .46rem .5rem; border-radius: 13px;
    /* Lit glass MODULE: a crisp top specular, a cool brand kiss at the crown, over
       the theme glass substrate. The brand HALO in box-shadow is scaled for free
       by each chip's animated opacity — so the fully-opaque front chip reads as
       the brightest/"ignited" one with no per-chip class. */
    background:
        linear-gradient(180deg, color-mix(in srgb, #fff 66%, transparent) 0%, color-mix(in srgb, #fff 12%, transparent) 38%, transparent 82%),
        radial-gradient(132% 150% at 50% -14%, color-mix(in srgb, var(--blurpleblue) 18%, transparent), transparent 58%),
        var(--surface-glass-bg);
    border: 1px solid color-mix(in srgb, var(--inv-bg-color) 15%, transparent);
    box-shadow:
        0 24px 46px -20px rgba(12, 16, 46, .55),
        0 8px 18px -10px rgba(12, 16, 46, .38),
        /* BRAND HALO hugging the chip — this is the focus glow, and because it's
           scaled by each chip's animated opacity it lives ON the focal node and
           travels with it (front chip = opacity 1 = brightest; the rest fade). */
        0 0 26px -2px color-mix(in srgb, var(--blurple) 42%, transparent),
        0 13px 28px -16px color-mix(in srgb, var(--blurple) 32%, transparent),
        inset 0 1px 0 color-mix(in srgb, #fff 72%, transparent),
        inset 0 0 0 1px color-mix(in srgb, #fff 7%, transparent),
        inset 0 -10px 16px -12px color-mix(in srgb, var(--blurple) 20%, transparent);
    color: var(--inv-bg-color);
    font-family: var(--font-main, 'Satoshi', sans-serif); font-size: .82rem; font-weight: 680; letter-spacing: -.012em;
    animation: exp-orbit 26s linear infinite; will-change: transform, opacity; transform: translate(-50%, -50%);
}
.exp-orb-ic {
    display: inline-flex; flex: none; align-items: center; justify-content: center;
    width: 26px; height: 26px; border-radius: 8px;
    /* Brighter, brand-kissed lit tile so the glyph reads crisply instead of
       sinking into the glass (the old muddy grey square was the main "unfinished"
       tell). Icon ink near-full so it holds on the frosted surface. */
    color: color-mix(in srgb, var(--inv-bg-color) 92%, transparent);
    background:
        linear-gradient(180deg, color-mix(in srgb, #fff 56%, transparent), transparent 72%),
        radial-gradient(120% 120% at 50% 0%, color-mix(in srgb, var(--blurpleblue) 24%, transparent), transparent 62%),
        color-mix(in srgb, var(--inv-bg-color) 8%, transparent);
    box-shadow:
        inset 0 0 0 1px color-mix(in srgb, var(--inv-bg-color) 14%, transparent),
        inset 0 1px 0 color-mix(in srgb, #fff 58%, transparent),
        0 2px 5px -3px rgba(12, 16, 46, .5);
}
.exp-orb-ic svg { width: 13px; height: 13px; display: block; }
/* ── Focal name REVEAL ───────────────────────────────────────────────────────
   Every chip rides the ring as an ICON-ONLY pill. Only the chip in the front
   focal slot expands to reveal its name — the pill morphs open (max-width) as
   the label unspools + fades in. Driven by its OWN 26s animation sharing the
   orbit's clock + per-chip animation-delay, so the reveal peaks exactly when the
   stage lands front. Max-width/margin are layout, but only ONE chip is mid-
   reveal at a time (not the perf-critical orbit transform), so cost is trivial. */
.exp-orb-label {
    display: inline-block; overflow: hidden; white-space: nowrap; line-height: 1.1;
    max-width: 0; margin-left: 0; opacity: 0;
    /* Ease-out settle (not linear) so the name eases up into place, never a pop. */
    animation: exp-label 26s var(--surface-ease, ease) infinite;
    /* When the loop pauses (sibling hovered) the animation is REMOVED, so the
       label falls back to this collapsed base — this transition eases that fall,
       so a name half-way through its reveal retracts cleanly instead of freezing
       clipped mid-morph. (Idle otherwise: a running animation ignores it.) */
    transition: max-width .5s var(--surface-ease, ease), opacity .38s ease,
                margin-left .5s var(--surface-ease, ease);
    will-change: max-width, opacity, transform;
}
/* ── Hover focus / PAUSE STATE ───────────────────────────────────────────────
   Hovering EITHER card quiets the OTHER card's motion. A raw freeze can strand
   the stages in an awkward half-state — a name clipped mid-reveal, an empty pill
   mid-open, the pool glowing on a hand-off. So the orbit PAUSES its positions in
   place, but the graphic gracefully SETTLES to a calm "assembly at rest": every
   name eases back to its icon, the ignition pool fades to a soft ambient glow,
   and the whole engine recedes a touch. A clean, intentional pose from ANY stop
   point — and it simply resumes when you look back. */
/* CRITICAL: PAUSE all three loops (never `animation: none`). The orbit, the name
   reveal and the ignition pool share one clock via animation-delay; pausing
   freezes them together, so on resume they continue IN LOCKSTEP. Removing an
   animation instead (`none`) would re-sync it to the wall-clock while the paused
   orbit stays behind — each hover would then drift the reveal off the front chip
   ("expand node past the expand position"). We still get the clean rest look by
   OVERRIDING the (paused) output with `!important` + the transitions above: the
   labels collapse to icons and the pool dims to ambient, but every clock is
   frozen in place, so the loop resumes exactly where it left off — no drift. */
.exp-cards:has(.exp-c:hover) .exp-c:not(:hover) .exp-orb { animation-play-state: paused; }
.exp-cards:has(.exp-c:hover) .exp-c:not(:hover) .exp-orb-label {
    animation-play-state: paused;
    max-width: 0 !important; margin-left: 0 !important; opacity: 0 !important;
}
.exp-cards:has(.exp-c:hover) .exp-c:not(:hover) .exp-orbit-belt {
    animation-play-state: paused; opacity: .3 !important;
}
.exp-cards:has(.exp-c:hover) .exp-c:not(:hover) .exp-c-media--orbit { opacity: .82; }
@media (prefers-reduced-motion: reduce) {
    .exp-orb { animation: none; }
    .exp-orb-label { animation: none; }
    /* Front chip lands labelled; the rest stay icon-only (their default). */
    .exp-orb:nth-child(1) .exp-orb-label { max-width: 9rem; margin-left: .5rem; opacity: 1; }
    .exp-orbit-belt { animation: none; opacity: 1; }
  .exp-orb:nth-child(1) { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * 1.0000 + -2px), 60.0px) scale(1.100); opacity:1.000; }
  .exp-orb:nth-child(2) { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.019); opacity:0.722; }
  .exp-orb:nth-child(3) { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 1.0000), calc(var(--ry) * 0.0000 + -2px), -20.0px) scale(0.825); opacity:0.300; }
  .exp-orb:nth-child(4) { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.631); opacity:0.300; }
  .exp-orb:nth-child(5) { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * -1.0000 + -2px), -100.0px) scale(0.550); opacity:0.300; }
  .exp-orb:nth-child(6) { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.631); opacity:0.300; }
  .exp-orb:nth-child(7) { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -1.0000), calc(var(--ry) * -0.0000 + -2px), -20.0px) scale(0.825); opacity:0.300; }
  .exp-orb:nth-child(8) { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.019); opacity:0.722; }
}
.exp-orb:nth-child(1) { animation-delay: -0.000s; }
.exp-orb:nth-child(2) { animation-delay: -3.250s; }
.exp-orb:nth-child(3) { animation-delay: -6.500s; }
.exp-orb:nth-child(4) { animation-delay: -9.750s; }
.exp-orb:nth-child(5) { animation-delay: -13.000s; }
.exp-orb:nth-child(6) { animation-delay: -16.250s; }
.exp-orb:nth-child(7) { animation-delay: -19.500s; }
.exp-orb:nth-child(8) { animation-delay: -22.750s; }
/* Label reveal shares each chip's phase offset so the name opens on the chip
   that's front (same negative-delay ladder as the orbit above). */
.exp-orb:nth-child(1) .exp-orb-label { animation-delay: -0.000s; }
.exp-orb:nth-child(2) .exp-orb-label { animation-delay: -3.250s; }
.exp-orb:nth-child(3) .exp-orb-label { animation-delay: -6.500s; }
.exp-orb:nth-child(4) .exp-orb-label { animation-delay: -9.750s; }
.exp-orb:nth-child(5) .exp-orb-label { animation-delay: -13.000s; }
.exp-orb:nth-child(6) .exp-orb-label { animation-delay: -16.250s; }
.exp-orb:nth-child(7) .exp-orb-label { animation-delay: -19.500s; }
.exp-orb:nth-child(8) .exp-orb-label { animation-delay: -22.750s; }
@keyframes exp-orbit {
  0.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * 1.0000 + -2px), 60.0px) scale(1.082); opacity:1.000; }
  0.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * 1.0000 + -2px), 60.0px) scale(1.088); opacity:1.000; }
  1.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * 1.0000 + -2px), 60.0px) scale(1.101); opacity:1.000; }
  2.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * 1.0000 + -2px), 60.0px) scale(1.117); opacity:1.000; }
  3.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * 1.0000 + -2px), 60.0px) scale(1.123); opacity:1.000; }
  4.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * 1.0000 + -2px), 60.0px) scale(1.112); opacity:1.000; }
  5.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * 1.0000 + -2px), 60.0px) scale(1.096); opacity:1.000; }
  5.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * 1.0000 + -2px), 60.0px) scale(1.085); opacity:1.000; }
  6.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0021), calc(var(--ry) * 1.0000 + -2px), 60.0px) scale(1.081); opacity:1.000; }
  7.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0455), calc(var(--ry) * 0.9990 + -2px), 59.9px) scale(1.080); opacity:1.000; }
  8.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.1641), calc(var(--ry) * 0.9864 + -2px), 58.9px) scale(1.076); opacity:0.999; }
  9.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.3370), calc(var(--ry) * 0.9415 + -2px), 55.3px) scale(1.064); opacity:0.985; }
  10.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.5108), calc(var(--ry) * 0.8597 + -2px), 48.8px) scale(1.043); opacity:0.923; }
  10.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.6363), calc(var(--ry) * 0.7714 + -2px), 41.7px) scale(1.019); opacity:0.816; }
  11.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.6964), calc(var(--ry) * 0.7177 + -2px), 37.4px) scale(1.005); opacity:0.738; }
  12.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  13.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  14.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  15.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  15.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  16.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  17.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  18.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  19.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7086), calc(var(--ry) * 0.7056 + -2px), 36.4px) scale(1.002); opacity:0.720; }
  20.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7385), calc(var(--ry) * 0.6742 + -2px), 33.9px) scale(0.994); opacity:0.672; }
  20.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.8136), calc(var(--ry) * 0.5815 + -2px), 26.5px) scale(0.969); opacity:0.531; }
  21.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.9041), calc(var(--ry) * 0.4274 + -2px), 14.2px) scale(0.928); opacity:0.347; }
  22.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.9691), calc(var(--ry) * 0.2467 + -2px), -0.3px) scale(0.880); opacity:0.300; }
  23.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.9954), calc(var(--ry) * 0.0956 + -2px), -12.4px) scale(0.840); opacity:0.300; }
  24.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.9999), calc(var(--ry) * 0.0151 + -2px), -18.8px) scale(0.819); opacity:0.300; }
  25.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 1.0000), calc(var(--ry) * 0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  25.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 1.0000), calc(var(--ry) * 0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  26.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 1.0000), calc(var(--ry) * 0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  27.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 1.0000), calc(var(--ry) * 0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  28.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 1.0000), calc(var(--ry) * 0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  29.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 1.0000), calc(var(--ry) * 0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  30.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 1.0000), calc(var(--ry) * 0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  30.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 1.0000), calc(var(--ry) * 0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  31.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 1.0000), calc(var(--ry) * -0.0021 + -2px), -20.2px) scale(0.814); opacity:0.300; }
  32.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.9990), calc(var(--ry) * -0.0455 + -2px), -23.6px) scale(0.803); opacity:0.300; }
  33.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.9864), calc(var(--ry) * -0.1641 + -2px), -33.1px) scale(0.772); opacity:0.300; }
  34.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.9415), calc(var(--ry) * -0.3370 + -2px), -47.0px) scale(0.726); opacity:0.300; }
  35.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.8597), calc(var(--ry) * -0.5108 + -2px), -60.9px) scale(0.680); opacity:0.300; }
  35.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7714), calc(var(--ry) * -0.6363 + -2px), -70.9px) scale(0.646); opacity:0.300; }
  36.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7177), calc(var(--ry) * -0.6964 + -2px), -75.7px) scale(0.630); opacity:0.300; }
  37.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  38.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  39.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  40.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  40.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  41.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  42.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  43.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  44.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.7056), calc(var(--ry) * -0.7086 + -2px), -76.7px) scale(0.627); opacity:0.300; }
  45.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.6742), calc(var(--ry) * -0.7385 + -2px), -79.1px) scale(0.619); opacity:0.300; }
  45.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.5815), calc(var(--ry) * -0.8136 + -2px), -85.1px) scale(0.599); opacity:0.300; }
  46.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.4274), calc(var(--ry) * -0.9041 + -2px), -92.3px) scale(0.575); opacity:0.300; }
  47.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.2467), calc(var(--ry) * -0.9691 + -2px), -97.5px) scale(0.558); opacity:0.300; }
  48.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0956), calc(var(--ry) * -0.9954 + -2px), -99.6px) scale(0.551); opacity:0.300; }
  49.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0151), calc(var(--ry) * -0.9999 + -2px), -100.0px) scale(0.550); opacity:0.300; }
  50.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * -1.0000 + -2px), -100.0px) scale(0.550); opacity:0.300; }
  50.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * -1.0000 + -2px), -100.0px) scale(0.550); opacity:0.300; }
  51.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * -1.0000 + -2px), -100.0px) scale(0.550); opacity:0.300; }
  52.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * -1.0000 + -2px), -100.0px) scale(0.550); opacity:0.300; }
  53.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * -1.0000 + -2px), -100.0px) scale(0.550); opacity:0.300; }
  54.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * -1.0000 + -2px), -100.0px) scale(0.550); opacity:0.300; }
  55.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * -1.0000 + -2px), -100.0px) scale(0.550); opacity:0.300; }
  55.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * 0.0000), calc(var(--ry) * -1.0000 + -2px), -100.0px) scale(0.550); opacity:0.300; }
  56.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.0021), calc(var(--ry) * -1.0000 + -2px), -100.0px) scale(0.550); opacity:0.300; }
  57.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.0455), calc(var(--ry) * -0.9990 + -2px), -99.9px) scale(0.550); opacity:0.300; }
  58.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.1641), calc(var(--ry) * -0.9864 + -2px), -98.9px) scale(0.554); opacity:0.300; }
  59.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.3370), calc(var(--ry) * -0.9415 + -2px), -95.3px) scale(0.566); opacity:0.300; }
  60.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.5108), calc(var(--ry) * -0.8597 + -2px), -88.8px) scale(0.587); opacity:0.300; }
  60.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.6363), calc(var(--ry) * -0.7714 + -2px), -81.7px) scale(0.611); opacity:0.300; }
  61.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.6964), calc(var(--ry) * -0.7177 + -2px), -77.4px) scale(0.625); opacity:0.300; }
  62.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  63.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  64.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  65.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  65.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  66.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  67.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  68.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * -0.7071 + -2px), -76.6px) scale(0.628); opacity:0.300; }
  69.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7086), calc(var(--ry) * -0.7056 + -2px), -76.4px) scale(0.628); opacity:0.300; }
  70.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7385), calc(var(--ry) * -0.6742 + -2px), -73.9px) scale(0.636); opacity:0.300; }
  70.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.8136), calc(var(--ry) * -0.5815 + -2px), -66.5px) scale(0.661); opacity:0.300; }
  71.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.9041), calc(var(--ry) * -0.4274 + -2px), -54.2px) scale(0.702); opacity:0.300; }
  72.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.9691), calc(var(--ry) * -0.2467 + -2px), -39.7px) scale(0.750); opacity:0.300; }
  73.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.9954), calc(var(--ry) * -0.0956 + -2px), -27.6px) scale(0.790); opacity:0.300; }
  74.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.9999), calc(var(--ry) * -0.0151 + -2px), -21.2px) scale(0.811); opacity:0.300; }
  75.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -1.0000), calc(var(--ry) * -0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  75.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -1.0000), calc(var(--ry) * -0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  76.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -1.0000), calc(var(--ry) * -0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  77.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -1.0000), calc(var(--ry) * -0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  78.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -1.0000), calc(var(--ry) * -0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  79.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -1.0000), calc(var(--ry) * -0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  80.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -1.0000), calc(var(--ry) * -0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  80.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -1.0000), calc(var(--ry) * -0.0000 + -2px), -20.0px) scale(0.815); opacity:0.300; }
  81.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -1.0000), calc(var(--ry) * 0.0021 + -2px), -19.8px) scale(0.816); opacity:0.300; }
  82.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.9990), calc(var(--ry) * 0.0455 + -2px), -16.4px) scale(0.827); opacity:0.300; }
  83.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.9864), calc(var(--ry) * 0.1641 + -2px), -6.9px) scale(0.858); opacity:0.300; }
  84.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.9415), calc(var(--ry) * 0.3370 + -2px), 7.0px) scale(0.904); opacity:0.301; }
  85.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.8597), calc(var(--ry) * 0.5108 + -2px), 20.9px) scale(0.950); opacity:0.434; }
  85.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7714), calc(var(--ry) * 0.6363 + -2px), 30.9px) scale(0.984); opacity:0.614; }
  86.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7177), calc(var(--ry) * 0.6964 + -2px), 35.7px) scale(1.000); opacity:0.706; }
  87.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  88.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  89.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  90.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  90.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  91.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  92.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  93.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7071), calc(var(--ry) * 0.7071 + -2px), 36.6px) scale(1.002); opacity:0.722; }
  94.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.7056), calc(var(--ry) * 0.7086 + -2px), 36.7px) scale(1.003); opacity:0.724; }
  95.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.6742), calc(var(--ry) * 0.7385 + -2px), 39.1px) scale(1.011); opacity:0.769; }
  95.833% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.5815), calc(var(--ry) * 0.8136 + -2px), 45.1px) scale(1.031); opacity:0.871; }
  96.667% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.4274), calc(var(--ry) * 0.9041 + -2px), 52.3px) scale(1.055); opacity:0.962; }
  97.500% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.2467), calc(var(--ry) * 0.9691 + -2px), 57.5px) scale(1.072); opacity:0.996; }
  98.333% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.0956), calc(var(--ry) * 0.9954 + -2px), 59.6px) scale(1.079); opacity:1.000; }
  99.167% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.0151), calc(var(--ry) * 0.9999 + -2px), 60.0px) scale(1.080); opacity:1.000; }
  100.000% { transform: translate(-50%, -50%) translate3d(calc(var(--rx) * -0.0000), calc(var(--ry) * 1.0000 + -2px), 60.0px) scale(1.080); opacity:1.000; }
}
@keyframes exp-focus {
  /* Bloom ONLY while a stage is parked front (around 0%/100%); fall to ZERO across
     the hand-off (the ~50% mid-point) so the pool never hangs on empty space. */
  0%   { opacity: 1;    transform: translate(-50%, -50%) scale(1.06); }
  24%  { opacity: .9;   transform: translate(-50%, -50%) scale(1.02); }
  36%  { opacity: 0;    transform: translate(-50%, -50%) scale(.84); }
  64%  { opacity: 0;    transform: translate(-50%, -50%) scale(.84); }
  76%  { opacity: .9;   transform: translate(-50%, -50%) scale(1.02); }
  100% { opacity: 1;    transform: translate(-50%, -50%) scale(1.06); }
}
/* Name reveal, phase-locked to the orbit's front dwell (chip is front across the
   0%/100% wrap). OPEN during the dwell, snap-collapse as the chip leaves front
   (7%→14%), icon-only through the back arc (14%→84%), then unspool as the next
   chip arrives (84%→92%). max-width caps past the longest label so the pill sizes
   to content — the pill morphs open around the name. */
@keyframes exp-label {
  /* The open pill lives in a window NARROWER than the 12.5% inter-chip gap, so
     the outgoing chip fully collapses to an icon BEFORE the incoming one starts
     to open — never two pills open at once, with a ~3% all-icons breath between.
     Opacity leads width (ink fades before the pill finishes closing / after it
     cracks open) so the morph is clean, never a clipped-text flash. */
  0%    { max-width: 9rem;   margin-left: .5rem; opacity: 1; transform: translateY(0); }    /* front: fully open, name settled */
  3.5%  { max-width: 9rem;   margin-left: .5rem; opacity: 1; transform: translateY(0); }
  5%    { max-width: 3.5rem; margin-left: .5rem; opacity: 0; transform: translateY(4px); } /* name fades + sinks out first */
  6%    { max-width: 0;      margin-left: 0;     opacity: 0; transform: translateY(4px); } /* pill closed → icon-only */
  96%   { max-width: 0;      margin-left: 0;     opacity: 0; transform: translateY(7px); } /* icon-only across the ring */
  97.5% { max-width: 3.5rem; margin-left: .5rem; opacity: 0; transform: translateY(7px); } /* pill cracks open, name still hidden + low */
  100%  { max-width: 9rem;   margin-left: .5rem; opacity: 1; transform: translateY(0); }   /* name RISES + fades up into place */
}

/* ── 03 Pick your industry = vertical infinite gallery feed ──────────────────
   Two columns of real journey cards (mirroring the gallery .tg-card design:
   sector-accent stripe, industry icon badge, eyebrow, name, sub) rise
   bottom→top forever. Each column's track holds its cards duplicated 2× and
   animates translateY 0 → -50% (the duplicate returns the start to origin →
   seamless). Inter-card spacing MUST be a trailing margin-bottom (NOT flex
   gap): like the old marquee, gap omits a trailing gap so -50% would hitch.
   Top+bottom mask fades cards in/out at the edges; the two columns run at
   different speeds so they don't move in lockstep. Sector accent comes from a
   per-card class (--exp-accent), never an inline style — PUBLIC_CSP forbids
   inline style/script. The cards are decorative (aria-hidden); the crawlable
   gallery links stay server-rendered in the modal + the grid below. */
.exp-c-media--feed {
    aspect-ratio: auto; height: 262px; padding: 0; overflow: hidden;
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 20%, #000 80%, transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0%, #000 20%, #000 80%, transparent 100%);
}
.exp-feed { display: grid; grid-template-columns: 1fr 1fr; gap: .55rem; width: 100%; height: 100%; padding: 0 .65rem; box-sizing: border-box; }
.exp-feed-col { overflow: hidden; }
.exp-feed-track { display: flex; flex-direction: column; animation: exp-feed 32s linear infinite; will-change: transform; }
.exp-feed-col--b .exp-feed-track { animation-duration: 40s; }
/* Hover focus (see the orbit block): hovering the sibling card quiets this feed. */
.exp-cards:has(.exp-c:hover) .exp-c:not(:hover) .exp-feed-track { animation-play-state: paused; }
@keyframes exp-feed { from { transform: translateY(0); } to { transform: translateY(-50%); } }
@media (prefers-reduced-motion: reduce) { .exp-feed-track { animation: none; } }
.exp-fcard {
    position: relative; display: flex; flex-direction: row; align-items: center; gap: .6rem;
    margin-bottom: .55rem; padding: .62rem .8rem .62rem .95rem; border-radius: 11px;
    border: 1px solid color-mix(in srgb, var(--inv-bg-color) 15%, transparent);
    background: linear-gradient(180deg, color-mix(in srgb, var(--inv-bg-color) 5%, transparent), transparent), var(--main-bg-color);
    box-shadow: 0 5px 12px -8px rgba(0,0,0,.5), inset 0 1px 0 color-mix(in srgb, #fff 7%, transparent);
    overflow: hidden;
}
.exp-fcard-accent { position: absolute; top: 0; left: 0; width: 3px; height: 100%; border-radius: 10px 0 0 10px; background: var(--exp-accent, var(--blurple)); opacity: .35; }
.exp-fcard-icon {
    width: 25px; height: 25px; flex: none; display: inline-flex; align-items: center; justify-content: center;
    border-radius: 7px; color: var(--exp-muted);
    background: color-mix(in srgb, var(--inv-bg-color) 6%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--inv-bg-color) 12%, transparent);
}
.exp-fcard-icon svg { width: 14px; height: 14px; display: block; }
.exp-fcard-body { display: flex; flex-direction: column; justify-content: center; min-width: 0; }
/* Icon + name only. The name WRAPS to two lines (no single-line "…" truncation —
   that ellipsis-as-placeholder was the loudest unfinished tell); the industry
   eyebrow + sub-line were dropped so each card is one calm, legible journey. */
.exp-fcard-name {
    font-family: var(--font-main, 'Satoshi', sans-serif); font-size: .82rem; font-weight: 600;
    color: var(--inv-bg-color); line-height: 1.28; letter-spacing: -.01em;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* Sector accent MUTED to one neutral ink (the 6-hue rainbow was the main
   "circus" offender). "See it live" is a motion zone — the motion carries the
   interest; per-item colour only competed with the one signature (top edge).
   Per-sector classes are kept (guard-required) but all resolve to the same tone. */
.exp-fcard--tech,
.exp-fcard--fin,
.exp-fcard--health,
.exp-fcard--industrial,
.exp-fcard--consumer,
.exp-fcard--prof { --exp-accent: color-mix(in srgb, var(--inv-bg-color) 30%, transparent); }
