/* auth-trial-board.css — the trial board living inside /auth.
 *
 * Loaded LAST on auth.html, after game-v2.css / trial-mode.css / auth-felt.css /
 * auth-lucky-jack.css. Everything here is scoped under `body.lj-auth` so it cannot
 * reach /game or /campaign, which share game-v2.css and keep their own layout.
 *
 * ---- Structure this file assumes (see auth.html) ----
 *   body.trial-page.lj-auth
 *     #root                      <- the board. A DIRECT CHILD OF BODY, full-viewport,
 *                                   z-index 0. Deliberately NOT inside a
 *                                   section[data-screen]:
 *                                     (a) renderFromState wipes #root, so no auth
 *                                         markup may live in it;
 *                                     (b) a display:none subtree has zero-size rects
 *                                         and instant-reveal.js measures the board in
 *                                         the same event it renders;
 *                                     (c) it keeps the board outside the
 *                                         section[data-screen] token scope below.
 *     .bja-felt                  <- oxblood backdrop for screens 02-23 only
 *     section[data-screen]       <- all 17 auth screens, overlaying the board
 *
 * ---- The two body-class states ----
 *   (no class)          landing is active: board visible, felt hidden
 *   .lj-board-hidden    any other screen:  board + every board-owned fixed layer
 *                       hidden, felt visible. Toggled by auth-flow.js#activateScreen.
 */

/* ===== Token scope ======================================================
 * game-v2.css and auth-felt.css both declare --brass/--vellum/--ink/etc at
 * :root with DIFFERENT values, so source order alone decides them globally.
 * game-v2.css loads later and wins :root, which is what the board wants.
 * The auth screens take their palette back here at (0,1,1), which beats
 * :root (0,1,0) regardless of order. The board is outside this selector by
 * construction, so it keeps game-v2's values.
 * ====================================================================== */
/* `body` itself is outside the scope below by construction (the board is a body
   child), so inherited text would resolve --vellum against game-v2's :root
   (#f4f0e8) while tokened text inside the sections got auth's #ece3cf — two
   near-identical creams that no longer match. Pin the inherited one. */
body.lj-auth {
  color: #ece3cf;
  /* Height of the sign-in bar, per regime. The interactive cluster is anchored
     off THIS rather than a viewport percentage — see the desktop block. Keep in
     sync if a bar's contents change height. */
  --lj-bar-h: 244px;
}

body.lj-auth section[data-screen],
body.lj-auth .bja-felt {
  --brass:      #c9a24a;
  --brass-hi:   #f4d680;
  --brass-lo:   #5a4418;
  --vellum:     #ece3cf;
  --vellum-dim: rgba(236, 227, 207, 0.55);
  --iron-edge:  #2a2a30;
  --ink:        #1a1410;
}

/* ===== Board placement ================================================== */
body.lj-auth #root {
  position: fixed;
  inset: 0;
  z-index: 0;
}
/* The board's own page shell must not paint over the casino backdrop, and must
   not scroll independently. trial-mode.css already makes .gv2-page transparent
   under body.trial-page; this pins the box. */
body.lj-auth .gv2-page {
  min-height: 100vh;
  min-height: 100dvh;
  height: 100dvh;
  max-height: 100dvh;
  overflow: hidden;
}

/* Auth screens sit above the board. */
body.lj-auth section[data-screen] { position: relative; z-index: 20; }
body.lj-auth .bja-felt { z-index: 10; }

/* On the landing the casino scene IS the backdrop, so the oxblood felt retires.
   :not() keeps this to the landing state only — screens 02-23 keep the felt. */
body.lj-auth:not(.lj-board-hidden) .bja-felt { display: none; }

/* ===== Leaving the landing =============================================
 * ONE structural gate. Board-owned layers mount on document.body, OUTSIDE
 * #root, at z-index 5000-10000 — so hiding #root alone leaves all of them
 * floating over the phone form. The list below is the authoritative one; it is
 * deliberately not counted in prose, because every previous version of this
 * comment carried a tally that went stale the next time a layer was added.
 *
 * Each selector below is verified against the source that creates it; an
 * invented class name fails silently and is indistinguishable from a working
 * gate until you actually navigate mid-animation:
 *   .trial-coach          trial-engine.js:82
 *   .gv2-flight           render-deal-animation.js:262
 *   .gv2-fly              render-deal-animation.js:1232 (FH slam)
 *   .gv2-ir-fly           instant-reveal.js:130
 *   .gv2-overlay-chooser  chooser-sw.js:224, chooser-fc.js:147
 *   .gv2-co               countdown-overlay.js:296  <- NOT .gv2-countdown-overlay
 *   .gv2-toast            game-ui.js:131
 *   .gv2-match-closed     game-ui.js:2622
 *   .trial-matchend       trial-matchend.js:80 AND auth-flow.js#openGuestPanel
 *                         (gated by CLASS, not #id — the guest panel reuses the
 *                         class and would otherwise escape)
 *   .fx-float/.fx-particles/.fx-confetti-box   effects-manager.js, z 9997-9999.
 *                         Reachable, not theoretical: the fixture ends 3-2 to
 *                         the local player and game-ui.js:1642 fires confetti on
 *                         exactly that, so leaving the landing at match end
 *                         rained confetti over the phone form.
 * ===================================================================== */
body.lj-auth.lj-board-hidden #root,
body.lj-auth.lj-board-hidden .trial-coach,
body.lj-auth.lj-board-hidden .gv2-flight,
body.lj-auth.lj-board-hidden .gv2-fly,
body.lj-auth.lj-board-hidden .gv2-ir-fly,
body.lj-auth.lj-board-hidden .gv2-overlay-chooser,
body.lj-auth.lj-board-hidden .gv2-co,
body.lj-auth.lj-board-hidden .gv2-toast,
body.lj-auth.lj-board-hidden .gv2-match-closed,
body.lj-auth.lj-board-hidden .trial-matchend,
body.lj-auth.lj-board-hidden .fx-float,
body.lj-auth.lj-board-hidden .fx-particles,
body.lj-auth.lj-board-hidden .fx-confetti-box,
/* .fx-coin-shower (effects-manager.js:193) is unreachable today — its only
   caller is economy-ui.js, which this page does not load. Listed anyway: the
   whole point of a structural gate is that it does not depend on which callers
   happen to be wired up this week. */
body.lj-auth.lj-board-hidden .fx-coin-shower,
body.lj-auth.lj-board-hidden .ljb-chrome { display: none !important; }

/* The landing's guest sign-up panel must outrank BOTH things that can bury it:
   the demo's match-end card (`.trial-matchend`, z 5000, appended later in DOM
   order so it wins an equal-z tie) and the board's body-mounted animation
   layers — flights and instant-reveal at 9400, toast 9500, coach 9600 — which
   outrank 5000 by thousands. Sitting above the lot is one fix for both, and it
   lets the demo keep running underneath instead of being killed to get out of
   the way (which stranded anyone who backed out on a dead board). */
body.lj-auth #lj-guest-panel { z-index: 10050; }
/* Dismiss control, a sibling of the card so it survives signup.open()'s
   innerHTML swap and is reachable at every step of the form. */
body.lj-auth .lj-guest-close {
  position: absolute; top: 18px; right: 18px; z-index: 1;
  width: 42px; height: 42px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(236, 227, 207, .35);
  background: rgba(14, 10, 16, .8); color: #ece3cf;
  font-size: 22px; line-height: 1; cursor: pointer;
}
body.lj-auth .lj-guest-close:hover { border-color: rgba(236, 227, 207, .6); }

/* ===== Board chrome the landing does not want ========================== */
body.lj-auth .gv2-ca-rules,
body.lj-auth .gv2-ca-help,
/* .gv2-hdr-help is the desktop-redesign header's "How to play" link — a
   SEPARATE element from .gv2-ca-help, and .gv2-ph-qc is the Quick chat button.
   Neither has a handler loaded on this page (no quick-rules-panel.js, no chat),
   so both rendered as focusable dead controls ahead of the sign-in CTAs. */
body.lj-auth .gv2-hdr-help,
body.lj-auth .gv2-ph-qc,
body.lj-auth .gv2-log,
body.lj-auth [data-gv2-board-menu],
body.lj-auth .gv2-console-chip,
/* .gv2-pcl-console is the THIRD child of the control bar, sitting between HIT
   and STAND. In the bottom-bar design it fills the middle of a full-width bar;
   in a 384px cluster it ate 186px and squeezed both buttons to 81px, clipping
   "STAND" to "TANI". Not wanted on a landing page either way. */
body.lj-auth .gv2-pcl-console,
body.lj-auth .gv2-pa-spent,
body.lj-auth .gv2-pa-label-spent,
body.lj-auth .gv2-pa[data-gv2-player-area="1"] .gv2-pa-label-actions {
  display: none !important;
}

/* Lucky's action row is now VISIBLE (the label above stays hidden — deliberate
 * asymmetry against seat 0's labelled row). Round 1 he holds [], and portrait
 * collapses an empty row via game-v2.css:4783-4784's min-height:0 — but the
 * desktop block (:8188-8330) has no equivalent, so without these it shows
 * 110px + a 13px label = 123px of empty box for all of round 1.
 * Specificity is (0,6,1) — NOT the (0,4,1) that commit 4's shorter selectors
 * carry. Recount before writing an override against it. */
body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="1"] .gv2-pa-actions,
body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="1"] .gv2-ar-playable { min-height: 0; }

/* ===== Desktop / tablet: relocate the interactive cluster ==============
 * Both relocations are of elements the board pins to the VIEWPORT today.
 * .gv2-pcl is `position:fixed; bottom:0` (game-v2.css:8821) and renders over
 * the sign-in bar at every size; the action row sits bottom-left in flow.
 * They move to the open band beside the local hand — 34% not 50%, because a
 * true centre puts STAND on top of the opponent's cards.
 * ===================================================================== */
@media (min-width: 768px) and (min-height: 501px) {
  /* Scoped to the LOCAL player's controls. The opponent has a .gv2-pcl too — it
     is emptied/hidden by game-v2's desktop rules, but repositioning it as well
     left a zero-size fixed box parked at 0,0. This page is always my-idx 0 (the
     fixture pins it), so player-area="0" is the local seat. */
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="0"] .gv2-pcl {
    position: fixed;
    /* Anchored to the BAR, not to a viewport percentage. `top: 58%` looked fine
       at 900px tall and put HIT/STAND *inside* the 244px bar below ~581px tall —
       a percentage cannot clear a fixed-height element. Measured at 1280x560:
       controls at y292..358 against a bar starting at y317, elementFromPoint
       returning SECTION.lj-landing, and the demo frozen on an await beat with
       the coach reading "Tap STAND". Same failure class as two earlier passes;
       anchoring off --lj-bar-h removes the whole category. */
    bottom: calc(var(--lj-bar-h) + 20px);
    top: auto; left: 34%;
    transform: translateX(-50%);
    right: auto;
    width: 384px; height: auto;
    display: flex; gap: 18px;
    padding-bottom: 0;
    z-index: 5;
  }
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="1"] .gv2-pcl {
    display: none;
  }
  /* The bottom-bar design welds the two halves into edge slabs (square inner
     corners, no border, gradient bleed off the page edge). Re-form them into
     discrete buttons. */
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-cb {
    flex: 1 1 0; min-height: 0;
    height: 66px; padding: 0;
    border-radius: 8px;
    border: 1px solid rgba(201, 162, 74, .6);
    background: rgba(14, 10, 16, .82);
    box-shadow: 0 10px 34px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .07);
    display: flex; align-items: center; justify-content: center;
  }
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-cb-hit {
    border-color: rgba(214, 120, 120, .75);
  }
  body.lj-auth .gv2-cb-hit .gv2-cb-label { color: #ffd9d0; }

  /* Stacked upward off the same anchor: controls occupy bar+20 .. bar+86, so
     the action row starts above that and the label above the row. */
  body.lj-auth .gv2-pa[data-gv2-player-area="0"] .gv2-pa-actions {
    position: fixed;
    bottom: calc(var(--lj-bar-h) + 104px);
    top: auto; left: 34%;
    transform: translateX(-50%);
    z-index: 6;
    margin: 0; padding: 0;
    justify-content: center;
  }
  body.lj-auth .gv2-pa[data-gv2-player-area="0"] .gv2-pa-label-actions {
    position: fixed;
    bottom: calc(var(--lj-bar-h) + 236px);
    top: auto; left: 34%;
    transform: translateX(-50%);
    z-index: 6;
    margin: 0; white-space: nowrap;
  }

  /* Keep the board clear of the sign-in bar. */
  body.lj-auth .gv2-page { padding-bottom: 210px; }
}

/* ===== Portrait — DELIBERATELY MINIMAL ================================
 * The mockup proposed collapsing each player area into one compact row
 * (score, name, state, cards side by side, slack spread evenly).
 *
 * Three attempts at that via CSS override each traded one defect for another.
 * Two were the same mistake: game-v2's portrait rules are
 * `.gv2-page:not([data-mode="campaign"]) .gv2-pa` = (0,3,0), so anything
 * written `body.lj-auth .gv2-pa` (0,2,0) loses SILENTLY inside this media
 * query. The third landed but collapsed .gv2-pa-row to a column, stacking
 * PlayerHeader, the bank chip and StatusRibbon on top of each other.
 *
 * The board's portrait layout is a designed, shipped thing. Rather than
 * re-derive it blind against 9,000 lines of stylesheet, this keeps it and does
 * only what the merge REQUIRES: free the bottom strip for the sign-in bar, get
 * the controls out of their viewport-pinned bar and into flow, and scale the
 * cards up. A true compact-row portrait board is a change to the BOARD, not an
 * /auth override, and belongs in its own pass with its own review.
 *
 * Logged as debt: docs/NUTS/2026-07-18-auth-trial-unified-front-door/.
 * ===================================================================== */
/* Portrait phones AND short landscape phones. The desktop block above is gated
   on (min-width:768px) and (min-height:501px); a landscape phone (667x375,
   844x390) matched NEITHER that nor a portrait-only query, so it fell through
   to the base rules: three 262px-min buttons in a centred row = 786px of
   buttons in a 667px viewport, clipped 75px off each edge by the landing's
   inherited `overflow-x: clip` — the primary CTA was partly unreachable — with
   HIT/STAND behind the sign-in bar and a 250px wordmark across the hand. */
/* Exact complement of the desktop block above. Written as
   `(max-width:767px) and (orientation:portrait), (orientation:landscape) and (max-height:500px)`
   it left a hole: <=767px wide, landscape, >=501px tall (767x501, Surface Duo
   landscape, a narrow desktop window) matched NEITHER block and fell through to
   the base rules, reproducing the very clipping this file exists to fix. */
@media (max-width: 767.98px), (max-height: 500.98px) {
  body.lj-auth { --lj-bar-h: 198px; }
  /* Reserve the bottom strip for the sign-in bar. The board keeps its own
     internal layout above it. */
  body.lj-auth .gv2-page:not([data-mode="campaign"]) {
    padding-bottom: 236px;
  }

  /* Cards scale up so the space fills with content rather than gap.
     PlayingCard writes --pc-w/--pc-h as an INLINE style on each .gv2-pc
     (components/PlayingCard.js:54), and an inline custom property beats any
     stylesheet rule set on an ancestor. The override has to land on the card
     element itself, with !important, or it is silently ignored. */
  /* The fan is `min-height:99px; height:auto; overflow-y:hidden`
     (game-v2.css:4748) and is a flex item in a centred row, so it never grows
     to fit a taller card — a 121px card in a 99px box was clipped 22px, losing
     the bottom border and the corner index. Raise the floor with the card. */
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="0"] .gv2-pa-fan {
    min-height: 121px;
  }
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="0"] .gv2-pa-fan .gv2-pc {
    --pc-w: 86px !important;
    --pc-h: 121px !important;
    --pc-pip: 52px !important;
  }
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="1"] .gv2-pa-fan .gv2-pc {
    --pc-w: 68px !important;
    --pc-h: 96px !important;
    --pc-pip: 41px !important;
  }

  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-cb {
    flex: 1 1 0; min-height: 0;
    height: 56px; padding: 0;
    border-radius: 8px;
    border: 1px solid rgba(201, 162, 74, .6);
    background: rgba(14, 10, 16, .86);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .62);
    display: flex; align-items: center; justify-content: center;
  }
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-cb-hit {
    border-color: rgba(214, 120, 120, .78);
  }
  body.lj-auth .gv2-cb-hit .gv2-cb-label { color: #ffd9d0; }
}

/* ===== Brand + live badge (board-owned chrome, hidden off-landing) ====== */
body.lj-auth .ljb-chrome { position: fixed; inset: 0; z-index: 15; pointer-events: none; }
body.lj-auth .ljb-mark { position: absolute; top: 24px; left: 34px; }
body.lj-auth .ljb-mark img {
  width: 250px; height: auto; display: block;
  filter: drop-shadow(0 4px 20px rgba(0, 0, 0, .9));
}
body.lj-auth .ljb-tag {
  position: absolute; top: 132px; left: 36px;
  color: #c9a24a; font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: .32em; text-transform: uppercase;
  text-shadow: 0 2px 12px rgba(0, 0, 0, .95);
}
body.lj-auth .ljb-live {
  position: absolute; top: 26px; right: 32px;
  display: inline-flex; align-items: center; gap: 9px;
  padding: 9px 16px; border-radius: 999px;
  border: 1px solid rgba(201, 162, 74, .5); background: rgba(9, 9, 11, .72);
  color: #ece3cf; font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: .24em; text-transform: uppercase;
}
body.lj-auth .ljb-live i {
  width: 7px; height: 7px; border-radius: 50%; background: #c9a24a;
  display: block; box-shadow: 0 0 9px rgba(201, 162, 74, .7);
}
body.lj-auth .ljb-live[data-state="live"] i { background: #5ed17f; box-shadow: 0 0 9px #5ed17f; }
body.lj-auth .ljb-live[data-state="unavailable"] i { background: #a56b68; box-shadow: none; }

/* Optional demo controls sit outside .ljb-chrome so they keep pointer events. */
body.lj-auth .ljb-audio {
  position: fixed; top: 68px; right: 32px; z-index: 46;
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
}
body.lj-auth .ljb-mute { position: static; }
body.lj-auth .ljb-volume {
  display: grid; grid-template-columns: auto 92px 34px; align-items: center; gap: 8px;
  min-height: 34px; padding: 5px 10px 5px 12px;
  border: 1px solid rgba(201, 162, 74, .58); border-radius: 999px;
  background: rgba(9, 9, 11, .78); box-shadow: 0 8px 24px rgba(0, 0, 0, .34);
  color: #ece3cf;
}
body.lj-auth .ljb-volume-label,
body.lj-auth .ljb-volume output {
  font-family: 'JetBrains Mono', monospace; text-transform: uppercase;
  font-size: 9px; letter-spacing: .12em;
}
body.lj-auth .ljb-volume-label { color: #b8a98c; }
body.lj-auth .ljb-volume output { color: #f4d680; letter-spacing: 0; text-align: right; }
body.lj-auth .ljb-volume input[type="range"] {
  width: 92px; margin: 0; accent-color: #c9a24a; cursor: pointer;
}
body.lj-auth .ljb-volume input[type="range"]:focus-visible {
  outline: 2px solid #ffd873; outline-offset: 3px; border-radius: 999px;
}
body.lj-auth .ljb-welcome {
  position: fixed; inset: 0; z-index: 40;
  display: grid; place-items: center;
  padding: max(20px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right))
           max(20px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  background: rgba(4, 5, 5, .48);
  backdrop-filter: blur(3px);
}
body.lj-auth .ljb-welcome[hidden] { display: none !important; }
body.lj-auth .ljb-welcome-card {
  width: min(390px, 100%); max-height: min(420px, calc(100dvh - 40px)); overflow: auto;
  padding: 30px 30px 26px; text-align: center;
  border: 1px solid rgba(215, 181, 100, .72); border-radius: 18px;
  background:
    linear-gradient(145deg, rgba(31, 28, 24, .98), rgba(13, 14, 14, .98));
  box-shadow: 0 28px 80px rgba(0, 0, 0, .62), inset 0 1px 0 rgba(255, 244, 213, .08);
  color: #ece3cf;
}
body.lj-auth .ljb-welcome h1 {
  margin: 0; color: #f3e8cc;
  font-family: 'Cormorant Garamond', serif; font-size: clamp(31px, 4vw, 40px);
  font-weight: 600; line-height: 1; letter-spacing: -.02em;
}
body.lj-auth .ljb-welcome p {
  margin: 12px auto 22px; color: #bfb39d;
  font-family: Inter, sans-serif; font-size: 14px; line-height: 1.5;
}
body.lj-auth .ljb-welcome-actions { display: grid; gap: 10px; }
body.lj-auth .ljb-welcome button {
  min-height: 46px; border-radius: 10px; cursor: pointer;
  font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
}
body.lj-auth .ljb-welcome-play {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  border: 1px solid #e1bd63;
  background: linear-gradient(180deg, #d8b354, #a97a28); color: #17110b;
  box-shadow: inset 0 1px 0 rgba(255, 248, 214, .42), 0 10px 26px rgba(0, 0, 0, .3);
}
body.lj-auth .ljb-welcome-guest {
  border: 1px solid rgba(215, 181, 100, .48); background: rgba(255, 255, 255, .025);
  color: #dfcfaa;
}
body.lj-auth .ljb-welcome .ljb-welcome-signin {
  margin: 2px 0 0; color: #9e947f;
  font-family: Inter, sans-serif; font-size: 12px; line-height: 1.5;
}
body.lj-auth .ljb-welcome-signin button {
  min-height: 0; padding: 0; border: 0; border-radius: 0;
  background: transparent; color: #d9bf7a;
  font-family: inherit; font-size: inherit; font-weight: 600;
  letter-spacing: 0; text-transform: none; text-decoration: underline;
  text-underline-offset: 3px;
}
body.lj-auth .ljb-welcome-privacy {
  justify-self: center; color: #9e947f;
  font-family: Inter, sans-serif; font-size: 12px; line-height: 1.5;
  text-underline-offset: 3px;
}
body.lj-auth .ljb-welcome-privacy:focus-visible { outline: 3px solid #f4d680; outline-offset: 3px; }
body.lj-auth .ljb-welcome button:hover { filter: brightness(1.08); }
body.lj-auth .ljb-welcome button:focus-visible { outline: 3px solid #f4d680; outline-offset: 3px; }
body.lj-auth .ljb-welcome button:disabled { cursor: not-allowed; filter: grayscale(.7); opacity: .52; }
@media (max-width: 767.98px), (max-height: 500.98px) {
  body.lj-auth .ljb-audio { top: 44px; right: 12px; gap: 6px; }
  body.lj-auth .ljb-volume { grid-template-columns: auto 76px 30px; gap: 6px; padding-inline: 9px; }
  body.lj-auth .ljb-volume input[type="range"] { width: 76px; }
  body.lj-auth .ljb-welcome-card { width: min(350px, 100%); padding: 24px 22px 20px; }
}
@media (max-height: 500.98px) and (min-width: 480px) {
  body.lj-auth .ljb-audio { top: 8px; flex-direction: row; align-items: center; }
}
body.lj-auth.lj-board-hidden .ljb-audio,
body.lj-auth.lj-board-hidden .ljb-welcome { display: none !important; }

@media (max-width: 767.98px), (max-height: 500.98px) {
  /* The board paints its own "ROUND n" ornament + win pips across the top on
     portrait, so the wordmark cannot sit there too — it landed on top of them.
     Wordmark goes top-LEFT and small; the badges keep the right. */
  body.lj-auth .ljb-mark { top: 9px; left: 10px; right: auto; }
  body.lj-auth .ljb-mark img { width: 104px; }
  body.lj-auth .ljb-tag { display: none; }
  body.lj-auth .ljb-live { top: 10px; right: 12px; padding: 5px 11px; font-size: 8px; }
  body.lj-auth .ljb-live i { width: 5px; height: 5px; }
}

/* ===== Desktop: swap the wordmark and the round/pips ====================
 * On a landing page the brand outranks the demo's score bug, so the wordmark
 * takes the top-centre and the board's ROUND ornament + win pips retreat to
 * the top-left corner. DESKTOP ONLY — see the portrait block above, which
 * documents the collision that left-anchoring the plaque would reopen at
 * <=767.98px wide or <=500.98px tall (the 104px wordmark already owns that
 * corner there). This block is the exact complement of that query, so the two
 * can never both apply.
 *
 * Two specificity regimes are in play here and they are NOT interchangeable:
 *   .ljb-* live in .ljb-chrome, a BODY child outside #root. game-v2 has no
 *   rules for them, so `body.lj-auth .ljb-mark` (0,2,1) is enough — but it
 *   ties the base rule at :329, so this block must stay BELOW it in source
 *   order. Prefixing them with `.gv2-page` would never match at all.
 *   .gv2-* are styled by game-v2 at `.gv2-page:not([data-mode="campaign"]) X`
 *   = (0,3,0), so those overrides MUST carry the full
 *   `body.lj-auth .gv2-page:not([data-mode="campaign"])` (0,4,1) prefix or
 *   they lose SILENTLY — the trap documented at :249-268.
 * ===================================================================== */
@media (min-width: 768px) and (min-height: 501px) {
  /* Wordmark + tagline to centre. .ljb-mark carries no existing transform. */
  body.lj-auth .ljb-mark {
    left: 50%; right: auto;
    transform: translateX(-50%);
  }
  /* Stack the tagline onto two lines under the centred wordmark.
   * WHY: as one 442px line it ran straight across the painted card fan in
   * casino-bg.jpg at 1440x900 (the fan's right edge lands at x~595, the line
   * started at x=499) and the gold-on-card-face had no contrast. Two lines are
   * 220px of ink, so the block clears the fan at every desktop width.
   *
   * `max-width` is the wrap lever and it is deliberately 30px WIDER than the
   * 220px it produces: the wrap point is between "BLACKJACK ·" and "POWERED",
   * and the next word cannot fit in 250px either, so the slack buys ~14%
   * headroom for a wider fallback face without tipping into a THIRD line.
   * Verified identical wrap with the JetBrains Mono webfont blocked.
   *
   * `top` moves 132px -> 126px (this rule overrides the :335 base). The second
   * line at 132px sat on the bright rim of the .gv2-dc deck chip (y=84..186);
   * 6px up puts both lines on flat dark backdrop. The wordmark img box bottoms
   * at 123px but its ink ends ~13px higher, so the lockup still reads spaced.
   * DESKTOP ONLY — portrait sets display:none at :370. */
  body.lj-auth .ljb-tag {
    left: 50%; right: auto;
    transform: translateX(-50%);
    text-align: center;
    top: 126px;
    max-width: 250px;
    line-height: 1.3;
  }

  /* Round + pips to the top-left. BOTH halves below are required; either one
     alone is a broken layout, and the broken half fails SILENTLY.
     (i) The hairlines are `flex:1` and eat all the slack either side of the
     plaque (game-v2.css:8215-8219). `.gv2-hdr-orn` sets no justify-content and
     `.gv2-hdr-orn-plaque` has no margin/flex rule anywhere, so with both lines
     gone the plaque is the sole flex child and left-aligns by default. */
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-hdr-orn-line,
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-hdr-orn-line-rt {
    display: none;
  }
  /* (ii) The win counter is a SECOND row of .gv2-hdr (flex column). It has zero
     CSS rules repo-wide, so the column's `align-items` is the only thing
     positioning it — dropping the hairlines alone leaves the pips centred
     directly UNDER the now-centred wordmark. That collision is invisible to
     hit-testing: #root is z-index:0 (a stacking context) so the whole board
     paints below .ljb-chrome, which is z-index:15 and pointer-events:none.
     Nothing would report it; you would only ever see it in a screenshot.

     max-width also has to go. .gv2-hdr is `max-width:1520px; margin:0 auto`
     (content-box anchored) while .ljb-chrome is `position:fixed; inset:0`
     (viewport anchored). At 1920 that leaves the "top-left" plaque 200px of
     centring gutter + 40px of padding = ~240px from the left edge, against a
     wordmark centred on the viewport. Below 1520 the cap never binds, so no
     amount of checking at 1440x900 can reveal it. Fixed here at the source
     rather than by capping .ljb-chrome, which is shared by the other 16 auth
     screens. */
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-hdr {
    align-items: flex-start;
    max-width: none;
    /* .gv2-hdr is `padding: 20px 0 16px` — zero horizontal — while .gv2-hdr-orn
       is `padding: 0 40px`. So flex-start ALONE lands the win counter at x=0
       (its rounded left edge clipped by the viewport) and the plaque at x=40:
       two "top-left" elements aligned to different edges. Moving the inset up
       to .gv2-hdr applies it to BOTH rows of the flex column. */
    padding-left: 40px;
  }
  /* ...and zero the orn's own left padding so it doesn't double-count to 80px.
     That 40px existed to inset the full-width hairlines, which (i) deletes. */
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-hdr-orn {
    padding-left: 0;
  }
}

/* ===== The landing's sign-in bar =======================================
 * Overrides auth-lucky-jack.css, which centres the landing as a full-height
 * flex column (wordmark -> card fan -> buttons). Here the landing is a bar
 * pinned to the bottom over a full-bleed board.
 * ===================================================================== */
body.lj-auth section.lj-landing[data-screen="01-landing"][data-active="true"] {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  top: auto;
  display: block;
  min-height: 0;
  padding: 64px 32px 26px;
  background: linear-gradient(to top,
    rgba(9, 9, 11, .985) 0%, rgba(9, 9, 11, .96) 42%,
    rgba(9, 9, 11, .78) 68%, rgba(9, 9, 11, 0) 100%);
}

/* Landing furniture that belonged to the old centred design. */
body.lj-auth .lj-fan,
body.lj-auth .lj-brand,
body.lj-auth .lj-grain,
body.lj-auth .lj-toplight,
body.lj-auth .lj-vign { display: none !important; }

body.lj-auth .lj-landing .lj-auth {
  display: flex; flex-direction: row; align-items: center; justify-content: center;
  gap: 16px; width: auto;
}
/* display:contents dissolves the wrapper so phone + email become direct flex
   items of .lj-auth and sit inline with guest. The wrapper only becomes a real
   box in portrait, where the two share a row under the primary CTA. */
@media (min-width: 768px) and (min-height: 501px) {
  body.lj-auth .lj-landing .lj-auth-alt { display: contents; }
}

/* `flex: 0 1 262px` + `min-width: 0`, NOT `min-width: 262px`.
   Three 262px buttons plus two 16px gaps plus the bar's 64px padding needs
   882px, but the desktop block starts at 768px — so on any viewport from
   768-881px the row overflowed and the landing's inherited `overflow-x: clip`
   made the clipped part unreachable, with the primary CTA sitting at x=-25.
   A prior pass diagnosed this as a media-query gap and closed the gap, which
   moved the boundary by 1px and left the defect on the desktop side. The row
   has to be able to SHRINK; a fixed min-width on a flex row in a fixed-width
   bar is the bug regardless of where the breakpoint sits. */
body.lj-auth .lj-landing .lj-abtn {
  height: 64px; padding: 0 26px;
  flex: 0 1 262px; min-width: 0; width: auto;
  border-radius: 8px; gap: 11px;
  justify-content: center;
  box-shadow: 0 8px 26px rgba(0, 0, 0, .5);
}
body.lj-auth .lj-landing .lj-abtn .lj-txt { min-width: 0; }
/* The landing sheet sizes text off the viewport (clamp(17px,4vw,26px)) because it
   used to be a full-page hero. In a bar it has to be bar-sized. */
body.lj-auth .lj-landing .lj-abtn .lj-txt {
  flex: 0 0 auto;
  transform: none;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: .15em;
  text-transform: uppercase;
}
body.lj-auth .lj-landing .lj-abtn .lj-ic { flex: 0 0 auto; }
body.lj-auth .lj-landing .lj-abtn .lj-ic svg { width: 19px; height: 19px; }

body.lj-auth .lj-landing .lj-abtn--prime {
  background: linear-gradient(180deg, #f4d680 0%, #c9a24a 100%);
  color: #241a08;
  border: 1px solid #f7dd92;
  box-shadow: 0 6px 26px rgba(201, 162, 74, .32);
}
body.lj-auth .lj-landing .lj-abtn--prime .lj-ic { color: #241a08; }
body.lj-auth .lj-landing .lj-abtn--ghost {
  background: rgba(26, 20, 15, .9);
  border: 1px solid rgba(201, 162, 74, .5);
  color: #ece3cf;
  box-shadow: 0 8px 26px rgba(0, 0, 0, .5);
}
body.lj-auth .lj-landing .lj-abtn--ghost .lj-ic { color: rgba(201, 162, 74, .9); }

/* Footer: same viewport-sized-hero problem. */
body.lj-auth .lj-landing .lj-foot {
  margin-top: 17px; gap: 12px;
  font-size: 10.5px; font-weight: 500; letter-spacing: .2em;
  color: rgba(236, 227, 207, .44);
}
body.lj-auth .lj-landing .lj-foot a { color: rgba(236, 227, 207, .44); }
body.lj-auth .lj-landing .lj-foot .lj-age { color: rgba(236, 227, 207, .44); }
body.lj-auth .lj-landing .lj-foot .lj-dot { background: rgba(236, 227, 207, .3); }

/* Returning-user door. */
body.lj-auth .lj-backin {
  margin-top: 17px; display: flex; align-items: center; justify-content: center; gap: 13px;
}
body.lj-auth .lj-backin span {
  color: rgba(236, 227, 207, .62); font-family: 'JetBrains Mono', monospace;
  font-size: 11.5px; letter-spacing: .1em;
}
body.lj-auth .lj-backin button {
  height: 42px; padding: 0 22px; border-radius: 6px; cursor: pointer;
  border: 1px solid rgba(236, 227, 207, .42); background: transparent; color: #ece3cf;
  font-family: 'JetBrains Mono', monospace; font-size: 11.5px; font-weight: 600;
  letter-spacing: .15em; text-transform: uppercase;
}
body.lj-auth .lj-foot { margin-top: 17px; }

@media (max-width: 767.98px), (max-height: 500.98px) {
  body.lj-auth section.lj-landing[data-screen="01-landing"][data-active="true"] {
    padding: 15px 13px calc(9px + env(safe-area-inset-bottom));
    border-top: 1px solid rgba(201, 162, 74, .22);
    background: linear-gradient(to top,
      rgba(9, 9, 11, .99) 0%, rgba(9, 9, 11, .96) 62%, rgba(9, 9, 11, .5) 100%);
  }
  /* NOTE: every selector here carries `.lj-landing` to match the specificity of
     the desktop block above (0,3,0). Written as `body.lj-auth .lj-auth` it is
     (0,2,0) and the desktop row rule wins even inside this media query — which
     is exactly what shipped the first time and laid the three buttons out in a
     row that overflowed the phone. */
  body.lj-auth .lj-landing .lj-auth { flex-direction: column; gap: 9px; width: 100%; }
  /* Guest is the primary CTA and stays full width; phone + email share a row. */
  /* `flex: 0 0 auto` is load-bearing. The base rule uses `flex: 0 1 262px` so
     the desktop ROW can shrink, but flex-basis applies to the MAIN AXIS — and
     here .lj-auth is a COLUMN, so a 262px basis becomes each button's HEIGHT.
     That inflated the bar until it swallowed the board's controls. */
  body.lj-auth .lj-landing .lj-abtn {
    flex: 0 0 auto;
    width: 100%; min-width: 0; height: 54px; padding: 0 18px;
  }
  body.lj-auth .lj-landing .lj-abtn .lj-txt { font-size: 12px; }
  body.lj-auth .lj-landing .lj-auth-alt { display: flex; gap: 9px; width: 100%; }
  /* Phone + email SHARE a row here, so they must not keep the full-width sizing
     the stacked primary CTA uses — two 100%-wide buttons in one row push the
     second one off the screen. */
  body.lj-auth .lj-landing .lj-auth-alt .lj-abtn {
    height: 44px; flex: 1 1 0; width: auto; min-width: 0;
  }
  body.lj-auth .lj-landing .lj-auth-alt .lj-abtn .lj-txt {
    font-size: 10px; letter-spacing: .12em;
  }
  body.lj-auth .lj-landing .lj-backin { margin-top: 10px; gap: 9px; }
  body.lj-auth .lj-landing .lj-backin span { font-size: 10px; }
  body.lj-auth .lj-landing .lj-backin button { height: 36px; padding: 0 15px; font-size: 9.5px; }
  body.lj-auth .lj-landing .lj-foot { margin-top: 9px; font-size: 8px; gap: 8px; }
}

/* ===== Short landscape only ============================================
 * A landscape phone has width to spare and almost no height (667x375). The
 * portrait treatment above stacks three full-width buttons, which costs ~197px
 * of a 375px viewport and leaves the board's HIT/STAND behind the bar. Here the
 * buttons go back to a single row — the bar drops to ~110px and the board keeps
 * usable height.
 * ===================================================================== */
/* Compact bar for ANY narrow landscape viewport, not just short ones.
   Gated `max-height: 500px` alone, this stopped 1px short of a live failure
   band: at ~600-767 wide by ~501-710 tall (767x501, 767x600, 600x550) the
   stacked bar is ~197px, the board's content overflows its reserved padding,
   and elementFromPoint at the ringed action card returns the SIGN-IN BAR. The
   demo dead-ends on an await beat with the coach reading "Tap it" — the same
   failure mode as the inert regression, just viewport-scoped.
   The `max-width: 767px` clause covers that band without reaching small
   laptops (1024x700 is landscape and >500 tall but stays on the desktop
   layout, which fits there). */
@media (orientation: landscape) and (max-height: 500.98px),
       (orientation: landscape) and (max-width: 767.98px) {
  body.lj-auth { --lj-bar-h: 88px; }
  /* Measured: the board's own content needs ~272px at 667x375, so the bar has
     to stay under ~100px or HIT/STAND end up behind it. Everything below is
     sized to that budget. */
  body.lj-auth .gv2-page:not([data-mode="campaign"]) { padding-bottom: 100px; }

  body.lj-auth .lj-landing .lj-auth { flex-direction: row; gap: 8px; }
  body.lj-auth .lj-landing .lj-auth-alt { display: contents; }
  body.lj-auth .lj-landing .lj-abtn {
    flex: 1 1 0; width: auto; min-width: 0; height: 40px; padding: 0 12px; gap: 7px;
  }
  body.lj-auth .lj-landing .lj-auth-alt .lj-abtn { height: 40px; }
  body.lj-auth .lj-landing .lj-abtn .lj-txt { font-size: 9.5px; letter-spacing: .09em; }
  body.lj-auth .lj-landing .lj-auth-alt .lj-abtn .lj-txt { font-size: 9.5px; }
  body.lj-auth .lj-landing .lj-abtn .lj-ic svg { width: 14px; height: 14px; }

  body.lj-auth section.lj-landing[data-screen="01-landing"][data-active="true"] {
    padding: 8px 14px calc(5px + env(safe-area-inset-bottom));
  }
  /* Sign back in folds onto the same line as the legal footer. */
  body.lj-auth .lj-landing .lj-backin { margin-top: 6px; gap: 8px; }
  body.lj-auth .lj-landing .lj-backin span { font-size: 9px; }
  body.lj-auth .lj-landing .lj-backin button { height: 28px; padding: 0 12px; font-size: 8.5px; }
  body.lj-auth .lj-landing .lj-foot { display: none; }
}

/* ===== Narrow landscape WITH vertical room =============================
 * The band <=767px wide, landscape, >=501px tall (767x501, 767x600, 600x550)
 * is the awkward one and needs its own regime. It is too narrow for the
 * desktop block, but it is NOT short enough for game-v2's own landscape-short
 * layout (`max-height: 500px`) to kick in — so the board falls back to its
 * tall desktop-ish internal layout, which needs ~585px of content. Reserving
 * space with padding cannot help: the board is height-locked at 100dvh with
 * overflow:hidden, so the surplus is simply clipped and the action row lands
 * under the sign-in bar. Measured at 767x501: actions row at y 403-513 against
 * a content box ending at 401, and elementFromPoint on the ringed card
 * returned the sign-in bar — the demo dead-ends on an await beat exactly like
 * the inert regression did.
 *
 * The fix is the one the desktop block already uses: stop reserving space and
 * anchor the interactive cluster off --lj-bar-h, so clearance no longer depends
 * on the board's internal layout fitting. Later in the file than the small
 * block so it wins over that block's in-flow control rules.
 * ===================================================================== */
@media (orientation: landscape) and (max-width: 767.98px),
       (orientation: landscape) and (max-height: 500.98px) {
  body.lj-auth .gv2-page:not([data-mode="campaign"]) { padding-bottom: 0; }

  /* Same stacking-context trap as the short-portrait block: raise the seat-0
     CONTEXT, not the fixed child inside it. */
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="0"] { z-index: 6; }
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="1"] { z-index: 1; }

  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="0"] .gv2-pcl {
    position: fixed;
    bottom: calc(var(--lj-bar-h) + 16px);
    top: auto; left: 50%;
    transform: translateX(-50%);
    right: auto;
    width: min(340px, 62vw); height: auto;
    display: flex; gap: 14px;
    padding-bottom: 0;
    z-index: 5;
  }
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="1"] .gv2-pcl {
    display: none;
  }
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-cb {
    flex: 1 1 0; min-height: 0;
    height: 52px; padding: 0;
    border-radius: 8px;
    border: 1px solid rgba(201, 162, 74, .6);
    background: rgba(14, 10, 16, .86);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .62);
    display: flex; align-items: center; justify-content: center;
  }
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-cb-hit {
    border-color: rgba(214, 120, 120, .78);
  }

  body.lj-auth .gv2-pa[data-gv2-player-area="0"] .gv2-pa-actions {
    position: fixed;
    bottom: calc(var(--lj-bar-h) + 84px);
    top: auto; left: 50%;
    transform: translateX(-50%);
    z-index: 6;
    margin: 0; padding: 0;
    justify-content: center;
  }
  body.lj-auth .gv2-pa[data-gv2-player-area="0"] .gv2-pa-label-actions {
    position: fixed;
    bottom: calc(var(--lj-bar-h) + 200px);
    top: auto; left: 50%;
    transform: translateX(-50%);
    z-index: 6;
    margin: 0; white-space: nowrap;
  }
}

/* ===== Portrait ========================================================
 * Originally gated `max-height: 700px`, on the assumption that a tall phone had
 * room for the board's own in-flow layout above the 198px bar. It does for
 * HIT/STAND — but NOT for the action row, which sits lower in the board's flow
 * and lands under the bar even at 390x844 and 430x932. Driving the fixture
 * surfaced it: beat 5's ringed action card hit-tested to the "Sign back in"
 * button. Verifying only .gv2-pcl clearance is what hid it.
 * So: every portrait viewport gets the same bar-anchored cluster the other
 * regimes use. One rule for the whole orientation, no height threshold to be
 * wrong about.
 * Last block in the file so it wins over the small block's in-flow rules.
 * ===================================================================== */
@media (orientation: portrait) {
  body.lj-auth .gv2-page:not([data-mode="campaign"]) { padding-bottom: 0; }

  /* `.gv2-pa` sets z-index:2 and therefore establishes a STACKING CONTEXT, so a
     fixed descendant's z-index:6 is scoped inside it — it cannot rise above the
     sibling seat-1 area, which is also z:2 and paints later. At 320x568 that put
     the opponent's area over the local action row and killed the demo at beat 3.
     Raising the CONTEXT is what works; raising the child is what does not. */
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="0"] { z-index: 6; }
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="1"] { z-index: 1; }

  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="0"] .gv2-pcl {
    position: fixed;
    bottom: calc(var(--lj-bar-h) + 14px);
    top: auto; left: 50%;
    transform: translateX(-50%);
    right: auto;
    width: calc(100vw - 26px); height: auto;
    display: flex; gap: 11px;
    padding-bottom: 0;
    z-index: 5;
  }
  body.lj-auth .gv2-page:not([data-mode="campaign"]) .gv2-pa[data-gv2-player-area="1"] .gv2-pcl {
    display: none;
  }
  body.lj-auth .gv2-pa[data-gv2-player-area="0"] .gv2-pa-actions {
    position: fixed;
    bottom: calc(var(--lj-bar-h) + 78px);
    top: auto; left: 50%;
    transform: translateX(-50%);
    z-index: 6;
    margin: 0; padding: 0;
    justify-content: center;
  }
  body.lj-auth .gv2-pa[data-gv2-player-area="0"] .gv2-pa-label-actions {
    position: fixed;
    bottom: calc(var(--lj-bar-h) + 194px);
    top: auto; left: 50%;
    transform: translateX(-50%);
    z-index: 6;
    margin: 0; white-space: nowrap;
  }
}


/* ===== Choosers on short viewports ====================================
 * The Switch/Free-Card choosers are body-mounted cards with their own layout.
 * Their submit button sits low in the card, and game-v2.css caps the card's
 * height with overflow:auto — so on a short window the button ends up inside
 * the card's own CLIPPED SCROLLPORT, not merely below the viewport fold. Beat 9
 * of the fixture only advances on that button, so the demo dead-ends there.
 * Ordinary non-maximised laptop windows hit this. Pre-existing board behaviour;
 * scoped here because /auth is where it strands a visitor.
 *
 * The "below the fold" reading was the FIRST diagnosis and it was wrong — it
 * led to a scroll-based fix that changed nothing. See the note on the rule
 * below for what the clip actually is and why scaling alone cannot touch it.
 * ===================================================================== */
@media (max-height: 700px) {
  /* Two things had to change together, and an earlier attempt got this wrong by
     doing only the second.
     1. UNCAP the card. game-v2.css clips it with `max-height:88vh; overflow-y:auto`
        (:9085, desktop) and `max-height:100dvh; overflow-y:auto` (:4122, mobile).
        The Swap button lives past that cap, inside the card's own clipped
        scrollport — so it was unreachable even while its rect sat on-screen.
     2. SCALE the uncapped card so the now-full-height box still fits the
        viewport.
     Scale alone does nothing here: `transform` is paint-time and cannot change
     layout or scroll overflow. Measured at 1280x620 with and without the scale,
     clientHeight/scrollHeight were byte-identical at 542/617 and the button
     stayed clipped both ways. A rect-based check cannot see an ancestor clip,
     which is why "verified on-screen" was reported for viewports that were in
     fact still dead. Drive the beat, do not measure the button. */
  body.lj-auth .gv2-overlay-chooser-card {
    max-height: none;
    overflow-y: visible;
    transform: scale(0.86);
    transform-origin: center center;
  }
}
@media (max-height: 560px) {
  body.lj-auth .gv2-overlay-chooser-card { transform: scale(0.72); }
}
@media (max-height: 460px) {
  body.lj-auth .gv2-overlay-chooser-card { transform: scale(0.58); }
}

/* Authenticated /demo mode: board only, with compact home controls. */
body.lj-auth.lj-account-demo section[data-screen],
body.lj-auth.lj-account-demo .bja-felt { display: none !important; }
body.lj-auth.lj-account-demo .ljb-welcome-signin,
body.lj-auth.lj-account-demo .ljb-welcome-privacy { display: none !important; }
body.lj-auth.lj-account-demo .ljb-skip-demo {
  position: fixed;
  top: max(18px, env(safe-area-inset-top));
  right: max(18px, env(safe-area-inset-right));
  z-index: 4800;
  border: 1px solid rgba(240, 194, 96, .58);
  border-radius: 999px;
  padding: 9px 15px;
  background: rgba(15, 12, 18, .82);
  color: #f4dfad;
  cursor: pointer;
  font: 700 11px/1 'JetBrains Mono', monospace;
  letter-spacing: .1em;
  text-transform: uppercase;
}
body.lj-auth.lj-account-demo .ljb-skip-demo:focus-visible { outline: 3px solid #f4d680; outline-offset: 3px; }
body.lj-auth.lj-account-demo .trial-me-account-countdown {
  margin: 12px 0 18px;
  color: rgba(244, 223, 173, .78);
  font: 500 12px/1.45 'JetBrains Mono', monospace;
  letter-spacing: .04em;
}
