/* presengen.com — the site's one stylesheet.
   Axes arrive as attributes on <html> (data-theme, data-accent, data-anim),
   stamped before first paint; everything here keys off tokens so a theme is
   a block of variables, never a second set of rules. */

/* ------------------------------------------------------------- tokens -- */

:root {
	--font: "Figtree", system-ui, -apple-system, "Segoe UI", sans-serif;
	--mono: "Cascadia Code", Consolas, monospace;
	--wrap: 1120px;
	--sec-pad: 96px;
	--radius: 14px;

	/* paper (light) */
	--bg: #f7f8fb;
	--bg-alt: #eef0f6;
	--surface: #ffffff;
	--ink: #101828;
	--ink-2: #344054;
	--dim: #667085;
	--line: #e4e7ec;
	--shadow: 0 1px 2px rgba(16, 24, 40, .05), 0 8px 24px rgba(16, 24, 40, .07);
	--code-bg: #0d1117;
	--code-ink: #e6edf3;
}
html[data-theme="ink"] {
	--bg: #0b0f17;
	--bg-alt: #0f1522;
	--surface: #141b2a;
	--ink: #e7ecf5;
	--ink-2: #c3cad8;
	--dim: #8b94a7;
	--line: #232c3f;
	--shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 10px 30px rgba(0, 0, 0, .45);
}
:root, html[data-accent="violet"] {
	--accent: #4f46e5;
	--accent-2: #7c3aed;
	--accent-ink: #ffffff;
	--accent-soft: rgba(99, 91, 240, .12);
}
html[data-accent="sky"] {
	--accent: #0284c7;
	--accent-2: #06b6d4;
	--accent-soft: rgba(2, 132, 199, .12);
}
html[data-accent="lime"] {
	--accent: #4d7c0f;
	--accent-2: #16a34a;
	--accent-soft: rgba(77, 124, 15, .12);
}
html[data-theme="ink"][data-accent="violet"] { --accent: #7b74ff; --accent-2: #a78bfa; --accent-ink: #0b0f17; }
html[data-theme="ink"][data-accent="sky"] { --accent: #38bdf8; --accent-2: #22d3ee; --accent-ink: #0b0f17; }
html[data-theme="ink"][data-accent="lime"] { --accent: #a3e635; --accent-2: #4ade80; --accent-ink: #0b0f17; }

html[data-anim="still"] *, html[data-anim="still"] *::before, html[data-anim="still"] *::after {
	animation: none !important;
	transition: none !important;
}

/* --------------------------------------------------------------- base -- */

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
html[data-anim="still"] { scroll-behavior: auto; }
body {
	margin: 0;
	font: 16px/1.6 var(--font);
	background: var(--bg);
	color: var(--ink);
	-webkit-font-smoothing: antialiased;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
img, svg { max-width: 100%; }
.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }
.wrap.narrow { max-width: 780px; }
.center { text-align: center; }
h1, h2, h3 { line-height: 1.15; letter-spacing: -.02em; margin: 0 0 .4em; }
h1 { font-size: clamp(34px, 5.2vw, 56px); font-weight: 800; }
h2 { font-size: clamp(26px, 3.4vw, 36px); font-weight: 800; }
h3 { font-size: 17px; font-weight: 700; }
p { margin: 0 0 1em; }
.eyebrow {
	font-size: 12.5px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
	color: var(--accent); margin: 0 0 12px;
}
.lead { font-size: clamp(16px, 1.6vw, 19px); color: var(--ink-2); max-width: 46em; }
.section-head { max-width: 720px; margin-bottom: 42px; }
.ico { width: 18px; height: 18px; }
.ico.big { width: 28px; height: 28px; color: var(--accent); }

.btn {
	display: inline-flex; align-items: center; gap: 9px;
	border: 1px solid var(--line); background: var(--surface); color: var(--ink);
	border-radius: 10px; padding: 11px 20px; font-weight: 700; font-size: 15px;
	text-decoration: none; transition: transform .12s, box-shadow .12s;
}
.btn:hover { text-decoration: none; transform: translateY(-1px); box-shadow: var(--shadow); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn-ghost { background: transparent; }
.btn-sm { padding: 7px 14px; font-size: 13.5px; border-radius: 8px; }
.btn-lg { padding: 14px 26px; font-size: 16.5px; }

/* ------------------------------------------------------------- header -- */

.site-header {
	position: sticky; top: 0; z-index: 50;
	background: color-mix(in srgb, var(--bg) 82%, transparent);
	backdrop-filter: blur(10px);
	border-bottom: 1px solid var(--line);
}
.header-inner { display: flex; align-items: center; gap: 22px; height: 64px; }
.brand { display: inline-flex; align-items: center; color: var(--ink); flex: none; }
.brand-lockup { width: 164px; height: 33px; color: var(--ink); }   /* 332×64 lockup since the whole piece 1 (2026-10-04) */
/* Ensamble in the header's lockup. At rest: piece 1 stands whole (2026-10-04;
   it used to be a bar that slid out), 2/3/4 hidden under A+B. site.js adds .is-intro once on arrival (A and B pop, the pieces
   unfold to the map and fold back, the word appears), then .is-again while the
   header is hovered, one run every five seconds (the pieces only; the word
   dims while 3 and 4 cross it). */
.brand-anim .ba-2, .brand-anim .ba-3, .brand-anim .ba-4 { opacity: 0; }
.ba-2 { --dx: 0px; --dy: -5px; }
.ba-3, .ba-4 { --dx: -5px; --dy: 0px; }
.brand-anim.is-intro .ba-a, .brand-anim.is-intro .ba-b { transform-box: fill-box; transform-origin: center; animation: baPop .5s cubic-bezier(.34, 1.56, .64, 1) both; }
.brand-anim.is-intro .ba-b { animation-delay: .12s; }
.brand-anim.is-intro .ba-p { animation: baGo 2.4s cubic-bezier(.65, 0, .35, 1) both; }
.brand-anim.is-intro .ba-2 { animation-delay: .75s; }
.brand-anim.is-intro .ba-3 { animation-delay: .9s; }
.brand-anim.is-intro .ba-4 { animation-delay: 1.05s; }
.brand-anim.is-intro .ba-word { animation: baWord .8s ease-out 3.1s both; }
.brand-anim.is-again .ba-p { animation: baGo 2.4s cubic-bezier(.65, 0, .35, 1) both; }
.brand-anim.is-again .ba-2 { animation-delay: .15s; }
.brand-anim.is-again .ba-3 { animation-delay: .3s; }
.brand-anim.is-again .ba-4 { animation-delay: .45s; }
.brand-anim.is-again .ba-word { animation: baDim 2.85s ease-in-out both; }
/* piece 1 does not move: it IS the mark's left piece */
.brand-anim.is-intro .ba-1, .brand-anim.is-again .ba-1 { animation: none; }
@keyframes baPop { from { opacity: 0; transform: scale(.5); } }
@keyframes baGo {
	0% { transform: translate(var(--dx), var(--dy)); opacity: 0; }
	12% { opacity: .5; }
	28%, 52% { transform: translate(0, 0); opacity: 1; }
	66% { opacity: .5; }
	80%, 100% { transform: translate(var(--dx), var(--dy)); opacity: 0; }
}
@keyframes baWord { from { opacity: 0; transform: translate(-12px, 0); } to { opacity: 1; transform: none; } }
@keyframes baDim { 0%, 100% { opacity: 1; } 18%, 62% { opacity: .12; } }
.site-nav { display: flex; align-items: center; gap: 4px; margin-left: auto; }
/* text links only — NOT the CTA button, whose .btn-primary colours must win
   (a bare `.site-nav a` rule outranks `.btn-primary` and was painting the
   button's label in dark ink on the accent, ~1.7:1 and unreadable) */
.site-nav a:not(.btn) {
	color: var(--ink-2); font-weight: 600; font-size: 14px;
	padding: 7px 11px; border-radius: 8px;
}
.site-nav a:not(.btn):hover { background: var(--accent-soft); color: var(--ink); text-decoration: none; }
.nav-signin { color: var(--accent) !important; }
.nav-cta { margin-left: 6px; }
.header-tools { display: flex; align-items: center; gap: 2px; }
.tool { position: relative; }
.tool-btn {
	display: inline-flex; align-items: center; gap: 5px;
	border: 0; background: none; color: var(--ink-2); font: inherit; font-weight: 700;
	font-size: 12.5px; padding: 8px; border-radius: 8px; cursor: pointer; text-transform: uppercase;
}
.tool-btn:hover { background: var(--accent-soft); color: var(--ink); }
.tool-menu {
	position: absolute; right: 0; top: calc(100% + 6px); min-width: 170px;
	background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
	box-shadow: var(--shadow); padding: 6px; display: none; z-index: 60;
}
.tool-menu.open { display: block; }
.tool-menu button {
	display: flex; width: 100%; align-items: center; gap: 8px; text-align: left;
	border: 0; background: none; color: var(--ink-2); font: inherit; font-weight: 600;
	font-size: 13.5px; padding: 8px 10px; border-radius: 8px; cursor: pointer;
}
.tool-menu button:hover { background: var(--accent-soft); color: var(--ink); }
.tool-menu button.on { color: var(--accent); }
.tool-menu .menu-h {
	font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
	color: var(--dim); padding: 8px 10px 3px;
}
.swatch { width: 13px; height: 13px; border-radius: 4px; border: 1px solid var(--line); flex: none; }
.swatch-paper { background: #f7f8fb; }
.swatch-ink { background: #0b0f17; }
.swatch-violet { background: #6d5cf0; }
.swatch-sky { background: #0ea5e9; }
.swatch-lime { background: #65a30d; }
.swatch-motion, .swatch-still { display: none; }
.nav-toggle { display: none; border: 0; background: none; padding: 10px; cursor: pointer; }
.nav-toggle span { display: block; width: 20px; height: 2px; background: var(--ink); margin: 4px 0; border-radius: 2px; }

/* --------------------------------------------------------------- hero -- */

.hero { position: relative; padding: 84px 0 90px; overflow: hidden; }
.hero-glow {
	position: absolute; inset: 0; pointer-events: none;
	background:
		radial-gradient(700px 380px at 82% -60px, var(--accent-soft) 0%, transparent 65%),
		radial-gradient(560px 320px at 6% 108%, var(--accent-soft) 0%, transparent 60%);
}
.hero-inner { position: relative; }
.hero h1 { max-width: 15em; }
.hero .hl { color: var(--accent); }
.hero-cta { display: flex; gap: 12px; flex-wrap: wrap; margin: 26px 0 0; }
.hero-cta.center { justify-content: center; }

.hero-mock {
	display: grid; grid-template-columns: minmax(0, 7fr) 44px minmax(0, 8fr);
	align-items: center; gap: 6px; margin-top: 58px;
}
.mock-code {
	background: var(--code-bg); border-radius: var(--radius); box-shadow: var(--shadow);
	padding: 0 0 8px; overflow: hidden; border: 1px solid rgba(255, 255, 255, .06);
}
.mock-bar {
	display: flex; align-items: center; gap: 6px; padding: 10px 14px;
	border-bottom: 1px solid rgba(255, 255, 255, .07);
}
.mock-bar i { width: 10px; height: 10px; border-radius: 50%; background: #2e3646; }
.mock-bar span { margin-left: 8px; color: #7d8590; font: 11.5px var(--mono); }
.mock-code pre {
	margin: 0; padding: 14px 18px 8px; font: 12.5px/1.7 var(--mono);
	color: var(--code-ink); overflow-x: auto;
}
.mock-code .c-d { color: #d2a8ff; font-weight: 600; }
.mock-code .c-h { color: #79c0ff; font-weight: 700; }
.mock-code .c-k { color: #7ee787; }
.mock-code .c-dim { color: #57606a; }
.mock-code .c-em { color: #f2cc60; }
.mock-note { margin: 2px 18px 8px; color: #57606a; font-size: 11.5px; }
.mock-arrow { width: 34px; height: 34px; color: var(--accent); justify-self: center; }

.mock-slide {
	position: relative; aspect-ratio: 16 / 9; border-radius: var(--radius);
	background: linear-gradient(135deg, #16203a 0%, #241d4f 55%, #3b2170 100%);
	color: #fff; box-shadow: var(--shadow); overflow: hidden;
	display: flex; flex-direction: column; justify-content: center; padding: 7% 9%;
}
.ms-eyebrow { font-size: clamp(8px, 1vw, 12px); letter-spacing: .14em; text-transform: uppercase; color: #b9a8ff; font-weight: 700; margin-bottom: 1em; }
.ms-headline { font-size: clamp(18px, 2.6vw, 34px); font-weight: 800; letter-spacing: -.02em; line-height: 1.1; margin-bottom: .45em; }
.ms-lead { font-size: clamp(10px, 1.3vw, 15px); color: #c9cee0; max-width: 30em; }
.ms-chips { display: flex; gap: 8px; margin-top: 1.4em; }
.ms-chips span {
	font-size: clamp(8px, 1vw, 12px); font-weight: 700; padding: .45em 1em;
	border-radius: 999px; border: 1px solid rgba(255, 255, 255, .25);
}
.ms-river { position: absolute; left: 0; right: 0; bottom: 0; height: 26%; color: #b9a8ff; }
.ms-river svg { width: 100%; height: 100%; }

/* -------------------------------------------------------------- bands -- */

.band { padding: var(--sec-pad) 0; }
.band.alt { background: var(--bg-alt); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }

.steps .step {
	position: relative; background: var(--surface); border: 1px solid var(--line);
	border-radius: var(--radius); padding: 26px 24px 20px; box-shadow: var(--shadow);
}
.step-n {
	position: absolute; top: 18px; right: 20px; font-size: 42px; font-weight: 800;
	color: var(--accent-soft); -webkit-text-stroke: 1.5px var(--accent); line-height: 1;
	opacity: .85;
}
.steps h3 { margin: 14px 0 6px; }
.steps p { color: var(--ink-2); font-size: 14.5px; margin: 0; }

.feat-card {
	background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
	padding: 20px 18px 16px;
}
.feat-card .ico { width: 22px; height: 22px; color: var(--accent); }
.feat-card h3 { font-size: 15px; margin: 12px 0 5px; }
.feat-card p { color: var(--ink-2); font-size: 13.5px; margin: 0; }

/* --------------------------------------------------------- theme strip -- */

.theme-strip {
	display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
	gap: 10px;
}
.tcard {
	border-radius: 11px; padding: 12px 12px 10px; border: 1px solid var(--line);
	background: var(--tc-bg, #fff); color: var(--tc-ink, #111);
	box-shadow: var(--shadow); min-height: 74px;
	display: flex; flex-direction: column; justify-content: space-between;
	transition: transform .12s;
}
.tcard:hover { transform: translateY(-2px) rotate(-.5deg); }
.tcard b { font-size: 12.5px; letter-spacing: -.01em; }
.tcard .bar { display: flex; gap: 4px; margin-top: 10px; }
.tcard .bar i { height: 5px; border-radius: 3px; background: var(--tc-a, #888); opacity: .9; }
.tcard .bar i:nth-child(1) { width: 34%; }
.tcard .bar i:nth-child(2) { width: 22%; opacity: .55; }
.tcard .bar i:nth-child(3) { width: 14%; opacity: .3; }

/* -------------------------------------------------------------- plans -- */

.plan-grid { align-items: stretch; }
.plan {
	position: relative; background: var(--surface); border: 1px solid var(--line);
	border-radius: 16px; padding: 28px 26px; box-shadow: var(--shadow);
	display: flex; flex-direction: column;
}
.plan.hot { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft), var(--shadow); }
.plan-tag {
	position: absolute; top: -12px; right: 18px; background: var(--accent); color: var(--accent-ink);
	font-size: 11px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
	padding: 4px 11px; border-radius: 999px;
}
.plan h3 { font-size: 16px; }
.plan .price { font-size: 38px; font-weight: 800; letter-spacing: -.03em; margin: 2px 0 10px; }
.plan .price small { font-size: 13px; color: var(--dim); font-weight: 600; letter-spacing: 0; }
.plan ul { list-style: none; margin: 0 0 22px; padding: 0; display: grid; gap: 9px; }
.plan li { display: flex; gap: 9px; font-size: 14px; color: var(--ink-2); align-items: baseline; }
.plan li .ico { width: 14px; height: 14px; color: var(--accent-2); flex: none; transform: translateY(2px); }
.plan .btn { margin-top: auto; justify-content: center; }

/* ---------------------------------------------------------------- faq -- */

.faq-item {
	background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
	margin-bottom: 10px; overflow: hidden;
}
.faq-item summary {
	cursor: pointer; list-style: none; padding: 16px 20px; font-weight: 700;
	display: flex; justify-content: space-between; align-items: center; gap: 12px;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; font-size: 20px; color: var(--accent); flex: none; }
.faq-item[open] summary::after { content: "–"; }
.faq-item .faq-a { padding: 0 20px 18px; color: var(--ink-2); font-size: 14.5px; }

/* ---------------------------------------------------------------- cta -- */

.cta-band {
	background:
		radial-gradient(640px 300px at 50% -80px, var(--accent-soft) 0%, transparent 70%),
		var(--bg-alt);
}
.cta-alt { margin-top: 14px; font-size: 14px; }

/* ------------------------------------------------------------- footer -- */

.site-footer { border-top: 1px solid var(--line); padding: 46px 0 26px; background: var(--bg); }
.footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 30px; }
.f-brand .brand-lockup { width: 149px; height: 30px; color: var(--ink); }
.f-brand p { color: var(--dim); font-size: 13.5px; margin-top: 10px; }
.f-col h4 { margin: 4px 0 10px; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--dim); }
.f-col a { display: block; color: var(--ink-2); font-size: 14px; padding: 3px 0; }
.footer-legal { margin-top: 30px; padding-top: 16px; border-top: 1px solid var(--line); color: var(--dim); font-size: 12.5px; }

/* the view container while a page loads */
.nw-view { min-height: 40vh; }
.nw-loading { display: grid; place-items: center; padding: 90px 0; }
.spinner {
	width: 26px; height: 26px; border-radius: 50%;
	border: 3px solid var(--line); border-top-color: var(--accent);
	animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ------------------------------------------------------- scroll-reveal -- */
/* anything marked .reveal lifts in once, when site.js adds .in as it enters
   the viewport. A tiny per-column stagger gives a grid some life. */
.reveal { opacity: 0; transform: translateY(18px); transition: opacity .55s ease, transform .55s cubic-bezier(.2, .7, .2, 1); }
.reveal.in { opacity: 1; transform: none; }
.feat-grid .feat-card:nth-child(4n+2).in { transition-delay: .05s; }
.feat-grid .feat-card:nth-child(4n+3).in { transition-delay: .1s; }
.feat-grid .feat-card:nth-child(4n+4).in { transition-delay: .15s; }

/* ----------------------------------------------------- present-live band -- */
/* the marquee: an always-dark stage (like the hero's slide mock) so the live
   story reads as a different, on-air place regardless of the page theme. */
.live-band { background: linear-gradient(155deg, #0f1430 0%, #191139 58%, #241a4d 100%); color: #eaeefc; overflow: hidden; }
.live-inner { display: grid; grid-template-columns: 1.02fr .98fr; gap: 52px; align-items: center; }
.live-band .eyebrow { color: #b9a8ff; }
.live-band h2 { color: #fff; }
.live-band .lead { color: #c4c9e6; }
.live-points { display: grid; gap: 20px; margin-top: 28px; }
.lpoint { display: flex; gap: 14px; }
.lpoint .ico { width: 22px; height: 22px; color: #b9a8ff; flex: none; margin-top: 2px; }
.lpoint h3 { font-size: 15px; margin: 0 0 3px; color: #fff; }
.lpoint p { color: #b6bcda; font-size: 14px; margin: 0; }

/* the welcome-room mock */
.live-stage {
	background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .12);
	border-radius: 20px; padding: 22px; box-shadow: 0 24px 60px rgba(0, 0, 0, .38);
	max-width: 420px; margin: 0 auto; width: 100%;
}
.lstage-top { display: flex; align-items: center; justify-content: space-between; }
.live-pill {
	display: inline-flex; align-items: center; gap: 6px; background: #e02424; color: #fff;
	font-size: 11px; font-weight: 800; letter-spacing: .05em; padding: 4px 9px; border-radius: 999px;
}
.live-pill i { width: 6px; height: 6px; border-radius: 50%; background: #fff; animation: lpulse 1.3s ease-in-out infinite; }
.watching { display: inline-flex; align-items: center; gap: 7px; color: #c4c9e6; font-size: 13px; font-weight: 600; }
.watching .dot { width: 7px; height: 7px; border-radius: 50%; background: #24d16a; box-shadow: 0 0 6px rgba(36, 209, 106, .7); }
.lstage-join { display: flex; align-items: center; gap: 16px; margin: 20px 0; }
.lstage-join .qr { width: 116px; height: 116px; background: #fff; border-radius: 12px; padding: 8px; flex: none; box-shadow: 0 6px 18px rgba(0, 0, 0, .3); }
.lstage-join .qr rect[width="25"] { fill: #fff; }
.join-hint { display: inline-flex; align-items: center; gap: 8px; color: #d5d9f0; font-size: 14px; font-weight: 600; }
.join-hint .ico { width: 18px; height: 18px; color: #b9a8ff; }
.lstage-quiz { border-top: 1px solid rgba(255, 255, 255, .1); padding-top: 16px; }
.q-q { font-size: 13.5px; font-weight: 700; color: #fff; margin-bottom: 12px; }
.q-row { display: grid; grid-template-columns: 52px 1fr 40px; align-items: center; gap: 10px; margin-bottom: 9px; }
.q-lab { font-size: 12.5px; color: #c4c9e6; }
.q-bar { height: 9px; background: rgba(255, 255, 255, .1); border-radius: 999px; overflow: hidden; }
.q-bar i { display: block; height: 100%; width: 0; border-radius: 999px; background: linear-gradient(90deg, #6d5efc, #a78bfa); }
.q-pct { font-size: 12px; font-weight: 700; color: #d5d9f0; text-align: right; font-variant-numeric: tabular-nums; }
.live-stage.in .q-bar i { animation: qfill 1s cubic-bezier(.2, .7, .2, 1) .25s both; }
@keyframes qfill { from { width: 0; } to { width: var(--w); } }
@keyframes lpulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.7); } }

/* ------------------------------------------------ 3D tours: the mock -- */
/* a screenshot taken apart: the screen tilts, a region lifts out of its
   hole toward the room, its note stands beside it — then it settles back.
   The resting pose IS the lifted one, so "still" shows the point at once. */
.tours-band .lpoint h3 { color: var(--ink); }
.tours-band .lpoint p { color: var(--dim); }
.tours-band .lpoint .ico { color: var(--accent); }
.tour-stage { position: relative; height: 340px; max-width: 500px; width: 100%; margin: 0 auto; perspective: 1100px; }
.ts-screen {
	position: absolute; inset: 12% 4% 10% 8%; display: grid; grid-template-columns: 20% 1fr;
	background: var(--surface); border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
	transform: rotateY(-16deg) rotateX(7deg); transform-origin: 60% 50%; box-shadow: var(--shadow);
}
.ts-side { background: #1b2232; display: flex; flex-direction: column; gap: 10px; padding: 14px 10px; }
.ts-side i { height: 8px; border-radius: 4px; background: rgba(255, 255, 255, .22); }
.ts-side i:nth-child(2) { background: #B8B9BF; }
.ts-main { position: relative; padding: 12px 14px; display: flex; flex-direction: column; gap: 12px; }
.ts-bar { height: 12px; border-radius: 6px; background: var(--bg-alt); width: 70%; }
.ts-rows { display: grid; gap: 8px; }
.ts-rows i { height: 8px; border-radius: 4px; background: var(--bg-alt); }
.ts-rows i:nth-child(odd) { width: 86%; }
.ts-hole { position: absolute; right: 8%; bottom: 10%; width: 46%; height: 42%; border: 2px dashed var(--accent); border-radius: 8px; opacity: .55; }
.ts-piece {
	position: absolute; left: 50%; top: 45%; width: 38%; height: 34%; padding: 10px;
	background: var(--surface); border: 2px solid var(--accent); border-radius: 10px;
	box-shadow: 0 26px 50px rgba(16, 24, 40, .28); transform: translate(-4%, -30%) scale(1.22);
	animation: tsLift 6s cubic-bezier(.65, 0, .35, 1) infinite;
}
.ts-chart { display: flex; align-items: flex-end; gap: 6%; height: 100%; }
.ts-chart i { flex: 1; height: var(--h); border-radius: 3px 3px 0 0; background: linear-gradient(180deg, var(--accent), #8B85FF); }
.ts-note {
	position: absolute; left: 0; top: 4%; width: 46%; padding: 10px 12px; border-radius: 10px;
	background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--accent); box-shadow: var(--shadow);
	display: grid; gap: 3px; font-size: 12.5px; animation: tsNote 6s cubic-bezier(.65, 0, .35, 1) infinite;
}
.ts-note b { color: var(--accent); font-size: 13px; }
.ts-note span { color: var(--dim); }
@keyframes tsLift {
	0%, 12%, 92%, 100% { transform: translate(8%, 18%) scale(1); box-shadow: 0 2px 6px rgba(16, 24, 40, .12); }
	28%, 76% { transform: translate(-4%, -30%) scale(1.22); box-shadow: 0 26px 50px rgba(16, 24, 40, .28); }
}
@keyframes tsNote { 0%, 20%, 84%, 100% { opacity: 0; transform: translateY(6px); } 32%, 72% { opacity: 1; transform: none; } }
.nw-loading-mark { opacity: .9; }

/* ----------------------------------------- the hero: the mark, explained --
   presengen's Despliegue, with words: folded, the P — "you are here" on B;
   unfolded, the deck — chapters across (3, 4), slides down (2). The labels
   ride the same clock as the pieces they name. */
.hero-inner { position: relative; }
.hero-map { position: absolute; right: 0; top: 18px; width: min(40%, 430px); overflow: visible; pointer-events: none; }
.hm-p, .hm-a { fill: var(--iso-grey, #B8B9BF); }
.hm-b { fill: var(--iso-blue, #4F46E5); }
.hm-p { animation: hmOut 5.2s cubic-bezier(.65, 0, .35, 1) infinite both; }
.hm-1 { animation-name: hmBar; animation-delay: .6s; }
.hm-2 { --dx: 0px; --dy: -5px; animation-delay: .85s; }
.hm-3 { --dx: -5px; --dy: 0px; animation-delay: 1.1s; }
.hm-4 { --dx: -5px; --dy: 0px; animation-delay: 1.35s; }
@keyframes hmOut {
	0% { transform: translate(var(--dx), var(--dy)); opacity: 0; }
	9% { opacity: .5; }
	18%, 62% { transform: translate(0, 0); opacity: 1; }
	71% { opacity: .5; }
	80%, 100% { transform: translate(var(--dx), var(--dy)); opacity: 0; }
}
@keyframes hmBar { 0%, 80%, 100% { transform: translate(3px, 0); } 18%, 62% { transform: translate(0, 0); } }
.hm-t { font: 700 .95px var(--font); fill: var(--dim); letter-spacing: .01em; animation: 5.2s ease-in-out infinite both; }
.hm-ch { fill: var(--accent); animation-name: hmSay; animation-delay: 1.1s; }
.hm-sl { fill: var(--accent); animation-name: hmSay; animation-delay: .85s; }
.hm-here { fill: var(--iso-blue, #4F46E5); animation-name: hmHere; animation-delay: .6s; }
@keyframes hmSay { 0%, 12% { opacity: 0; } 22%, 60% { opacity: 1; } 70%, 100% { opacity: 0; } }
@keyframes hmHere { 0% { opacity: 1; } 8%, 76% { opacity: 0; } 88%, 100% { opacity: 1; } }
html[data-anim="still"] .hm-p { opacity: 1; transform: none; }
html[data-anim="still"] .hm-1 { transform: none; }
html[data-anim="still"] .hm-t { opacity: 1; }
html[data-anim="still"] .hm-here { opacity: 0; }
@media (min-width: 1101px) {                      /* the words keep clear of the map */
	.hero-inner > .eyebrow, .hero-inner > h1, .hero-inner > .lead { max-width: calc(100% - min(40%, 430px) - 8px); }
}
@media (max-width: 1100px) { .hero-map { display: none; } }

/* ------------------------------------------- the hero: the live demo -- */
/* the row is as tall as the deck (16:9); the editor stretches to match */
.hero-demo { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 26px; align-items: stretch; margin-top: 58px; }
.demo-code {
	background: var(--code-bg); border-radius: var(--radius); box-shadow: var(--shadow);
	overflow: hidden; border: 1px solid rgba(255, 255, 255, .06);
	display: flex; flex-direction: column; min-height: 0;
}
.demo-code .mock-bar { position: relative; }
.demo-reset { margin-left: auto; font: 600 11.5px var(--font); color: #c9d1d9; background: rgba(255, 255, 255, .08);
	border: 1px solid rgba(255, 255, 255, .16); border-radius: 6px; padding: 3px 10px; cursor: pointer; }
.demo-reset:hover { border-color: var(--accent); color: #fff; }
.demo-ed { position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); flex: 1 1 auto; height: 0; min-height: 0; overflow: hidden; }
.demo-gutter { margin: 0; padding: 12px 10px 12px 14px; font: 12.5px/1.7 var(--mono); color: #3d4757; text-align: right;
	user-select: none; border-right: 1px solid rgba(255, 255, 255, .05); tab-size: 4; }
.demo-cell { position: relative; overflow: hidden; }
.demo-hl { position: absolute; top: 0; left: 0; min-width: 100%; margin: 0; padding: 12px 16px; pointer-events: none;
	font: 12.5px/1.7 var(--mono); color: var(--code-ink); white-space: pre; tab-size: 4; }
.demo-hl code { font: inherit; }
.demo-ta { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 12px 16px; border: 0; outline: none; resize: none;
	background: transparent; color: transparent; caret-color: #e6edf3; font: 12.5px/1.7 var(--mono); white-space: pre; overflow: auto; tab-size: 4;
	scrollbar-width: thin; scrollbar-color: rgba(220, 230, 245, .5) rgba(255, 255, 255, .06); }
.demo-ta::selection { background: rgba(130, 170, 255, .32); }
.demo-code .c-d { color: #d2a8ff; font-weight: 600; }
.demo-code .c-h { color: #79c0ff; font-weight: 700; }
.demo-code .c-k { color: #7ee787; }
.demo-code .c-dim { color: #57606a; }
.demo-code .c-em { color: #f2cc60; }
.demo-code .c-p { color: #ffa198; }
.demo-code .c-v { color: #f2cc60; }
.demo-code .mock-note { margin: 8px 16px 10px; min-height: 1.2em; flex: none; }
.demo-code .mock-note.is-bad { color: #f97066; }
.demo-deck { align-self: start; border-radius: var(--radius); overflow: hidden; box-shadow: 0 24px 60px rgba(16, 24, 40, .25); background: #0b0b14; }
.demo-deck iframe { display: block; width: 100%; aspect-ratio: 16 / 9; border: 0; }
/* On a phone the frame is ~340px wide, where the deck would switch to its own
   phone chrome (a navigator pill over a third of the slide). Render it at twice
   the size and scale it down, so it looks as it does on a desktop. */
@media (max-width: 600px) {
	.demo-deck { position: relative; aspect-ratio: 16 / 9; }
	.demo-deck iframe { position: absolute; left: 0; top: 0; width: 200%; transform: scale(.5); transform-origin: 0 0; }
}

/* --------------------------------------------------------- responsive -- */

@media (max-width: 960px) {
	:root { --sec-pad: 64px; }
	.grid-4 { grid-template-columns: 1fr 1fr; }
	.grid-3 { grid-template-columns: 1fr; }
	.hero-demo { grid-template-columns: 1fr; }
	.demo-ed { flex: none; height: 300px; }
	.live-inner { grid-template-columns: 1fr; gap: 34px; }
	.live-stage { order: -1; }
	.footer-grid { grid-template-columns: 1fr; gap: 20px; }
	.site-nav {
		position: fixed; inset: 64px 0 auto 0; flex-direction: column; align-items: stretch;
		background: var(--surface); border-bottom: 1px solid var(--line);
		box-shadow: var(--shadow); padding: 14px 18px 22px; display: none; z-index: 49;
	}
	.site-nav.open { display: flex; }
	.site-nav a { padding: 12px 10px; font-size: 15px; }
	.nav-toggle { display: block; }
}
/* --------------------------------------------------------- text animation --
   The looks half of assets/js/nw_anim.js. That file decides WHEN something
   plays and hands over two custom properties — --anim-dur for the pass and --d
   for this letter's delay — plus --c for the colour effects. Everything below
   is driven by those, so a new effect is one keyframe block and one class,
   with no JavaScript change at all.

   .nw-anim wraps the phrase; .nw-anim-c is one letter, present only for the
   effects that need them. Nothing animates until .is-anim lands. */
.nw-anim { display: inline-block; }
/* a word of split letters stays on one line; the spaces between words are
   still ordinary break opportunities */
.nw-anim-w { white-space: nowrap; }
/* A phrase that replays on click has to look like it will. The focus ring is
   the standard one, since click also binds Enter and Space. */
.nw-anim[data-anim-when*="click"] { cursor: pointer; }
.nw-anim[data-anim-when*="click"]:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 4px;
	border-radius: 2px;
}
.nw-anim-c {
	display: inline-block;
	font-style: inherit;
	will-change: transform, opacity, color;
}

/* The letters of a typewriter start absent, not merely transparent — but only
   while the effect is actually running. Hiding them on .nw-anim-typewritter
   alone, as this did, is the one rule in this file that fails INVISIBLE: every
   other effect keeps its hiding inside a keyframe, so an element left without
   .is-anim simply looks unanimated, while this one left the words gone.

   And they do get left without it. The class naming the effect is put on by the
   pass and stays; .is-anim is taken off by stop(), which clear() calls on every
   live phrase — so changing the theme, the accent or the animation setting
   strips it from the whole page, and only the phrases on screen are played
   again. A heading that was not in view at that moment kept the typewriter
   class with nothing to animate it, and stayed blank until it was clicked.
   Scoping the rule to .is-anim is what makes the effect fail visible: the
   words come back by themselves, and the animation is unchanged, since
   `forwards` holds the last keyframe once the pass is over. */
.nw-anim-typewritter.is-anim .nw-anim-c {
	opacity: 0;
	animation: nwType .001s linear var(--d, 0s) forwards;
}
@keyframes nwType { to { opacity: 1; } }

.nw-anim-change-color.is-anim .nw-anim-c {
	animation: nwColor var(--anim-dur, .6s) ease-in-out var(--d, 0s) both;
}
@keyframes nwColor {
	40% { color: var(--c, var(--accent)); }
	60% { color: var(--c, var(--accent)); }
	to  { color: inherit; }
}

.nw-anim-bend.is-anim .nw-anim-c {
	animation: nwBend var(--anim-dur, .6s) ease-in-out var(--d, 0s) both;
}
@keyframes nwBend {
	40% { transform: translateY(-.24em) rotate(-6deg); }
	to  { transform: none; }
}

.nw-anim-flip.is-anim .nw-anim-c {
	animation: nwFlip var(--anim-dur, .6s) ease-in-out var(--d, 0s) both;
}
@keyframes nwFlip {
	50% { transform: rotateX(-90deg); }
	to  { transform: none; }
}

.nw-anim-rise.is-anim .nw-anim-c {
	animation: nwRise var(--anim-dur, .6s) var(--ease) var(--d, 0s) both;
}
@keyframes nwRise {
	from { transform: translateY(.7em); opacity: 0; }
	to   { transform: none; opacity: 1; }
}

.nw-anim-blur.is-anim .nw-anim-c {
	animation: nwBlur var(--anim-dur, .6s) ease-out var(--d, 0s) both;
}
@keyframes nwBlur {
	from { filter: blur(8px); opacity: 0; }
	to   { filter: none; opacity: 1; }
}

/* whole-phrase effects — no letters involved */
.nw-anim-tilt.is-anim {
	animation: nwTilt var(--anim-dur, .6s) ease-in-out both;
	transform-origin: left center;
}
@keyframes nwTilt {
	35% { transform: rotate(-2.2deg) scale(1.03); }
	to  { transform: none; }
}

/* The sweep rides a gradient through the text, so the text has to be painted
   from the background — and the ends of that gradient have to BE the real
   colour, which is what currentColor gives, but only while `color` still holds
   it. Setting `color: transparent` here would make currentColor transparent
   too and the phrase would vanish the moment the sweep starts;
   -webkit-text-fill-color hides the painted glyph without touching what
   currentColor means. */
.nw-anim-shine.is-anim {
	background: linear-gradient(100deg,
		currentColor 0%, currentColor 38%,
		color-mix(in srgb, var(--accent) 55%, #fff) 50%,
		currentColor 62%, currentColor 100%);
	background-size: 300% 100%;
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	animation: nwShine var(--anim-dur, 1.8s) linear both;
}
@keyframes nwShine {
	from { background-position: 120% 0; }
	to   { background-position: -60% 0; }
}

/* Someone who asked for less motion gets the words and none of the movement.
   nw_anim already refuses to play, but a stray class must not linger. */
@media (prefers-reduced-motion: reduce) {
	.nw-anim, .nw-anim-c { animation: none !important; opacity: 1 !important; }
	.nw-anim-shine.is-anim { background: none; -webkit-text-fill-color: currentColor; }
	.reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
	.live-pill i { animation: none; }
	.live-stage .q-bar i { animation: none; width: var(--w); }
}


/* the mark's blue on the dark look: the lighter one of logo-dark.svg */
html[data-theme="ink"] { --iso-blue: #8B85FF; }
