/* Holo's look: the collector's desk (<body data-theme="desk">); scene.js fills #scene with the desk props.
   Shared pieces first (mat, deck, sleeves, start screen), then each theme. */

/* ---------- Shared: the scene layer and the mat ---------- */
/* lvh: tall enough that no gap shows when a phone's address bar slides away. */
#scene { position: fixed; inset: 0 0 auto; height: 100vh; height: 100lvh; z-index: 0; pointer-events: none; overflow: hidden; contain: strict; }
/* The desk props never affect the game's layout: let the browser skip them when the game re-lays out. */
html { overflow-x: hidden; }
main { position: relative; z-index: 1; } /* above the scene; overlays keep their own higher z-index */
.mat { position: relative; border-radius: 22px; padding: 16px 16px 20px; margin-top: 12px; }
@media (min-width: 640px) { main { max-width: 560px; } .mat { padding: 20px 24px 24px; } }
.rail:empty, .ad:empty { display: none !important; } /* no blank gaps while ads are off (ads.js) */

/* ---------- Shared: pack progress ("the deck") ---------- */
.deck { display: flex; justify-content: center; gap: 8px; margin: 14px 0 8px; }
.deck .dk { width: 44px; position: relative; transition: transform .35s cubic-bezier(.2,1.4,.4,1), opacity .3s; }
.deck .dk .tcard { font-size: calc(44px / 13); animation: none; }
.deck .dk .tc-top, .deck .dk .tc-foot, .deck .dk .tc-rate, .deck .dk .tc-name { display: none; }
.deck .dk.upcoming { opacity: .45; }
.deck .dk.now { transform: translateY(-6px) scale(1.12); filter: drop-shadow(0 6px 14px rgba(173,140,255,.55)); }
.deck .dk.x::after { content: '✕'; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-weight: 900; font-size: 22px; color: var(--bad); text-shadow: 0 0 6px #000; }
.deck-label { display: flex; justify-content: space-between; font-size: 12px; color: var(--muted); letter-spacing: 1px; text-transform: uppercase; }
.deck-label b { color: var(--text); font-size: 14px; letter-spacing: 0; }

/* ---------- Shared: ladder sleeves and the pot ---------- */
.slot { border-style: solid; }
.slot::before { content: ''; position: absolute; inset: 4px; border-radius: 6px; pointer-events: none; }
.slot.filled::before { display: none; }
.pot .val.zero { color: var(--muted); font-size: 22px; }

/* ---------- Shared: start screen ---------- */
.pack-wrap { width: 220px; margin: 18px auto 6px; perspective: 900px; animation: float 4s ease-in-out infinite; }
.pack-wrap .pack { margin: 0; animation: sheen2 5s ease-in-out infinite alternate; transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); transition: transform .12s ease-out; }
.pack > :not(.shine):not(.pack-art):not(.tear) { position: relative; z-index: 1; } /* text stays above the art and the moving shine */
.pack > .tear { z-index: 1; }
.pack .pack-art { z-index: 0; }
/* The card back's art fills the whole card inside its foil frame. */
.tcard.back .tc-inner { padding: 0; }
.tcard.back svg.cb { display: block; width: 100%; height: 100%; }
.pack .tear { position: absolute; }
.pack-wrap .pack.ripping { animation: rip .6s ease-in forwards; transition: none; }
.pack .shine { position: absolute; inset: 0; z-index: 0; border-radius: 16px; pointer-events: none; mix-blend-mode: soft-light;
  background: radial-gradient(circle at var(--mx, 50%) var(--my, 30%), rgba(255,255,255,.85), transparent 45%); }
.me-row, .buzz { text-align: center; font-size: 14px; color: #cfcde6; margin-top: 10px; line-height: 1.6; }
.me-row b, .buzz b { color: var(--text); }
.me-row span + span::before { content: '·'; margin: 0 8px; color: var(--muted); }
.buzz:empty, .me-row:empty { display: none; }
.done-today { text-align: center; }
.done-today .slab { margin-top: 6px; }
.countdown { font-family: 'Unbounded', sans-serif; font-weight: 900; font-size: 34px; letter-spacing: 1px; margin-top: 4px; }
.countdown-label { font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: var(--muted); margin-top: 18px; }

/* ---------- Theme: Collector's desk ---------- */
body[data-theme="desk"] {
  --bg: #1a100a;
  --muted: #b5a48c;
  --line: rgba(255, 225, 180, .14);
  --panel: rgba(17, 19, 38, .94);
  background: #24160c;
}
body[data-theme="desk"] #scene {
  background:
    radial-gradient(ellipse 52% 58% at 50% 40%, transparent 0%, rgba(8, 4, 2, .35) 55%, rgba(5, 3, 1, .86) 100%),
    radial-gradient(ellipse 42% 46% at 50% 36%, rgba(255, 190, 110, .22), transparent 72%),
    linear-gradient(rgba(12, 6, 2, .28), rgba(12, 6, 2, .28)),
    url("art/desk-desktop.webp") center / cover no-repeat,
    #24160c;
}
body[data-theme="desk"] h1 { filter: drop-shadow(0 4px 10px rgba(0,0,0,.6)); }
body[data-theme="desk"] .tag, body[data-theme="desk"] .foot, body[data-theme="desk"] .foot a { text-shadow: 0 1px 3px rgba(0,0,0,.9); }
body[data-theme="desk"] .tag { color: #d9c9ad; }
body[data-theme="desk"] .foot { color: #cdbda3; }
body[data-theme="desk"] .foot a { color: #e2d6ff; }

/* A trading-card playmat: indigo rubber, stitched edge, faint printed holo artwork. */
body[data-theme="desk"] .mat {
  background:
    radial-gradient(circle at 50% 0%, rgba(255, 200, 140, .14), transparent 55%),
    repeating-radial-gradient(circle at 50% 62%, rgba(173, 140, 255, .055) 0 1px, transparent 1px 30px),
    conic-gradient(from 200deg at 50% 62%, rgba(255,106,213,.07), rgba(125,255,196,.06), rgba(148,208,255,.07), rgba(255,106,213,.07)),
    linear-gradient(165deg, #1a1d3a, #10122a 60%, #0c0d20);
  border: 3px solid #07081a;
  box-shadow: 0 34px 70px rgba(0, 0, 0, .7), 0 6px 14px rgba(0, 0, 0, .5), inset 0 1px 0 rgba(255, 255, 255, .08);
}
body[data-theme="desk"] .mat::before { content: ''; position: absolute; inset: 6px; border-radius: 17px; pointer-events: none;
  border: 2px dashed rgba(255, 255, 255, .16); }
body[data-theme="desk"] .mat::after { content: 'HOLO'; position: absolute; left: 0; right: 0; bottom: 16px; text-align: center; pointer-events: none;
  font-family: 'Unbounded', sans-serif; font-weight: 900; font-size: 54px; letter-spacing: 8px; color: rgba(173, 140, 255, .06); }
body[data-theme="desk"] .prompt { background: rgba(6, 7, 20, .65); border-color: rgba(173, 140, 255, .3); }
body[data-theme="desk"] .slot { border-color: rgba(255, 255, 255, .14); background: rgba(255, 255, 255, .025); box-shadow: inset 0 2px 8px rgba(0,0,0,.35); }
body[data-theme="desk"] .slot::before { border: 1px solid rgba(255, 255, 255, .05); }
body[data-theme="desk"] input { background: rgba(6, 7, 20, .8); border-color: rgba(255, 255, 255, .14); }
body[data-theme="desk"] .result, body[data-theme="desk"] .binder, body[data-theme="desk"] .modal .box { background: rgba(17, 19, 38, .96); border-color: rgba(255, 255, 255, .12); }
body[data-theme="desk"] .corner button { background: rgba(20, 13, 8, .85); border-color: rgba(255, 225, 180, .2); }
body[data-theme="desk"] .me-row, body[data-theme="desk"] .buzz, body[data-theme="desk"] .tagline { color: #d8d3ea; }

/* Desk props (wide screens): ring binder with your cards, a stack of card backs, the torn wrapper, a loose card under the lamp. */
.prop { position: absolute; display: none; }
@media (min-width: 1100px) { .prop { display: block; } }
/* Painted props (holo/art): binder with the player's cards in its sleeves, torn wrapper, pencil. */
.art-binder { left: calc(50% - 280px - 430px); top: 104px; width: 410px; transform: rotate(-6deg); filter: drop-shadow(0 30px 28px rgba(0,0,0,.7)); }
.art-binder img, .peek-art-binder img { display: block; width: 100%; height: auto; user-select: none; }
.sleeve { position: absolute; display: flex; align-items: center; justify-content: center; }
/* A sleeve is ~10.6% of the painted binder's width (--bw). */
.art-binder { --bw: 410px; }
.peek-art-binder { --bw: 340px; }
.sleeve .tcard { font-size: calc(var(--bw) * .106 * .9 / 13); }
.sleeve .tcard, .desk-stack .tcard, .peek .tcard { animation: none; }
/* Small or stacked cards keep their finish but hold still (many at once would cost frames on phones). */
:is(.sleeve, .desk-stack, .desk-loose, .peek, .deck) .tc-fx::before, :is(.sleeve, .desk-stack, .desk-loose, .peek, .deck) .tc-fx::after,
:is(.sleeve, .desk-stack, .desk-loose, .peek, .deck) .tc-inner::after { animation: none; }
/* ...and their foil is a plain tint: a blended layer in the background makes everything moving over it slow to draw. */
:is(.sleeve, .desk-stack, .desk-loose, .peek, .deck) .tc-fx::before { mix-blend-mode: normal; opacity: .2; }
/* Cards in the ladder and on the end screen: the foil holds still (the glint and sparkles still play). */
:is(.slot, .spread) .tc-fx::before { animation: none; }
.sleeve .tc-rate, .sleeve .tc-top, .sleeve .tc-foot { display: none; }
.sleeve .tc-name { font-size: 1.5em; min-height: 0; }
.sleeve::after { content: ''; position: absolute; inset: 0; border-radius: 3px; pointer-events: none;
  background: linear-gradient(125deg, rgba(255,255,255,.28), transparent 35%, transparent 60%, rgba(255,255,255,.18) 75%, transparent 90%); }
.art-binder .label { position: absolute; bottom: 30px; left: 0; right: 0; text-align: center; font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: rgba(255, 225, 180, .55); text-shadow: 0 1px 3px #000; }
.art-wrapper { right: calc(50% - 280px - 340px); top: 360px; width: 230px; transform: rotate(10deg); filter: drop-shadow(0 20px 18px rgba(0,0,0,.6)); }
.art-pencil { right: calc(50% - 280px - 330px); top: 650px; width: 240px; transform: rotate(-14deg); filter: drop-shadow(0 10px 8px rgba(0,0,0,.6)); }
.peek-art-binder { left: -110px; bottom: -120px; width: 340px; transform: rotate(16deg); }
.desk-stack { right: calc(50% - 280px - 250px); top: 120px; width: 120px; height: 168px; transform: rotate(9deg); }
.desk-stack .tcard { position: absolute; font-size: calc(120px / 13); box-shadow: 0 2px 0 rgba(0,0,0,.35); }
.desk-loose { left: calc(50% - 280px - 230px); top: 560px; width: 120px; transform: rotate(14deg); filter: drop-shadow(0 18px 20px rgba(0,0,0,.65)); }
.desk-loose .tcard { font-size: calc(120px / 13); }
.desk-loose .tc-rate { display: none; }
.desk-loose::after { content: ''; position: absolute; inset: 0; border-radius: 12px; background: linear-gradient(125deg, transparent 35%, rgba(255, 230, 190, .35) 48%, transparent 60%); pointer-events: none; }

/* Phones and small screens: the big props don't fit, so a binder corner and a loose card peek in at the bottom,
   and the lamp sits higher so the wood behind the logo catches the light. */
.peek { position: absolute; filter: drop-shadow(0 14px 18px rgba(0,0,0,.7)); }
/* The strip at the very bottom of the page that holds them: full screen width, clipped, never above content. */
.desk-foot { display: none; position: relative; contain: strict; content-visibility: auto; contain-intrinsic-size: 100vw 240px; height: 240px; margin: 24px 0 -48px calc(50% - 50vw); width: 100vw; overflow: hidden; pointer-events: none; }
@media (max-width: 1099px) {
  .desk-foot { display: block; }
  body[data-theme="desk"] #scene {
    background:
      radial-gradient(ellipse 90% 70% at 50% 30%, transparent 0%, rgba(8, 4, 2, .3) 60%, rgba(5, 3, 1, .8) 100%),
      radial-gradient(ellipse 85% 40% at 50% 8%, rgba(255, 190, 110, .26), transparent 75%),
      linear-gradient(rgba(12, 6, 2, .25), rgba(12, 6, 2, .25)),
      url("art/desk-phone.webp") center / cover no-repeat,
      #24160c;
  }
}
.peek-card { right: -20px; bottom: 50px; width: 104px; transform: rotate(-16deg); }
.peek-card .tcard { font-size: calc(104px / 13); }
.peek-card .tc-rate { display: none; }

@media (prefers-reduced-motion: reduce) { .pack-wrap { animation: none !important; } }

/* ---------- The timer lives in the answer box: seconds on the right, a burning fuse along the bottom ---------- */
.answer-wrap { position: relative; flex: 1; min-width: 0; display: flex; border-radius: 14px; }
.answer-wrap input { width: 100%; padding-right: 58px; }
.answer-wrap .secs { position: absolute; right: 12px; top: 50%; translate: 0 -50%; font: 900 19px 'Unbounded', sans-serif; color: var(--text); font-variant-numeric: tabular-nums; pointer-events: none; transition: color .3s; }
.answer-wrap .fuse { position: absolute; left: 7px; right: 7px; bottom: 4px; height: 3px; border-radius: 3px; background: rgba(255, 255, 255, .08); overflow: hidden; pointer-events: none; }
.answer-wrap .fuse i { display: block; height: 100%; background: #ad8cff; transform-origin: 0 50%; will-change: transform; transition: background-color .3s; }
.answer-wrap.hot .secs { color: #ff6b6b; }
.answer-wrap.hot .fuse i { background: #ff6b6b; }

/* ---------- Phones: the play screen ----------
   An ordinary page anchored to the top: no fixed layers, nothing sized to the screen. That way it behaves the same
   whether the keyboard slides over the page (iPhone Safari) or shrinks it (other browsers): the keyboard just covers
   or cuts off the bottom, and nothing moves or slides over anything else. The answer box sits high, right under the
   ladder, so it's always above the keyboard. Below the answer box: the pack's five cards, then the desk with the
   binder. The page itself can't be dragged while playing (script), so nothing drifts. */
@media (max-width: 700px) {
  html:has(body[data-screen="play"]), body[data-screen="play"] { overflow: hidden; overscroll-behavior: none; }
  body[data-screen="play"] h1, body[data-screen="play"] .tag, body[data-screen="play"] .corner { display: none; }
  body[data-screen="play"] main { padding: 0; }
  body[data-screen="play"] #play { position: relative; z-index: 2; padding: max(8px, env(safe-area-inset-top)) 8px 0; }
  body[data-screen="play"] #play > .mat { margin: 0; padding: 11px 12px 14px; display: flex; flex-direction: column; }
  /* The same playmat look, minus the fine printed rings, which are slow to redraw at phone resolution. */
  body[data-theme="desk"][data-screen="play"] #play > .mat {
    background: radial-gradient(circle at 50% 0%, rgba(255, 200, 140, .14), transparent 55%),
      linear-gradient(165deg, #1a1d3a, #10122a 60%, #0c0d20);
    box-shadow: 0 16px 34px rgba(0, 0, 0, .7), inset 0 1px 0 rgba(255, 255, 255, .08);
  }
  body[data-screen="play"] .mat::after { display: none; }
  /* The binder and the loose card, on the desk right below the mat (part of the page, so they never move or cover it). */
  body[data-screen="play"] .desk-foot { display: block; margin: 4px 0 0 calc(50% - 50vw); z-index: 1; }
  body[data-screen="play"] .deck-label { align-items: center; font-size: 11px; }
  body[data-screen="play"] .prompt { margin-top: 8px; padding: 10px 13px 12px; height: 82px; } /* room for two lines on every card */
  body[data-screen="play"] .prompt .q { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; line-height: 1.2; }
  body[data-screen="play"] .prompt .set-icon { width: 42px; height: 42px; border-radius: 11px; }
  body[data-screen="play"] .prompt .q { font-size: clamp(19px, 5.6vw, 24px); }
  body[data-screen="play"] .ladder { margin-top: 10px; }
  body[data-screen="play"] .pot { margin-top: 6px; height: 46px; } /* fixed heights, so the answer box never shifts */
  body[data-screen="play"] .pot .val { font-size: 22px; }
  body[data-screen="play"] .pot .label { font-size: 10px; }
  body[data-screen="play"] #controls { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 8px; align-items: center; margin-top: 6px; }
  body[data-screen="play"] #controls .need { grid-column: 1 / -1; margin: 0 0 6px; font-size: 13px; height: 18px; line-height: 18px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  body[data-screen="play"] #controls form { margin: 0; }
  body[data-screen="play"] #controls input { padding: 12px 58px 12px 12px; font-size: 18px; }
  body[data-screen="play"] #controls button { padding: 12px 14px; }
  body[data-screen="play"] #controls .actions { margin: 0; }
  body[data-screen="play"] #controls .bank { white-space: nowrap; }
  body[data-screen="play"] #controls .msg { grid-column: 1 / -1; min-height: 0; margin-top: 4px; }
  body[data-screen="play"] #controls .msg:empty { display: none; }
  body[data-screen="play"] #result { margin-top: 8px; max-height: 50svh; overflow-y: auto; overscroll-behavior: contain; padding-bottom: 0; }
  body[data-screen="play"] #result #next { position: sticky; bottom: 0; margin-bottom: 12px; box-shadow: 0 -10px 18px 6px var(--panel); }
  /* The pack's five cards, right under the answer box: done ones face up, the current one raised. */
  body[data-screen="play"] .deck { order: 10; margin: 14px 0 0; padding-top: 14px; gap: 10px; border-top: 1px dashed rgba(255, 255, 255, .1); }
  body[data-screen="play"] .deck .dk { width: 54px; }
  body[data-screen="play"] .deck .dk .tcard { font-size: calc(54px / 13); }
}
/* Short phones (iPhone SE and smaller): a slightly tighter top, so the answer box still clears the keyboard.
   html.short is decided once, from the screen when the page loads: a height media query would also switch on when a
   browser shrinks the page for the keyboard, and re-lay out the board mid-typing. */
@media (max-width: 700px) {
  html.short body[data-screen="play"] #play { padding-top: max(6px, env(safe-area-inset-top)); }
  html.short body[data-screen="play"] #play > .mat { padding: 9px 10px 12px; }
  html.short body[data-screen="play"] .prompt { margin-top: 6px; padding: 8px 11px 9px; height: 64px; }
  html.short body[data-screen="play"] .prompt .set-icon { width: 34px; height: 34px; border-radius: 9px; }
  html.short body[data-screen="play"] .prompt .q { font-size: 18px; }
  html.short body[data-screen="play"] .ladder { margin-top: 8px; }
  html.short body[data-screen="play"] .pot { margin-top: 2px; }
  html.short body[data-screen="play"] #controls .need { margin-bottom: 4px; }
  html.short body[data-screen="play"] .deck .dk { width: 44px; }
  html.short body[data-screen="play"] .deck .dk .tcard { font-size: calc(44px / 13); }
}
/* ---------- Phones (touch): the board pinned to the visible screen ----------
   #play covers exactly the part of the screen you can see (--seen-top/--seen-h, kept by fitPlay in index.html), so
   the phone keyboard can't push it off screen or reveal the desk over it. The board is anchored at the top: when the
   keyboard opens only the space under the answer box shrinks, and the pack's cards make way (html.kbd). */
html.touch-ui body[data-screen="play"] { overflow: hidden; overscroll-behavior: none; }
html.touch-ui body[data-screen="play"] #play { position: fixed; left: 0; right: 0; top: 0; z-index: 2; height: var(--seen-h, 100%);
  transform: translateY(var(--seen-top, 0px)); display: flex; flex-direction: column; padding: max(8px, env(safe-area-inset-top)) 8px 0; touch-action: none; }
html.touch-ui body[data-screen="play"] #play > .mat { flex: 1 1 auto; min-height: 0; overflow: hidden; overflow: clip; padding: 10px 12px 10px; margin-bottom: max(8px, env(safe-area-inset-bottom)); }
html.touch-ui.kbd body[data-screen="play"] #play > .mat { margin-bottom: 6px; }
html.touch-ui body[data-screen="play"] #play > .mat > * { flex-shrink: 0; } /* every row keeps its size; none gets squeezed */
html.touch-ui body[data-screen="play"] .desk-foot { display: none; }
html.touch-ui body[data-screen="play"] .prompt { height: 76px; }
html.touch-ui body[data-screen="play"] #controls { position: relative; }
/* A wrong answer's message shows in place of the "Next:" hint, so nothing below shifts. */
html.touch-ui body[data-screen="play"] #controls .msg { position: absolute; left: 0; right: 0; top: 0; height: 18px; margin: 0; font-size: 13px; line-height: 18px;
  text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; background: #121430; color: #ffb3b3; }
/* The card's result fills whatever room is left under the board and scrolls inside it, "Next card" always in reach. */
html.touch-ui body[data-screen="play"] #result { flex: 0 1 auto; min-height: 0; max-height: none; overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y; }
html.touch-ui body[data-screen="play"] .deck { margin-top: auto; padding-top: 10px; }
html.touch-ui body[data-screen="play"] .deck .dk { width: 46px; }
html.touch-ui body[data-screen="play"] .deck .dk .tcard { font-size: calc(46px / 13); }
html.touch-ui.kbd body[data-screen="play"] .deck { display: none; }
html.touch-ui.short body[data-screen="play"] .prompt { height: 60px; }
/* Compact rows, so the answer box clears the keyboard even on small phones: the pot's label and value share one line,
   and short phones leave out the "card 1 of 5" strip (the pack's cards at the bottom show it). */
html.touch-ui body[data-screen="play"] .pot { height: 24px; align-items: center; margin-top: 6px; }
html.touch-ui body[data-screen="play"] .pot > div:first-child { display: flex; align-items: baseline; gap: 8px; }
html.touch-ui body[data-screen="play"] .pot .val { font-size: 19px; line-height: 24px; }
html.touch-ui body[data-screen="play"] .pot .val.zero { font-size: 16px; }
html.touch-ui.short body[data-screen="play"] .deck-label { display: none; }
html.touch-ui.short body[data-screen="play"] .prompt { margin-top: 0; }
html.touch-ui.short body[data-screen="play"] #play > .mat { padding-top: 7px; }
html.touch-ui.short body[data-screen="play"] .ladder { margin-top: 6px; }
html.touch-ui.short body[data-screen="play"] .pot { margin-top: 3px; }

button, input { touch-action: manipulation; }
/* The buttons under the pack: small mats of their own, so they read as part of the table, not as a footnote. */
body[data-theme="desk"] .hub-btn {
  background: linear-gradient(165deg, #1a1d3a, #10122a 60%, #0c0d20);
  border: 2px solid #07081a;
  box-shadow: 0 14px 30px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .08);
}
body[data-theme="desk"] .hub-btn:hover { border-color: #3a2f6e; }
