* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  /* A cool blue felt, and deliberately not the green of the rummy pair or the
     saloon red of Pitch: this is the thinking game on the shelf, and the shelf
     is easier to navigate when the colour is part of the name. */
  background: linear-gradient(180deg, #14532d 0%, #166534 55%, #14532d 100%);
  color: #f0fdf4; user-select: none; -webkit-user-select: none;
  touch-action: none; overflow: hidden;
}
#app { height: 100%; display: flex; flex-direction: column; max-width: min(100%, 860px); margin: 0 auto; }

#hdr { display: flex; align-items: center; gap: 8px; padding: 8px 12px; padding-top: max(8px, env(safe-area-inset-top)); }
#hdr .pill { background: rgba(0,0,0,0.22); border: 2px solid rgba(255,255,255,0.16); border-radius: 999px; padding: 6px 11px; font-weight: 800; font-size: 15px; min-width: 44px; min-height: 44px; display: flex; align-items: center; cursor: pointer; justify-content: center; color: inherit; font-family: inherit; }
#hdrHome { border: none; background: #4ade80; color: #14532d; font-size: 18px; }
#hdrStatus { flex: 1; min-width: 0; text-align: center; font-weight: 800; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #bbf7d0; }

.scr { flex: 1; display: none; flex-direction: column; overflow-y: auto; padding: 6px 14px 18px; }
/* The table gets the full width: side padding comes straight off the card size. */
#scr-play { padding: 6px 4px 6px; }
.scr.on { display: flex; }

#scr-menu { align-items: center; text-align: center; gap: 12px; justify-content: center; }
#scr-menu h1 { font-size: clamp(32px, 9vw, 44px); color: #ffffff; }
#scr-menu .sub { color: #bbf7d0; font-weight: 600; margin-bottom: 4px; }
#tierRow { display: flex; gap: 8px; width: 100%; }
.tierCard { flex: 1; background: rgba(0,0,0,0.2); border: 3px solid rgba(255,255,255,0.14); border-radius: 16px; padding: 10px 4px; font-weight: 800; font-size: 14px; line-height: 1.35; cursor: pointer; color: #f0fdf4; font-family: inherit; }
.tierCard small { display: block; color: #bbf7d0; font-weight: 700; font-size: 11.5px; }
.tierCard .te { font-size: 26px; display: block; }
.tierCard.sel { border-color: #4ade80; background: rgba(74,222,128,0.16); }

/* Settings, behind a disclosure — the same shape as every other product's. */
#custom { width: 100%; margin: 2px 0; text-align: left; background: rgba(0,0,0,0.2); border: 3px solid rgba(255,255,255,0.13); border-radius: 16px; padding: 6px 12px 10px; }
#custom > summary { list-style: none; cursor: pointer; font-weight: 800; font-size: 16px; padding: 10px 2px; min-height: 44px; display: flex; align-items: center; gap: 8px; }
#custom > summary::-webkit-details-marker { display: none; }
#custom > summary::before { content: "▸"; transition: transform .12s; }
#custom[open] > summary::before { transform: rotate(90deg); }
/* WRAPS (R-G26.9). A settings row is [label][segmented control], and the
   control's width is decided by its option labels at runtime. Measured at
   320px this row ran 47px past the screen edge, so the last option was
   cut in half — a control you cannot see or reliably hit. Wrapping drops
   the control onto its own line ONLY when it has to; at 375px and wider
   nothing moves. */
.field { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 7px 0; }
.field .lbl { flex: 0 0 104px; font-size: 13.5px; font-weight: 800; color: #bbf7d0; }
.seg { flex: 1; display: flex; gap: 6px; }
.seg button { flex: 1; min-height: 44px; border-radius: 11px; border: 2px solid rgba(255,255,255,0.16); background: rgba(0,0,0,0.24); color: #f0fdf4; font-family: inherit; font-weight: 800; font-size: 13.5px; cursor: pointer; padding: 4px 2px; }
.seg button.on { background: #4ade80; border-color: #16a34a; color: #14532d; min-height: 44px;}
.blurb { margin: 6px 0 2px; font-size: 12.5px; line-height: 1.45; color: #bbf7d0; }

button.big { width: 100%; border-radius: 16px; min-height: 56px; font-size: 19px; font-weight: 800; background: rgba(0,0,0,0.2); color: #f0fdf4; border: 3px solid rgba(255,255,255,0.14); cursor: pointer; font-family: inherit; }
button.big:active { transform: translateY(2px); }
button.big.primary { background: #4ade80; border-color: #16a34a; color: #14532d; min-height: 44px;}

/* --- play ----------------------------------------------------------------- */
/* THE SCOREBOARD ROW (R-C19). Fixed height, and nothing in it changes width by
   more than a digit, so a message arriving cannot shove the numbers sideways. */
#playTop { display: flex; font-size: 13px; gap: 5px; min-height: 30px;
           align-items: stretch; justify-content: flex-start; padding: 2px 2px 3px;
           font-weight: 800; }
#playTop .gap { flex: 1 1 auto; min-width: 0; }
.chip { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px;
        padding: 0 8px; border-radius: 999px; background: rgba(0,0,0,0.26);
        border: 2px solid rgba(255,255,255,0.14); line-height: 1; }
.chip i { font-style: normal; font-size: 10px; font-weight: 800; opacity: 0.72; letter-spacing: 0.02em; }
.chip b { font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums; }

/* R13. THE OVER/UNDER CHIP, AND IT IS THE MOST USEFUL THING ON THE SCREEN.
   `5/4` means five tricks bid and four to be had: the table is fighting and
   somebody is going down. `3/4` means one is going spare and will be handed to
   whoever least wants it. Colour says which, and the numbers say it too —
   colour is never the only carrier. */

#msgLine { flex: none; min-height: 20px; display: flex; align-items: center; justify-content: center; padding: 0 4px 3px; }
#msgOut { font-weight: 800; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }

#stageWrap { flex: 1; position: relative; min-height: 0; }
canvas#stage { display: block; touch-action: none; }

/* THE BID ROW IS ALWAYS HERE, EVEN WITH NOTHING TO SAY. `visibility`, not
   `display`: hiding it with display:none makes #stageWrap taller, which re-fits
   the canvas, which re-lays the whole table — so every card resizes and slides
   the moment the row appears, and slides back when it goes (R-C19). */
/* The action row is ALWAYS here and always the same height (R-C19): three
   controls that are sometimes disabled, never three controls that come and go.
   A row that appears re-fits the canvas and moves the whole board. */
#actRow { flex: none; display: flex; gap: 8px; justify-content: center;
          align-items: center; min-height: 60px;
          padding: 8px 6px max(4px, env(safe-area-inset-bottom)); }
.act { flex: 1 1 0; min-height: 46px; border-radius: 13px; font-family: inherit;
       font-weight: 800; font-size: 15px; cursor: pointer; color: #f0fdf4;
       background: rgba(0,0,0,0.24); border: 2px solid rgba(255,255,255,0.16); }
.act:active { transform: translateY(2px); }
.act.primary { background: #4ade80; border-color: #16a34a; color: #052e16; }
.act:disabled { opacity: 0.42; cursor: default; transform: none; }

/* R19. The record, and it looks like a record: one weight, one colour, in the
   order they happened. Nothing here may suggest a pattern, because there is
   not one — see R11, which forbids "hot" and "due" anywhere in the product. */
#histLine { flex: none; display: flex; align-items: center; gap: 8px;
            min-height: 22px; padding: 0 8px 2px; font-size: 12px;
            font-weight: 700; color: #bbf7d0; }
#histLine i { font-style: normal; font-size: 10px; opacity: 0.7;
              letter-spacing: 0.02em; flex: 0 0 auto; }
#histOut { flex: 1 1 auto; min-width: 0; font-variant-numeric: tabular-nums;
           white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* R12. THE HOOK, SHOWN RATHER THAN REMOVED. The dealer may not make the bids
   add up, and the barred number is greyed IN PLACE with the reason on it —
   dropping it from the row would make the row one shorter and teach nothing.
   Kept tappable so the explanation has somewhere to come from. */

.ovl { position: absolute; inset: 0; display: none; align-items: flex-start; justify-content: center; background: rgba(5,46,22,0.55); border-radius: 12px; padding: 16px; overflow-y: auto; }
.ovl.on { display: flex; }
/* The overlay REPORTS ON THE TABLE, so it must not hide the table: the scrim is
   a dim and the words sit on a panel of their own. */
.ovlCard { text-align: center; width: 100%; max-width: 360px; display: flex; flex-direction: column; gap: 10px;
           background: rgba(6,44,22,0.96); border: 2px solid rgba(255,255,255,0.16);
           border-radius: 18px; padding: 16px 14px; box-shadow: 0 10px 30px rgba(0,0,0,0.45); margin: auto;}
#ovlTitle { font-size: 26px; font-weight: 800; color: #ffffff; }
#ovlSub { color: #bbf7d0; font-weight: 700; min-height: 22px; line-height: 1.45;
          display: flex; flex-direction: column; gap: 5px; }

/* THE RESULT ROWS ("a result must carry its evidence"). One row per player:
   what they said, what they got, what it was worth. Same class names as the
   other card games, because it is the same idea and a second vocabulary for it
   would drift. */
.sdRow { display: flex; align-items: center; gap: 7px; padding: 5px 7px; border-radius: 10px;
         background: rgba(255,255,255,0.05); border: 2px solid transparent; text-align: left; }
.sdRow.you { background: rgba(255,255,255,0.10); }
.sdRow.win { border-color: #4ade80; background: rgba(74,222,128,0.14); }
.sdWho { flex: 0 0 62px; font-size: 13px; font-weight: 800; }
.sdHand { flex: 1 1 auto; font-size: 12px; font-weight: 700; line-height: 1.25; color: #bbf7d0; }
.sdSwing { flex: 0 0 auto; font-size: 13px; font-weight: 800; font-variant-numeric: tabular-nums; color: #fca5a5; }
.sdSwing.up { color: #4ade80; }

/* --- help ----------------------------------------------------------------- */
#scr-how .card { background: rgba(0,0,0,0.2); border: 3px solid rgba(255,255,255,0.13); border-radius: 16px; padding: 14px; margin-bottom: 10px; font-size: 15px; line-height: 1.55; font-weight: 600; }
#scr-how h2 { margin-bottom: 8px; color: #ffffff; }
#scr-how ul { margin: 6px 0 0 18px; }
#scr-how li { margin: 3px 0; }

/* The legend (R-L1). One column of swatches at a fixed width, so the eye can
   run the column instead of the prose. */
.legend { display: flex; flex-direction: column; gap: 7px; }
.lgRow { display: flex; align-items: center; gap: 10px; }
.lgArt { flex: none; width: 46px; display: flex; align-items: center; justify-content: center; }
.lgTxt { display: flex; flex-direction: column; min-width: 0; }
.lgTxt b { font-size: 14px; font-weight: 800; }
.lgTxt small { font-size: 12.5px; color: #bbf7d0; line-height: 1.3; font-weight: 600; }

#toast { position: fixed; left: 50%; bottom: 84px; transform: translateX(-50%); background: #ffffff; color: #14532d; font-weight: 800; padding: 9px 16px; border-radius: 999px; opacity: 0; transition: opacity 0.25s; pointer-events: none; z-index: 40; max-width: calc(100vw - 32px); text-align: center; }
#toast.on { opacity: 1; }

/* docs/offline-pwa.md R-C15 — the PAGE must never scroll. */
html, body { overflow: hidden; overscroll-behavior: none; }
.scr { overscroll-behavior: contain; }

/* A TURNED PHONE HAS NO SPARE ROWS (R-T6). Every line of chrome here is a line
   the felt does not get, and at 375px of window height the felt is what the
   game IS. The text shrinks and the reserved rows tighten; the 44px touch floor
   on the action row does not move, because that is the one thing that must
   never give way — the whole board is a tap target and the three controls
   under it are the only way to resolve one. */
@media (orientation: landscape) and (max-height: 500px) {
  #hdr { padding: 4px 10px; padding-top: max(4px, env(safe-area-inset-top)); }
  #playTop { padding: 0 4px 2px; font-size: 12px; min-height: 0; }
  #msgLine { min-height: 15px; padding: 0 4px 1px; }
  #msgOut { font-size: 11.5px; }
  #actRow { min-height: 52px; padding: 4px 6px max(2px, env(safe-area-inset-bottom)); }
  #histLine { min-height: 18px; font-size: 11px; }
}
/* #228: the landscape footer float lives in version.js, which owns the footer's
   layout for every product. Nothing product-specific is left here. */

/* The legend's own swatches. A pip is a pocket, a chip is a counter, and the
   odds swatch is the pairing this whole product exists for. */
.lgPip { display: inline-block; width: 22px; height: 22px; border-radius: 999px;
         border: 2px solid rgba(255,255,255,0.35); }
.lgPip.red { background: #b91c1c; }
.lgPip.green { background: #15803d; }
.lgChip { display: inline-flex; align-items: center; justify-content: center;
          width: 24px; height: 24px; border-radius: 999px; background: #facc15;
          color: #3b2f00; font-weight: 800; font-size: 13px; }
.lgOdds { display: inline-flex; align-items: center; justify-content: center;
          padding: 3px 6px; border-radius: 7px; background: rgba(0,0,0,0.3);
          border: 2px solid rgba(255,255,255,0.2); font-weight: 800;
          font-size: 10.5px; white-space: nowrap; }
.chip#stackChip { border-color: rgba(250,204,21,0.55); color: #fde68a; }

/* R23 — the number chooser. Reached by tapping a number; the only way to place
   a split, street, corner or line, because those live on grid lines a finger
   cannot hit. Rows are full width and 46px so the tap floor holds however many
   there are (twelve, for a number in the middle of the grid). */
#pickCard { max-width: 340px; gap: 8px; }
#pickTitle { font-size: 17px; font-weight: 800; color: #fde68a; }
#pickList { display: flex; flex-direction: column; gap: 6px;
            /* R-C13: vh first for anything that does not know dvh, then dvh,
               which is the one that tracks a phone's collapsing toolbar. */
            max-height: 52vh; max-height: 52dvh; overflow-y: auto; }
.pickRow { display: flex; align-items: center; justify-content: space-between;
           gap: 10px; min-height: 46px; padding: 0 12px; border-radius: 12px;
           font-family: inherit; cursor: pointer; text-align: left;
           color: #f0fdf4; background: rgba(0,0,0,0.26);
           border: 2px solid rgba(255,255,255,0.16); }
.pickRow:active { transform: translateY(2px); }
/* Already has a chip on it — the same gold the felt uses for a staged bet, so
   the two views of the same fact look like the same fact. */
.pickRow.staged { border-color: #fbbf24; }
.pickName { font-size: 15px; font-weight: 800; }
/* R8. The payout AND the chance, on the control, before the tap. */
.pickOdds { display: flex; flex-direction: column; align-items: flex-end;
            font-size: 14px; font-weight: 800; color: #fde68a; line-height: 1.1; }
.pickOdds i { font-style: normal; font-size: 10.5px; font-weight: 700;
              color: #dcfce7; opacity: 0.8; }
