/* THE FELT - 04-sim.css
   the simulator shell shared by Practice and Tournament Practice: tabbed
   workspace, horizontal stat strip, live reads rail, replay and leak views.
   Part of a multi-file build; load order is fixed in The_Felt.html. */

/* ============================================================
   THE PROBLEM THIS FILE SOLVES
   The old Practice view stacked four panels - session, hand report, long run,
   session log - into one 340px column beside the table. Everything you needed
   while playing and everything you needed after playing fought for the same
   narrow strip, so the table was small and the reading was cramped.

   The fix is to separate the two. What you need WHILE a hand is live sits
   around the table: a stat strip above it, a reads rail beside it, the action
   bar under it. Everything you only look at BETWEEN hands - history, leaks,
   the long run - moves into its own tab and gets the full width.
   ============================================================ */

.sim{display:flex;flex-direction:column;gap:14px;}

/* ---------- tabs ---------- */
/* The track is cut INTO the page and the active tab sits ON it. A flat tint
   on a flat ground gave no clue which of the two was in front, which is most
   of why this row read as cheap. */
.sim-tabs{display:flex;gap:3px;padding:4px;background:var(--g-well);
  border:1px solid var(--border);border-radius:var(--r);align-self:flex-start;
  max-width:100%;overflow-x:auto;scrollbar-width:none;
  box-shadow:inset 0 1px 3px rgba(0,0,0,.45);}
.sim-tabs::-webkit-scrollbar{display:none;}
.sim-tabs button{font-size:13px;font-weight:600;color:var(--text2);background:transparent;
  border:0;border-radius:var(--r-sm);padding:8px 16px;cursor:pointer;white-space:nowrap;
  transition:background var(--t),color var(--t),box-shadow var(--t);display:flex;align-items:center;gap:7px;}
.sim-tabs button:hover{color:var(--text);background:rgba(255,255,255,.05);}
.sim-tabs button.on{background:var(--g-accent);color:var(--accent-ink);
  box-shadow:var(--hair-strong),0 2px 10px -3px var(--accent-glow);}
.sim-tabs .cnt{font-family:var(--mono);font-size:10px;padding:1px 6px;border-radius:99px;
  background:var(--surface3);color:var(--text3);}
/* on the lit pill the count is a hole punched in it, not a second pill */
.sim-tabs button.on .cnt{background:rgba(0,0,0,.26);color:var(--accent-ink);}

.sim-pane{display:none;}
.sim-pane.on{display:block;}

/* ---------- the stat strip ----------
   The numbers that used to live in a stacked right-hand panel, laid out
   horizontally above the table where they cost no width at all. */
.strip{display:flex;flex-wrap:wrap;gap:0;background:var(--g-surface);
  border:1px solid var(--border);border-radius:var(--r);overflow:hidden;
  box-shadow:var(--shadow-sm);}
.strip .cell{flex:1 1 auto;min-width:88px;padding:6px 12px;
  border-right:1px solid var(--border);display:flex;flex-direction:column;gap:1px;}
.strip .cell:last-child{border-right:0;}
.strip .k{font-family:var(--mono);font-size:9px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--text3);white-space:nowrap;}
.strip .v{font-family:var(--disp);font-size:15px;font-weight:600;color:var(--text);
  line-height:1.15;white-space:nowrap;}
/* up is green and down is red because that is the one place a result number
   is genuinely positive or negative; the rest of the chrome stays indigo */
.strip .v.up{color:var(--call-hi);}
.strip .v.dn{color:var(--raise);}
.strip .v.sm{font-size:14px;}
.strip .cell.hi{background:var(--accent-dim);}
.strip .cell.warn{background:rgba(229,72,77,.10);}

/* ---------- the playing area ---------- */
.sim-main{display:grid;grid-template-columns:minmax(0,1fr) 296px;gap:14px;align-items:start;}
.sim-felt{display:flex;flex-direction:column;gap:12px;min-width:0;}
.sim-felt .panel{margin:0;}

/* the table gets to be big now that it is not sharing the row with four panels */
.sim-stage{padding:14px 14px 34px;}
.sim-stage .ptable{max-width:none;}

/* ---------- reads rail ---------- */
.reads{display:flex;flex-direction:column;gap:8px;position:sticky;top:72px;
  max-height:calc(100vh - 88px);overflow-y:auto;padding-right:2px;}
.reads::-webkit-scrollbar{width:6px;}
.reads::-webkit-scrollbar-thumb{background:var(--border2);border-radius:99px;}
.reads h4{margin:0;font-family:var(--mono);font-size:9px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--text3);padding:0 2px;}

.rcard{background:var(--g-surface);border:1px solid var(--border);border-radius:var(--r-sm);
  padding:9px 10px;display:flex;flex-direction:column;gap:6px;
  box-shadow:var(--shadow-sm);transition:border-color var(--t),box-shadow var(--t);}
/* the seat that is actually acting gets lit rather than just outlined - the
   rail is eight near-identical cards and one of them has to win */
.rcard.live{border-color:var(--accent-line);
  box-shadow:var(--shadow-sm),0 0 16px -6px var(--accent-glow);}
.rcard.folded{opacity:.4;}
.rcard.hero{border-color:var(--border2);background:var(--g-surface2);}
.rcard .top{display:flex;align-items:center;gap:7px;}
.rcard .nm{font-weight:600;font-size:12.5px;color:var(--text);flex:1;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.rcard .stk{font-family:var(--mono);font-size:11px;color:var(--text2);white-space:nowrap;}
.rcard .pos{font-family:var(--mono);font-size:9px;padding:1px 5px;border-radius:4px;
  background:var(--surface3);color:var(--text3);}

/* the stat line: only what you could actually track live */
.rstats{display:flex;gap:8px;flex-wrap:wrap;}
.rstats span{font-family:var(--mono);font-size:10px;color:var(--text3);}
.rstats b{color:var(--text2);font-weight:600;}
.rstats .thin{opacity:.5;}

/* commitment: how much of their stack is already in the middle */
/* every bar in the app is the same two-part object: a track cut into the
   surface, and a fill lit along its own top edge */
.commit{height:4px;border-radius:99px;background:var(--g-well);overflow:hidden;
  box-shadow:inset 0 1px 2px rgba(0,0,0,.55);}
.commit i{display:block;height:100%;background:var(--bet);transition:width .25s;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.28);}
.commit.deep i{background:var(--raise);}
.ctext{font-size:10.5px;color:var(--bet);font-weight:600;}
.ctext.deep{color:var(--raise);}

.rread{font-size:11.5px;color:var(--text2);line-height:1.4;}
/* who covers whom. The single most useful fact about a seat before a hand
   starts, and the felt had no way of saying it. */
.rcover{font-family:var(--mono);font-size:10px;color:var(--text3);
  display:flex;gap:5px;align-items:baseline;}
.rcover b{font-weight:600;color:var(--text2);text-transform:uppercase;
  letter-spacing:.08em;font-size:9px;}
.rcover.good b{color:var(--accent-hi);}
.rcover.warn b{color:var(--gold);}
.radvice{font-size:11.5px;color:var(--accent-hi);font-weight:600;line-height:1.4;}
.rtell{font-size:11px;color:var(--gold);font-style:italic;}

/* ============================================================
   THE COACH
   Rebuilt. The old version was one line - a verb, a sentence and a string
   of frequencies - sitting in a div with no positioning underneath an
   action bar that was pulled 30px up over the top of it.

   What it is now: a verdict block whose colour is the colour of the button
   it is telling you to press, the reasoning, and the four or five numbers
   that actually priced the decision - the pot, the price, the equity you
   need, the effective stack and the SPR. Those numbers were all computed
   every hand already and thrown away.
   ============================================================ */
/* This is the primary instrument on the screen, so it is the one panel that
   gets a border a step brighter than everything else plus the full shadow.
   If two things on the felt look equally important, this one has failed. */
.coachdock{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:0;
  background:var(--g-surface);border:1px solid var(--border3);
  border-radius:var(--r);overflow:hidden;align-items:stretch;
  box-shadow:var(--shadow);
}
.cd-verdict{
  display:flex;flex-direction:column;justify-content:center;gap:1px;
  padding:9px 15px;min-width:118px;border-right:1px solid var(--border);
  background:var(--g-surface2);border-left:3px solid var(--text3);
}
.cd-verb{font-family:var(--disp);font-size:19px;font-weight:700;
  letter-spacing:.02em;line-height:1.05;color:var(--text);}
.cd-amt{font-family:var(--mono);font-size:11.5px;font-weight:600;color:var(--text2);}
/* The 3px stripe was the only thing carrying the advice's colour, and at a
   glance from the felt it was too small to register. The wash bleeds that
   same hue in off the stripe, so the dock changes colour with the verdict and
   you know what it says before you have read the verb. Blue folds, green
   calls, red raises - the same code as the buttons underneath. */
.cd-verdict.a-fold{border-left-color:var(--fold);
  background:linear-gradient(100deg,rgba(91,125,177,.26),rgba(91,125,177,.03) 76%),var(--g-surface2);}
.cd-verdict.a-fold .cd-verb{color:var(--fold-hi);}
.cd-verdict.a-call{border-left-color:var(--call);
  background:linear-gradient(100deg,rgba(63,169,106,.26),rgba(63,169,106,.03) 76%),var(--g-surface2);}
.cd-verdict.a-call .cd-verb{color:var(--call-hi);}
.cd-verdict.a-bet{border-left-color:var(--raise);
  background:linear-gradient(100deg,rgba(229,72,77,.24),rgba(229,72,77,.03) 76%),var(--g-surface2);}
.cd-verdict.a-bet .cd-verb{color:var(--raise-hi);}

.cd-body{display:flex;flex-direction:column;justify-content:center;gap:6px;
  padding:8px 14px;min-width:0;}
/* The reasoning varies from four words to a paragraph - the tournament coach
   in particular explains the whole spot. Left unbounded that made the felt a
   different size on every decision, which is worse than either extreme. It
   gets three comfortable lines and scrolls past them, so nothing is hidden
   and the table never moves. */
.cd-why{font-size:12px;line-height:1.45;color:var(--text2);margin:0;
  max-height:53px;overflow-y:auto;overscroll-behavior:contain;padding-right:4px;}
.cd-why::-webkit-scrollbar{width:4px;}
.cd-why::-webkit-scrollbar-thumb{background:var(--border2);border-radius:99px;}
.cd-why b{color:var(--text);}
.cd-facts{display:flex;gap:14px;flex-wrap:wrap;}
.cd-facts span{display:flex;align-items:baseline;gap:5px;white-space:nowrap;}
.cd-facts i{font-family:var(--mono);font-size:8.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--text3);font-style:normal;}
.cd-facts b{font-family:var(--mono);font-size:11.5px;font-weight:600;color:var(--text);}
.cd-facts b.warn{color:var(--gold);}
.cd-facts b.good{color:var(--accent-hi);}

/* the mix, as a bar rather than a string of percentages */
/* the mix column is cut into the dock rather than sitting on it, so the
   verdict and the reasoning stay the two things in front */
.cd-mix{display:flex;flex-direction:column;justify-content:center;gap:5px;
  padding:9px 14px;border-left:1px solid var(--border);
  background:var(--g-well);min-width:132px;
  box-shadow:inset 0 1px 3px rgba(0,0,0,.45);}
.cd-mix .lbl{font-family:var(--mono);font-size:8.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--text3);}
.mixbar{display:flex;height:7px;border-radius:99px;overflow:hidden;
  background:var(--bg2);box-shadow:inset 0 1px 2px rgba(0,0,0,.6);}
.mixbar i{display:block;height:100%;box-shadow:inset 0 1px 0 rgba(255,255,255,.22);}
.mixbar i.m-fold{background:var(--fold);}
.mixbar i.m-call{background:var(--call);}
.mixbar i.m-bet{background:var(--raise);}
.cd-mix .keys{display:flex;gap:9px;flex-wrap:wrap;}
.cd-mix .keys span{font-family:var(--mono);font-size:10px;color:var(--text2);}
.cd-mix .keys u{text-decoration:none;opacity:.62;}

/* the tournament variant: when ICM is what is really pricing the decision,
   the whole dock says so rather than burying it in the sentence */
/* gold, because when ICM is pricing the decision the thing being weighed is
   money rather than chips - and the wash overrides the action colour on
   purpose, since that is the whole point of the variant */
.coachdock.icm{border-color:rgba(232,180,76,.5);
  box-shadow:var(--shadow),0 0 22px -10px rgba(232,180,76,.45);}
.coachdock.icm .cd-verdict{
  background:linear-gradient(100deg,rgba(232,180,76,.20),rgba(232,180,76,.03) 76%),var(--g-surface2);}
.coachdock.icm .cd-why b{color:var(--gold);}

/* ---------- hand history browser ---------- */
.hfilters{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:12px;}
/* inputs are recessed everywhere else in the app; these were the one row
   that still looked raised, which read as buttons */
.hfilters select,.hfilters input{background:var(--g-well);border:1px solid var(--border2);
  color:var(--text);border-radius:var(--r-sm);padding:6px 9px;font-size:12px;font-family:var(--ui);
  box-shadow:inset 0 1px 3px rgba(0,0,0,.45);
  /* the app's base rule makes form controls full width; a filter row wants
     them side by side, so pin them to their own content instead */
  width:auto;flex:0 0 auto;min-width:118px;max-width:190px;}
.hfilters .clr{background:transparent;border:1px solid var(--border);color:var(--text3);
  border-radius:var(--r-sm);padding:6px 11px;font-size:12px;cursor:pointer;}
.hfilters .clr:hover{color:var(--text);border-color:var(--border2);}

.hlist{display:flex;flex-direction:column;gap:4px;max-height:62vh;overflow-y:auto;}
.hrow{display:grid;grid-template-columns:52px 1fr auto auto;gap:10px;align-items:center;
  padding:8px 10px;background:var(--g-surface);border:1px solid var(--border);
  border-radius:var(--r-sm);cursor:pointer;box-shadow:var(--shadow-sm);
  transition:border-color var(--t),background var(--t),box-shadow var(--t);}
.hrow:hover{border-color:var(--accent-line);background:var(--g-surface2);}
/* the wash sits ON the row's own gradient rather than replacing it - the base
   row and the hover state are both opaque objects, and a selected row that
   went translucent was the one raised thing in here with no ground of its own */
.hrow.on{border-color:var(--accent-line);
  background:linear-gradient(180deg,rgba(82,96,222,.22),rgba(82,96,222,.08)),var(--g-surface);
  box-shadow:var(--shadow-sm),0 0 16px -6px var(--accent-glow);}
.hrow .hno{font-family:var(--mono);font-size:10px;color:var(--text3);}
.hrow .hcards{display:flex;gap:3px;align-items:center;}
.hrow .hmeta{font-size:11.5px;color:var(--text2);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
.hrow .hnet{font-family:var(--mono);font-size:12px;font-weight:600;text-align:right;}
/* same rule as the stat strip: a won hand is green, a lost one is red */
.hrow .hnet.up{color:var(--call-hi);}
.hrow .hnet.dn{color:var(--raise);}

/* ---------- replay ---------- */
.replay{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:14px;align-items:start;}
.rp-controls{display:flex;align-items:center;gap:8px;justify-content:center;margin-top:10px;
  flex-wrap:wrap;}
.rp-controls .btn{min-width:40px;}
.rp-scrub{flex:1;min-width:140px;accent-color:var(--accent);}
.rp-step{font-family:var(--mono);font-size:11px;color:var(--text3);min-width:64px;text-align:center;}
.rp-log{display:flex;flex-direction:column;gap:2px;max-height:46vh;overflow-y:auto;
  font-size:12px;}
.rp-log .ln{padding:5px 9px;border-radius:6px;color:var(--text2);cursor:pointer;
  border-left:2px solid transparent;}
.rp-log .ln:hover{background:var(--surface2);}
.rp-log .ln.on{background:var(--accent-dim);color:var(--text);border-left-color:var(--accent);}
.rp-log .ln.head{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--text3);margin-top:6px;cursor:default;}
.rp-log .ln.head:hover{background:transparent;}
.rp-log .ln.hero{color:var(--text);font-weight:600;}
.rp-log .ln .g{font-family:var(--mono);font-size:9px;padding:0 4px;border-radius:3px;
  margin-left:6px;}

/* ---------- leaks ---------- */
.leakgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));gap:10px;}
.leak{background:var(--g-surface);border:1px solid var(--border);border-radius:var(--r-sm);
  padding:11px 13px;display:flex;flex-direction:column;gap:7px;box-shadow:var(--shadow-sm);}
.leak.bad{border-color:rgba(229,72,77,.4);
  box-shadow:var(--shadow-sm),0 0 18px -8px rgba(229,72,77,.5);}
.leak .lt{display:flex;align-items:baseline;gap:8px;}
.leak .ln2{font-weight:600;font-size:13px;color:var(--text);flex:1;}
.leak .lc{font-family:var(--mono);font-size:12px;font-weight:600;color:var(--raise);}
.leak .lm{font-family:var(--mono);font-size:10px;color:var(--text3);}
.leak .lbar{height:4px;border-radius:99px;background:var(--g-well);overflow:hidden;
  box-shadow:inset 0 1px 2px rgba(0,0,0,.55);}
.leak .lbar i{display:block;height:100%;background:var(--raise);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.28);}
.leak .lw{font-size:11.5px;color:var(--text2);line-height:1.45;}

/* ---------- tournament lobby ---------- */
.lobby{display:grid;grid-template-columns:repeat(auto-fill,minmax(310px,1fr));gap:12px;}
.ev{background:var(--g-surface);border:1px solid var(--border);border-radius:var(--r);
  padding:14px 15px;display:flex;flex-direction:column;gap:9px;box-shadow:var(--shadow-sm);
  transition:border-color var(--t),box-shadow var(--t);}
.ev:hover{border-color:var(--accent-line);
  box-shadow:var(--shadow-sm),0 0 18px -8px var(--accent-glow);}
.ev.today{border-color:var(--accent-line);
  box-shadow:var(--shadow-sm),0 0 22px -9px var(--accent-glow);}
.ev .evtop{display:flex;align-items:flex-start;gap:9px;}
.ev .evn{font-family:var(--disp);font-size:15px;font-weight:600;color:var(--text);flex:1;
  line-height:1.25;}
/* the buy-in is a price, and every price in this app is gold */
.ev .evb{font-family:var(--mono);font-size:14px;font-weight:600;color:var(--gold-hi);
  white-space:nowrap;}
.ev .evd{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text3);}
.ev .evgrid{display:grid;grid-template-columns:1fr 1fr;gap:5px 12px;}
.ev .evgrid div{display:flex;justify-content:space-between;gap:8px;font-size:11.5px;
  color:var(--text3);}
.ev .evgrid b{font-family:var(--mono);color:var(--text2);font-weight:600;}
.ev .evnote{font-size:11.5px;color:var(--text2);line-height:1.45;font-style:italic;}
.ev .evtag{font-family:var(--mono);font-size:9px;padding:2px 6px;border-radius:4px;
  background:var(--surface3);color:var(--text3);align-self:flex-start;}
.ev .evtag.live{background:var(--accent-dim);color:var(--accent-hi);
  box-shadow:inset 0 0 0 1px var(--accent-line);}

/* ---------- tournament status strip ---------- */
.trnbar{display:flex;flex-wrap:wrap;gap:0;background:var(--g-surface);
  border:1px solid var(--border2);border-radius:var(--r);overflow:hidden;
  box-shadow:var(--shadow-sm);}
.trnbar .cell{flex:1 1 auto;min-width:88px;padding:8px 13px;border-right:1px solid var(--border);}
.trnbar .cell:last-child{border-right:0;}
.trnbar .k{font-family:var(--mono);font-size:9px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--text3);}
.trnbar .v{font-family:var(--disp);font-size:16px;font-weight:600;color:var(--text);}
/* money and the bubble stay gold - these two cells are the only place in the
   tournament chrome that is talking about cash rather than chips */
.trnbar .cell.money .v{color:var(--gold);}
.trnbar .cell.bub{background:linear-gradient(180deg,rgba(232,180,76,.16),rgba(232,180,76,.06));}
.trnbar .cell.bub .v{color:var(--gold-hi);}

/* the ladder of what is left to play for */
.ladder{display:flex;flex-direction:column;gap:3px;}
.ladder .lr{display:flex;justify-content:space-between;gap:10px;font-size:11.5px;
  padding:4px 8px;border-radius:5px;color:var(--text3);}
/* your row in the prize ladder is the chrome accent, not a prize colour -
   the money on the row is gold already and two golds would compete */
.ladder .lr.you{background:var(--accent-dim);color:var(--accent-hi);font-weight:600;
  box-shadow:inset 0 0 0 1px var(--accent-line);}
.ladder .lr.next{background:var(--surface2);color:var(--text2);}
.ladder .lr b{font-family:var(--mono);}
/* the bubble caption is a sentence and gets the whole row */
.ladder .lr.note{display:block;background:var(--surface2);color:var(--text2);
  font-size:11px;line-height:1.4;}

/* the leaderboard you are fighting but cannot see the cards of */
.lboard{display:flex;flex-direction:column;gap:2px;max-height:280px;overflow-y:auto;}
.lboard .br{display:grid;grid-template-columns:26px 1fr auto;gap:8px;align-items:center;
  padding:4px 8px;border-radius:5px;font-size:11.5px;color:var(--text2);}
.lboard .br.you{background:var(--accent-dim);color:var(--accent-hi);font-weight:600;
  box-shadow:inset 0 0 0 1px var(--accent-line);}
.lboard .br .rk{font-family:var(--mono);font-size:10px;color:var(--text3);}
.lboard .br.you .rk{color:var(--accent-hi);}
.lboard .br .ch{font-family:var(--mono);}
.lboard .br .nmx{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}

/* ---------- career ---------- */
.carhead{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px;
  margin-bottom:14px;}
.carbox{background:var(--g-surface);border:1px solid var(--border);border-radius:var(--r);
  padding:13px 15px;box-shadow:var(--shadow-sm);}
.carbox .k{font-family:var(--mono);font-size:9px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text3);margin-bottom:5px;}
.carbox .v{font-family:var(--disp);font-size:24px;font-weight:700;color:var(--text);}
.carbox .v.up{color:var(--call-hi);}
.carbox .v.dn{color:var(--raise);}
.carbox .sub{font-size:11px;color:var(--text3);margin-top:3px;}

.runs{display:flex;flex-direction:column;gap:3px;max-height:52vh;overflow-y:auto;}
.run{display:grid;grid-template-columns:1fr 70px 74px 84px;gap:10px;align-items:center;
  padding:7px 11px;background:var(--g-surface);border:1px solid var(--border);
  border-radius:var(--r-sm);font-size:12px;box-shadow:var(--shadow-sm);}
.run .rn{color:var(--text2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.run .rp2,.run .rc,.run .rnet{font-family:var(--mono);font-size:11.5px;text-align:right;}
.run .rnet.up{color:var(--call-hi);}
.run .rnet.dn{color:var(--raise);}
/* a cashed run is a run that paid, so it is edged in gold rather than the
   old emerald - the same rule the buy-in and the prize ladder follow */
.run.cashed{border-color:rgba(232,180,76,.36);}

/* a bankroll warning that does not look like a decoration */
.rollwarn{border-radius:var(--r-sm);padding:9px 13px;font-size:12px;margin-bottom:12px;}
.rollwarn.warn{background:rgba(239,161,59,.12);border:1px solid rgba(239,161,59,.35);color:var(--bet);}
.rollwarn.bad{background:rgba(229,72,77,.12);border:1px solid rgba(229,72,77,.4);color:var(--raise);}
.rollwarn.stop{background:rgba(229,72,77,.18);border:1px solid var(--raise);color:var(--raise);
  font-weight:600;}

/* ---------- seat HUD chips drawn on the table itself ----------
   flex-basis 100% is what makes this its own row inside the pod rather than
   a third item competing with the name for width. */
.seat .hudline{flex:1 0 100%;order:9;font-family:var(--mono);font-size:8.5px;color:var(--text3);
  letter-spacing:.03em;margin-top:3px;padding-top:3px;border-top:1px solid rgba(255,255,255,.06);
  /* wraps BETWEEN its tokens, never inside one - a deep stack beside two
     wide bands is longer than the pod, and truncating it hid the numbers */
  white-space:normal;line-height:1.4;text-align:center;}
.seat .hudline > span{white-space:nowrap;}
.seat .hudline b{color:var(--text2);font-weight:600;}
.seat .hudline .af{opacity:.75;}
/* Three Wilson bands on one line reads as "27/4-23/0-13" and there is no way
   to tell where one number stops. The separator has to be visibly different
   from the dash INSIDE a band, so it gets its own colour and real spacing,
   and the bands use an en dash rather than a hyphen. */
.seat .hudline .vp s{text-decoration:none;color:var(--border3);font-weight:400;
  padding:0 2.5px;}
.seat .hudline .vp b.na{color:var(--text4);font-weight:400;}
.seat .hudline .bb{color:var(--text2);font-weight:600;}
/* a stat line the sample cannot support yet is shown, but shown quietly */
.seat .hudline.thin{opacity:.5;font-style:italic;}
.seat .committed{color:var(--bet);font-weight:600;}
.seat.steaming .pod{box-shadow:0 0 0 1px rgba(229,72,77,.5),0 0 16px rgba(229,72,77,.22);}

/* ---------- the assistance bar ----------
   Above the felt, in reach mid-hand. This is the control that decides how
   much the app tells you, and burying it in a settings tab meant most
   people never found it. */
.assistbar{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:10px;
  padding:7px 10px;background:var(--g-surface);border:1px solid var(--border);
  border-radius:var(--r-sm);box-shadow:var(--shadow-sm);}
.assistbar .alab{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--text3);margin-right:2px;}
.assistbar .agrow{flex:1;}
/* These are the switches that decide how much the app tells you, and you set
   them mid-hand, so on and off have to be readable without stopping to read.
   Off is a hole in the bar with a dead dot; on is a lit pill with a live one.
   Colour alone was never going to carry that at a glance. */
.assistbar .asw{display:inline-flex;align-items:center;gap:6px;cursor:pointer;
  background:var(--g-well);border:1px solid var(--border2);border-radius:99px;
  padding:4px 11px 4px 8px;font-size:11.5px;font-weight:600;color:var(--text3);
  box-shadow:inset 0 1px 2px rgba(0,0,0,.5);
  transition:color var(--t),border-color var(--t),background var(--t),box-shadow var(--t);}
.assistbar .asw .dot{width:7px;height:7px;border-radius:50%;background:var(--border3);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.35);transition:background var(--t),box-shadow var(--t);}
.assistbar .asw:hover{color:var(--text2);border-color:var(--accent-line);}
.assistbar .asw.on{color:var(--text);border-color:var(--accent-line);
  background:linear-gradient(180deg,rgba(82,96,222,.30),rgba(82,96,222,.13));
  box-shadow:var(--hair),0 0 12px -4px var(--accent-glow);}
.assistbar .asw.on .dot{background:var(--accent);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.35),0 0 8px var(--accent-glow);}
.assistbar .apreset{cursor:pointer;background:transparent;border:1px solid transparent;
  border-radius:var(--r-xs);padding:3px 9px;font-family:var(--mono);font-size:10px;
  letter-spacing:.08em;text-transform:uppercase;color:var(--text3);}
.assistbar .apreset:hover{color:var(--text2);border-color:var(--border2);}
.assistbar .apreset.on{color:var(--accent-hi);border-color:var(--accent-line);
  background:var(--accent-dim);}

/* ---------- the table feed ----------
   Who sat down, who racked up, who reloaded. At a real table you always know
   this, and both of those facts change how the game plays. */
.tablefeed{margin-top:8px;min-height:34px;display:flex;flex-direction:column;gap:1px;
  font-size:11.5px;line-height:1.45;}
.tablefeed .fline{color:var(--text2);}
.tablefeed .fline.old{opacity:.42;font-size:11px;}
.tablefeed .fline.join{color:var(--accent-hi);}
.tablefeed .fline.leave{color:var(--text3);}
.tablefeed .fline.reload{color:var(--gold);}

/* ---------- stat cells that carry a band rather than a point ---------- */
.rstats .st{font-family:var(--mono);font-size:10px;color:var(--text3);white-space:nowrap;}
.rstats .st i{font-style:normal;opacity:.72;}
.rstats .st b{color:var(--text2);font-weight:600;}
.rstats .st b.none{opacity:.4;}
/* a wide band is drawn as one, so you can see at a glance that the number
   has not settled down yet */
.rstats .st.wide b{color:var(--text3);font-weight:500;}
.rstats .st.hands{margin-left:auto;opacity:.5;}
.rcard.open{border-style:dashed;opacity:.6;}

/* ---------- empty states ---------- */
.blank{padding:34px 20px;text-align:center;color:var(--text3);font-size:13px;line-height:1.6;}
.blank b{color:var(--text2);display:block;font-size:14px;margin-bottom:5px;}

/* ============================================================
   THE LIVE TABLE FITS THE SCREEN
   The laptop complaint, and the reason the hand report was three screens
   down. Everything you need while a hand is running - the table, the
   coach, the buttons, the players, the report on the hand that just
   finished - now lives inside one viewport with no page scroll at all.

   The chain is plain flexbox: body -> main -> the active view -> .sim ->
   the table pane -> .sim-main.fit. Every link needs min-height:0 or a
   flex child refuses to shrink below its content and the whole thing
   overflows instead of fitting.
   ============================================================ */
body.tablefit{height:100vh;overflow:hidden;display:flex;flex-direction:column;}
/* the footer is a credit line; it was quietly holding 45px of the felt's
   height hostage while it sat off the bottom of a screen that no longer
   scrolls */
body.tablefit>footer{display:none;}
/* every pixel of chrome above the felt is a pixel off the table, so the
   two bars that frame the page get a little tighter while a hand is live */
body.tablefit .topbar{height:48px;}
body.tablefit .topbar nav button{padding:6px 13px;}
body.tablefit .sim-tabs{padding:3px;}
body.tablefit .sim-tabs button{padding:6px 14px;font-size:12.5px;}
body.tablefit>main{flex:1;min-height:0;display:flex;flex-direction:column;
  margin:10px auto 10px;width:100%;}
body.tablefit>main>section.view.on{flex:1;min-height:0;display:flex;
  flex-direction:column;animation:none;}
body.tablefit .sim{flex:1;min-height:0;gap:9px;}
body.tablefit .sim-pane.fitpane.on{flex:1;min-height:0;display:flex;
  flex-direction:column;gap:9px;}
/* The tournament wraps its whole live table in #tvGame so it can be hidden
   between tournaments. That div is one more link in the chain, and a link
   that is not itself a flex column stops a definite height reaching the felt
   - which showed up as a table exactly zero pixels tall. */
body.tablefit #tvGame{flex:1;min-height:0;display:flex;flex-direction:column;gap:9px;}
body.tablefit #tvNoGame:empty{display:none;}
/* the panes that are NOT the live table keep scrolling normally, inside
   themselves rather than by moving the page */
body.tablefit .sim-pane:not(.fitpane).on{flex:1;min-height:0;overflow-y:auto;
  overscroll-behavior:contain;padding-right:2px;}

.sim-main.fit{
  display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:12px;
  align-items:stretch;flex:1;min-height:0;margin:0;
}
.sim-main.fit .sim-felt{min-height:0;gap:9px;}
.sim-main.fit .sim-stage{flex:1;min-height:0;display:flex;flex-direction:column;
  padding:0;overflow:visible;}
.sim-main.fit .sim-stage>h3{flex:0 0 auto;}

/* the header strip inside the felt panel: what used to be an h3 plus a
   separate feed block, on one line, because both are glances */
/* this strip caps the felt panel, so it is lit like a panel header rather
   than filled like a bar - otherwise the top edge of the table just stops */
.stagehead{flex:0 0 auto;display:flex;align-items:center;gap:9px;
  padding:7px 13px;border-bottom:1px solid var(--border);
  background:var(--g-surface2);min-height:34px;
  box-shadow:var(--hair);}
.stagehead>b{font-family:var(--disp);font-size:12.5px;font-weight:600;
  color:var(--text);white-space:nowrap;}
.stagehead .grow{flex:1;}
.stagehead .tablefeed{margin:0;min-height:0;max-width:52%;text-align:right;
  align-items:flex-end;}
.stagehead .tablefeed .fline{white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;max-width:100%;}
.pacesw{display:flex;align-items:center;gap:6px;cursor:pointer;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--text3);white-space:nowrap;}
.pacesw input{width:auto;margin:0;accent-color:var(--accent);}
.pacesw:hover{color:var(--text2);}

/* ---------- the felt itself ----------
   The table used to be sized purely by width (aspect-ratio 2.05/1 on a
   100%-wide box), so a wider window made a TALLER table and pushed the
   action bar off the bottom of a laptop screen. It is now the smaller of
   what the column can spare across and what the screen can spare down.

   --fitchrome is everything above and below the felt: topbar, tabs, stat
   strip, assist bar, the console, and this panel's own padding. It is
   deliberately a little generous, so the table comes out slightly under
   the space available rather than slightly over it. */
/* .table-stage carries `margin:0 auto` for the old centred layout. An auto
   margin on the cross axis of a flex item switches off stretch, so the stage
   shrank to fit its own contents instead of filling the column - and then
   the table sized itself off that. */
.sim-main.fit .table-stage{flex:1;min-height:0;max-width:none;margin:0;
  /* the bottom reserve is bigger than the top on purpose: hero's pod is
     centred BELOW the felt's bottom edge and carries the two big hole cards,
     so it hangs about 60px down where the others hang about 30 */
  padding:38px 60px 68px;display:flex;align-items:center;justify-content:center;}
.sim-main.fit .ptable{
  /* Height first, because height is the scarce thing on a laptop: 100% of
     whatever the flex chain left over, so the felt is exactly as big as the
     screen can afford and never a pixel more. The second term is the cap
     that stops a very tall window deriving a table wider than the column -
     it is the column width (viewport, less the page gutters, the rail, the
     grid gap and this padding) turned back into a height through the ratio. */
  height:min(100%, calc((100vw - 516px) / 2.05));
  width:auto;aspect-ratio:2.05/1;margin:0 auto;min-width:0;
}

/* ---------- the console: coach and buttons, together ---------- */
.console{flex:0 0 auto;display:flex;flex-direction:column;gap:7px;}
.console .actionbar{margin-top:0;gap:8px;padding:9px 12px;}
.console .actionbar .who{margin-bottom:-4px;font-size:9.5px;}
.console .actionbar .keyhint{margin-top:-3px;}
.console .bigbtn{padding:11px 20px;}
.console:empty{display:none;}

/* ---------- the rail ----------
   Players while the hand is live, the graded report the moment it ends.
   Both are things you read at a glance beside the table, and neither is
   ever below the fold now.                                              */
.rail{display:flex;flex-direction:column;min-height:0;gap:8px;}
/* same recessed track and raised pill as the sim tabs, at rail scale */
.railtabs{flex:0 0 auto;display:flex;gap:3px;padding:3px;background:var(--g-well);
  border:1px solid var(--border);border-radius:var(--r-sm);
  box-shadow:inset 0 1px 3px rgba(0,0,0,.45);}
.railtabs button{flex:1;font-size:11.5px;font-weight:600;color:var(--text3);
  background:transparent;border:0;border-radius:5px;padding:6px 8px;cursor:pointer;
  white-space:nowrap;transition:background var(--t),color var(--t),box-shadow var(--t);position:relative;}
.railtabs button:hover{color:var(--text);background:rgba(255,255,255,.05);}
.railtabs button.on{background:var(--g-accent);color:var(--accent-ink);
  box-shadow:var(--hair-strong),0 2px 8px -3px var(--accent-glow);}
/* the report tab tells you there is something new in it without stealing
   the screen away from the table you are still looking at */
.railtabs .dot{display:none;width:5px;height:5px;border-radius:50%;
  background:var(--accent-hi);margin-left:5px;vertical-align:middle;
  box-shadow:0 0 6px var(--accent-glow);}
/* on the active tab the pill is already indigo, so the dot has to go white
   or it disappears into the thing it is sitting on */
.railtabs button.on .dot{background:var(--accent-ink);box-shadow:none;}
.railtabs button.fresh .dot{display:inline-block;}
.railbody{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  padding-right:3px;}
.railbody::-webkit-scrollbar{width:6px;}
.railbody::-webkit-scrollbar-thumb{background:var(--border2);border-radius:99px;}
.railpane{display:none;}
.railpane.on{display:block;}
.railpane.report{background:var(--g-surface);border:1px solid var(--border);
  border-radius:var(--r);padding:11px 12px;box-shadow:var(--shadow-sm);}
.rephead{font-family:var(--mono);font-size:9px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--text3);margin:0 0 8px;
  display:flex;align-items:center;gap:7px;}
.rephead:not(:first-child){margin-top:14px;padding-top:12px;
  border-top:1px solid var(--border);}
/* inside the rail the reads stack; the sticky/scrolling job moved up to
   .railbody, which owns the whole column now */
.sim-main.fit .reads{position:static;max-height:none;overflow:visible;
  padding-right:0;}
/* the report is read in a 340px column now, so it is laid out for one */
.railpane.report .scorebig .n{font-size:25px;}
.railpane.report .rline{padding:7px 0;gap:8px;}
.railpane.report .rwhy{font-size:11px;line-height:1.45;}
.railpane.report .ract{font-size:12px;}
.railpane.report .cardline .pcard.sm{width:22px;height:31px;}
.railpane.report .cardline .pcard.sm .r{font-size:10px;}
.railpane.report .cardline .pcard.sm .s{font-size:8px;}
.railpane.report p{font-size:12px;line-height:1.45;}


/* ---------- SHARP ----------
   The long-run score: book, money, deviation edge and table image in one
   number. Four bars rather than four numbers, because the point of the panel
   is which part is dragging, and a column of percentages does not say that. */
.sharpline{display:flex;align-items:baseline;gap:12px;margin-bottom:4px;}
.sharpline .n{font-family:var(--disp);font-size:40px;font-weight:700;line-height:1;}
.sharpline .d{font-size:11px;color:var(--text3);}
.shrow{display:grid;grid-template-columns:74px 1fr 62px;align-items:center;
  gap:9px;margin:7px 0;}
.shrow .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;
  text-transform:uppercase;color:var(--text3);}
.shrow .bar{height:6px;border-radius:99px;background:var(--g-well);
  overflow:hidden;box-shadow:inset 0 1px 2px rgba(0,0,0,.55);position:relative;}
.shrow .bar i{display:block;height:100%;border-radius:99px;transition:width .3s var(--ease);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.28);}
/* the midpoint, so a bar can be read as better or worse than neutral */
.shrow .bar::after{content:"";position:absolute;left:50%;top:0;bottom:0;width:1px;
  background:rgba(255,255,255,.10);}
.shrow .v{font-family:var(--mono);font-size:12px;text-align:right;color:var(--text);}
.shrow .v.none{color:var(--text4);}
.shrow.dim .k,.shrow.dim .v{color:var(--text4);}
.shwhy{font-size:11.5px;color:var(--text2);line-height:1.5;margin-top:10px;
  padding-top:9px;border-top:1px solid var(--border);}
