/* ============================================================================
   MOBILE REFINE — loaded LAST on purpose.
   mobile.css and mobile-coinflip-v12.css already set most of these properties with !important, so anything
   here has to both come after them and match their weight. Selectors are kept at the same shape they use
   (#creator .thing) rather than escalating, so this file stays readable next to them.

   Covers, in order:
     1. the create-coinflip sheet   - it was opening UNDER the header, with a search bar and two full-size
                                      selects eating a third of the screen and a 36px side picker
     2. the bottom tab bar          - the top tabs overflowed the viewport (Race was clipped at the edge)
     3. the balance chip            - undersized for the space it sits in
   ========================================================================= */

/* The tab bar and its More sheet are injected into the DOM at every width, so they must be hidden by DEFAULT
   and only turned on inside the mobile query below. Without this a desktop window gets a stray nav bar
   pinned across the bottom of the page. */
.gf-tabbar, .gf-more { display: none; }

@media (max-width: 900px) {

  /* ---- 1. CREATE COINFLIP -------------------------------------------------
     A true full-screen sheet. It was rendering at top:42px BEHIND the header, so its own "CREATE COINFLIP"
     label and close button were hidden under the nav. inset:0 + a z-index above the header fixes that
     without having to work out the header's stacking context. */
  /* .show ONLY. Setting display on #creator.modal unconditionally overrides the display:none that keeps the
     modal closed, and the sheet then sits open on top of the lobby permanently. */
  #creator.modal {
    position: fixed !important; inset: 0 !important;
    padding: 0 !important; margin: 0 !important;
    z-index: 4000 !important;
  }
  #creator.modal.show {
    display: flex !important; align-items: stretch !important; justify-content: stretch !important;
  }
  #creator .creator-card {
    width: 100% !important; max-width: 100% !important;
    height: 100% !important; max-height: 100% !important;
    border-radius: 0 !important;
    padding: max(10px, env(safe-area-inset-top)) 12px calc(10px + env(safe-area-inset-bottom)) 12px !important;
    display: flex !important; flex-direction: column !important; gap: 0 !important;
    overflow: hidden !important;
  }
  #creator .creator-card > .close {
    top: max(8px, env(safe-area-inset-top)) !important; right: 10px !important;
    width: 38px !important; height: 38px !important; font-size: 26px !important; z-index: 30 !important;
  }
  /* The "CREATE COINFLIP" eyebrow duplicates the button at the bottom of the very same sheet. */
  #creator .creator-card > p { display: none !important; }
  #creator .creator-card > h2 {
    font-size: 21px !important; line-height: 1.15 !important;
    margin: 2px 0 8px !important; padding-right: 46px !important;
  }

  /* The search box is the single biggest waste of height here: an inventory that fits on two thumb-scrolls
     does not need one, and the sort/filter row already narrows the list. */
  #creator .catalog-search { display: none !important; }

  /* Both selects on ONE row, captions dropped - "Highest value" and "All items" say what they are. */
  #creator .catalog-toolbar {
    display: grid !important; grid-template-columns: 1fr 1fr !important;
    gap: 8px !important; padding: 0 0 8px !important; margin: 0 !important; border: 0 !important;
  }
  #creator .catalog-toolbar .catalog-control { display: block !important; margin: 0 !important; padding: 0 !important; }
  #creator .catalog-toolbar .catalog-control > small { display: none !important; }
  /* refine.css hangs a "SORT & FILTER" caption off ::before - another whole line for something the two
     controls underneath already say. */
  #creator .catalog-toolbar::before { content: none !important; display: none !important; }
  #creator .catalog-toolbar select {
    width: 100% !important; height: 38px !important; min-height: 0 !important;
    padding: 0 30px 0 10px !important; font-size: 13px !important; border-radius: 9px !important;
  }

  /* The list itself takes whatever is left, and is the only thing that scrolls. */
  #creator .item-picker, #creator .catalog-picker {
    flex: 1 1 auto !important; min-height: 0 !important;
    display: flex !important; flex-direction: column !important;
    overflow: hidden !important; padding: 0 !important; margin: 0 !important;
  }
  #creator .catalog-grid {
    flex: 1 1 auto !important; min-height: 0 !important; overflow-y: auto !important;
    -webkit-overflow-scrolling: touch !important;
    display: grid !important; grid-template-columns: 1fr 1fr !important; gap: 8px !important;
    padding: 2px 2px 6px !important; align-content: start !important;
  }
  #creator .catalog-grid .catalog-item {
    min-height: 0 !important; height: auto !important;
    padding: 8px 8px 7px !important; gap: 4px !important; border-radius: 11px !important;
  }
  #creator .catalog-grid .catalog-item img { width: 100% !important; height: 62px !important; object-fit: contain !important; }
  #creator .catalog-grid .catalog-item > span { text-align: center !important; }
  #creator .catalog-grid .catalog-item > span b { font-size: 12px !important; }
  #creator .catalog-grid .catalog-item > span small { display: none !important; }   /* tier repeats the artwork */
  #creator .catalog-grid .catalog-item > strong { font-size: 13px !important; justify-content: center !important; }

  /* ---- the side picker ----------------------------------------------------
     Was 36px coins floating in the dead band above the submit button, overlapping the rule above it. Now a
     labelled row of its own with coins big enough to actually tap (Apple's minimum is 44px; these are 58). */
  /* Totals row: count and amount left, CLEAR right. The side picker is NOT here any more - see below. */
  #creator .creator-total {
    display: grid !important;
    grid-template-columns: auto 1fr auto !important;
    grid-template-areas: "count amount clear" !important;
    grid-template-rows: auto !important;
    align-items: center !important; gap: 10px !important;
    min-height: 0 !important; margin: 6px 0 0 !important; padding: 9px 2px !important;
  }
  #creator .creator-total > span { grid-area: count !important; font-size: 12px !important; justify-self: start !important; }
  #creator .creator-total > b,
  #creator .creator-total > .creator-amount { grid-area: amount !important; font-size: 18px !important; justify-self: start !important; }
  #creator .creator-total > button { grid-area: clear !important; justify-self: end !important; margin: 0 !important;
    align-self: center !important; font-size: 11px !important; padding: 6px 11px !important; }

  /* THE SIDE PICKER IS MOVED OUT OF .creator-total IN THE DOM (see the script in index.html). It was a grid
     item in a two-column grid whose areas are defined in mobile-coinflip-v12.css, and every attempt to give
     it a row from here fought that definition - it ended up at x=-167 with the heads chip clipped off the
     left edge. As a direct child of the card it is just a flex row and there is nothing left to fight. */
  /* NOTE THE SELECTOR: mobile-coinflip-v12.css targets this with `#creator #cfSide`, which is TWO ids. A
     `#creator .creator-card > .cf-side` (one id, two classes) loses to that no matter how late it loads or
     how many !importants it carries - which is why the picker stayed 99px wide and off-screen through two
     attempts. Match the id-count and the later file wins. */
  #creator #cfSide, #creator .creator-card > .cf-side {
    display: flex !important; align-items: center !important; justify-content: center !important;
    gap: 12px !important; width: 100% !important; flex: 0 0 auto !important;
    margin: 2px 0 9px !important; padding: 0 !important;
    grid-area: auto !important; grid-template-columns: none !important; grid-template-rows: none !important;
    height: auto !important; min-width: 0 !important; position: static !important;
    /* An earlier rule centres this with left:50% + translateX(-50%). position:static kills the offset but NOT
       the transform, which on its own shifted the row exactly half its width off the left edge. */
    transform: none !important; left: auto !important; right: auto !important; top: auto !important; bottom: auto !important;
  }
  /* No "PICK A SIDE" caption - two coins under a CREATE button are self-explanatory, and dropping it lets the
     pair sit dead centre instead of being pushed right by a label. */
  #creator #cfSide .cf-side-lbl, #creator .cf-side .cf-side-lbl { display: none !important; }
  #creator #cfSide .cf-side-btn, #creator .cf-side .cf-side-btn {
    width: 58px !important; height: 58px !important; min-width: 0 !important; padding: 3px !important;
    border-radius: 50% !important; display: grid !important; place-items: center !important;
    opacity: .5 !important; transition: opacity .12s ease, transform .12s ease !important;
  }
  #creator #cfSide .cf-side-btn img, #creator .cf-side .cf-side-btn img {
    width: 52px !important; height: 52px !important; object-fit: contain !important;
  }
  /* Unpicked sides are faded rather than outlined - the chips are already two obvious colours. */
  #creator #cfSide .cf-side-btn.is-active, #creator .cf-side .cf-side-btn.is-active {
    opacity: 1 !important; transform: scale(1.06) !important;
  }

  #creator .create-submit {
    flex: 0 0 auto !important; width: 100% !important;
    height: 52px !important; margin: 0 !important; font-size: 15px !important; border-radius: 12px !important;
  }

  /* ---- 2. BOTTOM TAB BAR --------------------------------------------------
     The top tab strip was 366px of content in a 390px viewport with five items, so "Race" sat on the edge
     and the row could not grow. A fixed bottom bar is both reachable one-handed and free of that limit. */
  .top-nav#gfPrimaryNav { display: none !important; }

  .gf-tabbar {
    position: fixed !important; left: 0 !important; right: 0 !important; bottom: 0 !important;
    z-index: 3500 !important;
    display: grid !important; grid-auto-flow: column !important; grid-auto-columns: 1fr !important;
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom)) !important;
    background: rgba(16, 16, 21, .94) !important;
    backdrop-filter: blur(14px) saturate(1.2) !important;
    -webkit-backdrop-filter: blur(14px) saturate(1.2) !important;
    border-top: 1px solid rgba(255, 255, 255, .07) !important;
  }
  .gf-tabbar button {
    appearance: none; background: none; border: 0; cursor: pointer;
    display: grid; justify-items: center; align-content: center; gap: 3px;
    padding: 5px 2px; min-height: 50px; border-radius: 10px;
    color: #8b8f99; font: 600 10px/1 "Space Grotesk", system-ui, sans-serif; letter-spacing: .04em;
  }
  .gf-tabbar button svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.9;
    stroke-linecap: round; stroke-linejoin: round; }
  .gf-tabbar button.is-active { color: #a56bff; }
  .gf-tabbar button.is-active svg { stroke: #a56bff; }

  /* The bar floats over the page, so the page needs to end above it - including the chat launcher, which
     otherwise sits on top of the tabs. */
  body { padding-bottom: calc(62px + env(safe-area-inset-bottom)) !important; }
  .gf-chat-launcher, #chatLauncher, .chat-fab { bottom: calc(74px + env(safe-area-inset-bottom)) !important; }

  /* "More" sheet: everything that does not earn a permanent tab. */
  .gf-more { position: fixed !important; inset: 0 !important; z-index: 3600 !important;
    display: none; align-items: flex-end; background: rgba(0, 0, 0, .55); }
  .gf-more.show { display: flex !important; }
  .gf-more-card { width: 100%; background: #17171d; border-radius: 16px 16px 0 0;
    border-top: 1px solid rgba(255, 255, 255, .08);
    padding: 10px 12px calc(16px + env(safe-area-inset-bottom)); }
  .gf-more-card > i { display: block; width: 38px; height: 4px; border-radius: 2px;
    background: rgba(255, 255, 255, .18); margin: 2px auto 12px; }
  .gf-more-card button { display: flex; align-items: center; gap: 12px; width: 100%;
    appearance: none; background: none; border: 0; cursor: pointer;
    padding: 13px 10px; border-radius: 11px; color: #e6e2f0;
    font: 600 15px/1 "Space Grotesk", system-ui, sans-serif; text-align: left; }
  .gf-more-card button + button { margin-top: 2px; }
  .gf-more-card button svg { width: 20px; height: 20px; fill: none; stroke: #a56bff; stroke-width: 1.9;
    stroke-linecap: round; stroke-linejoin: round; }

  /* ---- 2b. HEADER + LOBBY TOOLBAR ----------------------------------------
     The header still reserved the band its tab strip used to occupy, so there was ~26px of nothing under the
     logo row. */
  /* refine.css pins this to 72/104/124px in several media queries to make room for the tab strip. The strip
     is gone, so the height goes with it. Explicit rather than auto because those rules are all `header
     {height:...!important}` and an `auto` here would just lose the tie on some of them. */
  header, .app header, main > header {
    height: 56px !important; min-height: 56px !important; max-height: 56px !important;
    padding: 0 12px !important; gap: 8px !important;
    align-items: center !important;
  }
  header .top-brand .brand-name { display: none !important; }   /* the mark alone is enough at this width */
  header .brand-mark { width: 34px !important; height: 34px !important; }

  /* "OPEN GAMES / 4 games live / CREATE / FILTER" spread over two rows with the primary action squeezed into
     a 150px pill. Count and filter share a row; CREATE gets its own full-width one. */
  /* .lobby-heading and .lobby-tools are siblings, so the count and the FILTER pill can only share a line if
     the heading's children become items of the same flex row - hence display:contents on the wrapper. */
  /* EXPLICIT GRID PLACEMENT, not flex order. With flex, inherited width/flex-basis rules on these children
     kept forcing wraps - the count centred itself on its own line and pushed FILTER to a third row. Grid
     coordinates cannot wrap, so the layout is whatever is written here.
     .lobby-heading is display:contents so its children and .lobby-tools (a sibling) share one grid. */
  .game-list .list-head {
    display: grid !important; grid-template-columns: 1fr auto !important;
    align-items: center !important; height: auto !important;
    gap: 8px !important; padding: 10px 12px !important;
  }
  .game-list .lobby-heading { display: contents !important; }
  .game-list .lobby-heading > b { display: none !important; }          /* "OPEN GAMES" - the page title says it */
  .game-list .lobby-heading > .live-total { display: none !important; } /* "TOTAL OPEN G 0" - noise at this width */
  .game-list .lobby-heading > #lobbyCount {
    grid-column: 1 !important; grid-row: 1 !important;
    justify-self: start !important; text-align: left !important; white-space: nowrap !important;
    width: auto !important; margin: 0 !important; font-size: 12px !important;
  }
  .game-list .lobby-tools {
    grid-column: 2 !important; grid-row: 1 !important; justify-self: end !important;
    width: auto !important; max-width: none !important; margin: 0 !important; padding: 0 !important;
  }
  .game-list .lobby-heading > .create-open {
    grid-column: 1 / -1 !important; grid-row: 2 !important;
    width: 100% !important; min-width: 0 !important; height: 46px !important;
    margin: 0 !important; font-size: 13px !important; border-radius: 11px !important;
  }

  /* ---- 2c. LIVE COUNTDOWN ------------------------------------------------
     THE CONTAINER IS #gfLobby, NOT #lobbyList. game.js injects `#lobbyList{display:none!important}` and builds
     the real lobby into #gfLobby - so every countdown rule in mobile-coinflip-v12.css (all of them scoped to
     #lobbyList) has never applied on a phone. What was actually styling it is refine.css:169, which gives the
     countdown a 24px box, the spinning state a 38px box, and the result state a box sized to its contents.
     Swapping between those three at the last tick RESIZES the element inside its cell, which is the jump to
     the right and down.
     Fix: one fixed box for all three states, so a class change can never reflow it. */
  #gfLobby .lobby .player.matched > .match-status,
  #gfLobby .lobby .player.matched > .match-status.countdown,
  #gfLobby .lobby .player.matched > .match-status.spinning,
  #gfLobby .lobby .player.matched > .match-status.result {
    box-sizing: border-box !important;
    width: 46px !important; min-width: 46px !important; max-width: 46px !important;
    height: 46px !important; min-height: 46px !important; max-height: 46px !important;
    display: grid !important; place-items: center !important;
    grid-template-columns: 1fr !important; grid-template-rows: 1fr !important;
    padding: 0 !important; margin: 0 auto !important; gap: 0 !important;
    /* the count animation scales; pin the origin so it can only breathe about its own centre */
    transform-origin: 50% 50% !important;
  }
  #gfLobby .lobby .player.matched > .match-status.countdown {
    font: 800 21px/46px "Space Grotesk", system-ui, sans-serif !important;
    text-align: center !important;
  }
  /* The result state appends a HEADS/TAILS caption under the coin; inside a fixed box that would squash the
     coin, and it is already named by the colour of the chip. */
  #gfLobby .lobby .player.matched > .match-status.result > span { display: none !important; }
  #gfLobby .lobby .player.matched > .match-status .match-result-icon,
  #gfLobby .lobby .player.matched > .match-status .match-flip-coin {
    width: 42px !important; height: 42px !important;
    margin: 0 !important; padding: 0 !important; border: 0 !important; background: none !important;
  }

  /* ---- 2d. VIEWER COUNTDOWN ----------------------------------------------
     TWO DIFFERENT CENTRING MODELS on the same element, measured:
       .is-countdown  ->  left:164px (a resolved 50%) + transform:translate(-50%,-50%)   [refine.css:1892]
       .is-result     ->  left:0; right:0; text-align:center; transform:none             [experience-polish:4508]
     The instant the stage stops being .is-countdown the translate stops applying, but the resolved left does
     not - so the number snaps RIGHT by half its width and DOWN by half its height for a frame. That is the
     "moves to the right and down" on the last tick.
     Fix: one model for every state - a full-width box centred by text-align, which no class change can shift
     horizontally. Only `top` varies by state, and that difference is deliberate (the result sits below the
     coin), so it reads as a move rather than a glitch. */
  /* inset:0 + margin:auto centres on BOTH axes with no percentage and no transform. That matters because a
     top:50% is re-resolved every time the stage changes size - and on a phone the stage does change size mid-
     countdown: iOS collapses the URL bar on scroll (dvh units shift), and the coin image finishing its load
     reflows the stage too. Either one nudges a percentage-positioned number; neither can move this one. */
  #viewer .flip-stage #flipCount,
  .viewer-card .flip-stage #flipCount,
  #viewer .flip-stage.is-countdown #flipCount,
  .viewer-card .flip-stage.is-countdown #flipCount,
  #viewer .flip-stage.is-spinning #flipCount,
  .viewer-card .flip-stage.is-spinning #flipCount {
    position: absolute !important;
    inset: 0 !important;
    width: auto !important; height: -moz-fit-content !important; height: fit-content !important;
    margin: auto !important;
    transform: none !important;
    text-align: center !important;
  }
  /* The result caption keeps its own offset below the coin - same horizontal model, different top. */
  #viewer .flip-stage.is-result #flipCount,
  .viewer-card .flip-stage.is-result #flipCount {
    inset: auto 0 auto 0 !important;
    top: calc(50% + 82px) !important;
    margin: 0 !important;
    transform: translateY(-50%) !important;
  }

  /* ---- 3. BALANCE CHIP ---------------------------------------------------
     It read as an afterthought next to a 40px logo. The header row has the space now that the tabs have
     moved out of it. */
  /* The online counter is decoration and was competing for the same row. */
  header .online { display: none !important; }
  /* BOTH icons move into the More sheet. Measured: with them present the flanks were 54px (logo) versus
     137px (icons + avatar), so the space left for the balance was centred 36px LEFT of the screen centre -
     which is the "off centre" being reported. The chip was centred in its gap all along; the GAP was what
     was not centred. With only a logo and an avatar flanking it, the two sides match. */
  header .header-icons { display: none !important; }

  /* Then pin the chip to the true screen centre rather than trusting the flanks to stay symmetric.
     max-width keeps a long balance from ever reaching the avatar. */
  header { position: relative !important; }
  header .balance, header .header-right .balance {
    position: absolute !important;
    left: 50% !important;
    transform: translateX(-50%) !important;
    flex: 0 0 auto !important;
    width: auto !important;
    max-width: calc(100vw - 150px) !important;
  }
  /* header is display:grid by default, so a flex:1 child cannot stretch into the empty middle - the balance
     stayed a small pill with dead air either side of it. Flex row + a growing .header-right closes that gap. */
  header, .app header, main > header { display: flex !important; }
  header .header-right {
    display: flex !important; align-items: center !important;
    gap: 8px !important; margin-left: 10px !important; flex: 1 1 auto !important; min-width: 0 !important;
    justify-content: flex-end !important;
  }
  /* Icons grouped WITH the avatar on the right, balance taking the left run. Source order is icons, balance,
     account - which stranded the balance in the middle of the bar with icons on either side of nothing. */
  header .header-right .balance { order: 1 !important; }
  header .header-right .header-icons { order: 2 !important; flex: 0 0 auto !important; gap: 6px !important; }
  header .header-right .account { order: 3 !important; }

  /* The balance is the one number that matters on this screen, so it takes the leftover width rather than
     sitting as a small pill with dead space either side. Label, figure and the "+" deposit affordance all
     stay - the "+" is the existing deposit trigger, not decoration. */
  /* justify-content:center is the bit that was missing: the chip already stretched, but its contents stayed
     left-aligned inside it, so the number read as sitting just off the logo rather than centred in the bar. */
  header .balance, header .header-right .balance {
    flex: 1 1 auto !important; min-width: 0 !important;
    display: flex !important; align-items: center !important; justify-content: center !important;
    gap: 9px !important;
    height: 44px !important; padding: 0 10px !important; border-radius: 13px !important;
  }
  /* "BALANCE" caption dropped - the coin glyph already says what the number is, and the row is tight. */
  header .balance small, header .header-right .balance small { display: none !important; }
  header .balance b, header .header-right .balance b {
    flex: 0 1 auto !important; min-width: 0 !important;
    font-size: 22px !important; font-weight: 800 !important; text-align: center !important;
    white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important;
  }
  header .balance .g-coin, header .balance em {
    width: 24px !important; height: 24px !important; vertical-align: -5px !important;
  }
  header .balance strong {
    flex: 0 0 auto !important; display: grid !important; place-items: center !important;
    width: 28px !important; height: 28px !important; padding: 0 !important; border-left: 0 !important;
    border-radius: 9px !important; background: rgba(165, 107, 255, .18) !important;
    color: #c9a6ff !important; font-size: 18px !important; line-height: 1 !important;
  }

  /* The account chip was hidden entirely on mobile, which left the row lopsided and the account menu with no
     way in. Avatar only - the name and level do not fit and are in the menu anyway. */
  header .account, header .header-right .account {
    display: flex !important; align-items: center !important;
    flex: 0 0 auto !important; gap: 0 !important; padding: 0 !important;
    font-size: 0 !important; background: none !important; border: 0 !important;
  }
  header .account img {
    width: 36px !important; height: 36px !important; border-radius: 50% !important;
    object-fit: cover !important; background: #241d33 !important;
  }
  header .account span, header .account small, header .account b { display: none !important; }

  /* ---- 2e. iOS TEXT AUTOSIZING -------------------------------------------
     The countdown jump is iPhone-only, which rules out the layout maths (Chrome measures it dead centre in
     every state, at three different stage heights). The WebKit-specific suspect is text autosizing: Safari
     silently inflates text it decides is "primary content", recomputes that per block, and the countdown's
     block changes on every tick. An inflated glyph in a centred box drifts. Pinning the adjust to 100% turns
     the feature off for these elements. Tabular figures on top, so 1 and 3 occupy identical width. */
  html, body { -webkit-text-size-adjust: 100% !important; text-size-adjust: 100% !important; }
  #viewer #flipCount, .viewer-card #flipCount {
    -webkit-text-size-adjust: 100% !important; text-size-adjust: 100% !important;
    font-variant-numeric: tabular-nums !important;
    font-feature-settings: "tnum" 1 !important;
  }
  /* iOS can also lag an absolutely-positioned child of a scrolling container during momentum scroll. Giving
     the stage its own compositing layer keeps the coin and the number on the same layer, so they cannot
     separate mid-scroll. */
  #viewer .flip-stage, .viewer-card .flip-stage { transform: translateZ(0) !important; }


  /* ---- 4. FINISHED FLIP IN THE LIVE LIST ---------------------------------
     game.js already tags the row .flip-complete and the winning cell .live-flip-winner, and refine.css:143
     already turns that name green - but at this size the green reads as "slightly different grey", and the
     LOSER is not dimmed at all, so there is no contrast to carry the result. Strengthen both sides: brighter
     green plus a ring on the winner, and actually fade the other player.
     Row shape is deliberately untouched. */
  #gfLobby .lobby.flip-complete .live-match-player:not(.live-flip-winner),
  #gfLobby .lobby.gfl-past .live-match-player:not(.live-flip-winner),
  #pastGames .lobby .live-match-player:not(.live-flip-winner) {
    opacity: .4 !important;
    transition: opacity .25s ease !important;
  }
  #gfLobby .lobby.flip-complete .live-match-player.live-flip-winner b,
  #gfLobby .lobby.flip-complete .live-match-player.live-flip-winner b *,
  #gfLobby .lobby.gfl-past .live-match-player.live-flip-winner b,
  #pastGames .lobby .live-match-player.live-flip-winner b,
  #pastGames .lobby .live-match-player.live-flip-winner b * {
    color: #3ddc84 !important;
    -webkit-text-fill-color: #3ddc84 !important;   /* the rank classes paint names with a gradient clip */
    background: none !important;
    font-weight: 800 !important;
  }
  #gfLobby .lobby.flip-complete .live-match-player.live-flip-winner img,
  #gfLobby .lobby.gfl-past .live-match-player.live-flip-winner img,
  #pastGames .lobby .live-match-player.live-flip-winner img {
    border-color: #23a559 !important;
    box-shadow: 0 0 0 2px #23a559, 0 0 14px rgba(35, 165, 89, .4) !important;
  }



  /* ---- 5. FINISHED / LIVE ROW ALIGNMENT ----------------------------------
     Measured on a real row: the bottom band put its three children on THREE different baselines - items at
     y=112, pot at y=110, VIEW at y=123 - and an empty .gfl-nochance element was holding open a third grid
     row. The matchup band was 91px tall for two names. Nothing was on a shared line, which is why the whole
     row reads as loose.
     NOTE THE `body` PREFIX: game.js injects `#gfLobby .lobby.gfl-live` (1 id, 2 classes) into a <style> tag
     at runtime, so it comes after this file and wins any tie. Adding a type selector makes these (1,2,1) and
     tips it back. */
  body #gfLobby .lobby.gfl-live,
  body #gfLobby .lobby.gfl-past,
  body #pastGames .lobby {
    align-items: center !important;
    row-gap: 6px !important;
    padding-top: 9px !important; padding-bottom: 9px !important;
  }
  /* Empty spacer that still claimed a row and a gap. */
  body #gfLobby .lobby.gfl-live > .gfl-nochance,
  body #pastGames .lobby > .gfl-nochance { display: none !important; }

  /* The matchup band: 91px for two names and two faces. */
  body #gfLobby .lobby.gfl-live > .player.matched,
  body #pastGames .lobby:has(> .player.matched) > .player.matched {
    min-height: 0 !important; height: auto !important;
    align-items: center !important; row-gap: 4px !important;
  }
  body #gfLobby .lobby.gfl-live .live-match-player img,
  body #pastGames .lobby .live-match-player img {
    width: 34px !important; height: 34px !important; border-radius: 50% !important; object-fit: cover !important;
  }
  body #gfLobby .lobby.gfl-live .live-match-player > span,
  body #pastGames .lobby .live-match-player > span { min-width: 0 !important; }
  body #gfLobby .lobby.gfl-live .live-match-player b,
  body #pastGames .lobby .live-match-player b {
    font-size: 13px !important; white-space: nowrap !important;
    overflow: hidden !important; text-overflow: ellipsis !important;
  }

  /* One shared centreline for items / pot / action, and item tiles at a single size. */
  body #gfLobby .lobby.gfl-live > .offer,
  body #pastGames .lobby > .offer {
    align-self: center !important; align-items: center !important;
    gap: 5px !important; margin: 0 !important; padding: 0 !important;
  }
  body #gfLobby .lobby.gfl-live > .offer img,
  body #pastGames .lobby > .offer img {
    width: 42px !important; height: 42px !important; margin: 0 !important;
    padding: 3px !important; border-radius: 8px !important; object-fit: contain !important;
  }
  body #gfLobby .lobby.gfl-live > .pot,
  body #pastGames .lobby > .pot {
    align-self: center !important; margin: 0 !important; white-space: nowrap !important;
  }
  body #gfLobby .lobby.gfl-live > .actions,
  body #pastGames .lobby > .actions { align-self: center !important; margin: 0 !important; }


  /* Finished rows: collapse the matchup to ONE line with the landed coin in the middle, instead of a 91px
     band holding names on row 1 and the coin alone on row 2. The VS is redundant once the coin is sitting
     between the two players. Each name/avatar pair is pushed toward the centre so the faces sit beside the
     coin rather than pinned to the row's outer edges. */
  body #gfLobby .lobby.gfl-live.flip-complete > .player.matched,
  body #gfLobby .lobby.gfl-live.gfl-past > .player.matched,
  body #pastGames .lobby:has(> .player.matched) > .player.matched {
    grid-template-columns: minmax(0, 1fr) 46px minmax(0, 1fr) !important;
    grid-template-rows: auto !important;
    grid-template-areas: "host result guest" !important;
    min-height: 0 !important; height: auto !important;
    align-items: center !important;
    column-gap: 10px !important; row-gap: 0 !important;
  }
  body #gfLobby .lobby.gfl-live.flip-complete > .player.matched > i,
  body #gfLobby .lobby.gfl-live.gfl-past > .player.matched > i,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > i { display: none !important; }

  body #gfLobby .lobby.gfl-live.flip-complete > .player.matched > .match-status,
  body #gfLobby .lobby.gfl-live.gfl-past > .player.matched > .match-status,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .match-status {
    grid-area: result !important;
    justify-self: center !important; align-self: center !important;
    margin: 0 !important;
  }
  /* Pairs hug the centre: the left cell ends at the coin, the right cell (row-reverse) starts at it. */
  body #gfLobby .lobby.gfl-live.flip-complete > .player.matched > .live-match-player,
  body #gfLobby .lobby.gfl-live.gfl-past > .player.matched > .live-match-player,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player {
    justify-content: flex-end !important;
  }
  body #gfLobby .lobby.gfl-live.flip-complete > .player.matched > .live-match-player:first-child { grid-area: host !important; }
  body #gfLobby .lobby.gfl-live.flip-complete > .player.matched > .live-match-player.opponent { grid-area: guest !important; }
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player:first-child { grid-area: host !important; }
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player.opponent { grid-area: guest !important; }


  /* ---- 6. PLAYER CELL: NAME, RANK, AVATAR --------------------------------
     Measured on a real row: the cell is a grid whose columns compute to 42px + 172px inside a 137px cell (so
     it overflows), and the name lives in a 107px column-flex span with its items centred - which parks the
     name 49.8px away from the avatar. The rank crest stacks UNDER the name for the same reason (column).
     Fixes: content-sized columns, and the span becomes a ROW so the crest sits beside the name.

     SELECTOR SHAPE: game.js wins with `#gfLobby .lobby:has(> .player.matched) > .player.matched`, and :has()
     carries its argument's specificity, so that rule is (1,5,0) - not the (1,2,0) it looks like. Mirroring the
     :has() here lands at (1,6,1), which is the only reason these apply at all. */
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player {
    grid-template-columns: auto auto !important;
    align-items: center !important;
    column-gap: 8px !important;
    min-width: 0 !important;
  }
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player > span,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player > span {
    display: flex !important;
    flex-direction: row !important;      /* was column - this is why the rank sat under the name */
    align-items: center !important;
    justify-content: flex-start !important;
    gap: 5px !important;
    width: auto !important; min-width: 0 !important;
    grid-template-columns: none !important;
  }
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player.opponent > span,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player.opponent > span {
    justify-content: flex-end !important;
  }
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player > span > b,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player > span > b {
    flex: 0 1 auto !important; min-width: 0 !important;
    overflow: hidden !important; text-overflow: ellipsis !important; white-space: nowrap !important;
  }
  /* Rank crest: beside the name, matched to its cap height. */
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched .account-rank-icon,
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player > span > small,
  body #pastGames .lobby:has(> .player.matched) > .player.matched .account-rank-icon {
    flex: 0 0 auto !important; width: 14px !important; height: 14px !important;
    margin: 0 !important; align-self: center !important;
  }
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player > img,
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player > img.pav,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player > img,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player > img.pav {
    width: 30px !important; height: 30px !important; border-radius: 50% !important;
    object-fit: cover !important; flex: 0 0 auto !important;
  }

  /* The 3D spin is a .coin3d with two stacked faces that rotate OUT of the box - an overflow:hidden on the
     status clips it, which is why the flip does not read the same as it does on desktop. */
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .match-status,
  #gfLobby .lobby .player.matched > .match-status.spinning { overflow: visible !important; }


  /* ---- 8. ROW: ITEM ART, AVATARS, PLAYER CELLS ---------------------------
     Measured at 430px (iPhone Pro Max) with CSS.getMatchedStylesForNode:
       - the item "box" is the BASE `.offer img { background:#201d28; border:1px solid #302c37; padding:2px }`
         which my own sizing rule never unset. Requested: no box at all.
       - avatars measured 19x19 because an aspect-ratio backstop I added was collapsing them against a height
         constraint. Dropped it and set a real size.
       - the opponent's name OVERLAPPED its avatar by 38.8px: the cell is a grid whose two auto columns do not
         reverse for the mirrored side. Plain flex removes the collision entirely.
     Both cells put the AVATAR FIRST and hug the coin, so the two sides read the same way round. */
  body #gfLobby .lobby.gfl-live > .offer img,
  body #gfLobby .lobby.gfl-past > .offer img,
  body #pastGames .lobby > .offer img {
    width: 46px !important; height: 46px !important;
    background: none !important; background-color: transparent !important; background-image: none !important;
    border: 0 !important; border-radius: 0 !important; padding: 0 !important;
    object-fit: contain !important; margin: 0 !important;
  }
  body #gfLobby .lobby.gfl-live > .offer,
  body #pastGames .lobby > .offer {
    display: flex !important; align-items: center !important;
    gap: 10px !important; background: none !important; border: 0 !important;
  }

  /* Cells as plain flex rows - no grid columns left to collide. */
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player {
    display: flex !important; flex-direction: row !important;
    align-items: center !important; gap: 8px !important;
    grid-template-columns: none !important; min-width: 0 !important;
  }
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player:first-child,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player:first-child {
    justify-content: flex-end !important;
  }
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player.opponent,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player.opponent {
    justify-content: flex-start !important;
  }
  /* No aspect-ratio here - it collapsed the avatar to 19px against a height constraint. */
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player > img,
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player > img.pav,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player > img,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player > img.pav {
    width: 34px !important; height: 34px !important;
    min-width: 34px !important; max-width: 34px !important;
    min-height: 34px !important; max-height: 34px !important;
    aspect-ratio: auto !important;
    border-radius: 50% !important; object-fit: cover !important; flex: 0 0 auto !important;
  }
  /* Give the band room for a 34px face. */
  body #gfLobby .lobby.gfl-live.flip-complete > .player.matched,
  body #gfLobby .lobby.gfl-live.gfl-past > .player.matched,
  body #pastGames .lobby:has(> .player.matched) > .player.matched {
    grid-template-rows: minmax(40px, auto) !important;
  }


  /* THE ROOT CAUSE of "pfp super small" and "user doesn't fill any space": the player cell carries
     `zoom: 0.62` (an older container-query trick noted in experience-polish.css:5346). zoom is invisible to
     getComputedStyle().transform but it DOES scale getBoundingClientRect, so a declared 34px avatar was
     painting at 21.1px and every size I set was silently shrunk by 38%. Reset it and size normally. */
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player {
    zoom: 1 !important;
  }


  /* ---- 9. INLINE SPIN + ROW SPACING --------------------------------------
     THE SPIN BUG: `.coin3d` is 56px but its two `.coin-face` images measured 32px, so the coin that actually
     rotates is small and off-centre inside a larger invisible box - which is why the flip does not read like
     it does on desktop. Container and faces must be the SAME size for the 3D flip to look right. Sized to the
     38px status box so it no longer overhangs either.
     SPACING: the row was 132px = 12px padding + 50px + 9px gap + 48px. Tightened without losing the two
     bands. Items are centred in their column instead of bunching against the left with ~150px of dead space
     before the pot. */
  body #gfLobby .lobby.gfl-live .match-status .coin3d,
  body #pastGames .lobby .match-status .coin3d {
    width: 38px !important; height: 38px !important;
    transform-style: preserve-3d !important;
  }
  body #gfLobby .lobby.gfl-live .match-status .coin3d .coin-face,
  body #pastGames .lobby .match-status .coin3d .coin-face {
    width: 38px !important; height: 38px !important;
    inset: 0 !important; margin: 0 !important; object-fit: contain !important;
  }

  body #gfLobby .lobby.gfl-live:has(> .player.matched),
  body #pastGames .lobby:has(> .player.matched) {
    padding-top: 8px !important; padding-bottom: 8px !important;
    row-gap: 5px !important;
    min-height: 0 !important; height: auto !important;
  }
  body #gfLobby .lobby.gfl-live.flip-complete > .player.matched,
  body #gfLobby .lobby.gfl-live.gfl-past > .player.matched,
  body #pastGames .lobby:has(> .player.matched) > .player.matched {
    grid-template-rows: minmax(38px, auto) !important;
  }
  body #gfLobby .lobby.gfl-live > .offer,
  body #pastGames .lobby > .offer {
    justify-content: center !important;
  }
  body #gfLobby .lobby.gfl-live > .offer img,
  body #gfLobby .lobby.gfl-past > .offer img,
  body #pastGames .lobby > .offer img {
    width: 42px !important; height: 42px !important;
  }


  /* ---- 10. FULL-WIDTH ROW: KILL THE DEAD FLANKS -------------------------
     Measured at 430px. The row is 406px wide and EVERY element was bunched into the middle third:
       host cell   157px wide, content only x=127..182  -> 102px dead on the left
       guest cell  157px wide, content only x=248..315  ->  90px dead on the right
       .offer col  261px wide holding 94px of items, centred at x=109..203 -> ~84px dead EACH side
     So the items were never "placed" anywhere - they floated in an oversized column. Fixes:
       line 1  host hugs the left edge, guest MIRRORS to the right edge (row-reverse, so the avatar lands
               outermost on both sides and reads as a matchup) with the coin between them.
       line 2  items and pot form one tight cluster on the left, VIEW pinned right. Column 1/2 shrink to
               their content instead of stretching, so there is exactly one gap and it sits before the
               action button where it belongs.
     Specificity: game.js's runtime rule is `#gfLobby .lobby:has(> .player.matched)` = (1,5,0) because :has()
     carries its ARGUMENT's weight. `.lobby.lobby` doubles the class legitimately to reach (1,5,1) and win. */
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched),
  body #pastGames .lobby.lobby:has(> .player.matched) {
    grid-template-columns: max-content max-content 1fr !important;
    column-gap: 10px !important;
  }
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched) > .offer,
  body #pastGames .lobby.lobby:has(> .player.matched) > .offer {
    justify-content: flex-start !important; justify-self: start !important;
  }
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched) > .pot,
  body #pastGames .lobby.lobby:has(> .player.matched) > .pot {
    justify-self: start !important; align-self: center !important; margin: 0 !important;
  }
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched) > .actions,
  body #pastGames .lobby.lobby:has(> .player.matched) > .actions {
    justify-self: end !important; justify-content: flex-end !important;
  }

  /* Matchup band spans the full width and the two cells share it evenly. */
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched) > .player.matched,
  body #pastGames .lobby.lobby:has(> .player.matched) > .player.matched {
    grid-template-columns: 1fr auto 1fr !important;
    column-gap: 8px !important;
  }
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player:first-child,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player:first-child {
    justify-content: flex-start !important;
  }
  /* Mirror the guest: avatar outermost, name inboard toward the coin. */
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player.opponent,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player.opponent {
    flex-direction: row-reverse !important;
    justify-content: flex-start !important;
  }

  /* THE CLIPPED SECOND AVATAR: the cell is overflow:hidden and the guest avatar sat at cutL = 0.0 - its edge
     exactly ON the clip boundary - so the 1px border and the winner ring were shaved and the circle read as
     cut off. The host avatar had 101.6px of slack, which is why only one side looked wrong. The name keeps
     its own ellipsis, so the cell does not need to clip anything. */
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player {
    overflow: visible !important;
  }
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player > span,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player > span {
    min-width: 0 !important; overflow: hidden !important;
  }

  /* ---- 11. SIDED ITEMS, CENTRED POT, AVATAR-FIRST ON BOTH SIDES ---------
     Requested shape:  [av name]        (coin)        [av name]
                       [ items ]        G 500         [ items ]
     The pot has to sit on the ROW's centre line, directly under the coin - a pot centred in "whatever is left
     after the VIEW button" lands ~29px off, and an offset that size has been visible every previous time.
     So: five columns, with col1 and col5 the SAME width. That makes col3 the true row centre, and the matchup
     band (spanning cols 2-4, symmetric around col3) centres its coin on the same line. Col1 is empty on line 1
     and carries the host's items on line 2; col5 carries VIEW on line 1 and the guest's items on line 2, so
     neither reserved column is wasted space. */
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched),
  body #pastGames .lobby.lobby:has(> .player.matched) {
    grid-template-columns: 48px minmax(0, 1fr) max-content minmax(0, 1fr) 48px !important;
    grid-template-areas:
      "match match match  match match"
      "offer offer pot    guest guest" !important;
    column-gap: 6px !important;
  }
  /* VIEW is what was breaking the alignment: reserving a column for it forced an EMPTY matching column on the
     other side (the pot has to stay on the row's centre line), which indented the whole matchup band 48px to
     the right of the item strip under it. Retiring the button on mobile lets line 1 span all five columns, so
     the host avatar sits at x=25 exactly above the first item and the guest avatar at the right edge exactly
     above the last one. Tapping the row opens the viewer instead - the delegated handler forwards to this same
     button, so nothing about how a game opens changes. Only MATCHED rows lose it; an open game keeps JOIN. */
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched) > .actions,
  body #pastGames .lobby.lobby:has(> .player.matched) > .actions { display: none !important; }
  /* DISCOVERABILITY: a row that only opens on tap gives the user nothing to look at. The view control is moved
     INSIDE the opponent cell (a script does the move - CSS cannot reparent) and restyled as a trailing chevron,
     the standard "opens a detail view" affordance. Riding inside the cell means it costs the ROW grid nothing,
     so line 1 still spans all five columns and stays aligned with the item strip. It is still the real button,
     so tapping the chevron opens the viewer directly; tapping anywhere else on the row does the same. */
  body #gfLobby .lobby.gfl-live .live-match-player > .actions,
  body #pastGames .lobby .live-match-player > .actions {
    display: flex !important; flex: 0 0 auto !important;
    align-items: center !important; margin: 0 0 0 2px !important; padding: 0 !important;
  }
  body #gfLobby .lobby.gfl-live .live-match-player > .actions .view,
  body #pastGames .lobby .live-match-player > .actions .view {
    width: auto !important; min-width: 0 !important; height: auto !important;
    margin: 0 !important; padding: 0 2px !important;
    border: 0 !important; background: none !important; box-shadow: none !important;
    font-size: 0 !important; line-height: 0 !important;
  }
  body #gfLobby .lobby.gfl-live .live-match-player > .actions .view::after,
  body #pastGames .lobby .live-match-player > .actions .view::after {
    content: "›";
    font: 700 19px/1 "DM Mono", ui-monospace, monospace !important;
    color: #6f6879 !important;
  }
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched),
  body #pastGames .lobby.lobby:has(> .player.matched) {
    cursor: pointer !important; -webkit-tap-highlight-color: transparent !important;
  }
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched):active,
  body #pastGames .lobby.lobby:has(> .player.matched):active { background: #17161d !important; }
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched) > .offer,
  body #pastGames .lobby.lobby:has(> .player.matched) > .offer {
    grid-area: offer !important;
    justify-content: flex-start !important; justify-self: stretch !important;
  }
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched) > .offer.gfl-offer-guest,
  body #pastGames .lobby.lobby:has(> .player.matched) > .offer.gfl-offer-guest {
    grid-area: guest !important;
    justify-content: flex-end !important;
  }
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched) > .pot,
  body #pastGames .lobby.lobby:has(> .player.matched) > .pot {
    grid-area: pot !important;
    justify-self: center !important; align-self: center !important;
    justify-content: center !important; white-space: nowrap !important;
  }
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched) > .actions,
  body #pastGames .lobby.lobby:has(> .player.matched) > .actions {
    grid-area: actions !important;
    justify-self: end !important; align-self: center !important;
  }
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched) > .actions .view,
  body #pastGames .lobby.lobby:has(> .player.matched) > .actions .view {
    width: 48px !important; min-width: 48px !important;
  }
  /* Per-side overflow badge (offerHTML now caps at 3 PER SIDE, so both halves are always represented). */
  body #gfLobby .lobby.gfl-live > .offer > span,
  body #pastGames .lobby > .offer > span {
    /* refine.css:97 hides this on mobile (`.lobby .offer span{display:none}`) and professional.css makes it a
       21px circle; with a per-side cap the count matters, so show it as plain text. */
    display: inline-flex !important; align-items: center !important;
    width: auto !important; height: auto !important; min-width: 0 !important;
    margin: 0 0 0 4px !important; padding: 0 !important;
    font-size: 11px !important; font-weight: 700 !important; color: #baa3e8 !important;
    background: none !important; border: 0 !important; border-radius: 0 !important;
  }
  body #gfLobby .lobby.gfl-live > .offer,
  body #pastGames .lobby > .offer { gap: 8px !important; }
  /* A side is 159px wide and offerHTML caps it at 3. Three 42px tiles plus the badge needed 164px, which
     squeezed the "+2" down to 5px - 38px leaves slack even for a two-digit count (130 + 4 + 24 = 158). */
  body #gfLobby .lobby.lobby.gfl-live:has(> .player.matched) > .offer img,
  body #pastGames .lobby.lobby:has(> .player.matched) > .offer img {
    width: 38px !important; height: 38px !important;
    min-width: 38px !important; flex: 0 0 auto !important;
  }

  /* Guest reads the same way round as the host again: avatar, then name. Section 10 mirrored it with
     row-reverse to push the face to the outer edge; the owner prefers avatar-first on both sides, with the
     pair still anchored to the right edge so the row stays full width. */
  body #gfLobby .lobby.gfl-live:has(> .player.matched) > .player.matched > .live-match-player.opponent,
  body #pastGames .lobby:has(> .player.matched) > .player.matched > .live-match-player.opponent {
    flex-direction: row !important;
    justify-content: flex-end !important;
  }

  /* ---- 12. SETTINGS: MOBILE REVAMP ---------------------------------------
     Audited at 430x932 with the modal open on each tab. What was wrong:
       - the DESKTOP SIDEBAR was simply stacked full width on top. `.set-side` measured 396x312 and the panel
         content did not start until y=357, so more than a third of the screen was chrome and the nav had to be
         scrolled past to reach anything. mobile.css tried to make `.set-nav` a horizontal strip but never beat
         refine.css:2246 `flex-direction: column`, so it stayed a 238px stack of four full rows.
       - `.action-btn` (Log out) ran to x=464 on a 430px screen - 34px off the right edge, unreachable.
       - the close X sat mid-page beside the panel heading at 24px tall, well under the 44px touch minimum.
       - two competing titles: "Manage your account" AND the panel own "Account" heading.
       - nested scrollers (`.set-content` auto inside `.set-card` auto) which is a scroll trap on iOS.
     Shape now: a full-screen sheet with ONE scroll container, a sticky top bar carrying the title and a real
     44px close button, and the four sections as a horizontal pill strip under it. */
  body #settings .set-card {
    width: 100% !important; max-width: none !important;
    height: 100dvh !important; max-height: 100dvh !important;
    margin: 0 !important; padding: 0 !important;
    border: 0 !important; border-radius: 0 !important; box-shadow: none !important;
    display: block !important; overflow-y: auto !important;
    -webkit-overflow-scrolling: touch !important; overscroll-behavior: contain !important;
  }
  body #settings.modal { padding: 0 !important; }
  /* ONE scroller: the card. Everything inside stops competing for the scroll. */
  body #settings .set-body { display: block !important; min-height: 0 !important; }
  body #settings .set-main,
  body #settings .set-content { overflow: visible !important; min-height: 0 !important; display: block !important; }
  body #settings .set-main { padding: 0 14px 28px !important; }

  /* Sticky top bar out of .set-brand: keep the eyebrow as the title, drop the big h1 that duplicated the
     panel own heading. */
  body #settings .set-side {
    position: sticky !important; top: 0 !important; z-index: 6 !important;
    display: block !important; padding: 0 !important; margin: 0 !important;
    border: 0 !important; border-bottom: 1px solid rgba(255,255,255,.09) !important;
    background: #161320 !important;
  }
  body #settings .set-brand {
    display: flex !important; align-items: center !important;
    height: 52px !important; margin: 0 !important; padding: 0 56px 0 14px !important;
  }
  body #settings .set-brand h1 { display: none !important; }
  body #settings .set-brand .set-eyebrow {
    margin: 0 !important; font-size: 11px !important; letter-spacing: .16em !important; color: #b9a6e8 !important;
  }
  /* Fixed, not absolute: the card scrolls, so an absolute button would scroll away from the user. */
  body #settings #set-close {
    position: fixed !important; top: 4px !important; right: 6px !important; z-index: 8 !important;
    width: 44px !important; height: 44px !important; padding: 0 !important;
    display: grid !important; place-items: center !important;
    border: 0 !important; border-radius: 50% !important; background: transparent !important; color: #d6cfe4 !important;
  }
  body #settings #set-close svg { width: 20px !important; height: 20px !important; }

  /* Sections become a horizontal pill strip: label only, no description, no chevron. */
  body #settings .set-nav {
    display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important;
    gap: 6px !important; margin: 0 !important; padding: 0 14px 10px !important;
    border: 0 !important;
    overflow-x: auto !important; overscroll-behavior-x: contain !important;
    scrollbar-width: none !important;
  }
  body #settings .set-nav::-webkit-scrollbar { display: none !important; }
  body #settings .set-nav-item {
    flex: 0 0 auto !important;
    display: inline-flex !important; align-items: center !important; gap: 6px !important;
    min-height: 40px !important; padding: 0 13px !important; margin: 0 !important;
    border: 1px solid rgba(255,255,255,.1) !important;
    border-radius: 999px !important; background: rgba(255,255,255,.03) !important;
    color: #a49bbb !important; white-space: nowrap !important;
  }
  body #settings .set-nav-item.active {
    border-color: rgba(165,107,255,.55) !important; background: rgba(165,107,255,.16) !important; color: #efe8ff !important;
  }
  body #settings .set-nav-item .nav-ic { width: 16px !important; height: 16px !important; flex: 0 0 auto !important; }
  body #settings .set-nav-item .chev,
  body #settings .set-nav-item .copy small { display: none !important; }
  body #settings .set-nav-item .copy strong { font-size: 12.5px !important; font-weight: 700 !important; }

  /* Panel headings: one size down, and the close no longer collides with them. */
  body #settings .set-panel .section-head { margin: 14px 0 12px !important; padding-right: 0 !important; }
  body #settings .set-panel .section-head h2 { font-size: 21px !important; line-height: 1.15 !important; margin: 0 !important; }
  body #settings .set-panel .section-head p { font-size: 12.5px !important; margin: 4px 0 0 !important; }
  body #settings .set-panel .card { padding: 14px !important; margin-bottom: 12px !important; }

  /* Account: avatar + identity on one row, the profile button full width beneath (it was squeezed to the
     right of the name and forced the card wide). */
  body #settings .profile-card {
    display: grid !important;
    grid-template-columns: 64px minmax(0, 1fr) !important;
    gap: 12px !important; align-items: center !important;
  }
  body #settings .profile-card .avatar-shell { width: 64px !important; height: 64px !important; }
  body #settings .profile-card .avatar-shell img,
  body #settings .profile-card .avatar { width: 64px !important; height: 64px !important; }
  body #settings .profile-card .profile-info { min-width: 0 !important; }
  body #settings .profile-card .username-row h3 { font-size: 19px !important; }
  body #settings .profile-card .profile-action {
    grid-column: 1 / -1 !important; width: 100% !important;
    min-height: 44px !important; justify-content: center !important; margin: 2px 0 0 !important;
  }
  /* Four stats in one row wrapped "Total wagered" onto two lines and squashed the numbers. */
  body #settings .stats-card {
    display: grid !important; grid-template-columns: 1fr 1fr !important;
    gap: 12px 10px !important;
  }
  body #settings .stats-card .stat { border: 0 !important; padding: 0 !important; min-width: 0 !important; }
  body #settings .stats-card .stat-label { font-size: 11px !important; white-space: nowrap !important; }
  body #settings .stats-card .stat-value { font-size: 19px !important; }
  /* THE OFF-SCREEN BUTTON: two side-by-side actions do not fit 430px, so stack them. */
  body #settings .actions-row {
    display: grid !important; grid-template-columns: 1fr !important; gap: 8px !important;
  }
  body #settings .actions-row .action-btn {
    width: 100% !important; min-height: 52px !important; margin: 0 !important;
  }

  /* Touch minimums across the remaining tabs (prefs sub-tabs, support report tabs, fairness verifier). */
  body #settings .set-panel [data-a="pref-section"],
  body #settings .set-panel .report-tab,
  body #settings .set-panel .verifier-btn,
  body #settings .set-panel .set-btn {
    min-height: 44px !important; padding-top: 0 !important; padding-bottom: 0 !important;
  }
  body #settings .set-panel input:not([type="range"]),
  body #settings .set-panel select,
  body #settings .set-panel textarea { min-height: 44px !important; font-size: 16px !important; }
  body #settings .set-panel .set-row,
  body #settings .set-panel .set-pref-row { min-height: 52px !important; }

  /* NAV: 2x2 GRID, NOT A SCROLLER. As a horizontal strip the four pills measured 824px wide, so "Provably
     fair" and "Support & safety" sat off the right edge of a 430px screen with nothing to indicate they were
     there - the same hidden-affordance problem the lobby VIEW button had. Two columns fit every label
     ("Support & safety" needs ~153px of the 198px a column gives) and costs one extra 40px row. */
  body #settings .set-nav {
    display: grid !important; grid-template-columns: 1fr 1fr !important;
    gap: 6px !important; overflow: visible !important;
  }
  body #settings .set-nav-item { width: 100% !important; justify-content: flex-start !important; }
  body #settings .set-nav-item .copy { min-width: 0 !important; overflow: hidden !important; }
  body #settings .set-nav-item .copy strong {
    display: block !important; overflow: hidden !important;
    text-overflow: ellipsis !important; white-space: nowrap !important;
  }

  /* Remaining touch minimums: a "Back to report" link in the support section head measured 12px tall, the
     preference sub-tabs 15px, and the volume slider 39px. */
  body #settings .set-panel button:not(.set-switch),
  body #settings .set-panel .chat-rules { min-height: 44px !important; }
  body #settings .set-panel input[type="range"] { height: 44px !important; }
  body #settings .set-panel .section-head {
    display: flex !important; align-items: flex-start !important;
    justify-content: space-between !important; gap: 10px !important; flex-wrap: wrap !important;
  }
}

/* ---- ODDS COLOUR (all widths) ---------------------------------------------
   experience-polish.css:776 paints this #cf9fff, a lavender that reads pink next to the site's purple.
   Outside the media query because a colour should not depend on viewport. */
#viewer .replay-odds b,
.viewer-card .replay-odds b { color: #a56bff !important; }

@media (max-width: 900px) {
  header .header-icons { display: flex !important; align-items: center !important; gap: 4px !important; flex: 0 0 auto !important; }
  header .header-icons > *:not(#notificationButton) { display: none !important; }
  header .header-icons > #notificationButton { display: grid !important; place-items: center !important; position: relative !important; width: 34px !important; height: 34px !important; padding: 0 !important; border: 1px solid #2b2735 !important; border-radius: 8px !important; background: #16141d !important; color: #cfc6de !important; }
  header .header-icons > #notificationButton svg { width: 17px !important; height: 17px !important; }
  header .header-icons > #notificationButton .gf-notification-dot { position: absolute !important; top: 4px !important; right: 4px !important; width: 7px !important; height: 7px !important; border-radius: 50% !important; background: #ff5f7a !important; }
  header .header-icons > #notificationButton .gf-notification-dot[hidden] { display: none !important; }
  .gfn-panel { left: 8px !important; right: 8px !important; top: auto !important; bottom: 8px !important; width: auto !important; max-width: none !important; max-height: 72vh !important; overflow-y: auto !important; }
}
