/* Mobile first. The nine-card fan on a 375px viewport is the constraint the rest of the
   layout works around (PLAN.md §5.1), so it is sized first and everything else fits. */

:root {
  --felt: #1d5b45;
  --felt-dark: #16442f;
  --ink: #14201c;
  --paper: #fbfaf7;
  --line: rgba(0, 0, 0, .18);
  --red: #b6212c;
  --black: #1b1b1b;
  --gold: #d8b45a;
  --card-w: 62px;
  --card-h: 92px;
  --overlap: -30px;      /* how far each card tucks under the previous one */
  --lift: -18px;
}

* { box-sizing: border-box; }

/* The `hidden` attribute is only `display: none` in the UA stylesheet, at the same
   specificity as any class rule — so a later `.thing { display: grid }` silently beats it
   and the element stays on screen with `hidden` set. That happened here: the round
   scorecard sat over the table for a whole round while its attribute said hidden.
   Make the attribute win, once, for everything. */
[hidden] { display: none !important; }

body {
  margin: 0;
  min-height: 100dvh;
  font: 15px/1.4 ui-rounded, "SF Pro Rounded", system-ui, -apple-system, sans-serif;
  color: var(--paper);
  background: radial-gradient(120% 90% at 50% 0%, var(--felt) 0%, var(--felt-dark) 100%);
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
}

.table {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto auto;
  min-height: 100dvh;
  max-width: 720px;
  margin: 0 auto;
  padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);
}

/* ---------- scoreboard ---------- */

.scoreboard {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  /* The hamburger floats over this row, so the side padding clears it — symmetrically, to
     keep the contract badge on the centre line. "Us" was already tucked under the icon in
     English; "Nous" made it obvious. */
  padding: 10px 46px;
  background: rgba(0, 0, 0, .22);
}
.score { display: flex; flex-direction: column; align-items: center; min-width: 58px; }
.score .label { font-size: 11px; letter-spacing: .09em; text-transform: uppercase; opacity: .65; }
.score .value { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; }
.score.us .value { color: var(--gold); }
.meta { text-align: center; }
.contract {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 11px; border-radius: 999px;
  background: rgba(216, 180, 90, .18);
  border: 1px solid rgba(216, 180, 90, .35);
  font-size: 14px; font-weight: 700;
}
.contract .pip { font-size: 17px; line-height: 1; }
.contract .pip.red { color: #ff8a90; }
.contract .mult { font-size: 11px; font-weight: 600; opacity: .7; }
.contract.none { background: transparent; border-color: transparent; opacity: .5; font-weight: 500; }
.round { font-size: 11px; opacity: .6; }


/* ---------- felt ---------- */

.felt {
  position: relative;
  display: grid; place-items: center;
  padding: 8px;
  /* Cap the felt so the fan is never pushed off a short viewport, and so the trick does
     not float in an ocean of green on a tall one. */
  min-height: 260px;
}

.seat-marker {
  position: absolute;
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; opacity: .7;
  padding: 4px 9px; border-radius: 999px;
  background: rgba(0, 0, 0, .2);
  transition: opacity .2s, background .2s;
}
.seat-marker.north { top: 6px; left: 50%; transform: translateX(-50%); }
.seat-marker.west  { left: 6px; top: 50%; transform: translateY(-50%); }
.seat-marker.east  { right: 6px; top: 50%; transform: translateY(-50%); }
.seat-marker .turn { width: 7px; height: 7px; border-radius: 50%; background: transparent; }
.seat-marker.active { opacity: 1; background: rgba(216, 180, 90, .22); }
.seat-marker.active .turn { background: var(--gold); animation: pulse 1.1s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }

/* Cards on the table, positioned by who played them relative to the viewer.
   Swiss Jass is ALWAYS anticlockwise, so the next seat to play sits to your RIGHT:
   you (bottom) -> right -> top -> left. Putting rel 1 on the left instead runs the
   table clockwise, which is what this originally did. */
.trick { position: relative; width: 190px; height: 190px; }
.trick .card { position: absolute; margin: 0; }
.trick .card[data-rel="0"] { left: 50%; bottom: 0;   transform: translateX(-50%) rotate(2deg); }   /* you */
.trick .card[data-rel="1"] { right: 0;  top: 50%;    transform: translateY(-50%) rotate(6deg); }   /* right */
.trick .card[data-rel="2"] { left: 50%; top: 0;      transform: translateX(-50%) rotate(-2deg); }  /* partner */
.trick .card[data-rel="3"] { left: 0;   top: 50%;    transform: translateY(-50%) rotate(-6deg); }  /* left */

.trick.complete { cursor: pointer; }
.trick .card.winner { box-shadow: 0 0 0 2px var(--gold), 0 6px 16px rgba(0,0,0,.45); }
/* The card currently taking the trick, while the trick is still being played. Deliberately
   quieter than `.winner`: one is a running total, the other is the result. */
.trick .card.leading { box-shadow: 0 0 0 2px rgba(216, 180, 90, .45), 0 4px 12px rgba(0,0,0,.4); }

.trick-take {
  /* Anchored to the trick, not to the felt: it is a caption on those four cards, and at the
     bottom of a tall felt it reads as a caption on the hand instead. */
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, 104px);
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 2px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 700; letter-spacing: .04em;
  background: rgba(0, 0, 0, .3);
  font-variant-numeric: tabular-nums;
}
.trick-take .side { text-transform: uppercase; font-size: 11px; }
.trick-take.us { color: var(--gold); }
.trick-take.them { color: #ff8a90; }


.banner {
  position: absolute; inset: auto 12px 12px;
  padding: 10px 14px; border-radius: 12px;
  background: rgba(0, 0, 0, .55);
  text-align: center; font-weight: 600;
  backdrop-filter: blur(4px);
}

/* ---------- cards ---------- */

.card {
  width: var(--card-w); height: var(--card-h);
  border-radius: 7px;
  background: var(--paper);
  color: var(--black);
  border: 1px solid var(--line);
  box-shadow: 0 2px 5px rgba(0, 0, 0, .3);
  display: grid; place-items: center;
  font-weight: 700;
  user-select: none;
  will-change: transform;
}
.card .rank { font-size: 21px; line-height: 1; }
.card .pip  { font-size: 15px; line-height: 1; }
.card.red { color: var(--red); }
.card .inner { display: grid; place-items: center; gap: 1px; }

/* ---------- the fan ---------- */

.handwrap { padding: 4px 0 14px; overflow: visible; }
.hand {
  display: flex; justify-content: center; align-items: flex-end;
  min-height: calc(var(--card-h) + 24px);
  padding-inline: 18px;
}
.hand .card {
  margin-left: var(--overlap);
  transition: transform .18s cubic-bezier(.2, .8, .3, 1), filter .18s, opacity .18s;
  cursor: pointer;
  transform-origin: 50% 130%;   /* rotate about a point below the card, so it fans */
}
.hand .card:first-child { margin-left: 0; }
.hand .card.lifted { transform: translateY(var(--lift)) scale(1.04); z-index: 5; box-shadow: 0 8px 18px rgba(0,0,0,.4); }
.hand .card.illegal { filter: grayscale(.85) brightness(.62); cursor: not-allowed; }
.hand .card.played { opacity: 0; pointer-events: none; }

@media (hover: hover) {
  .hand .card:not(.illegal):hover { transform: translateY(-10px); }
}

/* ---------- bidding ---------- */

.bidding { padding: 6px 14px 2px; text-align: center; }
.prompt { margin: 0 0 8px; font-size: 13px; letter-spacing: .06em; text-transform: uppercase; opacity: .75; }
.bids { display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px; }
.bid {
  appearance: none; border: 1px solid rgba(255,255,255,.18);
  background: rgba(255,255,255,.08); color: var(--paper);
  border-radius: 11px; padding: 9px 4px;
  font: inherit; font-weight: 600; cursor: pointer;
  display: grid; gap: 2px; place-items: center;
  transition: background .15s, transform .1s;
}
.bid:active { transform: scale(.96); }
.bid:hover { background: rgba(255,255,255,.16); }
.bid .pip { font-size: 21px; line-height: 1; }
.bid em { font-style: normal; font-size: 10px; opacity: .6; }
.bid.suit-h .pip, .bid.suit-d .pip { color: #ff8a90; }
.bid.word { font-size: 12px; }
.bid.shove { grid-column: 1 / -1; background: rgba(216,180,90,.2); }

/* ---------- status ---------- */

.statusbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 8px 14px 12px;
  font-size: 12px; opacity: .75;
}
.newgame {
  appearance: none; border: 1px solid rgba(255,255,255,.2);
  background: transparent; color: inherit;
  border-radius: 8px; padding: 5px 11px; font: inherit; cursor: pointer;
}

/* Wider screens simply get bigger cards; the layout does not change shape. */
@media (min-width: 480px) {
  :root { --card-w: 74px; --card-h: 108px; --overlap: -26px; }
  .trick { width: 230px; height: 230px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ---------- Weis bubbles ---------- */

.weis-layer { position: absolute; inset: 0; pointer-events: none; }
.weis-bubble {
  position: absolute;
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 4px 9px; border-radius: 12px;
  font-size: 12px; font-weight: 700;
  background: rgba(0, 0, 0, .62);
  border: 1px solid rgba(255, 255, 255, .14);
  /* A winning team can show up to nine cards. Cap and wrap rather than letting the bubble
     run off the felt, which is what an unconstrained nowrap did. */
  max-width: 46%;
  text-align: center;
  animation: pop .28s cubic-bezier(.2, 1.3, .4, 1);
}
/* Same rotation as the trick: rel 1 right, rel 2 top, rel 3 left. Kept clear of the
   190px trick in the middle. */
.weis-bubble[data-rel="0"] { left: 50%; bottom: 2px; transform: translateX(-50%); max-width: 80%; }
.weis-bubble[data-rel="1"] { right: 4px; top: 14%; }
.weis-bubble[data-rel="2"] { left: 50%; top: 32px; transform: translateX(-50%); max-width: 80%; }
.weis-bubble[data-rel="3"] { left: 4px; top: 14%; }
/* Called but beaten: scores nothing, which is the whole point of showing it. */
.weis-bubble.lost { opacity: .45; text-decoration: line-through; }
/* A partner's Weis. It scores, but it is never shown — only the best one is proved. */
.weis-bubble.counts { background: rgba(216, 180, 90, .16); border-color: rgba(216, 180, 90, .4); }
/* The one that won and had to be shown. */
.weis-bubble.best { background: rgba(216, 180, 90, .32); border-color: var(--gold); }
.weis-bubble .value { font-variant-numeric: tabular-nums; }
.weis-bubble .cards {
  font-weight: 500; opacity: .8; font-size: 10px;
  letter-spacing: .02em; line-height: 1.25;
  word-break: break-word;
}
.weis-bubble.stoeck { background: rgba(120, 190, 255, .28); border-color: rgba(120,190,255,.5); }
@keyframes pop { from { opacity: 0; transform: scale(.8) translateY(6px); } }

/* ---------- round scorecard ---------- */

.scorecard-backdrop {
  position: fixed; inset: 0; z-index: 20;
  display: grid; place-items: center;
  padding: 20px;
  background: rgba(0, 0, 0, .55);
  backdrop-filter: blur(3px);
}
.scorecard {
  width: 100%; max-width: 340px;
  background: #12241d;
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 16px;
  padding: 16px 18px 14px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, .5);
}
.scorecard header {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 10px;
}
.scorecard header span:first-child { font-size: 16px; font-weight: 700; }
.sc-contract { font-size: 13px; opacity: .75; }
.scorecard table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.scorecard th { font-size: 11px; text-transform: uppercase; letter-spacing: .07em; opacity: .55; font-weight: 600; }
.scorecard th:not(:first-child), .scorecard td:not(:first-child) { text-align: right; width: 68px; }
.scorecard td { padding: 5px 0; font-size: 14px; border-bottom: 1px solid rgba(255,255,255,.06); }
.scorecard td:first-child { opacity: .8; }
.scorecard tr.subtotal td { font-weight: 700; border-bottom: 2px solid rgba(255,255,255,.18); }
.scorecard tr.total td { font-weight: 700; font-size: 16px; border-bottom: none; padding-top: 9px; }
.scorecard tr.total td:nth-child(2) { color: var(--gold); }
.scorecard tr.zero td { opacity: .35; }
.scorecard tr.note td { font-size: 11px; opacity: .5; border-bottom: none; padding: 2px 0 6px; }
.sc-continue {
  width: 100%; margin-top: 12px;
  appearance: none; border: none; border-radius: 10px;
  padding: 11px; font: inherit; font-weight: 700; cursor: pointer;
  background: var(--gold); color: #1a1a1a;
}

/* ---------- card faces ---------- */

.card { padding: 0; overflow: hidden; }
.card .face { display: block; width: 100%; height: 100%; }
.card .face text { font-family: ui-rounded, "SF Pro Rounded", system-ui, sans-serif; font-weight: 700; }
.face.red  { --face-ink: var(--red); }
.face.black { --face-ink: var(--black); }
.face text { fill: var(--face-ink); }

.face .idx-rank { font-size: 26px; text-anchor: middle; }
.face .idx-pip  { font-size: 19px; text-anchor: middle; }
.face .pip-mark { font-size: 22px; text-anchor: middle; dominant-baseline: central; }

.face .court-frame { fill: none; stroke: var(--face-ink); stroke-width: 1.2; opacity: .35; }
.face .court-divide { stroke: var(--face-ink); stroke-width: .8; opacity: .25; }
.face .court-ink { fill: var(--face-ink); }
.face .court-face { fill: #fff; stroke: var(--face-ink); stroke-width: 1.1; }
.face .court-robe { fill: var(--face-ink); opacity: .16; stroke: var(--face-ink); stroke-width: 1.1; }
.face .court-line { fill: none; stroke: var(--face-ink); stroke-width: 1; opacity: .7; }
.face .court-pip { font-size: 13px; text-anchor: middle; }

/* The trump Jack decides most tricks it appears in, so it has to be findable instantly. */
.card.puur .face .court-frame { stroke: var(--gold); opacity: 1; stroke-width: 2; }
.card.puur .face .court-robe { fill: var(--gold); opacity: .3; }



/* ---------- Weis prompt ---------- */

.weis-prompt { padding: 6px 14px 2px; text-align: center; }
.weis-prompt .prompt { text-transform: none; letter-spacing: 0; font-size: 14px; opacity: .9; }
.weis-prompt strong { color: var(--gold); }
.weis-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.bid.ghost { background: transparent; opacity: .8; }

/* ---------- settings menu ---------- */

.hamburger {
  position: absolute; top: calc(env(safe-area-inset-top) + 9px); left: 10px; z-index: 15;
  width: 34px; height: 30px; padding: 6px 5px;
  display: grid; gap: 4px; align-content: center;
  appearance: none; border: none; background: transparent; cursor: pointer;
}
.hamburger span { display: block; height: 2px; border-radius: 2px; background: var(--paper); opacity: .75; }

.menu-backdrop {
  position: fixed; inset: 0; z-index: 30;
  display: grid; place-items: center; padding: 18px;
  background: rgba(0, 0, 0, .6); backdrop-filter: blur(3px);
  overflow-y: auto;
}
.menu {
  width: 100%; max-width: 360px;
  background: #12241d; border: 1px solid rgba(255,255,255,.12);
  border-radius: 16px; padding: 16px 18px;
  box-shadow: 0 18px 40px rgba(0,0,0,.5);
}
.menu header { font-size: 16px; font-weight: 700; margin-bottom: 4px; }
.menu-note { font-size: 11px; opacity: .55; margin: 0 0 12px; line-height: 1.4; }
.menu fieldset { border: none; padding: 0; margin: 0 0 16px; }
.menu legend {
  padding: 0; margin-bottom: 7px;
  font-size: 11px; text-transform: uppercase; letter-spacing: .08em; opacity: .55; font-weight: 700;
}

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip { position: relative; cursor: pointer; }
.chip input { position: absolute; opacity: 0; pointer-events: none; }
.chip span {
  display: block; padding: 7px 13px; border-radius: 9px;
  border: 1px solid rgba(255,255,255,.16); background: rgba(255,255,255,.05);
  font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.chip.small span { padding: 5px 9px; font-size: 12px; }
.chip input:checked + span { background: rgba(216,180,90,.28); border-color: var(--gold); }
.chip input:focus-visible + span { outline: 2px solid var(--gold); outline-offset: 2px; }

.mult-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.mult-name { font-size: 13px; opacity: .8; }

.menu-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 4px; }
.bid.primary { background: var(--gold); color: #1a1a1a; border-color: transparent; }

/* ---------- menu modes: settings / how it works ---------- */

.menu-shell { padding: 0; display: flex; flex-direction: column; max-height: min(86dvh, 720px); }
.menu-modes {
  display: flex; align-items: center; gap: 4px;
  padding: 10px 12px 8px; border-bottom: 1px solid rgba(255,255,255,.08);
}
.menu-mode {
  appearance: none; border: none; background: transparent; color: inherit;
  font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  padding: 6px 11px; border-radius: 8px; opacity: .55;
}
.menu-mode.on { opacity: 1; background: rgba(255,255,255,.09); }
.menu-close {
  margin-left: auto; appearance: none; border: none; background: transparent;
  color: inherit; font-size: 22px; line-height: 1; cursor: pointer; opacity: .5;
  padding: 2px 6px;
}
.menu-mode-panel { padding: 14px 18px 16px; overflow-y: auto; }
form.menu-mode-panel { background: none; border: none; border-radius: 0; box-shadow: none; max-width: none; }

/* ---------- how it works ---------- */

.about { display: flex; flex-direction: column; gap: 10px; }
.about-tabs { display: flex; gap: 5px; }
.about-tab {
  appearance: none; border: 1px solid rgba(255,255,255,.14); background: rgba(255,255,255,.04);
  color: inherit; font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
  padding: 6px 10px; border-radius: 8px; opacity: .7;
}
.about-tab.on { opacity: 1; background: rgba(216,180,90,.2); border-color: var(--gold); }
.about-body { font-size: 13.5px; line-height: 1.55; }
.about-panel h3 { margin: 4px 0 6px; font-size: 15px; }
.about-panel h4 { margin: 18px 0 5px; font-size: 13px; letter-spacing: .04em; text-transform: uppercase; opacity: .6; }
.about-panel p { margin: 0 0 11px; opacity: .9; }
.about-panel p.warn {
  background: rgba(216,180,90,.1); border-left: 2px solid var(--gold);
  padding: 9px 11px; border-radius: 0 8px 8px 0; opacity: 1;
}
.about-panel b { color: var(--paper); }
.about-panel .meta { display: block; margin-top: 5px; font-size: 11px; opacity: .5; }

/* figures */
.fig { display: block; width: 100%; height: auto; margin: 6px 0 4px; overflow: visible; }
.fig-wrap { margin: 6px 0 10px; }
.fig-label { font-size: 9.5px; fill: var(--paper); opacity: .8; }
.fig-value { font-size: 10px; fill: var(--gold); font-weight: 700; }
.fig-tick { font-size: 9px; fill: var(--paper); opacity: .45; }
.fig-note { font-size: 9px; fill: var(--gold); opacity: .8; }
.fig-caption { font-size: 11.5px; opacity: .65; margin: 2px 0 12px; line-height: 1.45; }
.axis-line { stroke: var(--paper); stroke-opacity: .25; stroke-width: 1; stroke-dasharray: 3 3; }
.ci { stroke: var(--gold); stroke-width: 3; stroke-linecap: round; }
.ci-null { stroke: var(--paper); stroke-opacity: .3; }
.dot { fill: var(--gold); }
.dot-null { fill: var(--paper); fill-opacity: .5; }
.curve { fill: none; stroke: var(--gold); stroke-width: 2; stroke-linejoin: round; }
.bar { fill: var(--gold); opacity: .45; }
.bar-1, .bar-2 { opacity: .85; }

/* void inference grid */
.cardcell { fill: rgba(255,255,255,.1); stroke: rgba(255,255,255,.12); transition: fill .35s, opacity .35s; }
.cardcell-label { font-size: 9px; fill: var(--paper); opacity: .8; transition: opacity .35s; }
.cardcell.ruled { fill: rgba(255,255,255,.02); }
.cardcell-label.ruled { opacity: .15; }
.cardcell.kept { fill: rgba(216,180,90,.4); stroke: var(--gold); }
.fig-step {
  appearance: none; border: 1px solid rgba(255,255,255,.18); background: rgba(255,255,255,.06);
  color: inherit; font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
  padding: 5px 11px; border-radius: 8px; margin-top: 2px;
}

/* ---------- Jasstafel ---------- */

.scoreboard { cursor: pointer; }
.scoreboard:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }

.tafel-backdrop {
  position: fixed; inset: 0; z-index: 25;
  display: grid; place-items: center; padding: 20px;
  background: rgba(0, 0, 0, .6); backdrop-filter: blur(3px);
}
.tafel {
  width: 100%; max-width: 300px;
  /* Stone, not paper. Layered gradients give it an uneven, quarried look; the inset shadow
     is the worn darkening around the edge of a board that has been wiped for years. */
  background:
    radial-gradient(120% 80% at 30% 10%, rgba(255,255,255,.05), transparent 60%),
    radial-gradient(90% 70% at 80% 90%, rgba(255,255,255,.035), transparent 55%),
    linear-gradient(155deg, #3a3d3c 0%, #2c302f 45%, #242827 100%);
  border: 7px solid #5d3f22;
  border-radius: 5px;
  box-shadow:
    0 18px 40px rgba(0,0,0,.6),
    inset 0 0 60px rgba(0,0,0,.5),
    inset 0 1px 0 rgba(255,255,255,.06);
  overflow: hidden;
}
.tafel > header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 9px 12px 7px;
  font-size: 13px; font-weight: 700; letter-spacing: .06em;
  color: rgba(255,255,255,.75);
  border-bottom: 1px solid rgba(255,255,255,.08);
}
/* The board a Jass app draws is red on black; the chalk white is kept behind a variable so
   it is a one-line change back. */
.tafel { --chalk: #e2483f; }
.tafel-slate {
  background: #0a0a0a;
  padding: 10px 6px 12px;
  /* A tall board on a short phone still has to be reachable. */
  max-height: 62dvh; overflow-y: auto;
}

/* ---------- chalk ---------- */

.slate-svg { display: block; width: 100%; height: auto; overflow: visible; }
.chalk-stroke {
  stroke: var(--chalk, #f3f1ea);
  stroke-opacity: .9;
  stroke-linecap: round;
  fill: none;
}
.chalk-total, .chalk-target { fill: var(--chalk, #f3f1ea); fill-opacity: .9; }
.chalk-total {
  font-size: 15px; font-weight: 700;
  font-family: ui-rounded, system-ui, sans-serif; font-variant-numeric: tabular-nums;
}
.chalk-target {
  font-size: 12px; fill-opacity: .5;
  font-family: ui-rounded, system-ui, sans-serif; font-variant-numeric: tabular-nums;
}
.chalk-head, .chalk-number {
  fill: var(--chalk, #f3f1ea); fill-opacity: .85;
  /* Hand-written feel without shipping a font: a humanist face, loosened and slightly
     irregular, over the chalk filter. */
  font-family: "Bradley Hand", "Segoe Print", "Comic Sans MS", ui-rounded, cursive;
  letter-spacing: .04em;
}
.chalk-head { font-size: 15px; }
.chalk-number { font-size: 16px; }
.chalk-symbol { fill: var(--chalk, #f3f1ea); fill-opacity: .85; font-size: 19px; font-family: "Bradley Hand", "Segoe Print", "Comic Sans MS", ui-rounded, cursive; }
/* The printed band labels on a real board, not chalk — faint and out of the way. */
.chalk-band {
  fill: var(--chalk, #f3f1ea); fill-opacity: .28; font-size: 9px;
  font-family: ui-rounded, system-ui, sans-serif; letter-spacing: .04em;
}
.slate-note {
  margin: 12px 10px 0; text-align: center;
  font-size: 11px; letter-spacing: .04em;
  color: #f3f1ea; opacity: .38;
}
.tafel-legend {
  margin: 8px 12px 0; text-align: center; line-height: 1.5;
  font-size: 10px; color: #f3f1ea; opacity: .33;
}

.tafel-grid {
  display: grid; grid-template-columns: 1fr 1px 1fr;
  font-variant-numeric: tabular-nums;
  color: #eef1f0;
}
/* The divider is the one thing every Jass board has. */
.tafel-rule { background: rgba(255,255,255,.55); }
.tafel-head {
  text-align: center; padding: 8px 0 6px;
  font-size: 13px; letter-spacing: .16em; text-transform: uppercase;
  opacity: .65;
}
.tafel-cell {
  text-align: center; padding: 5px 0;
  font-size: 16px; opacity: .82;
}
.tafel-cell.dim { opacity: .35; }
.tafel-round {
  grid-column: 1 / -1; text-align: center;
  font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase;
  opacity: .3; padding-top: 4px;
}
.tafel-total {
  font-size: 25px; font-weight: 700; padding: 8px 0 4px;
  border-top: 2px double rgba(255,255,255,.45);
  margin-top: 4px;
}
.tafel-total.leading { color: var(--gold); }
.tafel-empty { text-align: center; opacity: .4; font-size: 12.5px; padding: 18px 12px; }

.tafel-target {
  margin: 10px 14px 0; font-size: 10.5px; opacity: .5; text-align: center;
}
.tafel-bar {
  margin: 5px 14px 0; height: 4px; border-radius: 2px;
  background: rgba(255,255,255,.12); position: relative; overflow: hidden;
}
.tafel-bar i { position: absolute; inset: 0 auto 0 0; background: var(--gold); border-radius: 2px; }
.tafel-bar i.them { background: rgba(255,255,255,.5); }
.tafel-bar + .tafel-bar { margin-top: 3px; }

/* -- the Nerd-Doc walkthrough -------------------------------------------- */
/* A stepper rather than a long scroll: each step is one idea and one figure, and the
   figure animates only where the motion is the argument. See walkthrough.js. */
.wt-stage {
  border: 1px solid rgba(255,255,255,.1);
  border-radius: 10px;
  padding: 12px 12px 10px;
  background: rgba(0,0,0,.16);
}
.about-panel h4.wt-title {
  margin: 0 0 6px; font-size: 14px; text-transform: none; letter-spacing: 0; opacity: 1;
}
.wt-body { margin: 0 0 10px; font-size: 13px; line-height: 1.55; opacity: .9; min-height: 5.6em; }
.wt-figure { min-height: 120px; }
.wt-dots { display: flex; gap: 6px; justify-content: center; margin: 8px 0 10px; }
.wt-dot {
  width: 7px; height: 7px; padding: 0; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.3); background: transparent; cursor: pointer;
  transition: background .2s, border-color .2s;
}
.wt-dot.on { background: var(--gold); border-color: var(--gold); }
.wt-nav-row { display: flex; align-items: center; gap: 6px; }
.wt-nav {
  font: inherit; font-size: 12px; padding: 5px 10px; border-radius: 7px; cursor: pointer;
  border: 1px solid rgba(255,255,255,.18); background: rgba(255,255,255,.06); color: var(--paper);
}
.wt-nav-main { border-color: var(--gold); background: rgba(216,180,90,.2); }
.wt-counter { margin-left: auto; font-size: 11px; opacity: .45; }

.wt-chip rect { fill: rgba(255,255,255,.1); stroke: rgba(255,255,255,.14); }
.wt-chip.wt-mine rect { fill: rgba(216,180,90,.55); stroke: var(--gold); }
.wt-chip.wt-hidden rect { fill: rgba(255,255,255,.05); }
.wt-chip-t { font-size: 9px; fill: var(--paper); opacity: .4; }
.wt-chip.wt-dealt rect { fill: rgba(216,180,90,.3); stroke: rgba(216,180,90,.45); }
.wt-seat { fill: rgba(255,255,255,.04); stroke: rgba(255,255,255,.12); }

.wt-world-ok { fill: rgba(216,180,90,.5); stroke: var(--gold); stroke-width: .8; }
.wt-world-bad { fill: rgba(255,255,255,.05); stroke: rgba(255,255,255,.1); }
.wt-strike { stroke: var(--paper); stroke-opacity: .35; stroke-width: 1; }

.wt-edge { stroke: rgba(255,255,255,.22); stroke-width: 1.4; }
.wt-edge-thin { stroke-opacity: .12; }
.wt-node { fill: rgba(255,255,255,.12); stroke: rgba(255,255,255,.25); }
.wt-node-root { fill: rgba(216,180,90,.7); stroke: var(--gold); }
.wt-node-leaf { fill: rgba(255,255,255,.07); }
.wt-visits { fill: var(--gold); opacity: .75; }

.wt-rollout { fill: none; stroke: var(--gold); stroke-width: 2; stroke-linejoin: round; }

@media (prefers-reduced-motion: reduce) {
  .wt-chip, .wt-visits, .wt-rollout { transition: none !important; }
}

/* -- advice mode --------------------------------------------------------- */
/* A fourth bot's opinion on your own seat. Gold is the app's "this matters" colour, so the
   ranks step down through it rather than using three unrelated hues — rank is an ordering,
   not a category.

   The badge sits *inside* the card, bottom-left: `.card` clips its content so it can keep
   the rounded corners over the face SVG, and in the fan it is the left strip of each card
   that stays visible. The corner indices live top-left and bottom-right (cards.js), so the
   bottom-left is the one quiet corner on the face. */
.hand .card { position: relative; }
.hand .card.advised { box-shadow: 0 0 0 2px var(--gold), 0 6px 16px rgba(0,0,0,.4); }
.hand .card.advised-2 { box-shadow: 0 0 0 2px rgba(216,180,90,.6), 0 5px 12px rgba(0,0,0,.35); }
.hand .card.advised-3 { box-shadow: 0 0 0 2px rgba(216,180,90,.32), 0 4px 10px rgba(0,0,0,.3); }

.advice-rank {
  position: absolute;
  left: 4px; bottom: 4px;
  min-width: 17px; height: 17px;
  display: grid; place-items: center;
  padding: 0 4px;
  border-radius: 9px;
  font-size: 11px; font-weight: 700; line-height: 1;
  background: var(--gold); color: var(--ink);
  box-shadow: 0 1px 4px rgba(0,0,0,.45);
  pointer-events: none;
}
.card.advised-2 .advice-rank { background: rgba(216,180,90,.78); }
.card.advised-3 .advice-rank { background: rgba(216,180,90,.55); }
