/* ===========================================================================
   PennyGames UI
   One stylesheet, two themes, shared by the cabinet and the play screen.
   Every colour is a token so day/night is a single attribute flip on <html>.
   =========================================================================== */

:root{
  --r:6px;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --pad:22px;
  --maxw:1280px;
}

:root[data-theme=dark]{
  --bg:#0a0c10;
  --panel:#0d1117;
  --panel-2:#111820;
  --raise:#161f2a;
  --line:#1f2833;
  --line-soft:#141b23;
  --ink:#eef4fb;
  --ink-2:#c9d4e3;
  /* was #65778c, which measured 4.12:1 on panels and failed AA. This clears
     4.5:1 against both --panel and --panel-2. */
  --muted:#8695ab;
  --accent:#4ade80;
  --danger:#f87171;
  --shadow:0 24px 60px -30px rgba(0,0,0,.9);
  --art-bg:#0b1219;
  color-scheme:dark;
}

:root[data-theme=light]{
  --bg:#eef1f6;
  --panel:#ffffff;
  --panel-2:#f5f7fa;
  --raise:#e9edf3;
  --line:#d7dee8;
  --line-soft:#e6ebf1;
  --ink:#0c1320;
  --ink-2:#2b3648;
  --muted:#61708a;
  --accent:#0a7d43;
  --danger:#c02626;
  --shadow:0 20px 50px -28px rgba(20,30,50,.45);
  --art-bg:#f0f3f8;
  color-scheme:light;
}

*{box-sizing:border-box;margin:0;padding:0}
svg{display:block}

body{
  background:var(--bg);color:var(--ink-2);
  font:14px/1.55 var(--mono);
  font-variant-numeric:tabular-nums;
  -webkit-font-smoothing:antialiased;
  min-height:100vh;
}
a{color:inherit;text-decoration:none}

/* visible keyboard focus everywhere, which the earlier passes were missing */
:where(a,button,input,select,[tabindex]):focus-visible{
  outline:2px solid var(--accent);outline-offset:2px;border-radius:4px;
}

.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--pad)}
.sp{flex:1}
.mut{color:var(--muted)}
.tiny{font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}

/* ---- top bar ------------------------------------------------------------ */
.topbar{
  position:sticky;top:0;z-index:30;
  background:var(--panel);border-bottom:1px solid var(--line);
}
.topbar .row{display:flex;align-items:center;gap:14px;height:54px}
.brand{
  font-size:13px;letter-spacing:.26em;text-transform:uppercase;
  font-weight:700;color:var(--ink);white-space:nowrap;
}
.brand b{color:var(--accent)}

/* ---- account strip ------------------------------------------------------ */
/* the band's rule runs edge to edge, but the figures line up with the grid */
.acctband{border-top:1px solid var(--line)}
.acct{display:flex;flex-wrap:wrap}
.acct div{flex:1;min-width:150px;padding:13px 20px;border-right:1px solid var(--line)}
.acct div:first-child{padding-left:0}
.acct div:last-child{border-right:0;padding-right:0}
.acct b{display:block;font-size:19px;font-weight:600;color:var(--ink);letter-spacing:-.01em}
.acct .pos b{color:var(--accent)}

/* ---- toolbar ------------------------------------------------------------ */
.toolbar{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:14px 0 12px;
}
.chips{display:flex;gap:5px;flex-wrap:wrap}
.chip{
  font:inherit;font-size:10px;letter-spacing:.14em;text-transform:uppercase;cursor:pointer;
  background:var(--panel-2);border:1px solid var(--line);color:var(--muted);
  padding:6px 12px;border-radius:var(--r);transition:.14s;
}
.chip:hover{color:var(--ink);border-color:var(--muted)}
.chip[aria-pressed=true]{background:var(--ink);color:var(--bg);border-color:var(--ink)}

.field{
  display:flex;align-items:center;gap:8px;
  background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r);
  padding:0 10px;height:32px;
}
.field svg{width:13px;height:13px;color:var(--muted);flex:none}
.field input{
  font:inherit;font-size:12px;background:none;border:0;color:var(--ink);
  width:150px;height:100%;outline:none;
}
.field input::placeholder{color:var(--muted)}
/* the native search clear is inconsistent and unstyleable in dark, so hide it
   and supply our own */
.field input::-webkit-search-cancel-button{display:none}
.field .clear{
  font:inherit;font-size:15px;line-height:1;cursor:pointer;border:0;background:none;
  color:var(--muted);padding:0 2px;display:none;
}
.field .clear:hover{color:var(--ink)}
.field.filled .clear{display:block}

.count{font-size:11px;color:var(--muted);white-space:nowrap}

/* keyboard hints on controls, shown only on real pointers */
kbd{
  font:inherit;font-size:10px;background:var(--raise);border:1px solid var(--line);
  border-bottom-width:2px;border-radius:4px;padding:1px 5px;color:var(--muted);
}

/* ---- skeleton ----------------------------------------------------------- */
.skel{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(232px,1fr))}
.skel div{
  height:232px;border:1px solid var(--line);border-radius:var(--r);background:var(--panel);
  position:relative;overflow:hidden;
}
.skel div::after{
  content:'';position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,var(--raise),transparent);
  animation:sweep 1.3s infinite;
}
@keyframes sweep{100%{transform:translateX(100%)}}

/* ---- banner ------------------------------------------------------------- */
/* block, not flex: as flex items the label and the sentence wrapped separately */
.banner{
  border:1px solid var(--danger);border-radius:var(--r);
  padding:11px 14px;font-size:12.5px;line-height:1.5;color:var(--ink);
  background:color-mix(in srgb, var(--danger) 12%, transparent);
}
.banner b{color:var(--danger);margin-right:4px}

select.sel{
  font:inherit;font-size:11px;letter-spacing:.06em;cursor:pointer;height:32px;
  background:var(--panel-2);border:1px solid var(--line);color:var(--ink-2);
  border-radius:var(--r);padding:0 8px;
}

.seg{display:flex;background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.seg button{
  font:inherit;cursor:pointer;background:none;border:0;color:var(--muted);
  width:34px;height:32px;display:grid;place-items:center;transition:.14s;
}
.seg button svg{width:15px;height:15px}
.seg button:hover{color:var(--ink)}
.seg button[aria-pressed=true]{background:var(--ink);color:var(--bg)}

/* ---- table view --------------------------------------------------------- */
.tablewrap{overflow-x:auto;border:1px solid var(--line);border-radius:var(--r);background:var(--panel)}
table{width:100%;border-collapse:collapse;font-size:13px;min-width:820px}
thead th{
  text-align:left;font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);
  font-weight:600;padding:11px 14px;border-bottom:1px solid var(--line);white-space:nowrap;
  background:var(--panel-2);
}
thead th[data-k]{cursor:pointer;user-select:none}
thead th[data-k]:hover{color:var(--ink)}
thead th .dir{opacity:0;margin-left:5px}
thead th[aria-sort] .dir{opacity:1;color:var(--accent)}
th.num,td.num{text-align:right}
tbody tr{border-bottom:1px solid var(--line-soft)}
tbody tr:last-child{border-bottom:0}
tbody tr:hover{background:var(--panel-2)}
tbody td{padding:11px 14px;white-space:nowrap}
.gname{display:flex;align-items:center;gap:11px}
.gname i{width:3px;height:24px;background:var(--game);border-radius:2px;flex:none}
.gname b{font-weight:600;color:var(--ink);letter-spacing:.02em}
tr.locked .gname b,tr.locked td{color:var(--muted)}
tr.locked .gname i{background:var(--line)}

/* ---- grid view ---------------------------------------------------------- */
.cards{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(232px,1fr))}
.card{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  overflow:hidden;display:flex;flex-direction:column;transition:border-color .15s,transform .15s;
}
.card:hover{border-color:var(--muted);transform:translateY(-2px)}
.card .art{aspect-ratio:16/10;background:var(--art-bg);border-bottom:1px solid var(--line);color:var(--game)}
.card .art svg{width:100%;height:100%}
.card .body{padding:12px 13px 13px;display:flex;flex-direction:column;gap:9px;flex:1}
.card .hd{display:flex;align-items:baseline;gap:8px}
.card .hd b{font-size:14px;font-weight:600;color:var(--ink);letter-spacing:.02em}
.card .hd .slot{font-size:10px;letter-spacing:.14em;color:var(--muted);margin-left:auto}
.card p{font-size:12px;color:var(--muted);line-height:1.45;flex:1}
/* the grid card is the table row folded into a box: same fields, same order */
.card .stats{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;border-top:1px solid var(--line-soft);padding-top:9px}
.card .stats div{min-width:0}
.card .stats b{display:block;font-size:13px;color:var(--ink);font-weight:600}
.card .stats span{font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.card .foot{display:flex;align-items:center;gap:9px}
/* locked games stay legible instead of being faded into the background */
.card.locked .art{filter:grayscale(1);opacity:.28}
.card.locked:hover{transform:none;border-color:var(--line)}
.card.locked .hd b,.card.locked .stats b{color:var(--muted)}

/* ---- bits --------------------------------------------------------------- */
/* sparklines inherit colour from context, so locked rows mute automatically */
.spark{width:76px;height:22px;flex:none;color:var(--game)}
tr.locked .spark,.card.locked .spark{color:var(--muted);opacity:.7}
.btn{
  font:inherit;font-size:10px;letter-spacing:.16em;text-transform:uppercase;cursor:pointer;
  background:transparent;border:1px solid var(--line);color:var(--ink-2);
  padding:7px 14px;border-radius:var(--r);transition:.14s;white-space:nowrap;
}
.btn svg{width:14px;height:14px}
.btn:hover{background:var(--ink);color:var(--bg);border-color:var(--ink)}
/* a button-shaped label for things that aren't buttons yet */
.btn.ghost{color:var(--muted);border-style:dashed;cursor:default}
.btn.ghost:hover{background:transparent;color:var(--muted);border-color:var(--line)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:#04140a}
:root[data-theme=light] .btn.primary{color:#fff}
.btn.primary:hover{filter:brightness(1.1);background:var(--accent);border-color:var(--accent)}
.btn:disabled{opacity:.4;cursor:not-allowed}
.lockmark{font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.price{font-size:12px;color:var(--ink);font-weight:600;margin-left:auto}

.empty{
  border:1px dashed var(--line);border-radius:var(--r);padding:56px 20px;
  text-align:center;color:var(--muted);font-size:13px;
}

footer.foot{border-top:1px solid var(--line);margin-top:40px;padding:20px 0 60px;color:var(--muted);font-size:11px}

/* ---- play screen -------------------------------------------------------- */
.playbar{display:flex;align-items:center;gap:14px;height:54px}
.playbar .title{font-size:14px;font-weight:600;color:var(--ink);letter-spacing:.04em}
.playbar .slot{font-size:10px;letter-spacing:.18em;color:var(--muted)}
.live{
  display:flex;align-items:center;gap:8px;background:var(--panel-2);
  border:1px solid var(--line);border-radius:var(--r);padding:5px 12px;
}
.live b{font-size:15px;color:var(--ink);font-weight:600}
.live.bump{animation:bump .4s ease}
@keyframes bump{35%{transform:scale(1.07)}}

/* fullscreen: the board takes the whole display, no frame, no rounding */
.screen:fullscreen{border:0;border-radius:0;min-height:100vh;box-shadow:none;background:#000}
.screen:fullscreen iframe{height:100vh}

/* the level track, now shown beside the game rather than inside it */
.levdots{display:flex;flex-wrap:wrap;gap:4px;padding:13px 14px 10px}
.levdots i{
  width:8px;height:8px;border-radius:50%;display:block;
  background:var(--panel-2);border:1px solid var(--line);
}
.levdots i.done{background:var(--accent);border-color:var(--accent)}
.levdots i.here{background:none;border-color:var(--accent);
                box-shadow:0 0 0 2px var(--accent) inset;transform:scale(1.25)}

/* stretch, so the screen matches the side column instead of leaving a hole */
.stage{display:grid;grid-template-columns:1fr 300px;gap:16px;padding:16px 0 40px;align-items:stretch}
.main{display:flex;flex-direction:column;gap:14px;min-width:0}
/* wide mode: drop the side column and let the board take the room */
.stage.wide{grid-template-columns:1fr}
.stage.wide .side{display:none}
.screen{
  background:#000;border:1px solid var(--line);border-radius:var(--r);
  overflow:hidden;box-shadow:var(--shadow);position:relative;
  display:flex;min-height:min(74vh,680px);
}
.screen iframe{display:block;width:100%;flex:1;border:0;background:#07070d}
.side{display:flex;flex-direction:column;gap:14px}
.panel{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.panel h3{
  font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted);
  font-weight:600;padding:11px 14px;border-bottom:1px solid var(--line);background:var(--panel-2);
}
.panel .rows{padding:4px 0}
.prow{display:flex;align-items:center;gap:10px;padding:8px 14px;font-size:12px}
.prow span{color:var(--muted)}
.prow b{margin-left:auto;color:var(--ink);font-weight:600}
.prow.new b{color:var(--accent)}

/* ---- leaderboard -------------------------------------------------------- */
.board table{min-width:0}
.board thead th{background:transparent;border-bottom:1px solid var(--line)}
.board td{padding:9px 14px}
.board .rank{width:44px;color:var(--muted)}
/* the handle soaks up the slack so level and plays stay hugged to the right */
.board .who{width:100%;font-weight:600;color:var(--ink);letter-spacing:.14em}
.board .lvl{white-space:nowrap;color:var(--ink)}
.board tr.you{background:color-mix(in srgb, var(--accent) 10%, transparent)}
.board tr.you .who{color:var(--accent)}
.board tr.you .rank{color:var(--accent)}
.board .none{padding:22px 14px;color:var(--muted);font-size:12.5px;text-align:center}
.board h3{display:flex;align-items:center;gap:10px}
.wins{display:flex;gap:2px;margin-left:auto}
.wins button{
  font:inherit;font-size:10px;letter-spacing:.12em;text-transform:uppercase;cursor:pointer;
  background:transparent;border:1px solid transparent;color:var(--muted);
  padding:3px 9px;border-radius:99px;
}
.wins button:hover{color:var(--ink)}
.wins button[aria-pressed=true]{background:var(--raise);border-color:var(--line);color:var(--ink)}
.board .foot a{color:var(--muted);text-decoration:underline}
.board .foot a:hover{color:var(--ink)}

/* ---- collection --------------------------------------------------------- */
.collect{display:flex;flex-wrap:wrap;gap:5px;padding:13px 14px 4px}
.collect i{
  width:11px;height:11px;display:block;transform:rotate(45deg);
  background:var(--panel-2);border:1px solid var(--line);
}
.collect i.got{background:#ffd23f;border-color:#ffd23f;box-shadow:0 0 8px rgba(255,210,63,.55)}
.board .foot{
  padding:9px 14px;border-top:1px solid var(--line);
  color:var(--muted);font-size:11px;display:flex;gap:8px;align-items:center;
}
.board .foot b{color:var(--ink);letter-spacing:.14em}

/* the receipt, printed when a run ends */
.receipt{
  background:#f7f4ea;color:#1b1a20;padding:22px 24px 26px;position:relative;
  font-size:12.5px;line-height:1.7;box-shadow:var(--shadow);
}
.receipt::after{
  content:'';position:absolute;left:0;right:0;bottom:-9px;height:9px;
  background:radial-gradient(circle at 5px 0,var(--bg) 5px,transparent 5.5px) repeat-x;
  background-size:10px 9px;
}
.receipt .rh{text-align:center;letter-spacing:.28em;text-transform:uppercase;font-weight:700;font-size:13px}
.receipt .rs{text-align:center;font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:#6c6875;margin-top:3px}
.receipt hr{border:0;border-top:1px dashed #b8b3a6;margin:12px 0}
.receipt hr.solid{border-top:2px solid #1b1a20}
.receipt .line{display:flex;justify-content:space-between;gap:12px}
.receipt .line.big{font-size:16px;font-weight:700}
.receipt .best{text-align:center;letter-spacing:.2em;text-transform:uppercase;font-size:11px;font-weight:700;margin-top:10px}
.receipt .barcode{display:flex;gap:2px;justify-content:center;align-items:flex-end;height:34px;margin-top:14px}
.receipt .barcode i{background:#1b1a20;display:block;height:100%}

@media (max-width:900px){
  .stage{grid-template-columns:1fr}
  .screen{min-height:min(52vh,420px)}
}

/* ---- phones -------------------------------------------------------------
   The chrome was taking 382px of an 820px viewport before a single game
   appeared. Secondary identifiers go, the stats fold to 2x2 without internal
   rules, and the toolbar stops wrapping onto three rows.
   ------------------------------------------------------------------------- */
@media (max-width:700px){
  .hide-sm{display:none !important}
  .topbar .row{height:48px}
  .acct{display:grid;grid-template-columns:1fr 1fr;gap:2px 16px}
  .acct div{min-width:0;padding:9px 0;border-right:0}
  .acct b{font-size:17px}
  /* plays-to-date and best-run aren't worth a second row here; best score is
     already on every card */
  .acct div:nth-child(n+3){display:none}
  /* search and sort share the first row, chips scroll under it */
  .toolbar{gap:7px;padding:11px 0}
  .toolbar .sp{display:none}
  .field{order:-1;flex:1 1 58%}
  .field input{width:100%;min-width:0}
  select.sel{order:-1;flex:1 1 30%;min-width:0}
  /* chips scroll sideways rather than stacking into a second row */
  .chips{order:1;flex:1 1 100%;flex-wrap:nowrap;overflow-x:auto;padding-bottom:2px;scrollbar-width:none}
  .chips::-webkit-scrollbar{display:none}
  .chip{flex:none}
  .playbar{height:auto;padding:9px 0;flex-wrap:wrap}
  .playbar .title{order:-1}
}
/* ---- toast ----------------------------------------------------------------
   Earning something is a moment, and it happens while the player is looking at
   the board, so the notice has to land over the board rather than somewhere in
   the page they are not reading. Pinned to the top centre and above everything,
   including a game running full screen.
   ------------------------------------------------------------------------- */
.toast{
  /* inset/margin/border are reset because the UA centres popovers by default */
  /* clear of the top bar, so it never sits over the level and balance readouts */
  position:fixed;inset:auto;top:70px;left:50%;margin:0;
  z-index:2147483647;                /* for the no-popover fallback path */
  display:flex;align-items:center;gap:9px;
  /* sized to its text: in the top layer there is no parent to inherit a width
     from, so without this it collapses to a one-word column */
  width:max-content;max-width:min(92vw,460px);
  padding:11px 16px;border-radius:9px;
  background:var(--panel);border:1px solid var(--accent);
  box-shadow:0 8px 30px -10px rgba(0,0,0,.55);
  color:var(--ink);font-size:12.5px;letter-spacing:.09em;text-transform:uppercase;
  font-weight:600;text-align:center;
  /* out of the way and untouchable until shown, so it can never eat a click */
  opacity:0;transform:translate(-50%,-14px);pointer-events:none;
  transition:opacity .22s ease,transform .22s ease;
}
.toast::before{
  content:'';flex:none;width:7px;height:7px;border-radius:50%;
  background:var(--accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 28%,transparent);
}
.toast.show{opacity:1;transform:translate(-50%,0)}

/* ---- dev bar: save / load / reset -----------------------------------------
   Bottom right, deliberately quiet until you go near it: these are testing
   tools and shouldn't compete with the game for attention.
   ------------------------------------------------------------------------- */
.devbar{
  position:fixed;right:14px;bottom:14px;z-index:60;display:flex;gap:6px;
  opacity:.45;transition:opacity .15s;
}
.devbar:hover,.devbar:focus-within{opacity:1}
.resetbtn{
  font:inherit;font-size:11px;letter-spacing:.12em;text-transform:uppercase;
  padding:8px 12px;border-radius:7px;cursor:pointer;
  background:var(--panel);color:var(--muted);border:1px solid var(--line);
  transition:color .15s,border-color .15s,background .15s;
}
.resetbtn:hover,.resetbtn:focus-visible{color:var(--ink);border-color:var(--muted)}
.resetbtn.armed{
  opacity:1;color:#fff;background:#c0392b;border-color:#c0392b;
}
:root[data-theme=light] .resetbtn.armed{background:#b02a1c;border-color:#b02a1c}
.resetbtn:disabled{cursor:default;opacity:.7}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001ms !important;transition-duration:.001ms !important}
}
