/* static/css/kit.css -- SKETCH 4: the one stylesheet for the kit.
 *
 * Components taken from the owner's YoRHa desktop panel (~/.config/yorha/
 * templates/eww.scss): the card with a solid header strip, label/value rows in
 * mono, thin bars, tabs inside a card, buttons at a card's foot, the accent
 * alert strip, rows with a coloured left mark. Plus the Webull part: ONE panel
 * (title strip with a count, one action and a link-group dot; an optional tab
 * stack; a body that never scrolls; an optional foot) that every region of
 * every screen is made of. Notes: .planning/sketch4/DESIGN-NOTES.md.
 *
 * RULES OF THIS FILE
 * - Every colour and size is a token from kit-tokens.css. No hex below.
 * - No !important. No per-screen colours. Only .k-* classes and the kit's own
 *   data attributes (data-pc, data-set, data-link, data-why), so the file is
 *   inert on a page that does not use them (one exception, at the end and scoped
 *   to <html data-k-desk>: moderation.js's sheets in the kit's look, sketch 4.2
 *   item 15): it sits beside the game's 30
 *   stylesheets without changing a pixel of them (proved by
 *   tools/sketch/s4_phone_same.py, 390x844 before and after).
 * - Unlayered on purpose: it beats layer(legacy) and layer(components) on the
 *   kit's own elements. It does NOT beat a legacy `!important` (CLAUDE.md 6a,
 *   D-039), so kit classes go on NEW markup, never on a legacy element.
 * - Components carry no breakpoint. The only desktop rules (the page grid that
 *   places panels) sit behind ONE breakpoint, min-width 900px, at the end.
 *   900, not 960: a half-screen browser window on a 1920 monitor is about
 *   945px inside, and the brief needs half-width to be a desktop layout.
 */

/* ── Base ─────────────────────────────────────────────────────────────── */
[class^="k-"], [class*=" k-"],
[class^="k-"]::before, [class*=" k-"]::before,
[class^="k-"]::after, [class*=" k-"]::after { box-sizing: border-box; }

.k-root {
  margin: 0; min-height: 100vh; min-height: 100dvh;
  background: var(--k-bg); color: var(--k-ink);
  font: 400 var(--k-f-md)/1.4 var(--k-sans);
  -webkit-font-smoothing: antialiased;
}
.k-mono, .k-num { font-family: var(--k-mono); font-variant-numeric: lining-nums tabular-nums; }
.k-num { text-align: right; white-space: nowrap; }
.k-dim  { color: var(--k-dim); }
.k-up   { color: var(--k-postext); }
.k-down { color: var(--k-negtext); }
.k-acc  { color: var(--k-accenttext); }
.k-grow { flex: 1 1 auto; min-width: 0; }
.k-col  { display: flex; flex-direction: column; gap: var(--k-gap); min-height: 0; min-width: 0; }
.k-line { display: flex; align-items: center; gap: var(--k-s2); min-width: 0; }
.k-rule { border: 0; border-top: 1px solid var(--k-linesoft); margin: 0; flex: 0 0 auto; }
.k-empty { margin: 0; padding: var(--k-s1) 2px; color: var(--k-dim); font-size: var(--k-f-sm); line-height: 1.5; }
.k-empty.k-down { color: var(--k-negtext); }        /* an error line (the menu's code error was painted dim) */
.k-label {
  font: 500 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .1em; text-transform: uppercase;
  color: var(--k-dim);
}

/* players and sets: a data attribute picks the colour, the theme picks the shade */
[data-pc="sky"]    { --k-pc: var(--k-c-sky); }
[data-pc="green"]  { --k-pc: var(--k-c-green); }
[data-pc="violet"] { --k-pc: var(--k-c-violet); }
[data-pc="pink"]   { --k-pc: var(--k-c-pink); }
[data-pc="amber"]  { --k-pc: var(--k-c-amber); }
[data-pc="orange"] { --k-pc: var(--k-c-orange); }
[data-set="brown"]  { --k-sc: var(--k-s-brown); }
[data-set="lblue"]  { --k-sc: var(--k-s-lblue); }
[data-set="pink"]   { --k-sc: var(--k-s-pink); }
[data-set="orange"] { --k-sc: var(--k-s-orange); }
[data-set="red"]    { --k-sc: var(--k-s-red); }
[data-set="yellow"] { --k-sc: var(--k-s-yellow); }
[data-set="green"]  { --k-sc: var(--k-s-green); }
[data-set="blue"]   { --k-sc: var(--k-s-blue); }
[data-set="rail"]   { --k-sc: var(--k-s-rail); }
[data-set="util"]   { --k-sc: var(--k-s-util); }
[data-link="a"] { --k-lc: var(--k-link-a); }
[data-link="b"] { --k-lc: var(--k-link-b); }
[data-link="c"] { --k-lc: var(--k-link-c); }

/* ── PANEL: the one region every screen is made of ────────────────────── */
.k-panel {
  display: flex; flex-direction: column; min-height: 0; min-width: 0;
  background: var(--k-panel); color: var(--k-ink);
  border: 1px solid var(--k-line); border-radius: var(--k-radius);
  font: 400 var(--k-f-md)/1.4 var(--k-sans);
  overflow: hidden;           /* a panel never scrolls: content goes to tabs, pages or a sheet */
}
.k-fill { flex: 1 1 0; }      /* the last panel in a column takes the rest of the height */

.k-head {
  display: flex; align-items: center; gap: var(--k-s2);
  flex: 0 0 auto; height: var(--k-head-h); min-width: 0;
  padding: 0 4px 0 var(--k-pad);
  background: var(--k-head-bg); color: var(--k-head-fg);
}
.k-title {
  margin: 0; min-width: 0; flex: 0 1 auto;
  font: 600 var(--k-f-sm)/1 var(--k-sans); letter-spacing: var(--k-track); text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.k-stat {
  margin-left: auto; flex: 0 0 auto; padding: 0 4px;
  font: 500 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .06em; text-transform: uppercase;
  white-space: nowrap; color: var(--k-head-soft);
}
.k-title + .k-hbtn, .k-title + .k-ibtn, .k-title + .k-seg { margin-left: auto; }

/* the link-group dot (Webull): filled in the group's colour, a ring when unlinked */
.k-link {
  flex: 0 0 auto; display: inline-block; width: 9px; height: 9px; border-radius: 50%;
  background: var(--k-lc, transparent); box-shadow: 0 0 0 1.5px var(--k-ink);
}
.k-head .k-link { box-shadow: 0 0 0 1.5px var(--k-head-fg); }
.k-panel.is-linked .k-link { animation: k-link-pulse 600ms ease-out; }
.k-panel.is-linked2 .k-link { animation: k-link-pulse2 600ms ease-out; }     /* the same, to start it again (kit.js) */
@keyframes k-link-pulse { 0% { box-shadow: 0 0 0 1.5px var(--k-head-fg), 0 0 0 0 var(--k-lc, var(--k-accent)); }
  100% { box-shadow: 0 0 0 1.5px var(--k-head-fg), 0 0 0 7px transparent; } }
@keyframes k-link-pulse2 { 0% { box-shadow: 0 0 0 1.5px var(--k-head-fg), 0 0 0 0 var(--k-lc, var(--k-accent)); }
  100% { box-shadow: 0 0 0 1.5px var(--k-head-fg), 0 0 0 7px transparent; } }

/* the header's one action */
.k-hbtn {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px;
  height: calc(var(--k-head-h) - 8px); margin: 0; padding: 0 10px;
  border: 0; border-radius: var(--k-radius); cursor: pointer;
  background: var(--k-head-fg); color: var(--k-head-bg);
  font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
}
.k-hbtn--pri { background: var(--k-accentbg); color: var(--k-onaccent); }
/* sketch 4.2, item 10: the You panel's Dashboard, "a bit longer vertical wise": 2 px from the strip's edges */
.k-hbtn.k-hbtn--tall { height: calc(var(--k-head-h) - 4px); padding: 0 12px; }
.k-hbtn:not([aria-disabled="true"]):hover { background: var(--k-accenthover); color: var(--k-onaccent); }
/* greyed: looks it, says why on hover (kit.js), and does nothing (look review, 6 Oct) */
.k-hbtn[aria-disabled="true"], .k-mi[aria-disabled="true"], .k-seg > button[aria-disabled="true"] { opacity: .42; cursor: not-allowed; }

/* a small square icon button (gear, close, menu) */
.k-ibtn {
  flex: 0 0 auto; display: inline-grid; place-items: center;
  width: 24px; height: 24px; margin: 0; padding: 0;
  border: 0; border-radius: var(--k-radius); background: transparent; color: inherit; cursor: pointer;
  font: 600 14px/1 var(--k-sans);
}
.k-ibtn:hover { background: var(--k-selbg); color: var(--k-ink); }
.k-head .k-ibtn:hover { background: var(--k-head-fg); color: var(--k-head-bg); }

/* tab stack: a row under the strip (the desktop's OPERATIONS card) ... */
.k-tabs { display: flex; flex: 0 0 auto; border-bottom: 1px solid var(--k-line); background: var(--k-panel); }
.k-tab {
  flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  height: var(--k-tab-h); margin: 0; padding: 0 8px; min-width: 0;
  border: 0; background: transparent; color: var(--k-dim); cursor: pointer;
  font: 500 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
}
.k-tab:hover { background: var(--k-selbg); color: var(--k-ink); }
.k-tab[aria-selected="true"] { background: var(--k-well); color: var(--k-ink); font-weight: 700; }
/* ... or inside the strip itself (Webull's stacked widgets), for a tight panel */
.k-head > .k-tabs { align-self: stretch; border: 0; background: transparent; flex: 0 1 auto; min-width: 0; }
.k-head > .k-tabs:first-child { margin-left: calc(-1 * var(--k-pad)); }
.k-head > .k-tabs .k-tab { flex: 0 0 auto; height: auto; padding: 0 11px; color: var(--k-head-fg); }
.k-head > .k-tabs .k-tab:hover { background: var(--k-head-fg); color: var(--k-head-bg); }
.k-head > .k-tabs .k-tab[aria-selected="true"] { background: var(--k-panel); color: var(--k-ink); }
.k-head > .k-tabs + .k-stat { margin-left: auto; }

.k-body {
  flex: 1 1 auto; min-height: 0; min-width: 0; overflow: hidden;
  display: flex; flex-direction: column; gap: var(--k-s2);
  padding: var(--k-pad);
}
.k-body--flush { padding: 0; gap: 0; }
.k-body--fit { flex: 0 0 auto; }          /* a panel as tall as its content */
.k-pane { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: var(--k-s2); }
.k-pane[hidden] { display: none; }

.k-foot {
  flex: 0 0 auto; display: flex; gap: var(--k-s2);
  padding: 0 var(--k-pad) var(--k-pad);
}
.k-foot > .k-btn { flex: 1 1 0; }
.k-body--flush + .k-foot { padding-top: var(--k-pad); }

/* ── label / value rows (the desktop's .kv) ───────────────────────────── */
.k-kv {
  display: flex; align-items: baseline; gap: var(--k-s2); min-height: var(--k-kv-h); min-width: 0;
  font: 400 var(--k-f-sm)/1.35 var(--k-mono); font-variant-numeric: lining-nums tabular-nums;
}
.k-k { flex: 1 1 auto; min-width: 0; color: var(--k-dim); letter-spacing: .04em; text-transform: uppercase;
       white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.k-v { flex: 0 0 auto; color: var(--k-ink); text-align: right; white-space: nowrap; }
.k-v.is-up { color: var(--k-postext); }
.k-v.is-down { color: var(--k-negtext); }
.k-v.is-acc { color: var(--k-accenttext); font-weight: 600; }
.k-kv--big .k-v { font-size: var(--k-f-xl); font-weight: 600; line-height: 1; }

/* a bar under a label row (the desktop's `bar` widget) */
.k-meter { display: flex; flex-direction: column; gap: 5px; }
.k-meter > .k-kv { min-height: 0; }
.k-bar { height: var(--k-bar-h); border: 1px solid var(--k-line); background: transparent; overflow: hidden; }
/* the fill is scaled, not sized: a width that changes (the turn clock's, twice a
   second, eased) laid the page out on every frame of its transition; a transform
   is the compositor's alone (sketch 4.1, the lag). Kit.bars sets --k-v. */
.k-bar > i { display: block; height: 100%; width: 100%; background: var(--k-ink);
             transform: scaleX(var(--k-v, 0)); transform-origin: left center; transition: transform var(--k-dur) ease; }
.k-bar.is-hot > i { background: var(--k-accent); }      /* the desktop turns a bar accent from 80% */
.k-bar.is-up > i  { background: var(--k-pos); }
.k-bar.is-down > i { background: var(--k-neg); }

/* ── list rows with a left colour mark (the desktop's task and crew rows) ── */
.k-row {
  position: relative; display: flex; align-items: center; gap: 10px;
  min-height: var(--k-row-h); min-width: 0; width: 100%; margin: 0;
  padding: 4px var(--k-pad) 4px calc(var(--k-pad) + var(--k-mark-w));
  border: 0; border-bottom: 1px solid var(--k-linesoft); background: transparent;
  color: var(--k-ink); font: 400 var(--k-f-md)/1.3 var(--k-sans); text-align: left;
}
.k-row::before {
  content: ""; position: absolute; left: 0; top: 5px; bottom: 5px;
  width: var(--k-mark-w); background: var(--k-mark, transparent);
}
.k-row[data-pc] { --k-mark: var(--k-pc); }
.k-row[data-set] { --k-mark: var(--k-sc); }
.k-row--tall { min-height: 52px; }
button.k-row, a.k-row, .k-row[role="button"] { cursor: pointer; text-decoration: none; }
button.k-row:hover, a.k-row:hover, .k-row[role="button"]:hover { background: var(--k-selbg); }
.k-row.is-current { background: var(--k-selbg); }
.k-row.is-current::before { top: 0; bottom: 0; }
.k-row.is-alert { background: var(--k-well); --k-mark: var(--k-accent); }
.k-row.is-done { color: var(--k-dim); }
.k-row.is-off { opacity: .55; }
.k-name { min-width: 0; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.k-row--tall .k-name { font-size: var(--k-f-lg); }
.k-sub { font: 400 var(--k-f-xs)/1.3 var(--k-mono); color: var(--k-dim); letter-spacing: .03em; white-space: nowrap;
         overflow: hidden; text-overflow: ellipsis; }
.k-stack { display: flex; flex-direction: column; gap: 3px; min-width: 0; }

/* a player's token */
.k-token {
  flex: 0 0 auto; display: inline-grid; place-items: center;
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--k-pc, var(--k-soft)); color: var(--k-onpc);
  font: 700 12px/1 var(--k-sans);
}
.k-token--sm { width: 18px; height: 18px; font-size: 9px; }

/* ── the cash figure and its +/- flash (richup's red/green change) ────── */
.k-cash { position: relative; display: inline-flex; flex-direction: column; align-items: flex-end; flex: 0 0 auto;
          font: 600 var(--k-f-xl)/1 var(--k-mono); font-variant-numeric: lining-nums tabular-nums; white-space: nowrap; }
.k-cash--md { font-size: var(--k-f-lg); }
.k-cash-v { transition: color var(--k-dur) ease; }
.k-cash.is-up .k-cash-v { color: var(--k-postext); }
.k-cash.is-down .k-cash-v { color: var(--k-negtext); }
.k-delta {
  position: absolute; right: 0; top: calc(100% + 3px);
  font: 600 var(--k-f-sm)/1 var(--k-mono); white-space: nowrap; opacity: 0; pointer-events: none;
}
.k-delta.is-up   { color: var(--k-postext); animation: k-flash var(--k-dur-flash) ease-out both; }
.k-delta.is-down { color: var(--k-negtext); animation: k-flash var(--k-dur-flash) ease-out both; }
.k-delta.is-held { opacity: 1; animation: none; }      /* a still picture of it (the gallery) */
/* in a label/value row (the You panel) the change goes beside the figure, so it
   never lands on the row under it (look review, 6 Oct) */
.k-kv--big .k-delta { top: auto; bottom: 2px; right: calc(100% + 8px); }
@keyframes k-flash {
  0% { opacity: 0; transform: translateY(-5px); }
  12% { opacity: 1; transform: translateY(0); }
  78% { opacity: 1; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .k-delta.is-up, .k-delta.is-down { animation: none; opacity: 1; }
}
.k-big { font: 600 var(--k-f-xxl)/1 var(--k-mono); font-variant-numeric: lining-nums tabular-nums; letter-spacing: -.01em; }

/* ── buttons ──────────────────────────────────────────────────────────── */
.k-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: var(--k-btn-h); margin: 0; padding: 0 14px; min-width: 0;
  border: 1px solid var(--k-line); border-radius: var(--k-radius);
  background: transparent; color: var(--k-ink); cursor: pointer;
  font: 600 var(--k-f-sm)/1 var(--k-mono); letter-spacing: .06em; text-transform: uppercase;
  white-space: nowrap; text-decoration: none;
  transition: background var(--k-dur), color var(--k-dur), border-color var(--k-dur);
}
.k-btn:not([aria-disabled="true"]):not(:disabled):hover { background: var(--k-inv); border-color: var(--k-inv); color: var(--k-invtext); }
.k-btn--pri { background: var(--k-accentbg); border-color: var(--k-accentedge); color: var(--k-onaccent); }
.k-btn--pri:not([aria-disabled="true"]):not(:disabled):hover { background: var(--k-accenthover); border-color: var(--k-accentedge); color: var(--k-onaccent); }
.k-btn--danger { border-color: var(--k-negtext); color: var(--k-negtext); }
.k-btn--danger:not([aria-disabled="true"]):not(:disabled):hover { background: var(--k-negtext); border-color: var(--k-negtext); color: var(--k-panel); }
.k-btn--sm { height: var(--k-btn-h-sm); padding: 0 9px; font-size: var(--k-f-xs); }
.k-btn--lg { height: var(--k-btn-h-lg); padding: 0 22px; font-size: var(--k-f-md); }
.k-btn--block { width: 100%; }
.k-btn[aria-disabled="true"], .k-btn:disabled { opacity: .42; cursor: not-allowed; }
.k-btn:focus-visible, .k-hbtn:focus-visible, .k-ibtn:focus-visible, .k-tab:focus-visible, .k-row:focus-visible,
.k-seg > button:focus-visible, .k-chip:focus-visible, .k-mi:focus-visible, .k-switch:focus-visible {
  outline: 2px solid var(--k-focus); outline-offset: 1px;
}

/* segmented choice (Square / Compressed) */
.k-seg { display: inline-flex; flex: 0 0 auto; border: 1px solid var(--k-line); border-radius: var(--k-radius); overflow: hidden; }
.k-seg > button {
  height: 22px; margin: 0; padding: 0 9px; border: 0; background: transparent; color: var(--k-dim); cursor: pointer;
  font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .06em; text-transform: uppercase; white-space: nowrap;
}
.k-seg > button + button { border-left: 1px solid var(--k-line); }
/* the pressed one keeps its look under a pointer (sketch 4.11: under a mouse, or a
   phone's hover that stays after a tap, the head's pressed choice lost its text) */
.k-seg > button:not([aria-disabled="true"]):not([aria-pressed="true"]):hover { color: var(--k-ink); background: var(--k-selbg); }
.k-seg > button[aria-pressed="true"] { background: var(--k-inv); color: var(--k-invtext); }
.k-head .k-seg { border-color: var(--k-head-fg); }
.k-head .k-seg > button { color: var(--k-head-fg); height: 20px; }
.k-head .k-seg > button + button { border-left-color: var(--k-head-fg); }
.k-head .k-seg > button:not([aria-disabled="true"]):not([aria-pressed="true"]):hover { background: transparent; text-decoration: underline; }
.k-head .k-seg > button[aria-pressed="true"] { background: var(--k-head-fg); color: var(--k-head-bg); }

/* ── chips, badges, set flags, dots ───────────────────────────────────── */
.k-chip {
  display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto;
  height: 22px; margin: 0; padding: 0 7px;
  border: 1px solid var(--k-line); border-radius: var(--k-radius); background: transparent; color: var(--k-ink);
  font: 500 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .05em; text-transform: uppercase; white-space: nowrap;
}
button.k-chip { cursor: pointer; }
button.k-chip:hover { background: var(--k-selbg); }
.k-chip.is-acc  { border-color: var(--k-accentedge); color: var(--k-accenttext); }
.k-chip.is-up   { border-color: var(--k-postext); color: var(--k-postext); }
.k-chip.is-down { border-color: var(--k-negtext); color: var(--k-negtext); }
.k-chip.is-on   { background: var(--k-accentsoft); border-color: var(--k-accentedge); color: var(--k-ink); }
.k-chip.is-solid { background: var(--k-inv); border-color: var(--k-inv); color: var(--k-invtext); }
.k-badge {
  display: inline-block; flex: 0 0 auto; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px;
  background: var(--k-accentbg); color: var(--k-onaccent);
  font: 700 10px/16px var(--k-mono); text-align: center;
}
.k-badge.is-quiet { background: var(--k-inv); color: var(--k-invtext); }
.k-set {
  display: inline-block; flex: 0 0 auto; width: 10px; height: 10px;
  background: var(--k-sc, transparent); box-shadow: inset 0 0 0 1px var(--k-line);
}
.k-set.is-empty { background: transparent; }
.k-sets { display: inline-flex; gap: 3px; flex-wrap: wrap; }
.k-dot { display: inline-block; flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%;
         border: 2px solid var(--k-ink); background: transparent; }
.k-dot.is-run  { background: var(--k-ink); }
.k-dot.is-wait { background: var(--k-accent); border-color: var(--k-accent); }
.k-dot.is-up   { background: var(--k-pos); border-color: var(--k-pos); }
.k-dot.is-down { background: var(--k-neg); border-color: var(--k-neg); }
.k-dot.is-off  { border-color: var(--k-dim); }

/* ── form controls ────────────────────────────────────────────────────── */
.k-input {
  height: var(--k-btn-h); min-width: 0; margin: 0; padding: 0 10px;
  border: 1px solid var(--k-line); border-radius: var(--k-radius);
  background: var(--k-well); color: var(--k-ink); font: 400 var(--k-f-md)/1 var(--k-sans);
}
.k-input.is-mono { font-family: var(--k-mono); letter-spacing: .08em; text-transform: uppercase; }
.k-input::placeholder { color: var(--k-soft); }
.k-input:focus { outline: none; border-color: var(--k-accentedge); box-shadow: 0 0 0 1px var(--k-accent); }
.k-input.is-bad { border-color: var(--k-negtext); }
/* a submit that is waiting for its answer takes no second tap (the page's .dsf-btn.busy) */
.k-btn[aria-busy="true"] { pointer-events: none; cursor: progress; opacity: .7; }
.k-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.k-select { appearance: none; -webkit-appearance: none; padding-right: 26px; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--k-dim) 50%), linear-gradient(135deg, var(--k-dim) 50%, transparent 50%);
  background-position: calc(100% - 14px) 50%, calc(100% - 9px) 50%; background-size: 5px 5px; background-repeat: no-repeat; }

.k-switch {
  appearance: none; -webkit-appearance: none; position: relative; flex: 0 0 auto;
  width: 34px; height: 18px; margin: 0; cursor: pointer;
  border: 1px solid var(--k-line); border-radius: var(--k-radius); background: var(--k-well);
  transition: background var(--k-dur), border-color var(--k-dur);
}
.k-switch::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px;
  background: var(--k-soft); transition: transform var(--k-dur), background var(--k-dur);
}
.k-switch:checked { background: var(--k-accentsoft); border-color: var(--k-accentedge); }
.k-switch:checked::after { transform: translateX(16px); background: var(--k-accent); }
.k-switch:disabled { opacity: .42; cursor: not-allowed; }

.k-range { appearance: none; -webkit-appearance: none; width: 100%; height: 20px; margin: 0; background: transparent; cursor: pointer; }
.k-range::-webkit-slider-runnable-track { height: 6px; border: 1px solid var(--k-line); background: var(--k-well); }
.k-range::-moz-range-track { height: 4px; border: 1px solid var(--k-line); background: var(--k-well); }
.k-range::-moz-range-progress { height: 4px; background: var(--k-accent); }
.k-range::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 18px; margin-top: -7px;
  border: 1px solid var(--k-accentedge); border-radius: var(--k-radius); background: var(--k-accent); }
.k-range::-moz-range-thumb { width: 12px; height: 18px; border: 1px solid var(--k-accentedge); border-radius: var(--k-radius); background: var(--k-accent); }
.k-range:focus-visible { outline: 2px solid var(--k-focus); outline-offset: 2px; }

/* pages instead of a scroll: ‹ 1 / 3 › */
.k-pager { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto;
  font: 500 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .06em; color: var(--k-dim); }
.k-pager > button {
  width: 22px; height: 22px; margin: 0; padding: 0; border: 1px solid var(--k-line); border-radius: var(--k-radius);
  background: transparent; color: var(--k-ink); cursor: pointer; font: 600 12px/1 var(--k-mono);
}
.k-pager > button:hover:not(:disabled) { background: var(--k-inv); color: var(--k-invtext); border-color: var(--k-inv); }
.k-pager > button:disabled { opacity: .35; cursor: default; }
.k-page[hidden], .k-pager[hidden] { display: none; }
/* `hidden` always wins inside the kit's own markup (a class's display would beat the attribute) */
.k-root [hidden] { display: none; }
.k-head .k-pager { color: var(--k-head-fg); margin-left: auto; }
.k-head .k-stat + .k-pager { margin-left: 0; }
.k-head .k-pager > button { border-color: var(--k-head-fg); color: var(--k-head-fg); }
.k-head .k-pager > button:hover:not(:disabled) { background: var(--k-head-fg); color: var(--k-head-bg); border-color: var(--k-head-fg); }

/* ── alert strip (the desktop's "● 14 NEED YOU · OPEN ▸") ──────────────── */
.k-alert {
  display: flex; align-items: center; gap: var(--k-s2); flex: 0 0 auto;
  min-height: 30px; padding: 6px var(--k-pad); margin: 0; width: 100%;
  border: 0; border-radius: 0; background: var(--k-accentbg); color: var(--k-onaccent); text-align: left;
  font: 700 var(--k-f-sm)/1.3 var(--k-mono); letter-spacing: .05em; text-transform: uppercase;
}
button.k-alert { cursor: pointer; }
button.k-alert:hover { background: var(--k-accenthover); }
.k-alert--neg { background: var(--k-negtext); color: var(--k-panel); }
.k-alert--quiet {
  background: var(--k-well); color: var(--k-ink); font-weight: 600;
  border-left: var(--k-mark-w) solid var(--k-accent); text-transform: none; letter-spacing: 0; font-family: var(--k-sans);
}
.k-alert-act { margin-left: auto; flex: 0 0 auto; white-space: nowrap; }

/* ── modal and sheet (native <dialog>, the browser's top layer) ────────── */
dialog.k-modal {
  width: min(520px, calc(100vw - 32px)); max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); margin: auto; padding: 0;
  border: 1px solid var(--k-line); border-radius: var(--k-radius);
  background: var(--k-panel); color: var(--k-ink); box-shadow: var(--k-shadow);
  font: 400 var(--k-f-md)/1.4 var(--k-sans); overflow: hidden;
}
dialog.k-modal[open] { display: flex; flex-direction: column; }
dialog.k-modal--wide { width: min(960px, calc(100vw - 32px)); }
dialog.k-sheet { margin: 0 0 0 auto; width: min(420px, 100vw); height: 100vh; height: 100dvh; max-height: none; border-width: 0 0 0 1px; }
dialog.k-modal::backdrop { background: rgba(0, 0, 0, .55); background: var(--k-scrim); }
/* the same panel drawn in place (the gallery, a pre-lobby card) */
.k-modal-still { box-shadow: var(--k-shadow); }

/* ── toast ────────────────────────────────────────────────────────────── */
.k-toasts {
  position: fixed; right: var(--k-s4); bottom: var(--k-s4); z-index: var(--k-z-toast);
  display: flex; flex-direction: column; gap: var(--k-s2);
  width: min(340px, calc(100vw - 32px)); pointer-events: none;
}
.k-toasts--still { position: static; width: auto; pointer-events: auto; z-index: auto; }
.k-toast {
  pointer-events: auto; display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 6px 10px 12px;
  background: var(--k-panel); color: var(--k-ink);
  border: 1px solid var(--k-line); border-left: var(--k-mark-w) solid var(--k-tc, var(--k-ink));
  box-shadow: var(--k-shadow-sm); font: 400 var(--k-f-md)/1.4 var(--k-sans);
  animation: k-toast-in 180ms ease-out;
}
.k-toast.is-up { --k-tc: var(--k-pos); }
.k-toast.is-down { --k-tc: var(--k-neg); }
.k-toast.is-acc { --k-tc: var(--k-accent); }
.k-toast-t { flex: 1 1 auto; min-width: 0; }
.k-toast-t b { font-weight: 600; }
.k-toast .k-ibtn { margin-top: -3px; color: var(--k-dim); }
@keyframes k-toast-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ── a reason for a greyed-out control, and the gear menu ─────────────── */
.k-tipbox {
  position: fixed; z-index: var(--k-z-toast); max-width: 260px; padding: 6px 9px; pointer-events: none;
  background: var(--k-inv); color: var(--k-invtext); border-radius: var(--k-radius);
  font: 400 var(--k-f-sm)/1.4 var(--k-sans); box-shadow: var(--k-shadow-sm);
}
.k-tipbox[hidden] { display: none; }
.k-menu {
  margin: 0; padding: 4px 0; min-width: 220px;
  border: 1px solid var(--k-line); border-radius: var(--k-radius);
  background: var(--k-panel); color: var(--k-ink); box-shadow: var(--k-shadow-sm);
  font: 400 var(--k-f-md)/1.3 var(--k-sans);
}
.k-menu[popover] { position: fixed; inset: auto; }
.k-menu--still { display: inline-block; box-shadow: var(--k-shadow-sm); }
.k-mi {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 34px; margin: 0; padding: 0 12px;
  border: 0; background: transparent; color: inherit; text-align: left; cursor: pointer; font: inherit;
}
.k-mi:not([aria-disabled="true"]):hover { background: var(--k-selbg); }
.k-mi .k-sub { margin-left: auto; }
.k-mi.is-danger { color: var(--k-negtext); }
.k-menu .k-rule { margin: 4px 0; }

/* ── the page grid that places panels: DESKTOP ONLY ───────────────────── */
@media (min-width: 900px) {
  .k-desk {
    display: grid; grid-template-columns: var(--k-side-w) minmax(0, 1fr) var(--k-side-w);
    gap: var(--k-gap); padding: var(--k-gap);
    height: 100vh; height: 100dvh; overflow: hidden; background: var(--k-bg);
  }
  .k-desk--half { grid-template-columns: minmax(0, 1fr) var(--k-side-w); }
  .k-desk > * { min-height: 0; min-width: 0; }
  .k-boardbox { height: 100%; max-width: 100%; aspect-ratio: 1 / 1; margin: 0 auto; }
}

/* ══ STEP 2a: THE BOARD AND THE SCREENS ═══════════════════════════════════
 * Everything below is still the kit: tokens only, no !important, no colour of
 * its own. The board is one more component (Kit.Board, static/js/kit-board.js);
 * the screens are page grids that place panels (desktop only, at the end). */

/* ── BOARD: richup's logic in the kit's look ──────────────────────────────
 * The square is 100cqmin of its box (a size container that fills the board
 * panel's body), so it is always as big as the window height allows. Tiles are
 * quiet: the name, a small set flag on the INNER edge, the price on the OUTER
 * edge until someone buys it, then a solid block in the owner's colour in that
 * same place (data-pc: the colour of their token and their player row).
 * Houses are small icons; a mortgaged deed shows an M on its owner block. */
.k-boardbox {
  position: relative; flex: 1 1 auto; min-height: 0; min-width: 0;
  display: grid; place-items: center; container-type: size; background: var(--k-grid);
}
/* THE BOARD'S UNIT IN PX (sketch 4.1, the lag). The box was a size container and
   the board's sizes were container units (cqmin). Measured on a phone at 4x: a
   container makes every change inside it (a price tag, the clock's figure, a log
   line) restyle and lay out the whole board again, 70-140 ms each, against ~8 ms
   without one. So kit-board.js reads the box's size from a ResizeObserver and
   sets --k-bq, 1% of its smaller side in px (what 1cqmin was), and marks the box
   data-k-px; from then on the box is no container, only contained as one was
   (size, layout, style). Until then (the first frame) the units are cqmin, so
   the server-drawn board is the same either way. --k-rq is the same for the
   compressed rows (1cqw). */
.k-boardbox[data-k-px] { container-type: normal; contain: size layout style; }
.k-sq {
  --k-u: var(--k-bq, 1cqmin);
  position: relative; display: grid; width: calc(100 * var(--k-bq, 1cqmin)); height: calc(100 * var(--k-bq, 1cqmin));
  grid-template-columns: calc(var(--k-corner) * var(--k-u)) repeat(9, minmax(0, 1fr)) calc(var(--k-corner) * var(--k-u));
  grid-template-rows: calc(var(--k-corner) * var(--k-u)) repeat(9, minmax(0, 1fr)) calc(var(--k-corner) * var(--k-u));
  gap: var(--k-tile-gap); padding: var(--k-tile-gap); background: var(--k-grid);
}
/* SKETCH 4.1 (item 4): THE TILE, V3's board in the kit with richup's tile logic,
   measured from richup's screenshots (2026-10-05, 07/09/11/12, board 745 px;
   DECISIONS S41-12..): a tile is a rounded card (radius .7% of the board) on the
   board's dark ground, its country's flag washed over the whole of it (V3's
   vendored flags, the tall twin on the top and bottom rows; pre-softened PNGs,
   so no filter is painted), the name in white in the middle, the set's flag as a
   ROUND badge 3.6% of the board across, centred on the inner edge (half of it
   over the board's centre, as richup's), and on the outer edge the price in a
   small pill (58% of the tile's width) until someone buys it; then a block in
   the owner's colour, opaque and a quarter lighter in its middle (richup's
   owner block measured: the token's colour plus 18-30% white), the whole width
   of the tile, with the houses on it. The left and right columns are the same
   tile turned a quarter (text reads down, as richup's). */
.k-tile {
  --k-tilebg: var(--k-tile);
  --k-tile-r: calc(.55 * var(--k-u));     /* richup's ~5 px corners on a 745 px board */
  position: relative; display: flex; min-width: 0; min-height: 0; margin: 0; padding: 0;
  border: 0; border-radius: var(--k-tile-r); background-color: var(--k-tilebg); color: var(--k-tile-ink); cursor: pointer;
  font: 600 clamp(8px, calc(1.42 * var(--k-u)), 13px)/1.12 var(--k-sans); text-align: center; overflow: visible;
  /* a tile's size is its grid cell's, never its content's (the tracks are fixed
     or minmax(0, 1fr)), so what changes inside one tile (an owner, a token, a
     name's size) lays out that tile alone (sketch 4.1, the lag). Not paint
     contained: the round flag stands half over the inner edge. */
  contain: size layout style;
}
.k-sq > .k-tile { z-index: 1; }                 /* the flags' outer halves over the centre */
.k-tile.is-corner { contain: strict; overflow: hidden; }
.k-tile[data-flag] {
  --k-tveil: color-mix(in srgb, var(--k-tilebg) calc(100% - var(--k-tile-wash)), transparent);
  background-image: linear-gradient(var(--k-tveil), var(--k-tveil)), var(--k-fimg, none);
  background-size: 100% 100%, cover; background-position: center; background-repeat: no-repeat;
}
.k-tile.is-m { --k-tile-wash: calc(var(--k-tile-wash-m)); }
.k-tile[data-kind="railroad"] { --k-tilebg: var(--k-tile-rail); }
.k-tile[data-kind="utility"]  { --k-tilebg: var(--k-tile-util); }
.k-tile:hover, .k-tile.is-open { --k-tilebg: var(--k-tile-hover); }
.k-tile:focus-visible { outline: 2px solid var(--k-focus); outline-offset: -2px; }
.k-tile[data-side="top"]    { flex-direction: column; }
.k-tile[data-side="bottom"] { flex-direction: column-reverse; }
/* the side columns: a top tile turned a quarter, its words reading down */
.k-tile:is([data-side="left"], [data-side="right"]) { writing-mode: vertical-rl; }
.k-tile[data-side="right"] { flex-direction: column; }          /* vertical-rl: the outer edge (right) first */
.k-tile[data-side="left"]  { flex-direction: column-reverse; }  /* the outer edge (left) first */
/* richup turns its two side columns opposite ways, so every name's top faces
   the board's centre: the left column reads down, the RIGHT one UP (richup 09,
   11). Each of the right tile's words and its pill is turned half round in its
   own place (a transform: no layout changes, Board.fitNames keeps its measures);
   an owner's block keeps its rounded outer corners (drawn turned, so its radius
   is given turned). The phone's side tiles keep their level names (S41-13). */
@media (min-width: 900px) {
  .k-tile[data-side="right"]:not(.is-corner) .k-tbody > *,
  .k-tile[data-side="right"]:not(.is-corner) > .k-tag { transform: rotate(180deg); }
  .k-tile[data-side="right"]:not(.is-corner) > .k-tag[data-pc] { border-radius: var(--k-tile-r) 0 0 var(--k-tile-r); }
}
.k-tile[data-flag="br"] { --k-fimg: url("/static/img/flags/soft/br-v.png"); }
.k-tile[data-flag="br"]:is([data-side="left"], [data-side="right"]) { --k-fimg: url("/static/img/flags/soft/br.png"); }
.k-tile[data-flag="il"] { --k-fimg: url("/static/img/flags/soft/il-v.png"); }
.k-tile[data-flag="il"]:is([data-side="left"], [data-side="right"]) { --k-fimg: url("/static/img/flags/soft/il.png"); }
.k-tile[data-flag="it"] { --k-fimg: url("/static/img/flags/soft/it-v.png"); }
.k-tile[data-flag="it"]:is([data-side="left"], [data-side="right"]) { --k-fimg: url("/static/img/flags/soft/it.png"); }
.k-tile[data-flag="de"] { --k-fimg: url("/static/img/flags/soft/de-v.png"); }
.k-tile[data-flag="de"]:is([data-side="left"], [data-side="right"]) { --k-fimg: url("/static/img/flags/soft/de.png"); }
.k-tile[data-flag="cn"] { --k-fimg: url("/static/img/flags/soft/cn-v.png"); }
.k-tile[data-flag="cn"]:is([data-side="left"], [data-side="right"]) { --k-fimg: url("/static/img/flags/soft/cn.png"); }
.k-tile[data-flag="fr"] { --k-fimg: url("/static/img/flags/soft/fr-v.png"); }
.k-tile[data-flag="fr"]:is([data-side="left"], [data-side="right"]) { --k-fimg: url("/static/img/flags/soft/fr.png"); }
.k-tile[data-flag="gb"] { --k-fimg: url("/static/img/flags/soft/gb-v.png"); }
.k-tile[data-flag="gb"]:is([data-side="left"], [data-side="right"]) { --k-fimg: url("/static/img/flags/soft/gb.png"); }
.k-tile[data-flag="us"] { --k-fimg: url("/static/img/flags/soft/us-v.png"); }
.k-tile[data-flag="us"]:is([data-side="left"], [data-side="right"]) { --k-fimg: url("/static/img/flags/soft/us.png"); }
/* the outer edge: the price pill (inset .7% of the board from the edge), or the
   owner's block (the whole zone, 3.4% deep), so neither moves the name */
.k-tag {
  flex: 0 0 auto; display: grid; place-items: center; min-width: 0; min-height: 0; white-space: nowrap;
  border-radius: calc(.4 * var(--k-u)); background: var(--k-tag-bg); color: var(--k-tag-ink);
  font: 600 clamp(8px, calc(1.2 * var(--k-u)), 11px)/1 var(--k-mono); font-variant-numeric: lining-nums tabular-nums;
}
.k-tile:is([data-side="top"], [data-side="bottom"]) .k-tag { height: calc(2.2 * var(--k-u)); min-width: 58%; padding: 0 calc(.7 * var(--k-u)); }
.k-tile:is([data-side="left"], [data-side="right"]) .k-tag { width: calc(2.2 * var(--k-u)); min-height: 58%; padding: calc(.7 * var(--k-u)) 0; }
.k-tile[data-side="top"] .k-tag    { margin: calc(.7 * var(--k-u)) auto calc(.5 * var(--k-u)); }
.k-tile[data-side="bottom"] .k-tag { margin: calc(.5 * var(--k-u)) auto calc(.7 * var(--k-u)); }
.k-tile[data-side="right"] .k-tag  { margin: auto calc(.7 * var(--k-u)) auto calc(.5 * var(--k-u)); }
.k-tile[data-side="left"] .k-tag   { margin: auto calc(.5 * var(--k-u)) auto calc(.7 * var(--k-u)); }
.k-tag:empty { background: transparent; }
.k-tile:is([data-kind="chance"], [data-kind="treasure"]) .k-tag { visibility: hidden; }
/* OWNED: one block in the owner's colour, no price, its middle lit a little */
.k-tile .k-tag[data-pc] {
  align-self: stretch; margin: 0; padding: 0; min-width: 0; min-height: 0; color: transparent;
  background: radial-gradient(farthest-side, var(--k-own-hi), var(--k-own-lo)), var(--k-pc);
}
.k-tile:is([data-side="top"], [data-side="bottom"]) .k-tag[data-pc] { height: calc(3.4 * var(--k-u)); }
.k-tile:is([data-side="left"], [data-side="right"]) .k-tag[data-pc] { width: calc(3.4 * var(--k-u)); }
.k-tile[data-side="top"] .k-tag[data-pc]    { border-radius: var(--k-tile-r) var(--k-tile-r) 0 0; }
.k-tile[data-side="bottom"] .k-tag[data-pc] { border-radius: 0 0 var(--k-tile-r) var(--k-tile-r); }
.k-tile[data-side="right"] .k-tag[data-pc]  { border-radius: 0 var(--k-tile-r) var(--k-tile-r) 0; }
.k-tile[data-side="left"] .k-tag[data-pc]   { border-radius: var(--k-tile-r) 0 0 var(--k-tile-r); }
/* mortgaged: the block hatched, an M on it, the flag washed out, the name dim */
.k-tile .k-tag[data-pc].is-m {
  color: var(--k-onpc); font-weight: 700;
  background: repeating-linear-gradient(135deg, var(--k-hatch) 0 3px, transparent 3px 7px), var(--k-pc);
}
.k-tile.is-m .k-tname { color: var(--k-dim); }
/* the houses stand on the owner's block, in the colour that reads on it */
.k-tile > .k-ths { position: absolute; z-index: 1; display: flex; gap: 1px; align-items: center; justify-content: center;
                   pointer-events: none; writing-mode: horizontal-tb; }
.k-tile[data-side="top"] > .k-ths    { inset: 0 0 auto 0; height: calc(3.4 * var(--k-u)); }
.k-tile[data-side="bottom"] > .k-ths { inset: auto 0 0 0; height: calc(3.4 * var(--k-u)); }
.k-tile[data-side="right"] > .k-ths  { inset: 0 0 0 auto; width: calc(3.4 * var(--k-u)); flex-direction: column; }
.k-tile[data-side="left"] > .k-ths   { inset: 0 auto 0 0; width: calc(3.4 * var(--k-u)); flex-direction: column; }
.k-ths:empty { display: none; }
.k-house { width: calc(1.45 * var(--k-u)); height: calc(1.45 * var(--k-u)); fill: var(--k-onpc); flex: 0 0 auto; }
.k-house.is-hotel { width: calc(2.2 * var(--k-u)); height: calc(2.2 * var(--k-u)); fill: var(--k-onpc); }
/* the middle: the name (and an icon); the inner edge is left to the round flag
   and the tokens (3% of the board, a token and its gap) */
.k-tbody {
  position: relative; flex: 1 1 auto; min-width: 0; min-height: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: calc(.35 * var(--k-u));
  padding: var(--k-tb-y) var(--k-tb-x);
}
.k-tile[data-side="top"] .k-tbody    { padding-bottom: calc(var(--k-tb-in) * var(--k-u)); }
.k-tile[data-side="bottom"] .k-tbody { padding-top: calc(var(--k-tb-in) * var(--k-u)); }
.k-tile[data-side="right"] .k-tbody  { padding: var(--k-tb-x) var(--k-tb-y) var(--k-tb-x) calc(var(--k-tb-in) * var(--k-u)); }
.k-tile[data-side="left"] .k-tbody   { padding: var(--k-tb-x) calc(var(--k-tb-in) * var(--k-u)) var(--k-tb-x) var(--k-tb-y); }
.k-tname { max-inline-size: 100%; overflow: hidden; overflow-wrap: normal; word-break: normal; text-shadow: var(--k-tile-shadow); }
.k-tname.is-long { font-size: .9em; letter-spacing: -.01em; }      /* Board.fitNames: a word wider than its tile */
.k-tname.is-longer { font-size: .8em; letter-spacing: -.02em; }
.k-tic { width: calc(2.4 * var(--k-u)); height: calc(2.4 * var(--k-u)); flex: 0 0 auto;
         fill: none; stroke: var(--k-dim); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.k-tile:not(.is-corner) .k-tic { stroke: var(--k-tile-ink); opacity: .8; }
/* a card tile carries its card's colour, as richup's Treasure and Surprise */
.k-tile[data-kind="chance"]   { --k-tcard: var(--k-chance); }
.k-tile[data-kind="treasure"] { --k-tcard: var(--k-treasure); }
.k-tile:is([data-kind="chance"], [data-kind="treasure"]) .k-tname { color: var(--k-tcard); }
.k-tile:is([data-kind="chance"], [data-kind="treasure"]) .k-tic { stroke: var(--k-tcard); opacity: 1;
  width: calc(3.2 * var(--k-u)); height: calc(3.2 * var(--k-u)); }
/* the set's flag: a small chip in the set's colour (a panel's head), or, for a
   country, its flag in a circle */
.k-tflag { flex: 0 0 auto; align-self: center; width: 14px; height: 10px;
           background: var(--k-sc, transparent); box-shadow: inset 0 0 0 1px var(--k-line); }
.k-tflag[data-flag] { width: 16px; height: 16px; border-radius: 50%;
                      background: var(--k-fround) center / cover no-repeat var(--k-sc, transparent); box-shadow: 0 0 0 1px var(--k-flag-ring); }
.k-tflag[data-flag="br"] { --k-fround: url("/static/img/flags/br.svg"); }
.k-tflag[data-flag="il"] { --k-fround: url("/static/img/flags/il.svg"); }
.k-tflag[data-flag="it"] { --k-fround: url("/static/img/flags/it.svg"); }
.k-tflag[data-flag="de"] { --k-fround: url("/static/img/flags/de.svg"); }
.k-tflag[data-flag="cn"] { --k-fround: url("/static/img/flags/cn.svg"); }
.k-tflag[data-flag="fr"] { --k-fround: url("/static/img/flags/fr.svg"); }
.k-tflag[data-flag="gb"] { --k-fround: url("/static/img/flags/gb.svg"); }
.k-tflag[data-flag="us"] { --k-fround: url("/static/img/flags/us.svg"); }
/* the US canton and China's stars sit at the flag's hoist: the circle shows that end */
.k-tflag:is([data-flag="us"], [data-flag="cn"]) { background-position: 18% 50%; }
.k-tflag:not([data-set]) { visibility: hidden; }
.k-tile > .k-tflag { position: absolute; z-index: 2; margin: 0; pointer-events: none;
                     width: calc(3.6 * var(--k-u)); height: calc(3.6 * var(--k-u)); }
.k-tile > .k-tflag:not([data-flag]) { display: none; }       /* airports and utilities: their icon says it */
.k-tile[data-side="top"] > .k-tflag    { left: 50%; bottom: calc(-1.8 * var(--k-u)); transform: translateX(-50%); }
.k-tile[data-side="bottom"] > .k-tflag { left: 50%; top: calc(-1.8 * var(--k-u)); transform: translateX(-50%); }
.k-tile[data-side="right"] > .k-tflag  { top: 50%; left: calc(-1.8 * var(--k-u)); transform: translateY(-50%); }
.k-tile[data-side="left"] > .k-tflag   { top: 50%; right: calc(-1.8 * var(--k-u)); transform: translateY(-50%); }
/* THE TOKENS ON A TILE. Sketch 4.12 (item 10) stood them on the tile's inner
   edge, half over the board's centre, the round flag stepping aside and smaller
   while players stood there. SKETCH 4.2, item 7: the owner, 8 Oct, with a
   screenshot of a side tile ("San Francisco", its name area beside the round
   flag): "show were we want to try to have the player icons at on the tiles,
   unless there are over 3 players on a tile, otherwiswsw i think they should
   all fit in this area without chainging the size of anything like the flag or
   player icons and wiouth player icons overlapping." So (DECISIONS S42-31..):
   - A TILE'S TOKENS STAND IN ITS NAME AREA, INSIDE THE TILE, from the round
     flag's side toward the price or the owner's block: one beside the flag;
     two side by side; three close together (two beside the flag, the third
     in the notch between them), so up to three stand at full size clear of
     the flag, the price, the owner's block and each other; four in two rows
     of two; five or six three to a row, overlapping a little (the brief:
     "with 4 or more they may overlap a little"). The name stays whole under
     them (item 16), as on richup.
   - THE ROUND FLAG NEVER MOVES OR SHRINKS for them; a token never changes size
     for one, two, three or four.
   - The square places each token (below); the compressed rows stack them in
     rows from the flag's side up.
   - The one token's place is the lane a glide runs along (kit-board.js laneProbes).
   - A CORNER holds its tokens inside, in a band on the side toward the centre.
   --k-tkc is the size this crowd's tokens are drawn at (data-n, kit-board.js);
   --k-tkz the name area's edge on the price's side (the pill or the owner's
   block: 3.4 units); --k-tw a side tile's width (its row's share). */
.k-sq, .k-rowsbox { --k-tk: calc(3 * var(--k-u)); --k-tks: calc(2.1 * var(--k-u)); --k-tkg: max(1px, calc(.3 * var(--k-u)));
                    --k-tkp: 2px; --k-tkr: 4px;          /* the token's rim; the turn's ring */
                    --k-tkz: calc(3.4 * var(--k-u)); }
.k-sq { --k-tw: calc((74 * var(--k-u) - 12 * var(--k-tile-gap)) / 9); }
.k-ttok { --k-tkc: var(--k-tk);
          position: absolute; z-index: 3; display: flex; flex-wrap: wrap; align-items: center; align-content: flex-start;
          justify-content: center; gap: var(--k-tkg); margin: 0; padding: 0; pointer-events: none; writing-mode: horizontal-tb; }
.k-ttok .k-token { width: var(--k-tkc); height: var(--k-tkc); font-size: calc(.46 * var(--k-tkc)); writing-mode: horizontal-tb;
                   box-shadow: 0 0 0 var(--k-tkp) var(--k-panel); transition: transform var(--k-dur) ease; }
.k-ttok .k-token.is-turn { box-shadow: 0 0 0 var(--k-tkp) var(--k-panel), 0 0 0 var(--k-tkr) var(--k-accent); z-index: 1; }
.k-ttok .k-token.is-jailed { box-shadow: 0 0 0 var(--k-tkp) var(--k-panel), 0 0 0 calc(var(--k-tkr) - 1px) var(--k-neg); }
/* THE SQUARE. Each token's place is given as (--k-ax, --k-dp): across the tile from
   its middle, and its middle's depth from the tile's inner edge; each side maps
   them onto the tile (a side column's "across" is down its length). The depths,
   worked out so a token's disc and the turn's ring never reach the round flag,
   whatever stands where (the flag: 1.8 units of radius, centred on the inner
   edge):
     one        centred, beside the flag (--k-h1): the lane a glide runs along;
     two        side by side, straddling the flag, so a little nearer the edge
                (--k-h2: the two discs off-centre clear the round flag sooner,
                0.905 of the straight distance, measured for every board size);
     three      the third nested in the notch between them (--k-h3: an
                equilateral triangle, 0.866 of a row), so on a phone's 280 px
                board three stand clear of the owner's block, which a second
                row of its own would reach;
     four       two rows of two;
     five, six  three to a row (the brief: "with 4 or more they may overlap a
                little"): each as big as three fit across the tile overlapping
                by a quarter at most, the full size where that fits (a desktop
                board's); the second row no nearer the price than one token. */
.k-sq > .k-tile:not(.is-corner) > .k-ttok { inset: 0; display: block; z-index: 3;
  --k-tr: calc(var(--k-tkc) / 2); --k-fr: calc(1.8 * var(--k-u));
  --k-to: calc(var(--k-tr) + var(--k-tkg) / 2);
  --k-h1: calc(var(--k-fr) + var(--k-tkr) + .5px + var(--k-tr));
  --k-h2: calc(.905 * (var(--k-fr) + var(--k-tkr) + var(--k-tr)) + .5px);
  --k-h3: calc(var(--k-h2) + .866 * (var(--k-tkc) + var(--k-tkg))); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok > .k-token { position: absolute; --k-ax: 0px; --k-dp: var(--k-h1); }
.k-sq > .k-tile[data-side="top"]:not(.is-corner) > .k-ttok > .k-token    { left: calc(50% + var(--k-ax) - var(--k-tr)); top: calc(100% - var(--k-dp) - var(--k-tr)); }
.k-sq > .k-tile[data-side="bottom"]:not(.is-corner) > .k-ttok > .k-token { left: calc(50% + var(--k-ax) - var(--k-tr)); top: calc(var(--k-dp) - var(--k-tr)); }
.k-sq > .k-tile[data-side="left"]:not(.is-corner) > .k-ttok > .k-token   { left: calc(100% - var(--k-dp) - var(--k-tr)); top: calc(50% + var(--k-ax) - var(--k-tr)); }
.k-sq > .k-tile[data-side="right"]:not(.is-corner) > .k-ttok > .k-token  { left: calc(var(--k-dp) - var(--k-tr)); top: calc(50% + var(--k-ax) - var(--k-tr)); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok:is([data-n="2"], [data-n="3"], [data-n="4"]) > .k-token:nth-child(1) { --k-ax: calc(-1 * var(--k-to)); --k-dp: var(--k-h2); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok:is([data-n="2"], [data-n="3"], [data-n="4"]) > .k-token:nth-child(2) { --k-ax: var(--k-to); --k-dp: var(--k-h2); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok[data-n="3"] > .k-token:nth-child(3) { --k-ax: 0px; --k-dp: var(--k-h3); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok[data-n="4"] > .k-token:nth-child(3) { --k-ax: calc(-1 * var(--k-to)); --k-dp: calc(var(--k-h2) + var(--k-tkc) + var(--k-tkg)); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok[data-n="4"] > .k-token:nth-child(4) { --k-ax: var(--k-to); --k-dp: calc(var(--k-h2) + var(--k-tkc) + var(--k-tkg)); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok:is([data-n="5"], [data-n="6"]) { --k-tkc: min(var(--k-tk), calc((var(--k-tw) - 2 * var(--k-tkp)) / 2.5));
  --k-t3: min(calc(var(--k-tkc) + var(--k-tkg)), calc((var(--k-tw) - 2 * var(--k-tkp) - var(--k-tkc)) / 2));
  --k-h5: min(calc(var(--k-h1) + var(--k-tkc) + var(--k-tkg)), calc(var(--k-corner) * var(--k-u) - var(--k-tkz) - var(--k-tr) - var(--k-tkp))); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok:is([data-n="5"], [data-n="6"]) > .k-token:nth-child(1) { --k-ax: calc(-1 * var(--k-t3)); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok:is([data-n="5"], [data-n="6"]) > .k-token:nth-child(3) { --k-ax: var(--k-t3); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok[data-n="5"] > .k-token:nth-child(4) { --k-ax: calc(-.5 * var(--k-t3)); --k-dp: var(--k-h5); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok[data-n="5"] > .k-token:nth-child(5) { --k-ax: calc(.5 * var(--k-t3)); --k-dp: var(--k-h5); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok[data-n="6"] > .k-token:nth-child(4) { --k-ax: calc(-1 * var(--k-t3)); --k-dp: var(--k-h5); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok[data-n="6"] > .k-token:nth-child(5) { --k-ax: 0px; --k-dp: var(--k-h5); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok[data-n="6"] > .k-token:nth-child(6) { --k-ax: var(--k-t3); --k-dp: var(--k-h5); }
.k-sq > .k-tile:not(.is-corner) > .k-ttok:is([data-n="5"], [data-n="6"]) > .k-token.is-turn { z-index: auto; }   /* a hand of cards: each over a quarter of the one before it (the turn's ring not over the next), so every letter shows */
/* THE COMPRESSED ROWS: the name area above the flag, which stays at the tile's foot
   (--k-tkl, its middle over the foot); the tokens' rows from the flag's side up (the
   turn's ring clear of the flag), as many a row as fit across (--k-rw, a row tile's
   width: the row's, less its corner and gaps, over nine). A lone token's middle
   (--k-tkm) is the row's lane: a corner's first row of tokens stands on it too, so a
   glide keeps one height along the row. */
.k-rowsbox { --k-tkl: calc(max(calc(.4 * var(--k-u)), calc(var(--k-tkr) - 1px)) + var(--k-tk) / 2);
             --k-tkm: calc(var(--k-tkl) + 1.8 * var(--k-u) + var(--k-tkr) + .5px + var(--k-tk) / 2);   /* a lone token's middle: the glides' lane */
             --k-rw: calc((100 * var(--k-rq, 1cqw) - var(--k-rc) - 9 * var(--k-tile-gap)) / 9); }
.k-rowsbox .k-tile:not(.is-corner) > .k-ttok { left: 0; right: 0; top: var(--k-tkz); bottom: calc(var(--k-tkm) - var(--k-tk) / 2);
                                               flex-wrap: wrap-reverse; }
.k-rowsbox .k-tile > .k-tflag { bottom: calc(var(--k-tkl) - 1.8 * var(--k-u)); }   /* inside the tile, at its foot, on the lane */
.k-rowsbox .k-tile:not(.is-corner) > .k-ttok:is([data-n="5"], [data-n="6"]) { --k-tkc: min(var(--k-tk), calc((var(--k-rw) - 2 * var(--k-tkg)) / 3)); }
/* sketch 4.11 (item 6): A TOKEN ON ITS WAY, V3's glide. A copy of the token in a
   layer over the tiles (under a property card) is moved by one transform
   animation (kit-board.js Board.glide); the token itself waits, hidden but in
   its place, on the tile it lands on. In the compressed rows the layer clips:
   a token goes out at a row's end and comes in at the next row's start. */
.k-glide { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
.k-rowsbox > .k-glide { overflow: hidden; }
.k-glide > .k-token { position: absolute; left: 0; top: 0; margin: 0; box-shadow: 0 0 0 var(--k-tkp, 2px) var(--k-panel); will-change: transform; }
.k-glide > .k-token.is-turn { box-shadow: 0 0 0 var(--k-tkp, 2px) var(--k-panel), 0 0 0 var(--k-tkr, 4px) var(--k-accent); }
.k-glide > .k-token.is-jailed { box-shadow: 0 0 0 var(--k-tkp, 2px) var(--k-panel), 0 0 0 calc(var(--k-tkr, 4px) - 1px) var(--k-neg); }
.k-ttok > .k-token.is-gliding { visibility: hidden; }
/* corners: big squares. Their tokens stand inside, in a band on the side toward
   the board's centre, from the corner nearest it (sketch 4.12): GO's along its
   foot from the right, Jail's along its foot from the left, Vacation's along its
   head from the left, Go to Prison's along its head from the right; in the
   compressed rows along the foot from the right (the row's way). While players
   stand on a corner its icon and name make room for the band (--k-tkb: a row of
   tokens and its margins) and its small words step aside; an empty corner keeps
   them centred, whole. */
.k-tile.is-corner { --k-tki: max(calc(.45 * var(--k-u)), calc(var(--k-tkr) + 1px));   /* the band's inset: the turn's ring whole */
                    --k-tkb: calc(var(--k-tcc) + 2 * var(--k-tki));
                    flex-direction: column; justify-content: center; align-items: center; gap: calc(.5 * var(--k-u));
                    font-size: clamp(9px, calc(1.6 * var(--k-u)), 15px); font-weight: 600; letter-spacing: .02em; }
.k-tile.is-corner[data-tk] { padding-bottom: var(--k-tkb); }
.k-tile.is-corner[data-tk] > .k-tsub { display: none; }
.k-tile.is-corner > .k-ttok { left: var(--k-tki); right: var(--k-tki); bottom: var(--k-tki); flex-wrap: wrap-reverse; justify-content: flex-end; }
.k-rowsbox .k-tile.is-corner > .k-ttok { bottom: calc(var(--k-tkm) - var(--k-tcc) / 2); }   /* on the row's lane */
.k-rowsbox .k-tile.is-corner[data-tk] { padding-bottom: calc(var(--k-tkb) + var(--k-tkm) - var(--k-tcc) / 2 - var(--k-tki)); }
.k-sq > .k-tile.is-corner[data-tile="10"] > .k-ttok { justify-content: flex-start; }
.k-sq > .k-tile.is-corner:is([data-tile="20"], [data-tile="30"])[data-tk] { padding-bottom: 0; padding-top: var(--k-tkb); }
.k-sq > .k-tile.is-corner:is([data-tile="20"], [data-tile="30"]) > .k-ttok { top: var(--k-tki); bottom: auto; flex-wrap: wrap; }
.k-sq > .k-tile.is-corner[data-tile="20"] > .k-ttok { justify-content: flex-start; }
/* a corner's crowd: up to three in its one row (as big as three fit across the
   band, --k-tcw); four in one row; five or six in two rows of three, the band
   two rows deep. --k-tcc is the size, on the tile, so the band follows it. */
.k-tile.is-corner { --k-tcc: var(--k-tk); }
.k-sq > .k-tile.is-corner { --k-tcw: calc(var(--k-corner) * var(--k-u) - 2 * var(--k-tki));
                            --k-tcc: min(var(--k-tk), calc((var(--k-tcw) - 2 * var(--k-tkg)) / 3)); --k-tkb: calc(var(--k-tcc) + 2 * var(--k-tki)); }
.k-sq > .k-tile.is-corner[data-tk="4"] { --k-tcc: min(var(--k-tk), calc((var(--k-tcw) - 3 * var(--k-tkg)) / 4)); }
.k-tile.is-corner:is([data-tk="5"], [data-tk="6"]) { --k-tcc: var(--k-tks); --k-tkb: calc(2 * var(--k-tcc) + var(--k-tkg) + 2 * var(--k-tki)); }
/* the compressed rows' corners are as wide as they are tall (--k-rc): four in one row and
   five or six in two rows of three keep the tokens' own size where it fits (sketch 4.2,
   item 7: everyone on GO at a game's start, 9 px on a phone, not 6) */
.k-rowsbox .k-tile.is-corner[data-tk="4"] { --k-tcc: min(var(--k-tk), calc((var(--k-rc) - 2 * var(--k-tki) - 3 * var(--k-tkg)) / 4)); }
.k-rowsbox .k-tile.is-corner:is([data-tk="5"], [data-tk="6"]) { --k-tcc: min(var(--k-tk), calc((var(--k-rc) - 2 * var(--k-tki) - 2 * var(--k-tkg)) / 3)); }
.k-rowsbox .k-tile.is-corner:is([data-tk="5"], [data-tk="6"]) .k-tic { display: none; }   /* two rows of them: the name says the corner */
.k-tile.is-corner > .k-ttok { --k-tkc: var(--k-tcc); }
.k-tile.is-corner:is([data-tk="5"], [data-tk="6"]) > .k-ttok { left: auto; width: calc(3 * var(--k-tcc) + 2 * var(--k-tkg)); }
.k-sq > .k-tile.is-corner:is([data-tile="10"], [data-tile="20"]):is([data-tk="4"], [data-tk="5"], [data-tk="6"]) > .k-ttok { left: var(--k-tki); right: auto; }
.k-tile.is-corner .k-tic { width: calc(4.4 * var(--k-u)); height: calc(4.4 * var(--k-u)); stroke: var(--k-ink); }
.k-tile.is-corner .k-tsub { font: 500 clamp(7px, calc(1.05 * var(--k-u)), 10px)/1.2 var(--k-mono); color: var(--k-dim);
                            letter-spacing: .06em; text-transform: uppercase; }
.k-tile.is-go .k-tic { stroke: var(--k-accent); }

/* SKETCH 4.2, item 5: A PLAYER'S DEEDS LIT (their round badge on the Players
   list; Kit.Board.highlight): V3.21's five looks (v32-highlight.css) on the kit's
   tiles, picked in Settings > Display, default A. The board's wrap says the look
   (data-hl) and whose colour (data-hlpc: --k-hl); their tiles are .is-hl. A token
   never fades: where everyone stands stays plain while you look. Every look is
   drawn inside the tile, so the board's panel (it clips) cuts none of it.
     A Spotlight         everyone else's tiles fade right back; theirs stay as they are
     B Solid wash        their tiles fill with their colour; the rest untouched
     C Outline and glow  an outline in their colour and a soft glow inside; nothing fades
     D Lift              their tiles rise toward the centre, outlined, with a shadow; the rest dim a little
     E Colour band       their owner's block grows to a third of the tile, the round flag ringed; the rest dim a little */
.k-boardwrap[data-hlpc="sky"]    { --k-hl: var(--k-c-sky); }
.k-boardwrap[data-hlpc="green"]  { --k-hl: var(--k-c-green); }
.k-boardwrap[data-hlpc="violet"] { --k-hl: var(--k-c-violet); }
.k-boardwrap[data-hlpc="pink"]   { --k-hl: var(--k-c-pink); }
.k-boardwrap[data-hlpc="amber"]  { --k-hl: var(--k-c-amber); }
.k-boardwrap[data-hlpc="orange"] { --k-hl: var(--k-c-orange); }
.k-boardwrap[data-hl="A"] .k-tile:not(.is-hl) { --k-tilebg: color-mix(in srgb, var(--k-tile) 45%, var(--k-grid)); --k-tile-wash: 4%; }
.k-boardwrap[data-hl="A"] .k-tile:not(.is-hl) > .k-tag,
.k-boardwrap[data-hl="A"] .k-tile:not(.is-hl) > .k-ths,
.k-boardwrap[data-hl="A"] .k-tile:not(.is-hl) > .k-tbody,
.k-boardwrap[data-hl="A"] .k-tile:not(.is-hl) > .k-tflag,
.k-boardwrap[data-hl="A"] .k-tile:not(.is-hl) > .k-tic,
.k-boardwrap[data-hl="A"] .k-tile:not(.is-hl) > .k-tname,
.k-boardwrap[data-hl="A"] .k-tile:not(.is-hl) > .k-tsub { opacity: .28; }   /* a tile's parts but its tokens, each by name (a selector ending in :not() is tried on every element of the page) */
.k-boardwrap:is([data-hl="D"], [data-hl="E"]) .k-tile:not(.is-hl) { --k-tilebg: color-mix(in srgb, var(--k-tile) 75%, var(--k-grid)); }
.k-boardwrap:is([data-hl="D"], [data-hl="E"]) .k-tile:not(.is-hl) > .k-tag,
.k-boardwrap:is([data-hl="D"], [data-hl="E"]) .k-tile:not(.is-hl) > .k-ths,
.k-boardwrap:is([data-hl="D"], [data-hl="E"]) .k-tile:not(.is-hl) > .k-tbody,
.k-boardwrap:is([data-hl="D"], [data-hl="E"]) .k-tile:not(.is-hl) > .k-tflag,
.k-boardwrap:is([data-hl="D"], [data-hl="E"]) .k-tile:not(.is-hl) > .k-tic,
.k-boardwrap:is([data-hl="D"], [data-hl="E"]) .k-tile:not(.is-hl) > .k-tname,
.k-boardwrap:is([data-hl="D"], [data-hl="E"]) .k-tile:not(.is-hl) > .k-tsub { opacity: .55; }
/* B: their colour over the tile (the flag's wash under it), the name kept readable */
.k-boardwrap[data-hl="B"] .k-tile.is-hl { --k-tilebg: color-mix(in srgb, var(--k-hl) 55%, var(--k-tile)); --k-tile-wash: 0%; }
.k-boardwrap[data-hl="B"] .k-tile.is-hl .k-tname { text-shadow: 0 0 3px var(--k-bg), 0 0 1px var(--k-bg); }
/* C: inside the tile, so the board's edge rows read as the others */
.k-boardwrap[data-hl="C"] .k-tile.is-hl {
  box-shadow: inset 0 0 0 2px var(--k-hl), inset 0 0 calc(2.2 * var(--k-u)) color-mix(in srgb, var(--k-hl) 55%, transparent); }
/* D: a little bigger, grown from its outer edge toward the board's centre (never past the board's edge) */
.k-boardwrap[data-hl="D"] .k-tile.is-hl { z-index: 3; transform: scale(1.06); box-shadow: 0 0 0 2px var(--k-hl), var(--k-shadow-sm); }
.k-boardwrap[data-hl="D"] .k-tile.is-hl[data-side="top"]    { transform-origin: 50% 0; }
.k-boardwrap[data-hl="D"] .k-tile.is-hl[data-side="bottom"] { transform-origin: 50% 100%; }
.k-boardwrap[data-hl="D"] .k-tile.is-hl[data-side="left"]   { transform-origin: 0 50%; }
.k-boardwrap[data-hl="D"] .k-tile.is-hl[data-side="right"]  { transform-origin: 100% 50%; }
/* E: the owner's block a third of the tile, in their colour, and their round flag ringed */
.k-boardwrap[data-hl="E"] .k-tile.is-hl:is([data-side="top"], [data-side="bottom"]) > .k-tag[data-pc] { height: 34%; }
.k-boardwrap[data-hl="E"] .k-tile.is-hl:is([data-side="left"], [data-side="right"]) > .k-tag[data-pc] { width: 34%; }
.k-boardwrap[data-hl="E"] .k-tile.is-hl > .k-tag[data-pc]:not(.is-m) { background: var(--k-hl); }
.k-boardwrap[data-hl="E"] .k-tile.is-hl > .k-tflag { box-shadow: 0 0 0 2px var(--k-panel), 0 0 0 4px var(--k-hl); }
/* the badge of the player lit: a ring in their colour (a second tap reads as the way back) */
.k-plrow > .k-pbadge[aria-pressed="true"] > .k-token { box-shadow: 0 0 0 2px var(--k-panel), 0 0 0 4px var(--k-pc); }

/* the turn centre: dice, actions, timer, a short fading log. ANCHORED (look
   review, 6 Oct): the stack starts at a fixed height and every slot keeps its
   room when empty (the message's two lines, the clock's row in the game, the
   buttons' row), and the log is last and only shrinks, so the dice and the
   buttons never move while a turn plays; a card or an auction floats over the
   centre instead of pushing it (.k-cslot-card / -auction, below). */
.k-centre {
  grid-area: 2 / 2 / 11 / 11; position: relative; min-width: 0; min-height: 0; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: calc(1.5 * var(--k-u));
  padding: calc(14 * var(--k-u)) calc(3 * var(--k-u)) calc(3 * var(--k-u)); background: var(--k-board-centre); text-align: center;
}
/* in the square the centre's size is its grid area's, never its content's: what
   changes in it (the clock's figure, the message, the log) lays out the centre alone */
.k-sq > .k-centre { contain: strict; }
/* the centre's words, a card and an auction keep 3 units clear of the tiles at the
   sides and foot (sketch 4.12's band for a crowd's second row over the centre is
   gone with it: sketch 4.2, item 7, the tokens stand inside their tiles) */
.k-sq > .k-centre { --k-cpad: calc(3 * var(--k-u));
                    padding-left: var(--k-cpad); padding-right: var(--k-cpad); padding-bottom: var(--k-cpad); }
.k-dice { display: flex; gap: calc(1.6 * var(--k-u)); flex: 0 0 auto; }
/* the dice: V3's 3D dice (brief item 17; foundation.css .dsf-die3d, D-084), a
   cube of six faces in the die's box, turned by kit-board.js; the box never moves */
.k-die { position: relative; width: calc(7 * var(--k-u)); height: calc(7 * var(--k-u)); perspective: calc(45 * var(--k-u)); }
.k-die::after { content: ""; position: absolute; left: 12%; right: 12%; bottom: -12%; height: 14%; border-radius: 50%;
                background: radial-gradient(closest-side, var(--k-die-shadow), transparent); pointer-events: none; }
.k-die-hop, .k-die-cube { position: absolute; inset: 0; transform-style: preserve-3d; }
.k-die-cube { will-change: transform; }
.k-die-face {
  position: absolute; inset: 0; display: grid; grid-template: repeat(3, 1fr) / repeat(3, 1fr); padding: 14%;
  border-radius: 18%; background: var(--k-die); backface-visibility: hidden;
  box-shadow: inset 0 0 0 1px var(--k-die-edge), inset 0 -3px 6px var(--k-die-lo), inset 0 2px 3px var(--k-die-hi);
}
.k-die-face.f1 { transform: translateZ(calc(3.5 * var(--k-u))); }
.k-die-face.f6 { transform: rotateY(180deg) translateZ(calc(3.5 * var(--k-u))); }
.k-die-face.f2 { transform: rotateY(90deg) translateZ(calc(3.5 * var(--k-u))); }
.k-die-face.f5 { transform: rotateY(-90deg) translateZ(calc(3.5 * var(--k-u))); }
.k-die-face.f3 { transform: rotateX(90deg) translateZ(calc(3.5 * var(--k-u))); }
.k-die-face.f4 { transform: rotateX(-90deg) translateZ(calc(3.5 * var(--k-u))); }
.k-die-face > i { place-self: center; width: 74%; height: 74%; border-radius: 50%; }
.k-die-face > i.on { background: var(--k-pip); box-shadow: inset 0 1px 1px var(--k-pip-shadow); }
.k-dice.is-idle .k-die { opacity: .38; }
.k-cmsg { margin: 0; max-width: calc(62 * var(--k-bq, 1cqmin)); color: var(--k-dim); font: 500 var(--k-f-md)/1.35 var(--k-sans); flex: 0 0 auto;
          min-height: 2.7em; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.k-centre .k-cmsg[hidden] { display: -webkit-box; visibility: hidden; }
.k-cmsg b { color: var(--k-ink); font-weight: 600; }
.k-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--k-s2); min-height: var(--k-btn-h-lg); flex: 0 0 auto; }
.k-acts:empty { display: flex; visibility: hidden; }
.k-clock { display: flex; align-items: center; gap: var(--k-s2); width: min(240px, calc(36 * var(--k-bq, 1cqmin))); flex: 0 0 auto; }
.k-clock[hidden] { display: none; }
.k-app[data-k-screen="game"] .k-centre > .k-clock[hidden] { display: flex; visibility: hidden; }
.k-clock .k-bar { flex: 1 1 auto; }
.k-clock-v { font: 600 var(--k-f-sm)/1 var(--k-mono); font-variant-numeric: tabular-nums; min-width: 3.4em; text-align: right; }
.k-clock.is-warn .k-clock-v { color: var(--k-accenttext); }
.k-clock.is-crit .k-clock-v { color: var(--k-negtext); }
.k-flog { list-style: none; margin: 0; padding: 0; width: min(100%, calc(64 * var(--k-bq, 1cqmin))); display: flex; flex-direction: column; gap: 3px;
          flex: 0 1 auto; min-height: 0; max-height: calc(6 * 1.35 * var(--k-f-sm) + 15px); overflow: hidden; }
.k-flog > li { display: flex; align-items: baseline; justify-content: center; gap: 6px; min-width: 0;
               font: 400 var(--k-f-sm)/1.35 var(--k-sans); color: var(--k-ink); }
.k-flog > li > span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.k-flog > li:nth-child(2) { opacity: .78; } .k-flog > li:nth-child(3) { opacity: .58; }
.k-flog > li:nth-child(4) { opacity: .42; } .k-flog > li:nth-child(5) { opacity: .28; }
.k-flog > li:nth-child(n+6) { opacity: .16; }
.k-pdot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: var(--k-pc, var(--k-soft)); align-self: center; }

/* the property card: opens next to its tile, over the board */
.k-deed { position: absolute; z-index: 5; width: 250px; box-shadow: var(--k-shadow); }
.k-deed[hidden] { display: none; }
.k-deed .k-head .k-tflag { margin: 0; box-shadow: inset 0 0 0 1px var(--k-head-fg); }
.k-deed .k-body { gap: 2px; padding: 8px var(--k-pad) 10px; }
.k-deed .k-kv.is-now { background: var(--k-selbg); margin: 0 -6px; padding: 0 6px; }
.k-deed .k-kv.is-now .k-k { color: var(--k-ink); }
.k-deed .k-foot { padding-top: 2px; }
.k-deed .k-foot > .k-btn { padding: 0 4px; letter-spacing: .02em; min-width: max-content; }   /* BUILD · SELL · UNMORTGAGE in 250 px */
/* sketch 4.11, item 1: a card the board cannot hold (a phone browser's bars
   leave the board shorter than a street's card) floats over the screen, next to
   its tile, never cut by the board's panel (kit-board.js placeCard); one taller
   than the screen can hold packs its rent lines two to a row */
.k-deed.is-float { position: fixed; z-index: 30; }
.k-deed.is-tight { width: min(380px, calc(100vw - 8px)); }
.k-deed.is-tight > .k-body { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--k-s4); }
.k-deed.is-tight > .k-body > :not(.k-kv) { grid-column: 1 / -1; }
.k-deed-own { display: flex; align-items: center; gap: var(--k-s2); min-height: 28px; }
.k-costs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; padding-top: 6px; border-top: 1px solid var(--k-linesoft); }
.k-costs > div { display: flex; flex-direction: column; gap: 3px; align-items: center; }
.k-costs .k-v { font: 600 var(--k-f-sm)/1 var(--k-mono); }

/* the compressed view: 4 rows of 10 read like text from GO, a big corner first */
.k-rowsbox { --k-u: calc(.74 * var(--k-rq, 1cqw)); position: relative; display: flex; flex-direction: column; flex: 0 0 auto; gap: var(--k-tile-gap);
             padding: var(--k-tile-gap); background: var(--k-grid); container-type: inline-size; }
/* the rows' unit in px too (see .k-boardbox[data-k-px]); --k-rc is worked out
   here again, from --k-rq, as kit-tokens.css works it out from 1cqw */
.k-rowsbox[data-k-px] { container-type: normal; contain: inline-size layout style;
                        --k-rc: clamp(58px, calc((100 * var(--k-rq) - 9 * var(--k-tile-gap)) * 1.4 / 10.4), 150px); }
.k-rowsbox .k-tile { font-size: clamp(8px, calc(1.42 * var(--k-u)), 12px); }
/* each row starts with its corner drawn as a BIG SQUARE, 1.4 tiles wide (the
   brief; look review, 6 Oct): the corner's width is the row's height
   (capped, so a very wide panel keeps short rows; past a 1,560 px board the
   tiles then get wider than the corner) */
.k-rrow { display: grid; grid-template-columns: var(--k-rc) repeat(9, minmax(0, 1fr)); grid-template-rows: var(--k-rc);
          gap: var(--k-tile-gap); }
.k-rrow .k-tile.is-corner { gap: calc(.4 * var(--k-u)); }
.k-rrow .k-tile.is-corner .k-tic { width: calc(3.6 * var(--k-u)); height: calc(3.6 * var(--k-u)); }
.k-boardwrap { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.k-boardwrap[data-view="rows"] > .k-boardbox { display: none; }
.k-boardwrap[data-view="square"] > .k-rowsbox, .k-boardwrap[data-view="square"] > .k-strip { display: none; }
/* in the compressed view the centre's content sits in a strip under the rows */
.k-strip { --k-u: 7px; flex: 1 1 auto; min-height: 0; position: relative; display: flex; }
/* the strip is a grid with every part in its place (look review, 6 Oct): the
   dice on the left with the clock under them, the message beside the dice, the
   buttons anchored to the right edge, the log beside the clock. A buttons row
   that does not fit wraps inside its own cell. */
.k-strip > .k-centre {
  flex: 1 1 auto; grid-area: auto; display: grid; grid-template-columns: 160px minmax(0, 1fr) minmax(0, max-content);
  align-items: center; align-content: start; gap: 10px var(--k-s4); padding: 10px var(--k-pad); text-align: left;
}
.k-strip .k-dice { grid-row: 1; grid-column: 1; }
.k-strip .k-cmsg { grid-row: 1; grid-column: 2; max-width: none; }
.k-strip .k-acts { grid-row: 1; grid-column: 3; justify-content: flex-end; }
.k-strip .k-clock { grid-row: 2; grid-column: 1; align-self: start; width: 100%; }
.k-strip .k-flog { grid-row: 2; grid-column: 2 / -1; width: auto; }
.k-strip .k-flog > li { justify-content: flex-start; }
.k-strip .k-cslot { display: contents; }
.k-strip .k-cslot > :not(.k-cslot-card):not(.k-cslot-auction) { grid-row: 3; grid-column: 1 / -1; justify-self: center; }

/* a label/value row whose label is a sentence (the log) */
.k-kv--text .k-k { text-transform: none; letter-spacing: 0; color: var(--k-ink); font-family: var(--k-sans); }
.k-kv--text .k-pdot { display: inline-block; margin-right: 6px; }
.k-plist > .k-kv--text { padding: 0 var(--k-pad); }      /* the Log tab: off the panel's borders, like every kit list */
.k-empty--pad { padding: var(--k-pad); }

/* ── the colour picker (pre-lobby, over the board) ───────────────────── */
.k-swatches { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.k-swatch {
  position: relative; display: grid; place-items: center; width: 40px; height: 40px; margin: 0; padding: 0;
  border: 0; border-radius: 50%; background: var(--k-pc); color: var(--k-onpc); cursor: pointer;
  font: 700 14px/1 var(--k-sans); box-shadow: 0 0 0 2px var(--k-panel);
}
.k-swatch:hover:not([aria-disabled="true"]) { box-shadow: 0 0 0 2px var(--k-panel), 0 0 0 4px var(--k-ink); }
.k-swatch[aria-checked="true"] { box-shadow: 0 0 0 2px var(--k-panel), 0 0 0 4px var(--k-accent); }
.k-swatch.is-taken { background: transparent; color: var(--k-pc); box-shadow: inset 0 0 0 3px var(--k-pc); cursor: not-allowed; }
.k-swatch:focus-visible { outline: 2px solid var(--k-focus); outline-offset: 3px; }
.k-over { position: relative; z-index: 2; width: min(420px, 100%); }

/* a setting: a title, one plain sentence, a control on the right (richup 03) */
.k-opt { display: flex; align-items: center; gap: var(--k-s3); min-width: 0; padding: 8px 0; border-bottom: 1px solid var(--k-linesoft); }
.k-opt > .k-stack { flex: 1 1 auto; }
.k-opt-t { font: 600 var(--k-f-md)/1.25 var(--k-sans); }
.k-opt-d { font: 400 var(--k-f-sm)/1.35 var(--k-sans); color: var(--k-dim); }
.k-stepper { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.k-stepper .k-num { min-width: 4.6em; text-align: center; font-size: var(--k-f-md); }
.k-panel[hidden] { display: none; }
.k-panel.is-paged > .k-head > .k-stat { display: none; }        /* a pager in the strip takes the status's place */

/* ── chat lines (pre-lobby and game) ─────────────────────────────────── */
.k-chatlog { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; justify-content: flex-end; gap: 6px; overflow: hidden; }
.k-msg { display: flex; flex-direction: column; gap: 1px; min-width: 0; font: 400 var(--k-f-md)/1.35 var(--k-sans); overflow-wrap: anywhere; }
.k-msg .k-sub { display: flex; gap: 6px; align-items: center; }
.k-msg.is-sys { color: var(--k-dim); font-size: var(--k-f-sm); font-style: italic; }
.k-send { display: flex; gap: var(--k-s2); flex: 0 0 auto; }
.k-send .k-input { flex: 1 1 auto; }

/* ── lobby cards (the lobby search list: the one list that may scroll) ── */
.k-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
            scrollbar-color: var(--k-line) transparent; }
.k-rooms { display: flex; flex-direction: column; gap: var(--k-s2); padding: var(--k-s2) var(--k-pad) var(--k-pad); }
.k-room { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px var(--k-s4); align-items: center;
          padding: 10px var(--k-pad); background: var(--k-panelalt); border: 1px solid var(--k-linesoft); border-radius: var(--k-radius); }
.k-room:hover { border-color: var(--k-line); }
.k-room-main { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.k-room-side { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.k-seats { display: flex; gap: 4px; align-items: center; }
.k-seat { width: 16px; height: 16px; fill: none; stroke: var(--k-ink); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.k-seat.is-bot { stroke: var(--k-accenttext); }
.k-seat-free { width: 6px; height: 6px; margin: 0 5px; border-radius: 50%; background: var(--k-soft); }
.k-rules { display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; }

/* ── a page's top bar (the menu) ─────────────────────────────────────── */
.k-topbar { display: flex; align-items: center; gap: var(--k-s4); height: 44px; padding: 0 var(--k-s4); min-width: 0;
            background: var(--k-panel); border-bottom: 1px solid var(--k-line); }
.k-mark { font: 600 15px/1 var(--k-mono); letter-spacing: .02em; white-space: nowrap; color: var(--k-ink); }
.k-mark b { color: var(--k-accenttext); font-weight: 600; }
.k-hero { display: flex; flex-direction: column; gap: 4px; align-items: stretch; }
.k-hero .k-btn { height: 56px; font-size: var(--k-f-lg); }
.k-hero .k-sub { text-align: center; }
.k-links { display: flex; flex-wrap: wrap; gap: 6px var(--k-s4); font: 500 var(--k-f-xs)/1.4 var(--k-mono); letter-spacing: .06em; text-transform: uppercase; }
.k-links a { color: var(--k-dim); text-decoration: none; }
.k-links a:hover { color: var(--k-ink); text-decoration: underline; }

/* the chat bubble (half-width): chat lives behind it */
.k-bubble { display: none; }

/* ══ SCREENS: the page grids that place panels. DESKTOP ONLY. ════════════
 * Below 900 px the kit app is not drawn and the phone page is exactly as it
 * was (proof: tools/sketch/s4_phone_same.py). At 900 px and up the kit app is
 * the screen, and the legacy page's IN-FLOW regions step aside. Its overlays
 * (trade windows, the auction, the dashboards, the card popup, toasts) stay
 * as they are until step 2b rebuilds them. */
.k-app { display: none; }
@media (min-width: 900px) {
  .k-app { display: block; }
  /* `html[data-k-desk]` (base.html, on the three kit screens) is true from the
     first byte, so the legacy regions never reach a frame while the page is
     parsed (look review, 6 Oct). Only those three pages draw the kit app. (The
     `body:has(> .k-app)` fallbacks sketch 4 had here are gone, sketch 4.1: a
     :has() on <body> made every DOM write anywhere restyle from <body> down.) */
  html[data-k-desk] body > :is(.mv2-shell, .pv2-shell, .cp-intro, #tt-top, #wallet-bar, .game-container, #tt-crawl, #money-strip) { display: none; }
  html[data-k-desk], html[data-k-desk] body { overflow: hidden; background: var(--k-bg); }
  /* the page you leave stays on screen until the next kit screen is ready to
     paint, then the two cross-fade (a cross-document view transition; Chromium
     and Safari; elsewhere the page simply changes). Both pages must ask. */
  @view-transition { navigation: auto; }

  /* THE TABLE: the pre-lobby and the game share it, so Start changes contents,
     never the layout. Wide: two card columns and the board between them, the
     board a square sized from the window height (richup). */
  .k-table {
    --k-sq: min(calc(100dvh - 2 * var(--k-gap) - var(--k-head-h) - 2px),
                calc(100vw - 2 * var(--k-side-min) - 4 * var(--k-gap)));
    display: grid; height: 100vh; height: 100dvh; overflow: hidden;
    gap: var(--k-gap); padding: var(--k-gap); background: var(--k-bg);
    grid-template-columns: minmax(0, 1fr) calc(var(--k-sq) + 2px) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);
    grid-template-areas: "a board b";
  }
  .k-table > * { min-width: 0; min-height: 0; }
  .k-table > .k-col--a { grid-area: a; }
  .k-table > .k-col--b { grid-area: b; }
  .k-table > .k-col--c { grid-area: board; }
  .k-board-panel > .k-body { padding: 0; }
  .k-table .k-col--c > .k-board-panel { flex: 1 1 0; }
  .k-table .k-col--c > .k-board-panel.is-rows { flex: 0 0 auto; }
  .k-table .k-col--c > .k-rows-extra { display: none; }
  .k-table .k-col--c.is-rows > .k-rows-extra { display: flex; flex: 1 1 0; }
  .k-col > .k-panel { flex: 0 0 auto; }
  .k-col > .k-panel.k-fill { flex: 1 1 0; }

  /* THE MENU: the menu column and the lobby list side by side */
  .k-menuscr { display: grid; grid-template-rows: auto minmax(0, 1fr); height: 100vh; height: 100dvh; overflow: hidden; background: var(--k-bg); }
  .k-menugrid { display: grid; grid-template-columns: minmax(340px, 400px) minmax(0, 1fr); gap: var(--k-gap); padding: var(--k-gap); min-height: 0; }
  .k-menugrid > * { min-height: 0; min-width: 0; }
}
/* HALF-WIDTH (a window on half a 1920 screen): the board on the left with the
   room's card under it, one card column on the right, chat behind a bubble. */
@media (min-width: 900px) and (max-width: 1279px) {
  .k-table {
    --k-sq: min(calc(100dvh - 3 * var(--k-gap) - var(--k-head-h) - 2px - 132px),
                calc(100vw - var(--k-side-half) - 3 * var(--k-gap)));
    grid-template-columns: calc(var(--k-sq) + 2px) minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas: "board b" "a b";
  }
  .k-table .k-col--c > .k-board-panel { flex: 0 0 auto; height: calc(var(--k-sq) + var(--k-head-h) + 2px); }
  .k-table .k-col--c > .k-board-panel.is-rows { height: auto; }
  .k-table .k-col--c.is-rows > .k-rows-extra { display: none; }
  .k-table .k-col--a { flex-direction: row; }
  .k-table .k-col--a > .k-panel { flex: 1 1 0; }
  /* a panel as tall as its content (You) takes the row's height here and pages
     what does not fit (s4-game.js fitYou), so nothing is cut */
  .k-table .k-col--a > .k-panel > .k-body.k-body--fit { flex: 1 1 auto; }
  .k-table .k-col--a > .k-chatpanel {
    position: fixed; right: var(--k-s4); bottom: 72px; z-index: 40; width: min(360px, calc(100vw - 32px)); height: min(440px, 62vh); height: min(440px, 62dvh);
    box-shadow: var(--k-shadow); display: none;
  }
  .k-app.is-chat-open .k-table .k-col--a > .k-chatpanel { display: flex; }
  /* the pre-lobby: the room's Chat sits in flow beside Share this room, under
     the board, instead of behind the bubble (look review, 6 Oct) */
  .k-app[data-k-screen="room"] .k-table .k-col--a > .k-chatpanel {
    position: static; display: flex; flex: 1.6 1 0; width: auto; height: auto; box-shadow: none; z-index: auto;
  }
  .k-app[data-k-screen="room"] .k-bubble { display: none; }
  .k-app[data-k-screen="room"] .k-table .k-col--a > .k-panel:not(.k-chatpanel) > .k-head > .k-stat { display: none; }  /* the code is in the link */
  /* overflow: visible (sketch 4.1, S41-71): theme.css clips every button (`body, button, ...
     { overflow-x: hidden }`), which cut the unread count on the bubble's corner along its
     round edge */
  .k-bubble {
    position: fixed; right: var(--k-s4); bottom: var(--k-s4); z-index: 41; display: grid; place-items: center;
    width: 48px; height: 48px; margin: 0; padding: 0; border: 1px solid var(--k-accentedge); border-radius: 50%;
    background: var(--k-accentbg); color: var(--k-onaccent); cursor: pointer; box-shadow: var(--k-shadow-sm);
    overflow: visible;
  }
  /* the toasts stand above the bubble, not on it (S41-71) */
  .k-toasts { bottom: calc(var(--k-s4) + 48px + var(--k-s2)); }
  .k-bubble svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; }
  .k-bubble .k-badge { position: absolute; top: -3px; right: -3px; background: var(--k-inv); color: var(--k-invtext); }
  .k-menugrid { grid-template-columns: minmax(320px, 360px) minmax(0, 1fr); }
}

/* ══ STEP 2b: THE SCREENS IN THE GAME ════════════════════════════════════
 * Still the kit: tokens only, no !important, no colour of its own. Every
 * in-game window is a kit panel or a kit dialog drawn by the screen scripts
 * (s4-game.js, s4-trade.js, s4-desks.js, s4-end.js); the game's own
 * controllers keep running underneath and the kit presses their buttons. */

/* the legacy windows step aside on desktop (S4-32): the kit draws each one.
   visibility, not display, so their own code still measures and runs. */
@media (min-width: 900px) {
  /* #reconnect-loading-overlay (look review, 6 Oct): the board's centre says
     "Joining the game…" or "Reconnecting…" instead, and the table is inert
     while it would be up (s4-game.js), as the legacy overlay made the page. */
  html[data-k-desk] body > :is(#trade-screen-overlay, #trade-modal, #b5-dash, #b6-stocks, #b7-bonds,
                           #game-over-overlay, #v2-raise-sheet, #toast-container, #card-popup, #auction-modal,
                           #reconnect-loading-overlay) {
    visibility: hidden; pointer-events: none;
  }
  /* the name step is a kit card over the board (s4-table.js); the legacy dialog
     is hidden only once the kit has taken it over (made it non-modal and
     marked it), so a page whose kit script failed still shows its own prompt */
  html[data-k-desk] body > #name-prompt-modal[data-k-took] { visibility: hidden; pointer-events: none; }
  .k-app.is-joining.is-rejoin .k-col--a, .k-app.is-joining.is-rejoin .k-col--b { opacity: .55; transition: opacity var(--k-dur) ease; }
}
@media (min-width: 900px) and (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation-duration: 0s; }
}

/* ── dialogs as panels: one panel fills the dialog, nothing in it scrolls ── */
dialog.k-modal > .k-panel { flex: 1 1 auto; min-height: 0; border: 0; border-radius: 0; }
dialog.k-modal--trade { width: min(1240px, calc(100vw - 32px)); height: min(860px, calc(100vh - 32px)); height: min(860px, calc(100dvh - 32px)); }
dialog.k-modal--pick { width: min(560px, calc(100vw - 32px)); height: fit-content; max-height: min(720px, calc(100vh - 32px)); max-height: min(720px, calc(100dvh - 32px)); }
dialog.k-modal--quick { width: min(820px, calc(100vw - 32px)); height: min(600px, calc(100vh - 32px)); height: min(600px, calc(100dvh - 32px)); }
dialog.k-modal--desk { width: min(1320px, calc(100vw - 32px)); height: min(860px, calc(100vh - 32px)); height: min(860px, calc(100dvh - 32px)); }
dialog.k-modal--mid { width: min(640px, calc(100vw - 32px)); }
/* as tall as its content: fit-content, not auto, because a modal dialog is fixed
   with top and bottom 0, where auto stretches it to the window */
dialog.k-modal--fit { height: fit-content; max-height: min(820px, calc(100vh - 32px)); max-height: min(820px, calc(100dvh - 32px)); }
dialog.k-modal--offer { width: min(860px, calc(100vw - 32px)); max-height: min(760px, calc(100vh - 32px)); max-height: min(760px, calc(100dvh - 32px)); }
.k-dgrid { display: grid; gap: var(--k-gap); min-height: 0; min-width: 0; flex: 1 1 auto; padding: var(--k-gap); background: var(--k-bg); }
.k-dgrid > * { min-height: 0; min-width: 0; }
.k-panel.k-inner { border-color: var(--k-linesoft); }
.k-panel.k-inner > .k-head { background: var(--k-panelalt); color: var(--k-ink); --k-head-bg: var(--k-panelalt); --k-head-fg: var(--k-ink); }
.k-panel.k-inner > .k-head .k-stat { color: var(--k-dim); }
.k-panel.k-inner > .k-head .k-ibtn:hover, .k-panel.k-inner > .k-head > .k-tabs .k-tab:hover { background: var(--k-selbg); color: var(--k-ink); }
.k-panel.k-inner > .k-head > .k-tabs .k-tab { color: var(--k-dim); }
.k-panel.k-inner > .k-head > .k-tabs .k-tab[aria-selected="true"] { background: var(--k-panel); color: var(--k-ink); }
.k-panel.k-inner > .k-head .k-pager { color: var(--k-dim); }
.k-panel.k-inner > .k-head .k-pager > button { border-color: var(--k-line); color: var(--k-ink); }
.k-foot.k-foot--bar { align-items: center; padding: 10px var(--k-pad); border-top: 1px solid var(--k-line); background: var(--k-panel); }
.k-foot.k-foot--bar > .k-btn { flex: 0 0 auto; }
.k-foot .k-say { flex: 1 1 auto; min-width: 0; font: 400 var(--k-f-sm)/1.35 var(--k-sans); color: var(--k-dim);
                 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.k-foot .k-say.is-err { color: var(--k-negtext); }
.k-foot .k-say.is-ok { color: var(--k-postext); }

/* partner tabs in a strip: a token dot and the name */
.k-head > .k-tabs .k-tab .k-pdot { margin-right: 2px; }
.k-head > .k-tabs .k-tab[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }

/* ── deed chips (the quick trade, the full composer's Deeds tab) ────────── */
.k-chips { display: flex; flex-wrap: wrap; gap: 6px; align-content: flex-start; min-height: 0; }
.k-chip.k-deedchip { height: 30px; padding: 0 9px 0 7px; gap: 7px; text-transform: none; letter-spacing: 0;
                     font: 500 var(--k-f-md)/1 var(--k-sans); }
.k-deedchip::before { content: ""; width: 8px; height: 14px; flex: 0 0 auto; background: var(--k-sc, var(--k-soft)); }
.k-deedchip .k-v { font: 600 var(--k-f-xs)/1 var(--k-mono); color: var(--k-dim); }
.k-deedchip.is-on { background: var(--k-accentsoft); border-color: var(--k-accentedge); }
.k-deedchip.is-on .k-v { color: var(--k-ink); }
.k-deedchip[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.k-deedchip .k-mtag { font: 700 var(--k-f-xs)/1 var(--k-mono); color: var(--k-negtext); }

/* the quick trade: two sides and the swap mark between them (richup 19-20) */
.k-tq { display: grid; grid-template-columns: minmax(0, 1fr) 34px minmax(0, 1fr); gap: var(--k-gap); flex: 1 1 auto; min-height: 0; }
.k-tq > * { min-height: 0; min-width: 0; }
.k-swapmark { display: grid; place-items: center; align-self: stretch; border-radius: var(--k-radius); background: var(--k-panelalt);
              color: var(--k-dim); font: 600 16px/1 var(--k-mono); }
.k-tside .k-body { gap: 10px; }
.k-tside-who { display: flex; align-items: center; gap: var(--k-s2); min-width: 0; }
.k-cashpick { display: flex; flex-direction: column; gap: 6px; }
.k-cashpick .k-line { justify-content: space-between; }
.k-cashpick .k-v { font: 600 var(--k-f-lg)/1 var(--k-mono); }
.k-quickamts { display: flex; gap: 4px; flex-wrap: wrap; }

/* lists of offer lines (give / get) */
.k-oline { display: flex; align-items: center; gap: var(--k-s2); min-height: 40px; padding: 4px var(--k-pad) 4px calc(var(--k-pad) + var(--k-mark-w));
           position: relative; border-bottom: 1px solid var(--k-linesoft); }
.k-oline::before { content: ""; position: absolute; left: 0; top: 6px; bottom: 6px; width: var(--k-mark-w); background: var(--k-sc, var(--k-line)); }
.k-oline .k-stack { flex: 1 1 auto; }
.k-oline .k-name { font-size: var(--k-f-md); }
.k-oline .k-sub { white-space: normal; }
.k-ocols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); flex: 1 1 auto; min-height: 0; }
.k-ocols > div { display: flex; flex-direction: column; min-height: 0; min-width: 0; overflow: hidden; }
.k-ocols > div + div { border-left: 1px solid var(--k-line); }
.k-ocol-h { display: flex; align-items: center; gap: var(--k-s2); flex: 0 0 auto; height: 28px; padding: 0 var(--k-pad);
            border-bottom: 1px solid var(--k-line); font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .08em; text-transform: uppercase; }
.k-ocol-h.is-give { color: var(--k-negtext); }
.k-ocol-h.is-get { color: var(--k-postext); }
.k-ocol-h .k-pager { margin-left: auto; }
.k-olist { flex: 1 1 auto; min-height: 0; overflow: hidden; }

/* validation and disclosure lines, one style (the desktop's task rows) */
.k-msgs { display: flex; flex-direction: column; gap: 4px; flex: 0 0 auto; }
.k-mline { display: flex; gap: 8px; align-items: baseline; padding: 5px 8px 5px 10px; border-left: var(--k-mark-w) solid var(--k-line);
           background: var(--k-well); font: 400 var(--k-f-sm)/1.4 var(--k-sans); color: var(--k-ink); }
.k-mline.is-err  { border-left-color: var(--k-neg); }
.k-mline.is-warn { border-left-color: var(--k-accent); }
.k-mline.is-ok   { border-left-color: var(--k-pos); color: var(--k-dim); }

/* a legacy term form, drawn in the kit (S4-34) */
.k-form { display: flex; flex-direction: column; gap: 0; min-height: 0; overflow: hidden; flex: 1 1 auto; }
.k-frow { display: flex; align-items: center; gap: var(--k-s3); min-height: 38px; padding: 4px 0; border-bottom: 1px solid var(--k-linesoft); min-width: 0; }
.k-frow > .k-flab { flex: 0 0 34%; min-width: 0; display: flex; flex-direction: column; gap: 2px;
                    font: 500 var(--k-f-sm)/1.25 var(--k-mono); letter-spacing: .04em; text-transform: uppercase; color: var(--k-dim); }
.k-frow > .k-flab .k-sub { text-transform: none; }
.k-frow > .k-fctl { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; justify-content: flex-end; }
.k-frow > .k-fctl .k-input { width: 120px; }
.k-frow.is-stack { flex-direction: column; align-items: stretch; }
.k-frow.is-stack > .k-flab { flex: 0 0 auto; }
.k-frow.is-stack > .k-fctl { justify-content: flex-start; }
.k-fhd { display: flex; align-items: center; gap: var(--k-s2); min-height: 26px; padding: 8px 0 2px; font: 600 var(--k-f-xs)/1.2 var(--k-mono);
         letter-spacing: .08em; text-transform: uppercase; color: var(--k-ink); }
.k-fhd > span + span { margin-left: auto; color: var(--k-dim); }
.k-fprose { margin: 0; padding: 6px 0; font: 400 var(--k-f-sm)/1.45 var(--k-sans); color: var(--k-dim); }
.k-fkv { display: flex; align-items: baseline; gap: var(--k-s2); min-height: 28px; padding: 3px 0; border-bottom: 1px solid var(--k-linesoft);
         font: 400 var(--k-f-md)/1.3 var(--k-sans); }
.k-fkv > .k-v { margin-left: auto; font: 600 var(--k-f-md)/1 var(--k-mono); font-variant-numeric: tabular-nums; }
.k-fkv > .k-v.is-up { color: var(--k-postext); }
.k-fkv > .k-v.is-down { color: var(--k-negtext); }
.k-fsays { margin: 8px 0 2px; padding: 8px 10px; border-left: var(--k-mark-w) solid var(--k-accent); background: var(--k-well);
           font: 400 var(--k-f-sm)/1.45 var(--k-sans); }
.k-fsays b { display: block; margin-bottom: 3px; font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--k-dim); }
.k-fpick { display: flex; align-items: center; gap: var(--k-s2); width: 100%; min-height: 32px; margin: 0; padding: 3px 6px;
           border: 0; border-bottom: 1px solid var(--k-linesoft); background: transparent; color: var(--k-ink); cursor: pointer; text-align: left;
           font: 400 var(--k-f-md)/1.3 var(--k-sans); }
.k-fpick:hover { background: var(--k-selbg); }
.k-fpick .k-v { margin-left: auto; font: 500 var(--k-f-sm)/1 var(--k-mono); color: var(--k-dim); }
.k-fpick.is-on { background: var(--k-accentsoft); }
.k-check { flex: 0 0 auto; display: inline-grid; place-items: center; width: 14px; height: 14px; border: 1px solid var(--k-line); background: var(--k-well);
           font: 700 10px/1 var(--k-mono); color: var(--k-onaccent); }
.k-fpick.is-on .k-check { background: var(--k-accent); border-color: var(--k-accentedge); }
.k-fpick.is-radio .k-check { border-radius: 50%; }
.k-fsw { flex: 0 0 auto; width: 10px; height: 10px; background: var(--k-sc, var(--k-soft)); }
.k-fchips { display: flex; flex-wrap: wrap; gap: 4px; padding: 4px 0; }

/* ── the before/after table: every number for both players (the Leverage numbers) ── */
.k-itab { display: grid; grid-template-columns: minmax(96px, 1.1fr) repeat(2, minmax(0, 1fr)); flex: 0 0 auto;
          font: 400 var(--k-f-sm)/1.3 var(--k-mono); font-variant-numeric: lining-nums tabular-nums; }
.k-itab > div { display: flex; align-items: center; gap: 6px; min-height: 24px; padding: 2px 6px; border-bottom: 1px solid var(--k-linesoft); min-width: 0; white-space: nowrap; }
.k-itab > .k-ih { font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--k-dim); }
.k-itab > .k-ih .k-pdot { margin-right: 2px; }
.k-itab > .k-ik { color: var(--k-dim); font-family: var(--k-sans); }
.k-itab > .k-iv { justify-content: flex-end; }
.k-itab .k-ib { color: var(--k-dim); }
.k-itab .k-ia { font-weight: 600; color: var(--k-ink); }
.k-itab .k-ic { min-width: 3.6em; text-align: right; }
.k-itab .k-ic.is-up { color: var(--k-postext); }
.k-itab .k-ic.is-down { color: var(--k-negtext); }

/* ── the side panels in the game ─────────────────────────────────────── */
.k-players .k-row .k-chip { height: 18px; padding: 0 5px; }
.k-row .k-why { font: 400 var(--k-f-xs)/1.2 var(--k-mono); color: var(--k-dim); }
.k-group { display: flex; align-items: center; gap: var(--k-s2); min-height: 26px; padding: 6px var(--k-pad) 2px;
           font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--k-ink); }
.k-group .k-set { width: 10px; height: 10px; }
.k-group .k-sub { margin-left: auto; letter-spacing: .04em; }
.k-group.is-whole .k-sub { color: var(--k-accenttext); }
.k-row--deed { min-height: 30px; padding-top: 2px; padding-bottom: 2px; font-size: var(--k-f-md); }
.k-row--deed .k-name { font-weight: 500; }
.k-offer-row .k-sub { white-space: nowrap; }
.k-tagline { display: flex; gap: 6px; align-items: center; }
/* SKETCH 4.2, item 4: a deed that cannot be put on the offer (rented, a pledged set the
   host locked, a set with houses on it) looks it, and says why (its tooltip; a tap on a
   phone, s4-trade.js); a built set's head says "sell its houses first" */
.k-fpick[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }
.k-group.is-built .k-sub { color: var(--k-warntext); }
/* SKETCH 4.2, items 5 and 6: A PLAYER'S ROW, three buttons in the row's own box
   (its colour mark, the turn's background): the round initial badge (it lights
   their deeds on the board), the rest of the row (the trade, as before) and,
   while the server allows the vote, Remove. A press on the row's padding is
   the trade's too (s4-game.js drawPlayers). */
.k-plrow { gap: 10px; cursor: pointer; }
.k-plrow:hover { background: var(--k-selbg); }
/* the badge: the round token (28 px) in a 40 px button, a thumb's room round it; the
   row keeps its spacing (the button's extra 12 px are taken back by its margins) */
.k-plrow > .k-pbadge { flex: 0 0 auto; display: grid; place-items: center; width: 40px; height: 40px; margin: -6px;
                      padding: 0; border: 0; border-radius: 50%; background: transparent; color: inherit; cursor: pointer; }
.k-plrow > .k-pbadge:focus-visible { outline: 2px solid var(--k-focus); outline-offset: -4px; }
.k-plrow > .k-pmain {
  flex: 1 1 auto; display: flex; align-items: center; gap: 10px; min-width: 0; align-self: stretch;
  margin: 0; padding: 0; border: 0; background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer;
  overflow: visible;
}
.k-plrow > .k-pmain:focus-visible { outline: 2px solid var(--k-focus); outline-offset: -2px; }
.k-plrow > .k-prm { flex: 0 0 auto; margin-left: -2px; padding: 0 6px; letter-spacing: .03em; }   /* a narrow desktop column keeps the name's chip whole */

/* the board centre while you are in debt */
.k-debtnote { max-width: calc(60 * var(--k-bq, 1cqmin)); }
/* the debt notice: the Players strip turns red (s4-game.js), the same height */
.k-panel.is-debt > .k-head { --k-head-bg: var(--k-negtext); --k-head-fg: var(--k-panel); --k-head-soft: var(--k-panel); }
.k-panel.is-debt > .k-head > .k-title { letter-spacing: .08em; }

/* sketch 4.1: A SWITCH IN A STRIP, a word and a small switch in the strip's
   own colours (the desktop's square switch); on, the switch takes the accent.
   Item 2: the game's Auto-play (Players strip); item 15: the pre-lobby's
   Spectate only (Players strip). In debt the strip is the notice, so the word
   steps aside and the switch stays. */
.k-hsw {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
  height: calc(var(--k-head-h) - 8px); margin: 0; padding: 0 5px 0 6px;
  border: 0; border-radius: var(--k-radius); background: transparent; color: var(--k-head-fg); cursor: pointer;
  font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
}
.k-hsw-t { position: relative; flex: 0 0 auto; width: 26px; height: 14px; border: 1px solid var(--k-head-fg); border-radius: var(--k-radius); }
.k-hsw-t::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 8px; height: 8px;
  background: var(--k-head-fg); transition: transform var(--k-dur), background var(--k-dur);
}
.k-hsw[aria-checked="true"] .k-hsw-t { background: var(--k-accentbg); border-color: var(--k-accentedge); }
.k-hsw[aria-checked="true"] .k-hsw-t::after { transform: translateX(12px); background: var(--k-onaccent); }
.k-hsw:hover { background: var(--k-head-fg); color: var(--k-head-bg); }
.k-hsw:hover .k-hsw-t { border-color: var(--k-head-bg); }
.k-hsw:hover .k-hsw-t::after { background: var(--k-head-bg); }
.k-hsw[aria-checked="true"]:hover .k-hsw-t::after { background: var(--k-onaccent); }
.k-hsw:focus-visible { outline: 2px solid var(--k-focus); outline-offset: -2px; }
.k-hsw:disabled { opacity: .45; cursor: not-allowed; }
.k-hsw:disabled:hover { background: transparent; color: var(--k-head-fg); }
.k-hsw:disabled:hover .k-hsw-t { border-color: var(--k-head-fg); }
.k-hsw:disabled:hover .k-hsw-t::after { background: var(--k-head-fg); }
.k-panel.is-debt .k-hsw-l { display: none; }
@media (prefers-reduced-motion: reduce) { .k-hsw-t::after { transition: none; } }
/* Settings -> Auto-play: V3's options, its trade filters under Auto-accept */
.k-autokinds { flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.k-autokinds > .k-btn { margin-left: 2px; flex: 0 0 auto; }
.k-reserve { width: 5.4em; height: var(--k-btn-h-sm); padding: 0 6px; text-align: center; -moz-appearance: textfield; }
.k-reserve::-webkit-inner-spin-button, .k-reserve::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }

/* sketch 4.11, item 5: AUTO-PLAY'S OPTIONS, ONE TAP FROM THE SWITCH. The caret
   sits against the AUTO switch (the two read as one control) and opens every
   option, AUTO on or off: a drop-down from the Players strip on desktop, a
   sheet standing on the turn buttons on a phone (s4-game.js placeAutoPop). */
.k-hsw-more {
  flex: 0 0 auto; display: inline-grid; place-items: center;
  width: 22px; height: calc(var(--k-head-h) - 8px); margin: 0 0 0 calc(2px - var(--k-s2)); padding: 0;
  border: 0; border-radius: var(--k-radius); background: transparent; color: var(--k-head-fg); cursor: pointer;
}
html[data-k-phone] .k-hsw-more { height: calc(var(--k-head-h) - 4px); }     /* a thumb's target: the strip's height */
.k-hsw-more:hover, .k-hsw-more[aria-expanded="true"] { background: var(--k-head-fg); color: var(--k-head-bg); }
.k-hsw-more:focus-visible { outline: 2px solid var(--k-focus); outline-offset: -2px; }
.k-chev { width: 10px; height: 6px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.k-hsw-more[aria-expanded="true"] .k-chev { transform: rotate(180deg); }
/* A STRIP'S WORDS IN TWO PARTS, the second stepping aside where the strip is
   narrow, with no measuring: it wraps onto a second line the strip never shows.
   The Players strip: "4" + " · turn 9" (the You strip has the turn too), and in
   debt "● $1,234" + " in debt". Its title gives way only in debt. */
.k-head > .k-drop { display: inline-flex; flex-wrap: wrap; align-content: flex-start; align-items: flex-start;
                    height: 1.3em; min-width: 0; overflow: hidden; }
.k-head > .k-drop[hidden] { display: none; }
.k-head > .k-drop > span { white-space: pre; line-height: 1.3; }
.k-players > .k-head > .k-stat.k-drop { flex: 0 100 auto; }
.k-players:not(.is-debt) > .k-head > .k-title { flex-shrink: 0; }
/* a phone's strip holds the pager too: its gaps are a little closer */
html[data-k-phone] .k-players > .k-head { gap: 6px; }
html[data-k-phone] .k-players > .k-head > .k-hsw-more { margin-left: -4px; }
/* the drop-down: the game's own layer (a popover), placed by the page */
.k-autopop {
  position: fixed; inset: auto; z-index: var(--k-z-menu); margin: 0; padding: 0; overflow: hidden;
  border: 1px solid var(--k-line); border-radius: var(--k-radius);
  background: var(--k-panel); color: var(--k-ink); box-shadow: var(--k-shadow);
  font: 400 var(--k-f-md)/1.4 var(--k-sans);
}
.k-autopop > .k-panel { border: 0; border-radius: 0; }
.k-autopop > .k-panel > .k-body { padding: 0 var(--k-pad) 4px; }
/* the options (the drop-down and Settings -> Auto-play): AUTO itself first */
.k-autoopts { display: flex; flex-direction: column; min-width: 0; }
.k-autoopts > .k-opt { padding: 6px 0; }
.k-autoopts > label.k-opt { cursor: pointer; }
.k-autoopts > .k-opt:last-child { border-bottom: 0; }
.k-autoopts > .k-automaster { padding: 8px 0; }
.k-automaster .k-opt-t { font-size: var(--k-f-lg); }
/* each one's state in a word (V3's ON / OFF; PAUSED while AUTO is off) */
.k-autoword {
  flex: 0 0 auto; min-width: 4.4em; text-align: right;
  font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--k-soft);
}
.k-autoopts.is-on > .k-automaster .k-autoword, .k-autorow[data-k-state="on"] .k-autoword { color: var(--k-accenttext); }
.k-autorow[data-k-state="paused"] .k-autoword { color: var(--k-dim); }
/* ticked while AUTO is off: the switch is on, in the quiet ink, not the accent (it waits) */
.k-autorow[data-k-state="paused"] .k-switch:checked { background: var(--k-well); border-color: var(--k-dim); }
.k-autorow[data-k-state="paused"] .k-switch:checked::after { background: var(--k-dim); }
/* the filters belong to Auto-accept: under it, one rule for the two */
.k-autoopts > .k-autorow[data-k-key="autoAcceptTrades"] { border-bottom: 0; padding-bottom: 2px; }
.k-autoopts > .k-autokinds { margin: 0; padding: 2px 0 8px; border-bottom: 1px solid var(--k-linesoft); }
/* where the sentences do not fit (a phone with its browser's bars): the names */
.k-autoopts.is-compact > .k-opt { min-height: 34px; padding: 4px 0; }
.k-autoopts.is-compact > .k-autorow .k-opt-d, .k-autoopts.is-compact > .k-autoreserve .k-opt-d { display: none; }
.k-autoopts.is-compact > .k-automaster { padding: 6px 0; }
.k-autoopts.is-compact > .k-autokinds { padding-bottom: 5px; }
.k-autoopts.is-compact .k-long { display: none; }
.k-autoopts.is-compact .k-short { display: inline; }
/* and on a phone on its side, where even the names are taller than the screen: two columns */
.k-autoopts.is-two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--k-s5); }
.k-autoopts.is-two > :is(.k-automaster, .k-autokinds, .k-autoreserve) { grid-column: 1 / -1; }
.k-autoopts.is-two > .k-autorow[data-k-key="autoAcceptTrades"] { border-bottom: 1px solid var(--k-linesoft); padding-bottom: 4px; }
.k-autoopts.is-two > .k-autokinds { padding-top: 5px; }

/* ── the market list (Market tab, the stock desk) ─────────────────────── */
.k-mrow { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto auto; align-items: center; gap: 8px;
          width: 100%; min-height: 40px; margin: 0; padding: 3px var(--k-pad) 3px calc(var(--k-pad) + var(--k-mark-w)); position: relative;
          border: 0; border-bottom: 1px solid var(--k-linesoft); background: transparent; color: var(--k-ink); text-align: left; cursor: pointer;
          font: 400 var(--k-f-md)/1.25 var(--k-sans); }
.k-mrow::before { content: ""; position: absolute; left: 0; top: 5px; bottom: 5px; width: var(--k-mark-w); background: var(--k-pc, transparent); }
.k-mrow:hover { background: var(--k-selbg); }
.k-mrow.is-current { background: var(--k-selbg); }
.k-mrow.is-current::before { top: 0; bottom: 0; }
.k-tick { font: 700 var(--k-f-sm)/1 var(--k-mono); letter-spacing: .04em; }
.k-mrow .k-num { font-size: var(--k-f-md); }
.k-mchips { gap: 4px; }
.k-mrow .k-chip { height: 16px; padding: 0 4px; font-size: 9px; letter-spacing: .04em; }
/* sketch 4.2, item 8: a phone's Market tab in the stock desk: the stocks (paged) over the picked one's
   chart and its Buy and Sell; the list takes what the chart and the ticket leave */
.k-pmarket > .k-body { display: flex; flex-direction: column; min-height: 0; }
.k-pmlist { flex: 1 1 0; min-height: 44px; display: flex; flex-direction: column; overflow: hidden; }
.k-pmbar { flex: 0 0 auto; }
.k-pmbar .k-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.k-pmarea { flex: 0 0 auto; display: flex; flex-direction: column; gap: 6px; padding: 6px var(--k-pad) var(--k-pad); }
.k-pmarea.is-trades { flex: 1 1 0; min-height: 0; padding: 0; }
.k-pmarea.is-trades > .k-plist { flex: 1 1 0; min-height: 0; }
.k-pmarea .k-headline { display: flex; align-items: baseline; gap: 8px; }
.k-chartbox.k-pmchart { height: clamp(84px, 16vh, 190px); height: clamp(84px, 16dvh, 190px); min-height: 0; flex: 0 0 auto; }
.k-pmticket { display: flex; flex-direction: column; gap: 6px; }
html[data-k-phone] .k-pmticket .k-amt { height: 40px; gap: 1px; }
.k-pmarket .k-panebar.k-pmbar { min-height: 40px; margin: 0; padding-right: var(--k-pad); }
.k-pmwho { min-width: 0; gap: 1px; }
.k-pmwho .k-line { gap: 8px; min-width: 0; }
.k-pmwho .k-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.k-chartbox.k-mchart { min-height: 0; margin: 0 var(--k-pad) var(--k-pad); }      /* the Market tab's chart: the free space under the list */
.k-spark { width: 64px; height: 20px; }
.k-spark path { fill: none; stroke: var(--k-pc, var(--k-ink)); stroke-width: 1.4; }

/* ── the desks (stocks, bonds, Leverage) ──────────────────────────────── */
.k-deskgrid { grid-template-columns: minmax(300px, 0.9fr) minmax(0, 1.6fr); grid-template-rows: minmax(0, 1fr); }
.k-deskgrid--3 { grid-template-columns: minmax(280px, 0.9fr) minmax(0, 1.6fr); grid-template-rows: minmax(0, 1fr) auto; }
.k-chartbox { position: relative; flex: 1 1 auto; min-height: 120px; min-width: 0; }
.k-ticket { display: grid; grid-template-columns: 54px repeat(4, minmax(0, 1fr)); gap: 6px; align-items: stretch; }
.k-ticket > .k-label { align-self: center; }
.k-amt { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; height: 52px; padding: 0 4px;
         border: 1px solid var(--k-line); border-radius: var(--k-radius); background: transparent; color: var(--k-ink); cursor: pointer;
         font: 600 var(--k-f-md)/1 var(--k-mono); }
.k-amt .k-sub { font-size: var(--k-f-xs); }
.k-amt:hover:not([aria-disabled="true"]) { background: var(--k-selbg); }
.k-amt.is-pos { border-color: var(--k-postext); }
.k-amt.is-neg { border-color: var(--k-negtext); }
.k-amt.is-on { background: var(--k-accentsoft); border-color: var(--k-accentedge); }
.k-amt[aria-disabled="true"] { opacity: .42; cursor: not-allowed; }
.k-seg.k-seg--block { display: flex; }
.k-seg.k-seg--block > button { flex: 1 1 0; }
.k-headline { display: flex; align-items: baseline; gap: var(--k-s3); flex-wrap: wrap; min-width: 0; }
.k-headline .k-big { font-size: 26px; }
.k-tablegrid { display: grid; flex: 0 0 auto; font: 400 var(--k-f-sm)/1.3 var(--k-mono); font-variant-numeric: lining-nums tabular-nums; }
.k-tablegrid > div { display: flex; align-items: center; min-height: 30px; padding: 2px 8px; border-bottom: 1px solid var(--k-linesoft); min-width: 0; white-space: nowrap; overflow: hidden; }
.k-tablegrid > .k-th { min-height: 26px; font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--k-dim); }
.k-tablegrid > .k-th.is-pick { cursor: pointer; }
.k-tablegrid > .k-th.is-pick:hover, .k-tablegrid > .k-th.is-on { color: var(--k-ink); background: var(--k-selbg); }
.k-tablegrid > .k-tn { justify-content: flex-end; }
.k-tablegrid > .k-tp { gap: 6px; font-family: var(--k-sans); }
.k-tablegrid > .k-tp .k-name { font-size: var(--k-f-md); font-weight: 600; }

/* ── THE TRADE MENU (sketch 4.1, item 5: V3's, in the kit) ──────────────────── */
/* Trade with? one big row a player, the bots one line at the foot */
.k-pickrow { min-height: 64px; gap: 12px; }
.k-pickrow .k-token { width: 34px; height: 34px; font-size: 14px; }
.k-pickrow .k-name { font-size: var(--k-f-lg); }
.k-pickrow .k-line { gap: 8px; }
.k-pickrow .k-cashfig { font: 600 var(--k-f-lg)/1 var(--k-mono); }
.k-pickrow .k-go { font: 600 var(--k-f-sm)/1 var(--k-mono); letter-spacing: .04em; }
.k-psq { display: inline-flex; gap: 3px; align-items: center; }
.k-psq > i { width: 9px; height: 9px; background: var(--k-sc, var(--k-soft)); }
.k-pickbots { flex: 0 0 auto; padding: 10px var(--k-pad); border-top: 1px solid var(--k-linesoft); letter-spacing: .08em; text-transform: uppercase; }
/* the composer's strip: ‹ back, Trade with, the partner */
.k-head > .k-back { margin-left: -6px; font-size: 18px; }
.k-tpartner { display: inline-flex; align-items: center; gap: 7px; margin-left: 4px; font: 700 var(--k-f-md)/1 var(--k-sans); letter-spacing: 0; text-transform: none; }
.k-tpartner .k-pdot { width: 10px; height: 10px; }
.k-tpartner .k-sub { color: inherit; opacity: .7; }
.k-tgrid { grid-auto-rows: auto; }
.k-tnone { align-self: center; justify-self: center; align-items: center; gap: 12px; }
.k-toffer .k-ocol-h { height: 30px; }
.k-ocol-h.is-give { background: var(--k-negsoft); }
.k-ocol-h.is-get { background: var(--k-possoft); }
.k-olist { display: flex; flex-direction: column; }
.k-empty.k-ocol-empty { margin: auto; padding: 20px; }
/* the eight kind tiles (V3's rail) */
.k-kinds { display: grid; grid-template-columns: repeat(var(--k-kn, 8), minmax(0, 1fr)); gap: 6px; }
.k-kind { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; min-width: 0; height: 56px; padding: 4px;
          border: 1px solid var(--k-line); border-radius: var(--k-radius); background: var(--k-panel); color: var(--k-ink); cursor: pointer;
          font: 600 var(--k-f-sm)/1.1 var(--k-sans); text-align: center; }
.k-kind:hover:not([aria-disabled="true"]) { background: var(--k-selbg); }
.k-kind[aria-pressed="true"] { background: var(--k-accentsoft); border-color: var(--k-accentedge); }
.k-kind[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.k-kind-i { font: 600 15px/1 var(--k-mono); color: var(--k-accenttext); }
.k-kind-t { max-width: 100%; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }
.k-kind.is-two .k-kind-t { -webkit-line-clamp: 1; line-clamp: 1; }
.k-kind-s { font: 400 9px/1 var(--k-mono); color: var(--k-dim); white-space: nowrap; }
/* a narrower composer (under 1280 px): the rail's buttons are ~60 px, and the
   second line ("None to end") would wrap into the name; the button's own
   reason (data-why) says it, and the name takes both lines */
@media (min-width: 900px) and (max-width: 1279px) {
  .k-kind.is-two .k-kind-s { display: none; }
  .k-kind.is-two .k-kind-t { -webkit-line-clamp: 2; line-clamp: 2; }
}
.k-kind > .k-badge { position: absolute; top: 4px; right: 4px; }
/* the term panel: the picked kind's form, its Add at the foot */
.k-tterm > .k-body { display: flex; flex-direction: column; }
.k-panebar.k-tfoot { min-height: 50px; padding: 8px var(--k-pad); gap: var(--k-s2); border-top: 1px solid var(--k-line); }
.k-tfoot > .k-btn--pri { min-width: 180px; height: 34px; }
.k-tfoot > .k-say { flex: 1 1 auto; font: 400 var(--k-f-sm)/1.35 var(--k-sans); color: var(--k-dim); }
.k-dcols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); flex: 1 1 auto; min-height: 0; }
.k-dcol { display: flex; flex-direction: column; min-height: 0; min-width: 0; overflow: hidden; }
.k-dcol + .k-dcol { border-left: 1px solid var(--k-line); }
.k-dcol > .k-ocol-h { justify-content: space-between; color: var(--k-ink); }
.k-dcol > .k-ocol-h .k-pager { margin-left: 0; }
.k-dlist > .k-group { padding: 8px 8px 3px; }
.k-dlist > .k-fpick { padding-left: 8px; }
.k-mtag { font: 700 var(--k-f-xs)/1 var(--k-mono); color: var(--k-negtext); }
.k-kv.k-tface { flex: 0 0 auto; align-items: center; min-height: 34px; padding: 0 var(--k-pad); border-top: 1px solid var(--k-line); }
.k-kv.k-tface .k-v { font: 600 var(--k-f-lg)/1 var(--k-mono); }
.k-cashform { gap: 10px; }
.k-amtctl .k-input { width: 140px; text-align: center; }
.k-cashform .k-range { width: 100%; }

/* ── THE DASHBOARD (sketch 4.1, items 6-9: V3's dashboard in the kit) ──────── */
.k-dash > .k-body > .k-pane { gap: 0; }
.k-dash .k-dgrid { padding-top: var(--k-s2); }
.k-dsum { display: flex; align-items: baseline; gap: var(--k-s5); flex: 0 0 auto; min-height: 34px; padding: 8px var(--k-pad) 0;
          background: var(--k-bg); white-space: nowrap; overflow: hidden; }
.k-dfig { display: inline-flex; align-items: baseline; gap: 6px; min-width: 0; }
.k-dfig .k-label { margin-right: 2px; }
.k-dfig b { font: 600 var(--k-f-lg)/1 var(--k-mono); }
.k-dtiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1px; flex: 0 0 auto; background: var(--k-linesoft); border: 1px solid var(--k-linesoft); }
.k-dtile { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; background: var(--k-panel); min-width: 0; }
.k-dtile .k-big { font-size: 21px; }
.k-dtools { display: flex; align-items: center; gap: var(--k-s2); flex-wrap: wrap; flex: 0 0 auto; }
.k-toggle { gap: 6px; cursor: pointer; }
.k-dmulti { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--k-s2); flex: 1 1 auto; min-height: 0; }
.k-dcard { display: flex; flex-direction: column; gap: 6px; min-height: 0; min-width: 0; padding: 8px 10px; border: 1px solid var(--k-linesoft); background: var(--k-well); }
.k-dcard > .k-line .k-name { font-size: var(--k-f-md); }
.k-dcard > .k-sub { white-space: normal; line-height: 1.5; }
.k-dcards { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--k-s2); align-content: start; }
.k-dstack { display: flex; flex-direction: column; gap: var(--k-ph-gap, 8px); min-height: 0; }
.k-dstack > .k-panel { flex: 1 1 auto; min-height: 0; }
.k-chip.k-chip--xs { height: 15px; padding: 0 4px; font-size: 9px; letter-spacing: .05em; }
.k-strong { font-weight: 600; color: var(--k-ink); }
.k-row.k-row--log { min-height: 28px; gap: 8px; padding-top: 2px; padding-bottom: 2px; font-size: var(--k-f-sm); }
.k-row--log > .k-sub { flex: 0 0 2.6em; }
.k-row--log > .k-grow { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.k-panebar.k-panebar--mid { margin: 0 calc(-1 * var(--k-pad)); border-top: 1px solid var(--k-line); border-bottom: 1px solid var(--k-linesoft); }
.k-panebar.k-panebar--top0 { border-top: 0; border-bottom: 1px solid var(--k-linesoft); padding: 4px var(--k-pad); flex-wrap: wrap; row-gap: 4px; }
.k-link-btn { margin: 0; padding: 0; border: 0; background: transparent; color: var(--k-accenttext); cursor: pointer;
              font: 600 var(--k-f-sm)/1 var(--k-mono); }
.k-link-btn:hover { text-decoration: underline; }
/* the market table (Stocks): a row picks the stock (link group C) */
.k-tablegrid.k-mtable { grid-template-columns: 44px minmax(90px, 1fr) 64px 78px 72px auto; margin: 0 calc(-1 * var(--k-pad)); }
.k-mtable > .k-mname { justify-content: center; align-items: flex-start; gap: 1px; min-height: 40px; font-family: var(--k-sans); }
.k-tablegrid > .is-pick { cursor: pointer; }
.k-tablegrid > .is-current { background: var(--k-selbg); }
.k-tablegrid > .k-tick[data-pc] { position: relative; padding-left: calc(8px + var(--k-mark-w)); }
.k-tablegrid > .k-tick[data-pc]::before { content: ""; position: absolute; left: 0; top: 6px; bottom: 6px; width: var(--k-mark-w); background: var(--k-pc); }
.k-tablegrid > .k-tick.is-current::before { top: 0; bottom: 0; }
.k-spark.is-up path { stroke: var(--k-pos); }
.k-spark.is-down path { stroke: var(--k-neg); }
.k-obar { display: flex; height: 6px; background: var(--k-linesoft); overflow: hidden; }
.k-obar > i { display: block; flex: 0 0 auto; height: 100%; background: var(--k-pc, var(--k-dim)); }
.k-obar > i + i { box-shadow: -1px 0 0 var(--k-panel); }
.k-owners { display: flex; flex-direction: column; gap: 5px; flex: 0 0 auto; padding: 6px 0; }
.k-owners .k-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.k-owners .k-tick[data-pc] { color: var(--k-pc); }
.k-plist.k-bleed { margin: 0 calc(-1 * var(--k-pad)); }
.k-market > .k-body { padding-top: 0; padding-bottom: 0; gap: 0; }
.k-ystock { flex: 0 0 auto; border-top: 1px solid var(--k-line); margin: 0 calc(-1 * var(--k-pad)); padding: 0 var(--k-pad); }
.k-ystock .k-opt { border-bottom: 0; }
.k-stockchart .k-headline .k-big { font-size: 28px; }
/* ownership */
.k-tablegrid.k-holdgrid { grid-template-columns: minmax(120px, 0.8fr) minmax(0, 2fr) 64px 72px; }
.k-holdgrid .k-bar { width: 100%; height: 8px; }
.k-bar.k-bar--pc > i { background: var(--k-pc, var(--k-ink)); }
.k-bar.k-bar--free > i { background: repeating-linear-gradient(135deg, var(--k-line) 0 3px, transparent 3px 6px); }
/* bonds */
.k-legend { gap: 4px 10px; flex: 0 0 auto; flex-wrap: wrap; }
.k-tablegrid.k-ratetable.k-ratetable--phone { grid-template-columns: minmax(0, 1fr) 44px 54px 56px; }
@media (max-width: 899px) {
  html[data-k-phone] .k-dsum { gap: var(--k-s3); padding: 6px var(--k-ph-gap, 8px) 0; }
  html[data-k-phone] .k-dfig b { font-size: var(--k-f-md); }
  html[data-k-phone] .k-dtile { padding: 7px 6px; gap: 5px; }
  html[data-k-phone] .k-dtile .k-big { font-size: 14px; }
  html[data-k-phone] .k-dtile .k-label { font-size: 8px; letter-spacing: .04em; }
  html[data-k-phone] .k-dtools { gap: 6px; }
  html[data-k-phone] .k-seg.k-seg--block { width: 100%; }
  html[data-k-phone] .k-seg.k-seg--block > button { padding: 0 2px; min-width: 0; font-size: 9px; letter-spacing: .02em; }
  html[data-k-phone] .k-kinds { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.k-lgline { display: inline-block; width: 18px; height: 0; border-top: 2px solid var(--k-ink); }
.k-lgline.is-dash { border-top-style: dotted; }
.k-tablegrid.k-ratetable { grid-template-columns: minmax(0, 1.6fr) 52px 60px 56px 56px 64px; margin: 0 calc(-1 * var(--k-pad)); }
.k-ratetable .k-tp .k-sub { margin-left: 2px; }
.k-row.k-row--bond { min-height: 46px; }
.k-stack.k-end { align-items: flex-end; flex: 0 0 auto; }
.k-empty.k-empty--row { padding: 6px var(--k-pad) 10px; }
.k-borrowers { display: flex; flex-direction: column; flex: 0 0 auto; border: 1px solid var(--k-linesoft); }
.k-row.k-row--pick { min-height: 34px; gap: 10px; }
.k-row--pick > .k-sub { flex: 0 0 4.4em; text-align: right; }
/* sketch 4.2, items 10 and 18: the Lend screen: you in the borrowers' list, the list paged on a phone,
   the principal and its four amounts in one row there, your bond's switch at the foot, left */
.k-borrowhead { gap: 8px; min-height: 22px; }
.k-borrowhead > .k-pager { margin-left: auto; }
.k-borrowers.k-borrowers--paged { flex: 1 1 0; min-height: 35px; overflow: hidden; }
.k-row.k-row--me { background: var(--k-well); }
.k-row.k-row--me .k-chip { flex: 0 0 auto; }
.k-lendamt { display: flex; gap: 6px; align-items: stretch; flex: 0 0 auto; }
.k-lendamt > .k-input { flex: 0 0 76px; width: 76px; min-width: 0; height: 34px; }
.k-lendamt > .k-quickamts { flex: 1 1 auto; min-width: 0; gap: 4px; }
.k-lendamt > .k-quickamts > .k-btn { min-width: 0; padding: 0 2px; }
.k-fprose.k-lendsays { margin: 0; font-size: var(--k-f-sm); }
.k-bondfoot { display: flex; align-items: center; gap: 10px; margin-top: auto; padding-top: 6px; align-self: flex-start; cursor: pointer; flex: 0 0 auto; }
.k-bondfoot .k-opt-t { margin: 0; }
.k-ratetable .k-tp.is-pick { cursor: pointer; }
.k-ratetable .k-tp.is-pick .k-name { text-decoration: underline; text-decoration-color: var(--k-linesoft); text-underline-offset: 3px; }
.k-quickamts.k-quickamts--4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.k-quickamts--4 > .k-btn { height: 34px; font: 600 var(--k-f-md)/1 var(--k-mono); }
.k-btn.is-on { background: var(--k-accentsoft); border-color: var(--k-accentedge); }
.k-figs { display: flex; flex-direction: column; flex: 0 0 auto; padding: 4px 10px; border: 1px solid var(--k-linesoft); background: var(--k-well); }
.k-figs > .k-kv { min-height: 26px; border-bottom: 1px solid var(--k-linesoft); }
.k-figs > .k-kv:last-child { border-bottom: 0; }
.k-figs > .k-label { padding: 6px 0 2px; }
/* obligations */
.k-tablegrid.k-obtable { grid-template-columns: minmax(0, 1.5fr) 44px 70px 70px; flex: 0 0 auto; }
.k-obtable > .k-stack { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 2px; min-height: 40px; }
.k-plist > .k-tablegrid.k-obtable > div { border-bottom: 0; }
.k-plist > .k-tablegrid.k-obtable { border-bottom: 1px solid var(--k-linesoft); }
.k-walk { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 6px; flex: 0 0 150px; align-items: stretch; }
.k-walk-c { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 0; }
.k-walk-c > .k-sub { font-size: 9px; }
.k-walk-bar { flex: 1 1 auto; width: 100%; display: flex; align-items: flex-end; justify-content: center; border-bottom: 1px solid var(--k-line); }
.k-walk-bar > i { display: block; width: 70%; background: var(--k-accent); }
.k-walk-bar > i.is-many { background: var(--k-neg); }
/* Leverage: the option of every chart at once, two columns, the one scroll (item 9) */
.k-levtools { gap: 6px; flex: 0 0 auto; }
.k-head .k-levtools .k-label { color: var(--k-dim); }
.k-levgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--k-gap); align-content: start; flex: 1 1 auto; min-height: 0;
             padding: var(--k-gap); overflow-y: auto; overscroll-behavior: contain; scrollbar-gutter: stable; }
.k-levgrid.k-levgrid--one { grid-template-columns: minmax(0, 1fr); padding: var(--k-ph-gap, 6px); }
.k-levgrid--one .k-chartbox.k-levchart { height: 200px; }
.k-levcard { display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; border: 1px solid var(--k-linesoft); background: var(--k-panel); }
.k-levcard > .k-line .k-label { color: var(--k-ink); }
.k-chartbox.k-levchart { flex: 0 0 auto; height: 240px; min-height: 0; }
.k-levlegend { display: flex; flex-wrap: wrap; gap: 4px 14px; }
.k-levlegend .k-num { margin-left: 4px; color: var(--k-ink); }
.k-levcard > .k-fprose { padding: 0; }
.k-head > .k-seg:is([data-k-levview], [data-k-chartview]) { margin-left: auto; }
/* the Tabs / All charts switch stands by the status, so it does not move when the title changes (sketch 4.11) */
.k-head > .k-seg:is([data-k-levview], [data-k-chartview]) + .k-stat { margin-left: 10px; }
.k-panebar > .k-chhint { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* ── sketch 4.11: the Charts tab (V4.11 brief items 2, 3, 4) ──────────── */
/* the seven charts are TILES you tap (the composer's term tiles): framed, the
   whole name, the one on show filled and edged in the accent, a bar on its foot */
.k-picks { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; flex: 0 0 auto; }
.k-pick {
  display: flex; align-items: center; justify-content: center; min-width: 0; height: 36px; margin: 0; padding: 0 8px;
  border: 1px solid var(--k-line); border-radius: var(--k-radius); background: var(--k-panel); color: var(--k-ink); cursor: pointer;
  font: 600 var(--k-f-md)/1.1 var(--k-sans); text-align: center; white-space: nowrap;
}
.k-pick:hover { background: var(--k-selbg); }
.k-pick[aria-selected="true"] { background: var(--k-accentsoft); border-color: var(--k-accentedge); box-shadow: inset 0 -3px 0 var(--k-accent);
                                font-weight: 700; cursor: default; }
/* the legend under a combined chart: every player; a tap picks their line out */
.k-chlegend { display: flex; flex-wrap: wrap; gap: 4px 6px; flex: 0 0 auto; }
.k-lgi {
  display: inline-flex; align-items: center; gap: 7px; min-width: 0; height: 28px; margin: 0; padding: 0 9px 0 6px;
  border: 1px solid transparent; border-radius: var(--k-radius); background: transparent; color: var(--k-ink); cursor: pointer;
  font: 500 var(--k-f-md)/1 var(--k-sans); white-space: nowrap; text-align: left;
}
.k-lgi:hover { background: var(--k-selbg); }
.k-lgi[aria-pressed="true"] { border-color: var(--k-line); background: var(--k-well); }
.k-lgi .k-num { font: 600 var(--k-f-md)/1 var(--k-mono); font-variant-numeric: tabular-nums; }
.k-lgi .k-chip { flex: 0 0 auto; }
.k-lgi.is-out { color: var(--k-dim); }
.k-lgname { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; line-height: 1.3; }      /* room for a g's tail */
/* a line's key: a stroke of the player's colour ending in the line's dot */
.k-lgkey { position: relative; flex: 0 0 auto; width: 20px; height: 3px; margin-right: 3px; border-radius: 2px; background: var(--k-pc, var(--k-ink)); }
.k-lgkey::after { content: ""; position: absolute; right: -3px; top: 50%; width: 8px; height: 8px; margin-top: -4px; border-radius: 50%; background: var(--k-pc, var(--k-ink)); }
.k-lgi.is-out .k-lgkey { opacity: .4; }
.k-fprose.k-chdef { padding: 0; flex: 0 0 auto; }
.k-chgrid .k-chlegend { gap: 2px 4px; }
.k-chgrid .k-lgi { height: 24px; padding: 0 7px 0 4px; font-size: var(--k-f-sm); }
.k-chgrid .k-lgi .k-num { font-size: var(--k-f-sm); }
.k-dcard.is-out { opacity: .6; }
.k-dmulti > .k-dcard[hidden] { display: none; }
.k-dmulti .k-dcard > .k-line { gap: 6px; }
.k-dmulti .k-dcard > .k-line .k-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--k-ink);
                                       font: 600 var(--k-f-md)/1.15 var(--k-sans); letter-spacing: 0; }
.k-dmulti .k-dcard > .k-line .k-num { color: var(--k-ink); font-size: var(--k-f-sm); }
@media (max-width: 899px) {
  /* a phone: the tiles four to a row, the second row's three as wide as the row */
  html[data-k-phone] .k-picks { grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 5px; }
  html[data-k-phone] .k-pick { grid-column: span 3; height: 34px; padding: 0 3px; font-size: 12px; }
  html[data-k-phone] .k-pick:nth-child(n + 5) { grid-column: span 4; }
  /* the legend two to a row, each figure at its row's end */
  html[data-k-phone] .k-chlegend { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 6px; }
  html[data-k-phone] .k-lgi { height: auto; min-height: 26px; padding: 2px 4px 2px 2px; gap: 6px; font-size: 12px; }
  html[data-k-phone] .k-lgi .k-num { margin-left: auto; font-size: 12px; }
  /* a name never cut on a phone: it takes a second line ("Balanced Bot 2" beside "Balanced Bot") */
  html[data-k-phone] .k-lgname, html[data-k-phone] .k-dmulti .k-dcard > .k-line .k-name {      /* two plain selectors: matched by class */
    white-space: normal; overflow-wrap: break-word; line-height: 1.15;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  }
  /* in the All charts grid (it scrolls) a legend is one player a row: no name wraps */
  html[data-k-phone] .k-chgrid .k-chlegend { grid-template-columns: minmax(0, 1fr); }
  /* the mode and range row on one line down to 360 px */
  html[data-k-phone] .k-dtools .k-seg > button { padding: 0 7px; letter-spacing: .03em; }
  html[data-k-phone] .k-dmulti .k-dcard { padding: 6px 7px; gap: 4px; }
  html[data-k-phone] .k-dmulti .k-dcard > .k-line .k-name { font-size: 12px; }
  html[data-k-phone] .k-dmulti .k-chartbox { min-height: 0; }
}
/* a phone in its browser, its bars on (390x664, 375x553): the chart keeps the room */
@media (max-width: 899px) and (max-height: 719px) {
  html[data-k-phone] .k-fprose.k-chdef { display: none; }
  html[data-k-phone] .k-pick { height: 30px; }
}
/* a phone on its side (wide and short, 844x390): the tiles in one row, the legend in lines, the
   dashboard's tabs on one row, so the chart has a height to draw in */
@media (max-width: 899px) and (min-width: 600px) and (max-height: 500px) {
  html[data-k-phone] .k-picks { grid-template-columns: repeat(7, minmax(0, 1fr)); }
  html[data-k-phone] .k-pick, html[data-k-phone] .k-pick:nth-child(n + 5) { grid-column: auto; height: 28px; }
  html[data-k-phone] .k-body > .k-chlegend { display: flex; flex-wrap: wrap; gap: 0 12px; }
  html[data-k-phone] .k-body > .k-chlegend .k-lgi { min-height: 24px; }
  html[data-k-phone] .k-dash > .k-tabs.k-tabs--wrap .k-tab { flex: 1 1 0; }
}

/* ── the end of the game: the reveal on the board, the leaderboard, statistics ── */
.k-sq.is-over > .k-tile, .k-rowsbox.is-over .k-tile { opacity: .32; transition: opacity 600ms ease; }
.k-reveal { display: flex; flex-direction: column; align-items: center; gap: calc(1.4 * var(--k-u)); }
.k-reveal-h { margin: 0; font: 700 calc(6.2 * var(--k-u))/1 var(--k-sans); letter-spacing: -.01em; color: var(--k-ink); }
.k-reveal-s { margin: 0; font: 500 calc(1.7 * var(--k-u))/1.2 var(--k-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--k-dim); }
.k-reveal-w { display: flex; align-items: center; gap: calc(1.6 * var(--k-u)); opacity: 0; transform: translateY(8px); transition: opacity 500ms ease, transform 500ms ease; }
.k-reveal-w.is-shown { opacity: 1; transform: none; }
.k-reveal-w .k-token { width: calc(7 * var(--k-u)); height: calc(7 * var(--k-u)); font-size: calc(3 * var(--k-u)); }
.k-reveal-w .k-name { font: 700 calc(4 * var(--k-u))/1 var(--k-sans); }
@media (prefers-reduced-motion: reduce) { .k-reveal-w { transition: none; } }
/* SKETCH 4.12, item 8: who is back in the room's pre-lobby, under the reveal
   (nobody is moved from the results; this says where the others went) */
.k-reveal-note {
  max-width: 92%; margin: calc(.6 * var(--k-u)) 0 0; text-align: center;
  font: 500 max(11px, calc(1.8 * var(--k-u)))/1.35 var(--k-sans); color: var(--k-dim);
}
.k-reveal-note[hidden] { display: none; }
.k-lb { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; gap: 4px 10px; align-items: center; padding: 5px var(--k-pad); }
.k-lb .k-num { font-size: var(--k-f-md); }
.k-lb .k-bar { grid-column: 2 / 4; height: 4px; }
.k-lb .k-bar > i { background: var(--k-pc, var(--k-ink)); }
.k-lb-rank { font: 700 var(--k-f-md)/1 var(--k-mono); color: var(--k-dim); text-align: right; }
.k-stat-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--k-s2); }
.k-stat-tile { display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; border: 1px solid var(--k-linesoft); background: var(--k-well); }
.k-stat-tile .k-big { font-size: 22px; }
.k-winner { display: flex; align-items: center; gap: var(--k-s3); padding: 12px; border-left: var(--k-mark-w) solid var(--k-pc, var(--k-accent)); background: var(--k-well); }
.k-winner .k-token { width: 40px; height: 40px; font-size: 16px; }
.k-winner .k-name { font-size: 22px; }

/* the chart (static/js/kit-chart.js) */
.k-chart { position: relative; flex: 1 1 auto; min-height: 0; min-width: 0; overflow: hidden; }
.k-ch-svg { display: block; position: absolute; inset: 0; }
.k-ch-grid line { stroke: var(--k-linesoft); stroke-width: 1; }
.k-ch-grid line.is-zero { stroke: var(--k-line); }
.k-ch-grid line.k-ch-base { stroke: var(--k-line); }
.k-ch-ylab, .k-ch-xlab { fill: var(--k-dim); font: 500 10px/1 var(--k-mono); font-variant-numeric: tabular-nums; }
.k-ch-empty { fill: var(--k-dim); font: 400 var(--k-f-sm)/1 var(--k-sans); }
.k-ch-line { fill: none; stroke: var(--k-pc, var(--k-ink)); stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; }
.k-ch-line.is-dim { opacity: .3; }
.k-ch-line.is-dash { stroke-dasharray: 2 4; stroke-width: 1.4; opacity: .75; }
/* candles (sketch 4.1, item 8): green up, red down, grey flat; the turn in progress hollow */
.k-ch-cdl .k-ch-wick { stroke-width: 1; }
.k-ch-cdl.is-up .k-ch-body { fill: var(--k-pos); }
.k-ch-cdl.is-up .k-ch-wick { stroke: var(--k-pos); }
.k-ch-cdl.is-dn .k-ch-body { fill: var(--k-neg); }
.k-ch-cdl.is-dn .k-ch-wick { stroke: var(--k-neg); }
.k-ch-cdl.is-flat .k-ch-body { fill: var(--k-dim); }
.k-ch-cdl.is-flat .k-ch-wick { stroke: var(--k-dim); }
.k-ch-cdl.is-live .k-ch-body { fill: var(--k-panel); stroke-width: 1.4; stroke-dasharray: 3 2; }
.k-ch-cdl.is-live.is-up .k-ch-body { stroke: var(--k-pos); }
.k-ch-cdl.is-live.is-dn .k-ch-body { stroke: var(--k-neg); }
.k-ch-cdl.is-live.is-flat .k-ch-body { stroke: var(--k-dim); }
.k-ch-cdl.is-hist .k-ch-body { opacity: .7; }
.k-ch-dot { fill: var(--k-pc, var(--k-ink)); stroke: var(--k-panel); stroke-width: 1.5; }
/* one series picked out (sketch 4.11, a name tapped in the Charts legend): on top, thicker; the rest fade */
.k-ch-line.is-focus { stroke-width: 3; }
.k-ch-line.is-faded, .k-ch-dot.is-faded { opacity: .18; }
.k-ch-dot.is-focus { r: 3.6; }
.k-ch-mark { stroke: var(--k-dim); stroke-width: 1; stroke-dasharray: 3 3; opacity: .7; }
.k-ch-mark.is-mine { stroke: var(--k-accent); opacity: .9; }
.k-ch-mark.is-hot { stroke: var(--k-ink); opacity: 1; stroke-dasharray: none; }
.k-ch-pin { fill: var(--k-dim); }
.k-ch-pin.is-mine { fill: var(--k-accent); }
.k-ch-pinn { fill: var(--k-dim); font: 600 10px/1 var(--k-mono); }
.k-ch-hline { stroke: var(--k-ink); stroke-width: 1; stroke-dasharray: 2 3; pointer-events: none; }
.k-ch-hbox { fill: var(--k-inv); }
.k-ch-htext { fill: var(--k-invtext); font: 600 10px/1 var(--k-mono); font-variant-numeric: tabular-nums; pointer-events: none; }
.k-ch-vline { stroke: var(--k-ink); stroke-width: 1; opacity: .45; pointer-events: none; }
.k-ch-read { position: absolute; z-index: 2; min-width: 150px; max-width: 280px; padding: 6px 8px; pointer-events: none;
             background: var(--k-panel); border: 1px solid var(--k-line); box-shadow: var(--k-shadow-sm);
             font: 400 var(--k-f-sm)/1.35 var(--k-mono); font-variant-numeric: tabular-nums; }
.k-ch-rhead { font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--k-dim); margin-bottom: 4px; }
.k-ch-rrow { display: flex; align-items: center; gap: 6px; min-height: 18px; }
.k-ch-rrow b { font-weight: 600; }
.k-ch-rtrade { margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--k-linesoft); font: 400 var(--k-f-xs)/1.35 var(--k-sans); color: var(--k-dim); white-space: normal; }
.k-ch-tip b { display: block; font-weight: 600; }
.k-ch-tip div + b { margin-top: 6px; }

/* lists that page inside a tab, with a slim bar for the pager */
.k-plist { flex: 1 1 auto; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }
.k-panebar { display: flex; align-items: center; gap: var(--k-s2); flex: 0 0 auto; min-height: 30px; padding: 0 6px 0 var(--k-pad);
             border-top: 1px solid var(--k-linesoft); }
.k-panebar > .k-pager { margin-left: auto; }
.k-panebar--top { border-top: 0; border-bottom: 1px solid var(--k-linesoft); margin: calc(-1 * var(--k-pad)) calc(-1 * var(--k-pad)) 0; }
.k-panebar[hidden] { display: none; }
.k-pane--pad { padding: var(--k-pad); }
.k-kv--long .k-k { flex: 0 0 auto; }
.k-kv--long .k-v { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
@media (min-width: 900px) and (max-width: 1279px) {
  .k-table .k-wideonly { display: none; }
}
.k-tabs.k-tabs--wrap { flex-wrap: wrap; }
.k-tabs.k-tabs--wrap .k-tab { flex: 1 1 22%; }
@media (max-width: 899px) {
  /* four to a row on a phone: INCOME SHARE, END A SHARE and CONTRACT CAP were
     cut by 2-6 px at 360 px with the desktop's spacing */
  html[data-k-phone] .k-tabs.k-tabs--wrap .k-tab { padding: 0 3px; letter-spacing: .02em; }
  /* a dialog's foot on a phone: DECLARE BANKRUPTCY… in half of 360 px */
  html[data-k-phone] .k-modal .k-foot > .k-btn { padding: 0 6px; letter-spacing: .02em; }
  /* a term form's foot on a phone (S41-72): Reset keeps its word and Add to offer takes
     what is left; with a form's pager at 360 px Add's 180 px squeezed RESET to 27 px */
  html[data-k-phone] .k-tfoot > .k-btn--sm { flex: none; }
  html[data-k-phone] .k-tfoot > .k-btn--pri { flex: 1 1 auto; min-width: 0; padding: 0 8px; }
}
@media (min-width: 900px) and (max-width: 1279px) {
  /* the chat bubble sits over the right column's foot: keep the buttons clear of it */
  .k-table .k-col--b > .k-fill > .k-foot { padding-right: 76px; }
  /* three buttons in what is left: the short words, no letter-spacing, slim sides
     (sketch 4.1 review: "STOCK DESK" was cut at 960x900) */
  .k-table .k-col--b > .k-fill > .k-foot.k-foot--three { gap: 6px; }
  .k-table .k-col--b > .k-fill > .k-foot.k-foot--three > .k-btn { padding: 0 4px; letter-spacing: 0; }
  .k-foot--three .k-long { display: none; }
  .k-foot--three .k-short { display: inline; }
}
.k-short { display: none; }
/* sketch 4.1, item 20: the clock's own line in the board's centre (S4.clock): a
   debt that stops the table, or the newest announcement while its claim holds */
.k-cnote { margin: 0; max-width: 46ch; font: 500 var(--k-f-sm)/1.35 var(--k-sans); color: var(--k-ink); text-align: center; text-wrap: balance; }
.k-cnote[hidden] { display: none; }
.k-cnote[data-level="crit"] { color: var(--k-negtext); }
.k-cnote[data-level="warn"] { color: var(--k-accenttext); }

/* three buttons share the desk's foot: slim sides at every width, so a label
   never runs into its padding (1280-1440 px: 3-8 px did, unseen) */
.k-foot.k-foot--three > .k-btn { padding: 0 6px; letter-spacing: .03em; }
/* the room link's Copy keeps its word whole; the link field gives way (sketch 4.1:
   the cut-label measure found "COPY" 2-3 px too wide for its button at half-width) */
.k-btn.k-copy { flex: 0 0 auto; }

/* the card and the auction, in the board's centre (s4-centre.js) */
.k-cslot-card:empty, .k-cslot-auction:empty { display: none; }
/* they float over the centre's lower part (over the log), so the dice, the
   message and the buttons stay where they are (look review, 6 Oct) */
.k-cslot-card:not(:empty), .k-cslot-auction:not(:empty) {
  position: absolute; z-index: 3; left: 0; right: 0; bottom: calc(3 * var(--k-u));
  display: flex; justify-content: center; pointer-events: none;
}
.k-cslot-card > *, .k-cslot-auction > * { pointer-events: auto; }
/* on the square an auction stands inside the band the tokens' rows keep (sketch
   4.12). A CARD KEEPS V4.11'S PLACE (the fix step): its foot 3 units over the
   centre's edge, as wide as the centre lets it. Inside the band (33 px at
   960x900 and 900x700) a card that moves you rose over Buy and Decline and End
   turn; and on a phone the band made it 21 px narrower, so taller, and the 280
   px board cut 35 px off its head (V4.11: 15). A card shows for a few seconds;
   a crowd's second row it may stand over stays for good. */
.k-sq .k-cslot-auction:not(:empty) { left: var(--k-cpad); right: var(--k-cpad); bottom: var(--k-cpad); }
.k-sq :is(.k-cslot-card, .k-cslot-auction) > * { max-width: 100%; }
/* the compressed view: over the board's lower right, not inside the short strip */
.k-boardwrap[data-view="rows"] { position: relative; }
.k-boardwrap[data-view="rows"] > .k-strip, .k-boardwrap[data-view="rows"] > .k-strip > .k-centre { position: static; }
.k-boardwrap[data-view="rows"] > .k-strip > .k-centre { overflow: visible; }
.k-boardwrap[data-view="rows"] :is(.k-cslot-card, .k-cslot-auction):not(:empty) { left: auto; right: var(--k-pad); top: var(--k-pad); bottom: auto; }
.k-cardpanel, .k-auctionpanel { width: min(380px, calc(64 * var(--k-bq, 1cqmin))); text-align: left; box-shadow: var(--k-shadow); }
.k-cardpanel .k-body { gap: 6px; }
.k-cardpanel .k-opt-t { margin: 0; font-size: var(--k-f-lg); line-height: 1.35; }
.k-cardpanel[data-deck="chance"] { border-color: var(--k-accentedge); }
.k-auctionpanel { width: min(420px, calc(70 * var(--k-bq, 1cqmin))); }
.k-auctionpanel .k-head .k-tflag { margin: 0; box-shadow: inset 0 0 0 1px var(--k-head-fg); }
.k-auctionpanel .k-acts { justify-content: flex-start; min-height: 0; }
.k-auctionpanel .k-clock { width: 100%; }
.k-auctionpanel .k-kv { min-height: 20px; }
.k-strip .k-cardpanel, .k-strip .k-auctionpanel { width: 360px; }
/* sketch 4.2, item 10: a phone's auction stands over the dock, full width, its foot on the turn's
   bar (s4-centre.js places it); its three bids and Pass in one row; who is in, two to a line */
.k-aucdock { position: fixed; z-index: 25; left: 8px; right: 8px; display: flex; flex-direction: column; justify-content: flex-end; pointer-events: none; }
.k-aucdock:empty { display: none; }
.k-aucdock > .k-auctionpanel { pointer-events: auto; width: 100%; min-height: 0; max-height: 100%; overflow: hidden; }
.k-aucdock .k-aucbids { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; width: 100%; }
.k-aucdock .k-aucbids > .k-btn { min-width: 0; padding: 0 4px; }
.k-aucdock .k-aucwho { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 14px; }
/* Ownership: every set, three columns, one screen */
.k-owngrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--k-s2) var(--k-s4); align-content: start; }
.k-ownset { display: flex; flex-direction: column; min-width: 0; }
.k-ownset .k-group { padding: 6px 0 2px; }
.k-ownset .k-kv { min-height: 20px; border-bottom: 1px solid var(--k-linesoft); }
.k-ownset .k-kv .k-k { text-transform: none; letter-spacing: 0; font-family: var(--k-sans); font-size: var(--k-f-md); color: var(--k-ink); }
.k-ownset .k-kv .k-v { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 1279px) { .k-owngrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ══ PHASE B: THE PHONE ═══════════════════════════════════════════════════
 * Below 900 px the same kit app is drawn, in the phone's own layout, when the
 * server marks <html data-k-phone> (s4_phone; SKETCH4_PHONE=0 keeps today's
 * phone page, and SKETCH4_DESK=0 turns both kits off). The legacy page steps
 * aside exactly as it does on desktop, and its windows keep running hidden.
 *
 * Today's phone keeps its order, rebuilt from the kit: the top panel (You in
 * the game, the room's card in the pre-lobby), the board as wide as the screen,
 * then THE DOCK: one side panel at a time, the turn's buttons, and the tab bar
 * that picks the panel (s4-table.js S4.dock). Every side panel is the desktop's
 * own; only where it sits changes (the panel contract). No page scrolls: what
 * does not fit a panel pages, as on desktop. Still tokens only, no !important. */
/* the phone's parts of the table and of the menu are not drawn at 900 px and up */
.k-table > .k-dockbar, .k-table > .k-docknav, .k-phoneonly { display: none; }

/* ── three components the phone added to the kit (the gallery's Phone tab) ── */
/* a TAB BAR at a screen's foot: a line icon over a short name; the open one
   joins the page (BG) and carries the accent mark on its top (today's phone) */
.k-tabs.k-tabs--bar { height: var(--k-ph-nav); border-top: 1px solid var(--k-linesoft); border-bottom: 0; background: var(--k-panel); }
.k-tabs--bar > .k-tab {
  position: relative; flex: 1 1 0; height: auto; min-width: 0; flex-direction: column; gap: 4px; padding: 7px 2px 5px;
  font-size: 9px; letter-spacing: .05em;
}
.k-tabs--bar > .k-tab .k-tic { width: 20px; height: 20px; stroke: currentColor; }
.k-tabs--bar > .k-tab > span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.k-tabs--bar > .k-tab[aria-selected="true"]::before {
  content: ""; position: absolute; left: 22%; right: 22%; top: -1px; height: 2px; background: var(--k-accent);
}
.k-tabs--bar > .k-tab .k-badge { position: absolute; top: 3px; left: calc(50% + 7px); }
/* an ACTION BAR: More, then big buttons; the main one keeps its whole label, the
   others share what is left (the phone's turn buttons) */
.k-actbar {
  display: flex; align-items: center; gap: var(--k-s2); min-width: 0;
  height: var(--k-ph-bar); padding: 0 var(--k-ph-gap); background: var(--k-panel); border-top: 1px solid var(--k-line);
}
.k-actbar > .k-dock-more { flex: 0 0 auto; width: 44px; padding: 0; }
.k-actbar > .k-dock-more .k-tic { width: 22px; height: 22px; stroke: currentColor; }
.k-actbar > .k-acts { flex: 1 1 auto; min-width: 0; min-height: var(--k-btn-h-lg); flex-wrap: nowrap; justify-content: flex-end; gap: 6px; }
.k-actbar > .k-acts > .k-btn {
  display: block; flex: 1 1 auto; min-width: 0; padding: 0 8px;
  overflow: hidden; text-overflow: ellipsis; line-height: calc(var(--k-btn-h-lg) - 2px); font-size: var(--k-f-sm);
}
.k-actbar > .k-acts > .k-btn--pri { flex: 1 0 auto; max-width: 70%; }
.k-actbar > .k-acts > .k-btn--pri:only-child { max-width: none; }
/* a panel of FIGURES: its label/value rows as cells side by side, the label over
   the value (today's wallet bar; the phone's You) */
.k-panel--cells > .k-body { flex-direction: row; gap: 0; padding: 7px 0; align-items: stretch; min-height: 48px; }
.k-panel--cells .k-kv {
  flex: 1 1 0; flex-direction: column; align-items: flex-start; justify-content: center; gap: 4px; min-height: 0; min-width: 0; padding: 0 10px;
}
.k-panel--cells .k-kv + .k-kv { border-left: 1px solid var(--k-linesoft); }
.k-panel--cells .k-kv--big { flex-grow: 1.25; }
.k-panel--cells .k-kv > .k-k { flex: 0 0 auto; max-width: 100%; font-size: var(--k-f-xs); }
.k-panel--cells .k-kv > .k-v {
  flex: 0 0 auto; max-width: 100%; overflow: hidden; text-overflow: ellipsis; text-align: left;
  font-size: var(--k-f-lg); font-weight: 600; line-height: 1;
}
.k-panel--cells .k-kv--big > .k-v { font-size: var(--k-f-xl); overflow: visible; }
.k-panel--cells .k-kv--big .k-delta { top: auto; bottom: 1px; right: auto; left: calc(100% + 6px); }

@media (max-width: 899px) {
  html[data-k-phone] .k-app { display: block; }
  html[data-k-phone] body > :is(.mv2-shell, .pv2-shell, .cp-intro, #tt-top, #wallet-bar, .game-container, #tt-crawl, #money-strip) { display: none; }
  html[data-k-phone], html[data-k-phone] body { overflow: hidden; background: var(--k-bg); }
  @view-transition { navigation: auto; }
  /* the legacy windows step aside (S4-32), the phone's own sheet of More too */
  html[data-k-phone] body > :is(#trade-screen-overlay, #trade-modal, #b5-dash, #b6-stocks, #b7-bonds, #game-over-overlay,
                                #v2-raise-sheet, #toast-container, #card-popup, #auction-modal, #reconnect-loading-overlay, #v2-menu) {
    visibility: hidden; pointer-events: none;
  }
  html[data-k-phone] body > #name-prompt-modal[data-k-took] { visibility: hidden; pointer-events: none; }
  /* a drop after the game was shown dims the side panels (the columns are not
     boxes on a phone: the panels themselves dim) */
  html[data-k-phone] .k-app.is-joining.is-rejoin .k-table > :is(.k-col--a, .k-col--b) > .k-panel { opacity: .55; transition: opacity var(--k-dur) ease; }

  /* THE TABLE, one column. The board is a square as wide as the screen, unless
     the screen is too short to keep the dock's four rows: then it shrinks, down
     to --k-ph-board (a phone browser's bars can leave 390 x 660), and below that
     the dock gives way (its rows page). */
  html[data-k-phone] .k-table {
    --k-sq: min(calc(100vw - 2 * var(--k-ph-gap) - 2px),
                max(var(--k-ph-board),
                    calc(100dvh - 6 * var(--k-ph-gap) - var(--k-ph-top) - var(--k-ph-dock) - var(--k-ph-bar) - var(--k-ph-nav) - 2px)));
    display: grid; height: 100vh; height: 100dvh; overflow: hidden;
    gap: var(--k-ph-gap); padding: var(--k-ph-gap); background: var(--k-bg);
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto calc(var(--k-sq) + 2px) minmax(0, 1fr) auto auto;
    grid-template-areas: "top" "board" "dock" "bar" "nav";
  }
  html[data-k-phone] .k-table > * { min-width: 0; min-height: 0; }
  /* the columns step out of the way: their panels are the grid's own items */
  html[data-k-phone] .k-table > :is(.k-col--a, .k-col--b) { display: contents; }
  html[data-k-phone] .k-table > .k-col--c { grid-area: board; display: flex; flex-direction: column; }
  html[data-k-phone] .k-table .k-col--c > .k-board-panel { flex: 1 1 auto; }
  html[data-k-phone] .k-table .k-col--c > .k-board-panel > .k-head { display: none; }   /* its news is in its centre */
  html[data-k-phone] .k-table .k-col--c > .k-rows-extra { display: none; }
  /* the compressed view on a phone (S4-75): the rows keep their height and the
     strip under them gets what is left of the square, so it is two short lines,
     the dice and the clock on the left, the message and the log (which only
     shrinks) on the right; nothing in it reaches past the board's edge */
  html[data-k-phone] .k-boardwrap[data-view="rows"] > .k-strip { --k-u: 5px; overflow: hidden; }
  html[data-k-phone] .k-boardwrap[data-view="rows"] > .k-strip > .k-centre {
    min-height: 0; overflow: hidden; padding: 6px var(--k-pad); gap: 4px 12px;
    grid-template-columns: max-content minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr);
  }
  html[data-k-phone] .k-strip .k-cmsg { grid-row: 1; grid-column: 2; align-self: center; }
  html[data-k-phone] .k-strip .k-clock { grid-row: 2; grid-column: 1; }
  html[data-k-phone] .k-strip .k-flog { grid-row: 2; grid-column: 2; max-height: 100%; }

  /* one panel at a time in the dock; the top panel always */
  html[data-k-phone] .k-table > :is(.k-col--a, .k-col--b) > .k-panel { display: none; grid-area: dock; }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > :is(#k-you, [data-k-shell="k-you"]),
  html[data-k-phone] .k-app[data-k-screen="room"] .k-table .k-col > :is(#k-room, [data-k-shell="k-room"]) { display: flex; grid-area: top; }
  html[data-k-phone] .k-table[data-k-dock="players"] .k-col > :is(#k-players, [data-k-shell="k-players"]):not([hidden]),
  html[data-k-phone] .k-table[data-k-dock="trades"] .k-col > :is(#k-trades, [data-k-shell="k-trades"], #k-gamestats):not([hidden]),
  html[data-k-phone] .k-table[data-k-dock="holdings"] .k-col > :is(#k-holdings, [data-k-shell="k-holdings"]):not([hidden]),
  html[data-k-phone] .k-table:is([data-k-dock="market"], [data-k-dock="log"], [data-k-dock="chat"]) .k-col > :is(#k-desk, [data-k-shell="k-desk"]):not([hidden]),
  html[data-k-phone] .k-table[data-k-dock="settings"] .k-col > :is(#k-settings, [data-k-shell="k-settings"]):not([hidden]),
  html[data-k-phone] .k-app[data-k-screen="room"] .k-table[data-k-dock="chat"] .k-col > :is(#k-chat, [data-k-shell="k-chat"]):not([hidden]) { display: flex; }
  /* a pager in a strip sits at the strip's end when it takes the status's place */
  html[data-k-phone] .k-panel.is-paged > .k-head > .k-stat + .k-pager { margin-left: auto; }
  /* a panel that is as tall as its rows on desktop fills the dock here, and pages */
  html[data-k-phone] .k-table .k-col > .k-panel > .k-body--fit { flex: 1 1 auto; }
  html[data-k-phone] .k-table .k-row--tall { min-height: var(--k-ph-row); }
  /* More is in the bar (thumb reach): the strips' own gear steps aside */
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > :is(#k-players, [data-k-shell="k-players"]) > .k-head > .k-ibtn,
  html[data-k-phone] .k-app[data-k-screen="room"] .k-table .k-col > :is(#k-room, [data-k-shell="k-room"]) > .k-head > .k-ibtn { display: none; }

  /* the desk (Market / Log / Chat): the tab bar picks the tab, so its strip
     shows a title instead of the three tabs; its foot belongs to Market */
  html[data-k-phone] .k-table .k-col > :is(#k-desk, [data-k-shell="k-desk"]) > .k-head > .k-tabs { display: none; }
  html[data-k-phone] .k-table .k-col > #k-desk > .k-head > .k-phoneonly { display: block; order: -1; }
  html[data-k-phone] .k-table .k-col > #k-desk > .k-head > .k-link { order: -2; }
  html[data-k-phone] .k-table .k-col > :is(#k-desk:not([data-k-cur="market"]), [data-k-shell="k-desk"]) > .k-foot { display: none; }

  /* the top panel in the game: You is a panel of figures (.k-panel--cells, set by
     s4-game.js); its shell in the first frame looks the same and shows the first
     three, as the panel's first page does */
  html[data-k-phone] .k-table [data-k-shell="k-you"] > .k-body { flex-direction: row; gap: 0; padding: 7px 0; align-items: stretch; min-height: 48px; }
  html[data-k-phone] .k-table [data-k-shell="k-you"] .k-kv {
    flex: 1 1 0; flex-direction: column; align-items: flex-start; justify-content: center; gap: 4px; min-height: 0; min-width: 0; padding: 0 10px;
  }
  html[data-k-phone] .k-table [data-k-shell="k-you"] .k-kv + .k-kv { border-left: 1px solid var(--k-linesoft); }
  html[data-k-phone] .k-table [data-k-shell="k-you"] .k-kv--big { flex-grow: 1.25; }
  html[data-k-phone] .k-table [data-k-shell="k-you"] .k-kv > .k-k { flex: 0 0 auto; font-size: var(--k-f-xs); }
  html[data-k-phone] .k-table [data-k-shell="k-you"] .k-kv > .k-v { flex: 0 0 auto; text-align: left; font-size: var(--k-f-lg); font-weight: 600; line-height: 1; }
  html[data-k-phone] .k-table [data-k-shell="k-you"] .k-kv--big > .k-v { font-size: var(--k-f-xl); }
  html[data-k-phone] .k-table [data-k-shell="k-you"] > .k-body > .k-kv:nth-child(n+4) { display: none; }

  /* THE DOCK'S FOOT, edge to edge: the action bar (More, then the turn's buttons:
     the board centre's .k-acts, moved here on a phone by s4-table.js) over the
     tab bar (the components above) */
  html[data-k-phone] .k-table > .k-dockbar { display: flex; grid-area: bar; margin: 0 calc(-1 * var(--k-ph-gap)); }
  html[data-k-phone] .k-table > .k-docknav {
    display: flex; grid-area: nav; margin: calc(-1 * var(--k-ph-gap)) calc(-1 * var(--k-ph-gap)) calc(-1 * var(--k-ph-gap));
  }

  /* toasts sit over the board's foot, clear of the turn's buttons */
  html[data-k-phone] .k-toasts { left: var(--k-s2); right: var(--k-s2); width: auto;
                                 bottom: calc(var(--k-ph-bar) + var(--k-ph-nav) + var(--k-s2)); }
}
/* ══ SKETCH 4.11, THE REVIEW: A SHORT PHONE, AND A PHONE ON ITS SIDE ═══════
 * Every phone test and gallery had run at 390 x 844, Chrome's device size with
 * no browser bars; this page never scrolls, so a phone browser's bars never
 * hide. UNDER 640 PX TALL (an iPhone SE in Safari is 375 x 553, an Android
 * phone with Chrome's bars 360 x 560) the board kept its 280 px floor and the
 * dock had what was left: 26-33 px of body at those two, so no tab's first
 * row, Market's desks or Chat's composer could be reached, and up to 623 px
 * Holdings' first deed and Market's first stock were still cut. There the You
 * panel folds to its strip, which carries the cash (YOU · $1,500 · LEVERAGE:
 * s4-game.js placeYouCash moves the figure up; Leverage opens the rest), and
 * the dock gets the 52 px its figures took. The shell does the same in the
 * first frame. */
.k-table [data-k-shell="k-you"] > .k-head > .k-cash { display: none; }
:is(#k-you, [data-k-shell="k-you"]) > .k-head > .k-cash {
  flex-direction: row; align-items: center; margin-left: 2px; color: var(--k-head-fg); font-size: var(--k-f-lg);
}
#k-you > .k-head > .k-cash.is-up .k-cash-v { color: var(--k-head-up); }
#k-you > .k-head > .k-cash.is-down .k-cash-v { color: var(--k-head-down); }
/* its change beside it, in the strip's own money colours */
#k-you > .k-head > .k-cash > .k-delta { top: 0; bottom: 0; right: auto; left: calc(100% + 6px); display: flex; align-items: center; }
#k-you > .k-head > .k-cash > .k-delta.is-up { color: var(--k-head-up); }
#k-you > .k-head > .k-cash > .k-delta.is-down { color: var(--k-head-down); }
@media (max-width: 899px) and (max-height: 639px) {
  /* the game: You is its strip, with the cash in it; and the table a little
     tighter, 4 px between its parts and the tab bar 46 px */
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table { --k-ph-top: calc(var(--k-head-h) + 2px); --k-ph-gap: 4px; --k-ph-nav: 46px; }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table > .k-docknav > .k-tab { padding: 5px 2px 3px; }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > :is(#k-you, [data-k-shell="k-you"]) > .k-body,
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > :is(#k-you, [data-k-shell="k-you"]) > .k-head > :is(.k-stat, .k-pager) { display: none; }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > [data-k-shell="k-you"] > .k-head > .k-cash { display: inline-flex; }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > :is(#k-you, [data-k-shell="k-you"]) > .k-head > .k-hbtn { margin-left: auto; }
  /* each dock tab keeps a whole first row: Market's foot 6 px from its stocks,
     Holdings' list against its pager's bar (a set's header and its first deed) */
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > #k-desk > .k-foot { padding: 6px var(--k-pad); }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > #k-holdings > .k-body > .k-pane { gap: 0; }
  /* Chat: its channels are its strip (as Holdings' tabs are Holdings'), so the
     messages keep a row over the composer (the tab bar under it says Chat) */
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > #k-desk[data-k-cur="chat"] > .k-head { display: none; }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > #k-desk .k-chatpane { gap: 6px; padding-bottom: 6px; }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > #k-desk .k-chatbar {
    min-height: var(--k-head-h); border-bottom: 0; background: var(--k-head-bg); color: var(--k-head-fg);
  }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > #k-desk .k-chatbar .k-chtab { border-bottom: 0; color: var(--k-head-fg); }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > #k-desk .k-chatbar .k-chtab:hover { background: var(--k-head-fg); color: var(--k-head-bg); }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > #k-desk .k-chatbar .k-chtab[aria-selected="true"] { background: var(--k-panel); color: var(--k-ink); }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > #k-desk .k-chatbar .k-watch { color: var(--k-head-soft); }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > #k-desk .k-chatbar .k-pager { color: var(--k-head-fg); }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > #k-desk .k-chatbar .k-pager > button { border-color: var(--k-head-fg); color: var(--k-head-fg); }
}
/* THE PRE-LOBBY shares the table, and on a phone with its browser's bars the
   host's six bot buttons (79 px) left the first seat 45 px of its 48 at
   390 x 664 (an iPhone in Safari) and 41 at 360 x 640: under 720 px tall the
   room's card is its strip and the link, 6 px round it, and the table has the
   game's short-phone spacing */
@media (max-width: 899px) and (max-height: 719px) {
  html[data-k-phone] .k-app[data-k-screen="room"] .k-table { --k-ph-gap: 4px; --k-ph-nav: 46px; }
  html[data-k-phone] .k-app[data-k-screen="room"] .k-table > .k-docknav > .k-tab { padding: 5px 2px 3px; }
  html[data-k-phone] .k-app[data-k-screen="room"] .k-table .k-col > :is(#k-room, [data-k-shell="k-room"]) > .k-body { padding: 6px var(--k-pad); gap: 0; }
}
/* A PHONE ON ITS SIDE (844 x 390, 740 x 360, 667 x 375: up to 500 px tall) had
 * no layout of its own: the one column left the top panel and the dock 0 px
 * tall, so the cash, the AUTO switch and every dock tab were out of sight. Two
 * columns: on the left the board, a square as tall as the window (narrower only
 * when the right column would be under --k-ph-side); on the right the top panel
 * (the game's You folded to its strip, as above), the dock's panel, the turn's
 * buttons and the tab bar, which reach the window's right edge and foot. */
@media (max-width: 899px) and (max-height: 500px) and (orientation: landscape) {
  html[data-k-phone] .k-table {
    --k-sq: min(calc(100dvh - 2 * var(--k-ph-gap) - 2px),
                calc(100vw - 3 * var(--k-ph-gap) - 2px - var(--k-ph-side)));
    grid-template-columns: calc(var(--k-sq) + 2px) minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr) auto auto;
    grid-template-areas: "board top" "board dock" "board bar" "board nav";
  }
  html[data-k-phone] .k-table > .k-col--c { justify-content: center; }
  html[data-k-phone] .k-table .k-col--c > .k-board-panel { flex: 0 0 auto; height: calc(var(--k-sq) + 2px); }
  html[data-k-phone] .k-table > .k-dockbar { margin: 0 calc(-1 * var(--k-ph-gap)) 0 0; }
  html[data-k-phone] .k-table > .k-docknav { margin: calc(-1 * var(--k-ph-gap)) calc(-1 * var(--k-ph-gap)) calc(-1 * var(--k-ph-gap)) 0; }
}
@media (max-width: 899px) {
  /* the board on a phone: tiles about 31 x 49 px. Each tile keeps its parts
     (richup's logic), packed tighter: names on one line height, a little less
     padding; the corners drop their small caption (the name and the icon say
     it). A word still too wide is split with a hyphen (Board.fitNames). */
  html[data-k-phone] .k-table .k-tname { line-height: 1.02; }
  html[data-k-phone] .k-table { --k-tb-x: 1px; --k-tb-y: 1px; --k-tb-in: 1.8; }
  /* SKETCH 4.2, item 16: EVERY NAME WHOLE ON THE PHONE (Board.fitNames' phone
     steps; each class is put on a tile whose name needs it, and no other). A name
     too tall takes the tile's free room: a tile with no round flag (an airport, a
     utility, a tax, a card tile) the flag's strip at its inner edge, a card tile
     the place its price would have (.is-roomy); its lines a little closer
     (.is-close); last, the name drawn smaller as a whole, laid out as wide as it
     will be drawn (.is-fit, --k-nfs: 0.9 down): a phone set to larger text draws
     letters no smaller than it asks, whatever the font size says */
  html[data-k-phone] .k-table .k-tile.is-roomy:not([data-flag])[data-side="top"] > .k-tbody    { padding-bottom: var(--k-tb-y); }
  html[data-k-phone] .k-table .k-tile.is-roomy:not([data-flag])[data-side="bottom"] > .k-tbody { padding-top: var(--k-tb-y); }
  html[data-k-phone] .k-table .k-tile.is-roomy:not([data-flag])[data-side="right"] > .k-tbody  { padding-left: var(--k-tb-y); }
  html[data-k-phone] .k-table .k-tile.is-roomy:not([data-flag])[data-side="left"] > .k-tbody   { padding-right: var(--k-tb-y); }
  html[data-k-phone] .k-table .k-tile.is-roomy:is([data-kind="chance"], [data-kind="treasure"]) > .k-tag { display: none; }
  html[data-k-phone] .k-table .k-tname.is-close { line-height: .9; }
  html[data-k-phone] .k-table .k-tname.is-fit { flex: none; max-inline-size: none; inline-size: calc(100% / var(--k-nfs, 1));
                                                transform: scale(var(--k-nfs, 1)); }
  /* a phone's side tiles keep sketch 4's level names (S4-67): along the edge a
     phone tile is 21-28 px, too short for a turned name; across it, 37-49 px
     (sketch 4.1, S41-13). The price pill and the owner block stay on the edge. */
  html[data-k-phone] .k-table .k-tile:is([data-side="left"], [data-side="right"]) { writing-mode: horizontal-tb; }
  html[data-k-phone] .k-table .k-tile[data-side="left"]  { flex-direction: row; }
  html[data-k-phone] .k-table .k-tile[data-side="right"] { flex-direction: row-reverse; }
  html[data-k-phone] .k-table .k-tile:is([data-side="left"], [data-side="right"]) .k-tag { writing-mode: vertical-rl; }
  html[data-k-phone] .k-table .k-tile[data-side="left"] .k-tag { transform: rotate(180deg); }
  /* the tokens on a phone (sketch 4.12, item 10): a size bigger than on desktop
     (the board's unit is small there); two side by side across a tile, inside its
     name area (sketch 4.2, item 7) */
  html[data-k-phone] .k-table :is(.k-sq, .k-rowsbox) { --k-tk: calc(3.4 * var(--k-u)); --k-tkp: 1px; --k-tkr: 2.5px; }
  html[data-k-phone] .k-table .k-tbody { gap: calc(.3 * var(--k-u)); }
  html[data-k-phone] .k-table .k-tile.is-corner { gap: calc(.3 * var(--k-u)); }
  html[data-k-phone] .k-table .k-tile.is-corner .k-tsub { display: none; }
  html[data-k-phone] .k-table .k-tile.is-corner .k-tic { width: calc(3.6 * var(--k-u)); height: calc(3.6 * var(--k-u)); }
  /* a corner with players on it (sketch 4.12): its name and the tokens' band
     share 13 units, so GO's and Jail's icon is smaller and Vacation's and Go to
     Prison's (their names take two lines on a phone) steps aside, as does any
     corner's for five or six */
  html[data-k-phone] .k-table .k-tile.is-corner[data-tk] .k-tic { width: calc(2.4 * var(--k-u)); height: calc(2.4 * var(--k-u)); }
  html[data-k-phone] .k-table .k-sq > .k-tile.is-corner:is([data-tile="20"], [data-tile="30"])[data-tk] .k-tic,
  html[data-k-phone] .k-table .k-tile.is-corner:is([data-tk="4"], [data-tk="5"], [data-tk="6"]) .k-tic { display: none; }
  /* and, its icon away, four stand in two rows of two and five or six in two
     rows of three, each as big as three fit across the corner (GO at a game's
     start: 9 px tokens on a 280 px board, not 6) */
  html[data-k-phone] .k-table .k-sq > .k-tile.is-corner:is([data-tk="4"], [data-tk="5"], [data-tk="6"]) {
    --k-tcc: min(var(--k-tk), calc((var(--k-tcw) - 2 * var(--k-tkg)) / 3)); --k-tkb: calc(2 * var(--k-tcc) + var(--k-tkg) + 2 * var(--k-tki)); }
  html[data-k-phone] .k-table .k-sq > .k-tile.is-corner[data-tk="4"] > .k-ttok { left: auto; width: calc(2 * var(--k-tcc) + var(--k-tkg)); }
  html[data-k-phone] .k-table .k-sq > .k-tile.is-corner:is([data-tile="10"], [data-tile="20"])[data-tk="4"] > .k-ttok { left: var(--k-tki); right: auto; }
}
@media (max-width: 899px) {
  /* the game's windows on a phone: the big ones (the trades, the desks, an
     offer, the statistics, Ownership) are full-screen sheets, the small ones
     (Raise, the confirms, Settings) a card the width of the screen */
  html[data-k-phone] dialog.k-modal { width: calc(100vw - 2 * var(--k-ph-gap)); max-width: none;
                                      max-height: calc(100vh - 2 * var(--k-ph-gap)); max-height: calc(100dvh - 2 * var(--k-ph-gap)); }
  html[data-k-phone] dialog.k-modal:is(.k-modal--trade, .k-modal--quick, .k-modal--desk, .k-modal--offer) {
    width: 100vw; height: 100vh; height: 100dvh; max-height: none; margin: 0; border: 0; border-radius: 0;
  }
  html[data-k-phone] dialog.k-modal > .k-panel > .k-body > .k-dgrid { padding: var(--k-ph-gap); gap: var(--k-ph-gap); }
  /* Ownership: one column of sets, paged (s4-game.js) */
  html[data-k-phone] .k-owngrid { grid-template-columns: minmax(0, 1fr); flex: 1 1 auto; min-height: 0; overflow: hidden; gap: 2px; }
}
@media (max-width: 899px) {
  /* THE MENU on a phone, in today's order: the wordmark takes the space left at
     the top, then your name (and Sign in), Start a Game and four tiles, the
     tucked-away code line, the links. Find a lobby opens the list as a screen of
     its own (the one list that may scroll). */
  html[data-k-phone] .k-menuscr { display: grid; grid-template-rows: auto minmax(0, 1fr); height: 100vh; height: 100dvh;
                                  overflow: hidden; background: var(--k-bg); }
  html[data-k-phone] .k-menuscr .k-topbar { gap: var(--k-s3); padding: 0 var(--k-s3); }
  html[data-k-phone] .k-menuscr .k-topbar > .k-mark,
  html[data-k-phone] .k-menuscr .k-topbar > .k-label { display: none; }
  html[data-k-phone] .k-menugrid { display: flex; flex-direction: column; min-height: 0; padding: var(--k-ph-gap); gap: var(--k-ph-gap); }
  html[data-k-phone] .k-menugrid > .k-col { flex: 1 1 auto; gap: var(--k-ph-gap); }
  html[data-k-phone] .k-menugrid > .k-col > .k-panel { flex: 0 0 auto; }
  html[data-k-phone] .k-menuscr .k-phoneonly { display: inline-flex; }
  html[data-k-phone] .k-menuhero.k-phoneonly {
    display: flex; flex: 1 1 auto; min-height: 96px; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  }
  .k-mark--hero { font-size: 40px; letter-spacing: .01em; }
  .k-heroline { display: flex; width: 92px; height: 3px; }
  .k-heroline > i { flex: 1 1 0; background: var(--k-pc); }
  /* your name, and Sign in beside it */
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-you"] > .k-body {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; column-gap: var(--k-s2); row-gap: 6px;
  }
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-you"] > .k-body > .k-empty { grid-column: 1 / -1; }
  html[data-k-phone] #k-name, html[data-k-phone] #k-signin { height: 40px; }
  /* Start a Game, then the four tiles (today's 2 x 2) */
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-play"] > .k-body {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--k-s2);
  }
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-play"] > .k-body > .k-hero { grid-column: 1 / -1; }
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-play"] > .k-body > .k-line { display: contents; }
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-play"] .k-btn:not(.k-btn--pri) {
    width: auto; height: 60px; flex-direction: column; gap: 6px; padding: 0 6px; white-space: normal; text-align: center; line-height: 1.15;
  }
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-play"] .k-btn .k-tic { width: 20px; height: 20px; stroke: currentColor; }
  html[data-k-phone] #k-bots { order: 1; } html[data-k-phone] #k-find { order: 2; }
  html[data-k-phone] #k-create { order: 3; } html[data-k-phone] #k-private { order: 4; }
  /* Join by code: a line until it is opened */
  .k-codeline {
    display: none; align-items: center; justify-content: center; gap: 6px; flex: 0 0 auto; height: 36px; margin: 0; padding: 0;
    border: 0; background: transparent; color: var(--k-dim); cursor: pointer; font: 400 var(--k-f-md)/1 var(--k-sans);
  }
  .k-codeline u { color: var(--k-ink); text-underline-offset: 3px; }
  .k-codeline .k-tic { width: 15px; height: 15px; stroke: currentColor; }
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-code"] { display: none; }
  html[data-k-phone] .k-menuscr.is-code .k-menugrid section[aria-labelledby="k-h-code"] { display: flex; }
  html[data-k-phone] .k-menuscr.is-code .k-codeline { display: none; }
  /* the links: a short panel at the foot */
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-about"] { flex: 0 0 auto; }
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-about"] > .k-body > .k-empty { display: none; }
  /* THE LOBBY LIST: a screen of its own, over the menu, with Back in its strip */
  html[data-k-phone] .k-menugrid > #k-lobbies { display: none; }
  html[data-k-phone] .k-menuscr.is-rooms .k-menugrid > #k-lobbies {
    display: flex; position: fixed; inset: 0; z-index: 5; border: 0; border-radius: 0;
  }
  html[data-k-phone] #k-lobbies .k-head > #k-rooms-back { display: inline-grid; margin-left: -6px; }
  html[data-k-phone] #k-lobbies .k-head > #k-rooms-stat { display: none; }       /* the list says it: open, then in play */
  html[data-k-phone] #k-lobbies .k-head > #k-rooms-back .k-tic { width: 18px; height: 18px; stroke: currentColor; }
  html[data-k-phone] #k-lobbies > .k-body > .k-line { flex-wrap: wrap; }
  html[data-k-phone] #k-lobbies #k-search { flex-basis: 100%; height: 36px; }
  html[data-k-phone] .k-room { grid-template-columns: minmax(0, 1fr); }
  html[data-k-phone] .k-room-side { flex-direction: row; align-items: center; justify-content: space-between; }
  html[data-k-phone] .k-room-side > .k-rules { justify-content: flex-start; }
}
@media (max-width: 899px) and (max-height: 699px) {
  /* THE MENU ON A SHORT PHONE (390x664, an iPhone in Safari; 375x553, an SE): the
     whole menu on one screen, nothing scrolling (S42-88 (a), the fix step): the
     hero is the wordmark alone, the name's hint goes (the field says it), the
     About links are two short lines under the code line, without their panel's
     strip, each a 24 px tap; an opened code is its field and Join, no strip.
     Delete account (Google Play's account-deletion rule), Terms and Join by code
     are whole and reached by a thumb. */
  html[data-k-phone] .k-menuhero.k-phoneonly { min-height: 0; gap: 0; overflow: hidden; }
  html[data-k-phone] .k-menuhero > .k-heroline, html[data-k-phone] .k-menuhero > .k-label { display: none; }
  html[data-k-phone] .k-menuhero > .k-mark--hero { font-size: 34px; line-height: 1.1; }
  html[data-k-phone] #k-name-hint { display: none; }
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-about"] { border: 0; background: transparent; box-shadow: none; }
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-about"] > .k-head { display: none; }
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-about"] > .k-body { padding: 0; }
  html[data-k-phone] .k-menugrid .k-links { justify-content: center; gap: 2px var(--k-s3); }
  html[data-k-phone] .k-menugrid .k-links > a { padding: 5px 0; }
  html[data-k-phone] .k-menuscr.is-code .k-menugrid section[aria-labelledby="k-h-code"] > .k-head { display: none; }
  html[data-k-phone] .k-menuscr.is-code .k-menugrid section[aria-labelledby="k-h-code"] > .k-body { padding: 6px var(--k-s3); }
}
@media (max-width: 899px) and (max-height: 599px) {
  /* shorter still (375x553): the wordmark moves into the top strip, beside the
     connection, where desktop has it, and the hero's room goes to the menu */
  html[data-k-phone] .k-menuhero.k-phoneonly { display: none; }
  html[data-k-phone] .k-menuscr .k-topbar > .k-mark { display: inline-flex; }
  /* and Start's "Opens a new lobby" goes (its name says it), the four tiles 54 px
     (was 60): an opened code with "Lobby not found" under it keeps Delete account
     on the screen */
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-play"] > .k-body > .k-hero > .k-sub { display: none; }
  html[data-k-phone] .k-menugrid section[aria-labelledby="k-h-play"] .k-btn:not(.k-btn--pri) { height: 54px; }
}
@media (max-width: 899px) {
  /* TRADES on a phone: the partners are a row of tabs under the strip; the
     quick trade's two sides are one over the other (the swap mark between);
     Every term and an offer are tab stacks (s4-trade.js); the foot puts what
     the game says on its own line over the buttons */
  html[data-k-phone] .k-panel > .k-tabs.k-partners .k-tab { gap: 6px; text-transform: none; letter-spacing: 0; font: 600 var(--k-f-md)/1 var(--k-sans); }
  html[data-k-phone] .k-tq { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) 22px minmax(0, 1fr); }
  html[data-k-phone] .k-swapmark { transform: rotate(90deg); background: transparent; }
  html[data-k-phone] .k-tside .k-body { gap: 8px; }
  html[data-k-phone] .k-dgrid > .k-tabs.k-stacktabs { border: 1px solid var(--k-linesoft); border-bottom-color: var(--k-line); }
  html[data-k-phone] dialog.k-modal .k-foot.k-foot--bar { flex-wrap: wrap; row-gap: 6px; }
  html[data-k-phone] dialog.k-modal .k-foot.k-foot--bar > .k-say { order: -1; flex: 1 1 100%; }
  html[data-k-phone] dialog.k-modal .k-foot.k-foot--bar > .k-say:empty { display: none; }
  html[data-k-phone] dialog.k-modal .k-foot.k-foot--bar > .k-btn--lg { flex: 1 1 auto; min-width: 0; padding: 0 12px; overflow: hidden; text-overflow: ellipsis; }
  html[data-k-phone] .k-ocol-h { padding: 0 8px; }
  html[data-k-phone] .k-oline { padding-right: 6px; }
}
/* the before/after numbers, one player a block (a phone's sheet, s4-trade.js) */
.k-itab.k-itab--one { grid-template-columns: minmax(0, 1.3fr) repeat(2, minmax(0, 1fr)) 3.6em; }
.k-itab--one > .k-ihead { grid-column: 1 / -1; gap: 6px; min-height: 26px; color: var(--k-ink); border-bottom-color: var(--k-line); }
.k-itab--one + .k-itab--one { margin-top: var(--k-s3); }
@media (max-width: 899px) {
  /* THE DESKS on a phone: one column. Stocks: a row of tickers to pick from,
     the picked stock's chart and ticket, your own stock. Bonds: Rates is the
     first of the bond tabs. Leverage: the metrics are tabs over one chart. */
  html[data-k-phone] .k-dgrid.k-deskgrid--phone { grid-template-columns: minmax(0, 1fr); }
  html[data-k-phone] .k-head > .k-tabs .k-tab { padding: 0 8px; letter-spacing: .05em; }
  html[data-k-phone] .k-ticket { grid-template-columns: 40px repeat(4, minmax(0, 1fr)); gap: 5px; }
  html[data-k-phone] .k-amt { height: 48px; }
  html[data-k-phone] .k-headline { row-gap: 6px; }
  html[data-k-phone] .k-headline .k-big { font-size: 24px; }
  /* the statistics: the tabs are the strip, so its title steps aside */
  html[data-k-phone] #k-stats > .k-panel > .k-head > .k-title { display: none; }
  html[data-k-phone] .k-stat-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  html[data-k-phone] .k-stat-tile { padding: 8px 10px; gap: 4px; }
  html[data-k-phone] .k-stat-tile .k-big { font-size: 18px; }
  html[data-k-phone] .k-winner { padding: 10px; }
  html[data-k-phone] .k-winner .k-name { font-size: 18px; }
  html[data-k-phone] .k-winner .k-big { font-size: 22px; }
}
/* the phone's row of tickers (the stock desk): the player's colour on the left */
.k-tickers { display: flex; flex-wrap: wrap; gap: 6px; }
.k-chip.k-tickchip { position: relative; height: 32px; padding: 0 9px 0 11px; gap: 7px; text-transform: none; letter-spacing: 0; }
.k-tickchip::before { content: ""; position: absolute; left: 0; top: 5px; bottom: 5px; width: var(--k-mark-w); background: var(--k-pc, var(--k-line)); }
.k-tickchip .k-v { font: 600 var(--k-f-sm)/1 var(--k-mono); color: var(--k-dim); }
.k-tickchip.is-on { background: var(--k-accentsoft); border-color: var(--k-accentedge); }
.k-tickchip.is-on .k-v { color: var(--k-ink); }
/* a tile too short for its two-line name and its icon drops the icon, and packs
   the name and the houses with no gap (Board.fitNames; a phone's narrowest board) */
.k-tile.is-tight .k-tbody > .k-tic { display: none; }
.k-tile.is-tight .k-tbody { gap: 0; }
.k-tile.is-tight .k-tname { line-height: .98; }
@media (max-width: 899px) {
  /* a quick trade side's deeds page there (s4-trade.js), in the space under the cash */
  html[data-k-phone] .k-tside .k-chips { flex: 1 1 auto; min-height: 0; overflow: hidden; }
}

/* ══ SKETCH 4.1, items 10 and 11: THE TICKER TAPE, and the strip under the
   compressed board (static/js/s4-tape.js) ════════════════════════════════
   One tape component: a viewport that clips, a track that moves by one
   transform animation (its own layer, no layout per frame), copies of the
   items inside. Every figure has a fixed-width slot (mono digits), so a new
   price changes text, never the tape's shape. Its colours are tokens
   (--k-tt-*, kit-tokens.css), swapped for the strip's own on a header strip.
   The edges fade by a mask (only its alpha counts; the ink is just opaque). */
.k-tape { display: flex; align-items: stretch; min-width: 0; color: var(--k-tt-ink); }
.k-tape-vp {
  position: relative; flex: 1 1 auto; min-width: 0; overflow: hidden; contain: strict;
  -webkit-mask-image: linear-gradient(90deg, transparent, var(--k-ink) 14px, var(--k-ink) calc(100% - 14px), transparent);
          mask-image: linear-gradient(90deg, transparent, var(--k-ink) 14px, var(--k-ink) calc(100% - 14px), transparent);
}
.k-tape-track { position: absolute; top: 0; bottom: 0; left: 0; display: flex; align-items: center; white-space: nowrap; will-change: transform; }
.k-tape-copy { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 14px; padding-right: 14px; }
.k-tt { display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto; font: 500 var(--k-f-sm)/1 var(--k-mono); color: var(--k-tt-ink); }
.k-tt .k-pdot { width: 7px; height: 7px; }
.k-tt-sym { font-weight: 700; letter-spacing: .04em; }
.k-tt-you { padding: 2px 3px; border: 1px solid currentColor; border-radius: var(--k-radius); font: 600 8px/1 var(--k-mono); letter-spacing: .08em; text-transform: uppercase; opacity: .8; }
.k-tt-v { min-width: 7ch; text-align: right; font-weight: 600; }
.k-tt-v.is-halted { color: var(--k-tt-dim); text-transform: uppercase; letter-spacing: .06em; }
.k-tt.is-halted > .k-tt-d, .k-tt.is-halted > .k-tt-p { display: none; }
.k-tt-d { min-width: 9ch; }
.k-tt-p { min-width: 6ch; }
.k-tt-r { min-width: 5ch; text-align: right; }
.k-tt-r.is-off { color: var(--k-tt-dim); }
.k-tt-s { min-width: 3ch; font-weight: 700; text-transform: uppercase; }
.is-up.k-tt-d, .is-up.k-tt-p, .k-tt-s.is-on { color: var(--k-tt-up); }
.is-down.k-tt-d, .is-down.k-tt-p { color: var(--k-tt-down); }
.is-flat.k-tt-d, .k-tt-s.is-off { color: var(--k-tt-dim); }
.k-tt-grp { display: inline-flex; align-items: center; gap: 12px; flex: 0 0 auto; }
.k-tt-lab { font: 600 9px/1 var(--k-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--k-tt-dim); }
.k-tt-sep { flex: 0 0 auto; width: 1px; height: 12px; background: currentColor; opacity: .25; }
/* item 10: in the board panel's strip, between its title and the turn's status,
   in the strip's own colours (the dots ringed so a light seat colour holds) */
.k-tape--head {
  --k-tt-ink: var(--k-head-fg); --k-tt-dim: var(--k-head-fg); --k-tt-up: var(--k-head-up); --k-tt-down: var(--k-head-down);
  flex: 1 1 auto; align-self: stretch; margin: 0 2px;
}
.k-tape--head .k-tt .k-pdot { box-shadow: 0 0 0 1px var(--k-head-fg); }
.k-tape--head .is-flat.k-tt-d, .k-tape--head .k-tt-s.is-off, .k-tape--head .k-tt-lab { opacity: .7; }
@media (min-width: 900px) and (max-width: 1279px) {
  /* half-width: the turn's status is in the board's centre already; the tape takes its room */
  .k-board-panel.has-tape > .k-head > .k-stat { display: none; }
}
/* item 11: the strip under the compressed board (wide desktop) */
.k-lower > .k-body > .k-pane { gap: 0; }
.k-tlines { display: flex; flex-direction: column; }
.k-tape--line { flex: 1 1 0; min-height: 0; align-items: stretch; border-bottom: 1px solid var(--k-linesoft); }
.k-tape--line:last-child { border-bottom: 0; }
.k-tape--line .k-tape-cap {
  flex: 0 0 auto; display: flex; align-items: center; width: 17ch; padding: 0 10px 0 var(--k-pad);
  border-right: 1px solid var(--k-linesoft); background: var(--k-panelalt);
  font: 600 var(--k-f-xs)/1.3 var(--k-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--k-dim);
}
.k-tape--line .k-tt { gap: 7px; font-size: var(--k-f-lg); }
.k-tape--line .k-tt .k-pdot { width: 9px; height: 9px; }
.k-tape--line .k-tape-copy { gap: 22px; padding-right: 22px; }
.k-tape--line .k-tt-you { font-size: 9px; }
.k-tape-calm { position: absolute; inset: 0; display: flex; align-items: center; padding: 0 var(--k-pad); color: var(--k-dim); font: 400 var(--k-f-sm)/1.3 var(--k-sans); }
/* Standings: every player in one row of cards, by net worth */
.k-standings { flex-direction: row; align-items: stretch; gap: var(--k-s2); padding: 10px var(--k-pad); overflow: hidden; }
.k-stand {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 4px;
  padding: 8px 10px; background: var(--k-panelalt); border: 1px solid var(--k-linesoft); border-left: var(--k-mark-w) solid var(--k-pc, var(--k-line));
  border-radius: var(--k-radius);
}
.k-stand.is-you { border-color: var(--k-accentedge); border-left-color: var(--k-pc, var(--k-accentedge)); }
.k-stand.is-out { opacity: .5; }
.k-stand-top { display: flex; align-items: center; gap: 7px; min-width: 0; margin-bottom: 2px; }
.k-stand-top .k-token { width: 22px; height: 22px; font-size: 11px; }
.k-stand-top .k-name { font: 600 var(--k-f-md)/1.2 var(--k-sans); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.k-stand-rank { flex: 0 0 auto; font: 700 var(--k-f-sm)/1 var(--k-mono); color: var(--k-dim); }
.k-stand .k-kv { min-height: 18px; }
.k-stand .k-kv .k-v { font-weight: 600; }
.k-stand-bar { margin-top: 2px; }
/* Events: the last log lines, newest first, as many as fit */
.k-events { padding: 6px 0; overflow: hidden; gap: 2px; }
.k-events > .k-event { padding: 0 var(--k-pad); }
/* item 10 on a phone: a slim row over the board (the dock gives the height) */
.k-taperow { display: none; }
@media (max-width: 899px) {
  html[data-k-phone] .k-table.has-tape {
    grid-template-rows: auto var(--k-ph-tape) calc(var(--k-sq) + 2px) minmax(0, 1fr) auto auto;
    grid-template-areas: "top" "tape" "board" "dock" "bar" "nav";
  }
  html[data-k-phone] .k-table.has-tape > .k-taperow:not([hidden]) {
    display: flex; grid-area: tape; min-width: 0;
    background: var(--k-panel); border: 1px solid var(--k-line); border-radius: var(--k-radius);
  }
  html[data-k-phone] .k-taperow > .k-tape { flex: 1 1 auto; }
  /* the phone's row is a panel, not a strip: the tape in the panel's own ink
     (sketch 4.11: it had the strip's, dark on the dark panel) */
  html[data-k-phone] .k-taperow > .k-tape--head {
    --k-tt-ink: var(--k-ink); --k-tt-dim: var(--k-dim); --k-tt-up: var(--k-postext); --k-tt-down: var(--k-negtext);
  }
  html[data-k-phone] .k-taperow > .k-tape--head .k-tt .k-pdot { box-shadow: none; }
}
/* sketch 4.11, the review: on its side the tape's row is under the You strip,
   in the column beside the board (kit.css, A PHONE ON ITS SIDE); upright under
   640 px tall it steps aside, the grid as without it: the panels under the
   board need its 30 px for each tab's first row (S411-43), and the prices are a
   tap away in Market. Turned on its side, the phone shows it again. */
@media (max-width: 899px) and (max-height: 500px) and (orientation: landscape) {
  html[data-k-phone] .k-table.has-tape {
    grid-template-rows: auto var(--k-ph-tape) minmax(0, 1fr) auto auto;
    grid-template-areas: "board top" "board tape" "board dock" "board bar" "board nav";
  }
}
@media (max-width: 899px) and (max-height: 639px) and (orientation: portrait) {
  html[data-k-phone] .k-table.has-tape {
    grid-template-rows: auto calc(var(--k-sq) + 2px) minmax(0, 1fr) auto auto;
    grid-template-areas: "top" "board" "dock" "bar" "nav";
  }
  html[data-k-phone] .k-table.has-tape > .k-taperow:not([hidden]) { display: none; }
}

/* ══ SKETCH 4.1, item 12: THE CHAT'S TWO CHANNELS, who watches, what is new ══
   Table and Spectators are tabs on the chat's slim bar, each with its unread
   count; the bar also says how many are watching; the total is on the desk's
   Chat tab, the phone's Chat tab and the half-width bubble (s4-game.js). */
.k-chatpane > .k-chatbox:not([hidden]) { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: var(--k-s2); }
.k-chatbar { gap: 6px; padding-right: 6px; }
.k-chtabs { display: inline-flex; align-self: stretch; margin-left: calc(-1 * var(--k-pad)); min-width: 0; }
.k-chtab {
  display: inline-flex; align-items: center; gap: 5px; margin: 0; padding: 0 10px 0 var(--k-pad); min-width: 0;
  border: 0; border-bottom: 2px solid transparent; background: transparent; color: var(--k-dim); cursor: pointer;
  font: 500 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
}
.k-chtab + .k-chtab { padding-left: 10px; }
.k-chtab:hover { color: var(--k-ink); background: var(--k-selbg); }
.k-chtab[aria-selected="true"] { color: var(--k-ink); font-weight: 700; border-bottom-color: var(--k-accent); }
.k-chtab:focus-visible { outline: 2px solid var(--k-focus); outline-offset: -2px; }
.k-watch { margin-left: auto; flex: 0 0 auto; font: 500 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--k-dim); white-space: nowrap; }
.k-chatbar > .k-pager { margin-left: 0; }
.k-chatbar > .k-watch[hidden] + .k-pager, .k-chatbar > .k-watch[hidden] ~ .k-pager { margin-left: auto; }
.k-chatlock {
  display: flex; align-items: center; gap: var(--k-s2); flex: 0 0 auto; min-height: var(--k-btn-h); padding: 6px 6px 6px 10px;
  border: 1px dashed var(--k-line); border-radius: var(--k-radius); color: var(--k-dim); font: 400 var(--k-f-sm)/1.35 var(--k-sans);
}
.k-chatlock > .k-btn { flex: 0 0 auto; }
/* the count of people watching, in the board's strip (desktop) */
.k-bwatch {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px; height: calc(var(--k-head-h) - 8px); margin: 0 0 0 auto; padding: 0 6px;
  border: 0; border-radius: var(--k-radius); background: transparent; color: var(--k-head-fg); cursor: pointer;
  font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .04em;
}
.k-bwatch .k-tic { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; }
.k-bwatch:hover { background: var(--k-head-fg); color: var(--k-head-bg); }
.k-board-panel > .k-head > .k-bwatch:not([hidden]) + .k-stat { margin-left: 0; }

/* ══ SKETCH 4.1, items 14-18: THE PRE-LOBBY (static/js/s4-room.js) ══════════ */
/* item 16: Leave lobby. A row in the room's card on desktop; on a phone, where
   the card is the screen's top panel, its strip's action (no height added) */
.k-leaverow { justify-content: flex-end; }
.k-leaverow > .k-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.k-leavehead { display: none; }
.k-hbtn.k-leavehead { background: var(--k-negtext); color: var(--k-panel); }
.k-hbtn.k-leavehead:hover { background: var(--k-neg); color: var(--k-panel); }
/* items 14 and 15: under the seats, the host's bots (one click each) and Spectate only */
.k-plfoot { flex: 0 0 auto; display: flex; flex-direction: column; gap: 8px; padding: 10px var(--k-pad); border-top: 1px solid var(--k-linesoft); }
.k-botbox { display: flex; flex-direction: column; gap: 6px; }
.k-botgrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.k-btn.k-botbtn {
  display: block; min-width: 0; height: 28px; padding: 0 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font: 600 var(--k-f-sm)/26px var(--k-sans); letter-spacing: 0; text-transform: none;
}
/* SKETCH 4.2, item 1 (V3.2's brief B): LabBot 2.0 are THE bots. "Bot" is the box's
   one bot button, one click; beside it "Classic bots (old)", quiet (no frame, the
   dim ink, a caret), opens the old five in the bots' sheet (s4-room.js). With lab
   bots off the five are the box, as before (.k-botgrid). */
.k-botrow, .k-botpop-main { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px; align-items: center; }
.k-btn.k-botold {
  height: 28px; padding: 0 4px 0 8px; border-color: transparent; color: var(--k-dim);
  font: 500 var(--k-f-sm)/26px var(--k-sans); letter-spacing: 0; text-transform: none;
}
.k-btn.k-botold::after { content: "\25BE"; margin-left: 4px; font-size: 10px; }
/* sketch 4.2, item 12: smaller and quieter, a "?" beside it that says these are the old bots (always shown) */
.k-botoldwrap { display: inline-flex; align-items: center; gap: 2px; min-width: 0; color: var(--k-dim); }
.k-botrow .k-btn.k-botold { height: 24px; padding: 0 2px 0 6px; font-size: var(--k-f-xs); line-height: 22px; opacity: .85; }
.k-botoldwrap > .k-tipq { margin-left: 2px; }
html[data-k-tips="off"] .k-tipq.k-tipq--always { display: inline-flex; }
.k-btn.k-botold[aria-expanded="true"]::after { content: "\25B4"; }
/* quiet under the pointer too: the panel's picked-row fill, not the inverted one (a
   phone's hover stays after a tap, so the inverted fill read as a pressed button) */
.k-btn.k-botold:not([aria-disabled="true"]):not(:disabled):hover,
.k-btn.k-botold[aria-expanded="true"] { background: var(--k-selbg); border-color: transparent; color: var(--k-ink); }
.k-botpop.is-drop .k-btn.k-botbtn { height: 28px; font-size: var(--k-f-sm); line-height: 26px; }
.k-botpop .k-botpop-main + .k-botgrid { margin-top: 8px; }
.k-botpop .k-botpop-main[hidden], .k-botpop .k-botgrid[hidden] { display: none; }
/* SKETCH 4.12, item 8: a seat whose player is still on the last game's results */
.k-row.is-away { opacity: .62; }
/* the fix step: the room's Players strip counts "6 / 6" + " · 1 on results" + " · 1
   watching" (s4-room.js), the last parts stepping aside where the strip is narrow
   (.k-drop), never its title (at 1440x900 "Players" was cut to "P…") */
.k-app[data-k-screen="room"] #k-players > .k-head > .k-title { flex-shrink: 0; }
.k-app[data-k-screen="room"] #k-players > .k-head > .k-stat.k-drop { flex: 0 100 auto; }
/* SKETCH 4.12, the fix step: ON A PHONE THE ROOM'S WORDS STAND OVER THE COLOUR CARD.
   The centre's message (the host's "You host. 2 of 2 ready. 1 still on the
   results.", "You are the host now.") came after the colour card, two rows of
   three on a phone: at the 280 px board (390x664, 375x553) it stood wholly under
   the bottom row of tiles, at 390x844 its second line (V4.11's S411-46 (b)). The
   room's dice are idle, so on a phone they step aside and the message comes
   first, 3 units under the top row (its round flags reach 1.8 into the centre),
   the card under it: at the 280 px board the two lines and the card end 6 px
   above the centre's foot. */
@media (max-width: 899px) {
  html[data-k-phone] .k-app[data-k-screen="room"] .k-sq > .k-centre { padding-top: calc(3 * var(--k-u)); }
  html[data-k-phone] .k-app[data-k-screen="room"] .k-sq > .k-centre > .k-dice { display: none; }
  html[data-k-phone] .k-app[data-k-screen="room"] .k-sq > .k-centre > .k-cmsg { order: -1; }
}
/* SKETCH 4.12, item 14: a short phone's "+ Bot" in the Players strip, and the
   sheet of six it opens (the bots under the seats elsewhere). Shown only by
   the short-phone block below; the host's, like the bots (s4-room.js). */
.k-botadd { display: none; }
.k-botpop > .k-panel > .k-body { padding: 8px var(--k-pad) 10px; }
.k-botpop .k-btn.k-botbtn { height: 40px; font-size: var(--k-f-md); line-height: 38px; }
.k-botpop .k-btn.k-botold { height: 40px; line-height: 38px; }
.k-copyhead { display: none; }
@media (max-width: 899px) and (max-height: 639px) and (orientation: portrait) {
  html[data-k-phone] .k-app[data-k-screen="room"] .k-botbox { display: none; }
  html[data-k-phone] .k-app[data-k-screen="room"] .k-botadd:not([hidden]) { display: inline-flex; }
  /* and the room's card is its strip, Copy in it (S411-46's other half) */
  html[data-k-phone] .k-app[data-k-screen="room"] .k-col > :is(#k-room, [data-k-shell="k-room"]) > .k-body { display: none; }
  html[data-k-phone] .k-app[data-k-screen="room"] .k-col > :is(#k-room, [data-k-shell="k-room"]) > .k-head > .k-copyhead { display: inline-flex; }
  /* the room's settings a whole one a page: the names (each sentence in its
     row's tooltip, as the auto-play options there, S411-35), and no "Only the
     host" line over them (the strip says "read only", the controls are grey) */
  html[data-k-phone] .k-app[data-k-screen="room"] #k-settings .k-opt-d { display: none; }
  html[data-k-phone] .k-app[data-k-screen="room"] #k-settings > .k-body { padding-top: 4px; padding-bottom: 4px; }
  html[data-k-phone] .k-app[data-k-screen="room"] #k-settings > .k-body > .k-empty { display: none; }
  html[data-k-phone] .k-app[data-k-screen="room"] #k-settings .k-opt { min-height: 40px; padding: 4px 0; }
}
/* item 18: Table, Money and Rules at once, each under its heading, where they fit */
.k-optsec { display: none; }
.k-panel.is-all > .k-tabs { display: none; }
.k-root .k-panel.is-all > .k-body > .k-pane[hidden] { display: flex; }
.k-panel.is-all > .k-body > .k-pane { flex: 0 0 auto; gap: 0; }
.k-panel.is-all .k-optsec {
  display: block; padding: 10px 0 4px; border-bottom: 1px solid var(--k-line);
  font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--k-accenttext);
}
.k-panel.is-all > .k-body > .k-pane:first-of-type .k-optsec { padding-top: 0; }
.k-panel.is-all .k-opt { padding: 7px 0; }
.k-panel.is-all.is-compact .k-opt { padding: 5px 0; min-height: 34px; }
.k-panel.is-all.is-compact .k-opt-d { display: none; }
@media (max-width: 899px) {
  html[data-k-phone] .k-leaverow { display: none; }
  html[data-k-phone] .k-app[data-k-screen="room"] .k-col > :is(#k-room, [data-k-shell="k-room"]) > .k-head > .k-leavehead { display: inline-flex; }
  /* the dock is short: the bots two rows of three, no label (the strip and the
     buttons say it), so two seats show a page */
  html[data-k-phone] .k-plfoot { gap: 6px; padding: 8px var(--k-pad); }
  html[data-k-phone] .k-botbox > .k-label { display: none; }
}
@media (min-width: 900px) and (max-width: 1279px) {
  /* half-width: the room's card is narrow; Leave lobby says it all */
  .k-leaverow > .k-sub { display: none; }
}
@media (max-width: 899px) {
  /* a phone's player row is 48 px: the cash change sits 1 px under the figure
     (3 px on desktop), so it stays inside the row (Kit.fit found it 2 px out
     while a payment flashed, sketch 4.1 step 4) */
  html[data-k-phone] .k-row--tall .k-cash > .k-delta { top: calc(100% + 1px); }
}

/* ══ SKETCH 4.1, item 3: THE COLOURS SHEET (static/js/kit-theme.js) ═════════
   A sheet at the side, the whole screen on a phone, with nothing dimmed behind
   it: every pick shows at once on the real screen, which is the preview (the
   sheet itself too: its strip, tabs, fields and buttons are the kit's own).
   A small preview at its top shows what the sheet does not: player rows and
   their cash changes, chips, a picked switch, a few tiles and a die. The roles
   sit in five tabs; Board and Players pack two to a row. Nothing scrolls. */
dialog.k-csheet { width: min(452px, 100vw); }
dialog.k-csheet::backdrop { background: transparent; }
dialog.k-csheet:focus, dialog.k-csheet:focus-visible { outline: none; }
dialog.k-csheet > .k-panel { flex: 1 1 auto; border: 0; border-radius: 0; }
/* the strip's status gives way first (a phone at 360 px), the title keeps its place */
.k-csheet .k-head > .k-stat { flex: 0 1000 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.k-csheet .k-cpeek { margin-left: auto; }
.k-csheet .k-cpeek + .k-ibtn { margin-left: 2px; }
/* Peek: the sheet folds to its strip at the foot of the screen */
dialog.k-csheet.is-peek { inset: auto 0 0 auto; height: auto; margin: 0; border-top-width: 1px; }
dialog.k-csheet.is-peek > .k-panel > :not(.k-head) { display: none; }
.k-ctop { display: flex; flex-direction: column; gap: var(--k-s2); flex: 0 0 auto; padding: var(--k-s2) var(--k-pad) var(--k-s3);
          border-bottom: 1px solid var(--k-line); }
.k-cpresets > .k-seg { display: flex; flex: 1 1 auto; }
.k-cpresets > .k-seg > button { flex: 1 1 0; height: 26px; padding: 0 4px; }
.k-cpresets > .k-seg > button[hidden] { display: none; }
.k-cnote { margin: 0; font: 400 var(--k-f-xs)/1.4 var(--k-sans); color: var(--k-dim); }

/* the preview: a Players card beside the board's top edge, on the page's colour */
.k-cprev { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: var(--k-s2); padding: var(--k-s2);
           background: var(--k-bg); border: 1px solid var(--k-linesoft); pointer-events: none; }
.k-cprev .k-head { height: 26px; }
.k-cprev .k-title { font-size: var(--k-f-xs); letter-spacing: .18em; }
.k-cprev .k-hbtn { height: 18px; padding: 0 7px; font-size: 9px; }
.k-cprev .k-row { min-height: 32px; padding: 3px 8px 3px calc(8px + var(--k-mark-w)); gap: 7px; font-size: var(--k-f-sm); }
.k-cprev .k-sub { font-size: 9px; }
.k-cprev .k-cash { flex-direction: row; align-items: baseline; gap: 5px; font-size: var(--k-f-md); }
.k-cprev .k-delta { position: static; font-size: 10px; }
.k-cprev-acts { flex-wrap: nowrap; gap: 5px; padding: 7px 8px; overflow: hidden; }
.k-cprev-acts .k-btn--sm { height: 22px; padding: 0 7px; font-size: 9px; }
.k-cprev-acts .k-badge { margin-left: auto; }
.k-cprev-acts .k-chip { height: 18px; padding: 0 5px; font-size: 9px; }
.k-cprev-acts .k-seg > button { height: 18px; padding: 0 6px; font-size: 9px; }
.k-cprev-board { --k-u: 3.4px; display: grid; grid-template-rows: 62px minmax(0, 1fr); gap: var(--k-tile-gap);
                 padding: var(--k-tile-gap); background: var(--k-grid); min-height: 0; }
.k-cprev-tiles { position: relative; z-index: 1; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--k-tile-gap); }
.k-cprev-tiles .k-tile { font-size: 8px; }
.k-cprev-tiles .k-house { width: 6px; height: 6px; }
.k-cprev-centre { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; min-height: 0;
                  padding-top: 8px; background: var(--k-board-centre); border-radius: var(--k-radius); }
.k-cprev-die { display: grid; grid-template: repeat(3, 1fr) / repeat(3, 1fr); width: 24px; height: 24px; padding: 4px; border-radius: 18%;
               background: var(--k-die); box-shadow: inset 0 0 0 1px var(--k-die-edge), inset 0 -2px 4px var(--k-die-lo), 0 2px 4px var(--k-die-shadow); }
.k-cprev-die > i { place-self: center; width: 4px; height: 4px; border-radius: 50%; background: var(--k-pip); }
.k-cprev-msg { font: 500 9px/1.2 var(--k-sans); color: var(--k-dim); text-align: center; }
.k-cprev-msg b { color: var(--k-ink); font-weight: 600; }

/* the roles: a swatch (the browser's own colour picker), the name and what it
   colours, the hex, and ↺ back to the theme's colour once changed */
.k-cpane { gap: 0; }
.k-cpane.is-two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-content: start; gap: 0 var(--k-s3); }
.k-cpane.is-two[hidden] { display: none; }
.k-cpane-h { grid-column: 1 / -1; padding: 10px 0 4px; }
.k-crow { display: flex; align-items: center; gap: 10px; min-width: 0; min-height: 42px; padding: 4px 0; border-bottom: 1px solid var(--k-linesoft); }
.k-crow.is-compact { min-height: 34px; gap: 8px; }
.k-crow-txt { flex: 1 1 auto; min-width: 0; gap: 1px; }
.k-crow-t { font: 600 var(--k-f-sm)/1.25 var(--k-sans); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.k-crow-d { font: 400 var(--k-f-xs)/1.3 var(--k-sans); color: var(--k-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.k-crow.is-changed .k-crow-t::after { content: " •"; color: var(--k-accenttext); }
.k-crow-v { flex: 0 0 3.2em; text-align: right; font-size: var(--k-f-sm); }
.k-crow .k-crange { flex: 1 1 auto; min-width: 0; }
.k-crow.is-range { grid-column: 1 / -1; }      /* the flag strength's slider takes the whole row */
.k-crow.is-range > .k-crow-t { flex: 0 0 auto; overflow: visible; }
.k-cswatch {
  appearance: none; -webkit-appearance: none; flex: 0 0 auto; width: 34px; height: 24px; margin: 0; padding: 0;
  border: 1px solid var(--k-line); border-radius: var(--k-radius); background: transparent; cursor: pointer;
}
.k-crow.is-compact .k-cswatch { width: 28px; height: 22px; }
.k-cswatch::-webkit-color-swatch-wrapper { padding: 2px; }
.k-cswatch::-webkit-color-swatch { border: 0; border-radius: 1px; }
.k-cswatch::-moz-color-swatch { border: 0; border-radius: 1px; }
.k-cswatch:focus-visible { outline: 2px solid var(--k-focus); outline-offset: 1px; }
.k-chex { flex: 0 0 auto; width: 84px; height: 26px; padding: 0 7px; font-size: var(--k-f-sm); letter-spacing: .04em; }
.k-creset { flex: 0 0 auto; color: var(--k-dim); }
.k-creset[hidden] { display: inline-grid; visibility: hidden; }

/* a short window: the note goes first, then the preview (the screen behind
   still shows every pick) */
@media (max-height: 820px) { .k-cnote { display: none; } }
@media (max-height: 720px) { .k-cprev { display: none; } }
@media (max-width: 899px) {
  html[data-k-phone] dialog.k-csheet { width: 100vw; height: 100vh; height: 100dvh; max-height: none; margin: 0; border: 0; }
  html[data-k-phone] dialog.k-csheet.is-peek { inset: auto 0 0 0; height: auto; margin: 0; border-top: 1px solid var(--k-line); }
  html[data-k-phone] .k-chex { width: 74px; }
  /* a phone's sheet is one column wide: the preview's card over the board's edge */
  html[data-k-phone] .k-cprev { grid-template-columns: minmax(0, 1fr); }
  html[data-k-phone] .k-cprev-board { grid-template-rows: 58px 40px; }
  html[data-k-phone] .k-cprev-centre { flex-direction: row; gap: 10px; padding-top: 6px; }
}

/* ══ SKETCH 4.2, ITEM 2: THE TRADE WINDOW, ITS THREE TABS, AND A BOT'S SHOP ══
   One window (s4-trade.js) with New trade / Pending / History in its strip, desktop
   and phone. Under the strip, a slim strip of the tab's own (.k-tstrip: ‹, the partner,
   a switch); then the tab's list or screen, which PAGES (S4.paged), never scrolls.
   A Bot's shop (s4-shop.js) fills New trade with its sections, rows and confirm.   */
dialog.k-modal--trade > .k-panel.k-twin > .k-head { padding-right: 4px; }
.k-twin > .k-head > .k-ttabs .k-tab { gap: 6px; }
.k-twin > .k-head > .k-ttabs .k-badge { min-width: 15px; height: 15px; font-size: 9px; line-height: 15px; }
.k-twin > .k-body { background: var(--k-bg); }
/* a tab's own strip: lighter than the window's, the panel's colours */
.k-tstrip { --k-head-fg: var(--k-dim); --k-head-bg: var(--k-panel);
          display: flex; align-items: center; gap: var(--k-s2); flex: 0 0 auto; min-height: 36px; min-width: 0;
          padding: 0 var(--k-pad); border-bottom: 1px solid var(--k-line); background: var(--k-panel); color: var(--k-ink); }
.k-tstrip > .k-back { margin-left: -8px; font-size: 20px; }
.k-tstrip > .k-tpartner { margin-left: 0; }
.k-tstrip-t { flex: 0 0 auto; font: 600 var(--k-f-sm)/1 var(--k-sans); letter-spacing: var(--k-track); text-transform: uppercase; }
.k-tstrip-s { flex: 0 1 auto; min-width: 0; }
.k-tstrip-n { flex: 0 0 auto; }
.k-tstrip .k-hsw { color: var(--k-dim); }
.k-tstrip .k-hsw:hover { background: var(--k-selbg); color: var(--k-ink); }
.k-tstrip .k-hsw:hover .k-hsw-t { border-color: var(--k-dim); }
.k-tstrip .k-hsw:hover .k-hsw-t::after { background: var(--k-dim); }
.k-tstrip .k-hsw[aria-checked="true"] { color: var(--k-ink); }
.k-tstrip .k-seg.k-tseg > button { height: 24px; }
/* the lists: who to trade with, the offers waiting, the trades done */
.k-twin .k-tpicklist, .k-twin .k-tpendlist, .k-twin .k-thistlist { background: var(--k-panel); }
.k-twin > .k-body > .k-panebar { min-height: 40px; border-top: 1px solid var(--k-line); background: var(--k-panel); }
.k-twin > .k-body > .k-panebar > .k-pickbots { padding: 0; border: 0; }
.k-tnote { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-transform: none; letter-spacing: 0; }
.k-tgroup { padding-top: 10px; font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--k-dim); }
.k-tway { display: inline-flex; align-items: center; gap: 6px; }
.k-tway .k-pdot { width: 9px; height: 9px; }
.k-tway .k-dim { font-weight: 400; }
.k-prow, .k-hrow { min-height: 54px; }
.k-prow .k-sub, .k-hrow .k-sub { white-space: nowrap; }
/* the per-turn numbers' switch where a trade is confirmed (the receipt's strip) */
.k-head > .k-tnumsw { margin-left: auto; }
.k-head > .k-tnumsw + .k-stat { margin-left: 0; }

/* ── A BOT'S SHOP (V3.2's v32-shop.css, in the kit's look) ───────────── */
.k-shophost { position: relative; }
.k-sword { color: var(--k-accenttext); border-color: var(--k-accentedge); }
.k-slay { display: inline-flex; align-items: center; flex: 0 0 auto; }
.k-slayseg > button { height: 24px; text-transform: none; letter-spacing: .02em; }
.k-slaycyc { display: none; align-items: center; gap: 6px; height: 30px; margin: 0; padding: 0 2px 0 6px; border: 0; background: transparent;
             color: var(--k-dim); cursor: pointer; font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .06em; text-transform: uppercase; }
.k-slaycyc-f { display: inline-grid; place-items: center; width: 26px; height: 26px; border: 1px solid var(--k-line); border-radius: var(--k-radius);
               background: var(--k-well); color: var(--k-ink); font-size: var(--k-f-sm); }
.k-snote { flex: 0 0 auto; padding: 8px var(--k-pad); border-bottom: 1px solid var(--k-line); background: var(--k-panel);
           font: 500 var(--k-f-sm)/1.4 var(--k-sans); color: var(--k-accenttext); }
.k-snote[data-tone="dim"] { color: var(--k-dim); }
.k-snote[hidden], .k-stabs[hidden], .k-slh[hidden] { display: none; }
.k-stabs { background: var(--k-panel); }
.k-stabs .k-tab { height: 38px; gap: 6px; }
.k-stabs .k-tab.is-none .k-stab-t { opacity: .6; }
.k-stab-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.k-sbody { gap: 6px; padding: 8px var(--k-pad); background: var(--k-bg); }
.k-sbody--cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-content: start; align-items: start; }
.k-sbody--cards > .k-ssh, .k-sbody--cards > .k-sempty, .k-sbody--cards > .k-sshut, .k-sbody--cards > .k-empty { grid-column: 1 / -1; }
.k-sbody--ledger { gap: 0; padding-top: 0; }
.k-ssh { flex: 0 0 auto; min-height: 30px; padding: 8px 2px 4px; border-bottom: 1px solid var(--k-line);
         font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--k-dim); }
.k-sempty { padding: 6px 2px; white-space: normal; }
/* a row: what it is, then a button for each term (A and B) */
.k-srow { display: grid; grid-template-columns: minmax(200px, 1fr) auto; align-items: center; gap: 10px 16px; flex: 0 0 auto;
          padding: 8px 10px; border: 1px solid var(--k-line); border-radius: var(--k-radius); background: var(--k-panel); }
.k-stt { display: flex; align-items: flex-start; gap: 10px; min-width: 0; }
.k-sic { flex: 0 0 24px; width: 24px; height: 24px; display: inline-grid; place-items: center; border-radius: var(--k-radius);
         background: var(--k-well); color: var(--k-ink); font: 600 12px/1 var(--k-mono); }
.k-st { font: 600 var(--k-f-md)/1.3 var(--k-sans); color: var(--k-ink); overflow-wrap: anywhere; }
.k-stx .k-sub { white-space: normal; overflow-wrap: anywhere; }
.k-sopts { display: flex; align-items: flex-end; justify-content: flex-end; gap: 14px; }
.k-sdur { display: flex; flex-direction: column; gap: 4px; }
.k-sdur-l { display: flex; align-items: baseline; gap: 6px; min-height: 12px; white-space: nowrap; }
.k-sdur-r { font: 600 var(--k-f-xs)/1.2 var(--k-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--k-dim); }
.k-spair { display: flex; gap: 6px; }
/* the button of one line: its price, and its money a round under it */
.k-sb { display: inline-flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 2px;
        min-width: 124px; min-height: 44px; margin: 0; padding: 5px 10px; border: 1px solid var(--k-line); border-radius: var(--k-radius);
        background: var(--k-well); color: var(--k-ink); text-align: left; cursor: pointer; }
.k-sb-l { font: 500 var(--k-f-xs)/1.15 var(--k-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--k-dim); }
.k-sb-m { font: 600 var(--k-f-md)/1.15 var(--k-mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.k-sb-s { font: 400 var(--k-f-xs)/1.2 var(--k-mono); color: var(--k-dim); font-variant-numeric: tabular-nums; white-space: nowrap; }
.k-sb:not([aria-disabled="true"]):hover { border-color: var(--k-accentedge); background: var(--k-accentsoft); }
.k-sb:focus-visible { outline: 2px solid var(--k-focus); outline-offset: 1px; }
.k-sb.is-shut { opacity: .42; cursor: not-allowed; }
.k-sb.is-one { min-width: 150px; }
/* a thing the bot does not sell now: one quiet line, with why */
.k-sshut { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; min-height: 32px; padding: 5px 10px;
           border: 1px dashed var(--k-line); border-radius: var(--k-radius); color: var(--k-dim); font-size: var(--k-f-sm); }
.k-slock { flex: 0 0 auto; color: var(--k-accenttext); font: 600 12px/1 var(--k-mono); }
.k-sshut-t { flex: 0 0 auto; font-weight: 600; color: var(--k-ink); opacity: .8; }
.k-sshut-n { flex: 0 0 auto; }
.k-sshut-w { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--k-accenttext); font-size: var(--k-f-xs); }
.k-sri { align-items: flex-end; text-align: right; }
.k-sri .k-sub { white-space: normal; max-width: 340px; }
/* C: cards in a grid */
.k-scard { display: flex; flex-direction: column; gap: 10px; min-width: 0; padding: 10px; border: 1px solid var(--k-line);
           border-radius: var(--k-radius); background: var(--k-panel); }
.k-scard.k-srentin { display: flex; }
.k-scard.k-srentin .k-sri { align-items: flex-start; text-align: left; }
.k-scm { display: flex; flex-direction: column; gap: 5px; }
.k-scm .k-sdur-l:not(:first-child) { margin-top: 4px; }
.k-scm .k-spair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.k-scm .k-sb { min-width: 0; width: 100%; }
.k-sx { align-self: center; color: var(--k-dim); text-align: center; font-family: var(--k-mono); }
/* D: the ledger (its column heads stand over the pages, .k-slh) */
.k-slh { flex: 0 0 auto; padding: 0 var(--k-pad); background: var(--k-bg); }
.k-slr { display: grid; grid-template-columns: minmax(0, 1fr) 64px 150px 150px 112px; align-items: center; gap: 8px; flex: 0 0 auto;
         min-height: 48px; padding: 3px 10px; border-bottom: 1px solid var(--k-line); background: var(--k-panel); }
.k-slr.k-slh-row { min-height: 30px; background: var(--k-well); font: 500 var(--k-f-xs)/1.2 var(--k-mono); letter-spacing: .06em;
                   text-transform: uppercase; color: var(--k-dim); }
.k-slc { min-width: 0; }
.k-slc0 { display: flex; align-items: center; gap: 10px; }
.k-slc1, .k-slc4 { font: 500 var(--k-f-sm)/1.2 var(--k-mono); font-variant-numeric: tabular-nums; text-align: right; }
.k-slc1 { text-align: center; }
.k-sshort, .k-slr-dur { display: none; }
.k-slr.is-shut { grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); min-height: 36px; background: transparent; }
.k-slcw { font-size: var(--k-f-xs); color: var(--k-accenttext); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.k-slr[data-k-rentin] .k-slcw { color: var(--k-dim); white-space: normal; }
.k-sbody--ledger > .k-ssh { padding: 10px 10px 6px; }
.k-sb.is-cell { min-width: 0; width: 100%; min-height: 40px; padding: 3px 8px; }
/* the foot: Custom trade, the pager */
.k-twin .k-sfoot { min-height: 50px; padding: 6px 6px 6px var(--k-pad); gap: var(--k-s2); }
.k-scustom { flex: 0 0 auto; }
.k-slive { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* the confirm: over the shop, the server's own sentence, Cancel and the one amber Buy */
.k-scf { position: absolute; inset: 0; z-index: 6; display: flex; align-items: center; justify-content: center; }
.k-scf[hidden] { display: none; }
.k-scf-scrim { position: absolute; inset: 0; background: var(--k-scrim); }
.k-scf-box { position: relative; display: flex; flex-direction: column; gap: 10px; width: min(560px, calc(100% - 32px)); max-height: calc(100% - 24px);
             padding: 16px; border: 1px solid var(--k-line); border-radius: var(--k-radius); background: var(--k-panel); box-shadow: var(--k-shadow); overflow: hidden; }
.k-scf-box.is-rise { animation: k-scf-rise 200ms ease-out both; }
@keyframes k-scf-rise { from { transform: translateY(14px); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .k-scf-box.is-rise { animation: none; } }
.k-scf-top { --k-head-fg: var(--k-dim); --k-head-bg: var(--k-panel); display: flex; align-items: center; gap: var(--k-s2); }
.k-scf-top > .k-tnumsw { margin-left: auto; }
.k-scf-top .k-hsw:hover { background: var(--k-selbg); color: var(--k-ink); }
.k-scf-t { font: 600 var(--k-f-lg)/1.2 var(--k-sans); }
.k-scf-q { margin: 0; font: 400 var(--k-f-md)/1.45 var(--k-sans); }
.k-scf-pr { margin: 0; font: 400 var(--k-f-sm)/1.45 var(--k-sans); color: var(--k-dim); }
.k-scf-say { margin: 0; padding: 7px 10px; border-left: var(--k-mark-w) solid var(--k-line); font: 500 var(--k-f-sm)/1.4 var(--k-sans); }
.k-scf-say[hidden] { display: none; }
.k-scf-say[data-tone="warn"] { border-left-color: var(--k-accent); color: var(--k-accenttext); }
.k-scf-say[data-tone="neg"] { border-left-color: var(--k-neg); color: var(--k-negtext); }
.k-scf-say[data-tone="pos"] { border-left-color: var(--k-pos); color: var(--k-postext); }
.k-scf-row { display: flex; gap: 10px; justify-content: flex-end; margin-top: 2px; }
.k-scf-row > .k-btn { height: 44px; }
.k-scf-buy { min-width: 180px; }
.k-btn.k-scf-done[aria-disabled="true"] { color: var(--k-postext); border-color: var(--k-postext); opacity: 1; }
.k-scf-nums { display: flex; flex-direction: column; min-height: 0; border: 1px solid var(--k-linesoft); border-radius: var(--k-radius); }
.k-scf-nh { padding: 6px 10px; border-bottom: 1px solid var(--k-linesoft); font: 600 var(--k-f-xs)/1 var(--k-mono); letter-spacing: .08em;
            text-transform: uppercase; color: var(--k-dim); }
.k-scf-nb { padding: 4px 8px 6px; min-height: 0; overflow: hidden; }
@media (max-width: 1279px) { .k-sbody--cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 899px) {
  /* a phone: the tabs' words shorter, a row's terms under what it is (two buttons a line), cards two a line
     (a card with terms takes the line), the ledger without its Rounds column, the layout one letter, and
     the confirm a sheet on the screen's foot */
  html[data-k-phone] .k-twin > .k-head > .k-ttabs .k-tab { padding: 0 9px; }
  html[data-k-phone] .k-tstrip { min-height: 34px; padding: 0 var(--k-ph-gap, 8px) 0 10px; gap: 6px; }
  html[data-k-phone] .k-tstrip .k-tpartner { font-size: var(--k-f-sm); }
  html[data-k-phone] .k-tnote { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; font-size: 10px; line-height: 1.3; }
  html[data-k-phone] .k-slayseg { display: none; }
  html[data-k-phone] .k-slaycyc { display: inline-flex; }
  html[data-k-phone] .k-sbody { padding: 6px 8px; }
  html[data-k-phone] .k-srow { grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 8px; }
  html[data-k-phone] .k-sopts { flex-direction: column; align-items: stretch; gap: 8px; }
  html[data-k-phone] .k-spair { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
  html[data-k-phone] .k-sb, html[data-k-phone] .k-sb.is-one { min-width: 0; width: 100%; }
  html[data-k-phone] .k-sri { align-items: flex-start; text-align: left; }
  html[data-k-phone] .k-sshut { flex-wrap: wrap; row-gap: 2px; }
  html[data-k-phone] .k-sshut-w { flex-basis: 100%; white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  html[data-k-phone] .k-sbody--cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
  html[data-k-phone] .k-sbody--cards > .k-scard.has-terms, html[data-k-phone] .k-sbody--cards > .k-srentin { grid-column: 1 / -1; }
  html[data-k-phone] .k-scard { padding: 8px; gap: 8px; }
  html[data-k-phone] .k-scard:not(.has-terms) .k-sic { display: none; }
  html[data-k-phone] .k-slh { padding: 0 8px; }
  html[data-k-phone] .k-slr { grid-template-columns: minmax(0, 1fr) 84px 84px 50px; gap: 5px; padding: 3px 6px; min-height: 50px; }
  html[data-k-phone] .k-slr > .k-slc1 { display: none; }
  html[data-k-phone] .k-slr-dur { display: block; margin-top: 2px; font: 600 10px/1.2 var(--k-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--k-dim); }
  html[data-k-phone] .k-slr.is-shut { grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); }
  html[data-k-phone] .k-slr.k-slh-row { font-size: 10px; letter-spacing: .02em; }
  html[data-k-phone] .k-slr.k-slh-row .k-slong { display: none; }
  html[data-k-phone] .k-slr.k-slh-row .k-sshort { display: inline; }
  html[data-k-phone] .k-slc0 .k-sic { display: none; }
  html[data-k-phone] .k-slcw { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  html[data-k-phone] .k-sb.is-cell { min-height: 44px; padding: 3px 6px; }
  html[data-k-phone] .k-sb.is-cell .k-sb-s { font-size: 10px; white-space: normal; }
  html[data-k-phone] .k-slive { display: none; }
  html[data-k-phone] .k-stabs .k-tab { gap: 4px; padding: 0 2px; }
  html[data-k-phone] .k-scf { align-items: flex-end; }
  html[data-k-phone] .k-scf-box { width: 100%; max-height: 100%; border-width: 1px 0 0; border-radius: 0; padding: 14px 12px calc(12px + env(safe-area-inset-bottom, 0px)); }
  html[data-k-phone] .k-scf-row > .k-btn { flex: 1 1 0; min-width: 0; }
  html[data-k-phone] .k-scf-buy { min-width: 0; }
}
/* a quiet strip button beside a strip's one action (sketch 4.2: the Trades card's History) */
.k-hbtn.k-hbtn--quiet { background: transparent; color: var(--k-head-fg); box-shadow: inset 0 0 0 1px var(--k-head-soft); }
.k-hbtn.k-hbtn--quiet:not([aria-disabled="true"]):hover { background: var(--k-head-fg); color: var(--k-head-bg); }
/* the before/after numbers on a phone: a player a page where both do not fit (s4-trade.js numbersGrid) */
.k-inumhost, .k-inumat { display: flex; flex-direction: column; min-height: 0; }
.k-inumat { flex: 1 1 auto; }
.k-inums { flex: 1 1 auto; min-height: 0; }
.k-inumbar { min-height: 28px; padding: 0 0 0 2px; border-top: 1px solid var(--k-linesoft); }
.k-inumbar[hidden] { display: none; }
.k-inumbar > .k-label { flex: 1 1 auto; min-width: 0; }
.k-scf-box { min-height: 0; }
.k-scf-nums { flex: 1 1 auto; min-height: 0; }
.k-scf-nb { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
@media (max-width: 899px) {
  /* a ledger cell on a phone holds its words whole: they wrap (sketch 4.2) */
  html[data-k-phone] .k-sb.is-cell .k-sb-m { white-space: normal; overflow-wrap: anywhere; }
}
/* the Trades card's strip (sketch 4.2): its title whole; History and + Create on the right */
#k-trades > .k-head > .k-title { flex-shrink: 0; }
#k-trades > .k-head > .k-stat[hidden] { display: none; }
#k-trades > .k-head > .k-thistbtn { margin-left: auto; }
#k-trades > .k-head > .k-pager:not([hidden]) + .k-thistbtn { margin-left: 0; }
/* a table's number heads wrap rather than cut ("CONTRACT CAP" at 960 px, with True net beside Net rent: sketch 4.2) */
.k-tablegrid > .k-th.k-tn { white-space: normal; text-align: right; line-height: 1.15; overflow-wrap: normal; }
/* the ledger's column heads keep their own small type, and a phone's head row its 30 px */
.k-slr.k-slh-row .k-slc1, .k-slr.k-slh-row .k-slc4 { font: inherit; }
@media (max-width: 899px) { html[data-k-phone] .k-slr.k-slh-row { min-height: 30px; } }

/* ── SKETCH 4.2, item 14: HELPER TIPS (s4-tips.js) ──────────────────────
   A small "?" beside a term, a desk or a panel's title; a tap opens the term
   in plain words. Settings › Display turns them off (<html data-k-tips="off">
   hides every "?": nothing is drawn again). Its hit area reaches 8 px past the
   ring, so a thumb finds it; it never takes a row's tap (s4-tips.js). */
.k-tipq {
  flex: 0 0 auto; position: relative; display: inline-flex; align-items: center; justify-content: center;
  box-sizing: border-box; width: 28px; height: 28px; margin: -6px -6px -6px -2px; padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: inherit; opacity: .62; cursor: help; vertical-align: middle;
  font: 700 10px/1 var(--k-sans); letter-spacing: 0; text-transform: none;
}
/* the ring a thumb sees is 16 px; the button (its hit area) is 28 */
.k-tipq::before { content: ""; position: absolute; inset: 6px; border: 1px solid currentColor; border-radius: 50%; }
.k-tipq:hover, .k-tipq[aria-expanded="true"] { opacity: 1; }
.k-tipq:hover::before, .k-tipq[aria-expanded="true"]::before { background: currentColor; opacity: .18; }
.k-head > .k-tipq { margin-right: 0; }
html[data-k-tips="off"] .k-tipq { display: none; }
/* a label with its "?" (the You panel, s4-game.js youBuild; the fix step): the label's box holds the whole "?"
   (its -6 px right margin left the button 6 px past the label, which clipped it and scrolled when it took the
   focus: "NET WORTH" read "ET WORTH"); a label too long for its cell clips its words, never the "?" */
.k-k.k-k--q { display: inline-flex; align-items: center; }
.k-k--q > .k-kt { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.k-k--q > .k-tipq { margin-right: 0; }
.k-tipbox {
  position: fixed; inset: auto; z-index: 60; margin: 0; padding: 10px 12px 10px; box-sizing: border-box;
  border: 1px solid var(--k-line); border-radius: var(--k-radius); background: var(--k-panel); color: var(--k-ink); pointer-events: auto;
  box-shadow: var(--k-shadow); font: 400 var(--k-f-md)/1.4 var(--k-sans); text-align: left;
}
.k-tipbox[hidden] { display: none; }
.k-tiphead { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.k-tiphead > b { flex: 1 1 auto; font: 700 var(--k-f-sm)/1.2 var(--k-mono); letter-spacing: .06em; text-transform: uppercase; }
.k-tipx { flex: 0 0 auto; width: 28px; height: 28px; margin: -6px -6px -6px 0; border: 0; background: transparent; color: var(--k-dim); font-size: 18px; cursor: pointer; }
.k-tipbox > p { margin: 0 0 6px; }
.k-tipoff { padding: 0; border: 0; background: transparent; color: var(--k-dim); font: 500 var(--k-f-xs)/1.4 var(--k-sans); text-decoration: underline; cursor: pointer; }
dialog.k-tippage { width: min(900px, calc(100vw - 32px)); }
.k-tiplist { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: min-content; column-gap: 22px; row-gap: 8px; overflow: hidden; }
.k-tipitem { min-width: 0; padding: 6px 0; border-bottom: 1px solid var(--k-linesoft); }
.k-tipitem > b { display: block; margin-bottom: 2px; font: 700 var(--k-f-xs)/1.3 var(--k-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--k-ink); }
.k-tipitem > p { margin: 0; font: 400 var(--k-f-sm)/1.4 var(--k-sans); color: var(--k-dim); }
.k-tipitem.is-group { grid-column: 1 / -1; padding-top: 10px; }
.k-tiplist.is-one { display: flex; flex-direction: column; row-gap: 0; }
@media (max-width: 899px) {
  .k-tiplist { grid-template-columns: minmax(0, 1fr); display: flex; flex-direction: column; row-gap: 0; }
}

/* ── SKETCH 4.2, item 11: Settings › Sound (s4-game.js soundPane) ─────────
   the volume's slider beside its words, as wide as a switch row's control
   allows; the rows under the master switch go quiet while the sound is off */
.k-sndvol > .k-range { flex: 0 0 auto; width: min(220px, 42%); }
.k-opt.is-quiet > .k-stack { opacity: .5; }
/* five tabs on a phone (Auto-play, Display, Trades, Sound, Rules): tighter, so each word is whole at 375 px */
@media (max-width: 899px) {
  html[data-k-phone] #k-settings-d .k-panel > .k-tabs > .k-tab { padding: 0 3px; letter-spacing: .04em; }
}
/* sketch 4.2, item 15: Sign in on the desktop menu too, beside your name as on a phone */
.k-menugrid section[aria-labelledby="k-h-you"] > .k-body {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; column-gap: var(--k-s2); row-gap: 6px;
}
.k-menugrid section[aria-labelledby="k-h-you"] > .k-body > .k-empty { grid-column: 1 / -1; }

/* ── SKETCH 4.2, item 15: THE MODERATION SHEETS' LOOK IS static/css/kit-mod.css, loaded when a sheet first opens
 * or at an idle moment after the page is up (kit.js Kit.modLook; the fix step: the review measured the 4x phone's
 * game page 60-70 ms slower than V4.12's, and the first paint parsed these rules for sheets nobody had opened).
 * Until it is there a sheet waits unseen, so it never shows in V3's look for a frame; a sheet whose stylesheet
 * failed to load shows in moderation.css's own look. */
html[data-k-desk]:not([data-k-modlook]) dialog.mod-sheet { visibility: hidden; }

/* ── the ⋯ on another player's chat line (s4-table.js chatInto) ─────────
   at the end of the line's name row, small so no line grows; its hit area
   reaches past the dots (moderation.css .mod-more::before) */
html[data-k-desk] .k-msg .mod-more { margin-left: auto; width: 28px; height: 16px; overflow: visible; color: var(--k-dim); }
/* its hit area reaches up and down only (28 x 36): a button wider inside than out reads as a cut label (Kit.fit) */
html[data-k-desk] .k-msg .mod-more::before { inset: -10px 0; }
html[data-k-desk] .k-msg .mod-more:hover { background: var(--k-selbg); color: var(--k-ink); }
html[data-k-desk] .k-msg .mod-more:focus-visible { outline: 2px solid var(--k-focus); outline-offset: 1px; }
html[data-k-desk] .k-msg.mod-actionable { cursor: pointer; }

/* ══ SKETCH 4.3, ITEM 1: SOCIAL (static/js/s4-social.js, s4-socialpanel.js) ═══════════════════════════════
   One button: the menu's Player strip; the room's card (a row over Leave) and the You strip on desktop; beside
   More in a phone's dock bar (the room and the game). One window, as Settings and Trade: the kit's strip, three
   tabs, a slim strip a tab, a list that PAGES (never a scroll), a foot with a note and the pager. A person's row:
   a neutral token (an account, not a seat), the name, where they are, the row's actions and ⋯. Tokens only. */
.k-socbtn { position: relative; }
.k-socbtn > .k-tic { width: 14px; height: 14px; stroke: currentColor; stroke-width: 1.8; }
.k-socbtn > .k-badge { margin-left: 1px; min-width: 15px; height: 15px; font-size: 9px; line-height: 15px; }
/* the You strip's icon: its count beside it, inside the button (a button clips what stands outside it) */
.k-ibtn.k-socbtn--icon { display: inline-flex; align-items: center; justify-content: center; gap: 3px; width: auto; min-width: 28px; padding: 0 5px; }
.k-ibtn.k-socbtn--icon > .k-tic { width: 17px; height: 17px; }
.k-ibtn.k-socbtn--icon > .k-badge { margin: 0; }
.k-socentry > .k-btn { flex: 0 0 auto; }
.k-socentry > .k-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.k-leaverow > .k-socin { display: none; }
@media (min-width: 900px) and (max-width: 1279px) {
  /* half-width: the room's card sits under the board with no height to spare (1024x768 cut Leave lobby by a
     row): Social is the first of Leave lobby's row there, whose sentence steps aside at this width anyway */
  .k-socentry { display: none; }
  .k-leaverow > .k-socin { display: inline-flex; flex: 0 0 auto; margin-right: auto; }
}
.k-actbar > .k-dock-soc { flex: 0 0 auto; width: 44px; padding: 0; position: relative; }
.k-actbar > .k-dock-soc > .k-tic { width: 22px; height: 22px; stroke: currentColor; stroke-width: 1.6; }
.k-actbar > .k-dock-soc > .k-badge { position: absolute; top: 4px; right: 3px; margin: 0; }
.k-actbar > .k-dock-soc[hidden] { display: none; }
dialog.k-modal--social { width: min(560px, calc(100vw - 32px)); height: min(620px, calc(100vh - 32px)); height: min(620px, calc(100dvh - 32px)); }
dialog.k-modal--social.is-guest { height: fit-content; }
.k-socpanel > .k-tabs .k-tab .k-badge { min-width: 15px; height: 15px; font-size: 9px; line-height: 15px; }
.k-socpanel > .k-body { background: var(--k-bg); }
.k-socpanel .k-pane.k-socpane { gap: 0; }
.k-soclist { background: var(--k-panel); }
.k-socpanel .k-socfoot { min-height: 40px; border-top: 1px solid var(--k-line); background: var(--k-panel); }
.k-socstrip > .k-btn--sm, .k-socstrip > .k-chip { flex: 0 0 auto; }
.k-socform { flex: 0 0 auto; padding: 10px var(--k-pad); border-bottom: 1px solid var(--k-linesoft); background: var(--k-panel); }
.k-socpanel.is-guest > .k-body { display: flex; flex-direction: column; }
.k-socguest { flex: 1 1 auto; display: flex; flex-direction: column; gap: 8px; padding: var(--k-pad); background: var(--k-panel); }
.k-socguest > .k-btn { margin-top: 6px; }
.k-socrow { min-height: 56px; gap: 10px; padding-right: 6px; }
.k-socrow .k-token.k-soctok { width: 32px; height: 32px; font-size: 13px; background: var(--k-well); color: var(--k-ink);
                              box-shadow: inset 0 0 0 1px var(--k-line); }
.k-socrow .k-socwhere { display: flex; align-items: center; gap: 6px; min-width: 0; }
.k-socrow .k-socwhere > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.k-socdot { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: var(--k-soft); }
.k-socrow.is-on, .k-socrow.is-room { --k-mark: var(--k-postext); }
.k-socrow.is-on .k-socdot, .k-socrow.is-room .k-socdot { background: var(--k-postext); }
.k-socrow.is-play, .k-socrow.is-ask { --k-mark: var(--k-accent); }
.k-socrow.is-play .k-socdot, .k-socrow.is-ask .k-socdot { background: var(--k-accent); }
.k-socrow.is-offline .k-name { color: var(--k-dim); }
.k-socacts { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; }
.k-socacts > .k-btn[aria-busy="true"] { opacity: .5; }
.k-ibtn.k-socmore { width: 30px; height: 34px; color: var(--k-dim); }
.k-ibtn.k-socmore > .k-tic { width: 20px; height: 20px; stroke: currentColor; }
dialog.k-modal--socsheet { width: min(400px, calc(100vw - 32px)); }
.k-socperson .k-socsays { padding-top: 0; }
.k-socstack { gap: 8px; }
.k-socstack > .k-rule { margin: 2px 0; }
@media (max-width: 899px) {
  html[data-k-phone] dialog.k-modal--social { height: min(600px, calc(100vh - 2 * var(--k-ph-gap))); height: min(600px, calc(100dvh - 2 * var(--k-ph-gap))); }
  html[data-k-phone] dialog.k-modal--social.is-guest { height: fit-content; }
  html[data-k-phone] .k-socentry { display: none; }
  html[data-k-phone] .k-app[data-k-screen="game"] .k-table .k-col > :is(#k-you, [data-k-shell="k-you"]) > .k-head > .k-socbtn { display: none; }
  html[data-k-phone] .k-socacts > .k-btn { height: 36px; padding: 0 10px; }
  html[data-k-phone] .k-ibtn.k-socmore { width: 34px; height: 44px; }
  html[data-k-phone] .k-socstack > .k-btn { height: 44px; }
  html[data-k-phone] .k-socform > .k-btn { height: 40px; }
  html[data-k-phone] .k-socform > .k-input { height: 40px; }
}

/* ══ SKETCH 4.3, ITEM 2: ADD FRIEND ON A PERSON'S ROW, ⋯ ON IT, WHO IS WATCHING ════════════════════════════════════
   The kit's own parts: Add friend is a chip-sized button on the row's line (button.k-chip, the accent's edge, as a
   chip that can be pressed), what it became a plain chip ("Request sent", "Friends" in the up colour); ⋯ is Social's
   (.k-socmore), before the cash so every row's cash keeps its place; the Spectators list is Social's window. */
button.k-frbtn { display: inline-flex; align-items: center; flex: 0 0 auto; height: 28px; margin: -3px 0; padding: 0;
                 border: 0; background: none; color: inherit; font: inherit; cursor: pointer; }
button.k-frbtn:hover > .k-chip { background: var(--k-selbg); }
button.k-frbtn:focus-visible { outline: 0; }
button.k-frbtn:focus-visible > .k-chip { outline: 2px solid var(--k-focus); outline-offset: 1px; }
.k-frslot { display: inline-flex; min-width: 0; }
.k-tagline > .k-sets:empty { display: none; }
.k-frslot[hidden] { display: none; }
.k-tagline > .k-frslot > *, .k-line > .k-frchip, .k-line > .k-frbtn { flex: 0 0 auto; }
.k-plrow > .k-pmore { flex: 0 0 auto; margin: -4px -6px -4px -4px; }
.k-row > .k-pmore { flex: 0 0 auto; }
/* the end of the game: Add friend under the person's bar, at the name's edge (the name line and the net worth's
   column keep their widths: beside the name, or under the net worth, it took the name's room in a narrow column) */
.k-lb > .k-lbfriend { grid-column: 2 / 4; justify-self: start; }
/* the watcher count: a button now (who is watching) */
button.k-watch { background: none; border: 0; padding: 10px 4px; margin-top: -10px; margin-bottom: -10px; cursor: pointer; }
button.k-watch:hover { color: var(--k-ink); text-decoration: underline; }
.k-socstrip > .k-socchat { flex: 0 0 auto; }
@media (max-width: 899px) {
  html[data-k-phone] .k-plrow > .k-pmore { width: 30px; height: 40px; margin: -6px -6px -6px -4px; }
  /* a thumb's height round the chip on a phone, inside the row (its margins give the row its height back) */
  html[data-k-phone] button.k-frbtn { height: 36px; margin: -7px 0; }
  html[data-k-phone] .k-row > .k-pmore { height: 40px; }
}
/* an answer said in a Social window's foot (a toast stands under an open window) */
.k-socfoot .k-tnote.k-socsaid { color: var(--k-ink); }
.k-socfoot .k-tnote.k-socsaid.is-up { color: var(--k-postext); }
.k-socfoot .k-tnote.k-socsaid.is-down { color: var(--k-negtext); }
.k-socfoot .k-tnote.k-socsaid.is-acc { color: var(--k-accenttext); }

/* ══ SKETCH 4.3, ITEM 3: SPECTATORS APART FROM THE SEATS (static/js/s4-room.js drawWatching) ═══════════════════════
   The room's Players list is its seats; the people watching are a count and a Spectators button under them (the
   foot's own line, as the bot box under it), which opens Social's Spectators window. On a phone the count is a
   square beside Social in the dock's bar (its count on it, the quiet badge), so the seats keep the dock's height. */
.k-plfoot.k-specline { flex-direction: row; align-items: center; gap: 8px; padding-top: 7px; padding-bottom: 7px; }
.k-plfoot.k-specline[hidden] { display: none; }
.k-specline > .k-tic { flex: 0 0 auto; width: 16px; height: 16px; fill: none; stroke: var(--k-dim); stroke-width: 1.8; stroke-linejoin: round; }
.k-specline > .k-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.k-specline > .k-specbtn { flex: 0 0 auto; }
.k-actbar > .k-dock-spec { flex: 0 0 auto; width: 44px; padding: 0; position: relative; }
.k-actbar > .k-dock-spec > .k-tic { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; }
.k-actbar > .k-dock-spec > .k-badge { position: absolute; top: 4px; right: 3px; margin: 0; }
.k-actbar > .k-dock-spec[hidden] { display: none; }
.k-socstrip > .k-socseat { flex: 0 0 auto; }
@media (max-width: 899px) {
  /* a phone: the dock bar's square says it; the dock's height stays the seats' */
  html[data-k-phone] .k-plfoot.k-specline { display: none; }
}
