/* ============================================================================
   experience_card.css — the MOTION LIBRARY for the experience section.

   Owns ONLY the two CSS motion graphics and their contracts:
     • .exp-orbit — 8 stage chips riding one elliptical orbit (icon ring +
       focal name reveal). Used by the anatomy band (#template-gallery).
     • .exp-feed  — vertical infinite marquee of industry cards. Used by the
       door's ambience wall (#template-gallery).
   Plus the shared .exp-c-media viewport and the exp-aurora-a/b keyframes
   (consumed by experience_section.css, which owns ALL section layout).

   PERF/CSP CONTRACT (do not break):
     • Motion touches ONLY transform + opacity (compositor-only).
     • The orbit + feed @keyframes are MECHANICALLY DERIVED and perf-critical
       — do not hand-edit; see their block comments.
     • Feed spacing is trailing margin on .exp-fcard, never flex gap (the
       -50% loop must wrap seamlessly; guarded).
     • Sector accents come from a per-card class (never inline style).
     • Strict public CSP: no inline styles anywhere.
   ========================================================================== */
@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); }
}

/* 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;
}


/* ── 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;
}
@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. */
@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); }

/* ══════════════════════════════════════════════════════════════════════════════
   MOBILE (≤640px) — iOS-native treatment.

   The desktop design is a wide "console": one glass pane, a 2-col device, two
   262px motion stages. Stacked on a phone that became a ~1100px tower of
   half-empty graphics, and the console framing stopped paying for itself.

   On iOS this is a section header + two tappable GROUPED CARDS. So: each zone
   gets its own surface + hairline + press feedback, the motion becomes a compact
   preview strip rather than a stage, and type goes left-aligned at iOS sizes.

   MUST STAY LAST IN THIS FILE. The earlier `@media (max-width: 640px)` block
   (~L303) is declared ABOVE the base `.exp-feed` / `.exp-c-media` rules, and a
   media query adds NO specificity — so those mobile rules were silently losing
   to the later base rules on source order. That's why the feed stayed 2-up on a
   phone and clamped names to "Value-Bas…" in a ~124px column.
   ══════════════════════════════════════════════════════════════════════════════ */