* { 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 darker, bluer felt than Roulette's, and deliberately so: these two sit
     next to each other on the shelf, they share a chip vocabulary, and the
     fastest way to know which one you opened is the colour. */
  background: linear-gradient(180deg, #082f23 0%, #0c3b2e 55%, #082f23 100%);
  color: #eefbf5; 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: #34d399; color: #0c3b2e; 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: #a7e8cd; }

.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: #a7e8cd; 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: #eefbf5; font-family: inherit; }
.tierCard small { display: block; color: #a7e8cd; font-weight: 700; font-size: 11.5px; }
.tierCard .te { font-size: 26px; display: block; }
.tierCard.sel { border-color: #34d399; 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 15px 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: #a7e8cd; }
.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: #eefbf5; font-family: inherit; font-weight: 800; font-size: 13.5px; cursor: pointer; padding: 4px 2px; }
.seg button.on { background: #34d399; border-color: #0f9b71; color: #0c3b2e; min-height: 44px;}
.blurb { margin: 6px 0 2px; font-size: 12.5px; line-height: 1.45; color: #a7e8cd; }

button.big { width: 100%; border-radius: 16px; min-height: 56px; font-size: 19px; font-weight: 800; background: rgba(0,0,0,0.2); color: #eefbf5; border: 3px solid rgba(255,255,255,0.14); cursor: pointer; font-family: inherit; }
button.big:active { transform: translateY(2px); }
button.big.primary { background: #34d399; border-color: #0f9b71; color: #0c3b2e; 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; }

#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 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: #eefbf5;
       background: rgba(0,0,0,0.24); border: 2px solid rgba(255,255,255,0.16); }
.act:active { transform: translateY(2px); }
.act.primary { background: #34d399; border-color: #0f9b71; color: #04241b; }
.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: #a7e8cd; }
#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; }
.ovl { position: absolute; inset: 0; display: none; align-items: flex-start; justify-content: center; background: rgba(4,36,27,0.58); 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,40,31,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: #a7e8cd; 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: #34d399; 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: #a7e8cd; }
.sdSwing { flex: 0 0 auto; font-size: 13px; font-weight: 800; font-variant-numeric: tabular-nums; color: #fca5a5; }
.sdSwing.up { color: #34d399; }

/* --- 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: #a7e8cd; line-height: 1.3; font-weight: 600; }

#toast { position: fixed; left: 50%; bottom: 84px; transform: translateX(-50%); background: #ffffff; color: #0c3b2e; 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 die face, the puck in both of its states, an
   edge badge in the two colours the table actually uses, and a counter. Each
   one is a GLYPH rather than a picture, because the art column is 46px wide
   and anything with detail in it disappears at that size. */
.lgDie { font-size: 27px; line-height: 1; }
.lgPuck { display: inline-flex; align-items: center; justify-content: center;
          width: 30px; height: 30px; border-radius: 999px; background: #0f172a;
          border: 3px solid rgba(255,255,255,0.4); color: #e2e8f0;
          font-weight: 800; font-size: 9px; }
.lgPuck.on { background: #f8fafc; border-color: #22c55e; color: #0f172a;
             font-size: 15px; }
.lgEdge { display: inline-flex; align-items: center; justify-content: center;
          padding: 3px 5px; border-radius: 7px; background: rgba(0,0,0,0.32);
          font-weight: 800; font-size: 10.5px; white-space: nowrap;
          border: 2px solid currentColor; }
.lgEdge.good { color: #22c55e; }
.lgEdge.bad { color: #ef4444; }
.lgChip { display: inline-flex; align-items: center; justify-content: center;
          width: 26px; height: 26px; border-radius: 999px; background: #facc15;
          color: #3b2f00; font-weight: 800; font-size: 13px; }
.chip#stackChip { border-color: rgba(250,204,21,0.55); color: #fde68a; }

/* THE PRICE LIST IN THE HELP, and it is generated from data.js rather than
   written out -- the same argument as Aggravation's round list. A hand-written
   price list is a price list that will disagree with the table it describes.
   Sorted cheapest first, so the shape of the thing is the lesson: one row at
   0.00%, then a long slide. */
.prices { display: flex; flex-direction: column; gap: 3px; margin-top: 6px; }
.prRow { display: flex; align-items: center; gap: 7px; font-size: 12.5px;
         font-weight: 700; padding: 3px 5px; border-radius: 7px;
         background: rgba(255,255,255,0.05); }
.prDot { flex: none; width: 9px; height: 9px; border-radius: 999px; }
.prName { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden;
          text-overflow: ellipsis; }
.prPay { flex: 0 0 auto; color: #a7e8cd; font-variant-numeric: tabular-nums; }
.prEdge { flex: 0 0 54px; text-align: right; font-weight: 800;
          font-variant-numeric: tabular-nums; }
.prNote { display: block; margin-top: 8px; font-size: 12px; line-height: 1.4;
          color: #a7e8cd; font-weight: 600; }

/* The link out to the printable card (#217). */
.cardLink { display: inline-block; margin-top: 8px; padding: 9px 14px;
            border-radius: 12px; background: rgba(52,211,153,0.16);
            border: 2px solid rgba(52,211,153,0.5); color: #eefbf5;
            font-weight: 800; font-size: 14px; text-decoration: none; min-height: 44px;}
