/* ============================================================
   Duelight — the room
   ------------------------------------------------------------
   The same drawing set as the board, printed on the app's own
   stock. Structure, lettering, the mono dimensions and the title
   block all carry over from css/board.css; the material does not.
   Here it is iOS 26 Liquid Glass: a lit field, plates that bend
   what is behind them, a specular rim, corners at 14 and 20, and
   every motion a spring at 0.3 / 0.7 — the app's own tokens.

   The interface shown on this page is authored, not photographed.
   Every capability it demonstrates is real; the tasks in it are
   made up, because someone's coursework is not ours to publish.
   ============================================================ */

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

:root {
    --bg:        #06091a;
    --bg-2:      #0a1030;
    --blue:      #2f6dff;
    --purple:    #8b46f0;
    --cyan:      #22cffa;
    --green:     #30d158;
    --orange:    #ff9f0a;

    /* Ratios are the WORST composite, not the ratio against --bg. The field
       below is fixed, so every one of these scrolls through its blue and
       purple lobes and, on a glass plate, through the plate's own lift too.
       Measuring against the base colour alone is how a token ends up
       documented at 5.3:1 while rendering at 3.5:1. */
    --ink:    #f3f5fc;                     /*  8.7:1 at worst */
    --ink-2:  rgba(230, 236, 255, 0.82);   /*  6.0:1 at worst */
    --ink-3:  rgba(228, 234, 255, 0.70);   /*  4.8:1 at worst — smallest allowed */
    --hair:   rgba(255, 255, 255, 0.13);
    --hair-2: rgba(255, 255, 255, 0.07);

    /* Liquid Glass, as three separate things rather than one blur. */
    --glass:      rgba(255, 255, 255, 0.075);
    --glass-lift: rgba(255, 255, 255, 0.12);
    --rim:        rgba(255, 255, 255, 0.22);
    --rim-top:    rgba(255, 255, 255, 0.5);

    --r-s: 10px;   /* the app's radiusS  */
    --r-m: 14px;   /* radiusM */
    --r-l: 20px;   /* radiusXL */
    --r-c: 999px;  /* radiusCircle */

    --rail:   50px;
    --gutter: clamp(20px, 4.6vw, 76px);
    --sheet:  1200px;

    --sans: 'Archivo', ui-sans-serif, system-ui, -apple-system, sans-serif;
    --mono: 'Fragment Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

    /* spring(response: 0.3, dampingFraction: 0.7). A spring at 0.7 damping
       overshoots by about 5%, not by a third — the curve is fitted to that
       number rather than to how a bounce feels to write. */
    --spring: cubic-bezier(0.34, 1.06, 0.4, 1);
    --ease:   cubic-bezier(0.16, 1, 0.3, 1);

    /* The press. Short enough to read as contact rather than as motion:
       the app highlights a control the instant a finger lands on it, and
       anything slower than this reads as the page thinking about it. */
    --press: 90ms;
}

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: calc(var(--rail) + 24px); }

body {
    font-family: var(--sans);
    background: var(--bg);
    color: var(--ink);
    /* 17px at the browser's default, stated relatively so a reader who has
       raised their base text size is honoured rather than overridden. */
    font-size: 1.0625rem;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: hidden;
}

/* The light the glass has to bend. Fixed, so plates keep refracting
   something as the page moves under them. */
.field {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(58% 46% at 14% 0%, rgba(47, 109, 255, 0.42) 0%, transparent 62%),
        radial-gradient(52% 44% at 92% 22%, rgba(139, 70, 240, 0.36) 0%, transparent 64%),
        radial-gradient(64% 40% at 50% 104%, rgba(34, 207, 250, 0.2) 0%, transparent 66%),
        linear-gradient(178deg, #0a1136 0%, #06091a 54%, #070a1e 100%);
}

a { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }

:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; border-radius: 3px; }
::selection { background: rgba(47, 109, 255, 0.5); }

/* ── Type ──────────────────────────────────────────────────── */

h1, h2, h3 { font-weight: 600; letter-spacing: -0.028em; line-height: 1.06; text-wrap: balance; }

.t-note {
    font-family: var(--mono);
    font-size: 0.688rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.t-dim {
    font-family: var(--mono);
    font-size: 0.75rem;
    color: var(--ink-3);
    font-variant-numeric: tabular-nums;
}

.lede { font-size: clamp(1.04rem, 1.4vw, 1.2rem); color: var(--ink-2); line-height: 1.6; max-width: 46ch; }
.body { color: var(--ink-2); line-height: 1.65; max-width: 60ch; }

/* ── Rail ──────────────────────────────────────────────────── */

/* The board's sheet header, in glass. Same information, same
   position; the material is the only thing that changed. */
.rail {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 90;
    height: var(--rail);
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 0 var(--gutter);
    background: rgba(8, 12, 34, 0.6);
    -webkit-backdrop-filter: blur(18px) saturate(180%);
    backdrop-filter: blur(18px) saturate(180%);
}

/* A scroll edge rather than a rule. Glass separates itself from what is
   behind it by bending light, not by drawing a line — so the only thing
   the page adds is a short shadow, and only once there is content under
   the rail for it to be a shadow on. */
.rail::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    height: 14px;
    pointer-events: none;
    opacity: 0;
    background: linear-gradient(to bottom, rgba(0, 0, 0, 0.32), rgba(0, 0, 0, 0));
    transition: opacity 0.28s var(--ease);
}

.scrolled .rail::after { opacity: 1; }

.rail-mark {
    font-variation-settings: 'wdth' 78;
    font-weight: 700;
    font-size: 1.06rem;
    letter-spacing: 0.02em;
    padding-right: 18px;
    border-right: 1px solid var(--hair);
    align-self: stretch;
    display: flex;
    align-items: center;
    gap: 0.5em;
    color: var(--ink-2);
    transition: color 0.2s;
}
.rail-mark:hover { color: var(--ink); }

/* The studio's mark, inheriting this room's ink rather than carrying its own
   colour — one drawing, three materials. See board.css for why it is set
   larger than the wordmark's cap height. */
.rail-glyph {
    flex: none;
    height: 0.90em;
    width: auto;
    fill: currentColor;
}

.rail-here {
    font-family: var(--mono);
    font-size: 0.688rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink);
    margin-right: auto;
    display: flex;
    align-items: center;
    gap: 8px;
}
.rail-here::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--blue), var(--purple));
}

.rail-get {
    display: inline-flex;
    align-items: center;
    min-height: 30px;
    padding: 5px 14px;
    font-size: 0.781rem;
    font-weight: 600;
    border-radius: var(--r-c);
    color: #fff;
    background: linear-gradient(135deg, var(--blue), var(--purple));
    box-shadow: 0 3px 10px -3px rgba(47, 109, 255, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.26);
    transition: transform 0.3s var(--spring), box-shadow 0.3s var(--ease);
}
/* On the legal sheets this pill is a way back, not a download, so it
   drops the brand fill and stays a link. */
.rail-get--quiet {
    background: none;
    color: var(--ink-2);
    box-shadow: inset 0 0 0 1px var(--hair);
}
.rail-get--quiet:hover { color: var(--ink); box-shadow: inset 0 0 0 1px rgba(255,255,255,0.3); background: rgba(255,255,255,0.05); }

.rail-get:hover { transform: scale(1.04); box-shadow: 0 8px 22px -6px rgba(88, 90, 255, 0.85), inset 0 1px 0 rgba(255, 255, 255, 0.34); }

/* The press.
   ------------------------------------------------------------------
   This page is read on a phone, where there is no hover at all — until
   now the whole download path gave a reader nothing between touching a
   control and the App Store opening. iOS scales a control down under a
   finger and pulls its shadow in, because the control is being pushed
   into the glass rather than lifted off it. That is what these do.

   Placed after the hovers at equal specificity so a pressed control
   stops growing and starts giving. */
.rail-get:active {
    transform: scale(0.96);
    box-shadow: 0 2px 8px -4px rgba(47, 109, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.2);
    transition-duration: var(--press);
}

.rail-get--quiet:active { background: rgba(255, 255, 255, 0.1); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.34); }

.rail-mark:active { color: var(--ink); transition-duration: var(--press); }

/* Apple's badge artwork may not be modified, but the link around it is
   ours — so the press lands on the box, not on the mark. */
.hero-actions a:active,
.get-actions a:active {
    transform: scale(0.97);
    transition: transform var(--press) var(--ease);
}

.hero-badge:active,
.legal a:active,
.block-cell dd a:active,
.back-live:active,
.doc-back:active { color: var(--ink); transition-duration: var(--press); }

/* ── Sheets ────────────────────────────────────────────────── */

.sheet { padding: clamp(76px, 9vw, 136px) var(--gutter); position: relative; }
.sheet-inner { max-width: var(--sheet); margin: 0 auto; }
.sheet + .sheet { border-top: 1px solid var(--hair-2); }

.sheet-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 24px;
    padding-bottom: 18px;
    border-bottom: 1px solid var(--hair);
    margin-bottom: clamp(34px, 4.4vw, 56px);
}

.sheet-head h2 {
    font-size: clamp(1.7rem, 3.2vw, 2.6rem);
    font-variation-settings: 'wdth' 88;
}

/* ── Hero ──────────────────────────────────────────────────── */

.hero {
    padding-top: calc(var(--rail) + clamp(48px, 8vh, 96px));
    padding-bottom: clamp(56px, 7vw, 100px);
}

.hero-grid {
    max-width: var(--sheet);
    margin: 0 auto;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: clamp(36px, 5vw, 82px);
    align-items: center;
}

.hero-icon {
    width: 76px;
    height: 76px;
    border-radius: 18px;
    margin-bottom: 26px;
    box-shadow: 0 16px 40px -12px rgba(47, 109, 255, 0.66), 0 0 0 1px rgba(255, 255, 255, 0.1);
}

.hero h1 {
    font-size: clamp(2.4rem, 5vw, 4.1rem);
    font-variation-settings: 'wdth' 84;
    margin-bottom: 20px;
}

/* The brand gradient carries fields and controls — the toolbar, the
   selected pill, the icon glow — the way it does in the app. Apple sets
   its own headlines solid, so this one is solid too. */

.hero .lede { margin-bottom: 30px; }

.hero-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 14px 22px; }
.hero-actions img { height: 50px; width: auto; }

.hero-badge {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    min-height: 44px;
    font-size: 0.906rem;
    color: var(--ink-2);
    transition: color 0.2s;
}
.hero-badge:hover { color: var(--ink); }
.hero-badge svg { width: 17px; height: 17px; flex: none; }

.hero-specs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 26px;
    margin-top: 32px;
    padding-top: 20px;
    border-top: 1px solid var(--hair-2);
}

/* ── The phone ─────────────────────────────────────────────── */

/* Authored, not photographed. Internals are sized in container
   units so the whole interface scales as one object instead of
   drifting apart at each breakpoint. */
.phone {
    width: clamp(248px, 25vw, 318px);
    aspect-ratio: 402 / 874;
    position: relative;
    border-radius: 13.5%/6.2%;
    padding: 1.6%;
    background: linear-gradient(150deg, #3d4358 0%, #14161f 42%, #2c3040 100%);
    box-shadow:
        0 50px 90px -30px rgba(0, 0, 0, 0.8),
        0 0 0 1px rgba(255, 255, 255, 0.11),
        inset 0 0 0 1px rgba(255, 255, 255, 0.07);
}

.screen {
    container-type: inline-size;
    position: relative;
    width: 100%;
    height: 100%;
    border-radius: 12.4%/5.7%;
    overflow: hidden;
    background:
        radial-gradient(72% 42% at 8% 0%, rgba(47, 109, 255, 0.44), transparent 64%),
        radial-gradient(64% 40% at 100% 88%, rgba(139, 70, 240, 0.4), transparent 66%),
        linear-gradient(172deg, #0c1130 0%, #080b1e 60%, #0a0d24 100%);
    display: flex;
    flex-direction: column;
    font-size: 4cqw;
}

.status {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 3.6cqw 6cqw 1cqw;
    font-size: 3.4cqw;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.status-icons { display: flex; align-items: center; gap: 1.4cqw; }
.status-icons i { display: block; background: #fff; border-radius: 0.6cqw; }
.status-icons .s1 { width: 4.2cqw; height: 2.6cqw; }
.status-icons .s2 { width: 4cqw; height: 2.6cqw; border-radius: 50% 50% 0 0; }
.status-icons .s3 { width: 6.2cqw; height: 2.8cqw; border-radius: 0.8cqw; }

.island {
    position: absolute;
    top: 2.4cqw;
    left: 50%;
    transform: translateX(-50%);
    width: 26cqw;
    height: 7.4cqw;
    background: #000;
    border-radius: 4cqw;
    z-index: 5;
}

.app-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 3cqw 5cqw 2cqw;
}

.app-title { font-size: 6.4cqw; font-weight: 700; letter-spacing: -0.03em; }

.app-round {
    width: 8.6cqw;
    height: 8.6cqw;
    border-radius: 50%;
    background: var(--glass);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    box-shadow: inset 0 0 0 1px var(--rim);
    display: grid;
    place-items: center;
}
.app-round svg { width: 4.4cqw; height: 4.4cqw; }

/* The filter bar — a glass capsule with a tinted selection, the
   app's PillButton in its two states. */
.filters {
    display: flex;
    margin: 1cqw 4cqw 2cqw;
    padding: 1cqw;
    border-radius: var(--r-c);
    background: var(--glass);
    -webkit-backdrop-filter: blur(10px) saturate(170%);
    backdrop-filter: blur(10px) saturate(170%);
    box-shadow: inset 0 0 0 1px var(--hair-2), inset 0 1px 0 rgba(255, 255, 255, 0.14);
}

.filters span {
    flex: 1;
    text-align: center;
    font-size: 3cqw;
    font-weight: 600;
    padding: 1.8cqw 0.6cqw;
    border-radius: var(--r-c);
    color: var(--ink-3);
    white-space: nowrap;
}

.filters .on {
    color: #fff;
    background: linear-gradient(135deg, var(--blue), var(--purple));
    box-shadow: 0 2px 8px -2px rgba(47, 109, 255, 0.8), inset 0 1px 0 rgba(255, 255, 255, 0.3);
}

.day {
    padding: 3.4cqw 5.4cqw 1.4cqw;
    font-family: var(--mono);
    font-size: 2.7cqw;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.task {
    display: flex;
    align-items: center;
    gap: 2.6cqw;
    margin: 1.2cqw 4cqw;
    padding: 3.4cqw 4cqw;
    border-radius: var(--r-m);
    background: var(--glass);
    -webkit-backdrop-filter: blur(8px) saturate(160%);
    backdrop-filter: blur(8px) saturate(160%);
    box-shadow: inset 0 0 0 1px var(--hair-2), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

/* The app's own row: a 26pt check, a 4x40 priority bar, the title and its
   category line, and the due date as a pill on the trailing edge. */
.task .bar { width: 1.2cqw; min-width: 2px; height: 10cqw; flex: none; border-radius: 1cqw; }
.task .bar.hi { background: var(--orange); }
.task .bar.mid { background: var(--blue); }
.task .bar.low { background: rgba(255,255,255,0.34); }

.task .due {
    flex: none;
    font-size: 2.6cqw;
    color: var(--ink-3);
    padding: 1cqw 2.2cqw;
    border-radius: var(--r-c);
    background: rgba(255, 255, 255, 0.08);
    white-space: nowrap;
}
.task .due.late { color: #ffb37a; background: rgba(255, 159, 10, 0.16); }

.task .box {
    width: 5.6cqw;
    height: 5.6cqw;
    flex: none;
    border-radius: 50%;
    box-shadow: inset 0 0 0 0.55cqw rgba(255, 255, 255, 0.34);
}

.task.done .box { background: var(--green); box-shadow: none; }
.task.done .tt { color: var(--ink-3); text-decoration: line-through; }

.task .tw { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.task .tt { display: block; font-size: 3.4cqw; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 600; letter-spacing: -0.02em; line-height: 1.25; }
.task .tm { font-size: 2.7cqw; color: var(--ink-3); margin-top: 0.8cqw; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.task .dot { width: 1.7cqw; height: 1.7cqw; border-radius: 50%; flex: none; }
.task .dot.hi { background: var(--orange); }
.task .dot.mid { background: var(--blue); }
.task .dot.low { background: rgba(255,255,255,0.34); }

/* The floating toolbar. This is the piece of the app that made
   Liquid Glass worth quoting: it sits over the list and you can
   read the rows bending underneath it. */
.dock {
    position: absolute;
    left: 4cqw;
    right: 4cqw;
    bottom: 3.4cqw;
    display: flex;
    align-items: center;
    gap: 2.4cqw;
    padding: 2.2cqw;
    border-radius: var(--r-c);
    background: rgba(255, 255, 255, 0.09);
    -webkit-backdrop-filter: blur(13px) saturate(190%) brightness(1.18);
    backdrop-filter: blur(13px) saturate(190%) brightness(1.18);
    box-shadow:
        0 6cqw 12cqw -4cqw rgba(0, 0, 0, 0.6),
        inset 0 0 0 1px var(--rim),
        inset 0 1px 0 var(--rim-top);
}

.dock .ask {
    flex: 1;
    min-width: 0;
    font-size: 3.1cqw;
    color: var(--ink-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dock .knob {
    width: 8.4cqw;
    height: 8.4cqw;
    flex: none;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: rgba(255, 255, 255, 0.14);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2);
}
.dock .knob svg { width: 4.2cqw; height: 4.2cqw; }
.dock .knob.brand { background: linear-gradient(135deg, var(--blue), var(--purple)); box-shadow: 0 0.6cqw 2.4cqw -0.6cqw rgba(47, 109, 255, 0.9); }

.home-line {
    position: absolute;
    left: 50%;
    bottom: 1.4cqw;
    transform: translateX(-50%);
    width: 34cqw;
    height: 1cqw;
    border-radius: 1cqw;
    background: rgba(255, 255, 255, 0.4);
}

/* ── Demonstration plates ──────────────────────────────────── */

/* Three, and each is a thing the app does rather than a claim
   about it. Different widths on purpose: a page that alternates
   density reads as composed; four equal tiles read as a grid. */
.proofs { display: grid; gap: clamp(18px, 2.4vw, 30px); }

.plate {
    position: relative;
    border-radius: var(--r-l);
    background: var(--glass);
    -webkit-backdrop-filter: blur(22px) saturate(170%);
    backdrop-filter: blur(22px) saturate(170%);
    box-shadow: inset 0 0 0 1px var(--hair), inset 0 1px 0 rgba(255, 255, 255, 0.16);
    overflow: hidden;
}

.plate-wide { display: grid; grid-template-columns: minmax(0, 0.92fr) minmax(0, 1fr); align-items: center; }
.proofs-pair { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(18px, 2.4vw, 30px); }

.plate-body { padding: clamp(26px, 3vw, 40px); }
.plate-body h3 { font-size: clamp(1.24rem, 1.7vw, 1.55rem); margin-bottom: 12px; }
.plate-body p { color: var(--ink-2); font-size: 0.969rem; line-height: 1.62; }

.plate-art { position: relative; padding: clamp(26px, 3vw, 40px); min-height: 190px; display: flex; align-items: center; justify-content: center; }

/* Body pinned to the foot of the plate, art taking whatever is left and
   centring in it — otherwise the taller sibling in the pair opens a hole
   between the demonstration and the words about it. */
.proofs-pair .plate { display: flex; flex-direction: column; }
.proofs-pair .plate-art { flex: 1; }
.plate-wide .plate-art { border-left: 1px solid var(--hair-2); align-self: stretch; }

/* Assistant transcript */
.chat { width: 100%; max-width: 400px; display: flex; flex-direction: column; gap: 12px; }

.bubble {
    max-width: 84%;
    padding: 13px 17px;
    font-size: 0.906rem;
    line-height: 1.5;
    border-radius: var(--r-l);
}

.bubble.me {
    align-self: flex-end;
    color: #fff;
    background: linear-gradient(135deg, var(--blue), var(--purple));
    border-bottom-right-radius: 6px;
    box-shadow: 0 6px 18px -6px rgba(47, 109, 255, 0.8);
}

.bubble.it {
    align-self: flex-start;
    color: var(--ink);
    background: rgba(255, 255, 255, 0.1);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    box-shadow: inset 0 0 0 1px var(--hair);
    border-bottom-left-radius: 6px;
}

.chat-foot {
    display: flex;
    align-items: center;
    gap: 8px;
    align-self: flex-start;
    margin-top: 2px;
    font-family: var(--mono);
    font-size: 0.688rem;
    letter-spacing: 0.06em;
    color: var(--ink-3);
}
.chat-foot svg { width: 13px; height: 13px; }

/* Screenshot import: a captured image on the left, the task it
   became on the right, one arrow between them. */
.capture { display: flex; align-items: center; gap: 18px; width: 100%; }

.shot {
    flex: 1;
    min-width: 0;
    border-radius: var(--r-m);
    padding: 18px 19px;
    background: rgba(255, 255, 255, 0.94);
    color: #10131f;
    box-shadow: 0 14px 30px -14px rgba(0, 0, 0, 0.7);
    transform: rotate(-1.6deg);
}
.shot-h { font-size: 0.875rem; font-weight: 700; letter-spacing: -0.01em; }
.shot-l { height: 4px; border-radius: 2px; background: rgba(16, 19, 31, 0.16); margin-top: 7px; }
.shot-l.short { width: 56%; }
.shot-due { margin-top: 12px; font-family: var(--mono); font-size: 0.688rem; color: #b0341f; }

.arrow { flex: none; color: var(--ink-3); }
.arrow svg { width: 22px; height: 22px; }

.made {
    flex: 1;
    min-width: 0;
    border-radius: var(--r-m);
    padding: 18px 19px;
    background: rgba(255, 255, 255, 0.1);
    box-shadow: inset 0 0 0 1px var(--hair), inset 0 1px 0 rgba(255, 255, 255, 0.14);
}
.made-h { font-size: 0.938rem; font-weight: 600; letter-spacing: -0.015em; }
.made-m { font-size: 0.75rem; color: var(--ink-3); margin-top: 5px; }
.made-tags { display: flex; gap: 6px; margin-top: 10px; }
.made-tags span {
    font-family: var(--mono);
    font-size: 0.625rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 3px 8px;
    border-radius: var(--r-c);
    background: rgba(255, 255, 255, 0.12);
    color: var(--ink-2);
}

/* Canvas sync */
.sync { display: flex; align-items: center; justify-content: center; gap: 16px; width: 100%; }

.node {
    width: 80px;
    height: 80px;
    flex: none;
    border-radius: var(--r-l);
    display: grid;
    place-items: center;
    background: rgba(255, 255, 255, 0.1);
    box-shadow: inset 0 0 0 1px var(--hair), inset 0 1px 0 rgba(255, 255, 255, 0.16);
}
.node img { width: 44px; height: 44px; border-radius: 12px; }
.node svg { width: 40px; height: 40px; }

.wire { flex: 1; height: 24px; position: relative; min-width: 40px; }
.wire svg { position: absolute; inset: 0; width: 100%; height: 100%; }

.sync-note { text-align: center; margin-top: 18px; }

/* ── Capability list ───────────────────────────────────────── */

/* Not cards. A list of what is in the app, with the icons drawn in
   one stroke weight, because that is what the app's own settings
   screen looks like and it is denser to read. */
.caps { display: grid; grid-template-columns: 1fr 1fr; gap: 0 clamp(30px, 4vw, 64px); }

.cap {
    display: flex;
    gap: 16px;
    padding: 20px 0;
    border-bottom: 1px solid var(--hair-2);
}

.cap-ico {
    width: 34px;
    height: 34px;
    flex: none;
    border-radius: var(--r-s);
    display: grid;
    place-items: center;
    background: rgba(255, 255, 255, 0.08);
    box-shadow: inset 0 0 0 1px var(--hair-2);
    color: var(--cyan);
}
.cap-ico svg { width: 19px; height: 19px; }

.cap .cap-h { font-size: 1rem; font-weight: 600; letter-spacing: -0.02em; margin-bottom: 5px; }
.cap p { font-size: 0.906rem; color: var(--ink-2); line-height: 1.55; }

/* ── Privacy ───────────────────────────────────────────────── */

/* Two equal columns of the same thing, which is what makes the comparison
   read. It was a paragraph beside a table before, and prose can never balance
   a data column: one has a top edge and the other does not. */
.privacy {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(28px, 4vw, 60px);
    align-items: start;
    max-width: 940px;
    margin: 0 auto;
}

.ledger { width: 100%; border-collapse: collapse; }
.ledger caption {
    text-align: left;
    font-size: 1.06rem;
    font-weight: 600;
    letter-spacing: -0.015em;
    color: var(--ink);
    padding-bottom: 14px;
    border-bottom: 1px solid var(--hair);
}
.ledger td { padding: 13px 0; border-top: 1px solid var(--hair-2); font-size: 0.938rem; }
.ledger tr:last-child td { border-bottom: 1px solid var(--hair-2); }
.ledger td:first-child { color: var(--ink-2); }
.ledger td:last-child {
    text-align: right;
    font-family: var(--mono);
    font-size: 0.75rem;
    color: var(--ink-3);
    white-space: nowrap;
    padding-left: 16px;
}
.ledger .out td:last-child { color: #ff8a7a; }
.ledger .in td:last-child { color: var(--ink-3); }

.ledger .grp th {
    text-align: left;
    font-size: 0.813rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--ink);
    padding: 24px 0 6px;
    border-top: none;
}
.ledger tbody:first-of-type .grp th { padding-top: 0; }
.ledger .grp + tr td { border-top: 1px solid var(--hair); }

/* ── Get it ────────────────────────────────────────────────── */

.get { text-align: center; }
.get h2 { font-size: clamp(2rem, 4vw, 3.2rem); font-variation-settings: 'wdth' 84; margin-bottom: 18px; }
.get .lede { margin: 0 auto 34px; }
.get-actions { display: flex; flex-direction: column; align-items: center; gap: 18px; }
.get-actions img { height: 54px; width: auto; }

.legal { display: flex; gap: 8px 26px; justify-content: center; flex-wrap: wrap; margin-top: 34px; }
.legal a { font-size: 0.875rem; color: var(--ink-3); transition: color 0.2s; min-height: 44px; display: inline-flex; align-items: center; }
.legal a:hover { color: var(--ink); }

/* ── Title block ───────────────────────────────────────────── */

.block { border-top: 1px solid var(--hair); background: rgba(4, 6, 18, 0.5); }
.block-inner { max-width: var(--sheet); margin: 0 auto; padding: clamp(40px, 5vw, 64px) var(--gutter) 0; }
.block-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr; border-left: 1px solid var(--hair-2); border-top: 1px solid var(--hair-2); }

.block-cell { padding: 22px 20px 26px; border-right: 1px solid var(--hair-2); border-bottom: 1px solid var(--hair-2); min-height: 128px; }
.block-cell dt { font-family: var(--mono); font-size: 0.625rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 12px; }
.block-cell dd { font-size: 0.938rem; line-height: 1.75; color: var(--ink-2); }
/* Inline-block with real vertical padding: a 16px link box is under the
   minimum target size however comfortable the line-height around it looks. */
.block-cell dd a { display: inline-block; padding: 4px 0; transition: color 0.2s; }
.block-cell dd a:hover { color: var(--ink); }

.block-title { font-variation-settings: 'wdth' 78; font-weight: 700; font-size: clamp(1.7rem, 3vw, 2.3rem); letter-spacing: -0.02em; line-height: 1; margin-bottom: 10px; color: var(--ink); }
.block-foot { display: flex; flex-wrap: wrap; gap: 8px 22px; justify-content: space-between; padding: 16px 0 26px; }

/* ── Reveal ────────────────────────────────────────────────── */

/* Promoted only while the rise is still owed — a will-change carried for
   the life of the page is a memory bill, not an optimisation. */
.js .up { opacity: 0; transform: translateY(16px); transition: opacity 0.85s var(--ease), transform 0.85s var(--ease); will-change: opacity, transform; }
.up.seen { opacity: 1; transform: none; will-change: auto; }
.up.d1 { transition-delay: 0.09s; }
.up.d2 { transition-delay: 0.18s; }
.up.d3 { transition-delay: 0.27s; }

/* ── Adaptation ────────────────────────────────────────────── */

@media (max-width: 1020px) {
    .hero-grid { grid-template-columns: 1fr; justify-items: start; }
    .phone { width: min(300px, 76vw); margin: 8px auto 0; }
    .plate-wide { grid-template-columns: 1fr; }
    .plate-wide .plate-art { border-left: none; border-top: 1px solid var(--hair-2); }
    .proofs-pair { grid-template-columns: 1fr; }
    .caps { grid-template-columns: 1fr; }
    .privacy { grid-template-columns: 1fr; }
    .block-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 620px) {
    body { font-size: 1rem; }
    .rail-here { display: none; }
    .rail-mark { margin-right: auto; padding-right: 0; border-right: none; }
    .block-grid { grid-template-columns: 1fr; }
    .block-cell { min-height: 0; }
    .capture { flex-direction: column; align-items: stretch; }
    .arrow { align-self: center; transform: rotate(90deg); }
    .hero-actions img { height: 46px; }
}

/* Reduced motion is a gentler equivalent, not silence. Movement is what
   goes: the transition list is narrowed to properties that do not travel,
   so transforms apply instantly while the colour and opacity changes that
   tell a reader something answered them still cross-fade. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-property: opacity, color, background-color, border-color, box-shadow, outline-color !important;
        transition-duration: 0.18s !important;
    }
    .js .up { opacity: 1; transform: none; }
    /* The press still registers — as tint and shadow rather than travel. */
    .rail-get:active { transform: none; background: linear-gradient(135deg, #2559d8, #7439cc); }
    .hero-actions a:active, .get-actions a:active { transform: none; opacity: 0.72; }
}

/* Frostier, not transparent.
   ------------------------------------------------------------------
   Every surface the reader actually operates or reads through loses its
   blur and gains a near-solid ground. The phone is deliberately left
   alone: it is a picture of another device's screen rather than a
   surface on this page, and flattening it would misrepresent the very
   material the page exists to show. */
@media (prefers-reduced-transparency: reduce) {
    .rail {
        background: #070b20;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }
    .plate, .summary {
        background: rgba(18, 24, 58, 0.96);
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }
    .bubble.it {
        background: rgba(30, 38, 78, 0.97);
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }
    .made, .node, .cap-ico { background: rgba(28, 35, 74, 0.95); }
}

/* Near-solid grounds and a defined edge. The hairlines here run at
   0.055–0.13 alpha, which is a deliberate whisper and exactly what this
   setting asks to hear said plainly. */
@media (prefers-contrast: more) {
    :root {
        --ink-2: #ffffff;
        --ink-3: rgba(255, 255, 255, 0.88);
        --hair:  rgba(255, 255, 255, 0.5);
        --hair-2: rgba(255, 255, 255, 0.32);
    }
    .rail {
        background: #05081a;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        border-bottom: 1px solid var(--hair);
    }
    .plate, .summary {
        background: #0b1130;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        box-shadow: inset 0 0 0 2px var(--hair);
    }
    .cap { border-bottom-color: var(--hair); }
    :focus-visible { outline-width: 3px; }
}

/* The way back out of the preview. */
.back-live { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink-2); transition: color 0.2s; }
.back-live:hover { color: var(--ink); }
