            /* === Intentional non-token colour literals (Phase X5 audit L-02) ===
             * Most --xp-* tokens are sourced from openxp-theme.css + the project
             * extensions below. A small number of literal hex values are
             * INTENTIONAL and must NOT be replaced with tokens by future audits:
             *
             *   #fff / #ffffff (~10 sites) — pure-white text on coloured backdrops
             *     (CTAs on accent fills, deliberate maximum-contrast captions).
             *     `--xp-text-primary` (#E8E8EC) would soften the contrast on
             *     accent-coloured surfaces; kept literal where the surface design
             *     requires pure white.
             *
             *   #000 (mask gradients, one solid fill) — pure black is required for
             *     CSS mask-image alpha math (luminance-based mask: #000 = fully
             *     opaque). Not a brand colour; not tokenisable.
             *
             *   #2a2a2e, #ff5f57, #febc2e — recreating Apple's window-chrome
             *     traffic-light controls inside .demo-titlebar + .bridge-titlebar.
             *     Brand-mimicry literals; tokens would obscure intent.
             *
             *   #34d399 — Tailwind emerald-400. Used as a status-indicator hue
             *     where neither --xp-emerald (#10b981) nor --xp-green (#22c55e)
             *     produces the same perceived signal. Candidate for engine vM2
             *     palette if a third green is endorsed.
             *
             *   #08080c / #0d0d12 — bespoke atmospheric gradient stop pair on the
             *     hip-hop case-study backdrop. Off-token by design.
             *
             *   Partner-brand SVG fills (currently #65FF9B for silverscape, 5
             *     sites in PartnersSection.astro) — when a partner logo is
             *     reconstructed as inline SVG rather than loaded as an image,
             *     the partner's own brand hue is the correct fill, not ours.
             *     Justify per entry as new partners are added. Phase X5
             *     re-audit B-01-NEW (2026-05-21).
             *
             * Any NEW colour literal added below should match an existing token
             * or be added to this allowlist with a one-line justification.
             */

            /* === Reset === */
            *,
            *::before,
            *::after {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }

            /* === Platform palette + glows ===
             * The 11 extended --xp-* tokens (6 hues, 3 colour-name aliases, 2
             * accent-derived glows) come from the engine bundle's
             * tokens/palette-extended.css (engine vM2 M-02), inlined into
             * /theme/openxp-theme.css which loads before this file. No local
             * redeclaration (D-10).
             *
             * === No preset cascade neutralisers ===
             * The marketing preset link is the engine's headings-only split
             * (type-marketing-headings.css, vM2 M-01), so it no longer sets
             * body/p/code rules — body line-height stays `normal`, p margin/measure
             * stay default, code/pre stay 1em via the reset. The v1.1-era
             * neutraliser block is therefore gone (xpwebsite v2.1).
             */

            html {
                font-size: 16px;
                -webkit-font-smoothing: antialiased;
                -moz-osx-font-smoothing: grayscale;
                -webkit-text-size-adjust: 100%;
                text-size-adjust: 100%;
                scroll-behavior: smooth;
                scroll-padding-top: 80px;
                color-scheme: dark;
                /* Section scroll-snap (all pages). `proximity` (not `mandatory`)
                   nudges the settled section to a vertically central position
                   without trapping the user inside sections taller than the
                   viewport. Per-section alignment is on `section[id]` below;
                   the ≤640px block re-tunes alignment to `start` for mobile. */
                scroll-snap-type: y proximity;
            }
            /* Light theme must flip color-scheme too, or native scrollbars,
             * form controls, and focus rings keep dark UA chrome on the cream
             * page. The pre-paint stamp always sets an explicit data-theme, so
             * this attribute rule (higher specificity than html) always wins. */
            :root[data-theme='light'] {
                color-scheme: light;
            }
            /* While a programmatic scroll is in flight (arrow / nav links —
               see app.js + Layout), CSS snap is suspended: iOS Safari aborts
               smooth scrollIntoView at the nearest snap point otherwise, so
               long jumps (e.g. #studio → #projects) stall mid-way. The class
               is removed once the scroll settles; re-enabling re-snaps to the
               landed position (which is itself a snap point — no visible jump). */
            html.snap-suspend {
                scroll-snap-type: none !important;
            }
            section[id] {
                scroll-margin-top: 80px;
                /* Positioning context for the auto-injected .section-advance arrow. */
                position: relative;
                /* Snap each section to the viewport's vertical centre as it
                   settles (paired with html `scroll-snap-type: y proximity`). */
                scroll-snap-align: center;
                /* Every section is at least a full viewport tall, so once it
                   snaps into place neither the previous nor the next section is
                   visible. Taller content sections simply exceed this floor. */
                min-height: 100vh;
                box-sizing: border-box;
            }
            /* The developer fast-lane anchor is an in-flow <span id="start">
             * (not a section[id]), so it needs its own offset to land below the
             * fixed nav for both native hash jumps and the app.js scrollIntoView
             * path (Phase 2 WR-01). */
            #start {
                scroll-margin-top: 80px;
            }
            /* Mobile: sections usually exceed the viewport, so the proximity
               snap (and the section-advance arrow) must settle on a section's
               TOP — landing mid-section hides the heading and forces the
               visitor to scroll UP first. The per-section scroll-margin-top is
               zeroed because it would STACK with the html scroll-padding-top
               (80px, 64px ≤640px) — landing sections ~144px down with a strip
               of the previous section still visible. The html scroll-padding
               alone clears the fixed nav. */
            @media (max-width: 860px) {
                section[id] {
                    scroll-snap-align: start;
                    scroll-margin-top: 0;
                }
                /* Anchor the snap at the LARGE title (h2.section-heading), not
                   the section top — the eyebrow label above it scrolls past so
                   the headline is the first thing on screen. Sections without a
                   .section-heading keep snapping at their top (the :has() rule
                   simply doesn't match, and older engines without :has() fall
                   back to section-top snapping). html scroll-padding-top keeps
                   the snapped title clear of the fixed nav. */
                section[id]:has(.section-heading) {
                    scroll-snap-align: none;
                }
                section[id] .section-heading {
                    scroll-snap-align: start;
                    scroll-margin-top: 0;
                }
                /* #projects is a centred composition (portrait backdrop behind
                   the copy) — snap the whole section to the viewport centre
                   instead of anchoring its title at the top. */
                #projects {
                    scroll-snap-align: center;
                }
                #projects .section-heading {
                    scroll-snap-align: none;
                }
                /* The case-study hero sits at the very top of its page — a snap
                   point there pulls a freshly opened page down ~76px off the
                   true top, so it carries no snap of its own. */
                #hero {
                    scroll-snap-align: none;
                }
            }
            body {
                background: var(--xp-bg);
                color: var(--xp-text-primary);
                font-family: var(--xp-font-body);
                overflow-x: hidden;
            }

            /* === Typography === */
            h1,
            h2,
            h3 {
                font-family: var(--xp-font-heading);
                font-weight: 700;
                letter-spacing: -0.03em;
                line-height: 1.1;
            }
            a {
                color: var(--xp-accent);
                text-decoration: none;
            }
            a:hover {
                color: var(--xp-accent-hover);
            }

            /* === Navigation === */
            .nav {
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                z-index: 100;
                /* 3-column grid keeps the centre menu viewport-centred
                 * regardless of logo (left) / actions (right) widths. The two
                 * 1fr tracks are equal, so the auto centre track is centred. */
                display: grid;
                grid-template-columns: 1fr auto 1fr;
                align-items: center;
                padding: 1rem 2rem;
                background: transparent;
                transition:
                    background 0.3s,
                    border-color 0.3s,
                    backdrop-filter 0.3s;
                border-bottom: 1px solid transparent;
            }
            .nav.scrolled {
                background: rgba(5, 5, 7, 0.85);
                backdrop-filter: blur(16px);
                -webkit-backdrop-filter: blur(16px);
                border-bottom-color: var(--xp-border);
            }
            .nav-logo {
                display: flex;
                align-items: center;
                gap: 10px;
                text-decoration: none;
                color: var(--xp-text-primary);
                justify-self: start;
            }
            .nav-logo svg {
                width: 32px;
                height: 32px;
            }
            .nav-logo span {
                font-family: var(--xp-font-heading);
                font-size: 1.15rem;
                font-weight: 700;
                letter-spacing: -0.02em;
            }
            .nav-logo .xp {
                color: var(--xp-accent);
            }
            .nav-links {
                display: flex;
                gap: 2rem;
                justify-self: center;
            }
            .nav-actions {
                justify-self: end;
                display: flex;
                align-items: center;
                gap: 1rem;
            }
            .nav-links a {
                color: var(--xp-text-secondary);
                font-family: var(--xp-font-heading);
                font-size: 0.85rem;
                font-weight: 400;
                letter-spacing: 0.02em;
                text-decoration: none;
                transition: color 0.2s;
            }
            .nav-links a:hover {
                color: var(--xp-text-primary);
            }
            .nav-cta {
                padding: 8px 20px;
                background: var(--xp-accent);
                color: #fff;
                border-radius: 8px;
                font-family: var(--xp-font-heading);
                font-size: 0.85rem;
                font-weight: 600;
                text-decoration: none;
                transition:
                    background 0.2s,
                    box-shadow 0.2s;
            }
            .nav-cta:hover {
                background: var(--xp-accent-hover);
                box-shadow: 0 0 20px rgba(59, 130, 246, 0.3);
                color: #fff;
            }
            /* Active page indicator for route-model nav links (Phase 2 IA).
             * font-weight gives a non-colour affordance so the current page is
             * distinguishable without relying on hue (WCAG 1.4.1) (Phase 2 WR-04). */
            .nav-links a.active {
                color: var(--xp-accent);
                font-weight: 600;
            }
            /* Mobile burger nav — desktop hides it (the inline .nav-links carry
               the links); the ≤640px block shows it in the top-right, replacing
               the hidden .nav-links. Same trigger/popover shape as the theme
               menu; wired in assets/app.js. */
            .nav-burger {
                position: relative;
                display: none;
            }
            .nav-burger-trigger {
                appearance: none;
                -webkit-appearance: none;
                background: var(--xp-bg-surface);
                border: 1px solid var(--xp-border);
                cursor: pointer;
                display: inline-flex;
                align-items: center;
                justify-content: center;
                width: 32px;
                height: 32px;
                padding: 0;
                color: var(--xp-text-secondary);
                border-radius: var(--xp-radius-pill);
            }
            .nav-burger-trigger[aria-expanded="true"] {
                background: var(--xp-bg-elevated);
                color: var(--xp-text-primary);
            }
            .nav-burger-popover {
                position: absolute;
                top: calc(100% + 8px);
                right: 0;
                display: flex;
                flex-direction: column;
                gap: 2px;
                min-width: 168px;
                padding: 6px;
                background: var(--xp-bg-elevated);
                border: 1px solid var(--xp-border);
                border-radius: 10px;
                box-shadow: 0 10px 34px rgba(0, 0, 0, 0.45);
                z-index: 60;
            }
            .nav-burger-popover[hidden] {
                display: none;
            }
            .nav-burger-popover a {
                display: block;
                padding: 9px 12px;
                border-radius: 7px;
                color: var(--xp-text-secondary);
                font-family: var(--xp-font-heading);
                font-size: 0.95rem;
                text-decoration: none;
            }
            .nav-burger-popover a:hover {
                background: var(--xp-bg-surface);
                color: var(--xp-text-primary);
            }
            .nav-burger-popover a.active {
                color: var(--xp-accent);
                font-weight: 600;
            }
            /* Developer fast-lane quiet text link (Phase 2 IA-02) */
            /* === Theme toggle (quick task 260525-pzf) ===
             * Discrete three-segment light/auto/dark pill in the nav. Uses ONLY
             * --xp-* tokens so it auto-adapts to the active theme — no per-mode
             * rules and no raw colour literals (respects the L-02 allowlist).
             * The pressed segment fills with --xp-accent and the icon flips to
             * --xp-bg for maximum contrast in both light and dark. */
            /* Theme menu: single icon trigger → popover with light/dark/system. */
            .theme-menu {
                position: relative;
                display: inline-flex;
            }
            .theme-menu-trigger {
                appearance: none;
                -webkit-appearance: none;
                background: var(--xp-bg-surface);
                border: 1px solid var(--xp-border);
                cursor: pointer;
                display: inline-flex;
                align-items: center;
                justify-content: center;
                width: 32px;
                height: 32px;
                padding: 0;
                color: var(--xp-text-secondary);
                border-radius: var(--xp-radius-pill);
                transition:
                    background-color var(--xp-duration-fast)
                        var(--xp-easing-standard),
                    color var(--xp-duration-fast) var(--xp-easing-standard);
            }
            .theme-menu-trigger:hover {
                background: var(--xp-bg-elevated);
                color: var(--xp-text-primary);
            }
            .theme-menu-trigger:focus-visible {
                outline: 2px solid var(--xp-accent);
                outline-offset: 2px;
            }
            /* Trigger shows only the current mode's icon (set via [data-current-mode]). */
            .theme-menu-ticon {
                display: none;
                line-height: 0;
            }
            .theme-menu-trigger[data-current-mode="light"] .theme-menu-ticon[data-icon="light"],
            .theme-menu-trigger[data-current-mode="dark"] .theme-menu-ticon[data-icon="dark"],
            .theme-menu-trigger[data-current-mode="auto"] .theme-menu-ticon[data-icon="auto"] {
                display: block;
            }
            .theme-menu-trigger svg,
            .theme-menu-item svg {
                width: 16px;
                height: 16px;
                display: block;
            }
            .theme-menu-popover {
                position: absolute;
                top: calc(100% + 8px);
                right: 0;
                display: flex;
                flex-direction: column;
                gap: 2px;
                min-width: 152px;
                padding: 6px;
                background: var(--xp-bg-elevated);
                border: 1px solid var(--xp-border);
                border-radius: 10px;
                box-shadow: 0 10px 34px rgba(0, 0, 0, 0.45);
                z-index: 60;
            }
            .theme-menu-popover[hidden] {
                display: none;
            }
            .theme-menu-item {
                appearance: none;
                -webkit-appearance: none;
                background: transparent;
                border: none;
                cursor: pointer;
                display: flex;
                align-items: center;
                gap: 9px;
                width: 100%;
                padding: 7px 10px;
                color: var(--xp-text-secondary);
                font-family: var(--xp-font-body);
                font-size: 0.82rem;
                text-align: left;
                border-radius: 7px;
                transition:
                    background-color var(--xp-duration-fast)
                        var(--xp-easing-standard),
                    color var(--xp-duration-fast) var(--xp-easing-standard);
            }
            .theme-menu-iicon {
                line-height: 0;
            }
            .theme-menu-item:hover {
                background: var(--xp-bg-surface);
                color: var(--xp-text-primary);
            }
            .theme-menu-item:focus-visible {
                outline: 2px solid var(--xp-accent);
                outline-offset: -2px;
            }
            .theme-menu-item[aria-checked="true"] {
                color: var(--xp-accent);
            }

            /* === Scroll Animations === */
            .sr {
                opacity: 0;
                transform: translateY(30px);
                transition:
                    opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1),
                    transform 0.8s cubic-bezier(0.16, 1, 0.3, 1);
            }
            .sr.visible {
                opacity: 1;
                transform: translateY(0);
            }
            .sr-d1 {
                transition-delay: 0.1s;
            }
            .sr-d2 {
                transition-delay: 0.2s;
            }
            .sr-d3 {
                transition-delay: 0.3s;
            }
            .sr-d4 {
                transition-delay: 0.4s;
            }

            /* === Ambient Background === */
            .ambient {
                position: fixed;
                inset: 0;
                pointer-events: none;
                z-index: 0;
                overflow: hidden;
            }
            .ambient-glow {
                position: absolute;
                width: 900px;
                height: 900px;
                top: -350px;
                left: 50%;
                transform: translateX(-50%);
                background: radial-gradient(
                    circle,
                    var(--xp-accent-glow) 0%,
                    transparent 70%
                );
                animation: glow-pulse 8s ease-in-out infinite alternate;
            }
            @keyframes glow-pulse {
                0% {
                    opacity: 0.4;
                    transform: translateX(-50%) scale(1);
                }
                100% {
                    opacity: 0.7;
                    transform: translateX(-50%) scale(1.15);
                }
            }
            .ambient-grid {
                position: absolute;
                inset: 0;
                background-image:
                    linear-gradient(
                        rgba(59, 130, 246, 0.03) 1px,
                        transparent 1px
                    ),
                    linear-gradient(
                        90deg,
                        rgba(59, 130, 246, 0.03) 1px,
                        transparent 1px
                    );
                background-size: 60px 60px;
                mask-image: radial-gradient(
                    ellipse 60% 50% at 50% 0%,
                    black 0%,
                    transparent 100%
                );
                -webkit-mask-image: radial-gradient(
                    ellipse 60% 50% at 50% 0%,
                    black 0%,
                    transparent 100%
                );
            }

            /* === Section Common === */
            .section {
                position: relative;
                z-index: 1;
                padding: 8rem 2rem;
                max-width: 1200px;
                margin: 0 auto;
            }
            /* ============================================================
               SECTION TITLES — single source of truth for every section's
               eyebrow + main title, across all pages (modelled on the
               "Lost in translation" section). Pair: .section-label (eyebrow)
               + .section-heading (main title).

               MODIFIERS (mix and match):
                 Eyebrow colour/style
                   .section-label-gold / .section-label--amber  amber eyebrow
                   .section-label--project   grey, wider-tracked, heading-font
                                             eyebrow (project/case-study pages)
                 Alignment (any section, any page — opt in per element)
                   .is-center   centre the label/title
                   .is-left     left-align the label/title
                   (default: inherit the section's own text-align)
                 Main-title trailing accent
                   <strong> or <em> inside .section-heading wraps the trailing
                   text (2nd sentence, or text after a comma). Coloured blue by
                   default; .section-heading--amber makes it amber (project pages).
                 Size
                   .section-heading--compact   smaller title (project pages)
                 Special
                   .section-heading--gradient  animated rainbow shimmer
                                               (currently platform Perception)
               ============================================================ */
            .section-label {
                font-family: var(--xp-font-mono);
                font-size: 0.7rem;
                color: var(--xp-accent);
                text-transform: uppercase;
                letter-spacing: 0.14em;
                margin: 0 0 1.5rem;
                opacity: 0.8;
                text-align: inherit;
            }
            
            .section-label--amber {
                color: var(--xp-amber);
                opacity: 0.9;
            }
            /* Project / case-study eyebrow: grey, wider tracking, heading font
               (the /hip-hop-experience look). Left-aligned by inheritance. */
            .section-label--project {
                font-family: var(--xp-font-heading);
                font-size: 0.75rem;
                letter-spacing: 0.28em;
                color: var(--xp-text-subtle);
                opacity: 1;
            }
            .section-heading {
                font-size: clamp(2.2rem, 5vw, 3.5rem);
                font-weight: 700;
                line-height: 1.15;
                margin: 0 0 1.25rem;
                color: var(--xp-text-primary);
                text-wrap: balance;
                text-align: inherit;
            }
            /* Trailing accent: the 2nd sentence / post-comma phrase, wrapped in
               <strong> or <em> (both in the canon-gate strip-list, so canonical
               prose stays intact). Blue by default; weight/style neutralised so
               only the colour changes. */
            .section-heading strong,
            .section-heading em {
                color: var(--xp-accent);
                font-weight: inherit;
                font-style: normal;
            }
            /* Project pages: trailing accent is amber, not blue. */
            .section-heading--amber strong,
            .section-heading--amber em {
                color: var(--xp-amber);
            }
            /* Smaller title for project/case-study pages. */
            .section-heading--compact {
                font-size: clamp(1.75rem, 3.4vw, 2.75rem);
                letter-spacing: -0.028em;
                line-height: 1.2;
            }
            /* Alignment options — opt in per element on any section/page. */
            .section-label.is-center { text-align: center; }
            .section-label.is-left { text-align: left; }
            /* No max-width cap: a single sentence stays on one line when it fits
               its section container; only genuinely long titles wrap. */
            .section-heading.is-center { text-align: center; margin-inline: auto; }
            .section-heading.is-left { text-align: left; margin-inline: 0; }
            /* Two-sentence titles: keep each sentence on its own line. The leading
               sentence is wrapped in <strong>; making it a block pushes the
               trailing sentence onto the next line, so the break lands on the
               sentence boundary instead of text-wrap:balance breaking mid-sentence.
               Each sentence still stays on ONE line when it fits (only wraps within
               itself if a single sentence is too long) — so the cap is lifted to let
               them use the section's full width. Opt in with .section-heading--lines
               on genuine two-sentence titles, NOT comma clauses (those wrap normally).
               WORD-COUNT RULE: only apply --lines when at least one sentence is 4+
               words. If BOTH sentences are 3 words or fewer (e.g. "Every space. One
               XDL."), omit --lines so they render together on one line. */
            .section-heading--lines :is(strong, em) { display: block; }
            .section-heading--lines.is-center { max-width: none; }
            /* Special: animated rainbow shimmer (opt-in). Keyframes
               `perception-shimmer` are defined with the Perception section. */
            .section-heading--gradient {
                background: linear-gradient(
                    90deg,
                    #fbbf24 0%,
                    var(--xp-orange) 30%,
                    #ec4899 60%,
                    #a855f7 100%
                );
                background-size: 200% 100%;
                -webkit-background-clip: text;
                background-clip: text;
                -webkit-text-fill-color: transparent;
                color: transparent;
                animation: perception-shimmer 8s ease-in-out infinite alternate;
                line-height: 1.25;
                padding-bottom: 0.12em;
            }
            .section-sub {
                font-size: clamp(1rem, 2.5vw, 1.15rem);
                color: var(--xp-text-secondary);
                line-height: 1.7;
                max-width: 640px;
            }

            /* Section tagline — the short "resolution beat" line under a title
               (e.g. "Hard to capture. Hard to cost…"). Graduates grey→white
               left→right; the box hugs its text (width: fit-content) so it stays
               on ONE line when it fits and the gradient end-stop lands on the last
               word. Centred by default; add .is-left to left-align. Distinct from
               .section-sub (the longer, multi-line section description, which must
               NOT use the single-line gradient). */
            .section-tagline {
                font-size: 1.15rem;
                line-height: 1.6;
                width: fit-content;
                max-width: 100%;
                margin: 0 auto 3rem;
                background: linear-gradient(90deg, var(--xp-text-secondary), var(--xp-text-primary));
                -webkit-background-clip: text;
                background-clip: text;
                color: transparent;
            }
            .section-tagline.is-left { margin-inline: 0; }

            /* Terminal-comment line — a "# …" label rendered in the XDL terminal
               font (JetBrains Mono), e.g. the footer's "# Install. Design. Build.
               Experience.". Font-family only, so it composes with any size/colour.
               NOTE: CSS can't detect the literal "# " in text, so apply this class
               to the element that holds the "# …" line (or wrap that run). The
               auto-wrapper in Layout.astro adds it to any [data-term] container's
               "# …" text at load. */
            .xdl-term { font-family: var(--xp-font-mono, 'JetBrains Mono', monospace); }

            /* Graduated text theme (JS, app.js): once segmented, each sentence
               steps in weight (thin → heavy) and lightness (dim → bright). Drop
               the continuous colour-clip fallback so the per-segment colours show. */
            .is-graduated {
                background: none;
                -webkit-text-fill-color: initial;
                color: var(--xp-text-secondary);
            }
            .grad-seg {
                font-family: var(--xp-font-heading, 'Outfit', sans-serif);
                white-space: nowrap;
            }

            /* /platform intro lead (Phase 2 D-09) — a prominent centred lead
               statement that frames the page above the first migrated
               capability section. Clears the fixed nav; the first .section
               below supplies the separating gap via its own 8rem top padding.
               The canon-bound pain-framing is the page's hook, so it reads as
               an intentional lead — not muted fine print. */
            .platform-intro {
                position: relative;
                z-index: 1;
                max-width: 920px;
                margin: 0 auto;
                /* Vertically centred in its full-viewport section (symmetric
                   padding clears the fixed nav top + bottom). */
                min-height: 100vh;
                display: flex;
                flex-direction: column;
                justify-content: center;
                align-items: center;
                padding: 6rem 2rem;
                text-align: center;
            }
            /* Soft accent glow behind the opening thesis. */
            .platform-intro::before {
                content: "";
                position: absolute;
                top: 38%;
                left: 50%;
                width: min(680px, 90%);
                height: 420px;
                transform: translate(-50%, -50%);
                background: radial-gradient(
                    ellipse at center,
                    color-mix(in srgb, var(--xp-accent) 11%, transparent),
                    transparent 70%
                );
                pointer-events: none;
                z-index: -1;
            }
            /* The first principle (P001), sourced from the Manifesto and laid out
               as eyebrow → hook → calmer beats → link, so the thesis lands
               without one wall of text. */
            /* Eyebrow → a labelled chip with a glowing status dot. */
            .pi-eyebrow {
                display: inline-flex;
                align-items: center;
                gap: 0.55rem;
                align-self: center;
                font-family: var(--xp-font-mono, 'JetBrains Mono', monospace);
                font-size: 0.7rem;
                letter-spacing: 0.18em;
                text-transform: uppercase;
                color: var(--xp-accent);
                margin: 0 0 1.9rem;
                padding: 0.42rem 0.9rem;
                border: 1px solid color-mix(in srgb, var(--xp-accent) 28%, var(--xp-border));
                border-radius: 999px;
                background: color-mix(in srgb, var(--xp-accent) 7%, transparent);
            }
            .pi-eyebrow::before {
                content: "";
                width: 6px;
                height: 6px;
                border-radius: 50%;
                background: var(--xp-accent);
                box-shadow: 0 0 8px var(--xp-accent);
            }
            /* Thesis title — same size + weight as the section headings. */
            .pi-title {
                font-family: var(--xp-font-heading);
                /* Sized to sit on ONE line within the intro container. */
                font-size: clamp(1.5rem, 3vw, 2.8rem);
                font-weight: 700;
                line-height: 1.15;
                letter-spacing: -0.015em;
                color: var(--xp-text-primary);
                white-space: nowrap;
                max-width: none;
                margin: 0 auto;
            }
            /* Mobile: the one-line nowrap sizing collapses to the clamp floor
               (24px) — wrap normally instead at the shared section-heading
               size so the thesis title matches the other headings. */
            @media (max-width: 860px) {
                .pi-title {
                    white-space: normal;
                    font-size: clamp(2.2rem, 5vw, 3.5rem);
                    text-wrap: balance;
                }
            }
            /* Second sentence — blue, set apart from the title with breathing room. */
            .pi-lead {
                font-family: var(--xp-font-heading);
                font-size: clamp(1.25rem, 2.6vw, 1.7rem);
                font-weight: 400;
                line-height: 1.4;
                color: var(--xp-accent);
                text-wrap: balance;
                max-width: 760px;
                margin: 1.75rem auto 0;
            }
            /* Glowing accent divider between the thesis block and the beats. */
            .pi-lead::after {
                content: "";
                display: block;
                width: 52px;
                height: 2px;
                margin: 2rem auto 0;
                border-radius: 2px;
                background: linear-gradient(90deg, transparent, var(--xp-accent), transparent);
                box-shadow: 0 0 14px -2px var(--xp-accent);
            }
            .pi-body {
                font-size: 1.15rem;
                line-height: 1.75;
                color: var(--xp-text-secondary);
                max-width: 720px;
                margin: 1.5rem auto 0;
                text-wrap: pretty;
            }
            .pi-body:first-of-type {
                margin-top: 1.9rem;
            }
            /* Inline commands/code render in the terminal (mono) font. */
            .platform-intro code {
                font-family: var(--xp-font-mono, 'JetBrains Mono', monospace);
                font-size: 0.88em;
                color: var(--xp-accent);
                background: color-mix(in srgb, var(--xp-accent) 8%, transparent);
                border: 1px solid color-mix(in srgb, var(--xp-accent) 18%, var(--xp-border));
                border-radius: 5px;
                padding: 0.08em 0.4em;
                /* Wrap at word boundaries when the command is long; clone the
                   pill decoration so each wrapped fragment keeps its border. */
                white-space: normal;
                -webkit-box-decoration-break: clone;
                box-decoration-break: clone;
            }
            /* CTA → a subtle ghost-pill that lifts on hover. */
            .pi-link {
                display: inline-flex;
                align-items: center;
                gap: 0.5rem;
                align-self: center;
                margin-top: 2.6rem;
                font-family: var(--xp-font-mono, 'JetBrains Mono', monospace);
                font-size: 0.76rem;
                letter-spacing: 0.1em;
                text-transform: uppercase;
                color: var(--xp-accent);
                text-decoration: none;
                padding: 0.72rem 1.5rem;
                border: 1px solid color-mix(in srgb, var(--xp-accent) 32%, transparent);
                border-radius: 999px;
                background: color-mix(in srgb, var(--xp-accent) 6%, transparent);
                transition: color 0.2s ease, border-color 0.2s ease,
                    background 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
            }
            .pi-link:hover {
                color: var(--xp-accent-hover, #2563eb);
                border-color: var(--xp-accent);
                background: color-mix(in srgb, var(--xp-accent) 13%, transparent);
                transform: translateY(-1px);
                box-shadow: 0 10px 28px -12px var(--xp-accent);
            }

            /* /about stub (Phase 2 D-12) — minimal interim shell; Phase 4
               authors the real story. Centre the placeholder and give the page
               vertical presence so the stub reads as intentional, not broken,
               while it awaits content. */
            .about-stub {
                position: relative;
                z-index: 1;
                min-height: 60vh;
                max-width: 640px;
                margin: 0 auto;
                padding: 10rem 2rem 6rem;
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                text-align: center;
            }
            .about-stub p {
                font-size: clamp(1.1rem, 2.5vw, 1.35rem);
                line-height: 1.6;
                color: var(--xp-text-secondary);
                text-wrap: balance;
                margin: 0;
            }

            /* === Hero === */
            .hero {
                position: relative;
                z-index: 1;
                min-height: 100vh;
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                text-align: center;
                padding: 8rem 2rem 6rem;
            }
            .hero-badge {
                display: inline-flex;
                align-items: center;
                gap: 8px;
                padding: 6px 16px;
                border: 1px solid var(--xp-border);
                border-radius: 999px;
                font-family: var(--xp-font-mono);
                font-size: 0.75rem;
                color: var(--xp-text-secondary);
                margin-bottom: 2rem;
                background: color-mix(in srgb, var(--xp-bg-surface) 72%, transparent);
                backdrop-filter: blur(8px);
            }
            .hero-badge .dot {
                width: 6px;
                height: 6px;
                border-radius: 50%;
                background: var(--xp-green);
                animation: dot-blink 2s ease-in-out infinite;
            }
            @keyframes dot-blink {
                0%,
                100% {
                    opacity: 1;
                }
                50% {
                    opacity: 0.3;
                }
            }
            .hero-logo {
                width: clamp(56px, 12vw, 80px);
                height: auto;
                margin-bottom: 1.5rem;
                transition: transform 0.4s ease;
            }
            .hero-logo:hover {
                transform: scale(1.08) rotate(3deg);
            }
            .hero h1 {
                font-size: clamp(3rem, 8vw, 5.5rem);
                font-weight: 700;
                letter-spacing: -0.04em;
                line-height: 1;
                margin-bottom: 0.3em;
            }
            .hero h1 .light {
                font-weight: 300;
            }
            .hero h1 .xp {
                color: var(--xp-accent);
            }
            .hero-tagline {
                font-family: var(--xp-font-heading);
                font-size: clamp(1.1rem, 3vw, 1.5rem);
                color: var(--xp-text-primary);
                font-weight: 200;
                letter-spacing: 0.12em;
                text-transform: uppercase;
                margin-bottom: 1.5rem;
                min-height: 1.6em;
                transition: opacity 0.8s ease;
            }
            .hero-sub {
                font-size: clamp(1rem, 2.5vw, 1.15rem);
                color: var(--xp-text-secondary);
                line-height: 1.7;
                max-width: 600px;
                margin: 0 auto 2.5rem;
            }
            .hero-ctas {
                display: flex;
                gap: 1rem;
                flex-wrap: wrap;
                justify-content: center;
            }
            .btn {
                display: inline-flex;
                align-items: center;
                gap: 8px;
                padding: 14px 28px;
                border-radius: 10px;
                font-family: var(--xp-font-heading);
                font-size: 0.95rem;
                font-weight: 600;
                text-decoration: none;
                transition: all 0.25s;
                cursor: pointer;
            }
            .btn-primary {
                background: var(--xp-accent);
                color: #fff;
                border: 1px solid var(--xp-accent);
            }
            .btn-primary:hover {
                background: var(--xp-accent-hover);
                box-shadow: 0 0 30px rgba(59, 130, 246, 0.3);
                color: #fff;
            }
            .btn-ghost {
                background: transparent;
                color: var(--xp-text-primary);
                border: 1px solid var(--xp-border);
            }
            .btn-ghost:hover {
                border-color: rgba(59, 130, 246, 0.4);
                color: var(--xp-text-primary);
            }
            /* Shared "advance to next section" control. Auto-injected below the
               hero and every section on every page by Layout.astro; clicking it
               smooth-scrolls to the next section, which scroll-snap then centres.
               Slightly bigger + slightly higher than the old hero scroll cue. */
            /* Shared scroll-down cue, auto-injected below every section. Styled
               after the Creative-Drift hand-off arrow: a clean line+chevron that
               bobs and fades, tinted to the section it sits in (each section sets
               --section-advance-color below; amber is the default). */
            .section-advance {
                /* One shared cue, fixed to the viewport so it sits at the SAME
                   easy-to-see height on every section (a good gap above the
                   bottom), regardless of how tall the section is. app.js retints
                   it (--section-advance-color) and retargets it per active
                   section, and hides it on the last one. */
                position: fixed;
                bottom: 2.75rem;
                left: 50%;
                transform: translateX(-50%);
                z-index: 30;
                display: inline-flex;
                align-items: center;
                justify-content: center;
                width: 46px;
                height: 46px;
                padding: 0;
                border: 0;
                border-radius: 999px;
                background: transparent;
                color: var(--section-advance-color, var(--xp-orange));
                cursor: pointer;
                -webkit-appearance: none;
                appearance: none;
                transition: background 0.2s ease, box-shadow 0.2s ease, color 0.3s ease;
            }
            .section-advance[hidden] { display: none; }
            .section-advance svg {
                width: 28px;
                height: 32px;
                animation: sectionAdvanceBob 2.8s ease-in-out infinite;
                transition: transform 0.2s ease;
            }
            /* Hover / focus: a circular highlight + soft glow (in the section's
               colour) so the cue plainly reads as clickable. */
            .section-advance:hover,
            .section-advance:focus-visible {
                background: color-mix(in srgb, var(--section-advance-color, var(--xp-orange)) 14%, transparent);
                box-shadow: 0 0 0 1px color-mix(in srgb, var(--section-advance-color, var(--xp-orange)) 32%, transparent),
                            0 0 22px color-mix(in srgb, var(--section-advance-color, var(--xp-orange)) 30%, transparent);
            }
            .section-advance:hover svg,
            .section-advance:focus-visible svg {
                animation-play-state: paused;
                opacity: 1;
                transform: translateY(2px);
            }
            @keyframes sectionAdvanceBob {
                0%, 100% { transform: translateY(0);   opacity: 0.55; }
                50%      { transform: translateY(5px);  opacity: 1; }
            }
            @media (prefers-reduced-motion: reduce) {
                .section-advance svg { animation: none; opacity: 0.8; }
            }

            /* === XDL Section === */
            .xdl-section {
                padding-top: 3rem;
                padding-bottom: 3rem;
            }
            /* Anchor the intro as a sticky header pinned directly above the box
               groups (which reserve its height via padding-top), so it stays
               visible above whichever 4-box group is in view. */
            .xdl-section > .sr {
                position: sticky;
                top: 96px;
                z-index: 4;
                padding-bottom: 0.25rem;
                background: linear-gradient(to bottom, var(--xp-bg) 0%, var(--xp-bg) 72%, transparent 100%);
            }
            .xdl-split {
                display: grid;
                /* Narrower feature column, wider code window (was 1fr 1.4fr,
                   then 1fr 2fr) so gallery-walk.xdl has more room and wraps
                   less. */
                grid-template-columns: 1fr 2.5fr;
                gap: 1.5rem;
                margin-top: 0;
                align-items: start;
            }
            /* Two snap groups — each a viewport tall, its 4 cards vertically
               centred, so it snaps into place on its own. */
            .xdl-feature-groups {
                display: flex;
                flex-direction: column;
            }
            .xdl-feature-group {
                min-height: 100vh;
                box-sizing: border-box;
                /* Reserve the sticky intro's height at the top so the 4 boxes
                   centre in the space directly below the anchored intro header. */
                padding-top: var(--xdl-intro-h, 11rem);
                display: flex;
                flex-direction: column;
                justify-content: center;
                gap: 1.5rem;
                scroll-snap-align: center;
            }
            /* All four boxes in a group share one height (and, since both groups
               are a viewport tall, every box on the left matches). Content is
               vertically centred within each equal-height box. */
            .xdl-feature-group .xdl-feature {
                flex: 1 1 0;
                /* Cap the stack below the viewport so the four boxes stay a compact
                   block that justify-content can actually centre (with real margins),
                   rather than growing to fill the whole group edge-to-edge. */
                max-height: min(180px, calc((85vh - 4.5rem - var(--xdl-intro-h, 11rem)) / 4));
                align-items: center;
            }
            /* The XDL section itself no longer snaps as one unit — its two inner
               groups are the snap points instead. */
            section[id].xdl-section {
                scroll-snap-align: none;
            }
            /* Code window sticks beside the groups and scrolls internally (driven
               by app.js) so the highlighted lines align with the hovered box. */
            .xdl-code-sticky {
                position: sticky;
                align-self: start;
                /* Match the snapped 4-box stack: same height, vertically centred so
                   the window's top aligns with the first box and its bottom with the
                   fourth. --xdl-stack-h is measured in app.js (the stack height is
                   content/flex-driven); falls back to a viewport-ish height. */
                height: var(--xdl-stack-h, calc(100vh - 160px));
                top: calc((100vh + var(--xdl-intro-h, 11rem) - var(--xdl-stack-h, calc(100vh - 160px))) / 2);
                /* Start the window at the same centred offset as the boxes, so its
                   top lines up with the first box even before it sticks. */
                margin-top: calc((100vh + var(--xdl-intro-h, 11rem) - var(--xdl-stack-h, calc(100vh - 160px))) / 2);
            }
            .xdl-code-sticky .xdl-code {
                display: flex;
                flex-direction: column;
                height: 100%;
            }
            .xdl-code-sticky .xdl-code-body {
                position: relative;
                flex: 1 1 auto;
                overflow: hidden;
                scroll-behavior: smooth;
            }
            /* Per-box mini code snippet (mobile only) — injected by
               xdl-interact.js below each feature box, showing just that box's
               data-hl lines from gallery-walk.xdl. Hidden on desktop, where the
               sticky code window carries the highlighting instead. */
            .xdl-mini-snippet {
                display: none;
            }
            .xdl-mini-snippet:hover {
                transform: none;
            }
            .xdl-mini-snippet .xdl-code-body {
                padding: 0.8rem 1rem;
                font-size: 0.74rem;
            }
            /* Mobile / narrow: drop the two-viewport snap layout — boxes stack
               one at a time, each with its own mini code snippet below; the big
               code window is hidden once the minis are injected. */
            @media (max-width: 900px) {
                /* Intro flows normally — no sticky header hovering over boxes,
                   and no reserved padding gap before each group. */
                .xdl-section > .sr {
                    position: static;
                    padding-bottom: 0;
                    background: none;
                }
                .xdl-feature-group {
                    min-height: 0;
                    scroll-snap-align: none;
                    display: flex;
                    padding-top: 0;
                    gap: 1.25rem;
                }
                .xdl-feature-group .xdl-feature {
                    flex: initial;
                    max-height: none;
                }
                .xdl-mini-snippet {
                    display: block;
                    margin: -0.5rem 0 0.5rem;
                }
                .xdl-section.has-mini-snippets .xdl-code-sticky {
                    display: none;
                }
                .xdl-code-sticky {
                    position: static;
                    height: auto;
                    margin-top: 0;
                }
                .xdl-code-sticky .xdl-code-body {
                    overflow-x: auto;
                }
            }
            .xdl-feature {
                display: flex;
                gap: 12px;
                align-items: flex-start;
                padding: 1rem 1.25rem;
                border-radius: 10px;
                border: 1px solid transparent;
                transition:
                    border-color 0.3s,
                    background 0.3s;
            }
            .xdl-feature:hover {
                border-color: var(--xp-border);
                background: rgba(13, 13, 18, 0.5);
            }
            .xdl-feature-icon {
                width: 36px;
                height: 36px;
                flex-shrink: 0;
                display: flex;
                align-items: center;
                justify-content: center;
                border-radius: 8px;
                font-size: 1.1rem;
                /* Hue supplied per-card via inline --icon-hue. Dark mode: faint
                   tinted tile + hue glyph (the original rgba(hue,0.1) look).
                   Light mode flips to a dark tile + light glyph — see override
                   block item (13). */
                background: color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 12%, transparent);
                color: var(--icon-hue, var(--xp-accent));
            }
            .xdl-feature h3 {
                font-size: 1.4rem;
                font-weight: 600;
                margin-bottom: 6px;
                line-height: 1.2;
                text-wrap: balance;
            }
            .xdl-feature p {
                font-size: 1rem;
                color: var(--xp-text-secondary);
                line-height: 1.55;
            }
            .xdl-feature.breathing {
                animation: breathe 4s ease-in-out infinite;
            }
            .xdl-feature.breathing .xdl-feature-icon {
                animation: breathe-glow 4s ease-in-out infinite;
            }
            @keyframes breathe {
                0%, 100% { transform: scale(1); }
                50%      { transform: scale(1.015); }
            }
            @keyframes breathe-glow {
                0%, 100% {
                    box-shadow: 0 0 0 0 rgba(249, 115, 22, 0);
                }
                50% {
                    box-shadow:
                        0 0 16px rgba(249, 115, 22, 0.15),
                        0 0 40px rgba(249, 115, 22, 0.06);
                }
            }

            /* ============================================================
               The 8 shared XDL cards, brought to life. Two layers:
                 • .xdl-feature[data-card]      — hover life that applies in BOTH
                   the homepage deck grid AND the /platform column (per-card
                   flourishes, hue hover accent, hairline, lift). /platform keeps
                   its own format/structure; only the hover behaviour is added.
                 • .xdl-deck-cards .xdl-feature — homepage-only 2×4 grid layout,
                   readable type, and the one idle (feel) glow.
               In global CSS because Astro scoped styles can't reach a child
               component. Each card's hue is --icon-hue (set on the card).
               ============================================================ */

            /* ---- Shared hover life (homepage + /platform) ---- */
            .xdl-feature[data-card] {
                position: relative;
                overflow: hidden;
                transition: transform 0.35s cubic-bezier(.2,.7,.2,1),
                    border-color 0.35s ease, background 0.35s ease, box-shadow 0.35s ease;
            }
            .xdl-feature[data-card] .xdl-feature-icon { position: relative; }
            .xdl-feature[data-card] h3 { transition: color 0.3s ease; }
            .xdl-feature[data-card]:hover {
                transform: translateY(-4px);
                border-color: color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 55%, var(--xp-border));
                box-shadow: 0 16px 40px -22px color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 65%, transparent);
            }
            .xdl-feature[data-card]:hover h3 {
                color: color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 70%, var(--xp-text-primary));
            }
            /* Deep-link target (arrived via /platform#xdl-<key>): the selected box
               wears a hue ring + glow so it's obvious which one was clicked, and
               its top hairline stays drawn. Cleared on the next hover. */
            .xdl-feature[data-card].is-target {
                border-color: color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 55%, var(--xp-border));
                box-shadow:
                    0 0 0 1px color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 55%, transparent),
                    0 16px 40px -22px color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 65%, transparent);
            }
            .xdl-feature[data-card].is-target h3 {
                color: color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 70%, var(--xp-text-primary));
            }
            .xdl-feature[data-card].is-target::before { transform: scaleX(1); }
            /* Hue hairline wipes across the top on hover. */
            .xdl-feature[data-card]::before {
                content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px;
                background: linear-gradient(90deg, transparent, var(--icon-hue, var(--xp-accent)), transparent);
                transform: scaleX(0); transform-origin: left;
                transition: transform 0.5s cubic-bezier(.2,.7,.2,1);
            }
            .xdl-feature[data-card]:hover::before { transform: scaleX(1); }

            /* Industry Open Standard — one shared spec (the hub) that the whole
               industry connects to. On hover the adopter nodes ripple outward
               from the centre: the standard spreading. */
            .xdl-feature[data-card="open"] .xf-network { width: 1.35em; height: 1.35em; overflow: visible; }
            .xdl-feature[data-card="open"] .xf-node { transform-box: fill-box; transform-origin: center; }
            .xdl-feature[data-card="open"]:hover .xf-node { animation: xfAdopt 1.5s ease-out infinite; }
            .xdl-feature[data-card="open"]:hover .xf-network circle:nth-of-type(3) { animation-delay: 0.12s; }
            .xdl-feature[data-card="open"]:hover .xf-network circle:nth-of-type(4) { animation-delay: 0.24s; }
            .xdl-feature[data-card="open"]:hover .xf-network circle:nth-of-type(5) { animation-delay: 0.36s; }
            @keyframes xfAdopt {
                0%   { opacity: 0.35; transform: scale(0.65); }
                40%  { opacity: 1;    transform: scale(1.3); }
                100% { opacity: 0.35; transform: scale(0.65); }
            }

            /* Privacy, by design — a padlock. Closed at rest (privacy is the default);
               on hover the shackle gives a small "click" as it re-locks and the tile
               glows. Reads as privacy engaging, not a button press. */
            .xdl-feature[data-card="privacy"] .xf-lock {
                width: 1.3em; height: 1.3em; overflow: visible;
            }
            .xdl-feature[data-card="privacy"] .xf-lock-shackle {
                transform-origin: 12px 11px;
            }
            .xdl-feature[data-card="privacy"] .xdl-feature-icon {
                transition: box-shadow .4s ease;
            }
            .xdl-feature[data-card="privacy"]:hover .xf-lock-shackle {
                animation: xfLockClick 0.55s cubic-bezier(.2,.8,.2,1);
            }
            .xdl-feature[data-card="privacy"]:hover .xdl-feature-icon {
                box-shadow: 0 0 18px -2px color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 55%, transparent);
            }
            @keyframes xfLockClick {
                0%,100% { transform: translateY(0); }
                40%     { transform: translateY(-2.5px); }
            }

            /* Actors are first class — the cue: mark lifts, a spotlight blooms. */
            .xdl-feature[data-card="actors"]:hover .xdl-feature-icon { animation: xfCue 0.9s ease; }
            @keyframes xfCue { 0%{transform:translateY(0)} 35%{transform:translateY(-4px)} 65%{transform:translateY(-1px)} 100%{transform:translateY(0)} }
            .xdl-feature[data-card="actors"] .xdl-feature-icon::after {
                content:""; position:absolute; left:50%; top:50%; width:46px; height:46px;
                transform:translate(-50%,-50%) scale(0.5); border-radius:50%;
                background:radial-gradient(circle, color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 45%, transparent), transparent 70%);
                opacity:0; transition:opacity .4s ease, transform .5s ease; pointer-events:none;
            }
            .xdl-feature[data-card="actors"]:hover .xdl-feature-icon::after { opacity:1; transform:translate(-50%,-50%) scale(1.35); }

            /* AI agents as touchpoints — a small agent orbits the mark. */
            .xdl-feature[data-card="agents"] .xdl-feature-icon::after {
                content:""; position:absolute; top:50%; left:50%; width:5px; height:5px; border-radius:50%;
                background:var(--icon-hue, var(--xp-accent)); box-shadow:0 0 8px var(--icon-hue, var(--xp-accent));
                opacity:0; animation:xfOrbit 2.6s linear infinite; animation-play-state:paused;
            }
            .xdl-feature[data-card="agents"]:hover .xdl-feature-icon::after { opacity:1; animation-play-state:running; }
            @keyframes xfOrbit { from { transform: rotate(0) translateX(20px) rotate(0); } to { transform: rotate(360deg) translateX(20px) rotate(-360deg); } }

            /* Repeatable, by design — the repeat-loop icon cycles 360° on an
               exact, metronomic beat (same input → same turn, again and again),
               while a ring echoes out behind it on every loop. */
            .xdl-feature[data-card="repeatable"] .xf-repeat {
                width: 1.3em; height: 1.3em; transform-origin: 50% 50%;
            }
            .xdl-feature[data-card="repeatable"]:hover .xf-repeat {
                animation: xfLoop 1.4s cubic-bezier(.7,0,.3,1) infinite;
            }
            @keyframes xfLoop { from { transform: rotate(0); } to { transform: rotate(360deg); } }
            .xdl-feature[data-card="repeatable"] .xdl-feature-icon::after {
                content:""; position:absolute; inset:-3px; border-radius:9px;
                border:1.5px solid color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 60%, transparent);
                opacity:0; pointer-events:none;
            }
            .xdl-feature[data-card="repeatable"]:hover .xdl-feature-icon::after { animation: xfEcho 1.4s ease-out infinite; }
            @keyframes xfEcho { 0%{opacity:.8; transform:scale(1)} 100%{opacity:0; transform:scale(1.5)} }

            /* Safety policies built in — a physical EMERGENCY-STOP button.
               Green = systems running. On hover the button is "pressed": it
               depresses and the whole card flips RED ("STOP — everything halted").
               Move away and it springs back to green. This is a hover STATE
               (transitions both ways) and the deliberate press recoil is the point. */
            .xdl-feature[data-card="safety"] { --stop: var(--xp-red, #ef4444); }
            /* The top hairline wipes in red too (it defaults to the card hue = green). */
            .xdl-feature[data-card="safety"]::before {
                background: linear-gradient(90deg, transparent, var(--stop), transparent);
            }
            .xdl-feature[data-card="safety"] .xf-estop { width: 1.4em; height: 1.4em; overflow: visible; }
            .xdl-feature[data-card="safety"] .xf-estop-top {
                transition: transform .12s ease; transform-origin: 12px 12px;
            }
            /* The icon tile IS the button: raised + green at rest. */
            .xdl-feature[data-card="safety"] .xdl-feature-icon {
                transition: background .25s ease, color .2s ease, transform .12s ease, box-shadow .25s ease;
                box-shadow: 0 2px 0 color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 35%, transparent),
                            inset 0 1px 0 rgba(255,255,255,0.08);
            }
            /* Pressed state — depress + go red, card grounds (no lift) and reads STOP. */
            .xdl-feature[data-card="safety"]:hover {
                transform: none;
                border-color: color-mix(in srgb, var(--stop) 60%, var(--xp-border));
                box-shadow: 0 12px 34px -20px color-mix(in srgb, var(--stop) 70%, transparent);
            }
            .xdl-feature[data-card="safety"]:hover h3 {
                color: color-mix(in srgb, var(--stop) 75%, var(--xp-text-primary));
            }
            .xdl-feature[data-card="safety"]:hover .xdl-feature-icon {
                background: color-mix(in srgb, var(--stop) 22%, transparent);
                color: var(--stop);
                transform: translateY(2px);
                box-shadow: inset 0 3px 7px rgba(0,0,0,0.45);
            }
            .xdl-feature[data-card="safety"]:hover .xf-estop-top { transform: scale(0.84); }
            /* A red HALT ring snaps in — the button-press recoil is on-brand here. */
            .xdl-feature[data-card="safety"] .xdl-feature-icon::after {
                content:""; position:absolute; inset:-4px; border-radius:9px;
                border:2px solid var(--stop);
                opacity:0; transform:scale(1.3);
                transition: transform .22s cubic-bezier(.2,1.6,.35,1), opacity .18s ease;
            }
            .xdl-feature[data-card="safety"]:hover .xdl-feature-icon::after { opacity:1; transform:scale(1); }

            /* Accessible by design — the spoked wheel spins on hover. */
            .xdl-feature[data-card="accessibility"] .xf-wheel {
                display: block; width: 1.35em; height: 1.35em; transform-origin: 50% 50%;
            }
            .xdl-feature[data-card="accessibility"]:hover .xf-wheel { animation: xfSpin 1.4s linear infinite; }
            @keyframes xfSpin { from { transform: rotate(0); } to { transform: rotate(360deg); } }

            /* ---- Homepage-only: 2×4 grid layout, readable type, idle feel glow ---- */
            .xdl-deck-cards .xdl-feature {
                flex-direction: column;
                align-items: center;
                text-align: center;
                gap: 0.8rem;
                padding: 1.35rem 1.25rem;
                border-radius: 12px;
                border: 1px solid var(--xp-border);
                background: color-mix(in srgb, var(--xp-bg-surface) 55%, transparent);
            }
            /* Titles wear their card hue at rest (the colour the hover used),
               not plain white. */
            .xdl-deck-cards .xdl-feature h3 {
                color: color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 70%, var(--xp-text-primary));
            }
            .xdl-deck-cards .xdl-feature > div { width: 100%; }
            .xdl-deck-cards .xdl-feature:hover { background: color-mix(in srgb, var(--xp-bg-surface) 82%, transparent); }
            .xdl-deck-cards .xdl-feature-icon { width: 42px; height: 42px; font-size: 1.25rem; }

            /* Homepage deck: titles only. The sub-text lives on /platform#xdl, which
               you reach by clicking the card (each box is a link to its counterpart). */
            .xdl-deck-cards .xdl-feature p { display: none; }
            /* Whole card is a stretched link to its /platform#xdl-<key> box. */
            .xdl-deck-cards .xdl-feature { cursor: pointer; }
            .xdl-card-link {
                position: absolute; inset: 0; z-index: 4; border-radius: inherit;
                text-decoration: none;
            }
            .xdl-card-link:focus-visible {
                outline: 2px solid var(--xp-accent);
                outline-offset: 2px;
            }
            /* Box title + body inherit the global .xdl-feature sizes (h3 1.4rem,
               p 1rem) so they match the /platform#xdl boxes exactly. */
            /* Homepage drops the card breathe (the hover lift owns the motion); the
               feel card stays alive via the icon warmth glow. /platform keeps its
               own .breathing glow untouched. */
            .xdl-deck-cards .xdl-feature.breathing { animation: none; }
            .xdl-deck-cards [data-card="feel"] .xdl-feature-icon { animation: xfWarm 6s ease-in-out infinite; }
            @keyframes xfWarm {
                0%,100% { box-shadow: 0 0 0 0 transparent; }
                50% { box-shadow: 0 0 20px -2px color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 60%, transparent); }
            }
            /* On hover the "design for how people feel" box comes alive — a gentle
               breathe (the lift is held inside the keyframe so it stays raised while
               it pulses). Fits the card's emotional-resonance theme. */
            .xdl-deck-cards [data-card="feel"]:hover {
                animation: xfFeelBreathe 3.6s ease-in-out infinite;
            }
            @keyframes xfFeelBreathe {
                0%,100% { transform: translateY(-4px) scale(1); }
                50%     { transform: translateY(-4px) scale(1.025); }
            }

            @media (prefers-reduced-motion: reduce) {
                .xdl-feature[data-card],
                .xdl-feature[data-card]::before,
                .xdl-feature[data-card] .xdl-feature-icon,
                .xdl-feature[data-card] .xdl-feature-icon::after,
                .xdl-feature[data-card] .xf-wheel,
                .xdl-feature[data-card] .xf-lock,
                .xdl-feature[data-card] .xf-lock-shackle,
                .xdl-feature[data-card] .xf-estop,
                .xdl-feature[data-card] .xf-estop-top,
                .xdl-feature[data-card] .xf-repeat,
                .xdl-feature[data-card] .xf-network,
                .xdl-feature[data-card] .xf-node {
                    animation: none !important;
                    transition: none !important;
                }
                .xdl-feature[data-card]:hover { transform: none; }
                .xdl-feature[data-card="feel"]:hover { animation: none !important; }
                .xdl-feature[data-card="privacy"] .xf-lock-shackle { transform: none !important; }
            }

            /* XDL Code Block */
            .xdl-code {
                background: var(--xp-bg-surface);
                border: 1px solid var(--xp-border);
                border-radius: 12px;
                overflow: hidden;
                box-shadow:
                    0 4px 40px rgba(0, 0, 0, 0.4),
                    0 0 80px var(--xp-accent-glow);
                transition:
                    box-shadow 0.4s,
                    border-color 0.4s,
                    transform 0.4s;
            }
            .xdl-code:hover {
                transform: translateY(-2px);
                border-color: rgba(59, 130, 246, 0.25);
                box-shadow:
                    0 8px 60px rgba(0, 0, 0, 0.5),
                    0 0 120px var(--xp-accent-glow-strong);
            }
            .xdl-code-bar {
                display: flex;
                align-items: center;
                gap: 6px;
                padding: 12px 16px;
                border-bottom: 1px solid var(--xp-border);
            }
            .xdl-code-dot {
                width: 10px;
                height: 10px;
                border-radius: 50%;
                background: #2a2a2e;
            }
            .xdl-code-dot:nth-child(1) {
                background: #ff5f57;
            }
            .xdl-code-dot:nth-child(2) {
                background: #febc2e;
            }
            .xdl-code-dot:nth-child(3) {
                background: var(--xp-accent);
            }
            .xdl-code-filename {
                margin-left: auto;
                font-family: var(--xp-font-mono);
                font-size: 0.7rem;
                color: var(--xp-text-subtle);
            }
            .xdl-code-body {
                padding: 20px 24px;
                font-family: var(--xp-font-mono);
                font-size: 0.82rem;
                line-height: 1.8;
                overflow-x: auto;
                counter-reset: line;
            }
            .xdl-code-body .line {
                display: flex;
                gap: 0;
                transition: opacity 0.25s ease, background 0.25s ease;
                border-left: 2px solid transparent;
                padding-left: 4px;
                margin-left: -6px;
            }
            .xdl-code-body.dimming .line {
                opacity: 0.25;
            }
            .xdl-code-body .line.highlight {
                opacity: 1;
                background: rgba(59, 130, 246, 0.08);
                border-left-color: var(--xp-accent);
            }
            .perception-xdl {
                transition: opacity 0.25s ease, transform 0.25s ease;
            }
            .perception-xdl.flipping {
                opacity: 0;
                transform: translateY(4px);
            }
            .xdl-code-body .ln {
                display: none;
            }
            .xdl-code-body .code {
                /* Wrap long lines instead of overflowing into a horizontal
                   scroll, so the whole snippet reads in one viewport. pre-wrap
                   keeps the indentation; min-width:0 lets the flex child shrink
                   so wrapping actually engages. */
                white-space: pre-wrap;
                overflow-wrap: break-word;
                min-width: 0;
            }
            /* XDL syntax colors */
            .xk {
                color: var(--xp-accent);
            } /* keyword */
            .xs {
                color: #34d399;
            } /* string */
            .xc {
                color: #e3ebf7;
                opacity: 1;
                font-style: italic;
                font-weight: 500;
                text-shadow: 0 0 10px rgba(125, 170, 255, 0.4);
            } /* comment — marketing narration; kept bright + glowing in BOTH
                 themes (the code panel is a dark "screen" in light mode too).
                 Size unchanged to preserve monospace column alignment. */
            .xp {
                color: var(--xp-amber);
            } /* property */
            .xn {
                color: var(--xp-cyan);
            } /* number */
            .xt-s {
                color: var(--xp-green);
            } /* sensor type */
            .xt-o {
                color: var(--xp-purple);
            } /* output type */
            .xt-p {
                color: var(--xp-orange);
            } /* perception type */
            .xt-a {
                color: var(--xp-pink);
            } /* agent type */ /* default/punctuation */

            /* === Statement / Interstitial === */
            .statement {
                position: relative;
                z-index: 1;
                text-align: center;
                padding: 6rem 2rem;
                max-width: 800px;
                margin: 0 auto;
            }
            .statement-text {
                font-family: var(--xp-font-heading);
                font-size: clamp(1.3rem, 3.5vw, 2rem);
                font-weight: 300;
                font-style: italic;
                color: var(--xp-text-primary);
                line-height: 1.5;
                opacity: 0.7;
            }
            .statement-text em {
                font-style: normal;
                color: var(--xp-orange);
                font-weight: 400;
            }

            /* === Perception Section === */
            .perception-section {
                padding-top: 6rem;
                padding-bottom: 6rem;
                position: relative;
                /* Vertically centre the content within the 100vh section, to
                   match the neighbouring full-height home sections. */
                min-height: 100vh;
                display: flex;
                flex-direction: column;
                justify-content: center;
            }
            /* Slow drifting colour field — the section 'breathes'. Full-bleed:
               breaks out of the 1200px .section column to span the whole viewport
               width (body has overflow-x:hidden, so 100vw is safe). */
            .perception-section::before {
                content: "";
                position: absolute;
                top: 0;
                bottom: 0;
                left: 50%;
                width: 100vw;
                margin-left: -50vw;
                pointer-events: none;
                z-index: 0;
                background:
                    radial-gradient(46vw 420px at 18% 18%, rgba(249, 115, 22, 0.08), transparent 70%),
                    radial-gradient(40vw 420px at 82% 30%, rgba(236, 72, 153, 0.06), transparent 70%),
                    radial-gradient(44vw 460px at 50% 82%, rgba(124, 58, 237, 0.06), transparent 70%);
                animation: perception-drift 18s ease-in-out infinite alternate;
            }
            @keyframes perception-drift {
                0%   { transform: translate3d(0, 0, 0)    scale(1); opacity: 0.7; }
                50%  { transform: translate3d(-20px, 10px, 0) scale(1.05); opacity: 1; }
                100% { transform: translate3d(15px, -15px, 0) scale(1.08); opacity: 0.8; }
            }
            .perception-section > * { position: relative; z-index: 1; }

            /* Heading gets a gentle gradient shimmer */
            /* Perception heading shimmer now uses the shared
               .section-heading--gradient modifier (see the section-title block). */
            @keyframes perception-shimmer {
                0%   { background-position:   0% 50%; }
                100% { background-position: 100% 50%; }
            }

            .perception-grid {
                display: grid;
                grid-template-columns: repeat(3, 1fr);
                gap: 1.5rem;
                margin-top: 3rem;
            }
            .perception-card {
                padding: 2rem;
                border-radius: 12px;
                border: 1px solid var(--p-border, rgba(249, 115, 22, 0.15));
                background: var(--p-bg, rgba(249, 115, 22, 0.03));
                transition: all 0.4s ease;
                position: relative;
                overflow: hidden;
            }
            .perception-card::before {
                content: "";
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                height: 3px;
                background: var(--p-color, var(--xp-orange));
                opacity: 0.6;
                transition: opacity 0.3s, box-shadow 0.4s;
            }
            .perception-card:hover {
                border-color: var(--p-border-hover, rgba(249, 115, 22, 0.35));
                background: var(--p-bg-hover, rgba(249, 115, 22, 0.07));
                transform: translateY(-3px);
            }
            .perception-card:hover::before {
                opacity: 1;
                box-shadow: 0 0 16px var(--p-color, var(--xp-orange));
            }
            /* Homepage variant: the whole card is a link to its /platform box. */
            .perception-card-link {
                position: absolute; inset: 0; z-index: 3;
                border-radius: inherit; text-decoration: none;
            }
            .perception-card-link:focus-visible {
                outline: 2px solid var(--p-color, var(--xp-accent));
                outline-offset: 2px;
            }
            /* Deep-link target on /platform#perception-<sub>: the clicked box wears
               its perception colour as a ring + glow. Cleared on the next hover. */
            .perception-card.is-target {
                border-color: var(--p-border-hover, rgba(249, 115, 22, 0.35));
                background: var(--p-bg-hover, rgba(249, 115, 22, 0.07));
                box-shadow:
                    0 0 0 1px var(--p-color, var(--xp-accent)),
                    0 16px 44px -22px var(--p-color, var(--xp-accent));
            }
            .perception-card.is-target::before {
                opacity: 1;
                box-shadow: 0 0 16px var(--p-color, var(--xp-orange));
            }

            /* Per-perception colour tokens */
            .perception-card[data-perception="warmth"] {
                --p-color: #fbbf24;
                --p-border: rgba(251, 191, 36, 0.15);
                --p-border-hover: rgba(251, 191, 36, 0.35);
                --p-bg: rgba(251, 191, 36, 0.03);
                --p-bg-hover: rgba(251, 191, 36, 0.07);
            }
            .perception-card[data-perception="energy"] {
                --p-color: #f97316;
                --p-border: rgba(249, 115, 22, 0.15);
                --p-border-hover: rgba(249, 115, 22, 0.35);
                --p-bg: rgba(249, 115, 22, 0.03);
                --p-bg-hover: rgba(249, 115, 22, 0.07);
            }
            .perception-card[data-perception="tension"] {
                --p-color: #ef4444;
                --p-border: rgba(239, 68, 68, 0.15);
                --p-border-hover: rgba(239, 68, 68, 0.35);
                --p-bg: rgba(239, 68, 68, 0.03);
                --p-bg-hover: rgba(239, 68, 68, 0.07);
            }
            .perception-card[data-perception="calm"] {
                --p-color: #7c3aed;
                --p-border: rgba(124, 58, 237, 0.15);
                --p-border-hover: rgba(124, 58, 237, 0.35);
                --p-bg: rgba(124, 58, 237, 0.03);
                --p-bg-hover: rgba(124, 58, 237, 0.07);
            }
            .perception-card[data-perception="wonder"] {
                --p-color: #ec4899;
                --p-border: rgba(236, 72, 153, 0.15);
                --p-border-hover: rgba(236, 72, 153, 0.4);
                --p-bg: rgba(236, 72, 153, 0.03);
                --p-bg-hover: rgba(236, 72, 153, 0.07);
            }
            .perception-card[data-perception="presence"] {
                --p-color: #10b981;
                --p-border: rgba(16, 185, 129, 0.15);
                --p-border-hover: rgba(16, 185, 129, 0.35);
                --p-bg: rgba(16, 185, 129, 0.03);
                --p-bg-hover: rgba(16, 185, 129, 0.07);
            }

            .perception-card-orb {
                width: 44px;
                height: 44px;
                border-radius: 50%;
                background: radial-gradient(
                    circle,
                    var(--p-color, var(--xp-orange)) 0%,
                    transparent 75%
                );
                border: 1px solid var(--p-color, var(--xp-orange));
                display: flex;
                align-items: center;
                justify-content: center;
                margin-bottom: 1rem;
                color: var(--p-color, var(--xp-orange));
                font-size: 1.2rem;
                animation: orb-breathe 5s ease-in-out infinite;
                animation-delay: var(--p-delay, 0s);
            }
            @keyframes orb-breathe {
                0%, 100% {
                    box-shadow: 0 0 8px 0 var(--p-color, var(--xp-orange));
                    transform: scale(1);
                }
                50% {
                    box-shadow: 0 0 28px 4px var(--p-color, var(--xp-orange));
                    transform: scale(1.08);
                }
            }
            /* Each perception has its own breathing rhythm */
            .perception-card[data-perception="warmth"]  .perception-card-orb { animation-duration: 6s;   --p-delay: 0s;   }
            .perception-card[data-perception="energy"]  .perception-card-orb { animation-duration: 2.4s; --p-delay: 0.3s; }
            .perception-card[data-perception="tension"] .perception-card-orb { animation-duration: 3.2s; --p-delay: 1.1s; }
            .perception-card[data-perception="calm"]    .perception-card-orb { animation-duration: 7.5s; --p-delay: 2s;   }
            .perception-card[data-perception="wonder"]  .perception-card-orb { animation-duration: 4s;   --p-delay: 0.8s; }
            .perception-card[data-perception="presence"] .perception-card-orb { animation-duration: 5.5s; --p-delay: 1.5s; }

            .perception-card h3 {
                font-size: 1.1rem;
                font-weight: 600;
                margin-bottom: 0.5rem;
                color: var(--p-color, var(--xp-orange));
            }
            .perception-card p {
                font-size: 0.88rem;
                color: var(--xp-text-secondary);
                line-height: 1.6;
            }
            .perception-xdl {
                margin-top: 3rem;
                padding: 1.5rem 2rem;
                background: var(--xp-bg-surface);
                border: 1px solid var(--xp-border);
                border-radius: 10px;
                font-family: var(--xp-font-mono);
                font-size: 0.82rem;
                line-height: 1.8;
                color: var(--xp-text-subtle);
                overflow-x: auto;
            }
            /* Per-card mini terminals (mobile only) — injected by
               xdl-interact.js below each perception card with that card's
               snippet; the single cycling terminal is hidden there. Hidden on
               desktop, where the cycling terminal carries the snippets. */
            .perception-xdl-mini {
                display: none;
            }
            @media (max-width: 600px) {
                .perception-xdl-mini {
                    display: block;
                    margin: -0.75rem 0 0;
                    padding: 1.1rem 1.25rem;
                    font-size: 0.74rem;
                }
                .perception-section.has-perception-minis #perception-xdl {
                    display: none;
                }
                /* Compact card: orb + title stack on the LEFT, body text sits to
                   their RIGHT spanning both rows — halves the card height vs the
                   stacked desktop layout. The deep-link overlay (.perception-
                   card-link) is absolutely positioned, so the grid ignores it. */
                .perception-card {
                    display: grid;
                    grid-template-columns: auto 1fr;
                    grid-template-rows: auto auto;
                    column-gap: 1.1rem;
                    align-items: center;
                    align-content: center;
                    padding: 1.1rem 1.25rem;
                }
                .perception-card-orb {
                    grid-column: 1;
                    grid-row: 1;
                    margin: 0 auto 0.4rem;
                }
                .perception-card h3 {
                    grid-column: 1;
                    grid-row: 2;
                    margin: 0;
                    text-align: center;
                }
                .perception-card p {
                    grid-column: 2;
                    grid-row: 1 / span 2;
                    margin: 0;
                }
            }

            /* === Realms Section === */
            .realms-section {
                padding-top: 6rem;
                padding-bottom: 6rem;
            }
            /* Wider measure for the realms convergence intro (default
               .section-sub caps at 640px). Left-aligned to match the heading. */
            .realms-section .section-sub {
                max-width: 900px;
            }
            .realm-grid {
                display: grid;
                grid-template-columns: repeat(4, 1fr);
                gap: 1.25rem;
                margin-top: 3rem;
            }
            .realm-card {
                padding: 1.75rem 1.5rem;
                border-radius: 12px;
                border: 1px solid var(--r-border, rgba(59, 130, 246, 0.15));
                background: var(--r-bg, rgba(59, 130, 246, 0.03));
                transition: all 0.4s ease;
                position: relative;
                overflow: hidden;
                /* Column layout so the realm: keyword can be pushed to the
                   bottom (margin-top:auto) — keywords align across all cards
                   regardless of body length, while the text above stays top-
                   justified. */
                display: flex;
                flex-direction: column;
            }
            .realm-card::before {
                content: "";
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                height: 3px;
                background: var(--r-color, var(--xp-accent));
                opacity: 0.6;
                transition: opacity 0.3s, box-shadow 0.4s;
            }
            .realm-card:hover {
                border-color: var(--r-border-hover, rgba(59, 130, 246, 0.35));
                background: var(--r-bg-hover, rgba(59, 130, 246, 0.07));
                transform: translateY(-3px);
            }
            .realm-card:hover::before {
                opacity: 1;
                box-shadow: 0 0 16px var(--r-color, var(--xp-accent));
            }
            .realm-card[data-realm="physical"] {
                --r-color: #3b82f6;
                --r-border: rgba(59, 130, 246, 0.15);
                --r-border-hover: rgba(59, 130, 246, 0.35);
                --r-bg: rgba(59, 130, 246, 0.03);
                --r-bg-hover: rgba(59, 130, 246, 0.07);
            }
            .realm-card[data-realm="digital"] {
                --r-color: #06b6d4;
                --r-border: rgba(6, 182, 212, 0.15);
                --r-border-hover: rgba(6, 182, 212, 0.35);
                --r-bg: rgba(6, 182, 212, 0.03);
                --r-bg-hover: rgba(6, 182, 212, 0.07);
            }
            .realm-card[data-realm="augmented"] {
                --r-color: #a855f7;
                --r-border: rgba(168, 85, 247, 0.15);
                --r-border-hover: rgba(168, 85, 247, 0.35);
                --r-bg: rgba(168, 85, 247, 0.03);
                --r-bg-hover: rgba(168, 85, 247, 0.07);
            }
            .realm-card[data-realm="virtual"] {
                --r-color: #ec4899;
                --r-border: rgba(236, 72, 153, 0.15);
                --r-border-hover: rgba(236, 72, 153, 0.4);
                --r-bg: rgba(236, 72, 153, 0.03);
                --r-bg-hover: rgba(236, 72, 153, 0.07);
            }
            .realm-card-orb {
                width: 40px;
                height: 40px;
                border-radius: 50%;
                background: radial-gradient(
                    circle,
                    var(--r-color, var(--xp-accent)) 0%,
                    transparent 75%
                );
                border: 1px solid var(--r-color, var(--xp-accent));
                display: flex;
                align-items: center;
                justify-content: center;
                margin-bottom: 1rem;
                color: var(--r-color, var(--xp-accent));
                font-size: 1.1rem;
            }
            .realm-card h3 {
                font-size: 1.05rem;
                font-weight: 600;
                margin-bottom: 0.4rem;
                color: var(--r-color, var(--xp-accent));
            }
            .realm-card p {
                font-size: 0.85rem;
                color: var(--xp-text-secondary);
                line-height: 1.55;
                margin-bottom: 1rem;
            }
            .realm-card-keyword {
                display: inline-block;
                font-family: var(--xp-font-mono);
                font-size: 0.78rem;
                color: var(--xp-text-primary);
                background: rgba(0, 0, 0, 0.25);
                border: 1px solid var(--r-border, rgba(59, 130, 246, 0.18));
                border-radius: 4px;
                padding: 2px 8px;
                /* Pin to the bottom of the flex-column card + keep it hugging
                   the left edge (not stretched full-width). */
                margin-top: auto;
                align-self: flex-start;
            }
            .realm-split {
                display: grid;
                grid-template-columns: 3fr 2fr;
                gap: 2rem;
                margin-top: 3rem;
                align-items: start;
            }
            .realm-bullets {
                list-style: none;
                margin: 0;
                padding: 0;
                display: flex;
                flex-direction: column;
                gap: 1.25rem;
            }
            .realm-bullet {
                display: flex;
                gap: 1rem;
                align-items: flex-start;
                padding: 1.25rem 1.25rem;
                border-radius: 10px;
                border: 1px solid var(--xp-border);
                background: rgba(13, 13, 18, 0.5);
            }
            .realm-bullet-num {
                flex-shrink: 0;
                width: 28px;
                height: 28px;
                border-radius: 50%;
                background: rgba(59, 130, 246, 0.1);
                border: 1px solid rgba(59, 130, 246, 0.3);
                color: var(--xp-accent);
                font-family: var(--xp-font-mono);
                font-size: 0.85rem;
                font-weight: 600;
                display: flex;
                align-items: center;
                justify-content: center;
            }
            .realm-bullet p {
                font-size: 0.9rem;
                color: var(--xp-text-secondary);
                line-height: 1.6;
                margin: 0;
            }
            .realm-bullet p code {
                font-family: var(--xp-font-mono);
                font-size: 0.85em;
                color: var(--xp-text-primary);
                background: rgba(59, 130, 246, 0.08);
                border: 1px solid rgba(59, 130, 246, 0.2);
                border-radius: 4px;
                padding: 1px 5px;
            }
            /* festival-companion.xdl window: cap its height to the bullets
               column (measured in app.js → --realm-code-h) so the window bottom
               lines up with the last bullet (realm.transition). The capped body
               then has internal overflow, so the hover scroll-to-align in
               xdl-interact.js slides the code so the highlighted block lines up
               vertically with the hovered bullet. */
            .realm-split .xdl-code {
                display: flex;
                flex-direction: column;
                height: var(--realm-code-h, auto);
                max-height: var(--realm-code-h, none);
            }
            .realm-split .xdl-code-body {
                flex: 1 1 auto;
                overflow-y: hidden;
                scroll-behavior: smooth;
            }
            @media (max-width: 1024px) {
                .realm-grid {
                    grid-template-columns: 1fr;
                }
                .realm-split {
                    grid-template-columns: 1fr;
                }
            }
            /* Bullet minis sit inside .realm-split, where `.realm-split
               .xdl-code` (display:flex) would out-rank the base
               .xdl-mini-snippet hide — re-hide at matching specificity. */
            .realm-split .xdl-mini-snippet {
                display: none;
            }
            /* Mobile: per-box mini snippets (injected by xdl-interact.js) carry
               the festival-companion.xdl lines below each realm card and inside
               each numbered bullet; the big code window is redundant there. */
            @media (max-width: 900px) {
                .realms-section.has-mini-snippets .realm-split > .xdl-code {
                    display: none;
                }
                /* Bullets are flex rows (num + text) — let the mini wrap onto
                   its own full-width row inside the bullet box, free of the
                   measured height cap the big window uses. */
                .realm-bullet {
                    flex-wrap: wrap;
                }
                .realm-bullet .xdl-mini-snippet {
                    display: block;
                    flex-basis: 100%;
                    height: auto;
                    max-height: none;
                    margin: 0.25rem 0 0;
                }
            }

            /* === Stack Section === */
            .stack-section {
                padding-top: 6rem;
                padding-bottom: 6rem;
            }
            /* Tricolour rule for 3-sentence section headings (opt-in via
               .section-heading--triad). The three sentences are wrapped
               1st=<em>, 2nd=<strong>, 3rd=<code> — inert wrappers the CanonText
               canon-compare strips, so the canon body is unchanged. They colour
               the sentences blue / amber / text-primary (white in dark, black in
               light). CSS can't count sentences, and bare em/strong are already
               used for 2-part heading accents, so this is deliberately opt-in.
               Used by the "Build. Run. Scale." heading. */
            .section-heading--triad em { color: var(--xp-accent); }
            .section-heading--triad strong { color: var(--xp-amber); }
            .section-heading--triad code {
                font-family: inherit;
                font-size: inherit;
                font-weight: inherit;
                color: var(--xp-text-primary);
            }
            /* v2.2: three marketing bands (Design it → Run it → Scale it),
               not a vertical layer stack. Tiles derive from the architecture
               manifest's marketing projection; per-tile accent is inline. */
            .stack-bands {
                display: flex;
                flex-direction: column;
                gap: 2.5rem;
                margin-top: 3rem;
            }
            .stack-band-head {
                display: flex;
                align-items: center;
                gap: 0.85rem;
                margin-bottom: 1.1rem;
            }
            /* descriptive icon before each band title — matches the
               .xdl-feature-icon pattern (hue-tinted rounded tile) */
            .stack-band-icon {
                width: 36px;
                height: 36px;
                flex-shrink: 0;
                display: flex;
                align-items: center;
                justify-content: center;
                border-radius: 8px;
                background: color-mix(in srgb, var(--band-hue, var(--xp-accent)) 12%, transparent);
                color: var(--band-hue, var(--xp-accent));
            }
            .stack-band-icon svg { width: 20px; height: 20px; }
            /* title: same font / size / weight as the "Open standard"
               (.xdl-feature h3) title — 1.4rem, weight 600 */
            .stack-band-label {
                font-family: var(--xp-font-mono);
                font-weight: 600;
                font-size: 1.4rem;
                line-height: 1.2;
                text-transform: uppercase;
                letter-spacing: 0.06em;
            }
            .stack-band-tiles {
                display: grid;
                grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
                gap: 1rem;
            }
            .stack-tile {
                position: relative;
                display: flex;
                flex-direction: column;
                padding: 1.25rem 1.5rem;
                border: 1px solid var(--xp-border);
                border-radius: 10px;
                background: var(--xp-bg-surface);
                transition: background 0.25s, transform 0.25s;
            }
            /* Whole-tile click target → the module's deep-dive surface. Sits
               above the tile content + FX so any click follows the link. */
            .stack-tile-link {
                position: absolute;
                inset: 0;
                z-index: 2;
                border-radius: inherit;
                text-decoration: none;
            }
            .stack-tile:hover {
                background: var(--xp-bg-elevated);
                transform: translateY(-2px);
            }
            .stack-tile-name {
                font-family: var(--xp-font-mono);
                font-weight: 600;
                font-size: 1.2rem;
                line-height: 1.2;
                margin-bottom: 0.5rem;
                text-transform: uppercase;
                letter-spacing: 0.04em;
                /* Tie each module title to its own accent (same hue as the
                   tile's left border). */
                color: var(--tile-accent);
            }
            .stack-tile p {
                font-size: 0.88rem;
                color: var(--xp-text-secondary);
                line-height: 1.5;
                margin: 0 0 1rem;
            }

            /* === Per-module hover FX (decorative; samples each module's
               signature from the demos/assets above). Pure CSS; idle is dim
               and still, hover brings it to life. prefers-reduced-motion off. */
            .stack-tile-fx {
                position: relative;
                height: 66px;
                margin-top: auto;
                border-radius: 6px;
                overflow: hidden;
                background: color-mix(in srgb, var(--tile-accent) 6%, transparent);
                opacity: 0.5;
                transition: opacity 0.3s ease;
            }
            .stack-tile:hover .stack-tile-fx,
            .stack-tile:focus-within .stack-tile-fx,
            .stack-band-head:hover ~ .stack-band-tiles .stack-tile-fx { opacity: 1; }

            /* studio — Visualise storyboard filmstrip (3 tiles), sequenced from
               the original demo (public/assets/demo.js): a Starry-Night →
               Constellation → Violet-sky progression. Tiles:
                 1 (left)   context beat still — independent random 4-10s cycle
                 2 (middle) the scene's beat still (e.g. the Starry-Night room)
                 3 (right)  that SAME scene's video twin (vid-04/05/07) — so the
                            moving clip always sits to the right of its still.
               Middle+right advance together (the scene pair) on their own random
               4-10s cadence; the left tile cycles independently. Image tiles
               cross-fade between two .fx-layer planes; every still + the clip
               slowly Ken-Burns zoom/drift. Driven by /assets/studio-filmstrip.js
               (CSP 'self', no inline handlers). Under prefers-reduced-motion the
               script skips its timers + pauses the clip, and the @media block
               kills the zoom — leaving the seeded Starry-Night scene static. */
            .fx-studio { padding: 4px; }
            .fx-studio .fx-strip { display: flex; gap: 3px; height: 100%; }
            .fx-studio .fx-frame {
                position: relative;
                flex: 1;
                min-width: 0;
                border-radius: 3px;
                overflow: hidden;
            }
            .fx-studio .fx-layer {
                position: absolute;
                inset: 0;
                background-size: cover;
                background-position: center;
                opacity: 0;
                transition: opacity 0.8s ease;
            }
            .fx-studio .fx-layer.is-on { opacity: 1; }
            .fx-studio .fx-frame-vid video {
                position: absolute; inset: 0; width: 100%; height: 100%;
                object-fit: cover;
                transition: opacity 0.5s ease;
            }
            .fx-studio .fx-frame-vid.is-swapping video { opacity: 0; }
            .fx-studio .fx-sweep {
                position: absolute; top: 0; bottom: 0; left: -35%; width: 35%;
                background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--tile-accent) 40%, transparent), transparent);
            }
            /* Hover only: the Ken-Burns zoom (here) + the JS-driven cycle/video
               play (studio-filmstrip.js) both gate on hover, so the tile is a
               static storyboard at rest and only comes alive on hover. */
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-studio .fx-layer { animation: fxKenStudio 8s ease-in-out infinite alternate; }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-studio .fx-frame[data-role="scene-img"] .fx-layer { animation-duration: 10s; }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-studio .fx-frame-vid video { animation: fxKenStudio 9s ease-in-out infinite alternate; }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-studio .fx-sweep { animation: fxSweep 2.2s ease-in-out infinite; }
            /* slow Ken-Burns zoom + drift for the storyboard stills and the clip */
            @keyframes fxKenStudio { 0% { transform: scale(1); } 100% { transform: scale(1.12) translate(-2%, -1%); } }
            @keyframes fxSweep { 0% { left: -35%; } 100% { left: 100%; } }

            /* bridge — wiring canvas: nodes + a signal pulse travelling the edge */
            .fx-bridge .fx-edge {
                position: absolute; top: 50%; left: 12%; right: 12%; height: 2px; transform: translateY(-50%);
                background: color-mix(in srgb, var(--tile-accent) 35%, var(--xp-border));
            }
            .fx-bridge .fx-node {
                position: absolute; top: 50%; width: 9px; height: 9px; border-radius: 50%;
                transform: translate(-50%, -50%); background: var(--xp-bg-surface); border: 2px solid var(--tile-accent);
            }
            .fx-bridge .fx-node:nth-child(2) { left: 12%; }
            .fx-bridge .fx-node:nth-child(3) { left: 50%; }
            .fx-bridge .fx-node:nth-child(4) { left: 88%; }
            .fx-bridge .fx-dot {
                position: absolute; top: 50%; width: 6px; height: 6px; border-radius: 50%;
                transform: translate(-50%, -50%);
            }
            /* idle resting positions + colours (paused until hover) */
            .fx-bridge .fx-dot-a { left: 12%; background: var(--xp-accent); }
            .fx-bridge .fx-dot-b { left: 88%; background: var(--xp-green); }
            .fx-bridge .fx-dot-c { left: 50%; background: var(--xp-pink); }
            /* dots run between the three nodes at variable speeds, shifting
               colour as they reach each node */
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-bridge .fx-dot-a { animation: fxDotA 2.6s ease-in-out infinite alternate; }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-bridge .fx-dot-b { animation: fxDotB 1.9s ease-in-out infinite alternate; }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-bridge .fx-dot-c { animation: fxDotC 3.3s ease-in-out infinite; }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-bridge .fx-node { animation: fxNodeLit 1.9s ease-in-out infinite; }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-bridge .fx-node:nth-child(3) { animation-delay: 0.4s; }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-bridge .fx-node:nth-child(4) { animation-delay: 0.8s; }
            @keyframes fxDotA {
                0%   { left: 12%; background: var(--xp-accent); box-shadow: 0 0 7px var(--xp-accent); }
                50%  { left: 50%; background: var(--xp-cyan);   box-shadow: 0 0 7px var(--xp-cyan); }
                100% { left: 88%; background: var(--xp-pink);   box-shadow: 0 0 7px var(--xp-pink); }
            }
            @keyframes fxDotB {
                0%   { left: 88%; background: var(--xp-green);  box-shadow: 0 0 7px var(--xp-green); }
                50%  { left: 50%; background: var(--xp-amber);  box-shadow: 0 0 7px var(--xp-amber); }
                100% { left: 12%; background: var(--xp-purple); box-shadow: 0 0 7px var(--xp-purple); }
            }
            @keyframes fxDotC {
                0%   { left: 50%; background: var(--xp-pink);   box-shadow: 0 0 7px var(--xp-pink); }
                25%  { left: 88%; background: var(--xp-cyan);   box-shadow: 0 0 7px var(--xp-cyan); }
                50%  { left: 50%; background: var(--xp-accent); box-shadow: 0 0 7px var(--xp-accent); }
                75%  { left: 12%; background: var(--xp-green);  box-shadow: 0 0 7px var(--xp-green); }
                100% { left: 50%; background: var(--xp-pink);   box-shadow: 0 0 7px var(--xp-pink); }
            }
            @keyframes fxNodeLit { 0%,100% { box-shadow: none; } 50% { box-shadow: 0 0 8px var(--tile-accent); } }

            /* runtime — the intelligent core: pulsing core branching to a decision,
               ending in a supernova where the decision token resolves */
            .fx-runtime { overflow: visible; }
            .fx-runtime .fx-coredot {
                position: absolute; top: 50%; left: 22%; width: 12px; height: 12px; border-radius: 50%;
                transform: translate(-50%, -50%); background: var(--tile-accent);
            }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-runtime .fx-coredot { animation: fxPulseRing 1.6s ease-out infinite; }
            /* decision branches — two layers per branch:
                 ::before = a faint, PART-drawn "frozen" skeleton (first ~55% of
                   the branch from the core dot), visible at rest so the tile
                   reads as a branching core mid-decision, not a lone dot. It
                   fades out on hover so only the animated trace shows.
                 ::after  = the moving trace — grows from the core, trails its
                   token (dot leads in front), holds, then fades/disappears,
                   looping. Hover only; behaves exactly as before. Phase-locked to
                   the matching token's duration+delay (a<->tok1, c<->tok2,
                   b<->tok3). The .fx-branch itself is just the rotated container. */
            .fx-runtime .fx-branch {
                position: absolute; left: 22%; top: 50%; height: 2px;
                transform-origin: left center;
                transform: rotate(var(--ang, 0deg));
            }
            .fx-runtime .fx-branch-a { --ang: -7deg; width: 50%; } /* up   -> tok1 (68%,27%) */
            .fx-runtime .fx-branch-c { --ang: 0deg;  width: 54%; } /* flat -> tok2 (74%,50%) */
            .fx-runtime .fx-branch-b { --ang: 7deg;  width: 50%; } /* down -> tok3 (68%,73%) */
            /* frozen part-drawn skeleton (idle) — fades out on hover */
            .fx-runtime .fx-branch::before {
                content: ""; position: absolute; left: 0; top: 0; height: 100%; width: 55%;
                border-radius: 2px; opacity: 1;
                background: color-mix(in srgb, var(--tile-accent) 20%, var(--xp-border));
                transition: opacity 0.3s ease;
            }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-runtime .fx-branch::before { opacity: 0; }
            /* moving trace (hover only) — grows via scaleX from the core-dot end
               (the parent supplies the rotation); the light trailing wake. */
            .fx-runtime .fx-branch::after {
                content: ""; position: absolute; inset: 0;
                transform-origin: left center; transform: scaleX(0);
                opacity: 0; border-radius: 2px;
                background: color-mix(in srgb, var(--tile-accent) 38%, var(--xp-border));
            }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-runtime .fx-branch-a::after { animation: fxTrace 2.0s ease-in infinite; }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-runtime .fx-branch-c::after { animation: fxTrace 2.7s ease-in 0.4s infinite; }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-runtime .fx-branch-b::after { animation: fxTrace 2.35s ease-in 0.9s infinite; }
            /* three decision tokens emitted from the core down different branches
               at staggered cadences, each resolving in a supernova burst at its
               branch tip — varied, not a single repeating path */
            .fx-runtime .fx-tok {
                position: absolute; top: 50%; left: 22%; width: 7px; height: 7px; border-radius: 2px;
                background: var(--tile-accent); transform: translate(-50%, -50%) rotate(45deg); opacity: 0;
            }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-runtime .fx-tok1 { animation: fxTok1 2.0s ease-in infinite; }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-runtime .fx-tok2 { animation: fxTok2 2.7s ease-in 0.4s infinite; }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-runtime .fx-tok3 { animation: fxTok3 2.35s ease-in 0.9s infinite; }
            @keyframes fxPulseRing {
                0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tile-accent) 55%, transparent); }
                100% { box-shadow: 0 0 0 15px transparent; }
            }
            @keyframes fxTok1 {
                0%   { left: 22%; top: 50%; opacity: 0; transform: translate(-50%,-50%) rotate(45deg) scale(0.8); box-shadow: none; }
                9%   { opacity: 1; }
                56%  { left: 68%; top: 27%; opacity: 1; transform: translate(-50%,-50%) rotate(45deg) scale(1); box-shadow: none; }
                64%  { left: 68%; top: 27%; opacity: 1; transform: translate(-50%,-50%) rotate(45deg) scale(2.6); box-shadow: 0 0 6px 1px var(--tile-accent); }
                72%,100% { left: 68%; top: 27%; opacity: 0; transform: translate(-50%,-50%) rotate(45deg) scale(3.4); box-shadow: 0 0 2px 11px transparent; }
            }
            @keyframes fxTok2 {
                0%   { left: 22%; top: 50%; opacity: 0; transform: translate(-50%,-50%) rotate(45deg) scale(0.8); box-shadow: none; }
                9%   { opacity: 1; }
                56%  { left: 74%; top: 50%; opacity: 1; transform: translate(-50%,-50%) rotate(45deg) scale(1); box-shadow: none; }
                64%  { left: 74%; top: 50%; opacity: 1; transform: translate(-50%,-50%) rotate(45deg) scale(2.8); box-shadow: 0 0 6px 1px var(--tile-accent); }
                72%,100% { left: 74%; top: 50%; opacity: 0; transform: translate(-50%,-50%) rotate(45deg) scale(3.6); box-shadow: 0 0 2px 12px transparent; }
            }
            @keyframes fxTok3 {
                0%   { left: 22%; top: 50%; opacity: 0; transform: translate(-50%,-50%) rotate(45deg) scale(0.8); box-shadow: none; }
                9%   { opacity: 1; }
                56%  { left: 68%; top: 73%; opacity: 1; transform: translate(-50%,-50%) rotate(45deg) scale(1); box-shadow: none; }
                64%  { left: 68%; top: 73%; opacity: 1; transform: translate(-50%,-50%) rotate(45deg) scale(2.6); box-shadow: 0 0 6px 1px var(--tile-accent); }
                72%,100% { left: 68%; top: 73%; opacity: 0; transform: translate(-50%,-50%) rotate(45deg) scale(3.4); box-shadow: 0 0 2px 11px transparent; }
            }

            /* trace lifecycle — the token dot launches first; the faint line
               then TRAILS behind it, only reaching full length at 64% (after the
               dot has hit its endpoint at 56% and begun to resolve), so the dot
               stays out in front the whole way. HOLD through the token's resolve
               + a linger past its vanish (72%), then fade. rotate(var(--ang)) is
               constant per trace; only scaleX/opacity animate, so the line
               extends from the core dot along its branch and snaps back
               invisibly at loop. Opacity capped low (0.5) — a light wake. */
            @keyframes fxTrace {
                0%   { transform: scaleX(0); opacity: 0; }
                12%  { transform: scaleX(0); opacity: 0.5; }
                64%  { transform: scaleX(1); opacity: 0.5; }
                90%  { transform: scaleX(1); opacity: 0.5; }
                100% { transform: scaleX(1); opacity: 0; }
            }

            /* fabric — protocol signal bars (the "hundreds of adapters") */
            .fx-fabric { display: flex; align-items: flex-end; gap: 3px; padding: 7px 12px; height: 100%; }
            .fx-fabric i {
                flex: 1; height: 22%; border-radius: 2px 2px 0 0;
                background: color-mix(in srgb, var(--tile-accent) 60%, transparent);
            }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-fabric i { animation: fxBar 1.1s ease-in-out infinite; animation-delay: calc(var(--i) * 0.07s); }
            @keyframes fxBar { 0%,100% { height: 18%; } 50% { height: 88%; } }

            /* venue — an LED-wall pixel grid: random flicker, varying intensity,
               occasional bursts of colour */
            .fx-venue { display: grid; grid-template-columns: repeat(14, 1fr); gap: 3px; padding: 6px 10px; align-content: center; height: 100%; }
            .fx-venue i {
                aspect-ratio: 1; border-radius: 2px;
                background: color-mix(in srgb, var(--tile-accent) 14%, var(--xp-border));
            }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-venue i { animation: fxLed 2.4s ease-in-out infinite; animation-delay: calc(var(--d) * -2.4s); }
            :is(.stack-tile:hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-venue i.led-burst { animation: fxLedBurst 3.1s ease-in-out infinite; animation-delay: calc(var(--d) * -3.1s); }
            @keyframes fxLed {
                0%,100% { background: color-mix(in srgb, var(--tile-accent) 14%, var(--xp-border)); }
                50% { background: color-mix(in srgb, var(--tile-accent) calc(var(--s) * 1%), var(--xp-border)); }
            }
            @keyframes fxLedBurst {
                0%,100% { background: color-mix(in srgb, var(--tile-accent) 14%, var(--xp-border)); box-shadow: none; }
                44% { background: color-mix(in srgb, var(--tile-accent) 35%, var(--xp-border)); }
                50% { background: var(--burst); box-shadow: 0 0 5px var(--burst); }
                56% { background: color-mix(in srgb, var(--tile-accent) 35%, var(--xp-border)); box-shadow: none; }
            }

            /* cloud — a thin-outline world map scrolling vertically through
               latitudes, revealing capital-city rectangles as they pass.
               Taller FX box so the Cloud tile matches the Runtime Core tile
               height (Runtime's longer copy makes its tile 42px taller). */
            /* Scale-it / Cloud tile: the animation IS the box. The world map +
               comms fill the entire tile (which keeps its own border-left,
               surface bg and radius — same as the other tiles); the name + copy
               are overlaid on top. No separate inner FX box. Tile height = the
               former animated-box height (210px). */
            .stack-tile[data-module="cloud"] {
                position: relative;
                height: 210px;
                overflow: hidden;
                justify-content: flex-start;
            }
            .stack-tile[data-module="cloud"] .stack-tile-name,
            .stack-tile[data-module="cloud"] > p {
                position: relative;
                z-index: 1;
                text-shadow: 0 1px 6px var(--xp-bg), 0 0 12px var(--xp-bg-surface);
            }
            /* The cloud tile carries the collapsed "Scale" band heading — match
               the .stack-band-label terminal styling so SCALE reads at the same
               size/font as BUILD and RUN. */
            .stack-tile[data-module="cloud"] .stack-tile-name {
                font-family: var(--xp-font-mono);
                font-size: 1.4rem;
                font-weight: 600;
                text-transform: uppercase;
                letter-spacing: 0.06em;
                /* SCALE is the band heading — stays neutral like BUILD/RUN,
                   not the cloud accent the general module-title rule would give. */
                color: var(--xp-text-primary);
            }
            /* Wrap the cloud blurb onto two balanced lines at full width
               (text-wrap:balance evens the two lines; the max-width forces the
               break so it isn't one long line on a wide screen). */
            .stack-tile[data-module="cloud"] > p {
                max-width: 68ch;
                text-wrap: balance;
            }
            .fx-cloud {
                position: absolute;
                inset: 0;
                height: auto;
                margin: 0;
                border-radius: 0;
                background: none;
                z-index: 0;
            }
            .fx-cloud .fx-map {
                position: absolute; inset: 0; height: 100%;
                transform: translateY(18px); /* nudge map down to sit vertically centred under the copy */
            }
            .fx-cloud .fx-worldmap {
                position: absolute; inset: 0;
                color: color-mix(in srgb, var(--tile-accent) 55%, transparent);
            }
            .fx-cloud .fx-worldmap svg { display: block; width: 100%; height: 100%; }
            /* capital markers: a dot that lights up and emits an expanding
               circle pulse, each at a randomised phase (--delay/--dur) so only
               a shifting random subset shows at once */
            .fx-cloud .fx-city {
                position: absolute; width: 4px; height: 4px; border-radius: 50%;
                transform: translate(-50%, -50%);
                background: var(--tile-accent); opacity: 0;
            }
            .fx-cloud .fx-city::after {
                content: ""; position: absolute; left: 50%; top: 50%;
                width: 4px; height: 4px; border-radius: 50%;
                border: 1px solid var(--tile-accent);
                transform: translate(-50%, -50%) scale(0.5); opacity: 0;
            }
            /* INVARIANT (rules 1 & 2): an arc-endpoint city (.fx-city-live) MUST
               always show a pulsing dot. The ambient random blink is therefore
               excluded from live cities via :not(.fx-city-live) — without it the
               ambient rule's higher specificity (it sits under the :is() hover
               umbrella) would override the live pulse, leaving the endpoint
               mid-blink (invisible) when an arc connects. Unconnected cities keep
               blinking ambiently. */
            :is(.stack-tile:hover, .stack-tile.mobile-hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-cloud .fx-city:not(.fx-city-live) { animation: fxCityFlash var(--dur, 6s) ease-in-out var(--delay, 0s) infinite; }
            :is(.stack-tile:hover, .stack-tile.mobile-hover, .stack-band-head:hover ~ .stack-band-tiles .stack-tile) .fx-cloud .fx-city:not(.fx-city-live)::after { animation: fxCityPing var(--dur, 6s) ease-out var(--delay, 0s) infinite; }
            /* comms arcs (assets/cloud-comms.js): up to 5 thin arcing lines from
               the origin capital to real destination cities, re-rolled each
               second; a light beam flows through each line */
            /* width/height 100% is REQUIRED: an <svg> is a replaced element, so
               inset:0 alone leaves it at intrinsic size and the arc coordinate
               space stops matching the city % positions */
            .fx-cloud .fx-comms { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
            /* arcs fade in with the SAME timing as the lit cities (fxCommsIn),
               and are removed in the same frame the cities un-light — so a line
               and its city dots are always on-screen together */
            .fx-cloud .fx-arc-group { animation: fxCommsIn 0.3s ease both; }
            .fx-cloud .fx-arc {
                fill: none;
                stroke: color-mix(in srgb, var(--tile-accent) 62%, transparent);
                stroke-width: 1;
                stroke-linecap: round;
                vector-effect: non-scaling-stroke;
            }
            /* connected cities light up (the arc endpoint IS the city marker —
               the line needs no end-dot of its own) */
            /* a connected city is ACTIVE: fades in with its arc, then keeps
               pulsing with an expanding radar ping for as long as the arc is up */
            .fx-cloud .fx-city.fx-city-live {
                opacity: 1;
                /* Dot + glow pulse appear IMMEDIATELY with the arc (no
                   beam-travel delay), so every rendered arc endpoint always
                   shows a pulsing dot. Only the expanding ping (::after) waits
                   for the beam to arrive (--hit-delay). */
                animation: fxCommsIn 0.3s ease both, fxLiveDot 1.3s ease-in-out infinite;
            }
            @keyframes fxCommsIn { from { opacity: 0; } to { opacity: 1; } }
            .fx-cloud .fx-city.fx-city-live::after {
                opacity: 0;
                animation: fxLivePing 1.3s ease-out infinite;
                animation-delay: var(--hit-delay, 0s);
            }
            @keyframes fxLiveDot {
                0%, 100% { box-shadow: 0 0 4px var(--tile-accent); }
                50% { box-shadow: 0 0 10px var(--tile-accent); }
            }
            @keyframes fxLivePing {
                0% { transform: translate(-50%, -50%) scale(0.6); opacity: 0.85; }
                100% { transform: translate(-50%, -50%) scale(4.5); opacity: 0; }
            }
            .fx-cloud .fx-city.fx-city-origin {
                box-shadow: 0 0 10px var(--tile-accent);
                transform: translate(-50%, -50%) scale(1.5);
            }
            /* travelling light-beam: thin, soft-capped, translucent (per-arc
               opacity set inline) — reads as light flowing through the line */
            .fx-cloud .fx-arc-beam {
                fill: none;
                stroke: var(--tile-accent);
                stroke-width: 0.9;
                stroke-linecap: round;
                vector-effect: non-scaling-stroke;
            }
            @keyframes fxCityFlash {
                0%, 80%, 100% { opacity: 0; box-shadow: none; }
                85% { opacity: 1; box-shadow: 0 0 6px var(--tile-accent); }
                94% { opacity: 0.85; box-shadow: 0 0 4px var(--tile-accent); }
            }
            @keyframes fxCityPing {
                0%, 82% { transform: translate(-50%, -50%) scale(0.5); opacity: 0; }
                85% { opacity: 0.9; }
                100% { transform: translate(-50%, -50%) scale(5); opacity: 0; }
            }

            /* Mobile: the per-module FX are hover demos — with no hover they sit
               as static decorations, so drop them from every tile EXCEPT the
               SCALE (cloud) tile, whose world map is the tile backdrop and
               animates while scrolled into view (.mobile-hover, set by app.js). */
            @media (max-width: 900px) {
                .stack-tile:not([data-module="cloud"]) .stack-tile-fx {
                    display: none;
                }
                .stack-tile.mobile-hover .stack-tile-fx {
                    opacity: 1;
                }
            }
            @media (prefers-reduced-motion: reduce) {
                .stack-tile-fx, .stack-tile-fx * { animation: none !important; }
            }
            .stack-band-note {
                /* Sits on the same row as the "Run it" band label (inside
                   .stack-band-head): margin-left:auto pushes it to the right
                   edge; the head's align-items:center keeps it vertically
                   centred against the 1.4rem label. Brightened to the RUN-band
                   amber with a glow so it reads as a live status indicator. */
                margin: 0 0 0 auto;
                text-align: right;
                font-family: var(--xp-font-mono);
                font-size: 0.78rem;
                color: var(--xp-amber);
                letter-spacing: 0.01em;
                text-shadow: 0 0 8px color-mix(in srgb, var(--xp-amber) 60%, transparent),
                             0 0 18px color-mix(in srgb, var(--xp-amber) 35%, transparent);
            }

            /* === Use Cases Section === */
            .usecases-section {
                padding-top: 6rem;
                padding-bottom: 6rem;
            }
            .usecase-grid {
                display: grid;
                grid-template-columns: repeat(3, 1fr);
                gap: 1.25rem;
                margin-top: 3rem;
            }
            .usecase-card {
                padding: 1.6rem 1.5rem;
                border-radius: 12px;
                border: 1px solid var(--xp-border);
                background: var(--xp-bg-surface);
                transition:
                    transform 0.4s cubic-bezier(0.16, 1, 0.3, 1),
                    border-color 0.3s,
                    background 0.3s,
                    box-shadow 0.4s;
                position: relative;
                overflow: hidden;
            }
            .usecase-card::before {
                content: "";
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                height: 3px;
                opacity: 0.6;
                transition: opacity 0.4s, box-shadow 0.4s;
            }
            /* Ambient colour wash that glows on hover */
            .usecase-card::after {
                content: "";
                position: absolute;
                inset: 0;
                background: radial-gradient(
                    circle at 30% 0%,
                    var(--uc-color, var(--xp-accent)),
                    transparent 60%
                );
                opacity: 0;
                pointer-events: none;
                transition: opacity 0.4s;
                z-index: 0;
            }
            .usecase-card > * {
                position: relative;
                z-index: 1;
            }
            .usecase-card:hover {
                background: var(--xp-bg-elevated);
                transform: translateY(-4px);
                border-color: color-mix(in srgb, var(--uc-color) 50%, var(--xp-border));
                box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4);
            }
            .usecase-card:hover::before {
                opacity: 1;
                box-shadow: 0 0 18px var(--uc-color, var(--xp-accent));
            }
            .usecase-card:hover::after {
                opacity: 0.08;
            }
            .usecase-card h3 {
                transition: color 0.3s;
            }
            .usecase-card:hover h3 {
                color: var(--uc-color, var(--xp-text-primary));
            }
            .usecase-card h3 {
                font-size: 0.95rem;
                font-weight: 600;
                margin-bottom: 0.4rem;
            }
            .usecase-card p {
                font-size: 0.8rem;
                color: var(--xp-text-subtle);
                line-height: 1.5;
                margin-bottom: 0.75rem;
            }
            .usecase-tags {
                display: flex;
                flex-wrap: wrap;
                gap: 4px;
            }
            .usecase-tag {
                font-family: var(--xp-font-mono);
                font-size: 0.6rem;
                padding: 2px 8px;
                border-radius: 4px;
                letter-spacing: 0.02em;
            }

            /* === Protocols Section === */
            .protocols-section {
                padding: 6rem 0;
                overflow: hidden;
                position: relative;
                z-index: 1;
            }
            .protocols-inner {
                max-width: 1200px;
                margin: 0 auto;
                padding: 0 2rem;
            }
            .protocol-stream-permanent {
                margin-top: 3rem;
                overflow: hidden;
                position: relative;
                padding: 2rem 0;
            }
            .protocol-stream-permanent::before,
            .protocol-stream-permanent::after {
                content: "";
                position: absolute;
                top: 0;
                bottom: 0;
                width: 120px;
                z-index: 2;
            }
            .protocol-stream-permanent::before {
                left: 0;
                background: linear-gradient(90deg, var(--xp-bg), transparent);
            }
            .protocol-stream-permanent::after {
                right: 0;
                background: linear-gradient(270deg, var(--xp-bg), transparent);
            }
            .protocol-row {
                display: flex;
                gap: 3rem;
                white-space: nowrap;
                animation: scroll-protocols linear infinite;
            }
            .protocol-row span {
                font-family: var(--xp-font-mono);
                font-size: clamp(0.9rem, 2vw, 1.1rem);
                color: var(--xp-text-subtle);
                opacity: 0.5;
                transition:
                    opacity 0.3s,
                    color 0.3s;
            }
            .protocol-row span:hover {
                opacity: 1;
                color: var(--xp-accent);
            }
            @keyframes scroll-protocols {
                from {
                    transform: translateX(0);
                }
                to {
                    transform: translateX(-50%);
                }
            }

            /* Protocol spread — visual breadth card grid */
            .protocol-spread {
                display: grid;
                /* Five cards on one row. Language primitives is first and the
                   widest column (it has ~23 chips) so its chips pack into fewer
                   rows — that drops the row height, and grid stretch pulls the
                   four narrower cards down to match, so the whole band is
                   shorter and more balanced. */
                grid-template-columns: minmax(0, 360px) repeat(4, minmax(0, 188px));
                justify-content: center;
                gap: 1.25rem;
                margin-top: 3rem;
            }
            .protocol-card {
                padding: 1.25rem 1.25rem 1.1rem;
                border-radius: 12px;
                border: 1px solid var(--xp-border);
                background: rgba(13, 13, 18, 0.5);
                position: relative;
                /* visible (not hidden) so a chip's hover popup can escape the card. */
                overflow: visible;
                transition: border-color 0.3s, background 0.3s;
            }
            .protocol-card:hover {
                border-color: var(--pc, var(--xp-accent));
                background: rgba(13, 13, 18, 0.75);
                /* lift the hovered card so its popup sits above its neighbours */
                z-index: 5;
            }
            .protocol-card-label {
                font-family: var(--xp-font-heading);
                font-size: 0.68rem;
                font-weight: 600;
                text-transform: uppercase;
                letter-spacing: 0.14em;
                color: var(--pc, var(--xp-accent));
                margin-bottom: 0.9rem;
            }
            .protocol-card-chips {
                display: flex;
                flex-wrap: wrap;
                gap: 5px;
            }
            .protocol-card-chips span {
                padding: 4px 9px;
                border-radius: 999px;
                background: rgba(255, 255, 255, 0.04);
                border: 1px solid var(--xp-border);
                color: var(--xp-text-primary);
                font-family: var(--xp-font-body);
                font-size: 0.72rem;
                transition: border-color 0.3s, background 0.3s;
            }
            .protocol-card:hover .protocol-card-chips span {
                border-color: color-mix(in srgb, var(--pc) 40%, var(--xp-border));
            }

            /* Linked primitive chips (Language primitives / Touchpoint
               categories / Realms) — look identical to the plain span chips
               but are <a> elements that open the wiki entry and reveal a
               description popup on hover/focus. Pure CSS (CSP-safe). */
            .protocol-card-chips a.protocol-chip {
                padding: 4px 9px;
                border-radius: 999px;
                background: rgba(255, 255, 255, 0.04);
                border: 1px solid var(--xp-border);
                color: var(--xp-text-primary);
                font-family: var(--xp-font-body);
                font-size: 0.72rem;
                text-decoration: none;
                cursor: pointer;
                position: relative;
                transition: border-color 0.2s, background 0.2s, color 0.2s;
            }
            :root[data-theme='light'] .protocol-card-chips a.protocol-chip {
                background: rgba(0, 0, 0, 0.03);
            }
            .protocol-card:hover .protocol-card-chips a.protocol-chip {
                border-color: color-mix(in srgb, var(--pc) 40%, var(--xp-border));
            }
            .protocol-card-chips a.protocol-chip:hover,
            .protocol-card-chips a.protocol-chip:focus-visible {
                border-color: var(--pc, var(--xp-accent));
                color: var(--pc, var(--xp-accent));
                background: color-mix(in srgb, var(--pc) 10%, transparent);
                outline: none;
                z-index: 2;
            }
            /* Hover/focus description popup, content from data-tip (spec). */
            .protocol-card-chips a.protocol-chip[data-tip]::after {
                content: attr(data-tip);
                position: absolute;
                left: 50%;
                bottom: calc(100% + 8px);
                transform: translateX(-50%) translateY(4px);
                width: max-content;
                max-width: 260px;
                padding: 9px 11px;
                border-radius: 8px;
                background: var(--xp-bg-elevated);
                color: var(--xp-text-primary);
                border: 1px solid var(--xp-border);
                box-shadow: 0 10px 34px rgba(0, 0, 0, 0.45);
                font-family: var(--xp-font-body);
                font-size: 0.72rem;
                font-weight: 400;
                line-height: 1.45;
                letter-spacing: normal;
                text-transform: none;
                white-space: normal;
                text-align: left;
                opacity: 0;
                visibility: hidden;
                transition: opacity 0.15s ease, transform 0.15s ease;
                z-index: 60;
                pointer-events: none;
            }
            /* Little caret under the popup. */
            .protocol-card-chips a.protocol-chip[data-tip]::before {
                content: "";
                position: absolute;
                left: 50%;
                bottom: calc(100% + 3px);
                transform: translateX(-50%);
                border: 5px solid transparent;
                border-top-color: var(--xp-border);
                opacity: 0;
                visibility: hidden;
                transition: opacity 0.15s ease;
                z-index: 61;
                pointer-events: none;
            }
            .protocol-card-chips a.protocol-chip[data-tip]:hover::after,
            .protocol-card-chips a.protocol-chip[data-tip]:focus-visible::after {
                opacity: 1;
                visibility: visible;
                transform: translateX(-50%) translateY(0);
            }
            .protocol-card-chips a.protocol-chip[data-tip]:hover::before,
            .protocol-card-chips a.protocol-chip[data-tip]:focus-visible::before {
                opacity: 1;
                visibility: visible;
            }
            @media (max-width: 900px) {
                .protocol-spread { grid-template-columns: repeat(2, 1fr); }
            }
            @media (max-width: 600px) {
                .protocol-spread {
                    grid-template-columns: 1fr;
                    max-width: 360px;
                    margin-left: auto;
                    margin-right: auto;
                }
            }

            /* === Install Section === */
            .install-section {
                padding-top: 8rem;
                padding-bottom: 6rem;
                text-align: center;
                position: relative;
                z-index: 1;
            }
            /* Footer anchoring: the last section on a page — the section[id]
               directly before the <footer> — fills the viewport minus the footer
               and vertically centres its content, so the footer is anchored to
               the bottom of the page and clearly visible. Covers home
               (#get-started) and /platform (#partners), plus any future page
               whose footer follows a section[id]. /hip-hop-experience wraps its
               sections in <main>, handled in HipHopLayout; /manifesto's footer
               follows a prose <main> (no trailing section[id]), so this never
               matches there and its natural-flow footer is preserved. ~7rem ≈ the
               footer height (3rem top + 3rem bottom padding + one line). */
            section[id]:has(+ footer) {
                min-height: calc(100vh - 7rem);
                display: flex;
                flex-direction: column;
                justify-content: center;
                /* Do NOT centre-snap the last section — that would pull it to the
                   middle of the viewport and push the footer below the fold. The
                   footer is the snap target instead (rule below), so the page
                   settles with the footer at the bottom and this section filling
                   the space above it. */
                scroll-snap-align: none;
            }
            /* The footer is the page's final snap target: its end aligns to the
               bottom of the viewport, anchoring it there with the last section
               (≈100vh − footer) filling the rest. */
            footer {
                scroll-snap-align: end;
            }
            /* The signup section keeps its own breathing-room padding; its form's
               max-width + margin:auto keep it centred under the flex column. */
            section[id].install-section:has(+ footer) {
                padding-top: 5rem;
                padding-bottom: 4rem;
            }
            .install-section::before {
                content: "";
                position: absolute;
                inset: 0;
                z-index: -1;
                pointer-events: none;
                background-image:
                    linear-gradient(
                        rgba(59, 130, 246, 0.06) 1px,
                        transparent 1px
                    ),
                    linear-gradient(
                        90deg,
                        rgba(59, 130, 246, 0.06) 1px,
                        transparent 1px
                    );
                background-size: 48px 48px;
                -webkit-mask-image: radial-gradient(ellipse at 50% 50%, #000 20%, transparent 70%);
                mask-image: radial-gradient(ellipse at 50% 50%, #000 20%, transparent 70%);
                opacity: 0;
                transition: opacity 1s ease;
            }
            .install-section::after {
                content: "";
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                width: 600px;
                height: 600px;
                z-index: -1;
                pointer-events: none;
                background: radial-gradient(circle, rgba(59, 130, 246, 0.15) 0%, transparent 60%);
                opacity: 0;
                transition: opacity 0.6s ease, transform 0.6s ease;
            }
            .install-section.visible::before {
                opacity: 1;
            }
            .install-section:has(.signup:hover)::before {
                background-image:
                    linear-gradient(
                        rgba(59, 130, 246, 0.15) 1px,
                        transparent 1px
                    ),
                    linear-gradient(
                        90deg,
                        rgba(59, 130, 246, 0.15) 1px,
                        transparent 1px
                    );
                animation: electric-grid 0.8s ease-in-out infinite alternate;
            }
            .install-section:has(.signup:hover)::after {
                opacity: 1;
                transform: translate(-50%, -50%) scale(1.3);
                animation: electric-pulse 1.2s ease-in-out infinite;
            }
            @keyframes electric-grid {
                0% { opacity: 0.7; }
                100% { opacity: 1; }
            }
            @keyframes electric-pulse {
                0%, 100% { opacity: 0.6; transform: translate(-50%, -50%) scale(1.2); }
                50% { opacity: 1; transform: translate(-50%, -50%) scale(1.5); }
            }
            .install-section:has(.signup:hover) .signup input[type="email"] {
                border-color: var(--xp-accent);
                box-shadow: 0 0 20px rgba(59, 130, 246, 0.25), 0 0 60px rgba(59, 130, 246, 0.1);
            }
            .install-section:has(.signup:hover) .signup button {
                box-shadow: 0 0 30px rgba(59, 130, 246, 0.4), 0 0 80px rgba(59, 130, 246, 0.15);
            }
            .electric-canvas {
                position: absolute;
                inset: 0;
                width: 100%;
                height: 100%;
                z-index: -1;
                pointer-events: none;
                opacity: 0;
                transition: opacity 0.5s ease;
            }
            .electric-canvas.active {
                opacity: 1;
            }
            .terminal {
                width: 100%;
                max-width: 640px;
                margin: 2rem auto 2rem;
                background: var(--xp-bg-surface);
                border: 1px solid var(--xp-border);
                border-radius: 12px;
                overflow: hidden;
                text-align: left;
                box-shadow:
                    0 4px 40px rgba(0, 0, 0, 0.4),
                    0 0 80px var(--xp-accent-glow);
                transition:
                    box-shadow 0.4s,
                    transform 0.4s,
                    border-color 0.4s;
            }
            .terminal:hover {
                transform: translateY(-2px);
                border-color: rgba(59, 130, 246, 0.25);
                box-shadow:
                    0 8px 50px rgba(0, 0, 0, 0.5),
                    0 0 120px var(--xp-accent-glow-strong);
            }
            .terminal-dot:nth-child(1) {
                background: #ff5f57;
            }
            .terminal-dot:nth-child(2) {
                background: #febc2e;
            }
            .terminal-dot:nth-child(3) {
                background: var(--xp-accent);
            }
            .terminal-tab:hover {
                color: var(--xp-text-primary);
                border-color: rgba(59, 130, 246, 0.3);
            }
            .terminal-platform:hover {
                color: var(--xp-text-primary);
            }
            .cursor {
                display: inline-block;
                width: 8px;
                height: 1.15em;
                background: var(--xp-accent);
                vertical-align: text-bottom;
                margin-left: 2px;
                animation: blink 1s step-end infinite;
            }
            @keyframes blink {
                50% {
                    opacity: 0;
                }
            }
            .copy-btn:hover {
                color: var(--xp-text-primary);
                border-color: var(--xp-accent);
                background: rgba(59, 130, 246, 0.08);
            }

            /* === Signup === */
            .signup {
                width: 100%;
                max-width: 440px;
                display: flex;
                gap: 0;
                margin: 0 auto 1rem;
            }
            .signup input[type="email"] {
                flex: 1;
                min-width: 0;
                padding: 14px 16px;
                background: var(--xp-bg-surface);
                border: 1px solid var(--xp-border);
                border-right: none;
                border-radius: 10px 0 0 10px;
                color: var(--xp-text-primary);
                font-family: var(--xp-font-heading);
                font-size: 0.95rem;
                outline: none;
                transition:
                    border-color 0.2s,
                    box-shadow 0.2s;
            }
            .signup input[type="email"]::placeholder {
                color: var(--xp-text-subtle);
                opacity: 0.6;
            }
            .signup input[type="email"]:focus {
                border-color: var(--xp-accent);
                box-shadow: 0 0 0 3px var(--xp-accent-glow);
            }
            .signup button {
                padding: 14px 24px;
                background: var(--xp-accent);
                color: #fff;
                border: 1px solid var(--xp-accent);
                border-radius: 0 10px 10px 0;
                font-family: var(--xp-font-heading);
                font-size: 0.95rem;
                font-weight: 600;
                cursor: pointer;
                white-space: nowrap;
                transition:
                    background 0.25s,
                    transform 0.15s;
            }
            .signup button:hover {
                background: var(--xp-accent-hover);
                box-shadow: 0 0 20px rgba(59, 130, 246, 0.3);
            }
            .signup button:active {
                transform: scale(0.97);
            }
            .signup button:disabled {
                opacity: 0.6;
                cursor: not-allowed;
            }
            .signup-hint {
                font-size: 0.78rem;
                color: var(--xp-text-subtle);
                opacity: 0.5;
                text-align: center;
                margin: 0.5rem 0;
            }
            .signup-msg {
                font-size: 0.85rem;
                text-align: center;
                min-height: 1.2em;
            }
            .signup-msg.success {
                color: #34d399;
            }
            .signup-msg.error {
                color: #f87171;
            }

            /* === Featured project === */
            .featured-project {
                position: relative;
                text-align: center;
                padding: 10rem 2rem;
                max-width: 900px;
                margin: 0 auto;
                isolation: isolate;
            }
            /* .sr settles to transform:translateY(0) (≈ none); cleared once
               revealed so the entrance is visually identical. */
            .featured-project.visible {
                transform: none;
            }
            /* Section-anchored reveal: the portrait backdrop is position:absolute
               within .featured-project (position:relative above), so it stays
               pinned behind THIS section — not the viewport — and is contained
               (fully visible) rather than cropped to a viewport cover. */
            .featured-project::before {
                content: "";
                /* Pinned to the Featured Project section (position:absolute vs
                   the old viewport-fixed) and fully visible — the whole portrait
                   is contained within the section box, not viewport-cover. */
                position: absolute;
                inset: 0;
                transform: scale(1.04);
                background: url("/assets/projects/rhyme-refuge-portrait.webp") center / contain no-repeat;
                opacity: 0;
                z-index: -1;
                pointer-events: none;
                transition:
                    opacity 0.9s ease,
                    transform 1.2s ease;
                -webkit-mask-image: radial-gradient(ellipse at center, #000 45%, transparent 88%);
                mask-image: radial-gradient(ellipse at center, #000 45%, transparent 88%);
            }
            .featured-project:hover::before,
            .featured-project.mobile-hover::before {
                opacity: 0.55;
                transform: scale(1);
            }
            /* Mobile: portrait shows at full desktop strength; the copy stays
               readable via the .mobile-hover .section-sub colour lift + halo
               below, reinforced with a stronger drop shadow here. The CTA goes
               transparent (ghost) like the nav Get Started. */
            @media (max-width: 700px) {
                .featured-project .section-sub {
                    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.75);
                }
                /* .featured-project prefix out-ranks the base rule below
                   (this media block sits earlier in the file). */
                .featured-project .featured-project-link {
                    background: transparent;
                    border-color: var(--xp-accent);
                    color: var(--xp-accent);
                }
                .featured-project .featured-project-link:hover {
                    background: transparent;
                    border-color: var(--xp-accent-hover);
                    color: var(--xp-accent-hover);
                }
            }
            @media (prefers-reduced-motion: reduce) {
                .featured-project::before {
                    transition: opacity 0.2s ease;
                }
                .featured-project:hover::before {
                    transform: scale(1.02);
                }
            }
            .featured-project-title-img {
                display: block;
                max-width: min(1040px, 98%);
                height: auto;
                margin: 0.5rem auto 0;
                user-select: none;
                position: relative;
                z-index: 1;
                filter: brightness(1.35) saturate(0.92);
            }
            .featured-project-link {
                display: inline-flex;
                align-items: center;
                gap: 0.5rem;
                font-family: var(--xp-font-heading);
                font-weight: 600;
                font-size: 1rem;
                /* Always a solid, prominent blue button — white text in BOTH
                   themes. Fixed #2563eb (not the token) so white text holds
                   WCAG-AA (5.0:1) in dark mode too, where --xp-accent #3b82f6
                   would only give ~2.9:1. */
                color: #ffffff;
                background: #2563eb;
                padding: 0.75rem 1.5rem;
                border: 1px solid #2563eb;
                border-radius: 999px;
                transition: background 0.2s, border-color 0.2s, transform 0.2s;
            }
            .featured-project-link:hover {
                background: #1d4ed8;
                border-color: #1d4ed8;
                transform: translateY(-1px);
                color: #ffffff;
            }
            .featured-project-link span {
                transition: transform 0.2s;
            }
            .featured-project-link:hover span {
                transform: translateX(3px);
            }
            /* When the portrait fades in behind the copy on hover, lift the
               description to primary colour and halo it in the page background
               (works in both themes) so it stays readable over the image. */
            .featured-project .section-sub {
                transition: color 0.3s ease, text-shadow 0.3s ease;
            }
            .featured-project:hover .section-sub,
            .featured-project.mobile-hover .section-sub {
                color: var(--xp-text-primary);
                text-shadow:
                    0 1px 8px var(--xp-bg),
                    0 0 22px var(--xp-bg);
            }

            /* === Partners === */
            .partners-section {
                position: relative;
                z-index: 1;
                padding: 3rem 2rem 4rem;
                text-align: center;
                max-width: 1200px;
                margin: 0 auto;
            }
            /* `bare` variant: partners heading + logos embedded inside another
               section (the home page slots this into #invitation, below the
               pillars). No section wrapper, so it sits in the host section's
               flow — with a gap above the "Venues, tool builders…" line to
               separate it from the pillars. */
            .partners-block {
                position: relative;
                z-index: 1;
                max-width: 1200px;
                margin: 4rem auto 0;
                text-align: center;
            }
            .partners-heading {
                font-family: var(--xp-font-heading);
                font-size: 0.75rem;
                color: var(--xp-text-subtle);
                text-transform: uppercase;
                letter-spacing: 0.2em;
                font-weight: 400;
                margin-bottom: 2rem;
            }
            .partners-logos {
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 1.25rem;
                flex-wrap: wrap;
                row-gap: 1.5rem;
            }
            .partners-logos a {
                display: flex;
                align-items: center;
                justify-content: center;
                text-decoration: none;
                padding: 0.5rem;
                transition: transform 0.3s;
            }
            .partners-logos a:hover {
                transform: translateY(-2px);
            }
            .partners-logos img {
                width: auto;
                object-fit: contain;
                filter: grayscale(1) brightness(0) invert(0.4);
                opacity: 1;
                transition:
                    filter 0.3s,
                    opacity 0.3s;
            }
            .partners-logos a:hover img {
                filter: grayscale(0) brightness(1) invert(0);
                opacity: 1;
            }
            .partners-logos a:hover img[src*="james-chase"],
            .partners-logos a:hover img[src*="holland-house"] {
                filter: brightness(0) invert(1);
            }
            .partners-logos .allpoints-link svg {
                filter: grayscale(1) brightness(0) invert(0.4);
                transition: filter 0.3s;
            }
            .partners-logos .allpoints-link:hover svg {
                filter: none;
            }
            .allpoints-link .ap-grey {
                stroke: #1a1b30;
                transition: stroke 0.3s;
            }
            .allpoints-link .ap-grey-fill {
                fill: #1a1b30;
                transition: fill 0.3s;
            }
            .allpoints-link:hover .ap-grey {
                stroke: #ffffff;
            }
            .allpoints-link:hover .ap-grey-fill {
                fill: #ffffff;
            }

            /* === Footer === */
            footer {
                position: relative;
                z-index: 1;
                padding: 3rem 2rem;
                text-align: center;
                font-size: 0.82rem;
                color: var(--xp-text-subtle);
                border-top: 1px solid var(--xp-border);
                max-width: 1200px;
                margin: 0 auto;
            }
            footer a {
                color: var(--xp-text-subtle);
                text-decoration: none;
                transition: color 0.2s;
            }
            footer a:hover {
                color: var(--xp-text-primary);
            }
            .footer-inner {
                display: flex;
                align-items: center;
                justify-content: space-between;
                flex-wrap: wrap;
                gap: 1rem;
            }

            /* === Open Standard Section === */
            .open-section {
                padding-top: 6rem;
                padding-bottom: 6rem;
                text-align: center;
            }
            /* Deterministic formula visual */
            .open-formula {
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 16px;
                margin: 2.5rem auto 1.5rem;
                flex-wrap: wrap;
                font-family: var(--xp-font-mono);
            }
            .open-chip {
                padding: 14px 24px;
                border-radius: 12px;
                background: var(--xp-bg-elevated);
                border: 2px solid var(--xp-border);
                color: var(--xp-text-primary);
                font-size: 1rem;
                font-weight: 500;
                letter-spacing: 0.04em;
                text-transform: uppercase;
                position: relative;
                animation: open-chip-glow 2.4s ease-in-out infinite;
            }
            .open-chip[data-open="state"]      { border-color: var(--xp-accent);  color: var(--xp-accent);  animation-delay: 0s; }
            .open-chip[data-open="event"]      { border-color: var(--xp-orange);  color: #fdba74;        animation-delay: 0.4s; }
            .open-chip[data-open="transition"] { border-color: #34d399;         color: #34d399;        animation-delay: 0.8s; }
            @keyframes open-chip-glow {
                0%, 100% { box-shadow: 0 0 0 0 currentColor; }
                50%      { box-shadow: 0 0 18px -2px currentColor; }
            }
            .open-op {
                font-family: var(--xp-font-heading);
                font-size: 1.6rem;
                font-weight: 300;
                color: var(--xp-text-subtle);
            }
            .open-equals {
                color: var(--xp-accent);
            }
            @media (max-width: 560px) {
                .open-formula {
                    flex-direction: column;
                    gap: 10px;
                    margin: 2rem auto 1.25rem;
                }
                .open-chip { padding: 10px 22px; font-size: 0.95rem; }
                .open-op { font-size: 1.25rem; line-height: 1; }
            }
            .open-axiom {
                text-align: center;
                font-family: var(--xp-font-heading);
                font-size: 1.35rem;
                font-weight: 500;
                color: var(--xp-text-primary);
                margin: 0.5rem auto 0.75rem;
                max-width: 640px;
            }
            .open-axiom strong {
                color: var(--xp-accent);
                font-weight: 700;
            }
            .open-sub {
                text-align: center;
                max-width: 560px;
                margin: 0 auto 2rem;
                color: var(--xp-text-secondary);
                font-size: 0.95rem;
                line-height: 1.55;
            }

            /* Open-card mini visualisations */
            .open-viz {
                margin-bottom: 1rem;
                padding: 12px 14px;
                border-radius: 10px;
                background: rgba(5, 5, 7, 0.6);
                border: 1px solid var(--xp-border);
                display: flex;
                align-items: center;
                gap: 8px;
                flex-wrap: wrap;
                font-family: var(--xp-font-mono);
                font-size: 0.72rem;
                /* Equal height across all six illustration boxes — sized to the
                   tallest (the 3-row privacy box: transient/bounded/retained).
                   align-items:center keeps shorter boxes' content centred. */
                min-height: 112px;
            }
            .open-viz-chip {
                padding: 4px 10px;
                border-radius: 999px;
                border: 1px solid var(--xp-border);
                background: var(--xp-bg-elevated);
                color: var(--xp-text-primary);
            }
            .open-viz-chip.agent     { border-color: rgba(236,72,153,.4); color: #f472b6; }
            .open-viz-chip.policy    { border-color: rgba(34,197,94,.4);  color: #4ade80; }
            .open-viz-chip.decision  { border-color: rgba(59,130,246,.5); color: var(--xp-accent); background: rgba(59,130,246,.1); }
            .open-viz-chip.journey   { border-color: rgba(124,58,237,.4); color: #a78bfa; }
            .open-viz-chip.keepsake  { border-color: rgba(251,191,36,.4); color: #fbbf24; }
            .open-viz-chip.xdl       { border-color: rgba(59,130,246,.5); color: var(--xp-accent); }
            .open-viz-chip.chat      { border-color: rgba(59,130,246,.4); color: var(--xp-accent); }
            .open-viz-chip.canvas    { border-color: rgba(168,85,247,.4); color: var(--xp-purple); }
            .open-viz-arrow {
                color: var(--xp-text-subtle);
                font-size: 1rem;
            }

            /* Graceful degradation bars */
            .open-viz-bars {
                flex-direction: column;
                align-items: stretch;
                gap: 6px;
            }
            .open-bar {
                display: flex;
                align-items: center;
                justify-content: space-between;
                gap: 10px;
                font-size: 0.62rem;
                color: var(--xp-text-subtle);
            }
            .open-bar span { flex: 1; }
            .open-bar div { display: flex; gap: 3px; }
            .open-bar i {
                width: 16px; height: 8px; border-radius: 2px;
                background: var(--xp-green); display: block;
            }
            .open-bar i.off { background: var(--xp-border); }
            .open-bar i.sim {
                background: transparent;
                border: 1px dashed rgba(148, 163, 184, 0.5);
            }
            .open-bar.full span    { color: #4ade80; }
            .open-bar.partial span { color: #fbbf24; }
            .open-bar.sim span     { color: var(--xp-text-subtle); }

            /* Privacy */
            .open-viz-privacy {
                flex-direction: column;
                align-items: stretch;
                gap: 6px;
            }
            .open-privacy-row {
                display: flex;
                align-items: center;
                gap: 10px;
                font-size: 0.68rem;
            }
            .open-privacy-mode {
                padding: 3px 9px;
                border-radius: 4px;
                font-family: var(--xp-font-mono);
                min-width: 80px;
                text-align: center;
            }
            .open-privacy-mode.transient { background: rgba(168,85,247,.15); color: var(--xp-purple); border: 1px solid rgba(168,85,247,.3); }
            .open-privacy-mode.bounded   { background: rgba(59,130,246,.15); color: var(--xp-accent); border: 1px solid rgba(59,130,246,.3); }
            .open-privacy-mode.retained  { background: rgba(245,158,11,.12); color: #fbbf24; border: 1px solid rgba(245,158,11,.3); }
            .open-privacy-life { color: var(--xp-text-subtle); }

            /* Souvenir */
            .open-souvenir {
                color: #fbbf24;
                font-size: 1.3rem;
                animation: breathe-glow 3s ease-in-out infinite;
            }

            /* Fanout */
            .open-viz-fanout {
                flex-direction: column;
                align-items: center;
                gap: 10px;
            }
            .open-fanout-arms {
                display: flex;
                gap: 6px;
                flex-wrap: wrap;
                justify-content: center;
            }
            .open-venue {
                padding: 3px 10px;
                border-radius: 999px;
                border: 1px solid var(--xp-border);
                font-size: 0.66rem;
                color: var(--xp-text-primary);
                background: rgba(13,13,18,.6);
            }

            /* Creative-first merge */
            .open-viz-merge {
                justify-content: space-between;
            }
            .open-merge-left {
                display: flex;
                flex-direction: column;
                gap: 4px;
            }
            .open-merge-arrow {
                color: var(--xp-text-subtle);
                font-size: 1.3rem;
            }
            /* Lighter grey for the muted captions inside the (dark) philosophy
               illustration boxes — easier to read on the near-black panel in
               both themes. (Coloured bar labels keep their hue via higher
               specificity rules above.) */
            .open-privacy-life,
            .open-bar,
            .open-bar.sim span,
            .open-viz-arrow,
            .open-merge-arrow {
                color: #b4b6c2;
            }

            .open-grid {
                display: grid;
                grid-template-columns: repeat(3, 1fr);
                gap: 1.5rem;
                margin-top: 3rem;
                text-align: left;
            }
            .open-card {
                padding: 2rem;
                border-radius: 12px;
                border: 1px solid var(--xp-border);
                background: var(--xp-bg-surface);
                transition: all 0.3s;
            }
            .open-card:hover {
                background: var(--xp-bg-elevated);
                transform: translateY(-2px);
            }
            .open-card h3 {
                font-size: 1rem;
                font-weight: 600;
                margin-bottom: 0.5rem;
                color: var(--xp-text-primary);
            }
            .open-card p {
                font-size: 0.88rem;
                color: var(--xp-text-secondary);
                line-height: 1.6;
            }

            /* === Skip Link === */
            .skip {
                position: absolute;
                left: -9999px;
                top: auto;
                width: 1px;
                height: 1px;
                overflow: hidden;
            }
            .skip:focus {
                position: fixed;
                top: 8px;
                left: 8px;
                z-index: 200;
                width: auto;
                height: auto;
                padding: 12px 20px;
                background: var(--xp-accent);
                color: #fff;
                border-radius: 8px;
                font-size: 0.9rem;
                text-decoration: none;
            }

            /* === Responsive === */
            @media (max-width: 900px) {
                .xdl-split {
                    grid-template-columns: 1fr;
                }
                .perception-grid {
                    grid-template-columns: repeat(2, 1fr);
                }
                .usecase-grid {
                    grid-template-columns: repeat(2, 1fr);
                }
                .stack-band-tiles {
                    grid-template-columns: 1fr;
                }
                .open-grid {
                    grid-template-columns: 1fr;
                }
                .nav-links {
                    gap: 1.2rem;
                }
            }
            @media (max-width: 640px) {
                .nav-links {
                    display: none;
                }
                /* Mobile nav: logo (left, grid col 1) · "Get Started" centred ·
                   theme icon + burger hard right. The CTA is absolutely centred
                   in the fixed nav so it's independent of the right-aligned
                   actions; the theme menu + burger sit in .nav-actions (grid
                   col 3, justify-self:end) → pinned to the right edge. The CTA
                   goes transparent (ghost) on mobile. */
                .nav-cta {
                    position: absolute;
                    left: 50%;
                    top: 50%;
                    transform: translate(-50%, -50%);
                    background: transparent;
                    color: var(--xp-accent);
                    border: 1px solid color-mix(in srgb, var(--xp-accent) 45%, transparent);
                }
                .nav-cta:hover {
                    background: transparent;
                    color: var(--xp-accent-hover);
                    box-shadow: none;
                }
                /* .nav-links is display:none here, so grid AUTO-placement would
                   slide .nav-actions into the centre track (under the absolutely
                   centred CTA) — pin it to column 3 explicitly so the theme icon
                   and burger actually sit at the right edge. */
                .nav-actions {
                    grid-column: 3;
                }
                .nav-burger {
                    display: inline-flex;
                }
                /* Connector Fabric marquee: the 120px edge fades eat most of a
                   phone's width (240px of ~390px), leaving the scrolling
                   protocol names barely visible. Shrink the fades on mobile so
                   the animation reads. */
                .protocol-stream-permanent::before,
                .protocol-stream-permanent::after {
                    width: 40px;
                }
                /* Scroll-snap sections on mobile.
                   `proximity` nudges to section boundaries without trapping
                   the user inside sections taller than the viewport. */
                html {
                    scroll-snap-type: y proximity;
                    scroll-padding-top: 64px;
                }
                section[id] {
                    scroll-snap-align: start;
                }
                /* Pause CSS animations in sections scrolled off-screen.
                   JS-driven demos listen for the `xp:pause` / `xp:resume`
                   events dispatched alongside this class (see app.js). */
                section.section-offscreen,
                section.section-offscreen *,
                section.section-offscreen *::before,
                section.section-offscreen *::after {
                    animation-play-state: paused !important;
                }
            }
            @media (max-width: 600px) {
                .section {
                    padding: 5rem 1.25rem;
                }
                .hero {
                    padding: 6rem 1.25rem 4rem;
                }
                .perception-grid {
                    grid-template-columns: 1fr;
                }
                .usecase-grid {
                    grid-template-columns: 1fr;
                }
                .signup {
                    flex-direction: column;
                    gap: 10px;
                    max-width: 100%;
                }
                .signup input[type="email"] {
                    border-right: 1px solid var(--xp-border);
                    border-radius: 10px;
                }
                .signup button {
                    border-radius: 10px;
                    width: 100%;
                }
                .hero-ctas {
                    flex-direction: column;
                    width: 100%;
                    max-width: 320px;
                }
                .hero-ctas .btn {
                    width: 100%;
                    justify-content: center;
                }
                .footer-inner {
                    flex-direction: column;
                    text-align: center;
                    gap: 0.5rem;
                }
                /* XDL code block — scroll instead of clip */
                .bridge-io {
                    font-size: 0.72rem;
                    padding: 8px 12px;
                }
                .bridge-chip {
                    font-size: 0.65rem;
                    padding: 3px 6px;
                }
                .bridge-log {
                    font-size: 0.68rem;
                    max-height: 100px;
                    padding: 6px 10px;
                }
                /* Partners — wrap on mobile */
                .partners-logos {
                    flex-wrap: wrap;
                    gap: 1rem;
                }
                /* Featured project — reduce vertical padding */
                .featured-project {
                    padding: 5rem 1.25rem 6rem;
                }
                .featured-project-title-img {
                    max-width: 85%;
                }
                /* Install section — less padding */
                .install-section {
                    padding-top: 6rem;
                    padding-bottom: 8rem;
                }
                /* Electric canvas — hidden on mobile until signup is focused */
                .electric-canvas {
                    display: none;
                }
                .electric-canvas.active {
                    display: block;
                }
                .install-section::before,
                .install-section::after {
                    display: none;
                }
                /* Demo stage pills smaller */
                .demo-stage-pill {
                    font-size: 0.7rem;
                    padding: 6px 10px;
                }
                /* Brief: hide sidebar, full-width chat */
                .demo-brief {
                    grid-template-columns: 1fr !important;
                }
                .demo-sidebar {
                    display: none !important;
                }
                /* Journey: vertical stack — let stages flow naturally, no clipping */
                .demo-journey {
                    flex-direction: column !important;
                    height: auto !important;
                    overflow-x: hidden !important;
                    overflow-y: visible !important;
                    gap: 10px !important;
                }
                .demo-stage-col {
                    width: 100% !important;
                    min-width: 0 !important;
                    flex: 0 0 auto !important;
                }
                /* Generate: smaller XDL text */
                .demo-gen-line {
                    font-size: 0.68rem !important;
                }
                /* Visualise: extend viewport, simpler fidelity */
                .demo-vis {
                    min-height: auto !important;
                }
                .demo-vis-fidelity {
                    flex-wrap: nowrap;
                    gap: 4px;
                    overflow: hidden;
                }
                .demo-vis-fid {
                    font-size: 0.6rem;
                    padding: 3px 7px;
                    display: none;
                }
                .demo-vis-fid.active,
                .demo-vis-fid.done {
                    display: inline-block;
                }
                .demo-vis-fid-label {
                    display: none;
                }
                .demo-vis-cost {
                    display: none;
                }
                .demo-vis-tabs-hint {
                    display: none !important;
                }
                /* Screenplay: smaller text */
                .demo-vis-beat {
                    font-size: 0.68rem;
                    line-height: 1.6;
                }
                .demo-vis-beat-desc {
                    display: none;
                }
                /* Storyboard: 3 cols to keep the viewport short */
                .demo-vis-grid {
                    grid-template-columns: repeat(3, 1fr) !important;
                }
                .demo-vis-body {
                    grid-template-columns: 1fr !important;
                    max-height: none !important;
                    overflow: visible !important;
                }
                /* Walkthrough: 1 col × 3 rows stacked inline (not overlay) on mobile */
                .demo-vis-walkthrough {
                    position: relative !important;
                    inset: auto !important;
                    padding: 0 !important;
                    background: transparent !important;
                }
                .demo-vis-walkthrough.active {
                    grid-template-columns: 1fr !important;
                    grid-auto-rows: auto;
                    align-content: start !important;
                    padding: 0 !important;
                    background: transparent !important;
                }
                /* Slides — single column */
                .demo-slides {
                    grid-template-columns: 1fr !important;
                }
                /* Demo section / frame — tighten padding so scenes get more width */
                .demo-section {
                    padding: 4rem 0.75rem 6rem !important;
                }
                .demo-frame {
                    min-height: 600px;
                    max-height: none;
                    height: auto;
                }
                .demo-viewport {
                    padding: 10px !important;
                    min-height: auto !important;
                }
                .demo-scene {
                    position: relative !important;
                    inset: auto !important;
                    padding: 6px !important;
                    display: none;
                }
                .demo-scene.active {
                    display: block;
                }
                .demo-generate-output {
                    padding: 12px 14px !important;
                }
                /* Bridge mobile — remove blank space */
                .bridge-viewport {
                    min-height: auto !important;
                }
                .bridge-agents {
                    position: relative !important;
                    top: auto !important;
                    right: auto !important;
                    width: 100% !important;
                    margin-top: 8px;
                    display: none;
                }
                .bridge-agents.visible {
                    display: block;
                }
                .bridge-canvas {
                    min-height: 280px;
                }
                /* Bridge mobile — modes: shrink pills so all three fit at 375px */
                .bridge-modes {
                    gap: 6px !important;
                    padding: 10px 10px !important;
                    flex-wrap: nowrap !important;
                    justify-content: flex-start !important;
                }
                .bridge-mode-pill {
                    padding: 5px 9px !important;
                    font-size: 0.68rem !important;
                    flex: 0 0 auto !important;
                }
                .bridge-mode-pill.done::before {
                    margin-right: 1px;
                }
                .bridge-titlebar {
                    padding: 10px 12px !important;
                    gap: 8px !important;
                }
                .bridge-titlebar-label {
                    font-size: 0.7rem !important;
                }
            }

            /* === Reduced Motion === */
            @media (prefers-reduced-motion: reduce) {
                .sr {
                    transition: none;
                    opacity: 1;
                    transform: none;
                }
                .ambient-glow {
                    animation: none;
                    opacity: 0.5;
                }
                .cursor {
                    animation: none;
                    opacity: 1;
                }
                .protocol-row {
                    animation: none;
                }
                .perception-card-orb {
                    animation: none;
                }
                .section-advance {
                    animation: none;
                }
                html {
                    scroll-behavior: auto;
                }
            }

            /* === Pipeline demo === */
            .demo-section {
                padding: 4rem 1.5rem 6rem;
                max-width: 1200px;
                margin: 0 auto;
                position: relative;
                z-index: 1;
            }
            .demo-frame {
                margin-top: 3rem;
                min-height: 715px;
                background: var(--xp-bg-surface);
                border: 1px solid var(--xp-border);
                border-radius: 16px;
                overflow: hidden;
                box-shadow:
                    0 8px 60px rgba(0, 0, 0, 0.4),
                    0 0 120px rgba(59, 130, 246, 0.08);
            }
            .demo-titlebar {
                display: flex;
                align-items: center;
                gap: 8px;
                padding: 14px 20px;
                border-bottom: 1px solid var(--xp-border);
                background: rgba(0, 0, 0, 0.2);
            }
            .demo-titlebar-dot {
                width: 10px;
                height: 10px;
                border-radius: 50%;
                background: #2a2a2e;
            }
            .demo-titlebar-dot:nth-child(1) { background: #ff5f57; }
            .demo-titlebar-dot:nth-child(2) { background: #febc2e; }
            .demo-titlebar-dot:nth-child(3) { background: var(--xp-accent); }
            .demo-titlebar-label {
                margin-left: 12px;
                font-family: var(--xp-font-mono);
                font-size: 0.72rem;
                color: var(--xp-text-subtle);
            }
            .demo-titlebar-clock {
                margin-left: auto;
                font-family: var(--xp-font-mono);
                font-size: 0.72rem;
                color: var(--xp-text-subtle);
            }

            .demo-stages {
                display: flex;
                padding: 16px 20px;
                gap: 8px;
                border-bottom: 1px solid var(--xp-border);
                background: rgba(0, 0, 0, 0.15);
            }
            .demo-stage-pill {
                flex: 1;
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 10px;
                padding: 10px 14px;
                border-radius: 999px;
                font-family: var(--xp-font-heading);
                font-size: 0.8rem;
                font-weight: 500;
                color: var(--xp-text-subtle);
                border: 1px solid var(--xp-border);
                cursor: pointer;
                user-select: none;
                transition:
                    color 0.3s,
                    background 0.3s,
                    border-color 0.3s,
                    box-shadow 0.3s;
            }
            .demo-stage-pill:hover {
                color: var(--xp-text-primary);
                border-color: rgba(59, 130, 246, 0.35);
            }
            .demo-stage-pill:focus-visible {
                outline: none;
                box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5);
            }
            .demo-stage-pill.done {
                color: var(--xp-text-primary);
                border-color: rgba(52, 211, 153, 0.4);
            }
            .demo-stage-pill.active {
                color: var(--xp-text-primary);
                background: rgba(59, 130, 246, 0.12);
                border-color: rgba(59, 130, 246, 0.5);
            }
            .demo-stage-num {
                display: inline-flex;
                align-items: center;
                justify-content: center;
                width: 20px;
                height: 20px;
                border-radius: 50%;
                background: var(--xp-border);
                font-family: var(--xp-font-mono);
                font-size: 0.68rem;
                color: var(--xp-text-subtle);
                transition: background 0.3s, color 0.3s;
            }
            .demo-stage-pill.done .demo-stage-num {
                background: #34d399;
                color: #05130c;
            }
            .demo-stage-pill.active .demo-stage-num {
                background: var(--xp-accent);
                color: white;
            }

            .demo-viewport {
                position: relative;
                min-height: 560px;
                padding: 28px;
            }
            .demo-caption {
                padding: 14px 20px;
                border-top: 1px solid var(--xp-border);
                font-family: var(--xp-font-body);
                font-size: 0.86rem;
                color: var(--xp-text-subtle);
                background: rgba(0, 0, 0, 0.15);
                min-height: 46px;
            }
            .demo-caption strong {
                color: var(--xp-text-primary);
                font-weight: 500;
            }

            .demo-scene {
                position: absolute;
                inset: 28px;
                opacity: 0;
                visibility: hidden;
                transition: opacity 0.5s ease;
            }
            .demo-scene.active {
                opacity: 1;
                visibility: visible;
            }

            /* Scene: Brief */
            .demo-brief {
                display: grid;
                grid-template-columns: 1.6fr 1fr;
                gap: 20px;
                height: 100%;
            }
            .demo-chat {
                display: flex;
                flex-direction: column;
                gap: 12px;
                font-family: var(--xp-font-body);
                font-size: 0.88rem;
                line-height: 1.55;
                overflow-y: auto;
                overflow-x: hidden;
            }
            .demo-chat-msg {
                padding: 12px 16px;
                border-radius: 12px;
                max-width: 90%;
                opacity: 0;
                transform: translateY(8px);
                transition:
                    opacity 0.5s ease,
                    transform 0.5s ease;
            }
            .demo-chat-msg.visible {
                opacity: 1;
                transform: translateY(0);
            }
            .demo-chat-msg.user {
                align-self: flex-end;
                background: rgba(59, 130, 246, 0.12);
                border: 1px solid rgba(59, 130, 246, 0.3);
            }
            .demo-chat-msg.assistant {
                align-self: flex-start;
                background: var(--xp-bg);
                border: 1px solid var(--xp-border);
            }
            /* Brief: fast-forward blurred placeholder bubbles —
               rapid-fire alternating bars that suggest a longer
               conversation happened. Visible enough to read as
               "chat happened here" but blurred so you don't try
               to read the text. */
            .demo-chat-ff {
                border-radius: 10px;
                min-height: 22px;
                width: 72%;
                opacity: 0;
                transform: translateY(4px) scaleY(0.9);
                transition:
                    opacity 0.18s ease,
                    transform 0.18s ease;
                filter: blur(3px);
            }
            .demo-chat-ff.visible {
                opacity: 0.65;
                transform: translateY(0) scaleY(1);
            }
            .demo-chat-ff.user-ff {
                align-self: flex-end;
                background: rgba(59, 130, 246, 0.18);
                border: 1px solid rgba(59, 130, 246, 0.25);
            }
            .demo-chat-ff.asst-ff {
                align-self: flex-start;
                background: rgba(30, 30, 42, 0.9);
                border: 1px solid var(--xp-border);
            }
            .demo-chat-ff:nth-child(odd) {
                width: 55%;
                min-height: 32px;
            }
            .demo-chat-ff:nth-child(3n) {
                min-height: 42px;
            }
            /* Brief: uploaded-document card that seeds the conversation */
            .demo-chat-upload {
                align-self: flex-start;
                display: flex;
                align-items: center;
                gap: 10px;
                padding: 10px 14px;
                background: rgba(59, 130, 246, 0.06);
                border: 1px solid rgba(59, 130, 246, 0.25);
                border-radius: 10px;
                max-width: 92%;
                opacity: 0;
                transform: translateY(8px);
                transition:
                    opacity 0.5s ease,
                    transform 0.5s ease;
            }
            .demo-chat-upload.visible {
                opacity: 1;
                transform: translateY(0);
            }
            .demo-chat-upload-icon {
                width: 28px;
                height: 28px;
                border-radius: 6px;
                background: rgba(59, 130, 246, 0.15);
                display: flex;
                align-items: center;
                justify-content: center;
                color: var(--xp-accent);
                flex-shrink: 0;
            }
            .demo-chat-upload-meta {
                display: flex;
                flex-direction: column;
                gap: 1px;
                min-width: 0;
            }
            .demo-chat-upload-name {
                font-family: var(--xp-font-mono);
                font-size: 0.78rem;
                color: var(--xp-text-primary);
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
            }
            .demo-chat-upload-info {
                font-family: var(--xp-font-body);
                font-size: 0.68rem;
                color: var(--xp-text-subtle);
                display: flex;
                align-items: center;
                gap: 6px;
            }
            .demo-chat-upload-info .demo-upload-dot {
                width: 6px;
                height: 6px;
                border-radius: 50%;
                background: var(--xp-accent);
                animation: demo-status-pulse 1.6s ease-out infinite;
            }
            .demo-chat-upload.ready .demo-chat-upload-info .demo-upload-dot {
                background: #34d399;
                animation: none;
            }
            .demo-chat-msg .cursor {
                /* Use the install terminal's .cursor, sized for chat body
                   and tinted white to contrast with the bubble backgrounds. */
                background: #ffffff;
                width: 7px;
                height: 1em;
                vertical-align: -2px;
                margin-left: 1px;
            }
            .demo-typing {
                display: inline-flex;
                gap: 4px;
                padding: 4px 0;
            }
            .demo-typing span {
                width: 6px;
                height: 6px;
                border-radius: 50%;
                background: var(--xp-text-subtle);
                animation: demo-bounce 1.2s ease infinite;
            }
            .demo-typing span:nth-child(2) { animation-delay: 0.15s; }
            .demo-typing span:nth-child(3) { animation-delay: 0.3s; }
            @keyframes demo-bounce {
                0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
                30% { transform: translateY(-3px); opacity: 1; }
            }

            .demo-sidebar {
                display: flex;
                flex-direction: column;
                gap: 14px;
                border-left: 1px solid var(--xp-border);
                padding-left: 20px;
                overflow-y: auto;
                overflow-x: hidden;
                scroll-behavior: smooth;
            }
            .demo-sidebar-head {
                display: flex;
                align-items: center;
                justify-content: space-between;
                gap: 10px;
                padding-bottom: 12px;
                border-bottom: 1px solid var(--xp-border);
                margin-bottom: 2px;
            }
            .demo-sidebar-title {
                display: flex;
                align-items: center;
                gap: 8px;
                font-family: var(--xp-font-heading);
                font-size: 0.66rem;
                font-weight: 600;
                text-transform: uppercase;
                letter-spacing: 0.14em;
                color: #b8a898; /* warm-text from xpstudio */
            }
            .demo-sidebar-status {
                width: 7px;
                height: 7px;
                border-radius: 50%;
                background: var(--xp-accent);
                box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.6);
                animation: demo-status-pulse 1.8s ease-out infinite;
            }
            @keyframes demo-status-pulse {
                0%   { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.5); }
                70%  { box-shadow: 0 0 0 6px rgba(59, 130, 246, 0); }
                100% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0); }
            }
            .demo-sidebar-collapse {
                color: var(--xp-text-subtle);
                display: flex;
                opacity: 0.6;
            }
            .demo-sidebar-meta {
                display: flex;
                flex-direction: column;
                gap: 8px;
                padding-bottom: 12px;
                border-bottom: 1px solid var(--xp-border);
            }
            .demo-meta-item {
                display: flex;
                flex-direction: column;
                gap: 1px;
                opacity: 0;
                transform: translateY(4px);
                transition: opacity 0.35s ease, transform 0.35s ease;
            }
            .demo-meta-item.visible {
                opacity: 1;
                transform: translateY(0);
            }
            .demo-meta-label {
                font-family: var(--xp-font-heading);
                font-size: 0.58rem;
                font-weight: 600;
                text-transform: uppercase;
                letter-spacing: 0.12em;
                color: #b8a898;
            }
            .demo-meta-value {
                font-family: var(--xp-font-body);
                font-size: 0.76rem;
                color: var(--xp-text-primary);
                line-height: 1.35;
            }
            .demo-meta-value.bold {
                font-family: var(--xp-font-heading);
                font-weight: 600;
                font-size: 0.82rem;
            }
            .demo-meta-pills {
                display: flex;
                flex-wrap: wrap;
                gap: 4px;
                opacity: 0;
                transform: translateY(4px);
                transition: opacity 0.35s ease, transform 0.35s ease;
            }
            .demo-meta-pills.visible {
                opacity: 1;
                transform: translateY(0);
            }
            .demo-meta-pill {
                font-family: var(--xp-font-mono);
                font-size: 0.58rem;
                padding: 2px 7px;
                border-radius: 999px;
                border: 1px solid rgba(184, 168, 152, 0.25);
                color: #b8a898;
                background: rgba(184, 168, 152, 0.06);
            }
            .demo-meta-pill.perception {
                border-color: rgba(249, 115, 22, 0.3);
                color: #fdba74;
                background: rgba(249, 115, 22, 0.08);
            }
            .demo-meta-pill.accent {
                border-color: rgba(59, 130, 246, 0.3);
                color: var(--xp-accent);
                background: rgba(59, 130, 246, 0.08);
            }
            .demo-sidebar-group {
                display: flex;
                flex-direction: column;
                gap: 6px;
            }
            .demo-sidebar-label {
                font-family: var(--xp-font-heading);
                font-size: 0.7rem;
                font-weight: 600;
                color: var(--xp-text-subtle);
                text-transform: uppercase;
                letter-spacing: 0.1em;
            }
            .demo-lens-item {
                display: flex;
                align-items: center;
                gap: 10px;
                padding: 6px 10px;
                background: var(--xp-bg);
                border: 1px solid var(--xp-border);
                border-radius: 6px;
                font-family: var(--xp-font-body);
                font-size: 0.78rem;
                color: var(--xp-text-primary);
                opacity: 0;
                transform: translateX(12px);
                transition:
                    opacity 0.35s ease,
                    transform 0.35s ease;
            }
            .demo-lens-item.visible {
                opacity: 1;
                transform: translateX(0);
            }
            .demo-lens-dot {
                width: 8px;
                height: 8px;
                border-radius: 50%;
                flex-shrink: 0;
            }

            /* Scene: Journey — mirrors xpstudio's JourneyTimeline layout */
            .demo-journey {
                display: flex;
                gap: 10px;
                height: 100%;
                overflow-x: auto;
                overflow-y: hidden;
                padding-bottom: 4px;
            }
            .demo-stage-col {
                flex: 1 0 0;
                min-width: 175px;
                display: flex;
                flex-direction: column;
                background: rgba(13, 13, 18, 0.4);
                border: 1px solid var(--xp-border);
                border-radius: 10px;
                overflow: hidden;
            }
            .demo-stage-col-bar {
                height: 2px;
                background: var(--stage-color, var(--xp-accent));
            }
            .demo-stage-col-head {
                padding: 10px 12px 8px;
                border-bottom: 1px solid var(--xp-border);
                background: rgba(0, 0, 0, 0.2);
                opacity: 0;
                transform: translateY(6px);
                transition: opacity 0.35s ease, transform 0.35s ease;
            }
            .demo-stage-col-head.visible {
                opacity: 1;
                transform: translateY(0);
            }
            .demo-stage-col-title {
                font-family: var(--xp-font-heading);
                font-size: 1.4rem;
                font-weight: 600;
                color: var(--xp-text-primary);
                line-height: 1.15;
                display: flex;
                align-items: baseline;
                justify-content: space-between;
                gap: 6px;
            }
            .demo-stage-col-count {
                font-family: var(--xp-font-mono);
                font-size: 0.62rem;
                font-weight: 400;
                color: var(--xp-text-subtle);
            }
            .demo-stage-col-meta {
                margin-top: 6px;
                display: flex;
                flex-wrap: wrap;
                gap: 4px;
            }
            .demo-perception-tag {
                font-family: var(--xp-font-mono);
                font-size: 0.6rem;
                padding: 2px 7px;
                border-radius: 999px;
                background: rgba(247, 115, 22, 0.08);
                color: #fdba74;
                border: 1px solid rgba(247, 115, 22, 0.25);
            }
            .demo-stage-col-moments {
                display: flex;
                flex-direction: column;
                gap: 6px;
                padding: 10px;
                flex: 1;
            }
            .demo-moment {
                position: relative;
                display: flex;
                flex-direction: column;
                gap: 3px;
                padding: 9px 10px;
                background: var(--xp-bg);
                border: 1px solid var(--xp-border);
                border-radius: 8px;
                opacity: 0;
                transform: translateY(8px) scale(0.98);
                transition:
                    opacity 0.35s ease,
                    transform 0.35s ease;
            }
            .demo-moment.visible {
                opacity: 1;
                transform: translateY(0) scale(1);
            }
            .demo-moment.is-key {
                border-color: rgba(245, 158, 11, 0.35);
                box-shadow: 0 0 0 1px rgba(245, 158, 11, 0.12);
            }
            .demo-moment-title {
                font-family: var(--xp-font-heading);
                font-size: 0.78rem;
                font-weight: 500;
                color: var(--xp-text-primary);
                line-height: 1.25;
                padding-right: 12px;
            }
            .demo-moment-desc {
                font-family: var(--xp-font-body);
                font-size: 0.7rem;
                color: var(--xp-text-subtle);
                font-style: italic;
                line-height: 1.35;
            }
            .demo-moment-type {
                display: inline-block;
                margin-top: 2px;
                align-self: flex-start;
                padding: 1px 6px;
                border-radius: 999px;
                background: rgba(59, 130, 246, 0.1);
                color: var(--xp-accent);
                font-family: var(--xp-font-mono);
                font-size: 0.58rem;
                text-transform: uppercase;
                letter-spacing: 0.06em;
            }
            .demo-moment-type.peak,
            .demo-moment-type.capture {
                background: rgba(236, 72, 153, 0.1);
                color: #f472b6;
            }
            .demo-moment-type.trigger,
            .demo-moment-type.generation {
                background: rgba(168, 85, 247, 0.1);
                color: #c084fc;
            }
            .demo-moment-type.arrival,
            .demo-moment-type.transition {
                background: rgba(34, 197, 94, 0.1);
                color: #4ade80;
            }
            .demo-moment-type.delivery,
            .demo-moment-type.departure {
                background: rgba(245, 158, 11, 0.1);
                color: #fbbf24;
            }
            .demo-moment-star {
                position: absolute;
                top: 6px;
                right: 8px;
                font-size: 0.72rem;
                color: #f59e0b;
                line-height: 1;
            }

            /* Scene: Generate — real-time XDL stream, full width */
            .demo-generate-output {
                height: 100%;
                background: var(--xp-bg);
                border: 1px solid var(--xp-border);
                border-radius: 10px;
                padding: 14px 18px;
                font-family: var(--xp-font-mono);
                font-size: 0.78rem;
                line-height: 1.65;
                overflow-y: auto;
                overflow-x: hidden;
                white-space: pre;
                scroll-behavior: smooth;
            }
            .demo-generate-output::-webkit-scrollbar {
                width: 6px;
            }
            .demo-generate-output::-webkit-scrollbar-thumb {
                background: rgba(255, 255, 255, 0.08);
                border-radius: 3px;
            }
            .demo-gen-line {
                opacity: 0;
                transform: translateY(2px);
                transition:
                    opacity 0.2s,
                    transform 0.2s;
            }
            .demo-gen-line.visible {
                opacity: 1;
                transform: translateY(0);
            }

            /* Scene: Visualise — mirrors xpstudio's render/FidelitySelector +
               Storyboard tab + DetailSidebar layout */
            .demo-vis {
                display: flex;
                flex-direction: column;
                gap: 10px;
                height: 100%;
            }
            .demo-vis-top {
                display: flex;
                align-items: center;
                justify-content: space-between;
                gap: 10px;
            }
            .demo-vis-fidelity {
                display: flex;
                align-items: center;
                gap: 6px;
                font-family: var(--xp-font-mono);
                font-size: 0.7rem;
                color: var(--xp-text-subtle);
                flex-wrap: wrap;
            }
            .demo-vis-fid-label {
                font-weight: 600;
                letter-spacing: 0.08em;
            }
            .demo-vis-fid {
                padding: 4px 10px;
                border: 1px solid var(--xp-border);
                border-radius: 999px;
                background: rgba(0, 0, 0, 0.2);
                color: var(--xp-text-subtle);
                transition: all 0.3s ease;
            }
            .demo-vis-fid.active {
                border-color: rgba(124, 58, 237, 0.5);
                color: var(--xp-text-primary);
                background: rgba(124, 58, 237, 0.1);
                box-shadow: 0 0 0 2px rgba(124, 58, 237, 0.12);
            }
            .demo-vis-fid.done {
                color: var(--xp-text-primary);
                border-color: rgba(52, 211, 153, 0.35);
                opacity: 0.85;
            }
            .demo-vis-fid.done::before {
                content: "✓ ";
                color: #34d399;
                font-weight: 600;
            }
            .demo-vis-cost {
                margin-left: 4px;
                font-style: italic;
                color: var(--xp-text-subtle);
                opacity: 0.7;
            }
            .demo-vis-run {
                padding: 6px 14px;
                border-radius: 8px;
                background: rgba(124, 58, 237, 0.15);
                border: 1px solid rgba(124, 58, 237, 0.4);
                color: var(--xp-text-primary);
                font-family: var(--xp-font-heading);
                font-size: 0.78rem;
                font-weight: 500;
                white-space: nowrap;
            }
            .demo-vis-tabs {
                display: flex;
                align-items: center;
                gap: 18px;
                padding-bottom: 8px;
                border-bottom: 1px solid var(--xp-border);
                font-family: var(--xp-font-heading);
                font-size: 0.78rem;
                color: var(--xp-text-subtle);
            }
            .demo-vis-tab {
                padding-bottom: 4px;
                border-bottom: 2px solid transparent;
                transition: color 0.3s, border-color 0.3s;
            }
            .demo-vis-tab.active {
                color: var(--xp-text-primary);
                border-bottom-color: var(--xp-accent);
            }
            .demo-vis-tabs-hint {
                margin-left: auto;
                font-family: var(--xp-font-mono);
                font-size: 0.68rem;
                color: var(--xp-text-subtle);
            }
            .demo-vis-body {
                position: relative;
                display: grid;
                grid-template-columns: 1fr 300px;
                gap: 16px;
                flex: 1;
                min-height: 0;
            }
            .demo-vis-screenplay {
                display: none;
                position: absolute;
                inset: 0;
                z-index: 2;
                background: var(--xp-bg-surface);
                border: 1px solid var(--xp-border);
                border-radius: 8px;
                padding: 1.25rem 1.5rem;
                font-family: var(--xp-font-mono);
                font-size: 0.78rem;
                line-height: 1.85;
                color: var(--xp-text-secondary);
                overflow-y: auto;
                opacity: 0;
                transition: opacity 0.5s ease;
            }
            .demo-vis-screenplay.active {
                display: block;
                opacity: 1;
            }
            .demo-vis-screenplay.fade-out {
                opacity: 0;
            }
            .demo-vis-beat {
                opacity: 0;
                transform: translateY(4px);
                transition: opacity 0.35s ease, transform 0.35s ease;
                padding: 2px 0;
            }
            .demo-vis-beat.visible {
                opacity: 1;
                transform: translateY(0);
            }
            .demo-vis-beat-stage {
                display: block;
                font-size: 0.65rem;
                padding: 2px 8px;
                border-radius: 3px;
                width: fit-content;
                margin-bottom: 0.5rem;
                margin-top: 0.75rem;
            }
            .demo-vis-beat:first-child .demo-vis-beat-stage {
                margin-top: 0;
                background: rgba(59, 130, 246, 0.1);
                color: var(--xp-accent);
                letter-spacing: 0.04em;
                text-transform: uppercase;
            }
            .demo-vis-beat-title {
                color: #f0f0f4;
                font-weight: 500;
            }
            .demo-vis-beat-desc {
                color: var(--xp-text-secondary);
                font-style: italic;
                margin-left: 0.25rem;
            }
            .demo-vis-walkthrough {
                display: none;
                position: absolute;
                inset: 0;
                z-index: 2;
                border-radius: 8px;
                overflow: hidden;
                opacity: 0;
                transition: opacity 0.5s ease;
            }
            .demo-vis-walkthrough.active {
                display: grid;
                grid-template-columns: repeat(3, 1fr);
                grid-auto-rows: min-content;
                align-content: center;
                gap: 8px;
                padding: 16px;
                background: var(--xp-bg-surface);
                opacity: 1;
            }
            /* When walkthrough overlay is active, hide storyboard + detail behind it */
            .demo-vis-body:has(.demo-vis-walkthrough.active) .demo-vis-grid,
            .demo-vis-body:has(.demo-vis-walkthrough.active) .demo-vis-detail {
                visibility: hidden;
            }
            .demo-vis-walkthrough.fade-out {
                opacity: 0;
            }
            .demo-vis-walkthrough video {
                width: 100%;
                height: 100%;
                object-fit: cover;
                display: block;
            }
            .demo-vis-walkthrough .wt-label {
                position: absolute;
                bottom: 6px;
                left: 8px;
                font-family: var(--xp-font-mono);
                font-size: 0.65rem;
                color: rgba(255,255,255,0.75);
                text-shadow: 0 1px 4px rgba(0,0,0,0.8);
                pointer-events: none;
            }
            .demo-vis-walkthrough .wt-cell {
                position: relative;
                aspect-ratio: 16 / 9;
                border-radius: 6px;
                border: 1px solid var(--xp-border);
                overflow: hidden;
                background: #000;
            }
            .demo-vis-grid {
                display: grid;
                grid-template-columns: repeat(4, 1fr);
                grid-auto-rows: 1fr;
                gap: 8px;
                overflow: hidden;
            }
            .demo-vis-frame {
                position: relative;
                aspect-ratio: 16 / 9;
                border-radius: 6px;
                overflow: hidden;
                background:
                    linear-gradient(
                        180deg,
                        transparent 50%,
                        rgba(5, 5, 7, 0.85) 100%
                    ),
                    linear-gradient(
                        135deg,
                        var(--fv-from, var(--xp-accent)),
                        var(--fv-to, var(--moment))
                    );
                background-size: cover;
                background-position: center;
                border: 1px solid var(--xp-border);
                opacity: 0;
                transform: translateY(8px) scale(0.97);
                transition:
                    opacity 0.35s,
                    transform 0.35s,
                    box-shadow 0.4s,
                    border-color 0.4s;
            }
            .demo-vis-frame.visible {
                opacity: 1;
                transform: translateY(0) scale(1);
            }
            .demo-vis-frame.selected {
                border-color: rgba(59, 130, 246, 0.6);
                box-shadow:
                    0 0 0 1px rgba(59, 130, 246, 0.4),
                    0 0 12px rgba(59, 130, 246, 0.35);
            }
            .demo-vis-frame::after {
                content: "";
                position: absolute;
                inset: 0;
                background: radial-gradient(
                    circle at 25% 25%,
                    rgba(255, 255, 255, 0.22) 0%,
                    transparent 55%
                );
                pointer-events: none;
            }
            .demo-vis-frame-num {
                position: absolute;
                top: 4px;
                left: 6px;
                font-family: var(--xp-font-mono);
                font-size: 0.58rem;
                color: rgba(255, 255, 255, 0.85);
                text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
            }
            .demo-vis-frame-label {
                position: absolute;
                left: 6px;
                right: 6px;
                bottom: 4px;
                font-family: var(--xp-font-heading);
                font-size: 0.62rem;
                color: rgba(255, 255, 255, 0.92);
                text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
            }
            .demo-vis-frame-star {
                position: absolute;
                top: 4px;
                right: 6px;
                font-size: 0.72rem;
                color: #fbbf24;
                text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
            }
            .demo-vis-frame-status {
                position: absolute;
                bottom: 4px;
                right: 6px;
                width: 6px;
                height: 6px;
                border-radius: 50%;
                background: #34d399;
                box-shadow: 0 0 6px rgba(52, 211, 153, 0.6);
            }
            .demo-vis-detail {
                display: flex;
                flex-direction: column;
                gap: 10px;
                padding: 14px;
                background: rgba(13, 13, 18, 0.4);
                border: 1px solid var(--xp-border);
                border-radius: 10px;
                overflow: hidden;
                min-height: 0;
            }
            .demo-vis-detail-beat {
                font-family: var(--xp-font-mono);
                font-size: 0.62rem;
                color: var(--xp-text-subtle);
                text-transform: uppercase;
                letter-spacing: 0.14em;
                opacity: 0;
                transform: translateY(4px);
                transition: opacity 0.4s, transform 0.4s;
            }
            .demo-vis-detail-beat.visible {
                opacity: 1;
                transform: translateY(0);
            }
            .demo-vis-detail-title {
                font-family: var(--xp-font-heading);
                font-size: 0.95rem;
                font-weight: 600;
                color: var(--xp-text-primary);
                line-height: 1.25;
                opacity: 0;
                transform: translateY(4px);
                transition: opacity 0.4s, transform 0.4s;
            }
            .demo-vis-detail-title.visible {
                opacity: 1;
                transform: translateY(0);
            }
            .demo-vis-detail-card {
                display: flex;
                flex-direction: column;
                gap: 4px;
                padding-top: 8px;
                border-top: 1px solid var(--xp-border);
                opacity: 0;
                transform: translateY(6px);
                transition: opacity 0.4s, transform 0.4s;
            }
            .demo-vis-detail-card.visible {
                opacity: 1;
                transform: translateY(0);
            }
            .demo-vis-detail-label {
                font-family: var(--xp-font-heading);
                font-size: 0.62rem;
                font-weight: 600;
                color: var(--xp-text-subtle);
                text-transform: uppercase;
                letter-spacing: 0.1em;
            }
            .demo-vis-detail-body {
                font-family: var(--xp-font-body);
                font-size: 0.76rem;
                color: var(--xp-text-primary);
                line-height: 1.5;
            }
            .demo-vis-detail-body.italic {
                font-style: italic;
                color: var(--xp-text-subtle);
            }
            .demo-vis-swatches {
                display: flex;
                gap: 4px;
                margin-top: 4px;
            }
            .demo-vis-swatch {
                width: 22px;
                height: 22px;
                border-radius: 4px;
                border: 1px solid rgba(255, 255, 255, 0.1);
            }

            /* Scene: Pitch */
            .demo-pitch {
                display: grid;
                grid-template-columns: 1fr 1.5fr;
                gap: 20px;
                height: 100%;
            }
            .demo-deck-meta {
                display: flex;
                flex-direction: column;
                gap: 10px;
            }
            .demo-deck-title {
                font-family: var(--xp-font-heading);
                font-size: 1.05rem;
                font-weight: 600;
                color: var(--xp-text-primary);
                line-height: 1.25;
            }
            .demo-deck-desc {
                font-family: var(--xp-font-body);
                font-size: 0.82rem;
                color: var(--xp-text-subtle);
                line-height: 1.55;
            }
            .demo-deck-cta {
                display: inline-flex;
                align-items: center;
                gap: 8px;
                padding: 10px 16px;
                border-radius: 8px;
                background: var(--xp-accent);
                color: white;
                font-family: var(--xp-font-heading);
                font-size: 0.84rem;
                font-weight: 500;
                align-self: flex-start;
                margin-top: 8px;
                opacity: 0;
                transform: translateY(4px);
                transition:
                    opacity 0.5s,
                    transform 0.5s;
            }
            .demo-deck-cta.visible {
                opacity: 1;
                transform: translateY(0);
            }
            .demo-slides {
                display: grid;
                grid-template-columns: 1fr 1fr;
                grid-template-rows: 1fr 1fr;
                gap: 12px;
            }
            .demo-slide {
                aspect-ratio: 16 / 9;
                background: var(--xp-bg);
                border: 1px solid var(--xp-border);
                border-radius: 8px;
                padding: 14px;
                font-family: var(--xp-font-heading);
                display: flex;
                flex-direction: column;
                justify-content: space-between;
                opacity: 0;
                transform: scale(0.96);
                transition:
                    opacity 0.4s,
                    transform 0.4s;
                position: relative;
                overflow: hidden;
            }
            .demo-slide.visible {
                opacity: 1;
                transform: scale(1);
            }
            .demo-slide-band {
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                height: 3px;
                background: var(--sl-accent, var(--xp-accent));
            }
            .demo-slide-label {
                font-family: var(--xp-font-mono);
                font-size: 0.62rem;
                color: var(--xp-text-subtle);
                text-transform: uppercase;
                letter-spacing: 0.1em;
            }
            .demo-slide-h {
                font-size: 0.9rem;
                font-weight: 600;
                color: var(--xp-text-primary);
                line-height: 1.3;
            }
            .demo-slide-sub {
                font-size: 0.7rem;
                color: #e8e8ec;
                line-height: 1.5;
            }
            .demo-slide-overlay {
                position: relative;
                z-index: 1;
                background: rgba(5, 5, 7, 0.65);
                backdrop-filter: blur(4px);
                -webkit-backdrop-filter: blur(4px);
                border-radius: 4px;
                padding: 8px 10px;
                margin: 6px;
            }
            .demo-slide-overlay .demo-slide-label {
                color: rgba(255, 255, 255, 0.6);
            }
            .demo-slide-overlay .demo-slide-h {
                color: #fff;
            }
            .demo-slide-overlay .demo-slide-sub {
                color: rgba(255, 255, 255, 0.8);
            }

            /* End state */
            .demo-end {
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                gap: 18px;
                text-align: center;
                height: 100%;
            }
            .demo-end-headline {
                font-family: var(--xp-font-heading);
                font-size: 1.35rem;
                font-weight: 500;
                color: var(--xp-text-primary);
            }
            .demo-end-sub {
                font-family: var(--xp-font-body);
                font-size: 0.9rem;
                color: var(--xp-text-subtle);
                max-width: 420px;
            }
            @media (max-width: 900px) {
                .demo-brief,
                .demo-pitch {
                    grid-template-columns: 1fr;
                }
                .demo-sidebar {
                    border-left: none;
                    padding-left: 0;
                    border-top: 1px solid var(--xp-border);
                    padding-top: 16px;
                }
                .demo-journey { flex-direction: column; }
                .demo-vis-body {
                    grid-template-columns: 1fr;
                }
                .demo-vis-grid {
                    grid-template-columns: repeat(3, 1fr);
                }
                .demo-slides { grid-template-rows: auto; }
                .demo-stages { flex-wrap: wrap; }
                .demo-stage-pill { flex: 1 1 40%; }
            }
            @media (prefers-reduced-motion: reduce) {
                .demo-scene,
                .demo-chat-msg,
                .demo-lens-item,
                .demo-moment,
                .demo-gen-line,
                .demo-vis-frame,
                .demo-vis-detail-beat,
                .demo-vis-detail-title,
                .demo-vis-detail-card,
                .demo-slide,
                .demo-deck-cta {
                    transition: opacity 0.2s ease !important;
                    transform: none !important;
                }
                .demo-chat-msg .cursor,
                .demo-typing span {
                    animation: none !important;
                }
            }

            /* ============================================
               XPBRIDGE DEMO
               ============================================ */
            .bridge-section {
                padding: 4rem 1.5rem 6rem;
                max-width: 1200px;
                margin: 0 auto;
                position: relative;
                z-index: 1;
            }
            .bridge-frame {
                margin-top: 3rem;
                background: var(--xp-bg-surface);
                border: 1px solid var(--xp-border);
                border-radius: 16px;
                overflow: hidden;
                box-shadow:
                    0 8px 60px rgba(0, 0, 0, 0.4),
                    0 0 120px rgba(59, 130, 246, 0.08);
            }
            .bridge-titlebar {
                display: flex;
                align-items: center;
                gap: 8px;
                padding: 14px 20px;
                border-bottom: 1px solid var(--xp-border);
                background: rgba(0, 0, 0, 0.2);
            }
            .bridge-titlebar-dot {
                width: 10px;
                height: 10px;
                border-radius: 50%;
                background: #2a2a2e;
            }
            .bridge-titlebar-dot:nth-child(1) { background: #ff5f57; }
            .bridge-titlebar-dot:nth-child(2) { background: #febc2e; }
            .bridge-titlebar-dot:nth-child(3) { background: var(--xp-accent); }
            .bridge-titlebar-label {
                margin-left: 12px;
                font-family: var(--xp-font-mono);
                font-size: 0.72rem;
                color: var(--xp-text-subtle);
            }

            .bridge-modes {
                display: flex;
                align-items: center;
                gap: 8px;
                padding: 12px 20px;
                border-bottom: 1px solid var(--xp-border);
                background: rgba(0, 0, 0, 0.15);
            }
            .bridge-mode-pill {
                padding: 8px 18px;
                border-radius: 999px;
                font-family: var(--xp-font-heading);
                font-size: 0.8rem;
                font-weight: 500;
                color: var(--xp-text-subtle);
                border: 1px solid var(--xp-border);
                cursor: pointer;
                user-select: none;
                transition: color 0.3s, background 0.3s, border-color 0.3s, box-shadow 0.3s;
            }
            .bridge-mode-pill:hover {
                color: var(--xp-text-primary);
                border-color: rgba(59, 130, 246, 0.35);
            }
            .bridge-mode-pill:focus-visible {
                outline: none;
                box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5);
            }
            .bridge-mode-pill.active {
                color: var(--xp-text-primary);
                background: rgba(59, 130, 246, 0.12);
                border-color: rgba(59, 130, 246, 0.5);
            }
            .bridge-mode-pill.done {
                color: var(--xp-text-primary);
                border-color: rgba(52, 211, 153, 0.35);
            }
            .bridge-mode-pill.done::before {
                content: "\2713 ";
                color: #34d399;
                font-weight: 600;
            }

            .bridge-viewport {
                position: relative;
                min-height: 420px;
                background:
                    radial-gradient(circle at 20px 20px, rgba(255,255,255,0.04) 1px, transparent 1px);
                background-size: 24px 24px;
            }
            .bridge-canvas {
                position: relative;
                width: 100%;
                height: 380px;
                overflow: hidden;
            }
            .bridge-stage-label {
                position: absolute;
                font-family: var(--xp-font-heading);
                font-size: 0.66rem;
                font-weight: 600;
                text-transform: uppercase;
                letter-spacing: 0.16em;
                opacity: 0;
                transform: translateY(-3px);
                transition: opacity 0.4s ease, transform 0.4s ease;
                width: 80px;
                text-align: center;
            }
            .bridge-stage-label.visible {
                opacity: 0.85;
                transform: translateY(0);
            }
            .bridge-edges {
                position: absolute;
                inset: 0;
                pointer-events: none;
            }

            /* State nodes — sized to match xpbridge's React Flow state node */
            .bridge-node {
                position: absolute;
                padding: 8px 12px;
                background: var(--xp-bg-elevated);
                border: 2px solid var(--xp-accent);
                border-radius: 8px;
                text-align: center;
                opacity: 0;
                transform: scale(0.92);
                transition: opacity 0.35s ease, transform 0.35s ease,
                            box-shadow 0.5s ease, border-color 0.3s;
                z-index: 2;
                box-sizing: border-box;
            }
            .bridge-node.visible {
                opacity: 1;
                transform: scale(1);
            }
            .bridge-node.active {
                box-shadow:
                    0 0 0 4px rgba(59, 130, 246, 0.2),
                    0 0 24px rgba(59, 130, 246, 0.35);
                animation: bridge-pulse 1.5s ease infinite;
            }
            @keyframes bridge-pulse {
                0%, 100% { box-shadow: 0 0 0 4px rgba(59,130,246,0.2), 0 0 24px rgba(59,130,246,0.35); }
                50%      { box-shadow: 0 0 0 8px rgba(59,130,246,0.1), 0 0 36px rgba(59,130,246,0.2); }
            }
            .bridge-node.key {
                border-style: solid;
            }
            .bridge-node-label {
                font-family: var(--xp-font-heading);
                font-size: 0.76rem;
                font-weight: 600;
                color: var(--xp-text-primary);
                line-height: 1.2;
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
            }
            .bridge-node-stage {
                font-family: var(--xp-font-mono);
                font-size: 0.62rem;
                color: var(--xp-text-subtle);
                margin-top: 3px;
                text-transform: uppercase;
                letter-spacing: 0.08em;
            }
            .bridge-node-initial {
                position: absolute;
                top: 50%;
                right: calc(100% + 10px);
                transform: translateY(-50%);
                font-family: var(--xp-font-mono);
                font-size: 0.56rem;
                padding: 2px 7px;
                border-radius: 4px;
                background: rgba(59, 130, 246, 0.2);
                color: var(--xp-accent);
                text-transform: uppercase;
                letter-spacing: 0.06em;
                white-space: nowrap;
            }
            .bridge-node-key {
                position: absolute;
                top: -8px;
                right: 8px;
                font-size: 0.75rem;
                color: #fbbf24;
                text-shadow: 0 0 6px rgba(251, 191, 36, 0.5);
                line-height: 1;
            }
            .bridge-handle {
                position: absolute;
                top: 50%;
                width: 8px;
                height: 8px;
                border-radius: 50%;
                transform: translateY(-50%);
                border: 1.5px solid var(--xp-bg);
                box-sizing: border-box;
            }
            .bridge-handle-l { left: -5px; }
            .bridge-handle-r { right: -5px; }

            /* I/O chip bar — ambient hardware activity that fades in/out
               during simulation so the canvas breathes without clutter */
            .bridge-io {
                position: relative;
                padding: 10px 20px;
                background: rgba(5, 5, 7, 0.9);
                border-top: 1px solid var(--xp-border);
                display: flex;
                flex-direction: column;
                gap: 6px;
                z-index: 3;
                pointer-events: none;
            }
            .bridge-io-row {
                display: flex;
                align-items: center;
                gap: 8px;
                flex-wrap: wrap;
            }
            .bridge-io-label {
                font-family: var(--xp-font-heading);
                font-size: 0.58rem;
                font-weight: 600;
                text-transform: uppercase;
                letter-spacing: 0.14em;
                color: var(--xp-text-subtle);
                min-width: 56px;
            }
            .bridge-chip {
                display: inline-flex;
                align-items: center;
                gap: 6px;
                padding: 3px 9px;
                border-radius: 999px;
                border: 1px solid var(--xp-border);
                background: rgba(13, 13, 18, 0.6);
                font-family: var(--xp-font-mono);
                font-size: 0.64rem;
                color: var(--xp-text-subtle);
                opacity: 0.35;
                transition: opacity 0.6s ease, color 0.3s, border-color 0.3s, background 0.3s;
            }
            .bridge-chip.pulse {
                opacity: 1;
                color: var(--xp-text-primary);
            }
            .bridge-chip-dot {
                width: 6px;
                height: 6px;
                border-radius: 50%;
                background: var(--xp-text-subtle);
                transition: background 0.3s, box-shadow 0.3s;
            }
            /* Category colours */
            .bridge-chip[data-cat="sensor"] .bridge-chip-dot     { background: var(--xp-green); }
            .bridge-chip[data-cat="output"] .bridge-chip-dot     { background: var(--xp-purple); }
            .bridge-chip[data-cat="perception"] .bridge-chip-dot { background: var(--xp-orange); }
            .bridge-chip[data-cat="agent"] .bridge-chip-dot      { background: var(--xp-pink); }
            .bridge-chip[data-cat="performer"] .bridge-chip-dot  { background: var(--xp-emerald); }

            .bridge-chip.pulse[data-cat="sensor"]     { border-color: rgba(34, 197, 94, 0.5); background: rgba(34, 197, 94, 0.08); }
            .bridge-chip.pulse[data-cat="output"]     { border-color: rgba(168, 85, 247, 0.5); background: rgba(168, 85, 247, 0.08); }
            .bridge-chip.pulse[data-cat="perception"] { border-color: rgba(249, 115, 22, 0.5); background: rgba(249, 115, 22, 0.08); }
            .bridge-chip.pulse[data-cat="agent"]      { border-color: rgba(236, 72, 153, 0.5); background: rgba(236, 72, 153, 0.08); }
            .bridge-chip.pulse[data-cat="performer"]  { border-color: rgba(16, 185, 129, 0.5); background: rgba(16, 185, 129, 0.08); }

            .bridge-chip.pulse .bridge-chip-dot {
                box-shadow: 0 0 8px currentColor;
            }

            /* Operate mode: live agent monitor panel */
            .bridge-agents {
                position: absolute;
                top: 16px;
                right: 16px;
                width: 240px;
                padding: 10px 12px 12px;
                background: rgba(5, 5, 7, 0.85);
                backdrop-filter: blur(8px);
                -webkit-backdrop-filter: blur(8px);
                border: 1px solid var(--xp-border);
                border-radius: 10px;
                opacity: 0;
                transform: translateX(10px);
                transition: opacity 0.4s ease, transform 0.4s ease;
                z-index: 5;
                pointer-events: none;
            }
            .bridge-agents.visible {
                opacity: 1;
                transform: translateX(0);
            }
            .bridge-agents-title {
                font-family: var(--xp-font-heading);
                font-size: 0.62rem;
                font-weight: 600;
                text-transform: uppercase;
                letter-spacing: 0.14em;
                color: var(--xp-text-subtle);
                padding-bottom: 8px;
                margin-bottom: 8px;
                border-bottom: 1px solid var(--xp-border);
            }
            .bridge-agent {
                display: flex;
                align-items: center;
                gap: 8px;
                padding: 7px 8px;
                border-radius: 8px;
                border: 1px solid var(--xp-border);
                margin-bottom: 6px;
                opacity: 0;
                transform: translateY(4px);
                transition: opacity 0.3s ease, transform 0.3s ease,
                            border-color 0.3s, background 0.3s;
            }
            .bridge-agent:last-child { margin-bottom: 0; }
            .bridge-agent.visible {
                opacity: 1;
                transform: translateY(0);
            }
            .bridge-agent.firing {
                border-color: rgba(245, 158, 11, 0.4);
                background: rgba(245, 158, 11, 0.05);
            }
            .bridge-agent.fired {
                border-color: rgba(52, 211, 153, 0.3);
            }
            .bridge-agent-tier {
                flex-shrink: 0;
                width: 22px;
                height: 22px;
                border-radius: 6px;
                display: flex;
                align-items: center;
                justify-content: center;
                font-family: var(--xp-font-mono);
                font-size: 0.68rem;
                font-weight: 700;
            }
            .bridge-agent-tier.reactive {
                background: rgba(100, 116, 139, 0.2);
                color: #94a3b8;
            }
            .bridge-agent-tier.deliberative {
                background: rgba(59, 130, 246, 0.2);
                color: var(--xp-accent);
            }
            .bridge-agent-tier.compositional {
                background: rgba(168, 85, 247, 0.2);
                color: var(--xp-purple);
            }
            .bridge-agent-body {
                flex: 1;
                min-width: 0;
            }
            .bridge-agent-name {
                font-family: var(--xp-font-mono);
                font-size: 0.72rem;
                color: var(--xp-text-primary);
                line-height: 1.2;
            }
            .bridge-agent-meta {
                font-family: var(--xp-font-mono);
                font-size: 0.58rem;
                color: var(--xp-text-subtle);
                line-height: 1.3;
                margin-top: 1px;
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
            }
            .bridge-agent-dot {
                flex-shrink: 0;
                width: 8px;
                height: 8px;
                border-radius: 50%;
                background: var(--xp-text-subtle);
                opacity: 0.5;
            }
            .bridge-agent.firing .bridge-agent-dot {
                background: #f59e0b;
                opacity: 1;
                animation: bridge-agent-pulse 0.9s ease-in-out infinite;
            }
            .bridge-agent.fired .bridge-agent-dot {
                background: #34d399;
                opacity: 1;
                box-shadow: 0 0 6px rgba(52, 211, 153, 0.5);
            }
            @keyframes bridge-agent-pulse {
                0%, 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.6); }
                50%      { box-shadow: 0 0 0 4px rgba(245, 158, 11, 0); }
            }

            /* Edges */
            .bridge-edge {
                fill: none;
                stroke: var(--xp-accent);
                stroke-width: 2;
                opacity: 0;
                transition: opacity 0.5s ease;
            }
            .bridge-edge.visible {
                opacity: 0.6;
            }
            .bridge-edge.firing {
                opacity: 1;
                stroke: #f59e0b;
                stroke-width: 3;
            }

            /* Event log */
            .bridge-log {
                height: 140px;
                padding: 12px 20px;
                border-top: 1px solid var(--xp-border);
                background: rgba(0, 0, 0, 0.2);
                overflow-y: auto;
                scroll-behavior: smooth;
                font-family: var(--xp-font-mono);
                font-size: 0.72rem;
                line-height: 1.7;
            }
            .bridge-log-row {
                display: flex;
                gap: 14px;
                opacity: 0;
                transform: translateY(4px);
                transition: opacity 0.3s ease, transform 0.3s ease;
            }
            .bridge-log-row.visible {
                opacity: 1;
                transform: translateY(0);
            }
            .bridge-log-time {
                color: var(--xp-text-subtle);
                flex-shrink: 0;
            }
            .bridge-log-text {
                color: var(--xp-text-primary);
            }

            /* Status indicator */
            .bridge-status {
                margin-left: auto;
                font-family: var(--xp-font-mono);
                font-size: 0.7rem;
                color: var(--xp-text-subtle);
                display: flex;
                align-items: center;
                gap: 6px;
            }
            .bridge-status::before {
                content: "";
                width: 7px;
                height: 7px;
                border-radius: 50%;
                background: var(--xp-text-subtle);
            }
            .bridge-status.connected {
                color: #34d399;
            }
            .bridge-status.connected::before {
                background: #34d399;
                box-shadow: 0 0 8px rgba(52, 211, 153, 0.5);
            }

            @media (prefers-reduced-motion: reduce) {
                .bridge-node,
                .bridge-edge,
                .bridge-log-row {
                    transition: opacity 0.2s ease !important;
                    transform: none !important;
                }
                .bridge-node.active {
                    animation: none !important;
                }
            }

            /* ===== Four Rings architecture section ===== */
            .rings-section {
                padding-top: 6rem;
                padding-bottom: 6rem;
            }
            .rings {
                display: grid;
                grid-template-columns: repeat(2, minmax(0, 1fr));
                gap: 1.5rem;
                max-width: 1100px;
                margin: 3rem auto 0;
            }
            .ring {
                position: relative;
                background: var(--xp-bg-surface, #0D0D12);
                border: 1px solid var(--xp-border, #1E1E2A);
                border-radius: 14px;
                padding: 1.75rem 1.75rem 1.5rem;
                display: flex;
                flex-direction: column;
                gap: 0.9rem;
                transition: border-color 0.3s ease, transform 0.3s ease;
            }
            .ring:hover {
                border-color: var(--xp-accent, #3b82f6);
                transform: translateY(-2px);
            }
            .ring-header {
                display: flex;
                align-items: flex-start;
                gap: 0.75rem;
                flex-wrap: wrap;
            }
            .ring-num {
                font-family: var(--xp-font-mono, 'JetBrains Mono', monospace);
                font-size: 0.7rem;
                letter-spacing: 0.1em;
                color: var(--xp-text-subtle, #8E8E9A);
                padding: 0.25rem 0.55rem;
                border: 1px solid var(--xp-border, #1E1E2A);
                border-radius: 4px;
                align-self: center;
            }
            .ring-name {
                font-family: var(--xp-font-heading, 'Outfit', sans-serif);
                font-size: 1.2rem;
                font-weight: 600;
                color: var(--xp-text-primary, #E8E8EC);
                margin: 0;
                flex: 1 1 auto;
                min-width: 0;
            }
            .ring-licence {
                font-family: var(--xp-font-mono, 'JetBrains Mono', monospace);
                font-size: 0.68rem;
                padding: 0.25rem 0.6rem;
                border-radius: 999px;
                letter-spacing: 0.02em;
                white-space: nowrap;
            }
            .licence-cc {
                background: rgba(34, 197, 94, 0.12);
                color: #4ade80;
                border: 1px solid rgba(34, 197, 94, 0.25);
            }
            .licence-apache {
                background: rgba(59, 130, 246, 0.12);
                color: #60a5fa;
                border: 1px solid rgba(59, 130, 246, 0.25);
            }
            .licence-eula {
                background: rgba(245, 158, 11, 0.12);
                color: #fbbf24;
                border: 1px solid rgba(245, 158, 11, 0.25);
            }
            .licence-commercial {
                background: rgba(168, 85, 247, 0.12);
                color: #c084fc;
                border: 1px solid rgba(168, 85, 247, 0.25);
            }
            .ring-lead {
                color: var(--xp-text-secondary, #B8B8C4);
                font-size: 0.95rem;
                line-height: 1.55;
                margin: 0;
            }
            .ring-chips {
                list-style: none;
                padding: 0;
                margin: 0;
                display: flex;
                flex-direction: column;
                gap: 0.4rem;
            }
            .ring-chips li {
                font-size: 0.88rem;
                color: var(--xp-text-primary, #E8E8EC);
                padding: 0.4rem 0.7rem;
                background: rgba(255, 255, 255, 0.025);
                border-radius: 6px;
                border-left: 2px solid var(--xp-border, #1E1E2A);
                transition: border-color 0.25s ease;
            }
            .ring:hover .ring-chips li {
                border-left-color: var(--xp-accent, #3b82f6);
            }
            .ring-chips code {
                font-family: var(--xp-font-mono, 'JetBrains Mono', monospace);
                font-size: 0.82rem;
                color: var(--xp-accent, #3b82f6);
                background: rgba(59, 130, 246, 0.08);
                padding: 0.05rem 0.35rem;
                border-radius: 3px;
            }
            .ring-chips strong {
                font-weight: 600;
                color: var(--xp-text-primary, #E8E8EC);
            }
            .ring-cta {
                margin-top: auto;
                display: inline-block;
                font-family: var(--xp-font-mono, 'JetBrains Mono', monospace);
                font-size: 0.85rem;
                color: var(--xp-accent, #3b82f6);
                text-decoration: none;
                padding-top: 0.5rem;
                border-top: 1px dashed var(--xp-border, #1E1E2A);
                transition: color 0.25s ease;
            }
            .ring-cta:hover {
                color: #60a5fa;
            }
            /* Per-ring accent tints on the left edge */
            .ring-standard { border-top: 3px solid rgba(34, 197, 94, 0.5); }
            .ring-impl     { border-top: 3px solid rgba(59, 130, 246, 0.5); }
            .ring-tools    { border-top: 3px solid rgba(245, 158, 11, 0.5); }
            .ring-cloud    { border-top: 3px solid rgba(168, 85, 247, 0.5); }

            /* Mobile: single column */
            @media (max-width: 720px) {
                .rings {
                    grid-template-columns: 1fr;
                    gap: 1rem;
                }
                .ring {
                    padding: 1.5rem 1.25rem 1.25rem;
                }
                .ring-licence {
                    font-size: 0.62rem;
                }
            }

            /* ===== Footer licence row ===== */

            /* ============================================================
             * LIGHT-THEME ADJUSTMENTS  (quick task 260525-pzf follow-up)
             * The colour system was authored for a near-black background;
             * these rules make the LIGHT theme legible and WCAG-2.2-AA
             * compliant WITHOUT touching dark mode — every rule is scoped to
             * :root[data-theme='light'].
             *
             * The hex literals below are INTENTIONAL (cf. the L-02 allowlist
             * at the top of this file): each is a darkened, AA-on-light
             * variant (>=4.5:1 on --xp-bg #f5f4f0) of a dark-mode platform
             * hue, used only where that hue is foreground TEXT on a light
             * surface. Dark "screen" panels (code / data viz) deliberately
             * keep the original bright hues.
             * ============================================================ */

            /* (1) Hue-coloured TEXT on light cards that resolve hue *tokens*
             *     (protocol --pc, statement + section-heading accents, and the
             *     usecase-card accent bar + .usecase-tag chips whose inline
             *     color: var(--xp-hue) was light-hue-on-pale-chip in light):
             *     scope the darkened ramp to those containers only, so the
             *     same tokens stay bright inside dark panels elsewhere. */
            :root[data-theme='light'] :is(.protocol-card, .statement, .rr-section-heading, .usecase-card) {
                --xp-purple:  #9333ea;
                --xp-violet:  #6d28d9;
                --xp-cyan:    #0e7490;
                --xp-pink:    #be185d;
                --xp-emerald: #047857;
                --xp-orange:  #c2410c;
                --xp-green:   #15803d;
                --xp-amber:   #b45309;
                --xp-red:     #b91c1c;
            }

            /* (2) Perception + realm card titles set --p-color / --r-color to
             *     bright literals → override per variant for AA on white. */
            :root[data-theme='light'] .perception-card[data-perception="warmth"]   { --p-color: #8a5a00; }
            :root[data-theme='light'] .perception-card[data-perception="energy"]   { --p-color: #c2410c; }
            :root[data-theme='light'] .perception-card[data-perception="tension"]  { --p-color: #b91c1c; }
            :root[data-theme='light'] .perception-card[data-perception="calm"]     { --p-color: #6d28d9; }
            :root[data-theme='light'] .perception-card[data-perception="wonder"]   { --p-color: #be185d; }
            :root[data-theme='light'] .perception-card[data-perception="presence"] { --p-color: #047857; }
            :root[data-theme='light'] .realm-card[data-realm="physical"]  { --r-color: #2563eb; }
            :root[data-theme='light'] .realm-card[data-realm="digital"]   { --r-color: #0e7490; }
            :root[data-theme='light'] .realm-card[data-realm="augmented"] { --r-color: #9333ea; }
            :root[data-theme='light'] .realm-card[data-realm="virtual"]   { --r-color: #be185d; }

            /* (3) Philosophy formula chips: bright literal text on a light
             *     elevated surface → darken the foreground only. */
            :root[data-theme='light'] .open-chip[data-open="event"]      { color: #c2410c; }
            :root[data-theme='light'] .open-chip[data-open="transition"] { color: #047857; }

            /* (4) Code + data panels are intentionally DARK in both themes
             *     (embedded "screens"); keep them dark so the bright syntax /
             *     chip hues stay correct and high-contrast on a light page. */
            :root[data-theme='light'] .xdl-code {
                background: #0d0d12;
                border-color: #1e1e2a;
            }
            :root[data-theme='light'] .xdl-code-bar { border-bottom-color: #1e1e2a; }
            :root[data-theme='light'] .xdl-code-body { color: #e8e8ec; }
            :root[data-theme='light'] .xdl-code-filename { color: #6b6b76; }
            :root[data-theme='light'] .open-viz {
                background: #08080c;
                border-color: #1e1e2a;
            }

            /* (5) Protocol cards: light surface (were a dark translucent fill
             *     that muddied to grey on the light background). */
            :root[data-theme='light'] .protocol-card { background: var(--xp-bg-surface); }
            :root[data-theme='light'] .protocol-card:hover { background: var(--xp-bg-elevated); }
            :root[data-theme='light'] .protocol-card-chips span { background: rgba(0, 0, 0, 0.03); }

            /* (6) Featured-project graffiti is a baked WebP whose white glyphs
             *     ("hip" / "IMMERSIVE") vanish on the cream background. Add a
             *     dark edge + halo so it reads, and drop the dark-mode
             *     brightness boost that washed it out further. */
            :root[data-theme='light'] .featured-project-title-img,
            :root[data-theme='light'] .rr-hero-title-img {
                filter: brightness(0.95) saturate(1.05)
                        drop-shadow(0 1px 1px rgba(0, 0, 0, 0.5))
                        drop-shadow(0 0 18px rgba(0, 0, 0, 0.22));
            }

            /* (7) WCAG-AA (Lighthouse): the theme engine now ships a light
             * --xp-text-subtle of #5f5f66 (was #888 = 3.22:1, below AA 4.5),
             * so the global darken lives upstream — not here. Two residual
             * local rules remain: keep text-subtle BRIGHT inside the dark
             * code/data panels (comments / line numbers stay legible on dark),
             * and undo .signup-hint's opacity:0.5 (which re-halved it to ~1.7:1). */
            :root[data-theme='light'] :is(.xdl-code, .open-viz) {
                --xp-text-subtle: #888888;
            }
            /* .signup-hint multiplies text-subtle by opacity:0.5 → ~1.7:1 even
             * after the darken. Drop the opacity in light mode so it meets AA. */
            :root[data-theme='light'] .signup-hint {
                opacity: 1;
            }

            /* (8) Partner-logo hover reveals each logo's ORIGINAL artwork —
             *     correct on the dark page, but several logos are drawn white /
             *     near-white (cg-pro, changeworlds, fat-fish, silverscape) or
             *     pure black (james-chase, holland-house), so on hover they go
             *     white-on-white (or black) and vanish on the light background
             *     (reported 2026-05-26). CSS filter on an <img> can't selectively
             *     recolour only the white pixels, so in light mode render these
             *     mono-artwork logos as a dark silhouette on hover — fully legible
             *     and consistent with the dark page's "light up" hover. Colour
             *     logos (impossible-creative, vortex) keep the original-colour
             *     reveal. No new literals: brightness(0) is the black sibling of
             *     the dark-mode brightness(0) invert(1). */
            :root[data-theme='light'] .partners-logos a:hover img[src*="cg-pro"],
            :root[data-theme='light'] .partners-logos a:hover img[src*="changeworlds"],
            :root[data-theme='light'] .partners-logos a:hover img[src*="fat-fish"],
            :root[data-theme='light'] .partners-logos a:hover img[src*="silverscape"],
            :root[data-theme='light'] .partners-logos a:hover img[src*="james-chase"],
            :root[data-theme='light'] .partners-logos a:hover img[src*="holland-house"] {
                filter: brightness(0);
            }
            :root[data-theme='light'] .allpoints-link:hover .ap-grey {
                stroke: var(--xp-text-primary);
            }
            :root[data-theme='light'] .allpoints-link:hover .ap-grey-fill {
                fill: var(--xp-text-primary);
            }

            /* (9) Demo + Bridge product "windows" are embedded dark SCREENS
             *     (like .xdl-code / .open-viz at (4)): their internals — white
             *     label text, dark scrim panels, a white dot-grid, and slides
             *     that pull var(--xp-bg) — were all authored for a near-black
             *     canvas. The frame flips to white in light mode but the
             *     children don't, giving white-on-white text and grey-mud
             *     panels. Re-pin the *dark* token set on the two frames so the
             *     whole subtree resolves to the engine's dark values and the
             *     panels render identically to their audited dark appearance.
             *     Token literals below mirror :root in public/theme/openxp-theme.css.
             *     .open-viz (philosophy illustration screens) joins the island
             *     too (item 9): override (4) keeps its background dark, but its
             *     chips pulled var(--xp-bg-elevated) → near-white with light hue
             *     text. Re-pinning the dark tokens here fixes that colour balance.
             *     .perception-xdl (the cycling Perception snippet) joins too — it
             *     is fully token-driven (background:var(--xp-bg-surface)), so the
             *     re-pin alone flips it to a dark code screen like the rest. */
            /* Bridge/open-viz/perception stay dark "screens" in light mode (the
               in-product UIs they mirror are dark-only). The Studio demo
               (.demo-frame) is handled separately below — it gets a genuine
               light skin in light mode. */
            /* ============================================================
             * STUDIO DEMO — LIGHT SKIN (2026-06-09)
             * .demo-frame is out of the dark-island list (above), so the app
             * chrome adopts the light theme. These rules light-skin the scene
             * internals that were authored dark-first — the Journey kanban
             * columns and the Generate code pane + its syntax theme — so the
             * whole pipeline reads as a genuine light app. All scoped to
             * .demo-* so the dark code panels elsewhere (/platform) are
             * untouched. Hues use the AA-on-light darkened palette.
             * ============================================================ */
            /* Journey — columns, header band, cards */
            :root[data-theme='light'] .demo-stage-col { background: var(--xp-bg-elevated); }
            :root[data-theme='light'] .demo-stage-col-head { background: rgba(0, 0, 0, 0.035); }
            :root[data-theme='light'] .demo-moment { background: #ffffff; }
            :root[data-theme='light'] .demo-perception-tag {
                background: rgba(194, 65, 12, 0.08);
                color: #c2410c;
                border-color: rgba(194, 65, 12, 0.3);
            }
            :root[data-theme='light'] .demo-moment-type { background: rgba(37, 99, 235, 0.1); color: #1d4ed8; }
            :root[data-theme='light'] .demo-moment-type.peak,
            :root[data-theme='light'] .demo-moment-type.capture { background: rgba(190, 24, 93, 0.1); color: #be185d; }
            :root[data-theme='light'] .demo-moment-type.trigger,
            :root[data-theme='light'] .demo-moment-type.generation { background: rgba(124, 58, 237, 0.1); color: #7c3aed; }
            :root[data-theme='light'] .demo-moment-type.arrival,
            :root[data-theme='light'] .demo-moment-type.transition { background: rgba(21, 128, 61, 0.1); color: #15803d; }
            :root[data-theme='light'] .demo-moment-type.delivery,
            :root[data-theme='light'] .demo-moment-type.departure { background: rgba(180, 83, 9, 0.1); color: #b45309; }
            /* Generate — light code pane + AA-on-light syntax theme */
            :root[data-theme='light'] .demo-generate-output {
                background: var(--xp-bg-surface);
                border-color: var(--xp-border);
            }
            :root[data-theme='light'] .demo-generate-output .xk   { color: #1d4ed8; }
            :root[data-theme='light'] .demo-generate-output .xs   { color: #15803d; }
            :root[data-theme='light'] .demo-generate-output .xc   { color: #6b7280; text-shadow: none; }
            :root[data-theme='light'] .demo-generate-output .xp   { color: #b45309; }
            :root[data-theme='light'] .demo-generate-output .xn   { color: #0e7490; }
            :root[data-theme='light'] .demo-generate-output .xt-s { color: #15803d; }
            :root[data-theme='light'] .demo-generate-output .xt-o { color: #7c3aed; }
            :root[data-theme='light'] .demo-generate-output .xt-p { color: #c2410c; }
            :root[data-theme='light'] .demo-generate-output .xt-a { color: #be185d; }
            /* Visualise — screenplay beat titles are near-white (#f0f0f4) for dark;
               flip to primary text so "Warm welcome glow" etc. read on the light pane. */
            :root[data-theme='light'] .demo-vis-beat-title { color: var(--xp-text-primary); }
            :root[data-theme='light'] :is(.bridge-frame, .open-viz, .perception-xdl) {
                --xp-bg: #050507;
                --xp-bg-surface: #0d0d12;
                --xp-bg-elevated: #16161d;
                --xp-border: #1e1e2a;
                --xp-text-primary: #e8e8ec;
                /* secondary/subtle lifted to match the dark-mode legibility
                   lift (item 7) — keep the dark island readable in light. */
                --xp-text-secondary: #a6a6b2;
                --xp-text-subtle: #8c8c98;
                --xp-accent: #3b82f6;
                --xp-accent-hover: #2563eb;
                /* Re-pinning the *variables* only fixes children that set
                   color: var(--xp-text-*). JS-injected text that relies on
                   INHERITED colour (e.g. .demo-chat-msg, which sets no color
                   of its own) otherwise picks up the light-mode body colour
                   (#111) → dark-on-dark inside this dark island. Apply the
                   re-pinned light colour as the subtree's base so inherited
                   text resolves correctly. */
                color: var(--xp-text-primary);
            }

            /* (10) Signup confirmation messages — the success/error feedback a
             *      visitor sees right after the primary CTA. The dark-mode
             *      hues (#34d399 ~1.9:1, #f87171 ~2.7:1 on cream) fail WCAG-AA.
             *      Re-use the darkened green/red already in ramp (1) so the
             *      confirmation stays legible on the light background. */
            :root[data-theme='light'] .signup-msg.success { color: #15803d; }
            :root[data-theme='light'] .signup-msg.error   { color: #b91c1c; }

            /* (11) Sticky nav once scrolled: the at-rest bar is transparent and
             *      flips fine, but .nav.scrolled hardcodes a near-black
             *      translucent fill that stays a dark bar over the cream page.
             *      Track --xp-bg so the scrolled bar matches the light chrome
             *      (border + blur are already token/effect-driven). */
            :root[data-theme='light'] .nav.scrolled {
                background: color-mix(in srgb, var(--xp-bg) 85%, transparent);
            }

            /* (12) "open venue" pill on the philosophy section hardcodes a dark
             *      translucent fill that muddies to grey on the light page.
             *      Use the same faint fill as the protocol-card chips (5) so it
             *      reads as a subtle pill behind the (token-driven) dark text. */
            :root[data-theme='light'] .open-venue {
                background: rgba(0, 0, 0, 0.04);
            }

            /* (13) XDL feature-card hover — the dark rgba(13,13,18,.5) hover fill
             *      stayed a grey panel under the (now dark) heading/body text in
             *      light mode → grey-on-grey. Use a faint light wash so the dark
             *      text stays readable on hover. */
            :root[data-theme='light'] .xdl-feature:hover {
                background: rgba(0, 0, 0, 0.04);
                border-color: var(--xp-border);
            }

            /* (14) Icon tiles / orbs were too light in light mode (a faint hue
             *      tint + hue glyph on white). Flip them: DARK tile, LIGHT glyph.
             *      - XDL feature tiles: darken the per-card --icon-hue.
             *      - Perception + realm orbs: --p-color / --r-color already carry
             *        the darkened AA hue from ramp (2), so a solid fill + white
             *        glyph reads strongly. */
            :root[data-theme='light'] .xdl-feature-icon {
                background: color-mix(in srgb, var(--icon-hue, var(--xp-accent)) 70%, #0d0d14);
                color: #f6f7fb;
            }
            :root[data-theme='light'] .perception-card-orb {
                background: var(--p-color, var(--xp-orange));
                border-color: var(--p-color, var(--xp-orange));
                color: #ffffff;
            }
            :root[data-theme='light'] .realm-card-orb {
                background: var(--r-color, var(--xp-accent));
                border-color: var(--r-color, var(--xp-accent));
                color: #ffffff;
            }

            /* (15) Realm explainer bullets (right column) hardcoded a dark
             *      rgba(13,13,18,.5) fill → grey text on a grey panel in light.
             *      Flip to the light surface; the token-driven body text then
             *      reads normally. */
            :root[data-theme='light'] .realm-bullet {
                background: var(--xp-bg-surface);
                border-color: var(--xp-border);
            }

            /* ============================================================
             * DARK-THEME LEGIBILITY LIFT (item 7, 2026-05-26)
             * The engine bundle's muted greys (--xp-text-secondary #8e8e9a,
             * --xp-text-subtle #6b6b76) read too dim on the near-black canvas
             * (subtle was ~3.5:1, below AA). Lift both on dark so secondary
             * body copy, code-panel filenames, and the Studio/Bridge/terminal
             * "screens" are easier to read. Scoped to [data-theme='dark'] so it
             * never touches the light token set. The light-mode dark islands
             * (.demo-frame/.bridge-frame above) re-pin the same lifted values.
             * ============================================================ */
            :root[data-theme='dark'] {
                --xp-text-secondary: #a6a6b2;
                --xp-text-subtle: #8c8c98;
            }
            /* LIGHT-THEME SUBTLE-TEXT AA FIX (2026-06-09)
             * The engine bundle's light --xp-text-subtle (#888) reads ~3:1 on the
             * cream page — below WCAG-AA. Darken to the documented AA value so
             * footer text, the signup hint, and muted captions pass. The dark
             * panels (.demo-frame/.bridge-frame/.xdl-code/.open-viz) re-pin
             * --xp-text-subtle locally, so they are unaffected. */
            :root[data-theme='light'] {
                --xp-text-subtle: #5f5f66;
            }

/* ==========================================================================
 * AudienceSelfRouteSection — NARR-06 / D-05
 * Two-column card grid: builders → /platform#start, creative directors → /about
 * All colours via --xp-* tokens only; zero new raw hex values.
 * ========================================================================== */

.audience-card::before {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse at top left, color-mix(in srgb, var(--xp-accent) 6%, transparent), transparent 70%);
    pointer-events: none;
    z-index: 0;
}

/* Creative directors card: amber radial tint (instead of default blue accent) */
.audience-card.card-creative::before {
    background: radial-gradient(ellipse at top right, color-mix(in srgb, var(--xp-amber) 6%, transparent), transparent 70%);
}

/* Ensure all card children sit above the tint pseudo-element */

.audience-card:hover {
    border-color: var(--xp-accent);
}
