/* =============================================================================
 * mobile.css — Cardboard Oracle mobile-only layer
 * =============================================================================
 *
 * DESKTOP SAFETY CONTRACT (do not break):
 *   1. This file is loaded AFTER styles.css and is gated by a media attribute
 *      for portrait phones/small tablets plus short phone landscapes, so normal
 *      desktop layouts never apply it.
 *   2. EVERY rule below additionally lives inside the same compound query.
 *      This double-gating means a desktop-affecting rule cannot be added here
 *      even by accident — if a rule isn't inside the media block, it doesn't
 *      belong in this file.
 *   3. Desktop keeps its existing cascade. Removing this <link> disables this
 *      mobile override layer, but does not roll back app.js's semantic layout
 *      classifier or dialog behavior; use it only as an emergency visual
 *      rollback while a complete fix is prepared.
 *
 * Breakpoint: 768px (phones + portrait small tablets). Primary design target
 * is phones (~360–430px).
 *
 * Anchor on STRUCTURAL selectors (view IDs, .topbar, .view, .nav-tab) — not
 * fragile cosmetic class chains — because the desktop site is still changing.
 *
 * Phases landed here:
 *   Phase 0 — scaffold + global overflow guard.
 *   Phase 1 — global shell: topbar/nav reflow, tap-target floor, view padding.
 * ========================================================================== */

@media (max-width: 768px), (max-width: 932px) and (max-height: 500px) {

  /* ===========================================================================
   * Phase 0 — global guards
   * ======================================================================== */

  /* Kill horizontal scroll/overflow at the document level (mobile only). */
  html,
  body {
    max-width: 100%;
    overflow-x: hidden;
  }

  /* Author-level display rules can otherwise beat the browser's `[hidden]`
   * rule (notably topbar nav/notifications on the login screen). Hidden is a
   * state contract, so make it authoritative throughout the phone UI. */
  [hidden] { display: none !important; }

  /* ===========================================================================
   * Phase 1 — global shell
   * ======================================================================== */

  /* --- Topbar: collapse the single 96px row (with an absolute-centred 116px
   * logo) into a compact two-row layout that fits a phone:
   *   row 1 → logo (left) + icon cluster (right)
   *   row 2 → nav tabs as a full-width, horizontally swipeable strip
   * The logo is taken out of absolute-centring (mobile only) so it sits in the
   * flow and can't overlap the nav/icons. -------------------------------------- */
  .topbar {
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    padding: max(6px, env(safe-area-inset-top))
             max(10px, env(safe-area-inset-right))
             6px
             max(10px, env(safe-area-inset-left));
    min-height: 0;
    row-gap: 4px;
  }

  .brand {
    position: static;       /* out of absolute centring on mobile */
    transform: none;
    order: 1;
    height: auto;
  }
  .brand-logo {
    height: 40px;
    margin-bottom: 0;       /* drop the desktop -10px overhang */
  }

  .topbar-right {
    order: 2;
    flex: 1 1 0;
    min-width: 0;
    gap: 6px;
    flex-wrap: nowrap;
    justify-content: flex-end;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .topbar-right::-webkit-scrollbar { display: none; }
  .topbar-right > * { flex: 0 0 auto; }

  /* Nav forced onto its own full-width row, swipeable, no visible scrollbar. */
  .topbar-nav {
    order: 3;
    flex-basis: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    gap: 2px;
    scrollbar-width: none;            /* Firefox */
  }
  .topbar-nav::-webkit-scrollbar { display: none; }  /* WebKit */

  /* --- Tap-target floor (44px) for primary interactive shell controls. ----- */
  .nav-tab {
    flex: 0 0 auto;          /* keep full width; never squash tabs */
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    padding: 8px 14px;
    font-size: 14px;
  }
  .topbar-right .notif-btn,
  .topbar-right .help-orb {
    min-width: 40px;
    min-height: 40px;
  }

  /* --- Tap latency: kill the ~300ms touch delay so taps register instantly,
     and keep a fast tap-highlight so a press gives immediate feedback. ------- */
  a, button, [role="button"], .nav-tab, .cer-btn,
  [data-deck], [data-playtest-deck], [data-fr-rules],
  .help-orb, .pt-btn, .rules-act, summary {
    touch-action: manipulation;
  }

  /* --- Deck card list: on a narrow phone the fixed-width mana pips
     (flex-shrink:0) can squeeze the flex:1 name (overflow:hidden) down to zero
     width, hiding the card name entirely. Guarantee the name a usable minimum
     and let the pips shrink/clip first — the NAME matters more than the pips. */
  .card-row-name { min-width: 7em; }
  .card-row-pips { flex-shrink: 1; overflow: hidden; }

  /* --- View container: trim the 32px desktop padding that eats ~17% of a
   * 375px screen. (max-width is harmless below it, so left untouched.) ------- */
  .view {
    padding: 16px max(12px, env(safe-area-inset-right))
             calc(16px + env(safe-area-inset-bottom))
             max(12px, env(safe-area-inset-left));
  }

  /* Safari's collapsing browser chrome makes 100vh taller than the visible
   * screen. Dynamic viewport units keep login and supported solo playtest
   * controls reachable above the home indicator and software keyboard. */
  #login-view { height: 100dvh; }
  #setup-view { min-height: calc(100dvh - 100px); }
  #playtest-view.pt-fullscreen { min-height: 100dvh; }
  .pt-fullscreen .pt-vs { height: 100dvh; }
  .rules-table.rules-boot-stage { min-height: 100dvh; }

  /* ===========================================================================
   * Phase 2 — core flow: #my-decks-view + #setup-view
   * NOTE: #deck-slots already collapses to one column at <=800px in styles.css,
   * so the deck-slot grid reflow is inherited here, not re-declared.
   * ======================================================================== */

  /* --- My Decks header: wrap so the action buttons drop to their own full
   * row, and scale the big display title down so it doesn't crowd them. ----- */
  .my-decks-header { flex-wrap: wrap; gap: 12px; }
  .my-decks-title { font-size: 26px; margin-bottom: 16px; }
  .my-decks-header-actions { width: 100%; }
  .my-decks-header-actions .accent-btn,
  .my-decks-header-actions .ghost-btn { height: 44px; }

  /* --- New-deck form: bump sub-16px inputs to 16px so iOS Safari doesn't
   * zoom the page on focus; wrap the import row; full, tappable actions. ----- */
  .new-deck-form { padding: 16px 14px; }
  .new-deck-list-input { font-size: 16px; min-height: 170px; }
  .new-deck-moxfield-input { font-size: 16px; flex-basis: 100%; }
  .new-deck-import-row { flex-wrap: wrap; }
  .new-deck-actions .primary-btn { margin-left: 0; }
  .new-deck-action-btn { flex: 1; min-height: 44px; }

  /* --- Saved-deck rows: keep a comfortable tap height. -------------------- */
  .my-deck-row { min-height: 56px; }
  #my-decks-view .dsf-chip,
  #my-decks-view .mdr-score-btn { min-height: 40px; }
  #my-decks-view .decks-sort-btn { min-width: 44px; min-height: 44px; }

  /* Deck detail command bar: the desktop no-wrap action group was the one
   * remaining source of page-level horizontal overflow. Put actions on their
   * own swipeable row and keep every control comfortably tappable. */
  #my-decks-view .md-detail-bar { flex-wrap: wrap; gap: 8px; }
  #my-decks-view .md-detail-bar > #my-decks-back-btn { min-height: 44px; }
  #my-decks-view .md-detail-bar-actions {
    width: 100%;
    min-width: 0;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    gap: 6px;
    padding-bottom: 2px;
  }
  #my-decks-view .md-detail-bar-actions::-webkit-scrollbar { display: none; }
  #my-decks-view .md-detail-bar-actions > * { flex: 0 0 auto; }
  #my-decks-view .md-detail-bar-actions button,
  #my-decks-view .md-status-toggle,
  #my-decks-view .deck-header-actions button { min-height: 40px; }
  #my-decks-view .md-detail-page button:not(.help-orb),
  #my-decks-view .md-detail-page select,
  #my-decks-view .md-detail-page input:not([type="checkbox"]):not([type="radio"]) {
    min-height: 40px;
  }
  #my-decks-view .md-detail-page select,
  #my-decks-view .md-detail-page input:not([type="checkbox"]):not([type="radio"]),
  #my-decks-view .md-detail-page textarea { font-size: 16px; }
  #my-decks-view .md-detail-page .md-icon-btn,
  #my-decks-view .md-detail-page .split-btn-caret,
  #my-decks-view .md-detail-page .deck-header-art-edit,
  #my-decks-view .md-detail-page .deck-header-deck-edit,
  #my-decks-view .md-detail-page .seer-title-btn { min-width: 40px; }
  #my-decks-view .deck-header-tier { min-height: 40px; display: inline-flex; align-items: center; }

  /* Mana/Simulation summaries place a fixed-width score, metadata, and chevron
   * on one desktop line. On phones the Simulation metadata was clipped outside
   * the closed <details>, making its chevron unreachable. Give metadata a full
   * second row; dense chip sets can swipe within that row. */
  #my-decks-view .benchmark-hero-summary {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px 8px;
  }
  #my-decks-view .benchmark-hero-summary .benchmark-hero-left {
    grid-column: 1;
    min-width: 0;
  }
  #my-decks-view .benchmark-hero-summary .benchmark-chevron {
    grid-column: 2;
    grid-row: 1;
  }
  #my-decks-view .benchmark-hero-summary .benchmark-hero-components {
    grid-column: 1 / -1;
    grid-row: 2;
    width: 100%;
    min-width: 0;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  #my-decks-view .benchmark-hero-summary .benchmark-hero-components::-webkit-scrollbar { display: none; }

  /* --- Setup: Simulate / Deep Match fill the row and are tall enough to tap;
   * they wrap (stack) on very narrow screens. The + Player pill matches. ---- */
  .run-btns { width: 100%; flex-wrap: wrap; }
  .run-btns .simulate-btn,
  .run-btns .deep-btn { flex: 1; min-height: 44px; }
  .add-player-pill { min-height: 44px; }

  /* Three primary modes fit as a compact segmented row on a phone. The rules
   * modes themselves are still guarded below; this only avoids spending almost
   * a quarter of the first screen on three stacked navigation buttons. */
  #setup-view .ta-tabs {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    margin-inline: 0;
  }
  #setup-view .ta-mode-btn {
    min-height: 48px;
    padding: 10px 6px;
    font-size: clamp(15px, 4.4vw, 18px);
    letter-spacing: 0.05em;
  }
  #setup-view .ta-submodes {
    justify-content: flex-start;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  #setup-view .ta-submodes::-webkit-scrollbar { display: none; }
  #setup-view .ta-submodes .pt-pm-btn { flex: 0 0 auto; min-height: 44px; }

  /* ===========================================================================
   * Phase 3 — #results-view (simulation dashboard)
   * Charts already render as width:100% SVG (responsive), so no overflow
   * handling is needed for them. All rules scoped to #results-view.
   * ======================================================================== */

  /* Stat-row: the 2-player row collapses via the existing <=800px rule, but the
   * 3p/4p rows set `grid-template-columns` INLINE in app.js (renderStatRow),
   * which a normal media rule can't beat — hence !important. It is mobile-gated,
   * so desktop is untouched. Forces a single stacked column on phones. */
  #results-view .stat-row { grid-template-columns: 1fr !important; gap: 12px; }

  /* Panels + stat cards: trim the 28px desktop side padding for phone width. */
  #results-view .panel { padding: 16px 14px; }
  #results-view .stat-card { padding: 18px 16px; }

  /* Wins-by-turn legend wraps instead of overflowing a narrow row. */
  #results-view .bar-chart-legend { flex-wrap: wrap; gap: 10px 14px; }

  /* Games grid: fewer, larger cells so each game stays tappable on a phone
   * (overrides the existing <=800px repeat(5,1fr) via #id specificity). */
  #results-view .games-grid { grid-template-columns: repeat(4, 1fr); }

  /* ===========================================================================
   * Phase 4 — #builder-view (BETA) + #history-view
   * The builder's *-grid layouts (arch/power/cmd/constraint/skel) already
   * collapse to 1–2 columns at phone widths via existing media queries in
   * styles.css, so they're inherited here, not re-declared.
   * ======================================================================== */

  /* Builder step rail: 8 labelled dots overflow a phone — make the whole rail a
   * left-aligned, horizontally swipeable strip (hidden scrollbar). */
  #builder-view .builder-rail-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding: 12px 14px;
    scrollbar-width: none;
  }
  #builder-view .builder-rail-wrap::-webkit-scrollbar { display: none; }
  #builder-view .builder-rail { justify-content: flex-start; max-width: none; width: max-content; }

  /* Builder content: trim the 24px desktop side padding for phone width. */
  #builder-view .builder-content { padding: 16px 14px 60px; }

  /* Mode tabs swipe horizontally instead of overflowing. */
  #builder-view .builder-mode-tabs { overflow-x: auto; scrollbar-width: none; }
  #builder-view .builder-mode-tabs::-webkit-scrollbar { display: none; }
  #builder-view .builder-mode-tab { flex: 0 0 auto; white-space: nowrap; }
  #builder-view .builder-mode-tab,
  #builder-view .builder-primary-btn { min-height: 44px; }

  /* Step nav (Back / Next): stay one row, tall enough to tap. */
  #builder-view .builder-nav-back,
  #builder-view .builder-nav-next { min-height: 44px; }

  /* History cards: shrink the flanking 110px commander-art columns so the
   * matchup title + meta get usable width on a phone. */
  #history-view .history-card { grid-template-columns: 72px 1fr 72px; }
  #history-view .history-card-art,
  #history-view .history-cmdr,
  #history-view .history-cmdr-placeholder { width: 72px; }
  #history-view #history-matchups-btn { min-height: 44px; }

  /* ===========================================================================
   * Phase 5 — #login-view + #admin-view
   * Login is a centered card (form max-width 380px) — already phone-friendly.
   * Admin is internal/low-priority: the tab bar already wraps and .adash-stats
   * already collapses to 2 cols at <=700px (inherited), so only the wide data
   * tables need handling.
   * ======================================================================== */

  /* Login: bump the 14px inputs to 16px so iOS Safari doesn't zoom on focus. */
  #login-view .login-form input { font-size: 16px; }

  /* Admin: make the wide diagnostic tables horizontally scrollable instead of
   * cramming columns to unreadable widths on a phone. */
  #admin-view .rv3-table,
  #admin-view .detqa-table,
  #admin-view .detqa-eventstable,
  #admin-view .calib-table,
  #admin-view .match-report-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
  }

  /* ===========================================================================
   * Phase 6 — polish: modals, toasts, topbar dropdowns, small-phone tuning
   * ======================================================================== */

  /* Modals become bottom sheets: full-width, anchored to the bottom, rounded
   * top. (.modal-panel already caps height and scrolls its own body.) */
  .modal-backdrop { padding: 0; align-items: flex-end; }
  .modal-panel {
    width: 100%;
    max-width: 100%;
    max-height: 90dvh;
    border-radius: 16px 16px 0 0;
    padding-bottom: env(safe-area-inset-bottom);
  }

  /* Toasts span the bottom of the screen instead of a fixed 360px column. */
  .toast-stack {
    left: max(12px, env(safe-area-inset-left));
    right: max(12px, env(safe-area-inset-right));
    bottom: calc(12px + env(safe-area-inset-bottom));
  }
  .toast { max-width: none; }

  /* Fixed topbar dropdowns (notifications / what's new) are 570px/320px on
   * desktop — span the viewport width and clear the compact two-row topbar. */
  .notif-dropdown,
  .whatsnew-dropdown {
    top: calc(100px + env(safe-area-inset-top));
    left: 8px;
    right: 8px;
    width: auto;
    max-width: none;
    max-height: 70vh;
  }
  /* Activity dropdown is absolute (anchored to its wrap) — cap its width so it
   * can't exceed the viewport. */
  .activity-dropdown { min-width: 0; max-width: 92vw; }

  /* ===========================================================================
   * Phase 7 — deck-detail hero (.deck-unified-header) long-name fix
   * The hero is a flex row: [art 150px | titles flex:1 | pips flex-shrink:0 |
   * rings]. On a phone the fixed-width art + non-shrinking mana pips starve the
   * title column, so the deck name (white-space:nowrap + ellipsis) collapses to
   * a single letter ("M.") and the pips crowd the score. Fix: narrow the art,
   * let the name/commander WRAP, and drop the pips to their own full row.
   * ======================================================================== */
  /* Density pass: the wrapped hero used to run 544px tall on a 375px phone —
     two thirds of the viewport — because the 20px flex gap fired between every
     wrapped row, the 64px score sat STACKED above its tier pill, and the 80px
     art left ~138px of dead column beneath it. Tighten the gap, run score+tier
     as one baseline row, and shrink the rings; the pips and the action pair
     then fill their rows instead of trailing empty space. */
  .deck-unified-header {
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 10px;
    padding-right: 12px;
  }
  /* Stretch the art down the whole title block. It used to be a 70px thumbnail
     beside a ~180px column, leaving a dead 96px-wide gutter under it. */
  .deck-header-art-wrap { width: 96px; align-self: stretch; }
  .deck-header-art-wrap img { width: 100%; height: 100%; object-fit: cover; }
  .deck-header-titles { padding: 10px 0; }
  .deck-header-deck { font-size: 24px; white-space: normal; }
  .deck-header-deck-text { white-space: normal; overflow: visible; text-overflow: clip; }
  .deck-header-cmdr {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    text-align: left;
  }
  /* Score and tier side by side, not stacked — reclaims ~40px and puts the
     pill in the empty space the big numeral left to its right. */
  .deck-header-score-stack {
    display: flex;
    flex-direction: row;      /* base rule is column — that stacking is the ~46px */
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 10px;
  }
  .deck-header-score { font-size: 42px; line-height: 1; margin: 0; }
  .deck-header-tier { margin: 0; padding: 4px 11px; }
  .deck-header-pips {
    flex-basis: 100%;
    justify-content: flex-start;
    padding: 0 12px;
  }
  .deck-header-rings {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 4px;
    width: 100%;
    padding: 2px 0 0;
  }
  .deck-header-rings .score-ring { min-width: 0; padding-inline: 0; }
  .deck-header-rings .score-ring svg { width: min(78px, 100%); height: auto; }
  /* Playtest/Share are pinned bottom-right (absolute) on desktop, where the
     rings sit to their left. Once the hero WRAPS on a phone the rings become a
     full-width bottom row and own that corner, so the buttons overlapped the
     Simulation ring's label + weight. Return them to normal flow and let the
     pair SPLIT the full width — no dead gutter, and proper touch targets. */
  .deck-header-actions {
    position: static;
    flex-basis: 100%;
    gap: 8px;
    padding: 0 12px 12px;
  }
  .deck-header-actions .deck-header-share-btn {
    flex: 1 1 0;
    min-height: 40px;
    font-size: 13px;
  }

  /* The compact deck pill is fixed to the visible phone viewport. Its desktop
   * top:96px assumed the full header remained above it; once Safari scrolls the
   * header away that hard-coded offset made the pill jump a full row downward. */
  .md-hero-pill {
    top: max(8px, env(safe-area-inset-top));
    max-width: calc(100vw - max(24px, env(safe-area-inset-left) + env(safe-area-inset-right)));
  }

  /* The Lab and Quest widgets contain input + action clusters. Let them wrap
   * rather than clipping the last action off the right edge on 360px phones. */
  #my-decks-view .md-lab-inline,
  #my-decks-view .md-quest-add { flex-wrap: wrap; }
  #my-decks-view .md-lab-inline > input,
  #my-decks-view .md-quest-add > select { flex: 1 1 150px; min-width: 0; }

  /* ===========================================================================
   * Phase 8 — match/duel result hero + Battle Log tabs (History duel detail)
   * The result scoreboard (.dm-scoreboard) is a `1fr 220px 1fr` grid; on a
   * phone the fixed 220px center + gaps eat the width, starving the two side
   * commander-art panels to ~44px so they're sliced off (overflow:hidden). And
   * the .bl-modebar tab row (Battle Log / Chronicle / Log Book / Score Card)
   * overflows. Fix: stack the scoreboard to one column; make the tabs swipe.
   * ======================================================================== */
  .dm-scoreboard { grid-template-columns: 1fr; gap: 12px; }
  .dm-score-side { min-height: 150px; }
  .dm-score-center { min-width: 0; }
  .dm-winner-name { font-size: 30px; }

  .bl-modebar {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .bl-modebar::-webkit-scrollbar { display: none; }
  .bl-mode { flex: 0 0 auto; }
  .bl-report-btn { margin-left: 8px; }

  /* ===========================================================================
   * Phase 9 — proactive sweep: Score Card + My Cards
   * ======================================================================== */

  /* Score Card (Battle Log "Score Card" mode): the team scoreboard is
   * `.bl-report-panel .bl-scoreboard` (grid auto|1fr|auto) — scoped to that
   * (NOT the live-duel .bl-scoreboard flex rule) so only the report card
   * stacks. One column on a phone, p2 left-aligned to match p1. */
  .bl-report-panel .bl-scoreboard { grid-template-columns: 1fr; gap: 10px; }
  .bl-score-team.p2 {
    text-align: left;
    border-right: none;
    border-left: 3px solid var(--p2);
  }

  /* My Cards collection rows: a 6-column fixed grid
   * (qty·name·price·EDHREC·printing·remove) crams the card name on a phone.
   * Tighten the gap and the numeric columns so the name keeps usable width. */
  #my-cards-view .mc-row--coll {
    gap: 6px 8px;
    grid-template-columns: 84px minmax(0, 1fr) 40px;
    grid-template-areas:
      "qty name remove"
      "price pop set";
    padding: 8px 4px;
  }
  #my-cards-view .mc-row--coll .mc-qty-step { grid-area: qty; }
  #my-cards-view .mc-row--coll .mc-name { grid-area: name; }
  #my-cards-view .mc-row--coll .mc-price {
    grid-area: price;
    justify-self: start;
    text-align: left;
  }
  #my-cards-view .mc-row--coll .mc-pop { grid-area: pop; }
  #my-cards-view .mc-row--coll .mc-set-chip { grid-area: set; }
  #my-cards-view .mc-row--coll .mc-remove { grid-area: remove; }
  #my-cards-view .mc-qty-btn { width: 32px; height: 32px; }
  #my-cards-view .mc-qty { min-width: 16px; }
  #my-cards-view .mc-remove { width: 36px; height: 36px; }
  #my-cards-view .mc-edhrec,
  #my-cards-view .mc-set-chip { min-height: 32px; display: inline-flex; align-items: center; justify-content: center; }
  #my-cards-view .mc-actions {
    flex: 1 0 100%;
    width: 100%;
    min-width: 0;
    margin-left: 0;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding-bottom: 2px;
  }
  #my-cards-view .mc-actions::-webkit-scrollbar { display: none; }
  #my-cards-view .mc-actions > * { flex: 0 0 auto; min-height: 40px; }
  #my-cards-view .mc-icon-btn { min-width: 40px; }

  /* ===========================================================================
   * Phase 10 — 1v1-vs-AI + networked 1v1: iPad-and-up only (disabled on phones)
   * The interactive rules-accurate board (.cob-v3 — "cob-v3 sandbox (1v1 vs
   * AI)") needs tablet-or-larger width, so we ALLOW it on iPad and up and show
   * a notice ONLY on semantic phone widths. The nested 767px breakpoint is
   * deliberately identical to app.js's PHONE_1V1_QUERY: wide phones remain
   * blocked through 767px while compact tablets begin at 768px.
   * Targeted at non-solo .cob-v3 tables only. Goldfish's live root is
   * .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) and receives the supported phone composition below.
   * ======================================================================== */
  @media (max-width: 767px), (max-width: 932px) and (max-height: 500px) {
    /* Legacy phone sizing remains useful, but every selector below is bounded
       by the semantic Goldfish root. Width alone must never compose a phone UI. */
    .phone-1v1-notice {
      min-height: 48vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 12px;
      padding: 28px 18px;
      text-align: center;
      border: 1px solid rgba(230, 86, 45, 0.28);
      border-radius: 14px;
      background: rgba(20, 8, 8, 0.48);
    }
    .phone-1v1-notice h2 { margin: 0; font-family: var(--font-display); }
    .phone-1v1-notice p { max-width: 330px; margin: 0; color: var(--text-dim); line-height: 1.55; }
    .phone-1v1-icon { font-size: 36px; color: var(--p1); }
    .phone-1v1-back { min-height: 44px; margin-top: 6px; }

    .cob-v3:not(.pt-solo) {
      display: flex !important;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      min-height: 55vh;
      padding: 28px 22px;
      text-align: center;
      gap: 14px;
    }
    .cob-v3:not(.pt-solo) > * { display: none !important; }   /* hide the live board guts */
    .cob-v3:not(.pt-solo)::before {
      content: "\2694";   /* crossed swords */
      font-size: 34px;
      opacity: 0.8;
    }
    .cob-v3:not(.pt-solo)::after {
      content: "1v1 vs AI needs a bigger screen.\A\A Open Cardboard Oracle on an iPad, tablet, or desktop to play a live match.";
      white-space: pre-line;
      display: block;
      max-width: 300px;
      font-size: 16px;
      line-height: 1.55;
      color: var(--text);
    }
    /* Hide the launch entry points so the feature isn't offered on a phone. */
    .cob-fight-btn,
    .fr-play { display: none !important; }

    /* Goldfish is intentionally supported on phones. It becomes one internally
     * scrollable column: compact toolbar, usable play stage, player/zones/hand,
     * then the full tool rail. Next Turn stays pinned above the home indicator. */
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) {
      display: grid !important;
      grid-template-columns: minmax(0, 1fr);
      grid-template-rows: auto minmax(560px, 1fr) auto;
      align-items: stretch;
      justify-content: stretch;
      gap: 8px;
      width: 100%;
      height: 100dvh;
      min-height: 100dvh;
      padding: max(6px, env(safe-area-inset-top))
               max(6px, env(safe-area-inset-right))
               calc(70px + env(safe-area-inset-bottom))
               max(6px, env(safe-area-inset-left));
      overflow-x: hidden;
      overflow-y: auto;
      overscroll-behavior: contain;
      text-align: left;
      -webkit-overflow-scrolling: touch;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-top {
      grid-column: 1;
      grid-row: 1;
      position: sticky;
      top: 0;
      z-index: 90;
      gap: 6px;
      padding: 5px 7px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-title { min-width: 0; flex: 1 1 auto; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-title b,
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-title span {
      display: block;
      max-width: 100%;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-title span { margin-left: 0; margin-top: 2px; font-size: 10px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-topbtns { flex: 0 0 auto; gap: 4px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-topbtns .pt-btn,
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-topbtns .cob-tool {
      min-width: 44px;
      min-height: 44px;
      padding: 4px 8px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-fsbtn { font-size: 24px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-exit { min-width: 64px !important; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-setpop {
      position: fixed;
      top: calc(58px + env(safe-area-inset-top));
      right: max(8px, env(safe-area-inset-right));
      width: min(290px, calc(100vw - 16px));
      max-height: calc(100dvh - 76px - env(safe-area-inset-top));
      overflow-y: auto;
    }

    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-bf-solo {
      grid-column: 1;
      grid-row: 2;
      min-width: 0;
      min-height: 560px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-bf { min-height: 235px; }
    /* Owner spec (batch 3): phone base card size = classic / 1.5 (PT_ZOOM_DEFAULT,
       app.js) so cards render at the old size at the 125% default open zoom.
       MUST match the .pt-bf-visual calc() sizes in styles.css — these fixed inner
       widths override the visual's width:100%, and a mismatch skews the card
       aspect ratio (phase2 proportion contract). */
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .pt-bf-slot .pt-card { width: calc(104px / 1.5); }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .pt-bf-slot.is-land :is(.pt-card, .land-card) { width: calc(94px / 1.5); }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-player {
      display: grid;
      grid-template-columns: auto minmax(0, 1fr);
      align-items: center;
      gap: 8px;
      padding: 6px 8px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-life-control { gap: 5px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-life-control .pt-life-btn {
      width: 44px;
      height: 44px;
      min-width: 44px;
      min-height: 44px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-life { --life: 52px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-pinfo { min-width: 0; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-pinfo h2 { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-pinfo p { font-size: 10px; line-height: 1.35; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-piles {
      grid-column: 1 / -1;
      display: grid;
      grid-template-columns: repeat(4, minmax(0, 1fr));
      gap: 4px;
      width: 100%;
      margin-left: 0;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-piles .pt-tile {
      min-width: 0;
      min-height: 76px;
      padding: 4px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-piles .pt-pile { width: min(52px, 100%); height: 54px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-hand {
      justify-content: flex-start;
      gap: 6px;
      width: 100%;
      min-height: 0;
      overflow-x: auto;
      overflow-y: hidden;
      padding: 4px 8px 8px;
      /* NO scroll-snap here: with count-fitted card widths (--hand-fit) the
         snap grid pitch (card + gap) never lines up with "card fully revealed
         at the right edge", so proximity snap claws back scrollIntoView /
         keyboard-focus reveals by one notch and leaves the target card
         clipped ~18-22px (dense-hand reachability contract, 844x390). Native
         momentum scrolling stays. */
      -webkit-overflow-scrolling: touch;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-hand .pt-card {
      /* Card width is derived from the live hand count (--hand-n, set in JS)
         so all 7 opening-hand cards fit the strip with no scroll, while a
         sparse hand doesn't blow up huge and an 8+ hand keeps the 7-card
         size (so it legitimately overflows into the scroll strip below).
         Height is derived from width via --card-ratio (5:7) so cards stay
         correctly proportioned at every hand size instead of a fixed height
         squishing/stretching the art. The container has no min-height so it
         hugs whatever height the cards resolve to (short for a full 7-card
         hand, taller for a sparse one) instead of leaving a dead band.
         Floor is 44px (not the fitted 36px): each card is a role="button"
         touch target and must never drop below the 44 CSS-pixel floor on
         the narrowest phones (320/360px) — a 7-card hand there overflows
         into the existing overflow-x:auto scroll strip instead. */
      --hand-fit: clamp(44px, calc((100% - 6px * (min(var(--hand-n, 7), 7) - 1)) / min(var(--hand-n, 7), 7)), 88px);
      flex: 0 0 var(--hand-fit);
      width: var(--hand-fit);
      aspect-ratio: var(--card-ratio);
      height: auto;
      margin-left: 0 !important;
      transform: none !important;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-hand .pt-card:hover ~ .pt-card { transform: none !important; }

    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-rail {
      grid-column: 1;
      grid-row: 3;
      display: block !important;
      min-width: 0;
      padding: 12px 10px 18px;
      overflow: visible;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-rail h3 { font-size: 14px; margin-bottom: 8px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-rail h4 { margin: 14px 0 6px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-summary { gap: 6px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-tools { gap: 6px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-tools .pt-btn { min-height: 44px; font-size: 13px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-actions {
      position: fixed;
      z-index: 95;
      left: max(8px, env(safe-area-inset-left));
      right: max(8px, env(safe-area-inset-right));
      bottom: max(8px, env(safe-area-inset-bottom));
      margin: 0;
      padding: 5px;
      border: 1px solid var(--bronze-dim);
      border-radius: 12px;
      background: rgba(5, 8, 11, .94);
      box-shadow: 0 -8px 28px rgba(0, 0, 0, .55);
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-actions .pt-btn { min-height: 48px; }

    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .pt-mull-overlay {
      position: fixed;
      top: calc(62px + env(safe-area-inset-top));
      right: max(8px, env(safe-area-inset-right));
      bottom: auto;
      left: max(8px, env(safe-area-inset-left));
      width: auto !important;
      max-height: min(220px, calc(100dvh - 150px));
      overflow-y: auto;
      transform: none;
      padding: 14px 10px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .pt-pickbot-overlay {
      bottom: calc(70px + env(safe-area-inset-bottom));
      max-height: none;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .pt-pickbot-hand { gap: 8px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .pt-pickbot-card { min-width: 68px; min-height: 94px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .pt-mull-btns .pt-btn { min-width: 110px; min-height: 44px; }
  }

  /* Goldfish Phase 2 phone composition. This later, solo-only block supersedes
   * the Phase 0 stacked rail without changing the non-solo phone notice above.
   * The renderer keeps one DOM tree: CSS turns the existing rail into a sheet. */
  @media (max-width: 767px), (max-width: 932px) and (max-height: 500px) {
    /* Keep the retired inline-sheet composition semantic while the portal
       implementation below remains the active phone surface. */
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]),
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"])[data-mode="goldfish"] {
      position: fixed;
      inset: var(--pt-vv-top, 0) auto auto var(--pt-vv-left, 0);
      grid-template-columns: minmax(0, 1fr);
      grid-template-rows: auto minmax(0, 1fr) auto;
      gap: 6px;
      width: var(--pt-vv-w, 100%);
      height: var(--pt-vv-h, 100dvh);
      min-height: 0;
      padding: max(6px, env(safe-area-inset-top))
               max(6px, env(safe-area-inset-right))
               max(6px, env(safe-area-inset-bottom))
               max(6px, env(safe-area-inset-left));
      overflow: hidden;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) > .cob-solo-top.cob-topbar {
      grid-column: 1;
      grid-row: 1;
      position: relative;
      inset: auto;
      z-index: 90;
      min-width: 0;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-title span { display: none; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-topbtns .cob-tool-icon {
      width: 44px;
      height: 44px;
      min-width: 44px;
      min-height: 44px;
      padding: 0;
    }

    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-bf-solo {
      grid-column: 1;
      grid-row: 2;
      min-width: 0;
      min-height: 0;
      display: flex;
      overflow-x: hidden;
      overflow-y: auto;
      overscroll-behavior: contain;
      -webkit-overflow-scrolling: touch;
    }
    /* True Sandbox: the stage GROWS to fill the felt down to the hand console.
       A fixed 44dvh basis left a dead band of felt below the card surface —
       the "bottom wall" a dragged card could never cross. */
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-stage,
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-bf {
      flex: 1 1 clamp(260px, 44dvh, 360px);
      min-height: 260px;
    }
    /* Portrait phone Turn marker: short landscape retains the compact override
       in the existing max-height block below. */
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-turn-marker {
      top: 8px;
      gap: 7px;
      padding: 4px 12px 6px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-turn-marker span { font-size: 10px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-turn-marker strong { font-size: 28px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-empty {
      max-width: 330px;
      padding-inline: 22px;
      font-size: 12px;
    }
    /* Owner spec (batch 3): phone base card size = classic / 1.5 (PT_ZOOM_DEFAULT,
       app.js) so cards render at the old size at the 125% default open zoom.
       MUST match the .pt-bf-visual calc() sizes in styles.css — these fixed inner
       widths override the visual's width:100%, and a mismatch skews the card
       aspect ratio (phase2 proportion contract). */
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .pt-bf-slot .pt-card { width: calc(104px / 1.5); }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .pt-bf-slot.is-land :is(.pt-card, .land-card) { width: calc(94px / 1.5); }

    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-console {
      flex: 0 0 auto;
      min-width: 0;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-console .cob-player {
      display: grid;
      grid-template-columns: auto minmax(0, 1fr);
      gap: 8px;
      padding: 8px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-console .cob-piles {
      grid-column: 1 / -1;
      display: grid;
      grid-template-columns: repeat(4, minmax(0, 1fr));
      width: 100%;
      margin: 0;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-console .cob-hand {
      position: relative;
      inset: auto;
      transform: none;
      justify-content: flex-start;
      gap: 6px;
      width: 100%;
      min-height: 0;
      overflow-x: auto;
      overflow-y: hidden;
      padding: 4px 8px 8px;
      /* NO scroll-snap — see the .cob-hand rule above (Phase 0 block): the
         count-fitted card widths make proximity snap clip scrollIntoView /
         keyboard-focus reveals. This later block wins the cascade so it must
         stay snap-free too. */
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-console .cob-hand .pt-card {
      /* See the .cob-hand .pt-card rule above (Phase 0 block) for the
         --hand-fit rationale — this later block wins the cascade (extra
         .cob-solo-console qualifier) so it must carry the same formula,
         including the 44px touch-target floor. */
      --hand-fit: clamp(44px, calc((100% - 6px * (min(var(--hand-n, 7), 7) - 1)) / min(var(--hand-n, 7), 7)), 88px);
      flex: 0 0 var(--hand-fit);
      width: var(--hand-fit);
      aspect-ratio: var(--card-ratio);
      height: auto;
      margin-left: 0 !important;
      transform: none !important;
    }
    /* Hand overflow affordance (mobile-UX: swipeable hand fan). The count-fit
       widths above make exactly 7 cards fill the strip, so an 8th+ card is
       100% clipped — nothing peeks to say the shelf scrolls. app.js
       (_ptHandFadeSync) tags the clipped edge(s) with data-pt-hand-fade;
       masking the SCROLLER fades those edges without a separate overlay
       element (the mask is painted in the border box, so it stays put while
       the content scrolls under it). */
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-hand[data-pt-hand-fade~="right"] {
      -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 30px), transparent 100%);
      mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 30px), transparent 100%);
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-hand[data-pt-hand-fade~="left"] {
      -webkit-mask-image: linear-gradient(to right, transparent 0, #000 30px, #000 100%);
      mask-image: linear-gradient(to right, transparent 0, #000 30px, #000 100%);
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-hand[data-pt-hand-fade~="left"][data-pt-hand-fade~="right"] {
      -webkit-mask-image: linear-gradient(to right, transparent 0, #000 30px, #000 calc(100% - 30px), transparent 100%);
      mask-image: linear-gradient(to right, transparent 0, #000 30px, #000 calc(100% - 30px), transparent 100%);
    }

    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock {
      grid-column: 1;
      grid-row: 3;
      position: sticky;
      bottom: 0;
      z-index: 105;
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 6px;
      padding: 6px 6px max(6px, env(safe-area-inset-bottom));
      border: 1px solid var(--bronze-dim);
      border-radius: 13px;
      background: rgba(5, 8, 11, .97);
      box-shadow: 0 -10px 30px rgba(0, 0, 0, .62);
    }
    .cob-v3.pt-solo[data-pt-layout="widePhone"] .cob-solo-dock[data-pt-action-count="4"] {
      grid-template-columns: repeat(4, minmax(0, 1fr));
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock .pt-btn,
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock .cob-tool {
      min-width: 0;
      min-height: 48px;
      margin: 0;
      padding: 7px 8px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock [data-pt="endturn"] {
      background: linear-gradient(180deg, #e7c878, var(--gold));
      border-color: #e7c878;
      color: #1a1206;
      font-weight: 900;
    }

    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-rail {
      position: fixed;
      inset: auto 0 0;
      z-index: 120;
      display: flex !important;
      flex-direction: column;
      gap: 8px;
      width: 100%;
      max-width: none;
      max-height: min(75dvh, 640px);
      padding: 10px max(12px, env(safe-area-inset-right))
               max(14px, env(safe-area-inset-bottom))
               max(12px, env(safe-area-inset-left));
      overflow-x: hidden;
      overflow-y: auto;
      overscroll-behavior: contain;
      -webkit-overflow-scrolling: touch;
      border: 1px solid var(--bronze);
      border-bottom: 0;
      border-radius: 18px 18px 0 0;
      background: #080d12;
      box-shadow: 0 -24px 70px rgba(0, 0, 0, .88);
      transform: translateY(105%);
      transition: transform .22s cubic-bezier(.2, .75, .3, 1);
      text-align: left;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"])[data-rail-open="true"] .cob-solo-rail,
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]).is-rail-open .cob-solo-rail { transform: translateY(0); }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-sheet-head {
      position: sticky;
      top: 0;
      z-index: 2;
      flex: 0 0 auto;
      display: flex;
      align-items: center;
      justify-content: space-between;
      min-height: 44px;
      padding: 0 2px 7px;
      border-bottom: 1px solid rgba(255, 255, 255, .08);
      background: #080d12;
      color: var(--gold);
      font-size: 13px;
      font-weight: 800;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-sheet-head .pt-btn,
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-sheet-head .cob-tool {
      min-width: 44px;
      min-height: 44px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-rail .cob-actions {
      position: static;
      inset: auto;
      z-index: auto;
      margin: 0;
      padding: 0;
      border: 0;
      background: none;
      box-shadow: none;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-rail .cob-solo-journal {
      flex: 1 1 auto;
      min-height: 96px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-rail .cob-solo-toolgroup { flex: 0 0 auto; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-rail .cob-solo-toolgroup > summary { min-height: 44px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-rail .cob-tools .pt-btn { min-height: 44px; }

    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-rail-scrim {
      position: fixed;
      inset: 0;
      z-index: 115;
      display: block;
      visibility: hidden;
      opacity: 0;
      pointer-events: none;
      background: rgba(2, 5, 8, .68);
      transition: opacity .18s ease, visibility 0s linear .18s;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"])[data-rail-open="true"] .cob-solo-rail-scrim,
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]).is-rail-open .cob-solo-rail-scrim {
      visibility: visible;
      opacity: 1;
      pointer-events: auto;
      transition-delay: 0s;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-overlay-layer .cob-solo-setpop {
      top: calc(58px + env(safe-area-inset-top));
      right: max(8px, env(safe-area-inset-right));
      width: min(296px, calc(100vw - 16px));
      max-height: calc(100dvh - 76px - env(safe-area-inset-top));
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .pt-pickbot-overlay { bottom: calc(66px + env(safe-area-inset-bottom)); }

    .arena-dialog-layer[data-arena-mode="goldfish"] {
      align-items: end;
      padding: 0;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-dialog {
      width: 100%;
      max-width: none;
      max-height: min(88dvh, calc(var(--pt-vv-h, 100dvh) - 8px), 760px);
      border-right: 0;
      border-bottom: 0;
      border-left: 0;
      border-radius: 18px 18px 0 0;
      padding-bottom: 0;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-dialog--mulligan {
      max-height: min(92dvh, calc(var(--pt-vv-h, 100dvh) - 8px), 760px);
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .pt-mull-hand-preview {
      justify-content: flex-start;
      overflow-x: auto;
      overflow-y: hidden;
      /* NO scroll-snap — same count-fitted widths as .cob-hand, so proximity
         snap would clip programmatic/keyboard reveals the same way (see the
         .cob-hand rule). */
      overscroll-behavior-x: contain;
      -webkit-overflow-scrolling: touch;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .pt-mull-card {
      /* Same --hand-n count-fit approach as the in-table .cob-hand (see
         hand-fit.js), but with the mulligan preview's 8px gap (not 6px) so
         all 7 opening-hand cards fit with no horizontal scroll, while an
         8+ hand keeps the 7-card size and legitimately scrolls. */
      --hand-fit: clamp(36px, calc((100% - 8px * (min(var(--hand-n, 7), 7) - 1)) / min(var(--hand-n, 7), 7)), 90px);
      flex: 0 0 var(--hand-fit);
      width: var(--hand-fit);
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-dialog--mulligan .pt-pickbot-hand {
      flex-wrap: nowrap;
      justify-content: flex-start;
      max-height: none;
      overflow-x: auto;
      overflow-y: hidden;
      /* NO scroll-snap — see .pt-mull-hand-preview above. */
      -webkit-overflow-scrolling: touch;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-dialog--mulligan .pt-pickbot-card {
      flex: 0 0 auto;
      min-width: 68px;
      min-height: 94px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-dialog--mulligan .pt-mull-btns {
      width: 100%;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-dialog--mulligan .pt-mull-btns .pt-btn {
      flex: 1 1 132px;
      min-height: 44px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-dialog-body {
      overscroll-behavior: contain;
      -webkit-overflow-scrolling: touch;
      padding: 12px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-dialog-header {
      padding: 14px 12px 12px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-dialog-footer {
      flex-wrap: wrap;
      padding: 10px 12px calc(12px + env(safe-area-inset-bottom));
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-dialog-footer .pt-btn {
      flex: 1 1 128px;
      min-height: 44px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .pt-modal-row {
      align-items: flex-start;
      flex-wrap: wrap;
      gap: 7px;
      padding-block: 9px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .pt-modal-name {
      min-width: 0;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .pt-modal-acts {
      width: 100%;
      justify-content: flex-end;
      overflow-x: auto;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-field-row {
      align-items: stretch;
      flex-direction: column;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-field-row .pt-btn {
      min-height: 44px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .pt-token-form {
      grid-template-columns: minmax(0, 1fr);
      gap: 12px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .pt-token-form > * {
      grid-column: 1;
      min-width: 0;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .pt-token-form :is(input, select) {
      min-height: 44px;
      font-size: 16px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .pt-token-selection {
      overflow-wrap: anywhere;
    }

    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) [data-pt-card-action] { scroll-margin: 70px 12px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) :is(button, summary),
    .pt-cardmenu[role="menu"] [role="menuitem"] {
      min-width: 44px;
      min-height: 44px;
    }
    .pt-cardmenu[role="menu"] {
      max-width: calc(100vw - 16px);
      max-height: min(72dvh, 620px);
      overflow-y: auto;
      overscroll-behavior: contain;
    }

    @media (max-height: 500px) {
      .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-stage,
      .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-bf {
        flex: 1 1 clamp(220px, 68dvh, 300px);
        min-height: 220px;
      }
      .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-turn-marker {
        top: 5px;
        gap: 6px;
        padding: 5px 10px 6px;
      }
      .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-turn-marker span { font-size: 10px; }
      .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-turn-marker strong { font-size: 26px; }
      .pt-cardmenu[role="menu"] {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 4px;
        width: min(720px, calc(100vw - 16px));
        max-width: calc(100vw - 16px);
        max-height: calc(100dvh - 16px);
        overflow-y: auto;
      }
      .pt-cardmenu[role="menu"] :is(.pt-menu-h, .pt-menu-counters) {
        grid-column: 1 / -1;
      }
      .pt-cardmenu[role="menu"] .pt-menu-h {
        margin-bottom: 0;
      }
      .pt-cardmenu[role="menu"] .pt-menu-item {
        min-width: 0;
        margin: 0;
      }
      .pt-cardmenu[role="menu"] .pt-menu-counters {
        margin-top: 0;
        padding-block: 5px;
      }
      .pt-cardmenu[role="menu"] .pt-menu-ctr-grid {
        grid-template-columns: repeat(6, minmax(0, 1fr));
      }
    }
  }

  /* ===========================================================================
   * Phase 11 — deck-detail card list: toolbar overflow + touch card preview
   * ======================================================================== */

  /* The CARDS toolbar (Builds / Export / Print / Combos / Insights / Reset /
   * Edit) is a no-wrap flex row that runs off the right edge on a phone. Keep
   * it on ONE line and make it horizontally swipeable (hidden scrollbar). */
  /* The summary is a 3-col grid (1fr auto 1fr) on desktop, which overlaps on a
   * phone — switch it to a stacked column so title / toolbar / price each get
   * their own full-width row. */
  .md-cards-summary { display: flex; flex-direction: column; align-items: stretch; gap: 8px; }
  .md-cards-actions {
    display: flex;
    flex-wrap: nowrap;
    gap: 6px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;   /* Firefox */
    padding-bottom: 2px;
  }
  .md-cards-actions::-webkit-scrollbar { display: none; }   /* WebKit */
  .md-cards-actions .cer-btn { flex: 0 0 auto; }            /* don't squash; keep swipeable */
  .md-cards-actions .cer-btn,
  .md-cards-actions .md-icon-btn { min-height: 40px; }

  /* The Export ▾ dropdown lives inside the now-scrollable strip, whose
   * overflow-x clips it vertically too. Re-home it as a fixed bottom sheet on
   * mobile so it escapes the clip and stays fully visible/tappable. */
  .md-export-dropdown {
    position: fixed;
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    min-width: 0;
    border-radius: 12px 12px 0 0;
    box-shadow: 0 -8px 28px rgba(0, 0, 0, 0.55);
    z-index: 3000;
    padding-bottom: env(safe-area-inset-bottom);
  }

  /* Card-name preview is tap-driven on phones. Suppress native selection and
   * callouts so Safari cannot replace that first tap with text/image UI. */
  [data-card] {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
  }

  /* Current Goldfish root (the stale .rules-arena-solo variants were retired). */
  .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .pt-btn { min-height: 44px; }

  /* =======================================================================
   * Phase 1 — semantic Goldfish phone composition
   *
   * app.js owns the mode decision and stamps data-pt-layout before it renders
   * children.  Keep this last so old width-only Goldfish rules cannot turn the
   * inert inline rail back into a second phone sheet.  The live root remains
   * the one renderer; Tools and Settings are registered body-portal dialogs.
   * ===================================================================== */
  @media (max-width: 767px), (max-width: 932px) and (max-height: 500px) {
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) {
      position: fixed;
      inset: var(--pt-vv-top, 0) auto auto var(--pt-vv-left, 0);
      display: grid !important;
      grid-template-columns: minmax(0, 1fr);
      grid-template-rows: auto minmax(0, 1fr) auto;
      gap: 6px;
      width: var(--pt-vv-w, 100%);
      height: var(--pt-vv-h, 100dvh);
      min-height: 0;
      padding: max(6px, env(safe-area-inset-top))
               max(6px, env(safe-area-inset-right))
               max(6px, env(safe-area-inset-bottom))
               max(6px, env(safe-area-inset-left));
      overflow: hidden;
      overscroll-behavior: none;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) > .cob-solo-top.cob-topbar {
      position: relative;
      inset: auto;
      grid-column: 1;
      grid-row: 1;
      min-width: 0;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-topbtns .cob-tool-icon {
      width: 44px;
      min-width: 44px;
      height: 44px;
      min-height: 44px;
      padding: 0;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-bf-solo {
      grid-column: 1;
      grid-row: 2;
      min-width: 0;
      min-height: 0;
      overflow: auto;
      overscroll-behavior: contain;
      -webkit-overflow-scrolling: touch;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-stage,
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-bf {
      min-height: clamp(260px, 44dvh, 360px);
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock {
      grid-column: 1;
      grid-row: 3;
      position: relative;
      inset: auto;
      z-index: 105;
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 6px;
      padding: 6px 6px max(6px, env(safe-area-inset-bottom));
      border: 1px solid var(--bronze-dim);
      border-radius: 13px;
      background: rgba(5, 8, 11, .97);
      box-shadow: 0 -10px 30px rgba(0, 0, 0, .62);
    }
    .cob-v3.pt-solo[data-pt-layout="widePhone"] .cob-solo-dock[data-pt-action-count="4"] {
      grid-template-columns: repeat(4, minmax(0, 1fr));
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock .pt-btn {
      min-width: 0;
      min-height: 48px;
      margin: 0;
      padding: 7px 8px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-life-control .pt-life-btn {
      width: 44px;
      min-width: 44px;
      height: 44px;
      min-height: 44px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-rail,
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-rail-scrim {
      /* The persistent rail is deliberately inert on phones.  Do not make it
         a transformed/fixed sheet: the registered dialog below is the only
         interactive Tools surface. */
      display: none !important;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-rail {
      position: static;
      inset: auto;
      transform: none;
    }

    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-dialog--sheet.cob-solo-tools-sheet,
    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-dialog--sheet.cob-solo-settings-sheet,
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-help-dialog {
      width: 100%;
      max-width: none;
      max-height: calc(100dvh - env(safe-area-inset-top));
      border-right: 0;
      border-bottom: 0;
      border-left: 0;
      border-radius: 18px 18px 0 0;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-inspector-figure {
      grid-template-columns: 1fr;
      justify-items: center;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-inspector-figure img {
      width: min(100%, 270px);
      max-height: 52dvh;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-dialog--sheet .arena-dialog-body {
      min-height: 0;
      padding: 12px;
      overscroll-behavior: contain;
      -webkit-overflow-scrolling: touch;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog {
      position: static;
      display: flex;
      flex-direction: column;
      gap: 10px;
      width: 100%;
      min-width: 0;
      padding: 0;
      overflow: visible;
      border: 0;
      background: transparent;
      box-shadow: none;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog > * { width: 100%; }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-solo-session {
      display: grid;
      grid-template-columns: 44px minmax(0, 1fr);
      align-items: center;
      gap: 9px;
      padding: 9px;
      border: 1px solid var(--bronze-soft);
      border-radius: 12px;
      background: linear-gradient(180deg, rgba(25, 34, 44, .96), rgba(10, 15, 20, .96));
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-solo-session-art {
      width: 44px;
      height: 44px;
      border: 1px solid var(--bronze);
      border-radius: 9px;
      object-fit: cover;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-solo-session-copy { min-width: 0; }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-solo-session-copy strong {
      display: block;
      overflow: hidden;
      color: var(--text);
      font-size: 13px;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-solo-status {
      display: block;
      margin-top: 2px;
      color: var(--muted);
      font-size: 11px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-solo-primary .pt-btn,
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-tools .pt-btn {
      width: 100%;
      min-height: 44px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-summary,
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-tools {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 6px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-summary > span {
      min-width: 0;
      padding: 8px;
      border: 1px solid rgba(142, 109, 52, .28);
      border-radius: 9px;
      color: var(--muted);
      font-size: 11px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-summary b {
      display: block;
      color: var(--gold);
      font-size: 16px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-solo-coach,
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-solo-journal {
      min-height: 96px;
      padding: 10px;
      overflow: hidden;
      border: 1px solid rgba(142, 109, 52, .34);
      border-radius: 12px;
      background: rgba(8, 12, 16, .72);
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-switch {
      justify-content: center;
      min-width: 44px;
      min-height: 44px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-solo-coach-body,
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-solo-journal-list {
      max-height: 28dvh;
      overflow-y: auto;
      overscroll-behavior: contain;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-solo-toolgroup {
      border-top: 1px solid rgba(255, 255, 255, .08);
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-solo-toolgroup > summary {
      display: flex;
      align-items: center;
      min-height: 44px;
      color: var(--gold);
      cursor: pointer;
      font-size: 11px;
      font-weight: 800;
      letter-spacing: .1em;
      text-transform: uppercase;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-solo-toolgroup > summary::-webkit-details-marker { display: none; }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-tools-dialog .cob-solo-toolgroup:not([open]) > .cob-tools { display: none; }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-settings-sheet .cob-settings,
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-settings-sheet .cob-settings-pop {
      position: static;
      width: auto;
      max-height: none;
      margin: 0;
      padding: 10px 12px;
      border: 1px solid var(--bronze-soft);
      border-radius: 12px;
      background: #0c1117;
      box-shadow: none;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-settings-sheet .cob-set-h {
      display: flex;
      align-items: center;
      gap: 6px;
      margin-bottom: 8px;
      color: var(--gold);
      font-size: 11px;
      font-weight: 800;
      letter-spacing: .12em;
      text-transform: uppercase;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-settings-sheet .cob-set-h2 { margin-top: 14px; }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-settings-sheet .cob-set-row {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 10px;
      min-height: 44px;
      padding: 6px 0;
      color: var(--text);
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-settings-sheet .cob-set-txt {
      display: flex;
      flex-direction: column;
      min-width: 0;
      font-size: 13px;
      font-weight: 600;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-settings-sheet .cob-set-txt small {
      color: var(--muted);
      font-size: 11px;
      font-weight: 400;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-settings-sheet .cob-set-row input {
      width: 24px;
      height: 24px;
      accent-color: var(--gold);
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-settings-sheet .cob-bg-grid {
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 8px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-settings-sheet .cob-bg-sw {
      position: relative;
      min-height: 48px;
      overflow: hidden;
      border: 2px solid rgba(255, 255, 255, .1);
      border-radius: 9px;
      background-position: center !important;
      background-size: cover !important;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-settings-sheet .cob-bg-sw.is-on {
      border-color: var(--gold);
      box-shadow: 0 0 0 2px var(--gold), 0 0 14px #d9af5d77;
    }
  }

  /* Very small phones (<=380px): tighten the nav tabs so more fit per swipe. */
  @media (max-width: 380px) {
    .nav-tab { padding: 8px 10px; font-size: 13px; }
    .view { padding: 14px 10px; }
  }

  /* Goldfish phone command surface — matches the compact physical-table
     hierarchy: status at the top, cards in the middle, five stable actions at
     the bottom. These selectors intentionally do not affect tablet/desktop. */
  @media (max-width: 767px), (max-width: 932px) and (max-height: 500px) {
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) > .cob-solo-mobile-top {
      display: grid;
      grid-template-columns: minmax(0, 1fr);
      gap: 0;
      padding: 6px 7px 7px;
      border-color: rgba(165, 113, 57, .72);
      border-radius: 12px;
      background: linear-gradient(180deg, rgba(13, 19, 24, .98), rgba(5, 9, 12, .98));
      box-shadow: 0 6px 22px rgba(0, 0, 0, .32);
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-mobile-main {
      position: relative;
      display: grid;
      /* Last column is auto, not a fixed 44px: .cob-solo-topbtns can now hold the
         exit button PLUS the reset-to-fit zoom button (44px each + gap), and the
         name column (minmax(0,1fr)) is what actually shrinks/ellipsizes to make
         room, instead of the topbtns box overflowing its old fixed track. */
      grid-template-columns: 42px minmax(0, 1fr) auto auto auto;
      align-items: center;
      gap: 6px;
      min-width: 0;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-mobile-art {
      display: block;
      width: 42px;
      height: 42px;
      border: 1px solid var(--bronze);
      border-radius: 8px;
      background: #080c10;
      object-fit: cover;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-mobile-name {
      min-width: 0;
      overflow: hidden;
      color: #e6bf69;
      font-family: "Cormorant Garamond", Georgia, serif;
      font-size: clamp(16px, 5vw, 22px);
      line-height: 1;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    /* Turn / life / exit share one chip family: 34px tall, matched border,
       radius and dark-bronze fill, so the top row reads as a deliberate set
       instead of a boxed pill next to a bare number next to a heavy button. */
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-mobile-turn {
      display: inline-flex;
      /* Center, not baseline: with mixed 12px/17px type, baseline alignment
         hung the whole "TURN 1" group off-center inside the fixed 34px chip
         (batch 4 owner report). line-height:1 keeps the serif's tall line box
         from re-introducing the offset; matches the life chip's centering. */
      align-items: center;
      gap: 4px;
      align-self: center;
      height: 34px;
      padding: 0 10px;
      line-height: 1;
      border: 1px solid rgba(165, 113, 57, .46);
      border-radius: 9px;
      background: rgba(22, 16, 9, .55);
      color: var(--gold);
      font-family: "Cormorant Garamond", Georgia, serif;
      font-size: 12px;
      font-weight: 800;
      letter-spacing: .04em;
      text-transform: uppercase;
      white-space: nowrap;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-mobile-turn strong { font-size: 17px; line-height: 1; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-mobile-life {
      display: inline-flex;
      align-items: center;
      gap: 5px;
      align-self: center;
      height: 34px;
      padding: 0 11px;
      border: 1px solid rgba(165, 113, 57, .34);
      border-radius: 9px;
      background: rgba(22, 16, 9, .55);
      color: #edf0f3;
      font-family: "Cormorant Garamond", Georgia, serif;
      font-size: 20px;
      font-weight: 800;
      white-space: nowrap;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-mobile-life .ti { color: #e0555f; font-size: 14px; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-mobile-metrics {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 8px;
      min-width: 0;
      margin-top: 6px;
      padding-top: 6px;
      border-top: 1px solid rgba(165, 113, 57, .26);
      color: #c7c9cb;
      font-family: "Cormorant Garamond", Georgia, serif;
      font-size: 13px;
      white-space: nowrap;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-mobile-metrics b { color: #f0f1f2; }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-mobile-metrics > i {
      width: 3px;
      height: 3px;
      border-radius: 50%;
      background: #d2a34f;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-mobile-top .cob-solo-exit {
      width: 44px !important;
      min-width: 44px !important;
      height: 44px !important;
      min-height: 44px !important;
      align-self: center;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      border: 1px solid rgba(165, 113, 57, .4);
      border-radius: 9px;
      background: rgba(22, 16, 9, .62);
      color: #e7e9ec;
      font-size: 18px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-mobile-top .cob-solo-exit:hover,
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-mobile-top .cob-solo-exit:active {
      border-color: rgba(201, 74, 74, .68);
      background: rgba(42, 17, 17, .72);
      color: #ef6461;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-turn-marker {
      visibility: hidden;
      opacity: 0;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-console { margin-top: auto; }

    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock,
    .cob-v3.pt-solo[data-pt-layout="widePhone"] .cob-solo-dock[data-pt-action-count="7"] {
      /* Seven items (Next Turn · Action · Decks · Draw · 🔮 · ↩ · ⚙). Every
         column keeps a 44px floor so the touch-target contract holds even at the
         narrowest tested phone (320px); Next Turn (now FIRST — David's order)
         gets the extra slack via fr. gap:1px + 1px inline padding keeps 7×44
         fitting inside a 320px viewport and tightens the trailing icon cluster. */
      grid-template-columns: minmax(44px, 1.4fr) minmax(44px, 1fr) minmax(44px, 1fr) minmax(44px, 1fr) repeat(3, minmax(44px, .82fr));
      gap: 1px;
      padding: 5px 1px max(5px, env(safe-area-inset-bottom));
      border-color: rgba(165, 113, 57, .56);
      background: rgba(5, 8, 11, .985);
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock .cob-solo-dock-item {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 3px;
      min-height: 54px;
      padding: 5px 2px;
      overflow: hidden;
      border-color: rgba(165, 113, 57, .42);
      border-radius: 8px;
      font-family: "Cormorant Garamond", Georgia, serif;
      font-size: 15px;
      line-height: 1;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock .cob-solo-dock-glyph {
      min-height: 23px;
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Symbol", "Apple Color Emoji", sans-serif;
      font-size: 23px;
      line-height: 23px;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock .cob-solo-dock-icon-only {
      /* Batch 4 (owner): icon buttons sit in the SAME button chrome as the
         dock's text buttons — no transparent-box treatment ("they look like
         they're just hanging there"). Only the glyph/svg sizing and the 44px
         min-width differ; background/border/radius inherit from
         .cob-solo-dock-item + .pt-btn exactly like Action/Decks/Draw. Full row
         height (54px) keeps the strict ≥44 touch contract sub-pixel-safe. */
      min-width: 44px;
      padding-inline: 4px;
    }
    /* Hover feedback is pointer-hover ONLY: on iOS, :hover sticks after a tap,
       which left the last-tapped icon (David's screenshot: undo) in a stuck
       highlight unlike its neighbours. Touch devices get no hover state at all;
       keyboard focus keeps its visible ring via :focus-visible. */
    @media (hover: hover) {
      .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock .cob-solo-dock-icon-only:not(:disabled):hover {
        color: #f1cc76;
        background: rgba(209, 163, 79, .08) !important;
      }
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock .cob-solo-dock-icon-only:not(:disabled):focus-visible {
      color: #f1cc76;
      background: rgba(209, 163, 79, .08) !important;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock .cob-solo-dock-svg {
      width: 27px;
      height: 27px;
      fill: none;
      stroke: currentColor;
      stroke-width: 2;
      stroke-linecap: round;
      stroke-linejoin: round;
    }
    .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock .cob-solo-dock-next {
      background: linear-gradient(180deg, #e9c46f, #c99a3e);
      color: #171006;
      font-weight: 900;
    }
    @media (max-width: 380px) {
      .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock .cob-solo-dock-item {
        font-size: 12px;
      }
    }
    /* Ultra-narrow phones (~320px): the seven 44px touch targets no longer fit
       inside the root's 6px side padding (7×44 = 308 > the ~304px the inset dock
       gets). Bleed the dock to the root's padding-box edges and drop the gap so
       every button keeps its 44px floor without spilling the page. Surgical to
       the dock — the rest of the layout keeps its 6px inset. */
    @media (max-width: 340px) {
      .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-dock {
        margin-inline: -4px;
        gap: 0;
        padding-inline: 0;
      }
    }

    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-decks-dialog .cob-piles {
      display: grid;
      grid-template-columns: repeat(4, minmax(0, 1fr));
      gap: 7px;
      width: 100%;
      margin: 0;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-decks-dialog .pt-tile {
      min-width: 0;
      min-height: 100px;
      padding: 7px 4px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-decks-dialog .pt-tile-h {
      overflow: hidden;
      font-size: 10px;
      text-overflow: ellipsis;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-decks-dialog .pt-pile {
      width: min(58px, 100%);
      height: 68px;
    }

    .arena-dialog-layer[data-arena-mode="goldfish"] .arena-dialog--sheet.cob-solo-oracle-sheet { max-height: min(76dvh, 620px); }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-action-dialog,
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-oracle-dialog {
      display: flex;
      flex-direction: column;
      gap: 12px;
      min-width: 0;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-action-group {
      padding: 10px;
      border: 1px solid rgba(142, 109, 52, .34);
      border-radius: 12px;
      background: rgba(8, 12, 16, .72);
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-action-group h3 {
      margin: 0 0 8px;
      color: var(--gold);
      font-size: 11px;
      letter-spacing: .11em;
      text-transform: uppercase;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-action-dialog .cob-tools,
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-settings-cheats,
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-oracle-mode {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 7px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-action-dialog .pt-btn,
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-settings-cheats .pt-btn,
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-oracle-mode .pt-btn { min-height: 44px; }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-life-actions > div {
      display: grid;
      grid-template-columns: 56px 1fr 56px;
      align-items: center;
      gap: 8px;
      text-align: center;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-life-actions strong {
      color: #f2d486;
      font-family: "Cormorant Garamond", Georgia, serif;
      font-size: 30px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-action-dialog .cob-solo-journal {
      min-height: 110px;
      max-height: 28dvh;
      overflow: hidden;
      border: 1px solid rgba(142, 109, 52, .34);
      border-radius: 12px;
      background: rgba(8, 12, 16, .72);
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-action-dialog .cob-solo-journal-list {
      margin: 0;
      padding: 6px 10px 10px;
      max-height: 22dvh;
      overflow-y: auto;
      list-style: none;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-action-dialog .cob-solo-journal-list li {
      display: grid;
      grid-template-columns: auto minmax(0, 1fr);
      gap: 8px;
      padding: 6px 2px;
      color: #d8dde2;
      font-size: 12px;
      line-height: 1.35;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-action-dialog .cob-solo-journal-list li + li {
      border-top: 1px solid rgba(255, 255, 255, .06);
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-oracle-dialog .cob-solo-coach {
      display: flex;
      flex-direction: column;
      gap: 12px;
      min-height: 230px;
      padding: 14px;
      border: 1px solid rgba(142, 109, 52, .5);
      border-radius: 14px;
      background: radial-gradient(circle at 50% 0, rgba(52, 60, 93, .35), transparent 55%), rgba(8, 12, 16, .92);
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-oracle-dialog .cob-solo-coach-head {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 8px;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-oracle-dialog .cob-solo-coach-title,
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-oracle-dialog .cob-solo-coach-mode {
      color: var(--gold);
      font-size: 11px;
      font-weight: 800;
      letter-spacing: .1em;
      text-transform: uppercase;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-oracle-dialog .cob-solo-coach-body {
      flex: 1 1 auto;
      min-height: 0;
      max-height: 36dvh;
      overflow-y: auto;
    }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-oracle-dialog .cob-solo-coach-text { margin: 0; line-height: 1.55; }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-solo-oracle-dialog .cob-solo-coach-go { min-height: 44px; }
    .arena-dialog-layer[data-arena-mode="goldfish"] .cob-set-note {
      margin: 7px 0 0;
      color: var(--muted);
      font-size: 11px;
      line-height: 1.4;
    }
    @media (max-height: 500px) {
      .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) > .cob-solo-mobile-top { padding-block: 4px; }
      .cob-v3.pt-solo:is([data-pt-layout="compactPhone"], [data-pt-layout="widePhone"]) .cob-solo-mobile-metrics { display: none; }
    }
  }
}
