/* ============================================================
   FRACTIONAL-X — one continuous 3D world. Loaded ONLY on
   /fractional-x (see functions.php). Scoped under #fx-root +
   body:has(#fx-root). Progressive enhancement doctrine:
   - DEFAULT (no JS / reduced motion): readable dark editorial
     document, everything visible, zero dependencies.
   - .fx-live (JS booted): world canvas + choreography take over.
   ============================================================ */

/* ---- fonts (theme-hosted) ---- */
@font-face { font-family: "Inter Display X"; src: url("../fonts/InterDisplay-Light.woff2") format("woff2"); font-weight: 300; font-display: swap; }
@font-face { font-family: "Inter Display X"; src: url("../fonts/InterDisplay-Medium.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Inter X"; src: url("../fonts/Inter-Regular.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Inter X"; src: url("../fonts/Inter-Medium.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Fragment Mono X"; src: url("../fonts/FragmentMono-Regular.woff2") format("woff2"); font-weight: 400; font-display: swap; }

:root {
	--fx-black: #050505;
	--fx-ink: #0A0A0A;
	--fx-brand: #0021FF;
	--fx-sky: #3388FF;
	--fx-bg: #050505;
	--fx-surface: #F1F1F1;
	--fx-dim: rgba(241,241,241,0.55);
	--fx-faint: rgba(241,241,241,0.28);
	--fx-hair: rgba(241,241,241,0.12);
	--fx-em: rgba(241,241,241,0.6);
	--fx-hero-kicker: rgba(241,241,241,0.48);
	--fx-word-dim: rgba(241,241,241,0.32);
	--fx-word-lit: #DDE2F9;
	--fx-panel: rgba(5,5,5,0.55);
	--fx-card-bg: rgba(241,241,241,0.02);
	--fx-grain-o: 0.06;
	--fx-vignette: radial-gradient(ellipse at center, transparent 56%, rgba(0,0,0,0.44) 100%);
	--fx-display: "Inter Display X", "Inter X", sans-serif;
	--fx-body: "Inter X", sans-serif;
	--fx-mono: "Fragment Mono X", monospace;
	--fx-ease: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ---- FX-8 · light theme: same world, considerably cleaner ----
   Toggled by fx.js via data-fx-theme on #fx-root (default dark; the dark
   version is the approved base). Vars land on body:has() so both the body
   shell and everything inside #fx-root re-skin from one block. */
body:has(#fx-root[data-fx-theme="light"]) {
	--fx-bg: #F1F1F1;
	--fx-surface: #171717;
	--fx-dim: rgba(23,23,23,0.62);
	--fx-faint: rgba(23,23,23,0.36);
	--fx-hair: rgba(23,23,23,0.13);
	--fx-em: rgba(23,23,23,0.55);
	--fx-hero-kicker: rgba(23,23,23,0.5);
	--fx-word-dim: rgba(23,23,23,0.3);
	--fx-word-lit: #0021FF;
	--fx-panel: rgba(255,255,255,0.62);
	--fx-card-bg: rgba(255,255,255,0.5);
	--fx-grain-o: 0.03;
	--fx-vignette: radial-gradient(ellipse at center, transparent 62%, rgba(255,255,255,0.55) 100%);
}

body:has(#fx-root) { background: var(--fx-bg); color: var(--fx-surface); margin: 0; overflow-x: hidden; }
body:has(#fx-root) .wp-site-blocks > *:not(main):not(.fx-root) { display: none; }

.fx-root { font-family: var(--fx-body); background: var(--fx-bg); color: var(--fx-surface); min-height: 100vh; transition: background-color 0.5s, color 0.5s; }
.fx-root *, .fx-root *::before, .fx-root *::after { box-sizing: border-box; }
.fx-root a { color: inherit; text-decoration: none; }

/* ---- fixed layers ---- */
.fx-canvas { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; display: none; }
.fx-live .fx-canvas { display: block; }
.fx-main, .fx-top { position: relative; z-index: 2; }
.fx-live .fx-main { overflow-x: clip; } /* FX-8: contains transform overflow (fit-card ±64px initial X was the last 24px of scrollable overflow); clip ≠ scroll container, so sticky + pinning keep working */
.fx-grain { position: fixed; inset: -50%; z-index: 40; pointer-events: none; opacity: var(--fx-grain-o);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.fx-live .fx-grain { animation: fx-grain-shift 0.9s steps(2) infinite; }
@keyframes fx-grain-shift { 0% { transform: translate(0,0); } 50% { transform: translate(2%, -1%);} 100% { transform: translate(-1%, 2%);} }

/* ---- custom cursor (desktop + live only) ---- */
.fx-cursor { display: none; }
.fx-live:not(.fx-touch) .fx-cursor { display: block; position: fixed; inset: 0; z-index: 100; pointer-events: none; }
.fx-live:not(.fx-touch) { cursor: none; }
.fx-live:not(.fx-touch) a, .fx-live:not(.fx-touch) button { cursor: none; }
.fx-cursor-dot { position: absolute; width: 6px; height: 6px; margin: -3px 0 0 -3px; border-radius: 50%; background: var(--fx-sky); }
.fx-cursor-ring { position: absolute; width: 34px; height: 34px; margin: -17px 0 0 -17px; border-radius: 50%; border: 1px solid rgba(51,136,255,0.5); transition: width 0.25s var(--fx-ease), height 0.25s var(--fx-ease), margin 0.25s var(--fx-ease), border-color 0.25s; }
.fx-cursor.is-hover .fx-cursor-ring { width: 56px; height: 56px; margin: -28px 0 0 -28px; border-color: rgba(51,136,255,0.9); }

/* ---- preloader ---- */
.fx-loader { position: fixed; inset: 0; z-index: 200; background: var(--fx-bg); display: none; align-items: center; justify-content: center; clip-path: inset(0 0 0 0); cursor: pointer; will-change: clip-path; }
.fx-live .fx-loader { display: flex; }
.fx-live .fx-loader.is-done { pointer-events: none; }
.fx-loader-inner { position: relative; text-align: center; perspective: 600px; }
.fx-loader-inner::after { content: ""; position: absolute; left: 50%; top: calc(100% + 1.1rem); width: 82px; height: 1px; background: linear-gradient(90deg, transparent, var(--fx-sky), transparent); transform: translateX(-50%) scaleX(0.2); opacity: 0.35; animation: fx-loader-pulse 1.3s var(--fx-ease) infinite; }
.fx-loader-mark { font-family: var(--fx-display); font-weight: 500; font-size: 1.4rem; letter-spacing: -0.03em; margin: 0 0 0.6rem; transform-style: preserve-3d; }
.fx-loader-mark span { display: inline-block; will-change: transform, opacity, filter; }
.fx-loader-mark .is-slash { color: var(--fx-sky); }
.fx-loader-count { font-family: var(--fx-mono); font-size: 0.7rem; letter-spacing: 0.25em; color: var(--fx-dim); margin: 0; }
.fx-loader.is-skipping .fx-loader-inner::after, .fx-loader.is-exiting .fx-loader-inner::after { animation-duration: 0.35s; }
@keyframes fx-loader-pulse { 0%,100% { transform: translateX(-50%) scaleX(0.2); opacity: 0.2; } 50% { transform: translateX(-50%) scaleX(1); opacity: 0.75; } }

/* ---- top bar ----
   Pinned to white-based literals: mix-blend-mode difference inverts them
   over the light theme automatically, so the bar never needs re-theming. */
.fx-top { position: fixed; top: 0; left: 0; right: 0; z-index: 60; display: flex; justify-content: space-between; align-items: center; padding: 1.4rem 2rem; mix-blend-mode: difference; color: #F1F1F1; }
.fx-wordmark { font-family: var(--fx-display); font-weight: 500; letter-spacing: -0.04em; font-size: 1.1rem; }
.fx-top-nav { display: flex; gap: 1.6rem; align-items: center; }
.fx-top-nav a { font-family: var(--fx-mono); font-size: 0.62rem; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(241,241,241,0.55); transition: color 0.25s; }
.fx-top-nav a:hover { color: #F1F1F1; }

/* ---- FX-8 · theme toggle (injected by fx.js, live mode only) ---- */
.fx-theme-toggle { display: flex; gap: 0.45rem; align-items: baseline; background: none; border: 0; padding: 0; font-family: var(--fx-mono); font-size: 0.62rem; letter-spacing: 0.18em; text-transform: uppercase; color: #F1F1F1; cursor: pointer; }
.fx-theme-toggle .fx-tt-opt { opacity: 0.4; transition: opacity 0.25s; }
.fx-theme-toggle .fx-tt-opt.is-on { opacity: 1; }
.fx-theme-toggle .fx-tt-sep { opacity: 0.3; }
.fx-theme-toggle:hover .fx-tt-opt:not(.is-on) { opacity: 0.7; }

/* ---- FX-8 · zone rail (injected by fx.js; desktop live only) ----
   White-based + difference blend, same doctrine as the top bar. */
.fx-rail { display: none; }
.fx-live:not(.fx-touch) .fx-rail { position: fixed; right: 1.7rem; top: 50%; transform: translateY(-50%); z-index: 70; display: flex; flex-direction: column; mix-blend-mode: difference; }
.fx-rail-item { position: relative; display: flex; align-items: center; justify-content: flex-end; gap: 0.7rem; background: none; border: 0; padding: 0.5rem 0; cursor: pointer; color: #F1F1F1; }
.fx-rail-label { font-family: var(--fx-mono); font-size: 0.56rem; letter-spacing: 0.2em; text-transform: uppercase; color: rgba(241,241,241,0.6); white-space: nowrap; opacity: 0; transform: translateX(6px); transition: opacity 0.28s var(--fx-ease), transform 0.28s var(--fx-ease); }
.fx-rail-item:hover .fx-rail-label, .fx-rail-item.is-here .fx-rail-label { opacity: 1; transform: none; }
.fx-rail-dot { width: 5px; height: 5px; border-radius: 50%; background: rgba(241,241,241,0.38); flex: none; transition: transform 0.3s var(--fx-ease), background 0.3s; }
.fx-rail-item:hover .fx-rail-dot { background: rgba(241,241,241,0.7); }
.fx-rail-item.is-here .fx-rail-dot { background: #F1F1F1; transform: scale(1.7); }
.fx-rail-thread { position: absolute; right: 2px; top: 14px; bottom: 14px; width: 1px; background: rgba(241,241,241,0.14); pointer-events: none; }
.fx-rail-fill { position: absolute; inset: 0; background: rgba(241,241,241,0.75); transform-origin: top center; transform: scaleY(0); }

/* ---- shared type ---- */
.fx-frame { width: min(1360px, calc(100% - 4rem)); margin: 0 auto; }
.fx-frame--center { text-align: center; }
.fx-kicker { font-family: var(--fx-mono); font-size: 0.66rem; letter-spacing: 0.22em; text-transform: uppercase; color: var(--fx-faint); margin: 0 0 2rem; display: flex; align-items: center; gap: 0.8rem; }
.fx-kicker::before { content: ""; width: 22px; height: 1px; background: currentColor; opacity: 0.7; }
.fx-kicker--center { justify-content: center; }
.fx-kicker--dim { margin-bottom: 0.9rem; }
.fx-kicker--gap { margin-top: 6rem; }
.fx-h1 { font-family: var(--fx-display); font-weight: 300; font-size: clamp(2.6rem, 1rem + 6.5vw, 7rem); line-height: 1.02; letter-spacing: -0.035em; margin: 0; }
.fx-h1 em { font-style: italic; color: var(--fx-em); }
.fx-h2 { font-family: var(--fx-display); font-weight: 300; font-size: clamp(2rem, 1rem + 3.6vw, 4.2rem); line-height: 1.08; letter-spacing: -0.03em; margin: 0 0 2.4rem; max-width: 20ch; }
.fx-h2--soft { max-width: 24ch; }
.fx-giant { font-family: var(--fx-display); font-weight: 300; font-size: clamp(1.9rem, 1rem + 3.2vw, 3.9rem); line-height: 1.12; letter-spacing: -0.028em; margin: 0 auto 2.2rem; max-width: 26ch; }
.fx-body { font-size: 1rem; line-height: 1.75; color: var(--fx-dim); margin: 0 0 1.4rem; max-width: 56ch; }
.fx-body--center { margin-left: auto; margin-right: auto; }
.fx-source { font-family: var(--fx-mono); font-size: 0.6rem; letter-spacing: 0.14em; color: var(--fx-faint); margin: 0; }
.fx-source--center { text-align: center; }
.fx-pull { font-style: italic; font-size: 0.95rem; line-height: 1.75; color: var(--fx-dim); border-left: 1px solid var(--fx-hair); padding-left: 1.4rem; max-width: 46ch; margin: 0 0 4rem; }

/* ---- zones (generous scroll room for the dolly) ---- */
.fx-zone { position: relative; padding: 22vh 0; }
.fx-zone--hero { min-height: 100vh; display: flex; align-items: center; padding: 14vh 0 10vh; overflow: clip; }
.fx-zone--hero > .fx-frame { position: relative; z-index: 2; transform-origin: 50% 35%; will-change: transform, opacity; }
.fx-zone--hero > .fx-frame > .fx-kicker { color: var(--fx-hero-kicker); }
.fx-hero-sub { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; max-width: 860px; border-top: 1px solid var(--fx-hair); padding-top: 2.4rem; margin-top: 3.4rem; }
.fx-scrollcue { position: absolute; left: 50%; bottom: 4vh; width: 1px; height: 64px; overflow: hidden; }
.fx-scrollcue-line { position: absolute; inset: 0; background: linear-gradient(var(--fx-sky), transparent); animation: fx-cue 2s var(--fx-ease) infinite; }
@keyframes fx-cue { from { transform: translateY(-100%);} to { transform: translateY(110%);} }

.fx-zone--corridor { min-height: 70vh; display: flex; align-items: center; }
.fx-corridor-words { display: flex; flex-wrap: wrap; gap: 1.2rem 2.6rem; width: min(1360px, calc(100% - 4rem)); margin: 0 auto; }
.fx-word { font-family: var(--fx-mono); font-size: clamp(0.8rem, 0.5rem + 1.2vw, 1.3rem); letter-spacing: 0.22em; text-transform: uppercase; color: var(--fx-faint); margin: 0; white-space: nowrap; }
.fx-live:not(.fx-touch) .fx-zone--corridor { display: block; min-height: 180vh; padding: 0; }
.fx-live:not(.fx-touch) .fx-corridor-words { position: sticky; top: 0; display: block; width: 100%; height: 100vh; overflow: hidden; perspective: 920px; perspective-origin: 50% 48%; transform-style: preserve-3d; }
.fx-live:not(.fx-touch) .fx-corridor-words::before { content: ""; position: absolute; inset: 12% 18%; border: 1px solid rgba(51,136,255,0.08); border-radius: 50%; transform: translateZ(-700px) rotateX(72deg); box-shadow: 0 0 120px rgba(0,33,255,0.08); }
.fx-live:not(.fx-touch) .fx-word { position: absolute; left: 50%; top: 50%; color: var(--fx-word-dim); font-size: clamp(0.95rem, 0.45rem + 1.8vw, 2rem); text-shadow: 0 0 32px rgba(51,136,255,0.08); transform-style: preserve-3d; will-change: transform, opacity, filter; }
.fx-live:not(.fx-touch) .fx-word.is-lit { color: var(--fx-word-lit); text-shadow: 0 0 24px rgba(51,136,255,0.45), 0 0 70px rgba(0,33,255,0.22); }
#fx-root[data-fx-theme="light"].fx-live:not(.fx-touch) .fx-word.is-lit { text-shadow: 0 0 26px rgba(0,33,255,0.2); }

.fx-zone--stats { display: grid; gap: 18vh; }
.fx-monument { width: min(1100px, calc(100% - 4rem)); margin: 0 auto; }
.fx-stat { font-family: var(--fx-display); font-weight: 300; font-size: clamp(4.4rem, 2rem + 12vw, 13rem); line-height: 0.95; letter-spacing: -0.05em; color: var(--fx-sky); margin: 0 0 1.4rem; }
.fx-stat-label { font-size: 0.95rem; line-height: 1.6; color: var(--fx-dim); max-width: 34ch; margin: 0 0 0.9rem; }

.fx-depth-paras { display: grid; grid-template-columns: 1fr 1fr; gap: 4rem; }

.fx-gallery { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--fx-hair); }
.fx-work { display: grid; grid-template-columns: 64px 1fr; grid-template-rows: auto auto; gap: 0.4rem 2rem; padding: 2rem 0; border-bottom: 1px solid var(--fx-hair); }
.fx-work-num { font-family: var(--fx-mono); font-size: 0.62rem; letter-spacing: 0.14em; color: var(--fx-faint); grid-row: 1 / span 2; padding-top: 0.5rem; }
.fx-work-title { font-family: var(--fx-display); font-weight: 300; font-size: clamp(1.5rem, 1rem + 2vw, 2.6rem); letter-spacing: -0.025em; line-height: 1.15; margin: 0; }
.fx-work-detail { font-size: 0.92rem; line-height: 1.65; color: var(--fx-dim); max-width: 62ch; margin: 0; }

.fx-practice-cols { display: grid; grid-template-columns: 1.2fr 1fr; gap: 4rem; }
.fx-checklist { list-style: none; margin: 0; padding: 0; }
.fx-checklist li { display: flex; gap: 0.9rem; align-items: flex-start; padding: 0.9rem 0; border-bottom: 1px solid var(--fx-hair); font-size: 0.95rem; color: var(--fx-dim); }
.fx-checklist li::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--fx-sky); flex: none; margin-top: 0.55em; }
.fx-checklist li:last-child { border-bottom: none; }

.fx-zone--climax { min-height: 130vh; display: flex; align-items: center; }
.fx-climax-num { font-family: var(--fx-display); font-weight: 300; font-size: clamp(5rem, 2rem + 16vw, 17rem); line-height: 1; letter-spacing: -0.05em; color: var(--fx-sky); margin: 0 0 1.6rem; }
.fx-climax-pound { font-size: 0.35em; vertical-align: 1.1em; margin-right: 0.1em; color: var(--fx-brand); }
.fx-cta-sub { margin-bottom: 3rem; }

.fx-how-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 4rem; }
.fx-fit-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; perspective: 1200px; }
.fx-card { border: 1px solid var(--fx-hair); border-radius: 22px; padding: 2.6rem; background: var(--fx-card-bg); transform-style: preserve-3d; will-change: transform; }
.fx-card--yes { border-color: rgba(51,136,255,0.35); background: rgba(0,33,255,0.05); }
.fx-card-label { font-family: var(--fx-mono); font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase; margin: 0 0 1.8rem; color: var(--fx-faint); }
.fx-card--yes .fx-card-label { color: var(--fx-sky); }
.fx-card-list { list-style: none; margin: 0; padding: 0; }
.fx-card-list li { padding: 0.8rem 0; border-bottom: 1px solid var(--fx-hair); font-size: 0.92rem; line-height: 1.6; color: var(--fx-dim); }
.fx-card-list li:last-child { border-bottom: none; }

.fx-zone--cta { min-height: 100vh; display: flex; align-items: center; }
.fx-cta-btn-wrap { margin: 0 0 5rem; }
.fx-btn { display: inline-block; background: var(--fx-sky); color: #fff; font-family: var(--fx-body); font-weight: 500; font-size: 0.95rem; padding: 1.2rem 2.4rem; border-radius: 100px; transition: background 0.3s, box-shadow 0.3s; will-change: transform; }
.fx-btn:hover { background: #1a72ff; box-shadow: 0 12px 48px rgba(51,136,255,0.35); }
.fx-exit { display: flex; gap: 1rem; justify-content: center; font-family: var(--fx-mono); font-size: 0.62rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--fx-faint); }
.fx-exit a { color: var(--fx-faint); transition: color 0.25s; }
.fx-exit a:hover { color: var(--fx-surface); }

/* ---- live-mode initial states (JS choreographs; gated so no-JS stays visible) ---- */
.fx-live .fx-h1 .fxc-word { display: inline-block; white-space: nowrap; }
.fx-live [data-fx-split] .fxw, .fx-live .fx-h1 .fxc { display: inline-block; opacity: 0; transform: translateY(0.7em); will-change: transform, opacity, filter; }
.fx-live .fx-h1 .fxc { transform-origin: 50% 100%; }
.fx-live .fx-monument .fx-stat { opacity: 0; transform: scale(0.9); filter: blur(8px); }
.fx-live .fx-checklist li { opacity: 0; transform: translateY(28px) scale(1.12); filter: blur(6px); } /* FX-5: stamp-in */
.fx-live .fx-card { opacity: 0; transform: translateY(48px); }
/* FX-5: fit cards converge from opposite sides on desktop */
.fx-live:not(.fx-touch) .fx-card--yes { transform: translateX(-64px); }
.fx-live:not(.fx-touch) .fx-card--no { transform: translateX(64px); }

/* ---- FX-5 · climax amphitheater: particles carry the number on desktop ---- */
.fx-live:not(.fx-touch)[data-fx-climax="particles"] .fx-climax-num { opacity: 0 !important; min-height: 52vh; margin-bottom: 0; } /* a11y text stays in the DOM; the world renders the numeral above the copy */

/* ---- FX-7 · edge vignette: deepens the world (injected by fx.js, live only) ---- */
.fx-vignette { position: fixed; inset: 0; z-index: 30; pointer-events: none; background: var(--fx-vignette); } /* FX-8: dark = black vignette, light = soft white edge-glow */

/* ---- FX-5 · CTA finale ---- */
.fx-live .fx-btn { animation: fx-btn-glow 3.2s var(--fx-ease) infinite; }
@keyframes fx-btn-glow { 0%, 100% { box-shadow: 0 0 0 rgba(51,136,255,0); } 50% { box-shadow: 0 10px 52px rgba(51,136,255,0.28); } }
/* .fx-work + .fx-depth-para: touch keeps the staged cascade; desktop is scrub-driven (FX-4) */
.fx-live.fx-touch .fx-work, .fx-live.fx-touch .fx-depth-para { opacity: 0; transform: translateY(48px); }
.fx-live .fx-word { opacity: 0; }

/* ---- FX-4 · stats void: sticky full-viewport monuments (desktop live) ---- */
.fx-live:not(.fx-touch) .fx-zone--stats { display: block; height: 330vh; padding: 0; }
.fx-live:not(.fx-touch) .fx-monument { position: sticky; top: 0; min-height: 100vh; width: 100%; margin: 0; display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; will-change: transform, opacity, filter; }
.fx-live:not(.fx-touch) .fx-monument .fx-stat { font-size: clamp(6rem, 2rem + 18vw, 19rem); }
.fx-live:not(.fx-touch) .fx-monument .fx-stat-label { max-width: 44ch; margin-left: auto; margin-right: auto; }

/* ---- FX-4 · problem chamber: word-scrub base state ---- */
.fx-live [data-fx-scrub] .fxw { display: inline-block; will-change: opacity; }

/* ---- FX-4 · services gallery: pinned horizontal track (desktop live) ----
   The pinned frame must fit one viewport: type is compacted in this zone.
   overflow-x: clip contains the max-content track pre-pin WITHOUT creating a
   scroll container (GSAP's fixed pin is unaffected by ancestor clip). */
.fx-live:not(.fx-touch) .fx-zone--services { overflow-x: clip; }
.fx-live:not(.fx-touch) .fx-zone--services .fx-h2 { font-size: clamp(1.7rem, 1rem + 2.4vw, 3rem); margin-bottom: 1.2rem; max-width: 30ch; }
.fx-live:not(.fx-touch) .fx-zone--services .fx-pull { margin-bottom: 2rem; }
.fx-live:not(.fx-touch) .fx-zone--services .fx-kicker { margin-bottom: 1.2rem; }
.fx-live:not(.fx-touch) .fx-gallery { display: flex; gap: 3vw; border-top: none; width: max-content; padding: 2vh 4vw 2vh 0; will-change: transform; }
.fx-live:not(.fx-touch) .fx-work { position: relative; overflow: hidden; flex: 0 0 52vw; max-width: 760px; border: 1px solid var(--fx-hair); border-radius: 24px; padding: 2.8rem 2.8rem 2.4rem; display: block; will-change: opacity; background: var(--fx-panel); backdrop-filter: blur(2px); transition: background-color 0.5s; }
.fx-live:not(.fx-touch) .fx-work-num { display: block; padding: 0 0 1.2rem; font-size: 0.7rem; color: rgba(51,136,255,0.75); }
.fx-live:not(.fx-touch) .fx-work-title { margin-bottom: 1.1rem; }
.fx-live:not(.fx-touch) .fx-work-detail { opacity: 0.35; transition: opacity 0.45s var(--fx-ease); }
.fx-live:not(.fx-touch) .fx-work.is-focus .fx-work-detail { opacity: 1; }
.fx-work-tex { position: absolute; inset: 0; z-index: -1; background-size: cover; background-position: center; opacity: 0.1; transition: opacity 0.6s var(--fx-ease), transform 0.9s var(--fx-ease); transform: scale(1.06); }
.fx-work.is-focus .fx-work-tex { opacity: 0.28; transform: scale(1); }
/* FX-8/9 light: the chrome-macro texture is noise on light panels — silent
   until a panel takes focus, then a whisper of identity */
#fx-root[data-fx-theme="light"] .fx-work-tex { opacity: 0; }
#fx-root[data-fx-theme="light"] .fx-work.is-focus .fx-work-tex { opacity: 0.1; }

/* ---- FX-9 · forward travel (light, desktop): the problem + practice
   chambers get a real perspective camera; fx.js drives their frames along
   z so scroll reads as motion INTO the scene. Dark is untouched. ---- */
#fx-root[data-fx-theme="light"].fx-live:not(.fx-touch) .fx-zone--problem,
#fx-root[data-fx-theme="light"].fx-live:not(.fx-touch) .fx-zone--practice { perspective: 1100px; perspective-origin: 50% 45%; }
#fx-root[data-fx-theme="light"].fx-live:not(.fx-touch) .fx-zone--problem .fx-frame,
#fx-root[data-fx-theme="light"].fx-live:not(.fx-touch) .fx-zone--practice .fx-frame { will-change: transform, opacity, filter; }
.fx-live:not(.fx-touch) .fx-work.is-focus { border-color: rgba(51,136,255,0.4); }
.fx-gallery-progress { display: none; }
.fx-live:not(.fx-touch) .fx-gallery-progress { display: flex; align-items: center; gap: 1rem; margin-top: 2.2rem; font-family: var(--fx-mono); font-size: 0.62rem; letter-spacing: 0.18em; color: var(--fx-faint); }
.fx-gallery-progress-bar { width: 180px; height: 1px; background: var(--fx-hair); position: relative; overflow: hidden; }
.fx-gallery-progress-bar span { position: absolute; inset: 0; background: var(--fx-sky); transform-origin: left center; transform: scaleX(0); }

/* ---- mobile ---- */
@media (max-width: 820px) {
	.fx-hero-sub, .fx-depth-paras, .fx-practice-cols, .fx-how-cols, .fx-fit-cards { grid-template-columns: 1fr; gap: 2rem; }
	.fx-zone { padding: 14vh 0; }
	.fx-work { grid-template-columns: 44px 1fr; }
	.fx-top { padding: 1rem 1.2rem; }
	/* FX-8: keep the bar on one clean line now the theme switch joined it */
	.fx-top-nav { gap: 0.9rem; }
	.fx-top-nav a, .fx-theme-toggle { font-size: 0.56rem; letter-spacing: 0.12em; }
	.fx-touch .fx-corridor-words { align-content: center; }
	.fx-touch .fx-word { transform: translateY(28px); }
}

/* ---- reduced motion: static art-directed document ---- */
@media (prefers-reduced-motion: reduce) {
	.fx-loader, .fx-canvas, .fx-cursor { display: none !important; }
	.fx-live [data-fx-split] .fxw, .fx-live .fx-h1 .fxc, .fx-live .fx-monument .fx-stat, .fx-live .fx-work,
	.fx-live .fx-checklist li, .fx-live .fx-card, .fx-live .fx-depth-para, .fx-live .fx-word,
	.fx-live [data-fx-scrub] .fxw, .fx-live .fx-monument {
		opacity: 1 !important; transform: none !important; filter: none !important;
	}
	.fx-scrollcue-line, .fx-grain, .fx-live .fx-btn { animation: none !important; }
	.fx-live .fx-checklist li { opacity: 1 !important; transform: none !important; filter: none !important; }
	.fx-live:not(.fx-touch)[data-fx-climax="particles"] .fx-climax-num { opacity: 1 !important; min-height: 0; }
	.fx-live:not(.fx-touch) { cursor: auto; }
	.fx-live:not(.fx-touch) a { cursor: pointer; }
}
