/* ═══════════════════════════════════════════
   BRIDGE · HOME — everything below the hero, on the platform ramp

   The homepage was the last surface still speaking the legacy dialect:
   mono set as body copy, a display ramp that topped out where the
   platform's begins, chips and stats on their own tokens. The memos,
   the artifacts sheet and the 404 already speak platform. This closes
   the gap.

   Override-only and additive: no markup moves, no content changes. It
   loads after the legacy sheets and restates the same surfaces in
   platform terms — hardening, not redesign.
   ═══════════════════════════════════════════ */

/* ── The thesis ────────────────────────────
   The first words after the mark. They were set two steps below the
   platform's display ramp, which made the hero's silence read as the
   loudest thing on the page and the argument as a caption under it. */
.thesis-section {
    padding-block: var(--band) var(--space-2xl);
    padding-inline: var(--safe-inline);
}

.thesis-section .hero-copy {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-lg);
    text-align: center;
}

.thesis-section .hero-title {
    font-family: var(--font-display);
    font-size: var(--display-2);
    font-weight: var(--weight-display);
    line-height: var(--leading-display);
    letter-spacing: var(--tracking-display);
    color: var(--text-primary);
    max-width: 20ch;
    /* The claim breaks on its own sense, not on the viewport's. */
    text-wrap: balance;
    margin: 0;
}

.thesis-section .hero-subhead {
    /* Was set in mono by the legacy sheet. The role is a sentence about
       a person, not a readout. */
    font-family: var(--font-ui);
    font-size: var(--text-lg);
    line-height: var(--leading-snug);
    color: var(--text-secondary);
    max-width: var(--measure-narrow);
    margin: 0;
}

/* The credential line is a LABEL, not a sentence — same voice as every
   other label on the platform, so it reads as a stamp under the claim. */
.thesis-section .hero-microcopy {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-muted);
    margin: 0;
}

/* ── Case studies ──────────────────────────
   Two bets, stated once each. The card is a frame around an argument,
   so it earns exactly one border and one hover move. */
/* Four memos: a 2x2 on a desk, one column on a phone. Three-up left an
   orphan row the moment the fourth case landed, and two-up also buys
   back a real reading measure inside each card. */
.case-studies-grid--three {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
}
@media (max-width: 760px) {
    .case-studies-grid--three { grid-template-columns: 1fr; }
}

.case-studies-grid {
    max-width: 1100px;
    margin-inline: auto;
    padding-inline: var(--safe-inline);
    /* One band between movements, not two: the grid's bottom band and
       the next section's top band would otherwise stack into a gap the
       reader mistakes for the end of the page. */
    padding-block: var(--space-2xl);
    gap: var(--space-xl);
    align-items: stretch;
}

.case-card {
    display: flex;
    flex-direction: column;
    /* Grid items default to min-width auto: one wide tracked chip was
       setting the card's min-content past a phone's viewport and the
       whole page grew a horizontal scrollbar. */
    min-width: 0;
    /* Anchor for the stretched case-link — the whole card navigates. */
    position: relative;
    gap: var(--space-lg);
    padding: var(--space-xl);
    background: transparent;
    border: 1px solid var(--line);
    border-radius: var(--radius-base);
    transition: var(--transition-color);
}

/* Hover LIFTS the frame toward the reader. The legacy card faded to 70%
   opacity on hover, which reads as "disabled", the one thing an
   invitation must never read as. */
.case-card:hover,
.case-card:focus-visible,
.case-card:focus-within {
    opacity: 1;
    border-color: var(--accent);
    /* A whisper of the hour's accent as ground — the palette made
       legible at the moment of attention. */
    background: color-mix(in srgb, var(--accent) 4%, transparent);
    transform: none;
    box-shadow: none;
}
.case-card:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 3px;
}

/* The card names itself.
   The decorative ASCII that used to sit here was doing a heading's job:
   the case was named only inside the artwork, so a screen reader and a
   crawler both met an anonymous card. A numbered, named case is better
   structure AND better expression — the memos are numbered documents,
   so the cards that open them should read as documents too. */
.case-meta {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-md);
    padding-bottom: var(--space-md);
    border-bottom: 1px solid var(--line);
}

/* The ledger numeral: architecture, not a chip. The system built
   --display-2 and the homepage never spent it — this is where it goes.
   Ghost-inked in the hour's accent so the number frames the title
   instead of shouting over it. */
.case-index {
    font-family: var(--font-display);
    font-size: var(--display-2);
    font-weight: var(--weight-display);
    line-height: 0.8;
    letter-spacing: var(--tracking-display);
    color: color-mix(in srgb, var(--accent) 38%, transparent);
    font-variant-numeric: tabular-nums;
}

/* The one card that is live work gets the accent, full strength. */
.case-now { font-style: normal; color: var(--accent); }

.case-kind {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-muted);
}

.case-title {
    font-family: var(--font-display);
    font-size: var(--text-4xl);
    font-weight: var(--weight-display);
    line-height: var(--leading-display);
    letter-spacing: var(--tracking-display);
    color: var(--text-primary);
    margin: 0;
}

/* The bet itself. Mono is the platform's label voice; body copy set in
   it is the tell of a portfolio that wants to look technical rather
   than be read. This is the sentence the page exists to deliver. */
.case-sentence {
    font-family: var(--font-ui);
    font-size: var(--text-base);
    line-height: var(--leading-body);
    color: var(--text-secondary);
    max-width: var(--measure);
    margin: 0;
}

.card-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
}

.case-card .proof-chip {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-muted);
    background: transparent;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    padding: var(--space-xs) var(--space-md);
}

.case-card .case-link {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--accent);
    margin-top: auto;
    text-decoration: none;
}
.case-card .case-link:hover { text-decoration: underline; text-underline-offset: 4px; }

/* The card promised a pointer and delivered nothing: cursor:pointer with
   a 20px link is an affordance lie. The link stretches over the frame —
   one tab stop, one click target, the whole card. */
.case-card .case-link::after {
    content: '';
    position: absolute;
    inset: 0;
}

/* The chips are credentials, not controls: strip the button costume
   (pill border + padding) that begged for a tap they can't answer. */
.case-card .proof-chip {
    border: none;
    border-radius: 0;
    padding: 0;
}
.case-card .card-chips {
    gap: var(--space-md);
    row-gap: var(--space-xs);
}

/* ── Section heads ─────────────────────────
   One treatment for every section title on the platform. */
.snake-section { padding-block: var(--band); padding-inline: var(--safe-inline); }

.snake-section .section-head {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-md);
    text-align: center;
    margin-bottom: var(--space-2xl);
}

.snake-section .section-head h2 {
    font-family: var(--font-display);
    /* A rank below the thesis. The page's argument is set at display-2;
       a playground rendered at the same size shouts as loudly as the
       claim it sits under, which is a hierarchy error before it is a
       taste one. */
    font-size: var(--text-3xl);
    font-weight: var(--weight-display);
    line-height: var(--leading-display);
    letter-spacing: var(--tracking-display);
    color: var(--text-primary);
    /* Sentence case: the platform's display voice is a word said, not
       shouted. Caps at 86px with display tracking is a siren. */
    text-transform: none;
    margin: 0;
}

.snake-section .section-head p {
    font-family: var(--font-ui);
    font-size: var(--text-lg);
    line-height: var(--leading-snug);
    color: var(--text-muted);
    max-width: var(--measure-narrow);
    margin: 0;
}

/* ── Playground instrument ─────────────────
   A readout, so the label voice governs and the numbers get the
   display face — the one place figures should carry weight. */
.snake-surface {
    max-width: 760px;
    margin-inline: auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-lg);
}

.snake-stats {
    border: 1px solid var(--line);
    border-radius: var(--radius-base);
    padding: var(--space-lg) var(--space-xl);
    gap: var(--space-lg);
}

.snake-stats .stat-label {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-muted);
}

.snake-stats .stat-value {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: var(--weight-semibold);
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-tight);
    color: var(--text-primary);
    /* Figures that change must not reflow their neighbours. */
    font-variant-numeric: tabular-nums;
    /* "RUN OVER" must stay one line: a wrapped status breaks the
       four-stat baseline the row is built on. */
    white-space: nowrap;
}

/* The counterpart accent takes LEVEL — both of the hour's inks live
   on the scoreboard, orange for state, blue for progress. */
.snake-stats .stat-value[data-snake-level] { color: var(--accent-secondary); }

.snake-board-wrapper,
.snake-board {
    border-radius: var(--radius-base);
}

/* The board was width:100% with aspect-ratio:1 and no height ceiling, so
   on a landscape phone it rendered roughly twice the viewport tall: you
   scrolled to see the half your snake was about to die in. A board you
   cannot see all of is not a game. */
.snake-board {
    max-height: min(62svh, 560px);
    max-width: min(62svh, 560px);
    margin-inline: auto;
}

/* The engine sizes the canvas in exact CSS pixels and scales its backing
   store by devicePixelRatio to keep the cells crisp. The engine's inline
   style is the one authority — width/height overrides here are how the
   board became 3x oversized on DPR-3 phones (auto !important resolves a
   canvas to its BACKING-STORE size, not the engine's CSS size). */
.snake-board .cyber-game-canvas {
    margin: auto;
}

/* Announcements for screen readers only — discrete events, not a
   per-frame score feed. */
.snake-live {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    clip-path: inset(50%);
    overflow: hidden;
    white-space: nowrap;
}

.dpad-boost {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
}
.snake-board {
    border: 1px solid var(--line);
    /* The legacy sheet paints this #0a0a0a with no light variant, so the
       board stayed a black hole punched through the light theme wherever
       the canvas did not cover it exactly. */
    background: var(--surface);
    /* Vertical gestures belong to the page; the board only takes them
       once a run is under way (the engine sets this while playing). */
    touch-action: pan-y;
}
.snake-board:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 3px;
}

.snake-start-btn,
.game-btn {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text);
    background: transparent;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-pill);
    padding: var(--space-sm) var(--space-xl);
    cursor: pointer;
    transition: var(--transition-color);
}
.snake-start-btn:hover,
.game-btn:hover { color: var(--accent); border-color: currentColor; }

.snake-controls-hint,
.snake-leaderboard-empty {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    letter-spacing: var(--tracking-label);
    color: var(--text-muted);
    text-align: center;
}

.snake-leaderboard h4 {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-muted);
    margin: 0 0 var(--space-sm);
}

/* ── Lab log ───────────────────────────────
   Mono is right here: it IS a log. Only the palette needs restating. */
.lab-log-console {
    border: 1px solid var(--line);
    border-radius: var(--radius-base);
    background: var(--surface-sunken);
}
.lab-log-header {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-muted);
    border-bottom: 1px solid var(--line);
}
.lab-log-status { color: var(--accent); }

/* ── Footer ────────────────────────────────
   Column heads are labels; links are the reading voice. */
.cyber-footer {
    border-top: 1px solid var(--line);
    padding-block: var(--band) var(--space-2xl);
    padding-inline: var(--safe-inline);
    background: var(--surface-primary);
}

.cyber-footer .footer-content {
    max-width: 1100px;
    margin-inline: auto;
    gap: var(--space-2xl);
}

.cyber-footer .footer-section h3 {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-muted);
    margin: 0 0 var(--space-md);
}

.cyber-footer .footer-links a {
    font-family: var(--font-ui);
    font-size: var(--text-base);
    color: var(--text-secondary);
    text-decoration: none;
    transition: var(--transition-color);
}
.cyber-footer .footer-links a:hover { color: var(--accent); }

.cyber-footer .footer-ascii pre {
    font-family: var(--font-ascii);
    font-size: var(--text-xs);
    color: var(--text-muted);
    margin: 0;
}

/* ── The help chip ─────────────────────────
   Same chip as the theme and sense toggles: one control language. */
.help-trigger {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    color: var(--text-muted);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    transition: var(--transition-color);
}
.help-trigger:hover { color: var(--accent); border-color: currentColor; }

/* ── Touch controls ────────────────────────
   The cross was three rows and about 160px of a phone's screen, on a
   surface that already ran past the viewport. One row of five does the
   same job in 56px, keeps every target at the 48px floor, and leaves
   the board and the controls visible at the same time — which is the
   whole requirement for a game you steer with your thumb. */
.snake-touch-dpad {
    display: none;
    gap: var(--space-xs);
}
@media (pointer: coarse) {
    .snake-touch-dpad { display: grid; grid-template-columns: repeat(5, 1fr); }
}

.snake-touch-dpad .dpad-btn {
    inline-size: auto;
    block-size: 52px;
    min-block-size: 48px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-base);
    background: transparent;
    color: var(--text);
    font-family: var(--font-mono);
    font-size: var(--text-base);
    display: flex;
    align-items: center;
    justify-content: center;
    touch-action: manipulation;
    transition: var(--transition-color);
}
.snake-touch-dpad .dpad-btn:active,
.snake-touch-dpad .dpad-btn.dpad-active {
    background: var(--accent);
    color: var(--text-inverse);
    border-color: var(--accent);
    transform: none;
}
.snake-touch-dpad .dpad-btn:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}

/* ── Portrait compression ──────────────────
   The section ran 1085px on a 390px phone with the readout at 174px
   against a 343px board — the instrument was half the size of the game.
   On a phone the board IS the status, so only the two figures that
   change during play survive. */
@media (max-width: 640px) {
    .snake-stats {
        display: flex;
        justify-content: space-between;
        padding: var(--space-md) var(--space-lg);
        gap: var(--space-md);
    }
    .snake-stats .stat-item:nth-child(2),
    .snake-stats .stat-item:nth-child(3) { display: none; }
    .snake-stats .stat-value { font-size: var(--text-lg); }
    .snake-section { padding-block: var(--space-2xl); }
    .snake-section .section-head { margin-bottom: var(--space-xl); }
}

/* ── Last of the legacy inks ───────────────
   The legacy sheet still paints the boost control and the run list in
   gold, and marks the current row with rgba(var(--time-primary), 0.06)
   — which is invalid CSS: --time-primary is a colour, not the three
   numbers rgba() wants, so that declaration was being dropped whole,
   !important and all. Both restated in tokens, where the contrast gate
   can see them. */
.snake-touch-dpad .dpad-boost {
    border-color: var(--accent);
    color: var(--accent);
}
.snake-touch-dpad .dpad-boost:active,
.snake-touch-dpad .dpad-boost.dpad-active {
    background: var(--accent);
    color: var(--text-inverse);
}

.snake-lb-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}
.snake-lb-row {
    display: grid;
    grid-template-columns: 2ch 1fr auto;
    gap: var(--space-md);
    align-items: baseline;
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    color: var(--text-muted);
}
.snake-lb-row.snake-lb-current {
    background: color-mix(in srgb, var(--accent) 8%, transparent);
    color: var(--text);
}
.snake-lb-rank,
.snake-lb-score { font-variant-numeric: tabular-nums; }
.snake-lb-score { color: var(--text); font-weight: var(--weight-bold); }
.snake-lb-meta { color: var(--text-muted); }

/* ── Fixed chrome discipline ───────────────
   Three pills share the viewport with the reading column. One control
   language — the pages.css chip — replacing the legacy neon treatment,
   a stacked bottom-right corner so help and sound never collide, and a
   compact footprint on phones so chrome never sits on the copy. */
.theme-toggle,
[data-theme] .theme-toggle {
    background: var(--surface);
    border: 1px solid var(--line);
    color: var(--text-muted);
    box-shadow: none;
    min-width: 0;
}
.theme-toggle:hover,
[data-theme] .theme-toggle:hover {
    background: var(--surface);
    color: var(--accent);
    border-color: currentColor;
    transform: none;
    box-shadow: none;
}
.theme-toggle:focus-visible,
[data-theme] .theme-toggle:focus-visible {
    background: var(--surface);
    color: var(--accent);
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    box-shadow: none;
}
.theme-toggle .theme-icon,
[data-theme] .theme-toggle .theme-icon { color: var(--accent); }
.theme-toggle .theme-label,
[data-theme] .theme-toggle .theme-label,
[data-theme] .theme-toggle #theme-state-label { color: inherit; }

/* Help stacks ABOVE the sense pill — same corner, two floors. */
.help-trigger {
    inset-block-end: calc(var(--space-md, 1rem) + 3.25rem);
}

@media (max-width: 640px) {
    /* Icon-only mode switch: a disc instead of a labelled bar, so the
       fixed pill stops parking on top of sentences mid-scroll. */
    .theme-toggle { padding: 0.55rem 0.65rem; min-height: 0; }
    .theme-toggle .theme-label { display: none; }
    .sense-toggle { padding: 0.35rem 0.65rem; }
}

/* ── The colophon ──────────────────────────
   An ending worth the opening: the minuscule rr at rest in the hour's
   accent, the living timestamp under it at reading size, the link
   columns demoted to what they are — an appendix. */
.colophon {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-lg);
    padding: var(--band) var(--safe-inline) var(--space-2xl);
    text-align: center;
}

.colophon-mark {
    font-family: var(--font-ascii);
    font-size: clamp(0.5rem, 0.35rem + 0.8vw, 0.85rem);
    line-height: 1.05;
    color: var(--accent);
    margin: 0;
    white-space: pre;
    /* The colophon centers its lines; centering each line of a bitmap
       independently re-draws the glyph. The block centers, the art
       stays left-aligned inside it. */
    text-align: left;
}
/* The pair, in the hour's two inks. */
.colophon-mark b { color: var(--accent); font-weight: inherit; }
.colophon-mark i { color: var(--accent-secondary); font-style: normal; }

.colophon-pulse {
    font-family: var(--font-mono);
    font-size: var(--text-lg);
    letter-spacing: 0.08em;
    color: var(--text-secondary);
    margin: 0;
}
