/* Dungeon Draft — a card table in a fantasy tavern. Class colours follow the card frames (light / base / dark). */
:root {
  --bg: #120a06; --panel: #21150c; --panel2: #2d1d11; --line: #4a3420; --ink: #f3e7c9; --muted: #cdbd96;
  --gold: #e8c26a; --gold-dark: #8e6224; --ok: #6fcf7f; --bad: #e06060; --parch-ink: #2a1a0c;
  --mage: #1B4F9C; --mage-l: #3F80D8; --mage-d: #081A3D;
  --druid: #2F6B2A; --druid-l: #61AA40; --druid-d: #0E2A0C;
  --warrior: #9E1219; --warrior-l: #D42A30; --warrior-d: #3E0508;
  --rogue: #4A2366; --rogue-l: #8C54C4; --rogue-d: #1A0828;
  --paladin: #9EA7B0; --paladin-l: #E4E9EE; --paladin-d: #3A4149;
  --pirate: #9A6A35; --pirate-l: #DBA85E; --pirate-d: #3B230C;
  --monster: #2b2b30; --monster-l: #5a5a63; --monster-d: #0b0b0d;
  --quest: #b8741f; --quest-l: #f0b552; --quest-d: #4a2a08;
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { background: var(--bg); }
html, body { margin: 0; color: var(--ink); font: 15px/1.35 'Alegreya Sans', system-ui, sans-serif; }
body { min-height: 100vh; }
/* behind everything: the same boards as the table (img/table/wood.svg, a seamless tile), larger, out of focus and darkened towards the edges */
body::before { content: ''; position: fixed; inset: -60px; z-index: -1; filter: blur(14px);
  background: radial-gradient(ellipse 62% 58% at 50% 46%, rgba(12,5,2,.3), rgba(6,2,1,.9) 100%), url(img/table/wood.svg) 50% 0 / 2420px auto; }
button { font: inherit; }
h1, h2, h3 { font-family: 'Kurale', 'Alegreya Sans', serif; font-weight: normal; margin: 0; }   /* Uncial Antiqua has no Cyrillic */
h3 { font-size: 15px; color: var(--gold); margin: 14px 0 6px; }

/* the header keeps to the top edge of the page on every screen; in a game it also carries the round, what to do now and the journal */
.top { position: sticky; top: 0; z-index: 15; display: flex; align-items: center; gap: 14px; min-height: 68px; padding: 6px 18px;
  background: linear-gradient(#2e170a, #170a04); box-shadow: inset 0 -1px 0 rgba(232,194,106,.4), 0 6px 18px rgba(0,0,0,.55); }
.top h1 { font: 22px/1 'Uncial Antiqua', serif; color: var(--gold); white-space: nowrap; }
.top h1 small { display: none; margin-top: 4px; font: 500 12px/1 'Alegreya Sans', sans-serif; color: var(--muted); letter-spacing: .03em; }   /* "table for four": only while a game shows */
.status { flex: 1; min-width: 0; color: var(--muted); font-size: 14px; overflow-wrap: anywhere; }
.status b { color: var(--ink); font-weight: 500; }
.hud { flex: 1; min-width: 0; min-height: 56px; display: none; align-items: center; gap: 16px; }
.round { flex: none; display: flex; align-items: center; gap: 10px; padding: 4px 16px; border: solid rgba(232,194,106,.3); border-width: 0 1px; white-space: nowrap; }
.pips { display: flex; gap: 5px; }   /* the four rounds */
.pips i { width: 11px; height: 11px; border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--gold-dark); }
.pips i.done { background: var(--gold-dark); }
.pips i.on { background: #ffd870; box-shadow: 0 0 0 1px #140902, 0 0 9px 2px rgba(255,190,70,.75); }
.round b { display: block; font: 400 17px/1.1 'Kurale', serif; color: var(--gold); }
.round b span { font: 700 15.5px/1 'Cinzel', serif; }
.round small { display: block; margin-top: 4px; font: 700 11px/1 'Alegreya Sans', sans-serif; letter-spacing: .12em; text-transform: uppercase; color: var(--ink); }
.say { flex: 1; min-width: 0; }   /* what to do now, and under it the details */
.say b { display: block; font: 400 18px/1.15 'Kurale', serif; color: #fff3d2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.say small { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; margin-top: 1px; font-size: 13px; line-height: 1.25; color: var(--muted); }
.say small:empty { display: none; }
/* the journal in the header: a scroll and, next to it, the last entry in a chronicler's hand. No button look;
   under the pointer the scroll glows (and the journal opens, see app.js) */
.ticker { flex: none; max-width: 330px; min-height: 44px; display: none; align-items: center; gap: 10px; padding: 0 4px; border: 0; background: none; color: #ecdcb2; cursor: pointer; text-align: left; }
.ticker .scroll { flex: none; width: 50px; height: 40px; filter: drop-shadow(0 2px 3px rgba(0,0,0,.65)); transition: filter .25s, transform .25s; }
.ticker:hover .scroll, .ticker:focus-visible .scroll, .ticker[aria-expanded="true"] .scroll { transform: translateY(-1px) scale(1.07);
  filter: drop-shadow(0 0 4px rgba(255,222,140,.95)) drop-shadow(0 0 13px rgba(255,176,66,.8)); }
#ticker { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 400 15.5px/1.25 'Kurale', serif; }
#ticker:empty { display: none; }
#ticker b { display: block; margin-bottom: 3px; color: var(--gold); font: 700 10.5px/1 'Alegreya Sans', sans-serif; letter-spacing: .16em; text-transform: uppercase; }
body:has(.game:not([hidden])) :is(.hud, .ticker) { display: flex; }
body:has(.game:not([hidden])) .top h1 small { display: block; }
body:has(.game:not([hidden])) .status { display: none; }
@media (max-width: 1279px) { #ticker { display: none; } }
@media (max-width: 1023px) {   /* a narrow window: the round and the prompt take a second row */
  .top { flex-wrap: wrap; row-gap: 2px; }
  .top h1 { margin-right: auto; }
  .hud { order: 9; flex-basis: 100%; }
  .round { padding-left: 0; border-left: 0; }
}
/* The one menu, behind the menu button on every screen: restart, new game, rules, sound, music, language. */
.burger { flex: none; display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 8px; cursor: pointer;
  background: rgba(20,12,6,.72); color: var(--gold); box-shadow: 0 0 0 1px var(--gold-dark), 0 3px 8px rgba(0,0,0,.4); }
.burger svg { width: 22px; height: 22px; }
.menu { display: none; position: absolute; right: 12px; top: calc(100% + 6px); z-index: 50; flex-direction: column; gap: 2px; width: 270px; max-width: calc(100vw - 16px);
  padding: 8px; border-radius: 12px; background: linear-gradient(#3a1c0c, #1e0d05); box-shadow: 0 0 0 1px rgba(232,194,106,.55), 0 18px 44px rgba(0,0,0,.75); }
.menu-open .menu { display: flex; }
.menu hr { width: 100%; margin: 4px 0; border: 0; border-top: 1px solid rgba(232,194,106,.25); }
.mi { display: flex; align-items: center; gap: 12px; min-height: 46px; padding: 0 12px; border: 0; border-radius: 8px; background: none; color: var(--ink);
  font: 500 16px/1.2 'Alegreya Sans', sans-serif; text-align: left; }
button.mi { cursor: pointer; }
button.mi:hover { background: rgba(232,194,106,.14); }
.mi > svg { flex: none; width: 20px; height: 20px; color: var(--gold); }
.mi > span:first-of-type { flex: 1; }
/* a switch: sound, music */
.sw i { flex: none; position: relative; width: 38px; height: 22px; border-radius: 11px; background: rgba(0,0,0,.45); box-shadow: inset 0 0 0 1px var(--gold-dark); }
.sw i::after { content: ''; position: absolute; left: 3px; top: 3px; width: 16px; height: 16px; border-radius: 50%; background: var(--muted); transition: transform .15s; }
.sw[aria-pressed="true"] i { background: linear-gradient(#f0cf7c, #b8862e); }
.sw[aria-pressed="true"] i::after { transform: translateX(16px); background: #2a1404; }
:is(.menu, .panel) .lang .btn { min-height: 34px; }
body.ph .hud { display: none !important; }   /* the phone column shows the round and the prompt itself */
@media (max-width: 700px) {
  .top { min-height: 54px; padding: 4px 10px; gap: 8px; }
  .top h1 { font-size: 19px; }
  .top h1 small { display: none !important; }
  .menu { right: 8px; }
}
.lang { display: inline-flex; white-space: nowrap; }
.lang .btn { min-width: 44px; padding: 0 11px; font-size: 13px; color: var(--muted); }
.lang .btn:first-child { border-radius: 8px 0 0 8px; }
.lang .btn:last-child { border-radius: 0 8px 8px 0; }
.lang .btn.on { background: linear-gradient(#ffeaa8, #e0aa3c); color: #2a1404; box-shadow: 0 0 0 1px #140902, inset 0 1px 0 rgba(255,255,255,.55); }

.btn { display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-height: 44px; padding: 0 18px; border: 0; border-radius: 8px;
  background: linear-gradient(#f0cf7c, #b8862e); color: #1b1206; font-weight: 700; font-size: 15px; white-space: nowrap; cursor: pointer;
  box-shadow: 0 0 0 1px #140902, inset 0 1px 0 rgba(255,255,255,.55), 0 3px 8px rgba(0,0,0,.5); }
.btn:hover { filter: brightness(1.08); }
.btn:disabled { opacity: .45; cursor: default; filter: none; }
.btn.ghost { background: rgba(20,12,6,.72); color: var(--gold); box-shadow: 0 0 0 1px var(--gold-dark), 0 3px 8px rgba(0,0,0,.4); }
.btn.quiet { background: var(--panel2); color: var(--ink); box-shadow: 0 0 0 1px var(--line); }
.btn.big { min-height: 52px; padding: 0 26px; font-size: 17px; }
.btn svg { width: 18px; height: 18px; flex: none; }

/* ------------------------------------------------------------------ the start screen
   The tavern picture fills the window, a little out of focus and darkened at the edges; the main menu and its panels
   (new game, online, simulation) stand in the middle. body.intro is on while this screen is the place to be. */
.scene { position: fixed; inset: 0; z-index: 2; display: none; overflow: hidden; background: #060201; }
body.intro .scene, body.fly-down .scene { display: block; }
.scene-img { position: absolute; inset: -4%; background: url(img/tavern.webp) 50% 42% / cover; filter: blur(3px) brightness(.82); will-change: transform, opacity;
  -webkit-mask-image: linear-gradient(#000 76%, transparent); mask-image: linear-gradient(#000 76%, transparent); }   /* its lower edge melts into the dark */
.scene::after { content: ''; position: absolute; inset: 0; background: radial-gradient(ellipse 75% 65% at 50% 45%, rgba(12,5,2,.2), rgba(6,2,1,.82) 100%); }
/* an overlay of its own, so the header coming and going never moves it; a panel taller than the window scrolls */
.setup { position: fixed; inset: 0; z-index: 3; overflow-y: auto; display: grid; padding: 28px 16px; }
.panel { width: min(460px, 100%); margin: auto; padding: 24px; display: grid; gap: 14px; border: 1px solid rgba(232,194,106,.45); border-radius: 14px;
  background: linear-gradient(rgba(44,24,12,.9), rgba(24,12,6,.93)); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); box-shadow: 0 24px 70px rgba(0,0,0,.75);
  animation: panel-in .35s cubic-bezier(.2,.8,.2,1) backwards; }   /* a panel that comes into view rises into place */
.menu0 { width: min(380px, 100%); text-align: center; }
.menu0 .btn { width: 100%; }
.setup .title { font: 44px/1 'Uncial Antiqua', serif; color: var(--gold); text-shadow: 0 0 24px rgba(255,180,70,.45), 0 3px 6px rgba(0,0,0,.8); }
.menu0 .hint { margin-bottom: 6px; font-size: 15px; }
#lobby:empty { display: none; }
/* this screen is the main menu itself: no header on it (on the way back from the table it slides out first) */
body.intro:not(.fly-up) .top { display: none; }
@keyframes panel-in { from { opacity: 0; transform: translateY(16px) scale(.97); } }

/* The camera. It stands at --cam in front of the screen and tilts down by a quarter turn, from the room to the table
   seen from above. Each plane is turned about the camera itself: translateZ out to it, rotateX, translateZ back.
   fly-down: the menu goes; the picture swings up out of view and goes dark; from the dark below the table swings in,
   lies flat and comes closer (it starts 3.2 times as far); then the header slides in and the room around the table
   lights up. fly-up is the way back. app.js sets the classes and takes them off when the flight is over (cam());
   the cards are dealt as the table arrives. */
.scene-img, .game { --cam: 120vh; }
@keyframes cam-down {
  from { transform: perspective(var(--cam)) translateZ(var(--cam)) rotateX(0deg) translateZ(calc(-1 * var(--cam))); opacity: 1; }
  to { transform: perspective(var(--cam)) translateZ(var(--cam)) rotateX(-54deg) translateZ(calc(-1 * var(--cam))); opacity: 0; } }
@keyframes cam-up {
  from { transform: perspective(var(--cam)) translateZ(var(--cam)) rotateX(-54deg) translateZ(calc(-1 * var(--cam))); opacity: 0; }
  to { transform: perspective(var(--cam)) translateZ(var(--cam)) rotateX(0deg) translateZ(calc(-1 * var(--cam))); opacity: 1; } }
@keyframes table-in {
  from { transform: perspective(var(--cam)) translateZ(var(--cam)) rotateX(38deg) translateZ(calc(-3.2 * var(--cam))); opacity: 0; }
  60% { opacity: 1; }
  to { transform: perspective(var(--cam)) translateZ(var(--cam)) rotateX(0deg) translateZ(calc(-1 * var(--cam))); opacity: 1; } }
@keyframes table-out {
  from { transform: perspective(var(--cam)) translateZ(var(--cam)) rotateX(0deg) translateZ(calc(-1 * var(--cam))); opacity: 1; }
  to { transform: perspective(var(--cam)) translateZ(var(--cam)) rotateX(32deg) translateZ(calc(-2.8 * var(--cam))); opacity: 0; } }
@keyframes panel-out { to { opacity: 0; transform: translateY(-22px) scale(.95); } }
@keyframes top-in { from { transform: translateY(-110%); } }
@keyframes top-out { to { transform: translateY(-110%); } }
@keyframes fade-out { to { opacity: 0; } }
@keyframes fade-in { from { opacity: 0; } }
body.fly-down .panel { animation: panel-out .32s ease-in forwards; }
body.fly-down .scene-img { animation: cam-down 1.05s .08s cubic-bezier(.55,.06,.75,.55) forwards; }
body.fly-down .game { animation: table-in 1.5s .75s cubic-bezier(.16,.72,.24,1) backwards; will-change: transform, opacity; }
body.fly-down .scene { animation: fade-out .55s 1.75s forwards; }
body.fly-down .top { animation: top-in .5s 1.8s cubic-bezier(.2,.8,.25,1) backwards; }
body.fly-up .game { animation: table-out .6s cubic-bezier(.5,0,.8,.5) forwards; will-change: transform, opacity; pointer-events: none; }
body.fly-up .scene { animation: fade-in .35s backwards; }
body.fly-up .top { animation: top-out .3s ease-in forwards; }
body.fly-up .scene-img { animation: cam-up 1s .4s cubic-bezier(.2,.7,.25,1) backwards; }
body.fly-up .panel { animation: panel-in .45s 1s cubic-bezier(.2,.8,.2,1) backwards; }
@media (prefers-reduced-motion: reduce) { body.fly-down *, body.fly-up *, .panel { animation: none !important; } }
.setup h2 { color: var(--gold); font-size: 24px; }
.setup label { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.setup select, .setup input:not([type]) { background: var(--panel2); color: var(--ink); border: 1px solid var(--line); border-radius: 6px; padding: 6px 10px; font: inherit; }
.setup .check { justify-content: flex-start; }
.hint { color: var(--muted); font-size: 13px; margin: 0; }
.levels { display: grid; gap: 8px; padding-left: 14px; border-left: 2px solid var(--line); }
.levels label { color: var(--ink); font-size: 15px; }
#lobbyBox .levels { margin: 6px 0 2px; }
.or { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: 13px; }
.or::before, .or::after { content: ''; flex: 1; border-top: 1px solid var(--line); }
/* the table before an online game: the code and the link to pass on, then a small table with a seat per player */
.lobby { display: grid; gap: 14px; }
.lobby-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.lobby-top h2 { margin: 0; }
.codechip { padding: 6px 12px; border: 1px dashed var(--gold-dark); border-radius: 8px; color: var(--gold); font: 800 17px/1 'Alegreya Sans SC', sans-serif; letter-spacing: .14em; user-select: all; }
.share { display: flex; gap: 8px; }
.share input { flex: 1; min-width: 0; font-size: 13px; text-overflow: ellipsis; }
.share .btn { flex: none; min-height: 38px; padding: 0 14px; }
.share .btn svg { width: 17px; height: 17px; }
.share .btn.done { background: var(--ok); color: #10240f; }
.mtable { position: relative; height: 292px; }
.mtable::before { content: ''; position: absolute; inset: 30% 22% 34%; border-radius: 50%; background: radial-gradient(ellipse at 50% 40%, rgba(30,11,4,.1), rgba(18,6,2,.6)), url(img/table/wood.svg) 50% 50% / 420px auto;
  box-shadow: 0 0 0 5px #3a1f0e, 0 0 0 7px #1a0f07, 0 14px 28px rgba(0,0,0,.6), inset 0 0 26px rgba(0,0,0,.55); }
.mtable-n { position: absolute; left: 50%; top: 47%; transform: translate(-50%, -50%); text-align: center; color: var(--gold); font: 30px/1 'Kurale', serif; text-shadow: 0 2px 4px #000; white-space: nowrap; }
.mtable-n small { display: block; margin-top: 4px; color: var(--ink); font: 12px/1 'Alegreya Sans', sans-serif; }
.mseat { position: absolute; z-index: 1; transform: translate(-50%, -50%); display: grid; justify-items: center; gap: 3px; width: 104px; text-align: center; }
.mseat .bust { width: 44px; height: 44px; font-size: 22px; }
.mseat b { display: flex; gap: 4px; max-width: 100%; white-space: nowrap; font-size: 14px; line-height: 1.15; text-shadow: 0 1px 3px #000; }
.mseat b span { overflow: hidden; text-overflow: ellipsis; }   /* a long name is cut, "(you)" after it is not */
.mseat b i { flex: none; color: var(--muted); font-style: normal; font-weight: 400; }
.mseat small { padding: 2px 8px; border-radius: 9px; background: rgba(0,0,0,.55); color: var(--muted); font-size: 12px; line-height: 1.2; white-space: nowrap; }
.mseat.ok small { background: var(--ok); color: #10240f; font-weight: 700; }
.mseat.ok small::before { content: '✓ '; }
.mseat.free .bust { background: none; box-shadow: none; border: 2px dashed var(--gold-dark); color: var(--gold-dark); text-shadow: none; }
.mseat.free b { color: var(--muted); font-weight: 400; }

.row { display: flex; gap: 10px; overflow-x: auto; padding: 4px 2px 10px; }
.row.cards { flex-wrap: wrap; overflow: visible; }
.actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.empty { color: var(--muted); font-size: 13px; padding: 6px 0; }

/* player panels of the simulation's one-game table */
.opp { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; }
.opp .head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.opp .name { font: 17px/1.2 'Kurale', serif; }
.badge { font-size: 12px; padding: 1px 7px; border-radius: 99px; background: var(--panel2); color: var(--muted); border: 1px solid var(--line); white-space: nowrap; }
.badge.turn { color: #1b1206; background: var(--gold); border-color: var(--gold); }
.stats { display: flex; flex-wrap: wrap; gap: 10px; margin: 6px 0; font-size: 14px; }
.stat { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }

/* ------------------------------------------------------------------ cards
   Card design: 200×280 in play, 150×210 thumbnail (.small). Everything inside is measured in --u,
   one design pixel, so a card scales with its width (--cw). The ability band sits in the flow at the bottom:
   a long text makes the card taller instead of being cut. */
.card { --u: calc(100cqw / 200); container-type: inline-size; position: relative; width: var(--cw, 200px); aspect-ratio: 5 / 7; flex: none;
  display: flex; flex-direction: column; justify-content: flex-end; padding: 0; margin: 0; border: 0; border-radius: 5% / 3.57%;
  background: #05060a; color: #F2E8D2; font: inherit; text-align: center; cursor: default; transition: transform .12s, box-shadow .12s; }
.card.small { --u: calc(100cqw / 150); width: var(--cw, 128px); }
.card > * { position: absolute; }
.card .art { inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
/* 5cqw is the card's own corner (5% of its width) at any size: the overlays never stick out of the rounded frame */
.card .nz { left: 0; top: 0; width: 100%; height: calc(var(--u) * 80); border-radius: 5cqw 5cqw 0 0;
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 45%, transparent 100%); mask-image: linear-gradient(180deg, #000 0%, #000 45%, transparent 100%);
  background: linear-gradient(180deg, rgba(3,4,8,.9) 0%, rgba(8,10,18,.62) 45%, rgba(8,10,18,0) 100%); }
.card .nz.q1, .card .nz.q2 { background: linear-gradient(180deg, rgba(14,6,10,.94) 0%, rgba(30,10,20,.72) 58%, rgba(30,10,20,0) 100%); height: calc(var(--u) * 104); }
.card .nz.q2 { height: calc(var(--u) * 124); }
.card.small .nz.q3 { height: calc(var(--u) * 122); }
.card .ab { position: relative; padding: calc(var(--u) * 34) calc(var(--u) * 6) calc(var(--u) * 11) calc(var(--u) * 57); border-radius: 0 0 5cqw 5cqw;
  background: linear-gradient(180deg, rgba(3,4,8,0) 0, rgba(10,12,22,.5) calc(var(--u) * 18), rgba(4,5,9,.86) calc(var(--u) * 34), rgba(2,3,5,.93) 100%); }
.card .ab p { margin: 0; font: 500 max(10.5px, calc(var(--u) * 11))/1.27 'Alegreya Sans', sans-serif; text-shadow: 0 1px 1px rgba(0,0,0,.9); overflow-wrap: break-word; }
.card .ab.long p { font-size: max(10.5px, calc(var(--u) * 10.5)); }
.card .strip { left: 0; top: 0; width: 35%; height: 100%; border-radius: 5cqw 0 0 5cqw; pointer-events: none; }
.card .md { display: block; width: calc(var(--u) * 37); height: calc(var(--u) * 37); }
.card .md img, .card .md svg { position: absolute; display: block; }
.card .md img { left: -6%; top: -6%; width: 112%; height: 112%; }
.card .md svg { inset: 0; width: 100%; height: 100%; overflow: visible; }
.card img.md { width: calc(var(--u) * 36 * 1.12); height: calc(var(--u) * 36 * 1.12); }
.card .cost { left: calc(var(--u) * 3); top: calc(var(--u) * 4); width: calc(var(--u) * 38); height: calc(var(--u) * 38); }
.card img.cost { left: calc(var(--u) * (3 - 2.28)); top: calc(var(--u) * (4 - 2.28)); width: calc(var(--u) * 42.56); height: calc(var(--u) * 42.56); }
.card .type { left: calc(var(--u) * (4 - 2.16)); top: calc(var(--u) * (45 - 2.16)); }
.card img.emb { left: calc(var(--u) * (4 - 2.16)); top: calc(var(--u) * (83 - 2.16)); width: calc(var(--u) * 40.32); height: calc(var(--u) * 44.8); }
.card img.emb.phx { top: calc(var(--u) * (129 - 2.16)); }   /* League of the Phoenix: its own emblem under the class emblem */
.card .stats { left: calc(var(--u) * 3.5); bottom: calc(var(--u) * 4); display: flex; flex-direction: column; gap: calc(var(--u) * 1); margin: 0; }
.card .stats .md { position: relative; }
.n1, .n2 { font-family: 'Cinzel', serif; font-weight: 700; text-anchor: middle; fill: url(#dd-num); stroke-linejoin: round; paint-order: stroke; }
.n1 { font-size: 52px; stroke-width: 10px; }
.n2 { font-size: 44px; letter-spacing: -3px; stroke-width: 9px; }
.n1.disc, .n2.disc { fill: url(#dd-green); }
.card .md.cost:has(.disc) { filter: drop-shadow(0 0 3px #6AFF5A); }
.card .nm { left: calc(var(--u) * 50); right: calc(var(--u) * 7); top: calc(var(--u) * 9); font: calc(var(--u) * 16)/1.06 'Uncial Antiqua', serif;
  filter: drop-shadow(0 0 .6px #140902) drop-shadow(0 0 .6px #140902) drop-shadow(0 0 .8px #140902) drop-shadow(0 1px 2px rgba(0,0,0,.9)); }
.card .nm.long { font-size: calc(var(--u) * 13); }
.card .nm span { background: linear-gradient(180deg, #FFF7D6 0%, #F8D77E 30%, #D29A38 56%, #FFE6A0 76%, #B07421 100%); -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.card .qb { left: calc(var(--u) * 50); right: calc(var(--u) * 5); top: calc(var(--u) * 7); display: flex; flex-direction: column; align-items: center; gap: calc(var(--u) * 5); }
.card .qb .nm { position: static; font-size: calc(var(--u) * 15); }
.card .qb .nm.long { font-size: calc(var(--u) * 13); }
.rqs { display: flex; flex-wrap: wrap; justify-content: center; gap: calc(var(--u) * 3) calc(var(--u) * 2.5); max-width: calc(var(--u) * 145); }
.rqs.six { max-width: calc(var(--u) * 106); }   /* 5 or 6 chips: 3 + 3 */
.rqc { display: inline-flex; align-items: center; gap: calc(var(--u) * 1); padding: calc(var(--u) * 1) calc(var(--u) * 3.5) calc(var(--u) * 1) calc(var(--u) * 1.5); border-radius: 999px; white-space: nowrap;
  box-shadow: 0 0 0 1px #C8913A, 0 0 0 2px #140902, 0 1px 3px rgba(0,0,0,.6); }
.card .rqc .gl { width: calc(var(--u) * 14); height: calc(var(--u) * 16); margin: 0; top: 0; }   /* compact: 4 chips in a row */
.rqc b { font: 700 calc(var(--u) * 10)/1 'Cinzel', serif; color: #fff; text-shadow: 0 0 1px #140902, 0 0 1.5px #140902, 0 0 2px #140902, 0 1px 2px #140902; }
.rqc.mage { background: linear-gradient(180deg, #6AA8F8 0%, #2E6CD6 50%, #163C8C 100%); }
.rqc.druid { background: linear-gradient(180deg, #7CD456 0%, #3E9A2C 50%, #1E5C16 100%); }
.rqc.warrior { background: linear-gradient(180deg, #FF6464 0%, #D42630 50%, #7E0A12 100%); }
.rqc.rogue { background: linear-gradient(180deg, #BE82F6 0%, #8442D2 50%, #4A1A82 100%); }
.rqc.paladin { background: linear-gradient(180deg, #EEF2F6 0%, #A8B3BE 50%, #5A6672 100%); }
.rqc.pirate { background: linear-gradient(180deg, #FFCC66 0%, #E0962E 50%, #8E5414 100%); }
.gl { position: relative; display: inline-block; vertical-align: middle; top: -1px; width: 1.64em; height: 1.82em; margin: 0 .5px; }
.act { display: inline-block; padding: .1em .6em .12em; border-radius: 999px; background: linear-gradient(180deg, #FFF0B8 0%, #E8B850 40%, #A8701E 72%, #D9A445 100%);
  color: #2A1404; font: 900 .82em/1.3 'Cinzel', serif; letter-spacing: .05em; white-space: nowrap; vertical-align: .05em;
  box-shadow: 0 0 0 1px #140902, 0 1px 2px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.7); }
.eog { display: inline-block; font-size: .8em; line-height: 1.3; padding: 1.5px; background: #140902; vertical-align: .08em;
  clip-path: polygon(0 0, 100% 0, calc(100% - .7em) 50%, 100% 100%, 0 100%, .7em 50%); }
.eog > span { display: block; padding: 1.2px; background: linear-gradient(180deg, #FFF0B8, #C8913A 55%, #8E5C18); clip-path: polygon(0 0, 100% 0, calc(100% - .66em) 50%, 100% 100%, 0 100%, .66em 50%); }
.eog > span > span { padding: .1em 1.05em .12em; background: linear-gradient(180deg, #9A1E28 0%, #5E0C14 55%, #3A060C 100%); color: #FFE6A0;
  font: 900 1em/1.3 'Cinzel', serif; letter-spacing: .05em; white-space: nowrap; clip-path: polygon(0 0, 100% 0, calc(100% - .62em) 50%, 100% 100%, 0 100%, .62em 50%); }
:lang(ru) .act, :lang(ru) .eog > span > span { font-family: 'Alegreya Sans SC', 'Alegreya Sans', sans-serif; font-weight: 800; letter-spacing: .02em; }
.card .newtag { right: calc(var(--u) * 6); top: calc(var(--u) * 84); padding: calc(var(--u) * 2) calc(var(--u) * 7); border-radius: 4px; background: linear-gradient(180deg, #1E9A6E, #0A5A3E);
  color: #FFF6DA; font: 900 max(9px, calc(var(--u) * 10))/1.2 'Cinzel', 'Alegreya Sans SC', serif; letter-spacing: .1em; text-transform: uppercase;
  box-shadow: 0 0 0 1px #E2B04A, 0 0 0 2px #140902, 0 2px 4px rgba(0,0,0,.6); }
.card .stamp { left: calc(var(--u) * 50); right: calc(var(--u) * 8); top: 46%; padding: calc(var(--u) * 6) 0; transform: rotate(-12deg); border: calc(var(--u) * 3) solid #C8283A;
  border-radius: 8px; color: #E8384A; font: 900 calc(var(--u) * 14)/1.1 'Cinzel', 'Alegreya Sans SC', serif; letter-spacing: .1em; text-transform: uppercase;
  background: rgba(40,4,8,.45); box-shadow: inset 0 0 0 2px rgba(200,40,58,.5); text-shadow: 0 1px 1px rgba(0,0,0,.6); }
.card.done .art { filter: sepia(.35) brightness(.8); }
.card .note { left: calc(var(--u) * 42); right: calc(var(--u) * 4); bottom: calc(var(--u) * 6); padding: 2px 6px; border-radius: 8px; background: rgba(8,6,4,.85);
  color: var(--gold); font: 700 max(10px, calc(var(--u) * 11))/1.15 'Alegreya Sans', sans-serif; box-shadow: 0 0 0 1px var(--gold-dark); }
.card.playable .note { background: linear-gradient(180deg, #FFF0B8 0%, #E8B850 40%, #A8701E 100%); color: #2A1404; box-shadow: 0 0 0 1px #140902; }
.card .bd { inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 1px rgba(0,0,0,.6), inset 0 0 0 1.5px rgba(255,226,160,.12); pointer-events: none; }
.card.playable { cursor: pointer; box-shadow: 0 0 0 2px #FFD870, 0 0 14px 3px rgba(255,190,70,.75), 0 0 34px 8px rgba(255,150,40,.35); }
.card.playable:hover { transform: translateY(-4px); }
.card.dim { filter: grayscale(.7) brightness(.55); }

/* thumbnail (150×210): bigger icons, no ability text */
.card.small .nz { height: calc(var(--u) * 62); }
.card.small .nz.q1, .card.small .nz.q2 { height: calc(var(--u) * 88); }
.card.small .md { width: calc(var(--u) * 31); height: calc(var(--u) * 31); }
.card.small img.md { width: calc(var(--u) * 33.6); height: calc(var(--u) * 33.6); }
.card.small .cost { left: calc(var(--u) * 2); top: calc(var(--u) * 3); width: calc(var(--u) * 32); height: calc(var(--u) * 32); }
.card.small img.cost { left: calc(var(--u) * 0.08); top: calc(var(--u) * 1.08); width: calc(var(--u) * 35.84); height: calc(var(--u) * 35.84); }
.card.small .type { left: calc(var(--u) * 1.2); top: calc(var(--u) * 35.2); }
.card.small img.emb { left: calc(var(--u) * 1.2); top: calc(var(--u) * 67.2); width: calc(var(--u) * 33.6); height: calc(var(--u) * 38.08); }
.card.small img.emb.phx { top: calc(var(--u) * 106); }
.card.small .stats { left: calc(var(--u) * 2.5); bottom: calc(var(--u) * 4); }
.card.small .n1 { font-size: 56px; stroke-width: 11px; }
.card.small .n2 { font-size: 46px; }
.card.small .nm { left: calc(var(--u) * 39); right: calc(var(--u) * 5); top: calc(var(--u) * 6); font-size: calc(var(--u) * 13); line-height: 1.05; }
.card.small .nm.long { font-size: calc(var(--u) * 11.5); }
.card.small .qb { left: calc(var(--u) * 38); right: calc(var(--u) * 4); top: calc(var(--u) * 5); gap: calc(var(--u) * 4); }
.card.small .qb .nm { font-size: calc(var(--u) * 12); }
.card.small .qb .nm.long { font-size: calc(var(--u) * 11); }
.card.small .rqs { max-width: calc(var(--u) * 76); gap: calc(var(--u) * 3) calc(var(--u) * 2); }   /* thumbnail: as large as before, 2 in a row */
.card.small .rqc { gap: calc(var(--u) * 1); padding: calc(var(--u) * 1) calc(var(--u) * 4) calc(var(--u) * 1) calc(var(--u) * 1); }
.card.small .rqc .gl { width: calc(var(--u) * 17); height: calc(var(--u) * 20); }
.card.small .rqc b { font-size: calc(var(--u) * 11); }
.card.small .newtag { top: calc(var(--u) * 64); }

/* stat medallions */
.ic { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%; font: 700 12px/1 'Alegreya Sans', sans-serif; color: #fff;
  text-shadow: 0 1px 0 rgba(0,0,0,.7); border: 1.5px solid #c9963f; box-shadow: inset 0 1px 0 rgba(255,255,255,.35); flex: none; }
.ic.xp, .ic.atk, .ic.gold { border: 0; border-radius: 0; box-shadow: none; background: center / 100% no-repeat; }
.ic.xp { background-image: url(img/icons/stat-xp-small.svg); }
.ic.atk { background-image: url(img/icons/stat-attack-small.svg); }
.ic.gold { background-image: url(img/icons/stat-gold-small.svg); }

/* ------------------------------------------------------------------ the table
   The game is drawn on a stage 1440 wide and 800 to 980 tall (390 wide and at least 708 tall on a phone, .ph).
   fit() in app.js scales it through --k to the space under the header and gives it the height that is left, so every
   size below is in stage pixels: the opponents hang from the top edge, the player's cards stand on the bottom one. */
.game { position: fixed; inset: 68px 0 0; z-index: 10; overflow: hidden; }
.tv { position: absolute; left: calc(50% - 720px * var(--k, 1)); top: 0; width: 1440px; height: 800px; transform-origin: 0 0; transform: scale(var(--k, 1)); }
.tv h2, .tv h3, .tv p { margin: 0; }

/* A tavern table from above: old boards (the tile img/table/wood.svg, a board is 96 px) inside a dark rim. Nothing stands on it but the game. */
.table { position: absolute; inset: 12px 40px 14px; border-radius: 64px;
  background: repeating-linear-gradient(90deg, rgba(0,0,0,.14) 0 2px, transparent 2px 9px), linear-gradient(180deg, #8a431c 0%, #5e2a10 12%, #47200c 55%, #57270f 100%);
  box-shadow: 0 0 0 2px #120704, inset 0 2px 0 rgba(255,200,140,.5), inset 0 -4px 7px rgba(0,0,0,.6), inset 3px 0 5px rgba(0,0,0,.3), inset -3px 0 5px rgba(0,0,0,.3), 0 30px 80px rgba(0,0,0,.85); }
.table::before { content: ''; position: absolute; inset: 24px; border-radius: 42px;
  background: radial-gradient(ellipse 72% 64% at 50% 42%, rgba(30,11,4,.2), rgba(18,6,2,.6) 100%), url(img/table/wood.svg) 0 0 / 1344px 768px;
  box-shadow: 0 0 0 2px rgba(14,5,2,.9), 0 0 0 3.5px rgba(255,190,120,.28), inset 0 0 0 1px rgba(0,0,0,.5), inset 0 12px 30px rgba(0,0,0,.6), inset 0 -8px 22px rgba(0,0,0,.45); }

/* The table itself is a 3D scene (table3d.js) on a canvas behind the stage; fit() in app.js lays its top on the frame of
   .table. The painted table above stays as it was: it shows until the scene is ready, and where the scene cannot run. */
.table3d { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity .9s; }
.table { transition: opacity .9s; }
body.t3d .table3d { opacity: 1; }
body.t3d .table { opacity: 0; }

/* draft: the way the packs travel between the opponents */
.flow { position: absolute; left: 0; top: 0; width: 1440px; height: 400px; pointer-events: none; }
.flow path { fill: none; stroke: #f0cf7c; stroke-width: 3; stroke-dasharray: 2 9; stroke-linecap: round; opacity: .8; }

/* seats: opponents sit clockwise from your left (.at-l, .at-tl, .at-t, .at-tr, .at-r) */
.seat { position: absolute; width: 330px; display: flex; flex-direction: row; align-items: flex-start; gap: 12px; z-index: 5; }
.seat.at-t, .seat.at-tl, .seat.at-tr { top: 6px; }
.seat.at-t { left: 555px; }
.seat.at-tl { left: 385px; }
.seat.at-tr { left: 725px; }
.seat.at-l, .seat.at-r { top: 150px; width: 400px; }
.seat.at-l { left: 24px; }
.seat.at-r { right: 24px; flex-direction: row-reverse; }   /* the head at the outer side, the cards towards the middle */
.seat.at-r .spot { flex-direction: row-reverse; }   /* cards in play lie towards the middle of the table */
.seat::before { content: ''; position: absolute; left: 50%; top: 40px; width: 420px; height: 270px; transform: translateX(-50%); border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255,214,140,.42), rgba(255,190,100,.16) 55%, transparent); opacity: 0; pointer-events: none; }
.seat.at-l::before, .seat.at-r::before { top: -10px; }
.seat.is-active::before { opacity: 1; }
.seat > * { position: relative; }

.bust { position: relative; width: 60px; height: 60px; border-radius: 50%; flex: none; display: grid; place-items: center;
  background: radial-gradient(circle at 34% 28%, var(--c1, #777), var(--c2, #333)); color: #fff7e0; font: 30px/1 'Kurale', serif; text-shadow: 0 2px 2px rgba(0,0,0,.65);
  box-shadow: 0 0 0 2px #1a0f07, 0 0 0 4px var(--gold), 0 0 0 5px #1a0f07, 0 6px 14px rgba(0,0,0,.65), inset 0 -8px 12px rgba(0,0,0,.35); }
.c-gold { --c1: #f0cf7c; --c2: #8e6224; } .c-crimson { --c1: #d8493c; --c2: #6a120f; } .c-teal { --c1: #44b0a8; --c2: #114c48; }
.c-violet { --c1: #9a6ee0; --c2: #3a1c72; } .c-amber { --c1: #e8a040; --c2: #7a420e; }
.is-active .bust { box-shadow: 0 0 0 2px #1a0f07, 0 0 0 4px #ffe08a, 0 0 0 5px #1a0f07, 0 0 26px 10px rgba(255,195,80,.7), inset 0 -8px 12px rgba(0,0,0,.35); }
.is-passed .bust { filter: saturate(.35) brightness(.75); }
.is-passed .spot, .is-passed .tokens { opacity: .62; }

.who { display: flex; align-items: baseline; gap: 8px; margin-top: 5px; white-space: nowrap; }
.who b { font: 400 21px/1.1 'Kurale', serif; color: var(--gold); text-shadow: 0 2px 3px rgba(0,0,0,.85); }
.who small { font-size: 13px; color: var(--muted); text-shadow: 0 1px 2px rgba(0,0,0,.85); }
.flags { display: flex; gap: 6px; align-items: center; min-height: 24px; }
.flag { display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 10px; border-radius: 99px; background: rgba(18,10,5,.88); color: var(--muted);
  font: 700 12.5px/1 'Alegreya Sans', sans-serif; white-space: nowrap; box-shadow: 0 0 0 1px var(--gold-dark); }
.flag.turn { background: linear-gradient(#ffeaa8, #e0aa3c); color: #2a1404; box-shadow: 0 0 0 1px #140902, 0 0 14px rgba(255,200,90,.85); }
.flag.ok { color: #c6ecb4; box-shadow: 0 0 0 1px #4f8a45; }
.flag.off { color: #f2b4aa; box-shadow: 0 0 0 1px #a5564a; }
.flag.first { color: var(--gold); }
.flag svg { width: 12px; height: 12px; }
.coin { display: inline-grid; place-items: center; width: 18px; height: 18px; margin-left: -5px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff0b8, #c9963f 60%, #8e5c18);
  color: #2a1404; font: 900 11px/1 'Cinzel', serif; text-shadow: none; box-shadow: 0 0 0 1px #140902; }

.tokens { display: flex; align-items: center; gap: 12px; margin-top: 5px; }
.tok { display: inline-flex; align-items: center; gap: 4px; font: 700 17px/1 'Cinzel', serif; color: #fff3d2; text-shadow: 0 1px 2px #000; white-space: nowrap; }
.tok img { width: 24px; height: 24px; display: block; }
.tok i { font: 500 12.5px/1 'Alegreya Sans', sans-serif; color: var(--muted); font-style: normal; text-shadow: 0 1px 2px rgba(0,0,0,.85); }

/* what lies in front of a player: cards in play face up, the hand and open quests face down, the draft pack */
/* a player's cards in play counted by class */
.classes { display: flex; gap: 8px; margin-top: 4px; }
.cc { display: inline-flex; align-items: center; gap: 2px; font: 700 14px/1 'Cinzel', serif; color: #fff3d2; text-shadow: 0 1px 2px #000; }
.cc .gl { top: 0; width: 19px; height: 21px; margin: 0; }
.cc.none { opacity: .36; }
.myplate .classes { gap: 10px; margin-top: 0; }
.myplate .cc { font-size: 16px; }
.myplate .cc .gl { width: 22px; height: 24px; }
.spot { display: flex; align-items: flex-end; gap: 14px; margin-top: 8px; min-height: 88px; }
.tab { display: flex; align-items: flex-end; }
.tab .card { --cw: 58px; box-shadow: 0 3px 7px rgba(0,0,0,.6); }
.tab .card + .card { margin-left: calc(var(--step, 31px) - 58px); }   /* --step: how far each next card shows, so any number fits */
.tab .card.fresh { box-shadow: 0 0 0 2px #ffd870, 0 0 14px 3px rgba(255,190,70,.8); transform: translateY(-8px); z-index: 2; }
.stack { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.stack small { font: 500 12px/1 'Alegreya Sans', sans-serif; color: var(--muted); white-space: nowrap; text-shadow: 0 1px 2px rgba(0,0,0,.9); }
.stack small b { color: var(--ink); font-weight: 700; }
.cb { display: block; flex: none; width: 28px; height: 39px; border-radius: 3px; border: 1.5px solid #c9963f;
  background: radial-gradient(circle at 50% 50%, #e8c26a 0 11%, transparent 12%), repeating-linear-gradient(45deg, rgba(232,194,106,.2) 0 2px, transparent 2px 6px),
    repeating-linear-gradient(-45deg, rgba(232,194,106,.2) 0 2px, transparent 2px 6px), linear-gradient(#5e1622, #2a060c);
  box-shadow: 0 0 0 1px #140902, 0 2px 5px rgba(0,0,0,.55); }
.stack.q .cb { border-color: #f0d28a; background: radial-gradient(circle at 50% 50%, #5a3410 0 13%, transparent 14%), radial-gradient(circle at 50% 50%, transparent 0 24%, #5a3410 25% 29%, transparent 30%),
    linear-gradient(#d6ad68, #9a6a2c); }
.pile { position: relative; width: 44px; height: 60px; }
.pile .cb { position: absolute; left: 0; bottom: 0; width: 40px; height: 56px; }
.pile .cb:nth-child(2) { left: 2px; bottom: 2px; } .pile .cb:nth-child(3) { left: 4px; bottom: 4px; }
.stack.pack small b { color: var(--gold); }

/* the middle of the table: the deck and the discard (the quest deck while quests are chosen); it keeps to the gap between the opponents and your cards */
.mid { position: absolute; left: 50%; top: max(240px, calc(50% - 184px)); transform: translateX(-50%); z-index: 4; }
.piles { display: flex; gap: 16px; align-items: flex-end; }
.piles .pile { width: 62px; height: 84px; }
.piles .pile .cb { width: 56px; height: 78px; border-radius: 5px; }
.piles .pile .cb:nth-child(2) { left: 3px; bottom: 3px; } .piles .pile .cb:nth-child(3) { left: 6px; bottom: 6px; }
.piles .pile .card { --cw: 56px; position: absolute; left: 0; bottom: 0; box-shadow: 0 3px 7px rgba(0,0,0,.6); }
.slot { flex: none; width: 56px; height: 78px; border-radius: 5px; border: 2px dashed rgba(240,207,124,.55); background: rgba(0,0,0,.22); }
.slot.wide { width: 78px; height: 109px; }

/* your place stands on the bottom edge: the row of big cards (a pack or your hand), under it your plate, quests, cards in play and the buttons */
.me { position: absolute; left: 0; right: 0; bottom: 0; height: 0; z-index: 6; }
.hand { position: absolute; left: 0; right: 0; bottom: 196px; display: flex; justify-content: center; align-items: flex-end; gap: 12px; }
.hand .card { transition: transform .14s ease, box-shadow .14s ease; transform-origin: 50% 100%; box-shadow: 0 10px 22px rgba(0,0,0,.6); }
.hand .card.playable { box-shadow: 0 0 0 2px #e8c26a, 0 10px 22px rgba(0,0,0,.6); }
/* a chosen card (a quest marked to keep, a card picked on a touch screen): see "chosen" further down */
.hand .empty { align-self: center; padding: 60px 0; font-size: 15px; text-shadow: 0 1px 2px rgba(0,0,0,.85); }
.hand.tight .card .ab p { font-size: calc(var(--u) * 11); }   /* ten cards or more: no 10.5px floor, the text is read through the zoom */
@media (hover: hover) {
  /* every card in the row grows under the cursor (--zm), playable or not */
  .hand .card:hover, .hand .card:focus-visible { transform: scale(var(--zm, 1.42)); z-index: 20; outline: none;
    box-shadow: 0 0 0 1px rgba(232,194,106,.55), 0 24px 50px rgba(0,0,0,.75); }
  .hand .card.playable:hover, .hand .card.playable:focus-visible { box-shadow: 0 0 0 2px #ffd870, 0 0 22px 5px rgba(255,190,70,.75), 0 24px 50px rgba(0,0,0,.7); }
  .hand .card.dim:hover, .hand .card.dim:focus-visible { filter: grayscale(.35) brightness(.85); }
  /* small cards (quests, cards in play, opponents' cards, the discard): the full card opens next to them (.peek) */
  .tv .card.small { cursor: zoom-in; }
  .tv .card.small.playable, .tv button.card.small.st-ready { cursor: pointer; }
  .tv .card.small:hover { z-index: 3; box-shadow: 0 0 0 2px #ffd870, 0 0 12px 2px rgba(255,190,70,.7); }
  .tv .card.small.playable:hover, .tv button.card.small.st-ready:hover { transform: none; }   /* a card that moved from under the cursor would flicker */
}
/* A card new to its place is laid there: it flies in from where it came (--dx, --dy, set by startLays in app.js), turns
   a little and settles. The keyframes have no end state, so the card lands on its own transform (hover, a fresh card's lift). */
@keyframes lay { from { opacity: 0; z-index: 30; transform: translate(var(--dx, 0px), var(--dy, -30px)) rotate(var(--rot, -8deg)) scale(var(--sc, 1.35)); } 30% { opacity: 1; } }
.card.in { animation: lay .46s cubic-bezier(.2, .9, .3, 1.12) backwards; }
.hand .card.in { --sc: .34; --rot: -12deg; }   /* dealt from a pile or by a neighbour: small at first */
.ph .hand .card.in { --dx: 90px; --dy: 0px; --sc: .9; --rot: 5deg; }   /* the phone row: cards slide in from the right unless a neighbour deals them */
@media (prefers-reduced-motion: reduce) { .card.in { animation: none; } }
.peek { position: fixed; z-index: 60; display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none; }
.peek .card { box-shadow: 0 0 0 2px #ffd870, 0 26px 60px rgba(0,0,0,.85); }
.peek > p { padding: 4px 12px; border-radius: 6px; background: rgba(24,12,6,.95); color: var(--ink); font-size: 13.5px; line-height: 1.3; white-space: nowrap; box-shadow: 0 0 0 1px rgba(232,194,106,.5); }
/* the wax seal on a quest marked to keep: see the wax seals further down */

.rail { position: absolute; left: 96px; right: 96px; bottom: 48px; height: 138px; display: flex; align-items: flex-end; gap: 30px; }
.myplate { display: flex; flex-direction: column; gap: 6px; align-self: center; min-width: 236px; }
.line { display: flex; align-items: center; gap: 12px; }
.myplate .bust { width: 54px; height: 54px; font-size: 27px; }
.myplate .who { margin: 0; flex-direction: column; align-items: flex-start; gap: 3px; }
.myplate .who b { font-size: 24px; }
.myplate .tokens { gap: 14px; margin-top: 2px; }
.myplate .tok { font-size: 21px; } .myplate .tok img { width: 30px; height: 30px; } .myplate .tok i { font-size: 13px; }
.group { display: flex; flex-direction: column; gap: 5px; }
.group h3 { font: 400 15px/1 'Kurale', serif; color: var(--gold); white-space: nowrap; text-shadow: 0 1px 2px rgba(0,0,0,.9); }
.group .cards { display: flex; gap: 8px; align-items: flex-end; min-height: 109px; }
.group .card { --cw: 78px; box-shadow: 0 4px 9px rgba(0,0,0,.6); }
.group .card.playable { box-shadow: 0 0 0 2px #ffd870, 0 0 12px 2px rgba(255,190,70,.7); }   /* a quest to complete or activate glows */
.group .cards.lap { gap: 0; }
.group .cards.lap .card + .card { margin-left: calc(var(--step) - 78px); }
.group .card .note { left: 2px; right: 2px; bottom: 3px; padding: 2px 3px; font-size: 10px; text-align: center; }
.group .empty { align-self: center; max-width: 170px; padding: 0; text-shadow: 0 1px 2px rgba(0,0,0,.85); }
.acts { margin-left: auto; align-self: center; display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }

/* What passes between players: a line of words on the table, coins or a card flying from seat to seat, a number
   rising by the purse. All of it lives in the stage, in stage pixels (app.js showFx). The line lies across the piles
   for a moment (the table has no bare strip at its smallest height; the piles tell the least), never over a seat
   or the row of cards. */
.toast { position: absolute; left: 50%; top: calc(max(240px, 50% - 184px) + 24px); z-index: 45; max-width: 900px; padding: 5px 24px 6px; border-radius: 10px; pointer-events: none; opacity: 0; white-space: nowrap;
  transform: translateX(-50%); background: linear-gradient(#f4e7c4, #dcc693); color: var(--parch-ink); font: 400 23px/1.3 'Kurale', serif; text-align: center;
  box-shadow: 0 0 0 1px rgba(90,50,10,.5), 0 10px 30px rgba(0,0,0,.7); }
.toast.on { animation: toast 2.6s ease both; }
.tv.ph .toast { top: 166px; max-width: 366px; padding: 4px 12px; font-size: 14.5px; white-space: normal; }   /* the phone column: under the seats */
/* a choice put aside: the way back to its window stands where the actions are (render), a button like the others with
   the card's name on it; it glows while the choice must be made */
.btn.must { position: relative; isolation: isolate; flex-direction: column; gap: 4px; min-height: 62px; padding: 8px 26px; }
.btn.must small { font: 700 11px/1 'Alegreya Sans', sans-serif; letter-spacing: .14em; text-transform: uppercase; opacity: .85; }
.btn.must span { font: 400 19px/1.1 'Kurale', serif; }
/* While the choice must be made the sun stands behind the button: two fans of rays turn against each other and
   fade outwards (::before); the button's own face is drawn over them (::after). --ray is the turn of the fans. */
@property --ray { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.btn.must:not(.ghost) { background: none; box-shadow: none; }
.btn.must:not(.ghost)::after { content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: linear-gradient(#ffeaa8, #e0aa3c);
  box-shadow: 0 0 0 1px #140902, inset 0 1px 0 rgba(255,255,255,.55), 0 0 16px 2px rgba(255,214,120,.6); }
.btn.must:not(.ghost)::before { content: ''; position: absolute; inset: -54px -62px; z-index: -2; pointer-events: none;
  background: repeating-conic-gradient(from var(--ray), rgba(255,246,196,.95) 0 3.5deg, rgba(255,222,124,0) 3.5deg 12deg),
    repeating-conic-gradient(from calc(var(--ray) * -1.5), rgba(255,176,64,.8) 0 7deg, rgba(255,176,64,0) 7deg 20deg);
  -webkit-mask-image: radial-gradient(ellipse closest-side, #000 56%, transparent 100%); mask-image: radial-gradient(ellipse closest-side, #000 56%, transparent 100%);
  animation: rays 18s linear infinite; }
@keyframes rays { to { --ray: 360deg; } }
@media (prefers-reduced-motion: reduce) { .btn.must::before { animation: none; } }
@keyframes toast { 0% { opacity: 0; transform: translate(-50%, -12px); } 9%, 86% { opacity: 1; transform: translate(-50%, 0); } 100% { opacity: 0; transform: translate(-50%, -6px); } }
.fx { position: absolute; z-index: 60; pointer-events: none; }
.fx.coin { width: 22px; height: 22px; margin: -11px 0 0 -11px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff3b0, #e8b93a 55%, #9a6a14);
  box-shadow: 0 0 0 1px #5a3a08, 0 0 12px rgba(255,200,80,.85); }
.fx.pop { transform: translate(-50%, -50%); font: 700 28px/1 'Cinzel', serif; text-shadow: 0 2px 4px #000, 0 0 12px rgba(0,0,0,.85); animation: fx-pop 1.5s ease-out forwards; }
.fx.pop.plus { color: #ffe08a; }
.fx.pop.minus { color: #ff8f73; }
@keyframes fx-pop { 0% { opacity: 0; transform: translate(-50%, -30%) scale(.6); } 14% { opacity: 1; transform: translate(-50%, -70%) scale(1.15); } 70% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -210%) scale(1); } }
.fx.cardfx { margin: -45px 0 0 -32px; filter: drop-shadow(0 6px 10px rgba(0,0,0,.7)); }
.fx.cardfx .card { --cw: 64px; }
.fx.cardfx .back { display: block; width: 64px; aspect-ratio: 5 / 7; border-radius: 6px; background: repeating-linear-gradient(45deg, #6a1a2a 0 5px, #4a0f1c 5px 10px); box-shadow: inset 0 0 0 2px #d9b25f, 0 0 0 1px #1a0f07; }
@media (prefers-reduced-motion: reduce) { .toast.on { animation-duration: 2.6s; } .fx.pop { animation-duration: 1.5s; } }

/* The journal: a scroll under the header, hidden until its sign in the header is pointed at or pressed; opening, it
   unrolls from its upper rod down to the lower one. Written in a chronicler's hand, newest first: every entry with
   the time and the day, its text in full, a dash between entries. On a phone it takes the whole screen. */
.log { position: absolute; top: 10px; right: 14px; bottom: 14px; width: min(430px, calc(100% - 28px)); z-index: 40; display: none; flex-direction: column; padding: 22px 22px 20px; border-radius: 2px;
  background: repeating-linear-gradient(0deg, rgba(90,50,10,.05) 0 1px, transparent 1px 26px), linear-gradient(#f4e7c4, #dcc693); color: var(--parch-ink); white-space: normal;
  box-shadow: 0 0 0 1px rgba(90,50,10,.5), 0 18px 50px rgba(0,0,0,.75), inset 0 0 40px rgba(120,70,20,.22); }
/* the rods the sheet is wound on, with a wooden knob at each end */
.log::before, .log::after, .verdict::before, .verdict::after { content: ''; position: absolute; left: -9px; right: -9px; height: 18px; border-radius: 9px; pointer-events: none;
  background: radial-gradient(circle at 8px 50%, #9a6a2c 0 6.5px, transparent 7px), radial-gradient(circle at calc(100% - 8px) 50%, #9a6a2c 0 6.5px, transparent 7px),
    linear-gradient(#fcf2d2, #dcc084 45%, #97733a);
  box-shadow: 0 0 0 1px #3d2409, 0 5px 10px rgba(0,0,0,.45); }
.log::before, .verdict::before { top: -9px; }
.log::after, .verdict::after { top: calc(100% - 9px); }
/* unrolling: the lower rod runs down and the sheet shows as far as the rod has come */
.log-open .log { display: flex; animation: unroll .62s cubic-bezier(.3,.7,.2,1) backwards; }
.log-open .log::after { animation: roll .62s cubic-bezier(.3,.7,.2,1) backwards; }
@keyframes unroll { from { clip-path: inset(-12px -14px calc(100% - 22px) -14px); } to { clip-path: inset(-12px -14px -9px -14px); } }
@keyframes roll { from { top: 4px; } }
body.ph .game.log-open { z-index: 16; }   /* over the header */
body.ph .log { position: fixed; inset: 0; width: auto; padding: 32px 18px 30px; }
body.ph .log::before { top: 0; left: 0; right: 0; }
body.ph .log::after { top: calc(100% - 18px); left: 0; right: 0; }
.log header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; padding-bottom: 8px; border-bottom: 2px double rgba(90,50,10,.45); }
.log h2 { font: 400 27px/1 'Kurale', serif; color: #4a2508; }
.log h2::first-letter { color: #9c2416; font-size: 1.25em; }
.x { flex: none; width: 44px; height: 44px; margin: -8px -10px -8px 0; border: 0; border-radius: 50%; background: transparent; color: inherit; display: grid; place-items: center; cursor: pointer; }
.x svg { width: 18px; height: 18px; }
.log ol { list-style: none; margin: 0; padding: 0 4px 0 0; overflow: hidden auto; }
.log li { padding: 10px 0 0; font: 400 16.5px/1.35 'Kurale', serif; color: #55381a; overflow-wrap: anywhere; }
.log li::after { content: '\2014\2009\2726\2009\2014'; display: block; margin-top: 9px; text-align: center; color: rgba(90,50,10,.5); font: 11px/1 serif; letter-spacing: .2em; }
.log li:last-child::after { content: none; }
.log li time { display: block; margin-bottom: 3px; color: #8a5a2c; font: 700 10.5px/1.2 'Alegreya Sans', sans-serif; letter-spacing: .1em; text-transform: uppercase; }
.log li span { display: block; }
.log li span::first-letter { color: #9c2416; font-size: 1.3em; }
.log li.mine { color: #24130a; }
/* an entry that opens a round; `.round` is also the header's round block, whose one-line layout must not reach here */
.log li.round { display: block; padding: 10px 0 0; border: 0; white-space: normal; text-align: center; font-size: 19px; color: #7a2a0c; }
@media (prefers-reduced-motion: reduce) { .log-open .log, .log-open .log::after { animation: none; } }

/* The end of the game: a scroll rolled out on the table, wound on the same rods as the journal. Under a wax seal the
   verdict, then every player's score. */
.verdict { position: relative; width: 720px; padding: 24px 30px 20px; border-radius: 2px; color: var(--parch-ink);
  background: repeating-linear-gradient(0deg, rgba(90,50,10,.05) 0 1px, transparent 1px 26px), linear-gradient(#f6ebcb, #dcc693);
  box-shadow: 0 0 0 1px rgba(90,50,10,.5), 0 22px 60px rgba(0,0,0,.8), inset 0 0 46px rgba(120,70,20,.24); }
.v-head { display: flex; align-items: center; gap: 20px; margin-bottom: 8px; padding-bottom: 10px; border-bottom: 2px double rgba(90,50,10,.45); }
.v-head h2 { margin: 0; font: 400 42px/1 'Kurale', serif; color: #8e1a10; text-shadow: 0 1px 0 rgba(255,255,255,.45); }
.verdict.lost .v-head h2 { color: #3a3f4c; }
.v-head p { margin: 6px 0 0; font: 400 18px/1.25 'Kurale', serif; color: #55381a; }
.v-head .wseal.verdict { position: relative; flex: none; width: 104px; height: 128px; margin: -14px 0 -22px; }
.verdict .results { margin: 0; font: 400 17.5px/1.2 'Kurale', serif; }
.verdict .results td, .verdict .results th { padding: 6px 10px; border-color: rgba(90,50,10,.28); }
.verdict .results th { color: #8a5a2c; font: 700 11px/1.2 'Alegreya Sans', sans-serif; letter-spacing: .1em; text-transform: uppercase; }
.verdict .results td:nth-child(n+3), .verdict .results th:nth-child(n+3) { text-align: right; font-variant-numeric: tabular-nums; }
.verdict .results td.pl { width: 30px; color: #8a5a2c; font: 900 14px/1 'Cinzel', serif; }
.verdict .results tr.win td { color: #8e1a10; font-weight: 400; text-shadow: 0 0 .5px currentColor; }
.verdict .results tr:last-child td { border-bottom: 0; }
/* just ended: the scroll unrolls (like the journal), the seal comes down on it, the lines follow one by one */
.verdict.fresh { animation: unroll .8s cubic-bezier(.3,.7,.2,1) backwards; }
.verdict.fresh::after { animation: roll .8s cubic-bezier(.3,.7,.2,1) backwards; }
.verdict.fresh .v-head > div { animation: fade-in .5s .5s backwards; }
.verdict.fresh .wseal.press .wax, .verdict.fresh .wseal.press .wax-press { animation-delay: .85s; }
.verdict.fresh .wseal .ribbons { animation: fade-in .3s 1.1s backwards; }
.verdict.fresh .results tr { animation: fade-in .4s calc(1.15s + var(--i, 0) * .14s) backwards; }
@media (prefers-reduced-motion: reduce) { .verdict.fresh, .verdict.fresh::after, .verdict.fresh * { animation: none; } }

/* ------------------------------------------------------------------ the table on a phone
   One column as wide as the screen: opponents in an arc, the round, what to do now, a row of big cards to swipe, then
   your tokens and buttons.
   A tap selects or opens a card; game actions are separate buttons. */
.tv.ph { left: 0; width: 390px; height: 708px; display: flex; flex-direction: column; }   /* fit() makes it as wide as the screen: 390 or more */
.ph .table { inset: 6px -60px -60px; border-radius: 240px 240px 0 0 / 120px 120px 0 0; }
.ph .table::before { inset: 20px; border-radius: 222px 222px 0 0 / 102px 102px 0 0; }
.ph .tvbody { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
.arc { position: relative; flex: none; height: 126px; z-index: 5; }
.pseat { position: absolute; width: 96px; margin-left: -48px; padding: 0; border: 0; background: none; color: inherit; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 3px; text-align: center; }
.pseat .bust { width: 46px; height: 46px; font-size: 23px; }
.pseat .bust .coin { position: absolute; right: -6px; bottom: -4px; margin: 0; }
.pseat > b { max-width: 100%; margin: -3px 0; padding: 3px 0; overflow: hidden; text-overflow: ellipsis; font: 400 15px/1 'Kurale', serif; color: var(--gold); text-shadow: 0 1px 3px #000; white-space: nowrap; }
.pseat > small { font-size: 11.5px; line-height: 1.1; color: var(--muted); white-space: nowrap; text-shadow: 0 1px 2px rgba(0,0,0,.9); }
.pseat .flag { height: 20px; padding: 0 8px; font-size: 11.5px; }
.pseat.is-active .bust { box-shadow: 0 0 0 2px #1a0f07, 0 0 0 4px #ffe08a, 0 0 0 5px #1a0f07, 0 0 20px 8px rgba(255,195,80,.7); }
.pmid { position: relative; flex: none; height: 44px; padding: 0 14px; display: flex; align-items: center; justify-content: center; gap: 12px; z-index: 5; }
.pmid > div:last-child { min-width: 0; }
.pmid h2 { font: 400 18px/1.1 'Kurale', serif; color: var(--gold); white-space: nowrap; text-shadow: 0 1px 3px #000; }
.pmid p { font-size: 12.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 1px 2px rgba(0,0,0,.9); }
.prompt { position: relative; flex: none; margin: 4px 14px 0; z-index: 6; text-align: center; font: 400 18px/1.15 'Kurale', serif; color: #fff3d2; text-shadow: 0 2px 4px rgba(0,0,0,.85); }
.ph .hand { position: relative; bottom: auto; flex: 1; min-height: 0; container-type: size; justify-content: flex-start; align-items: center; padding: 0 calc(50% - 107px);
  overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; scrollbar-width: none; z-index: 6; }
.ph .hand::-webkit-scrollbar { display: none; }
.ph .hand .card { --cw: min(214px, calc((100cqh - 24px) / 1.4)); scroll-snap-align: center; }
.ph .hand .card:hover, .ph .hand .card:focus-visible { transform: none; }
.ph .hand:has(.verdict) { padding: 12px 12px; }
.ph .verdict { width: 100%; padding: 22px 10px 16px; }
.ph .verdict::before, .ph .verdict::after { left: -5px; right: -5px; }
.ph .v-head { gap: 12px; }
.ph .v-head h2 { font-size: 30px; }
.ph .v-head p { font-size: 14px; }
.ph .v-head .wseal.verdict { width: 74px; height: 92px; margin: -8px 0 -14px; }
.ph .verdict .results { font-size: 13.5px; }
.ph .verdict .results td, .ph .verdict .results th { padding: 5px 4px; }
.ph .verdict .results th { font-size: 8.5px; letter-spacing: .04em; }

/* under the row: deck and discard counts at the sides, a dot per card in the middle */
.dots { position: relative; flex: none; height: 14px; padding: 0 14px; display: flex; align-items: center; gap: 7px; z-index: 6; }
.dots small { flex: 1; font-size: 11.5px; line-height: 1; color: var(--muted); white-space: nowrap; text-shadow: 0 1px 2px rgba(0,0,0,.9); }
.dots small:last-child { text-align: right; }
.dots span { display: flex; gap: 7px; }
.dots i { width: 7px; height: 7px; border-radius: 50%; background: rgba(243,231,201,.35); }
.dots i.on { background: var(--gold); }
.pme { position: relative; flex: none; z-index: 7; padding: 8px 14px 10px; display: flex; flex-direction: column; gap: 8px; background: linear-gradient(rgba(10,6,3,0), rgba(10,6,3,.82) 22%); }
.pme .line { justify-content: space-between; gap: 8px; min-height: 26px; }
.pme .line:has(.tabs:empty):has(.mini:empty) { display: none; }   /* nothing to show yet (quests are being chosen): no empty row */
.pme .tokens { margin: 0; gap: 12px; }
.pme .line > small { margin-left: auto; font-size: 11.5px; color: var(--muted); }
.pme .tok { font-size: 18px; } .pme .tok img { width: 26px; height: 26px; }
.tabs { display: flex; gap: 6px; }
.pick { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 12px; border: 0; border-radius: 6px; background: rgba(18,10,5,.88); color: var(--ink);
  font: 500 14px/1 'Alegreya Sans', sans-serif; white-space: nowrap; box-shadow: 0 0 0 1px var(--gold-dark); cursor: pointer; }
.pick.on { background: linear-gradient(#ffeaa8, #e0aa3c); color: #2a1404; font-weight: 700; }
.mini { display: flex; align-items: flex-end; height: 62px; min-width: 0; }
.mini .card { --cw: 44px; }
.mini .card + .card { margin-left: calc(var(--step, 50px) - 44px); }
.mini .newtag { display: none; }   /* too small for a word: a card played this round gets a gold edge */
.mini .card:has(.newtag) { box-shadow: 0 0 0 1.5px #ffd870; z-index: 1; }
.pme .acts { margin: 0; flex-direction: row; align-items: stretch; align-self: stretch; }
.pme .acts .btn { flex: 1; min-height: 50px; padding: 0 12px; font-size: 16px; }
.pme .acts .btn.ghost { flex: 0 0 auto; }
/* a sheet over the cards: your quests with their full text and action buttons, or one player's side of the table */
.sheet { position: absolute; left: 8px; right: 8px; top: 132px; bottom: 70px; z-index: 8; display: flex; flex-direction: column; gap: 10px; padding: 12px 14px 14px; border-radius: 14px 14px 10px 10px;
  background: linear-gradient(rgba(44,22,11,.98), rgba(26,12,6,.98)); box-shadow: 0 0 0 1px rgba(232,194,106,.55), 0 -10px 40px rgba(0,0,0,.7); }
.sheet header { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.sheet h3 { font: 400 20px/1.1 'Kurale', serif; color: var(--gold); }
.sheet header p { margin-top: 3px; font-size: 12.5px; line-height: 1.25; color: var(--muted); }
.sheet .x { margin: -8px -8px 0 0; }
.sheet .body { min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; }
.sheet .cards { display: flex; flex-wrap: wrap; gap: 8px; }
.sheet .cards .card { --cw: 78px; }
.qrow { display: flex; gap: 12px; align-items: flex-start; padding-top: 10px; border-top: 1px solid rgba(232,194,106,.22); }
.qrow .card { --cw: 88px; }
.qtxt { min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 5px; }
.qtxt > b { font: 15px/1.1 'Uncial Antiqua', serif; color: var(--gold); }
.qreq { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.qreq .req { display: inline-flex; align-items: center; gap: 2px; font: 700 13px/1 'Cinzel', serif; color: #fff3d2; }
.qtxt .gl { width: 18px; height: 20px; vertical-align: -5px; }
.qtxt p { font-size: 13.5px; line-height: 1.3; color: var(--ink); }

/* modal */
.modal { position: fixed; inset: 0; z-index: 20; background: rgba(5,7,10,.72); display: flex; align-items: center; justify-content: center; padding: 16px; }
.modal-box { background: var(--panel); border: 1px solid var(--gold-dark); border-radius: 14px; padding: 16px; max-width: 760px; width: 100%; max-height: 90vh; overflow: auto; }
.modal-box h2 { color: var(--gold); font-size: 20px; margin-bottom: 6px; }
.modal-box .src { color: var(--muted); margin: 0 0 10px; font-size: 14px; }
.modal-box .src b { color: var(--ink); font-weight: 700; }
/* the top of a choice window: whose effect it is, whether it can be declined, and the way out to the table */
.ask-top { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.ask-top .btn { margin-left: auto; min-height: 36px; padding: 0 12px; font-size: 14px; }
.ask-top .btn svg { width: 17px; height: 17px; }
.chip { display: inline-flex; align-items: center; gap: 7px; min-height: 30px; padding: 3px 12px; border-radius: 16px; font: 700 13.5px/1.1 'Alegreya Sans', sans-serif; }
.chip.mine { background: linear-gradient(#ffeaa8, #e0aa3c); color: #2a1404; }
.chip.theirs { padding-left: 4px; background: #5e1512; color: #ffe1d6; box-shadow: inset 0 0 0 1px #c9543f; }
.chip.plain { background: rgba(0,0,0,.35); color: var(--muted); font-weight: 500; }
.chip .bust { width: 24px; height: 24px; font-size: 13px; box-shadow: 0 0 0 1px #1a0f07, 0 0 0 2px var(--gold); }
.modal-box .btn { white-space: normal; padding-block: 8px; }
.rules h3 { margin: 12px 0 4px; font-size: 17px; }
.rules p, .rules ul { margin: 4px 0; }
.rules ul { padding-left: 20px; }
.rules li { margin: 3px 0; }
.modal-box > .big { width: 100%; max-width: 330px; margin: 0 auto; }   /* the card in the card window */
.modal-box > .big .card { width: 100%; }
.modal-box .en { color: var(--muted); font-size: 13px; font-style: italic; }

.error { position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 30; background: #3a1010; border: 1px solid var(--bad); color: #fff; border-radius: 10px; padding: 12px 14px; }

.results { width: 100%; border-collapse: collapse; margin: 8px 0 12px; }
.results td, .results th { padding: 6px 8px; border-bottom: 1px solid var(--line); text-align: left; }
.results tr.win td { color: var(--gold); font-weight: 700; }
.scroll { overflow-x: auto; }
.results.about td, .results.about th { text-align: right; white-space: nowrap; }
.results.about th { white-space: normal; vertical-align: bottom; }
.results.about td:first-child, .results.about th:first-child { text-align: left; white-space: normal; }
.results.about small { display: block; color: var(--muted); font-size: 12px; }
.about-levels { margin: 6px 0; padding-left: 20px; }
.about-levels li { margin: 3px 0; }

/* simulation */
#simSeed { width: 9em; min-width: 0; }
.sim-out { min-width: 0; }   /* a grid item: let the table scroll inside it, not widen the setup */
.sim-out:empty { display: none; }
.sim-out .progress { font-size: 17px; font-variant-numeric: tabular-nums; }
.sim-out .partial { color: var(--gold); font-weight: 700; margin: 0 0 4px; }
.results.sim td { white-space: nowrap; }
.results.sim td:first-child { white-space: normal; }
.results.sim th { vertical-align: bottom; font-weight: 500; color: var(--muted); }
.results.sim td:not(:first-child), .results.sim th:not(:first-child) { text-align: right; }
.results.sim td.above { color: var(--ok); }
.simgame { max-width: 1100px; margin: 0 auto; padding: 16px; display: grid; gap: 12px; }
.simgame h2 { color: var(--gold); font-size: 22px; }
.simgame .seats { display: grid; gap: 10px; }
.simgame .opp h3 { margin: 10px 0 4px; }
.simgame .opp.win { border-color: var(--gold); }

@media (max-width: 900px) {
  .status { font-size: 12px; }
  /* card rows outside the table: the choice window and the simulation's table */
  .row .card { width: calc(50% - 5px); min-width: 140px; max-width: 200px; }
  .row .card.small { width: 112px; min-width: 0; }
  .row.cards { gap: 8px; }
}
@media (max-width: 420px) {
  .results.sim td, .results.sim th { padding: 6px 4px; }
}

/* class glyph runs in ability text never break over two lines (the dash after them is joined by a no-break space) */
.card .gls { white-space: nowrap; }
/* set aside for the next round (Time Bender): a blue tag on the card in hand */
.card .newtag.later { background: linear-gradient(180deg, #4C8FE6, #1B4F9C); }
/* the completed-quest stamp: dark under the red ink, so the word reads over any art */
.card .stamp { background: rgba(20,2,6,.85); color: #FF5A6A; }

/* the draw for the first player: a light that runs round the seats and stays on the winner */
.fx.drawlight { width: 92px; height: 92px; margin: -46px 0 0 -46px; border-radius: 50%; box-shadow: 0 0 0 3px #ffe08a, 0 0 26px 12px rgba(255,200,90,.75);
  transition: left .1s ease-out, top .1s ease-out; }
.fx.drawlight.won { animation: draw-won 1.6s ease-out forwards; }
@keyframes draw-won { 0% { transform: scale(1); } 25% { transform: scale(1.4); box-shadow: 0 0 0 4px #fff3c0, 0 0 46px 20px rgba(255,210,100,.95); } 100% { transform: scale(1.1); opacity: 0; } }
.drawfx { position: absolute; left: 50%; top: 38%; transform: translate(-50%, -50%); z-index: 61; padding: 14px 28px; border-radius: 12px; text-align: center; cursor: pointer;
  background: rgba(20,10,4,.93); box-shadow: 0 0 0 1px var(--gold-dark), 0 18px 40px rgba(0,0,0,.65); }
.drawfx b { display: block; font: 400 28px/1.15 'Uncial Antiqua', serif; color: var(--gold); white-space: nowrap; }
.drawfx small { display: block; margin-top: 5px; font: 500 14px/1.2 'Alegreya Sans', sans-serif; color: var(--muted); }
/* a card passing between players: bigger, its way as an arc with an arrow, a ring where it lands */
.fx.cardfx.big { margin: -63px 0 0 -45px; }
.fx.cardfx.big .card { --cw: 90px; }
.fx.cardfx.big .back { width: 90px; }
.fx.trail { left: 0; top: 0; z-index: 59; overflow: visible; }
.fx.trail path { fill: none; stroke: #ffd870; stroke-width: 3.5; stroke-linecap: round; filter: drop-shadow(0 0 5px rgba(255,200,90,.85)); }
.fx.ring { width: 74px; height: 74px; margin: -37px 0 0 -37px; border-radius: 50%; box-shadow: 0 0 0 3px #ffd870, 0 0 22px 8px rgba(255,200,90,.75);
  opacity: 0; animation: fx-ring .9s ease-out forwards; }
@keyframes fx-ring { 0% { transform: scale(.55); opacity: 1; } 100% { transform: scale(1.6); opacity: 0; } }
/* a pile of played cards: the last one on top, the others as edges under it, how many; a click opens them all */
.cstack { position: relative; flex: none; }
.cstack .card { box-shadow: 3px 3px 0 -1px #2a1a0c, 4px 4px 0 0 rgba(217,178,95,.5), 7px 7px 0 -1px #2a1a0c, 8px 8px 0 0 rgba(217,178,95,.35), 0 6px 12px rgba(0,0,0,.6); }
.cstack .cnt { position: absolute; right: -9px; top: -9px; z-index: 3; min-width: 24px; height: 24px; padding: 0 6px; border-radius: 12px; display: grid; place-items: center;
  background: linear-gradient(180deg, #ffe08a, #c8913a); color: #1a0f07; font: 700 13px/1 'Cinzel', serif; box-shadow: 0 0 0 1.5px #1a0f07, 0 2px 4px rgba(0,0,0,.6); pointer-events: none; }
.tab .cstack { margin-right: 14px; }
.tab .cstack + .card { margin-left: 0; }
.spot > .cstack { margin-left: 10px; }
.group .cards .cstack { margin-right: 14px; }
.group .cards.lap .cstack + .card { margin-left: 0; }
/* the list window: the discard, a player's cards in play by round, completed quests */
.clist { display: flex; flex-direction: column; gap: 16px; max-height: 64vh; overflow: auto; padding: 6px 4px 10px; }
.clist h3 { margin: 0 0 8px; font: 400 16px/1.2 'Kurale', serif; color: var(--gold); }
.clist h3 b { margin-left: 4px; color: var(--muted); font: 600 14px/1 'Alegreya Sans', sans-serif; }
.clist .cards { display: flex; flex-wrap: wrap; gap: 10px; }
.clist .card { --cw: 96px; box-shadow: 0 4px 10px rgba(0,0,0,.55); }
.clist .hint { margin: 8px 0 0; }
.mid .stack.discard { cursor: pointer; }
.mid .stack.discard:hover small { color: var(--gold); }
.dots small.link { cursor: pointer; text-decoration: underline dotted; }

/* Wax seals (waxSeal in app.js): a quest marked to keep, a completed quest, the verdict at the end. The wax keeps its
   own shadow; when a seal first appears it is pressed in: it comes down from above, squashes a little and settles,
   and the pressed disk with its mark forms under it. */
.wax { display: block; width: 100%; height: 100%; overflow: visible; transform: rotate(var(--tilt, 0deg));
  filter: drop-shadow(0 1.5px 1px rgba(0,0,0,.55)) drop-shadow(0 5px 7px rgba(0,0,0,.35)); }
.wseal { position: absolute; z-index: 3; pointer-events: none; }
.card .wseal.done { left: calc(var(--u) * 84); top: calc(var(--u) * 108); width: calc(var(--u) * 94); aspect-ratio: 1; }
.wseal.verdict .wax { position: absolute; left: 0; top: 0; width: 104px; height: 104px; }
.wseal.verdict .ribbons { position: absolute; left: 6px; top: 6px; width: 92px; height: 117px; filter: drop-shadow(0 3px 3px rgba(0,0,0,.35)); }
.ph .wseal.verdict .wax { width: 74px; height: 74px; }
.ph .wseal.verdict .ribbons { left: 4px; top: 4px; width: 66px; height: 84px; }
.wseal.press .wax { animation: wax-press .78s cubic-bezier(.22,.85,.25,1) backwards; }
.wseal.press .wax-press { transform-box: fill-box; transform-origin: center; animation: wax-stamp .78s ease-out backwards; }
@keyframes wax-press {
  0% { opacity: 0; transform: translateY(-34%) scale(1.75) rotate(calc(var(--tilt, 0deg) - 20deg)); filter: drop-shadow(0 34px 24px rgba(0,0,0,.18)); }
  44% { opacity: 1; transform: translateY(0) scale(.88) rotate(var(--tilt, 0deg)); filter: drop-shadow(0 1px 1px rgba(0,0,0,.65)); }
  64% { transform: scale(1.06) rotate(var(--tilt, 0deg)); }
  100% { transform: scale(1) rotate(var(--tilt, 0deg)); }
}
@keyframes wax-stamp { 0%, 42% { opacity: 0; transform: scale(1.2); } 70% { opacity: 1; transform: scale(.96); } 100% { transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { .wseal.press .wax, .wseal.press .wax-press { animation: none; } }

/* Buttons answer the pointer: they rise a little and brighten under it, sink when pressed, show a ring for the
   keyboard. The menu opens like a sheet unfolding. */
.btn, .burger, .ticker, .pick, .pseat, .x, .mi, .mi > svg, .sw i, .sw i::after {
  transition: transform .16s cubic-bezier(.3,.7,.4,1), filter .16s ease, box-shadow .2s ease, background-color .2s ease, color .2s ease; }
.btn:not(:disabled):hover { transform: translateY(-2px); filter: brightness(1.1) drop-shadow(0 4px 9px rgba(255,190,80,.28)); }
.btn:not(:disabled):active { transform: translateY(1px) scale(.97); filter: brightness(.93); transition-duration: .06s; }
.btn.ghost:not(:disabled):hover { box-shadow: 0 0 0 1px var(--gold), 0 0 16px rgba(232,194,106,.35), 0 3px 8px rgba(0,0,0,.4); }
.lang .btn:not(.on):not(:disabled):hover { color: var(--ink); background: rgba(232,194,106,.16); }
.burger:hover, .ticker:hover { filter: brightness(1.15) drop-shadow(0 0 8px rgba(232,194,106,.35)); }
.burger:hover { transform: translateY(-1px); }
.burger:active, .ticker:active { transform: scale(.94); transition-duration: .06s; }
.menu-open .burger { box-shadow: 0 0 0 1px var(--gold), 0 0 14px rgba(232,194,106,.4); }
button.mi:hover > svg { transform: translateX(2px) scale(1.1); }
button.mi:active { background: rgba(232,194,106,.26); transform: scale(.985); transition-duration: .06s; }
.pick:not(:disabled):hover, .pseat:hover { filter: brightness(1.12); }
.pick:active, .pseat:active, .x:active { transform: scale(.95); }
.x:hover { transform: rotate(90deg); }
:is(.btn, .mi, .burger, .ticker, .pick, .pseat, .x):focus-visible { outline: 2px solid #ffe08a; outline-offset: 2px; }
/* the menu: its own layer (over the table's blurred card tops it was drawn in pieces, with a seam), unfolding */
.menu { will-change: transform; transform: translateZ(0); transform-origin: calc(100% - 22px) -6px; }
.menu-open .menu { animation: menu-in .2s cubic-bezier(.2,.8,.3,1); }
@keyframes menu-in { from { opacity: 0; transform: translateZ(0) translateY(-6px) scale(.96); } }
@media (prefers-reduced-motion: reduce) { .btn, .burger, .ticker, .pick, .pseat, .x, .mi, .mi > svg { transition: none; } .btn:not(:disabled):hover, .burger:hover { transform: none; } .menu-open .menu { animation: none; } }

/* A chosen card (a quest marked to keep, a card picked on a touch screen): a green edge that glows and breathes, and a
   check on its side that pops in when the card is chosen. Stronger than the gold of a card that can be played. */
.card.is-kept, .card.is-picked, .hand .card.is-kept, .hand .card.is-picked,
.hand .card.is-kept:hover, .hand .card.is-picked:hover, .hand .card.is-kept:focus-visible, .hand .card.is-picked:focus-visible {
  box-shadow: 0 0 0 3px #4be283, 0 0 0 5px rgba(8,36,18,.9), 0 0 22px 6px rgba(75,226,131,.7), 0 0 48px 14px rgba(75,226,131,.26), 0 18px 30px rgba(0,0,0,.6);
  animation: chosen-glow 2.4s ease-in-out infinite; }
@keyframes chosen-glow { 50% { box-shadow: 0 0 0 3px #7dffae, 0 0 0 5px rgba(8,36,18,.9), 0 0 30px 9px rgba(75,226,131,.85), 0 0 62px 18px rgba(75,226,131,.34), 0 18px 30px rgba(0,0,0,.6); } }
.card .chosen { position: absolute; z-index: 6; right: calc(var(--u) * -16); top: calc(var(--u) * 92); width: calc(var(--u) * 46); aspect-ratio: 1; border-radius: 50%;
  display: grid; place-items: center; color: #fff; pointer-events: none;
  background: radial-gradient(circle at 34% 28%, #a8ffc6, #2cc566 50%, #0c6a33);
  box-shadow: 0 0 0 calc(var(--u) * 2.4) #0b2a15, 0 0 0 calc(var(--u) * 4) #4be283, 0 0 16px 5px rgba(75,226,131,.75), 0 4px 9px rgba(0,0,0,.55), inset 0 2px 3px rgba(255,255,255,.45); }
.card .chosen svg { width: 60%; height: 60%; stroke-width: 3.6; filter: drop-shadow(0 1px 1px rgba(0,0,0,.5)); }
.card .chosen.pop { animation: chosen-pop .46s cubic-bezier(.2,1.7,.4,1) backwards; }
@keyframes chosen-pop { from { opacity: 0; transform: scale(0) rotate(-45deg); } }
@media (prefers-reduced-motion: reduce) { .card.is-kept, .card.is-picked { animation: none; } .card .chosen.pop { animation: none; } }

/* An opponent's seat (seatEl): the head at the outer side, the status above the avatar, the name under it, the quests
   (compasses: completed ones bright with a check, the others dim) and the cards in hand by its side; what the
   player has (tokens, classes, cards in play) towards the middle. The avatar and the quests open on a click. */
.head { flex: none; width: 122px; display: flex; flex-direction: column; align-items: center; gap: 5px; }
.head .flags { justify-content: center; flex-wrap: wrap; row-gap: 4px; }
.ava { position: relative; display: flex; align-items: center; gap: 7px; }
.seat.at-r .ava { flex-direction: row-reverse; }   /* the quests on the side towards the middle */
.ava-btn { display: block; padding: 0; border: 0; border-radius: 50%; background: none; cursor: pointer; }
.ava-btn:hover .bust { filter: brightness(1.14); }
.ava-btn:active .bust { transform: scale(.95); }
.ava-btn .bust .coin { position: absolute; right: -6px; top: -4px; margin: 0; }
.head .who { flex-direction: column; align-items: center; gap: 2px; margin-top: 0; text-align: center; }
.head .who b { font-size: 19px; }
.head .who small { font-size: 12px; }
.side { display: flex; flex-direction: column; align-items: center; gap: 5px; }
.qtok { display: grid; grid-auto-flow: column; grid-template-rows: repeat(3, 20px); gap: 3px; padding: 4px; border: 0; border-radius: 8px; cursor: pointer;
  background: rgba(18,10,5,.62); box-shadow: 0 0 0 1px rgba(232,194,106,.38); }
.qtok:hover { box-shadow: 0 0 0 1px var(--gold), 0 0 10px rgba(232,194,106,.4); }
.qtok .q { position: relative; display: block; width: 20px; height: 20px; background: url(img/icons/type-quest-compass-small.svg) center / 112% no-repeat;
  filter: grayscale(1) brightness(.55); opacity: .65; }
.qtok .q.on { filter: none; opacity: 1; }
.qtok .q.on::after { content: ''; position: absolute; right: -3px; bottom: -3px; width: 11px; height: 11px; border-radius: 50%; box-shadow: 0 0 0 1.5px #0b2a15;
  background: #2cc566 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12l5 5 9-10' fill='none' stroke='white' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 72% no-repeat; }
.hb { display: inline-flex; align-items: center; gap: 4px; font: 700 13px/1 'Cinzel', serif; color: #fff3d2; text-shadow: 0 1px 2px #000; }
.hb .cb { width: 14px; height: 20px; border-radius: 2px; border-width: 1px; }
.info { flex: 1; min-width: 0; display: flex; flex-direction: column; padding-top: 22px; }   /* level with the avatar, under the status */
.seat.at-r .info { align-items: flex-end; }
.info .tokens { margin-top: 0; flex-wrap: wrap; gap: 4px 8px; }
.info .classes { flex-wrap: wrap; gap: 3px 5px; }
.seat.at-r .info .tokens, .seat.at-r .info .classes { justify-content: flex-end; }
/* a seat's numbers a little tighter, so that the tokens and six classes fit the narrow top seats in one row each */
.seat .tok { gap: 3px; font-size: 15.5px; }
.seat .tok img { width: 21px; height: 21px; }
.seat .tok i { font-size: 12px; }
.seat .cc { font-size: 13px; }
.seat .cc .gl { width: 16px; height: 18px; }

/* The state of the player's own effect this round (effectOf in app.js), on its card in play or its quest: blue — not
   used yet and it can be used (on the player's turn the card is a button); red — it cannot work yet (classes short, or
   nothing to use it on); a quiet check — it has worked. The glow breathes slowly and faintly, still with reduced motion.
   It is drawn by the card's .bd overlay, so the card keeps its own shadow and its laying animation. */
.card.st-ready { --st: #9ad4ff; --st-glow: rgba(64,156,255,.55); }
.card.st-block { --st: #ff9282; --st-glow: rgba(235,64,44,.5); }
.card.st-ready > .bd, .card.st-block > .bd { box-shadow: inset 0 0 0 1px rgba(0,0,0,.6), 0 0 0 1.5px var(--st), 0 0 8px 1px var(--st-glow);
  animation: st-glow 4s ease-in-out infinite; }
.card.st-block > .bd { animation-duration: 5.2s; }
@keyframes st-glow { 50% { box-shadow: inset 0 0 0 1px rgba(0,0,0,.6), 0 0 0 2px var(--st), 0 0 15px 3px var(--st-glow); } }
button.card.st-ready { cursor: pointer; }
.card.st-ready .note { background: linear-gradient(180deg, #6CB8FF, #1F5EB6); color: #fff; box-shadow: 0 0 0 1px #071d3d; text-shadow: 0 1px 1px rgba(0,0,0,.4); }
.card.st-block .note { background: linear-gradient(180deg, #D04A36, #7C170D); color: #fff; box-shadow: 0 0 0 1px #2b0603; text-shadow: 0 1px 1px rgba(0,0,0,.4); }
.card.st-block .note b { font-weight: 800; }
.card.st-block .note .gl { width: 1.25em; height: 1.4em; margin: 0 1px 0 0; }
.card.st-done .note, .group .card.st-done .note { left: auto; max-width: calc(100% - var(--u) * 46); background: rgba(8,6,4,.8); color: #bfe6cb;
  box-shadow: 0 0 0 1px rgba(75,226,131,.35); }   /* small, at the right: the stat medals stay seen */
.card.st-done .note::before { content: '\2713\00a0'; color: #4be283; font-weight: 800; }
@media (prefers-reduced-motion: reduce) { .card.st-ready > .bd, .card.st-block > .bd { animation: none; } }
.mini .note { display: none; }   /* too small for a word: the edge tells it, the sheets and the zoomed card say it */
.peek > p { white-space: normal; max-width: var(--cw); text-align: center; }   /* a long caption wraps under the card */
.flag.st-ready { background: linear-gradient(180deg, #6CB8FF, #1F5EB6); color: #fff; box-shadow: 0 0 0 1px #071d3d; }   /* the phone's quest rows */
.flag.st-block { background: linear-gradient(180deg, #D04A36, #7C170D); color: #fff; box-shadow: 0 0 0 1px #2b0603; }
