/* ===================================================================
   Device Cloud — site design system

   Inherited from the app's own palette (Resources/Styles/Colors.xaml,
   theme name "Signal"), and extended by one idea that the old sheet
   did not have: colour here is a RAMP OF DISTANCE, not a set of
   brand accents.

       cyan    the device itself   — loopback
       indigo  this network        — the wifi you are on
       fuchsia anywhere            — the public tunnel
       amber   off until you say so

   Everything that carries colour on this page — a card's spine, a
   route's rail, a ring in the hero, the hero's own wash — takes it
   from where on that ramp the thing belongs. That is why the palette
   is allowed to be loud: it is the product's only real subject
   (how far your files travel, and on whose say-so) rendered as hue.
   A card whose spine is fuchsia is a card about reaching off the
   device. Colour picked for prettiness would have to be rationed;
   colour that means something can be spent.

   Motion follows the same rule. There is exactly one non-interactive
   animation with a job — the hero walking its three reaches, taking
   the whole band's colour with it — plus aurora drift behind it. The
   rest answers a pointer or a scroll.
   =================================================================== */

/* ─── reset ─── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
img { max-width: 100%; height: auto; }
[hidden] { display: none !important; }

:root {
    /* ---- the reach ramp ---- */
    --r0: #06B6D4;   /* on the device */
    --r0-lit: #22D3EE;
    --r0-soft: #67E8F9;

    --r1: #4F46E5;   /* this network */
    --r1-lit: #6366F1;
    --r1-soft: #A5B4FC;

    --r2: #C026D3;   /* anywhere */
    --r2-lit: #D946EF;
    --r2-soft: #F0ABFC;

    --amber: #F59E0B;
    --amber-lit: #FBBF24;
    --ok: #10B981;

    /* Set per-section (and, in the hero, per-reach) so one rule can paint
       a spine, a ring and a glow from the same source. */
    --accent: var(--r1);
    --accent-lit: var(--r1-lit);
    --accent-soft: var(--r1-soft);

    /* ---- the night: identical in both themes, because a hero that
       flips is a hero with no identity ---- */
    --night: #08090F;
    --night-2: #14162A;
    --night-ink: #EFF1FB;
    --night-ink-2: #9AA1C4;
    --night-line: rgba(239, 241, 251, 0.10);
    --night-line-strong: rgba(239, 241, 251, 0.20);

    /* ---- themed surfaces: light ---- */
    --bg: #F6F7FC;
    --surface: #FFFFFF;
    --surface-2: #ECEEF8;
    --ink: #0E1020;
    --ink-2: #565C7E;
    --ink-3: #878DAC;
    --line: #E1E4F0;
    --line-soft: rgba(14, 16, 32, 0.06);
    --nav-bg: rgba(255, 255, 255, 0.72);
    --shadow-card: 0 1px 2px rgba(14, 16, 32, 0.05);
    --tint: 0.14;   /* how strongly an accent tints a chip on this theme */
    --tint-hi: 0.22;

    /* ---- scale ---- */
    --s1: 0.25rem; --s2: 0.5rem; --s3: 0.75rem; --s4: 1rem; --s5: 1.25rem;
    --s6: 1.5rem; --s8: 2rem; --s10: 2.5rem; --s12: 3rem; --s16: 4rem;
    --s20: 5rem; --s24: 6rem;

    --r-sm: 6px; --r-md: 10px; --r-lg: 16px; --r-xl: 26px;

    --font-display: 'Sora', 'Segoe UI', system-ui, sans-serif;
    --font-body: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

    --ease: cubic-bezier(0.16, 1, 0.3, 1);
    --spring: cubic-bezier(0.34, 1.4, 0.5, 1);
    --fast: 140ms; --normal: 280ms; --slow: 620ms;
    --max: 1180px;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --bg: #08090F;
        --surface: #14162A;
        --surface-2: #0E1020;
        --ink: #EFF1FB;
        --ink-2: #9AA1C4;
        --ink-3: #6B7196;
        --line: #242840;
        --line-soft: rgba(239, 241, 251, 0.07);
        --nav-bg: rgba(8, 9, 15, 0.72);
        --shadow-card: none;
        --tint: 0.16;
        --tint-hi: 0.26;

        /* Lifted a step on dark, where the deep values go muddy against #08090F. */
        --r0: #22D3EE; --r1: #818CF8; --r2: #E879F9;
    }
}

:root[data-theme="dark"] {
    --bg: #08090F;
    --surface: #14162A;
    --surface-2: #0E1020;
    --ink: #EFF1FB;
    --ink-2: #9AA1C4;
    --ink-3: #6B7196;
    --line: #242840;
    --line-soft: rgba(239, 241, 251, 0.07);
    --nav-bg: rgba(8, 9, 15, 0.72);
    --shadow-card: none;
    --tint: 0.16;
    --tint-hi: 0.26;
    --r0: #22D3EE; --r1: #818CF8; --r2: #E879F9;
}

/* ─── base ─── */
body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

h1, h2, h3, h4 {
    font-family: var(--font-display);
    letter-spacing: -0.03em;
    text-wrap: balance;
    margin: 0;
}

p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }

/* Mono is reserved for text that genuinely IS an address, a path, a port
   or a glob. It is the product's subject matter, not a label style. */
code, .mono { font-family: var(--font-mono); font-size: 0.9em; }

:focus-visible {
    outline: 2px solid var(--accent-lit);
    outline-offset: 3px;
    border-radius: 3px;
}

.wrap {
    max-width: var(--max);
    margin: 0 auto;
    padding: 0 var(--s6);
}

.band { padding: var(--s24) 0; position: relative; }
.band--tight { padding: var(--s16) 0; }

.band--night {
    background: var(--night);
    color: var(--night-ink);
    position: relative;
    overflow: hidden;
}

/* Which reach a section is about. One attribute paints everything in it. */
[data-reach="0"] { --accent: var(--r0); --accent-lit: var(--r0-lit); --accent-soft: var(--r0-soft); }
[data-reach="1"] { --accent: var(--r1); --accent-lit: var(--r1-lit); --accent-soft: var(--r1-soft); }
[data-reach="2"] { --accent: var(--r2); --accent-lit: var(--r2-lit); --accent-soft: var(--r2-soft); }

/* ─── nav ─── */
.nav {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 100;
    background: var(--nav-bg);
    backdrop-filter: blur(20px) saturate(160%);
    -webkit-backdrop-filter: blur(20px) saturate(160%);
    border-bottom: 1px solid transparent;
    transition: border-color var(--normal) var(--ease), background var(--normal) var(--ease);
}

.nav.is-stuck { border-bottom-color: var(--line); }

/* The scroll meter: how far down the page you are, painted with the ramp,
   so the page's own progress reads as reach travelled. */
.nav::after {
    content: '';
    position: absolute;
    left: 0; bottom: -1px;
    height: 2px;
    width: 100%;
    transform: scaleX(var(--progress, 0));
    transform-origin: 0 50%;
    background: linear-gradient(90deg, var(--r0-lit), var(--r1-lit) 55%, var(--r2-lit));
}

.nav__inner {
    max-width: var(--max);
    margin: 0 auto;
    padding: 0 var(--s6);
    height: 64px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s6);
}

.brand {
    display: flex;
    align-items: center;
    gap: var(--s3);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.06rem;
    letter-spacing: -0.03em;
}

.brand svg { width: 30px; height: 30px; flex: none; }

.nav__links { display: flex; align-items: center; gap: var(--s6); }

.nav__links a {
    position: relative;
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--ink-2);
    transition: color var(--fast) var(--ease);
}

.nav__links a:not(.nav__gh)::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: -6px;
    height: 2px;
    border-radius: 2px;
    background: var(--r1-lit);
    transform: scaleX(0);
    transform-origin: 0 50%;
    transition: transform var(--normal) var(--ease);
}

.nav__links a:hover { color: var(--ink); }
.nav__links a:not(.nav__gh):hover::after { transform: scaleX(1); }

/* .nav__links a is (0,1,1) and this is (0,1,0), so the colour below loses to the
   muted link colour above unless the selector matches it - which is how the CTA
   ended up with grey text on its own gradient. */
.nav__links a.nav__gh {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    padding: var(--s2) var(--s4);
    border-radius: var(--r-sm);
    font-size: 0.85rem;
    font-weight: 600;
    color: #fff;
    background: linear-gradient(120deg, #4F46E5 0%, #A21CAF 100%);
    box-shadow: 0 4px 14px -4px rgba(79, 70, 229, 0.6);
    transition: transform var(--fast) var(--spring), box-shadow var(--fast) var(--ease);
}

.nav__links a.nav__gh svg { width: 15px; height: 15px; }
.nav__links a.nav__gh:hover { transform: translateY(-1px); box-shadow: 0 8px 22px -6px rgba(192, 38, 211, 0.65); }

.nav__theme {
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    color: var(--ink-2);
    width: 38px; height: 34px;
    flex: none;
    cursor: pointer;
    transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}

.nav__theme:hover { color: var(--ink); border-color: var(--r1-lit); }
.nav__theme + .nav__burger { margin-left: calc(var(--s6) * -1 + var(--s2)); }
.nav__theme svg { width: 17px; height: 17px; }

/* The icon names the theme you would switch *to*, swapped with the same three-state selector the
   tokens use - so it is already right on the first paint, before main.js runs. */
.nav__theme .i-sun { display: none; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .nav__theme .i-moon { display: none; }
    :root:not([data-theme="light"]) .nav__theme .i-sun  { display: block; }
}

:root[data-theme="dark"] .nav__theme .i-moon { display: none; }
:root[data-theme="dark"] .nav__theme .i-sun  { display: block; }

.nav__inner > .brand { margin-right: auto; }

.nav__burger {
    display: none;
    background: none;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    color: var(--ink);
    width: 38px; height: 34px;
    cursor: pointer;
    align-items: center;
    justify-content: center;
}
.nav__burger svg { width: 18px; height: 18px; }

/* ─── buttons ─── */
.btn {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    padding: var(--s3) var(--s6);
    border-radius: var(--r-md);
    font-family: var(--font-body);
    font-size: 0.95rem;
    font-weight: 600;
    border: 1px solid transparent;
    cursor: pointer;
    transition: transform var(--fast) var(--spring), box-shadow var(--normal) var(--ease),
                background var(--fast) var(--ease), border-color var(--fast) var(--ease);
}

.btn svg { width: 17px; height: 17px; flex: none; }

.btn--primary {
    position: relative;
    color: #fff;
    background: linear-gradient(115deg, var(--r0) -10%, #4F46E5 45%, var(--r2) 115%);
    background-size: 200% 100%;
    box-shadow: 0 10px 30px -8px rgba(99, 102, 241, 0.75);
    overflow: hidden;
}

.btn--primary:hover {
    background-position: 100% 0;
    transform: translateY(-2px);
    box-shadow: 0 16px 40px -10px rgba(192, 38, 211, 0.7);
}

.btn--ghost {
    background: rgba(239, 241, 251, 0.06);
    color: var(--night-ink);
    border-color: var(--night-line-strong);
}
.btn--ghost:hover { background: rgba(239, 241, 251, 0.13); transform: translateY(-2px); }

.btn--lg { padding: var(--s4) var(--s8); font-size: 1rem; }

/* ─── hero ────────────────────────────────────────────────────────────
   The one place boldness is spent. The band's --reach is set by script
   every few seconds, and everything below reads its colour from that:
   the aurora, the rings, the live dot, the URL. The page's thesis is
   that the product is an address whose reach you choose, so the hero
   is that address changing reach.
   ------------------------------------------------------------------ */
.hero {
    position: relative;
    background: var(--night);
    color: var(--night-ink);
    padding: calc(64px + var(--s20)) 0 var(--s20);
    overflow: hidden;
    isolation: isolate;
}

/* Two slow-drifting blobs. Their hue comes from the current reach, so the
   whole band warms from cyan to fuchsia as the address travels. */
.hero__aurora {
    position: absolute;
    inset: -30%;
    z-index: -2;
    pointer-events: none;
    background:
        radial-gradient(closest-side circle at 30% 42%, color-mix(in oklab, var(--accent) 60%, transparent), transparent 70%),
        radial-gradient(closest-side circle at 72% 26%, color-mix(in oklab, var(--accent-lit) 34%, transparent), transparent 72%),
        radial-gradient(closest-side circle at 55% 80%, rgba(79, 70, 229, 0.36), transparent 70%);
    filter: blur(30px) saturate(140%);
    opacity: 0.85;
    animation: drift 26s ease-in-out infinite alternate;
    transition: background 1400ms var(--ease);
}

@keyframes drift {
    0%   { transform: translate3d(-3%, -2%, 0) scale(1); }
    50%  { transform: translate3d(4%, 3%, 0) scale(1.08); }
    100% { transform: translate3d(-2%, 4%, 0) scale(1.03); }
}

/* Rings: the device at the centre, each ring one reach further out. The
   ring matching the current reach is the one that is lit and pulsing. */
.hero__rings {
    position: absolute;
    left: 50%; top: 46%;
    width: min(1100px, 130vw);
    aspect-ratio: 1;
    translate: -50% -50%;
    z-index: -1;
    pointer-events: none;
    opacity: 0.55;
}

.hero__rings i {
    position: absolute;
    inset: 0;
    margin: auto;
    border-radius: 50%;
    border: 1px solid var(--night-line);
    transition: border-color 900ms var(--ease), box-shadow 900ms var(--ease);
}

.hero__rings i:nth-child(1) { width: 34%; height: 34%; }
.hero__rings i:nth-child(2) { width: 62%; height: 62%; }
.hero__rings i:nth-child(3) { width: 92%; height: 92%; }

.hero[data-reach="0"] .hero__rings i:nth-child(1),
.hero[data-reach="1"] .hero__rings i:nth-child(2),
.hero[data-reach="2"] .hero__rings i:nth-child(3) {
    border-color: color-mix(in oklab, var(--accent-lit) 70%, transparent);
    box-shadow: 0 0 60px -10px color-mix(in oklab, var(--accent-lit) 55%, transparent);
    animation: ringPulse 2.8s var(--ease) infinite;
}

@keyframes ringPulse {
    0%, 100% { opacity: 0.55; transform: scale(1); }
    50%      { opacity: 1;    transform: scale(1.012); }
}

.hero__field { position: absolute; inset: 0; z-index: -1; pointer-events: none; }

.hero__field i {
    position: absolute;
    width: 2px; height: 2px;
    border-radius: 50%;
    background: rgba(239, 241, 251, 0.5);
    animation: blink 4s ease-in-out infinite;
}

@keyframes blink {
    0%, 100% { opacity: 0.12; }
    50%      { opacity: 0.95; }
}

.hero__inner {
    max-width: 940px;
    margin: 0 auto;
    padding: 0 var(--s6);
    text-align: center;
    position: relative;
}

.hero h1 {
    font-size: clamp(2.8rem, 7.4vw, 5.1rem);
    font-weight: 800;
    line-height: 0.98;
    letter-spacing: -0.055em;
    color: #fff;
    margin-bottom: var(--s6);
}

/* The whole second line moves, not one accented word: the sentence turns
   at "is the server", so that is the half that gets the ramp. */
.hero h1 span {
    display: block;
    background: linear-gradient(100deg, var(--r0-soft) 0%, var(--r1-soft) 42%, var(--r2-soft) 88%);
    background-size: 220% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: rampSlide 9s ease-in-out infinite alternate;
}

@keyframes rampSlide {
    from { background-position: 0% 50%; }
    to   { background-position: 100% 50%; }
}

.hero__sub {
    font-size: clamp(1.05rem, 2.2vw, 1.22rem);
    color: rgba(239, 241, 251, 0.74);
    max-width: 62ch;
    margin: 0 auto var(--s10);
    line-height: 1.65;
}

.hero__actions {
    display: flex;
    gap: var(--s4);
    justify-content: center;
    flex-wrap: wrap;
    margin-bottom: var(--s10);
}

/* the live address — the hero's thesis, and the thing that moves */
.addressbar {
    display: inline-flex;
    align-items: center;
    gap: var(--s4);
    max-width: 100%;
    padding: var(--s3) var(--s3) var(--s3) var(--s5);
    background: rgba(8, 9, 15, 0.55);
    border: 1px solid color-mix(in oklab, var(--accent-lit) 40%, transparent);
    border-radius: 999px;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    box-shadow: 0 0 40px -12px color-mix(in oklab, var(--accent-lit) 65%, transparent);
    transition: border-color 900ms var(--ease), box-shadow 900ms var(--ease);
}

.pulse {
    position: relative;
    width: 9px; height: 9px;
    border-radius: 50%;
    background: var(--accent-lit);
    flex: none;
    animation: pulse 2.4s var(--ease) infinite;
    transition: background 900ms var(--ease);
}

@keyframes pulse {
    0%   { box-shadow: 0 0 0 0 currentColor; }
    70%  { box-shadow: 0 0 0 11px transparent; }
    100% { box-shadow: 0 0 0 0 transparent; }
}

.addressbar__url {
    font-family: var(--font-mono);
    font-size: 0.92rem;
    color: var(--accent-soft);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: color 900ms var(--ease), opacity 220ms var(--ease);
}

.addressbar__tag {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--night-ink-2);
    padding: var(--s1) var(--s3);
    border: 1px solid var(--night-line);
    border-radius: 999px;
    white-space: nowrap;
    transition: opacity 220ms var(--ease);
}

/* The three reaches as a track you can click — the hero's only control,
   and the thing that tells you the address above is not decorative. */
.reaches {
    display: inline-flex;
    gap: var(--s2);
    margin-top: var(--s5);
    padding: var(--s1);
    border-radius: 999px;
    background: rgba(239, 241, 251, 0.05);
    border: 1px solid var(--night-line);
}

.reaches button {
    appearance: none;
    border: 0;
    cursor: pointer;
    background: transparent;
    color: var(--night-ink-2);
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    padding: var(--s2) var(--s4);
    border-radius: 999px;
    transition: color var(--fast) var(--ease), background var(--fast) var(--ease);
}

.reaches button:hover { color: var(--night-ink); }

.reaches button[aria-selected="true"] {
    color: #fff;
    background: color-mix(in oklab, var(--accent-lit) 34%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--accent-lit) 55%, transparent);
}

.hero__caption {
    margin-top: var(--s5);
    font-size: 0.85rem;
    color: rgba(239, 241, 251, 0.45);
}

/* ─── the device skyline divider ─── */
.skyline { line-height: 0; background: var(--night); }
.skyline svg { width: 100%; height: 110px; display: block; }

/* ─── section headers ─── */
.head {
    max-width: 860px;
    margin: 0 auto var(--s12);
    text-align: center;
}

/* Body copy keeps the measure the heading does not want. */
.head p { max-width: 64ch; margin-inline: auto; }
.head--left p { margin-inline: 0; }

.head--left { text-align: left; margin-left: 0; }

.head h2 {
    font-size: clamp(2rem, 4vw, 2.9rem);
    font-weight: 700;
    line-height: 1.08;
    margin-bottom: var(--s5);
}

.head p {
    color: var(--ink-2);
    font-size: 1.06rem;
    line-height: 1.7;
}

.band--night .head p { color: var(--night-ink-2); }

/* A short ramp rule, drawn under a heading in place of the all-caps
   eyebrow the old sheet used. It says which reach the section is about. */
.rule {
    width: 64px; height: 3px;
    border-radius: 3px;
    margin: 0 auto var(--s6);
    background: linear-gradient(90deg, var(--accent-lit), color-mix(in oklab, var(--accent) 20%, transparent));
    transform: scaleX(0);
    transform-origin: 0 50%;
    transition: transform var(--slow) var(--ease);
}

.head--left .rule { margin-left: 0; }
.reveal.in .rule, .in > .rule { transform: scaleX(1); }

/* ─── cards ─── */
.card {
    position: relative;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    padding: var(--s8);
    overflow: hidden;
    box-shadow: var(--shadow-card);
    transition: transform var(--normal) var(--spring), border-color var(--normal) var(--ease),
                box-shadow var(--normal) var(--ease);
}

/* The spine: inert until hover, and coloured by which reach the card is
   about, so a row of cards reads as a distribution rather than a grid. */
.card::before {
    content: '';
    position: absolute;
    left: 0; top: 0;
    width: 3px; height: 100%;
    background: linear-gradient(180deg, var(--accent-lit), var(--accent));
    transform: scaleY(0);
    transform-origin: 50% 0;
    transition: transform var(--normal) var(--ease);
}

/* A soft wash of the same accent, so the lift has somewhere to come from. */
.card::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(120% 90% at 0% 0%, color-mix(in oklab, var(--accent) 12%, transparent), transparent 60%);
    opacity: 0;
    transition: opacity var(--normal) var(--ease);
}

.card:hover {
    transform: translateY(-4px);
    border-color: color-mix(in oklab, var(--accent) 45%, var(--line));
    box-shadow: 0 18px 40px -22px color-mix(in oklab, var(--accent) 70%, transparent);
}

.card:hover::before { transform: scaleY(1); }
.card:hover::after { opacity: 1; }

.card > * { position: relative; }

.chip {
    width: 44px; height: 44px;
    border-radius: var(--r-md);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: var(--s5);
    background: color-mix(in oklab, var(--accent) calc(var(--tint) * 100%), transparent);
    color: var(--accent);
    transition: transform var(--normal) var(--spring), background var(--normal) var(--ease);
}

.card:hover .chip {
    transform: scale(1.08) rotate(-4deg);
    background: color-mix(in oklab, var(--accent) calc(var(--tint-hi) * 100%), transparent);
}

.chip svg { width: 21px; height: 21px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

.card h3 { font-size: 1.12rem; font-weight: 700; margin-bottom: var(--s2); }

.card p {
    font-size: 0.93rem;
    color: var(--ink-2);
    line-height: 1.65;
}

.card p code {
    background: var(--surface-2);
    padding: 1px 5px;
    border-radius: 4px;
    color: var(--ink);
}

.card p b { color: var(--ink); font-weight: 600; }

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
    gap: var(--s6);
}

em { font-style: normal; font-weight: 600; color: var(--ink); }
.band--night em, .openers em { color: var(--accent-soft); font-weight: 500; }

/* ─── routes ─── */
.routes { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: var(--s6); }

.route {
    position: relative;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    padding: var(--s6) var(--s6) var(--s6) var(--s8);
    box-shadow: var(--shadow-card);
    transition: border-color var(--normal) var(--ease), transform var(--normal) var(--spring),
                box-shadow var(--normal) var(--ease);
}

/* Unlike a card's spine this rail is always lit: the reach is the whole
   point of the row, and a route you have to hover to classify is a route
   that has not been classified. */
.route::before {
    content: '';
    position: absolute;
    left: 0; top: var(--s6); bottom: var(--s6);
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: linear-gradient(180deg, var(--accent-lit), var(--accent));
}

.route:hover {
    transform: translateY(-3px);
    border-color: color-mix(in oklab, var(--accent) 45%, var(--line));
    box-shadow: 0 16px 36px -22px color-mix(in oklab, var(--accent) 70%, transparent);
}

.route__reach {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--accent);
    margin-bottom: var(--s3);
}

.route__reach::before {
    content: '';
    width: 7px; height: 7px;
    border-radius: 50%;
    background: currentColor;
}

.route h3 { font-size: 1.05rem; font-weight: 700; margin-bottom: var(--s2); }
.route p { font-size: 0.9rem; color: var(--ink-2); line-height: 1.6; }
.route p code { font-family: var(--font-mono); font-size: 0.86em; color: var(--ink); }

/* ─── what it is for ───────────────────────────────────────────────────
   Deliberately not cards. The features grid below is cards, and putting
   these in the same container would rank them as more items of the same
   kind; they are the reason the items exist. A rail and a hairline give
   them a different weight without a second visual language.
   ------------------------------------------------------------------- */
.uses { display: flex; flex-direction: column; }

.use {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: var(--s12);
    align-items: start;
    padding: var(--s12) 0 var(--s12) var(--s8);
    border-top: 1px solid var(--line);
    position: relative;
}

.use:first-child { border-top: 0; }

/* The rail carries the reach, and it grows on hover rather than appearing:
   the row is already classified, so there is nothing for a hover to reveal. */
.use::before {
    content: '';
    position: absolute;
    left: 0; top: var(--s12); bottom: var(--s12);
    width: 3px;
    border-radius: 3px;
    background: linear-gradient(180deg, var(--accent-lit), var(--accent));
    transform: scaleY(0.35);
    transform-origin: 50% 0;
    transition: transform var(--slow) var(--ease);
}

.use.in::before, .use:hover::before { transform: scaleY(1); }

.use__where {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--accent);
    margin-bottom: var(--s3);
}

.use__where::before {
    content: '';
    width: 7px; height: 7px;
    border-radius: 50%;
    background: currentColor;
}

.use h3 {
    font-size: clamp(1.4rem, 2.4vw, 1.85rem);
    font-weight: 700;
    line-height: 1.15;
    margin-bottom: var(--s4);
}

.use__lead p {
    color: var(--ink-2);
    font-size: 1.02rem;
    line-height: 1.7;
    max-width: 60ch;
}

.use__lead p + p { margin-top: var(--s4); }

/* The mechanics: what makes the story above true, in the smallest type on
   the row. Marked with the reach colour rather than a bullet, so the list
   belongs to its row rather than to the page. */
.use__how {
    display: flex;
    flex-direction: column;
    gap: var(--s4);
    padding-top: var(--s6);
}

.use__how li {
    position: relative;
    padding-left: var(--s6);
    font-size: 0.92rem;
    line-height: 1.6;
    color: var(--ink-2);
}

.use__how li::before {
    content: '';
    position: absolute;
    left: 0; top: 0.62em;
    width: 10px; height: 2px;
    border-radius: 2px;
    background: var(--accent);
}

.use__how code {
    background: var(--surface-2);
    padding: 1px 5px;
    border-radius: 4px;
    color: var(--ink);
}

.use__how b { color: var(--ink); font-weight: 600; }

/* Anchors so a campaign can link straight to its row, and so a reader
   can see all four people before scrolling past the first. Pills in each
   row's reach colour - the same mark the row's rail carries - rather than
   a second navigation bar. */
.audiences {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s3);
    margin: calc(var(--s12) * -0.5) auto var(--s8);
}

.audiences a {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    padding: var(--s2) var(--s4);
    border-radius: 999px;
    border: 1px solid var(--line);
    background: var(--surface);
    color: var(--ink-2);
    font-size: 0.86rem;
    font-weight: 600;
    text-decoration: none;
    transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}

.audiences a::before {
    content: '';
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--accent);
}

.audiences a:hover, .audiences a:focus-visible {
    color: var(--ink);
    border-color: color-mix(in oklab, var(--accent) 55%, var(--line));
}

.openers code {
    font-family: var(--font-mono, monospace);
    font-size: 0.88em;
    color: var(--night-ink);
}

/* ─── screenshots ──────────────────────────────────────────────────── */
.shots { display: grid; gap: var(--s6); }

.shots__phones {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: var(--s6);
    justify-items: center;
}

/* A real device frame, not a drop shadow pretending to be one: these are
   screenshots off a phone, and the bezel is what says so. */
.phone {
    position: relative;
    width: 100%;
    max-width: 250px;
    border-radius: 34px;
    padding: 9px;
    background: linear-gradient(160deg, #2A2E45, #0B0C14);
    box-shadow: 0 26px 60px -30px rgba(8, 9, 15, 0.9), inset 0 0 0 1px rgba(239, 241, 251, 0.09);
    transition: transform var(--normal) var(--spring), box-shadow var(--normal) var(--ease);
}

.phone:hover {
    transform: translateY(-8px) rotate(-0.6deg);
    box-shadow: 0 40px 70px -34px color-mix(in oklab, var(--accent) 75%, transparent),
                inset 0 0 0 1px rgba(239, 241, 251, 0.14);
}

.phone img {
    display: block;
    width: 100%;
    border-radius: 26px;
    background: var(--night-2);
}

.phone__notch {
    position: absolute;
    top: 15px; left: 50%;
    translate: -50% 0;
    width: 78px; height: 20px;
    border-radius: 999px;
    background: #06070C;
    z-index: 2;
}

.shot__cap {
    display: block;
    margin-top: var(--s3);
    text-align: center;
    font-size: 0.84rem;
    color: var(--ink-3);
}

/* the desktop capture: one wide browser-chrome frame */
.screen {
    border-radius: var(--r-lg);
    overflow: hidden;
    border: 1px solid var(--line);
    background: var(--surface);
    box-shadow: 0 30px 70px -40px rgba(8, 9, 15, 0.8);
    transition: transform var(--normal) var(--spring), box-shadow var(--normal) var(--ease);
}

.screen:hover {
    transform: translateY(-4px);
    box-shadow: 0 40px 80px -40px color-mix(in oklab, var(--r1) 75%, transparent);
}

.screen__bar {
    display: flex;
    align-items: center;
    gap: var(--s2);
    padding: var(--s3) var(--s4);
    background: var(--surface-2);
    border-bottom: 1px solid var(--line);
}

.screen__dot { width: 10px; height: 10px; border-radius: 50%; background: var(--line); }
.screen__dot:nth-child(1) { background: #FF5F57; }
.screen__dot:nth-child(2) { background: #FEBC2E; }
.screen__dot:nth-child(3) { background: #28C840; }

.screen__url {
    margin-left: var(--s3);
    font-family: var(--font-mono);
    font-size: 0.76rem;
    color: var(--ink-3);
}

.screen img { display: block; width: 100%; }

/* ─── openers table ─── */
.table-scroll { overflow-x: auto; }

.openers {
    width: 100%;
    border-collapse: collapse;
    min-width: 620px;
    text-align: left;
}

.openers th {
    font-family: var(--font-body);
    font-size: 0.86rem;
    font-weight: 600;
    color: var(--night-ink-2);
    padding: 0 var(--s6) var(--s4) 0;
    border-bottom: 1px solid var(--night-line-strong);
}

.openers td {
    padding: var(--s5) var(--s6) var(--s5) 0;
    border-bottom: 1px solid var(--night-line);
    vertical-align: top;
    color: var(--night-ink-2);
    font-size: 0.95rem;
    line-height: 1.6;
}

.openers tr:last-child td { border-bottom: none; }

.openers tr { transition: background var(--fast) var(--ease); }
.openers tbody tr:hover { background: rgba(239, 241, 251, 0.04); }

.openers td:first-child {
    color: var(--night-ink);
    font-weight: 600;
    white-space: nowrap;
    width: 1%;
}

/* ─── security ─── */
.security {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: var(--s16);
    align-items: start;
}

.locks { display: flex; flex-direction: column; gap: var(--s5); }

.lock { display: flex; gap: var(--s4); align-items: flex-start; }

.lock__mark {
    flex: none;
    width: 22px; height: 22px;
    margin-top: 2px;
    border-radius: 50%;
    background: color-mix(in oklab, var(--ok) 16%, transparent);
    color: var(--ok);
    display: flex;
    align-items: center;
    justify-content: center;
}

.lock__mark svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }

.lock p { font-size: 0.96rem; color: var(--ink-2); line-height: 1.65; }
.lock b { color: var(--ink); font-weight: 600; }

.switches {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    padding: var(--s6);
    box-shadow: var(--shadow-card);
}

.switches__title {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--ink-2);
    margin-bottom: var(--s5);
}

.switch {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s4);
    padding: var(--s4) 0;
    border-bottom: 1px solid var(--line-soft);
}

.switch:last-child { border-bottom: none; padding-bottom: 0; }
.switch__label { font-size: 0.94rem; font-weight: 500; }
.switch__note { font-size: 0.82rem; color: var(--ink-3); }

/* Throwing one is the page's one piece of user-triggered motion, and it
   shows the thing the section is claiming: nothing is on until you say. */
.toggle {
    flex: none;
    appearance: none;
    border: 1px solid var(--line);
    width: 44px; height: 25px;
    border-radius: 999px;
    background: var(--surface-2);
    position: relative;
    cursor: pointer;
    transition: background var(--normal) var(--ease), border-color var(--normal) var(--ease);
}

.toggle::after {
    content: '';
    position: absolute;
    top: 2px; left: 2px;
    width: 19px; height: 19px;
    border-radius: 50%;
    background: var(--ink-3);
    transition: translate var(--normal) var(--spring), background var(--normal) var(--ease);
}

.toggle[aria-pressed="true"] {
    background: linear-gradient(120deg, var(--accent), var(--accent-lit));
    border-color: transparent;
}

.toggle[aria-pressed="true"]::after { translate: 19px 0; background: #fff; }

.switch--amber .toggle:not([aria-pressed="true"]) { border-color: color-mix(in oklab, var(--amber) 45%, var(--line)); }

/* ─── platforms ─── */
.platforms {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    gap: var(--s5);
}

.platform {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--s2);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    padding: var(--s6) var(--s5) var(--s5);
    box-shadow: var(--shadow-card);
    transition: border-color var(--normal) var(--ease), transform var(--normal) var(--spring),
                box-shadow var(--normal) var(--ease);
}

.platform:hover {
    transform: translateY(-4px);
    border-color: color-mix(in oklab, var(--r1) 45%, var(--line));
    box-shadow: 0 18px 40px -24px color-mix(in oklab, var(--r1) 75%, transparent);
}

.platform--soon { background: transparent; border-style: dashed; box-shadow: none; }

.platform__glyph { display: block; color: var(--ink); margin-bottom: var(--s1); line-height: 0; }
.platform__glyph svg { width: 26px; height: 26px; fill: currentColor; }
.platform--soon .platform__glyph { color: var(--ink-3); }
.platform__name { font-family: var(--font-display); font-weight: 700; font-size: 1.02rem; letter-spacing: -0.03em; }
.platform__meta { font-size: 0.8rem; color: var(--ink-3); }
.platform__spacer { flex: 1; min-height: var(--s4); }

.status {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    font-size: 0.76rem;
    font-weight: 600;
    padding: 3px var(--s3);
    border-radius: 999px;
    margin-bottom: var(--s2);
}

.status--live {
    background: color-mix(in oklab, var(--ok) 16%, transparent);
    color: var(--ok);
}

.status--live::before {
    content: '';
    width: 6px; height: 6px;
    border-radius: 50%;
    background: currentColor;
    animation: pulse 2.4s var(--ease) infinite;
}

.status--soon { border: 1px solid var(--line); color: var(--ink-3); }

/* ─── store buttons ─── */
.stores { display: flex; gap: var(--s4); flex-wrap: wrap; }
.stores--center { justify-content: center; }

.store {
    display: inline-flex;
    align-items: center;
    gap: var(--s3);
    padding: var(--s3) var(--s5);
    border-radius: var(--r-md);
    background: var(--ink);
    color: var(--bg);
    border: 1px solid var(--ink);
    transition: transform var(--fast) var(--spring), opacity var(--fast) var(--ease);
    white-space: nowrap;
}

.store:hover { transform: translateY(-2px); opacity: 0.92; }
.store svg { width: 22px; height: 22px; fill: currentColor; flex: none; }
.store__lines { display: flex; flex-direction: column; line-height: 1.15; text-align: left; }
.store__small { font-size: 0.68rem; opacity: 0.78; }
.store__big { font-family: var(--font-display); font-weight: 700; font-size: 0.98rem; letter-spacing: -0.02em; }

.store--night { background: #fff; color: #08090F; border-color: #fff; }
.platform .store { width: 100%; justify-content: center; }

/* ─── spec panel ─── */
.spec {
    background: var(--night);
    border: 1px solid var(--night-line-strong);
    border-radius: var(--r-lg);
    overflow: hidden;
    position: relative;
}

.spec::before {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(90% 70% at 100% 0%, rgba(192, 38, 211, 0.18), transparent 60%),
                radial-gradient(70% 60% at 0% 100%, rgba(6, 182, 212, 0.14), transparent 60%);
}

.spec > * { position: relative; }

.spec__bar {
    padding: var(--s3) var(--s5);
    border-bottom: 1px solid var(--night-line);
    font-size: 0.86rem;
    font-weight: 600;
    color: var(--night-ink-2);
}

.spec__rows { padding: var(--s3) var(--s5) var(--s5); }

.spec__row {
    display: flex;
    gap: var(--s5);
    padding: var(--s3) 0;
    border-bottom: 1px solid var(--night-line);
    font-size: 0.9rem;
}

.spec__row:last-child { border-bottom: none; }

.spec__k {
    font-family: var(--font-mono);
    font-size: 0.78rem;
    color: var(--r0-soft);
    width: 96px;
    flex: none;
    padding-top: 2px;
}

.spec__v { color: var(--night-ink-2); line-height: 1.6; }
.spec__v b { color: var(--night-ink); font-weight: 600; }

.build {
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: var(--s12);
    align-items: center;
}

/* ─── closer ─── */
.closer {
    background: var(--night);
    border-radius: var(--r-xl);
    padding: var(--s20) var(--s8);
    text-align: center;
    color: var(--night-ink);
    position: relative;
    overflow: hidden;
    isolation: isolate;
}

.closer::before {
    content: '';
    position: absolute;
    inset: -40%;
    z-index: -1;
    background:
        radial-gradient(closest-side circle at 26% 40%, rgba(6, 182, 212, 0.5), transparent 70%),
        radial-gradient(closest-side circle at 60% 70%, rgba(79, 70, 229, 0.55), transparent 70%),
        radial-gradient(closest-side circle at 78% 30%, rgba(192, 38, 211, 0.45), transparent 70%);
    filter: blur(40px) saturate(150%);
    animation: drift 22s ease-in-out infinite alternate;
}

.closer > * { position: relative; }

.closer h2 {
    font-size: clamp(2rem, 4.2vw, 3rem);
    font-weight: 800;
    letter-spacing: -0.05em;
    color: #fff;
    margin-bottom: var(--s4);
}

.closer p {
    color: rgba(239, 241, 251, 0.76);
    max-width: 56ch;
    margin: 0 auto var(--s8);
}

/* ─── footer ─── */
.footer {
    background: var(--surface);
    border-top: 1px solid var(--line);
    padding: var(--s12) 0 var(--s8);
}

.footer__inner {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--s10);
}

.footer__cols { display: flex; gap: var(--s16); flex-wrap: wrap; }

.footer__col h4 {
    font-family: var(--font-body);
    font-size: 0.86rem;
    font-weight: 600;
    color: var(--ink);
    margin-bottom: var(--s4);
}

.footer__col ul { display: flex; flex-direction: column; gap: var(--s2); }
.footer__col a { font-size: 0.9rem; color: var(--ink-2); transition: color var(--fast) var(--ease); }
.footer__col a:hover { color: var(--r1); }

.footer__blurb {
    max-width: 34ch;
    font-size: 0.88rem;
    color: var(--ink-3);
    margin-top: var(--s4);
    line-height: 1.6;
}

.footer__bottom {
    margin-top: var(--s10);
    padding-top: var(--s6);
    border-top: 1px solid var(--line-soft);
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--s4);
    font-size: 0.84rem;
    color: var(--ink-3);
}

/* A legend, not a slogan: the footer is where the ramp gets named. */
.legend { display: inline-flex; align-items: center; gap: var(--s4); flex-wrap: wrap; }
.legend span { display: inline-flex; align-items: center; gap: var(--s2); }
.legend i { width: 8px; height: 8px; border-radius: 50%; }

/* ─── feedback ───
   A card on the page's own surface rather than a night panel: it sits right after the closer,
   and two dark slabs in a row would read as one. The fields take the themed tokens, so the form
   flips with the rest of the page. */
.feedback {
    max-width: 760px;
    margin: 0 auto;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-card);
    padding: var(--s8);
}

.feedback__form { display: flex; flex-direction: column; gap: var(--s5); }
.feedback__row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s5); }

.field { display: flex; flex-direction: column; gap: var(--s2); }
.field__label { font-size: 0.85rem; font-weight: 600; color: var(--ink-2); }

.field input,
.field textarea {
    width: 100%;
    font: inherit;
    font-size: 0.98rem;
    color: var(--ink);
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    padding: var(--s3) var(--s4);
    transition: border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}

.field textarea { resize: vertical; min-height: 9rem; }
.field input::placeholder, .field textarea::placeholder { color: var(--ink-3); }

.field input:focus,
.field textarea:focus {
    outline: none;
    border-color: var(--r1);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--r1) 22%, transparent);
}

.feedback__actions { display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap; }
.feedback__actions .btn:disabled { opacity: 0.6; cursor: default; transform: none; }

.feedback__status { font-size: 0.92rem; color: var(--ink-2); }
.feedback__status.is-error { color: var(--r2); }

.feedback__thanks { text-align: center; padding: var(--s8) 0; }
.feedback__thanks .lock__mark { width: 44px; height: 44px; margin: 0 auto var(--s4); }
.feedback__thanks .lock__mark svg { width: 22px; height: 22px; }
.feedback__thanks h3 { font-size: 1.4rem; margin-bottom: var(--s2); }
.feedback__thanks p { color: var(--ink-2); }

@media (max-width: 760px) {
    .feedback { padding: var(--s6); }
    .feedback__row { grid-template-columns: 1fr; }
}

/* ─── reveal ─── */
.reveal {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity var(--slow) var(--ease), transform var(--slow) var(--ease);
}
.reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
    .reveal { opacity: 1; transform: none; transition: none; }
    .rule { transform: scaleX(1); transition: none; }
    .hero__field i, .pulse, .hero__aurora, .closer::before, .hero__rings i, .hero h1 span,
    .status--live::before { animation: none; }
    * { scroll-behavior: auto !important; }
}

html { scroll-behavior: smooth; scroll-padding-top: 80px; }

/* ─── responsive ─── */
@media (max-width: 900px) {
    .security, .build { grid-template-columns: 1fr; gap: var(--s10); }
    .use { grid-template-columns: 1fr; gap: var(--s6); padding-left: var(--s6); }
    .use__how { padding-top: 0; }
    .footer__cols { gap: var(--s10); }
}

@media (max-width: 760px) {
    .band { padding: var(--s16) 0; }
    .nav__links {
        display: none;
        position: absolute;
        top: 64px; left: 0; right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        background: var(--nav-bg);
        backdrop-filter: blur(20px);
        -webkit-backdrop-filter: blur(20px);
        border-bottom: 1px solid var(--line);
        padding: var(--s3) var(--s6) var(--s5);
    }
    .nav__links.open { display: flex; }
    .nav__links li { padding: var(--s3) 0; }
    .nav__links a:not(.nav__gh)::after { display: none; }
    .nav__burger { display: flex; }
    .addressbar { flex-wrap: wrap; border-radius: var(--r-lg); justify-content: center; }
    .reaches { flex-wrap: wrap; justify-content: center; }
    .skyline svg { height: 70px; }
    .hero__rings { opacity: 0.4; }
}
