/* SALT — vincent.services
 *
 * The map is the application. Everything else is a rail beside it that holds
 * whatever is selected, so there is exactly one dominant thing on screen and
 * the chrome never competes with the world.
 *
 * The language is HallMeet's: warm neutrals, Geist, pill buttons with a real
 * press state, hover only inside a hover media query, hairlines instead of
 * boxes, and depth from spacing rather than shadow. Related controls share one
 * surface and are separated by a rule; unrelated ones are separated by space.
 * There is one near-black primary button per screen and no more.
 */

@font-face { font-family: "Geist"; src: url("f/Geist-Regular.woff2") format("woff2");
  font-weight: 400; font-display: swap; }
@font-face { font-family: "Geist"; src: url("f/Geist-Medium.woff2") format("woff2");
  font-weight: 500; font-display: swap; }
@font-face { font-family: "Geist"; src: url("f/Geist-SemiBold.woff2") format("woff2");
  font-weight: 600; font-display: swap; }

:root {
  --n-00:#ffffff; --n-05:#fbfbfa; --n-10:#f6f6f4; --n-20:#ececea; --n-30:#dededa;
  --n-40:#c4c4bf; --n-50:#9a9a94; --n-60:#6f6f69; --n-70:#57574f; --n-80:#3a3a35;
  --n-90:#262622; --n-95:#1a1a18; --n-99:#111110;

  --accent-1:#3a6ea5; --accent-2:#2f7d66; --accent-3:#a06a2c;
  --accent-4:#b04a5e; --accent-5:#7154a8; --accent-6:#557f3d;
  --danger:#a33a3a; --success:#3f6b5f; --warning:#8a6742;

  --bg:var(--n-05); --bg-subtle:var(--n-10); --bg-sunken:var(--n-20);
  --surface:var(--n-00); --surface-raised:var(--n-10); --surface-hover:var(--n-10);
  --surface-active:var(--n-20);
  --border:#e9e9e5; --border-strong:#dcdcd7;
  --text:var(--n-99); --text-secondary:var(--n-70); --text-tertiary:var(--n-60);

  --accent:var(--accent-1);
  --focus-ring: color-mix(in srgb, var(--n-99) 10%, transparent);

  --font-sans:"Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

  --text-xs:0.75rem; --text-sm:0.8125rem; --text-base:0.9375rem;
  --text-md:1.0625rem; --text-lg:1.375rem; --text-xl:2rem;
  --tracking-display:-0.032em; --tracking-heading:-0.018em; --tracking-caps:0.06em;

  --space-1:.25rem; --space-2:.5rem; --space-3:.75rem; --space-4:1rem;
  --space-5:1.5rem; --space-6:2rem; --space-7:3rem;
  --radius-sm:6px; --radius-md:10px; --radius-lg:16px; --radius-full:999px;

  --shadow-sm:0 1px 2px rgb(23 23 20 / .04);
  --shadow-md:0 4px 12px rgb(23 23 20 / .06), 0 1px 2px rgb(23 23 20 / .04);
  --shadow-lg:0 12px 32px rgb(23 23 20 / .10), 0 2px 6px rgb(23 23 20 / .04);

  --ease:cubic-bezier(.4,0,.2,1); --ease-out:cubic-bezier(.16,1,.3,1);
  --duration-fast:120ms; --duration-enter:260ms; --duration-exit:160ms;
  --press-scale:.97; --press-scale-subtle:.99;

  --rail-left:296px; --rail-right:352px; --bar:52px; --res:38px;
  color-scheme: light;
}


*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin:0; background:var(--bg); color:var(--text);
  font-family:var(--font-sans); font-size:var(--text-base); line-height:1.5;
  -webkit-font-smoothing:antialiased; overscroll-behavior:none;
}
:focus-visible { outline:2px solid var(--n-99); outline-offset:2px; border-radius:4px; }
button, input, select { font:inherit; color:inherit; }
h1,h2,h3,p { margin:0; }
[hidden] { display:none !important; }

/* ------------------------------------------------------------------ shell */

#app { display:grid; grid-template-rows:var(--bar) var(--res) 1fr; height:100dvh; }


.purse { display:flex; align-items:center; gap:var(--space-4); }
.purse__item { display:flex; align-items:baseline; gap:6px; white-space:nowrap; }
.purse__v { font-variant-numeric:tabular-nums; font-weight:500; }
.purse__k { font-size:var(--text-xs); color:var(--text-tertiary); }
.purse__item--warn .purse__v { color:var(--danger); }

.clock {
  font-size:var(--text-xs); color:var(--text-tertiary);
  font-variant-numeric:tabular-nums; display:flex; align-items:center; gap:6px;
}
.clock__dot { width:6px; height:6px; border-radius:50%; background:var(--success); }
.clock__dot--off { background:var(--n-40); }

/* ------------------------------------------------------------------- body */


/* ------------------------------------------------------------ resource bar */

.res {
  display:flex; align-items:center; gap:6px; padding:4px 9px; border-radius:var(--radius-full);
  white-space:nowrap; font-size:var(--text-xs); color:var(--text-secondary); flex:none;
}
.res__dot { width:8px; height:8px; border-radius:2px; flex:none; }
.res__v { font-variant-numeric:tabular-nums; font-weight:500; color:var(--text); }
.res--zero { opacity:.42; }
.res--money { background:var(--bg-subtle); }
.res--low .res__v { color:var(--danger); }
.res__rate { color:var(--text-tertiary); font-variant-numeric:tabular-nums; }
.res--up .res__rate { color:var(--success); }
#map { display:block; width:100%; height:100%; touch-action:none; cursor:grab; }
#map.dragging { cursor:grabbing; }

/* The map's own controls sit together at the top right; the bottom left is
   the notifications panel's. */
.mapctl {
  position:absolute; top:var(--space-3); right:var(--space-3); z-index:11;
  display:flex; align-items:center; gap:var(--space-2);
}
.mapctl .field { width:auto; min-height:34px; height:34px; font-size:var(--text-xs);
  border-radius:var(--radius-full); border-color:var(--border); box-shadow:var(--shadow-sm); }
.layers {
  display:flex; background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius-full); padding:3px; gap:2px; box-shadow:var(--shadow-sm);
}
.layers button {
  border:0; background:transparent; padding:6px 12px; border-radius:var(--radius-full);
  font-size:var(--text-xs); font-weight:500; color:var(--text-tertiary);
  cursor:pointer; transition:background var(--duration-fast) var(--ease),
    color var(--duration-fast) var(--ease);
}
.layers button[aria-pressed="true"] { background:var(--n-99); color:var(--n-00); }
.layers button:active { transform:scale(var(--press-scale)); }

.zoomer {
  position:absolute; right:var(--space-4); bottom:96px; z-index:11;
  display:flex; flex-direction:column; background:var(--surface);
  border:1px solid var(--border); border-radius:var(--radius-md);
  overflow:hidden; box-shadow:var(--shadow-sm);
}
.zoomer button {
  width:34px; height:34px; border:0; background:transparent; cursor:pointer;
  color:var(--text-secondary); font-size:var(--text-md); line-height:1;
}
.zoomer button + button { border-top:1px solid var(--border); }
.zoomer button:active { background:var(--surface-active); }

.scalebar {
  position:absolute; left:var(--space-4); bottom:calc(var(--space-4) + 44px);
  font-size:11px; color:var(--n-70); letter-spacing:.04em;
  background:rgb(255 255 255 / .82); padding:2px 8px; border-radius:var(--radius-full);
}

/* ------------------------------------------------------------------- rail */




.sec { padding:var(--space-4); border-bottom:1px solid var(--border); }
.sec:last-child { border-bottom:0; }
.sec__h {
  font-size:var(--text-xs); text-transform:uppercase; letter-spacing:var(--tracking-caps);
  color:var(--text-tertiary); margin-bottom:var(--space-3);
}
.sec__title { font-size:var(--text-md); font-weight:600; letter-spacing:var(--tracking-heading); }
.sec__sub { font-size:var(--text-sm); color:var(--text-secondary); margin-top:2px; }

/* Rows: one surface, hairline separated. Not a stack of cards. */
.rows { display:flex; flex-direction:column; }
.row {
  display:flex; align-items:center; gap:var(--space-3); padding:9px 0;
  border-bottom:1px solid var(--border); font-size:var(--text-sm);
}
.row:last-child { border-bottom:0; }
.row__k { color:var(--text-secondary); }
.row__v { margin-left:auto; font-variant-numeric:tabular-nums; font-weight:500; }
.row__v--dim { color:var(--text-tertiary); font-weight:400; }
.row--act { cursor:pointer; margin:0 calc(var(--space-4) * -1); padding:9px var(--space-4); }
.row--act:active { background:var(--surface-active); }

.gbar { display:grid; grid-template-columns:64px 1fr 58px; align-items:center; gap:var(--space-3);
  font-size:var(--text-sm); }
.gbar__n { color:var(--text-secondary); }
.gbar__t { height:5px; background:var(--bg-sunken); border-radius:var(--radius-full);
  overflow:hidden; }
.gbar__f { height:100%; border-radius:var(--radius-full); background:var(--n-80);
  transition:width var(--duration-enter) var(--ease-out); }
.gbar__v { text-align:right; font-variant-numeric:tabular-nums; }

/* -------------------------------------------------------------- controls */

.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:7px;
  min-height:38px; padding:0 16px; border-radius:var(--radius-full);
  border:1px solid var(--border-strong); background:var(--surface);
  color:var(--text); font-size:var(--text-sm); font-weight:500; cursor:pointer;
  white-space:nowrap;
  transition:background var(--duration-fast) var(--ease),
    transform var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease);
}
.btn:active { transform:scale(var(--press-scale)); background:var(--surface-active); }
.btn--primary { background:var(--n-99); color:var(--n-00); border-color:var(--n-99); }
.btn--primary:active { background:var(--n-90); }
.btn--wide { width:100%; }
.btn--wide:active { transform:scale(var(--press-scale-subtle)); }
.btn--sm { min-height:30px; padding:0 11px; font-size:var(--text-xs); }
.btn--danger { color:var(--danger); }
.btn:disabled { opacity:.45; cursor:default; transform:none; }

.field {
  width:100%; min-height:40px; padding:0 12px; border-radius:var(--radius-md);
  border:1px solid var(--border-strong); background:var(--surface); color:var(--text);
  font-size:var(--text-base);
}
.field:focus { outline:0; border-color:var(--n-50); box-shadow:0 0 0 3px var(--focus-ring); }
.field--num { text-align:right; font-variant-numeric:tabular-nums; }
select.field { appearance:none; padding-right:28px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236f6f69' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 11px center; }

.stack { display:flex; flex-direction:column; gap:var(--space-3); }
.inline { display:flex; flex-wrap:wrap; gap:var(--space-2); align-items:center; }
.inline > .field { flex:1; min-width:0; }

.note { font-size:var(--text-sm); color:var(--text-secondary); line-height:1.45; }
.note strong { font-weight:600; color:var(--text); }
.warn { color:var(--danger); }

.pill {
  display:inline-flex; align-items:center; gap:5px; padding:3px 9px;
  border-radius:var(--radius-full); background:var(--bg-subtle);
  font-size:var(--text-xs); color:var(--text-secondary); border:1px solid var(--border);
}
.pill--live { background:color-mix(in srgb, var(--success) 12%, var(--n-00));
  color:var(--success); border-color:color-mix(in srgb, var(--success) 24%, transparent); }
.pill--bad { background:color-mix(in srgb, var(--danger) 10%, var(--n-00));
  color:var(--danger); border-color:color-mix(in srgb, var(--danger) 22%, transparent); }

.empty { padding:var(--space-6) var(--space-4); text-align:center; }
.empty__t { font-weight:500; margin-bottom:6px; }
.empty__s { font-size:var(--text-sm); color:var(--text-tertiary); line-height:1.5;
  max-width:26ch; margin:0 auto; }

/* --------------------------------------------------------------- overlays */

.veil {
  position:fixed; inset:0; background:rgb(23 23 20 / .34); z-index:300;
  display:flex; align-items:center; justify-content:center; padding:var(--space-4);
  animation:fade var(--duration-enter) var(--ease-out);
}
.sheet {
  background:var(--surface); border-radius:var(--radius-lg); width:100%;
  max-width:400px; box-shadow:var(--shadow-lg); overflow:hidden;
  animation:rise var(--duration-enter) var(--ease-out);
}
.sheet--wide { max-width:660px; }
.sheet__h { padding:var(--space-5) var(--space-5) var(--space-3); }
.sheet__b { padding:0 var(--space-5) var(--space-5); }
.sheet__t { font-size:var(--text-lg); font-weight:600; letter-spacing:var(--tracking-heading); }
.sheet__s { font-size:var(--text-sm); color:var(--text-secondary); margin-top:4px; line-height:1.45; }
@keyframes fade { from { opacity:0 } }
@keyframes rise { from { opacity:0; transform:translateY(10px) scale(.99) } }

.toasts {
  position:fixed; left:50%; transform:translateX(-50%); bottom:var(--space-5);
  z-index:400; display:flex; flex-direction:column; gap:var(--space-2);
  align-items:center; pointer-events:none;
}
.toast {
  background:var(--n-99); color:var(--n-00); padding:9px 15px;
  border-radius:var(--radius-full); font-size:var(--text-sm); max-width:min(92vw,460px);
  box-shadow:var(--shadow-md); animation:rise var(--duration-enter) var(--ease-out);
}
.toast--bad { background:var(--danger); }

.tip {
  /* Anchored by its top-left corner, not centred on the cursor. Centring means
     the label's own width decides where it sits, and the text changes with
     every hex — so it twitched left and right as the mouse moved, which reads
     as the whole screen shaking. */
  position:absolute; pointer-events:none; background:var(--n-99); color:var(--n-00);
  font-size:var(--text-xs); padding:5px 9px; border-radius:var(--radius-sm);
  white-space:nowrap; z-index:30; box-shadow:var(--shadow-md);
}

/* ---------------------------------------------------------------- alerts
 * The most valuable thing a dense strategy UI can have: one prioritised list
 * of what needs you, each with the action attached. Borrowed from the
 * notification rails in Anno and the alert tray in Paradox games — the player
 * should never have to go looking for what is wrong.
 */
.alerts { display:flex; flex-direction:column; gap:6px; }
.alert {
  display:flex; align-items:flex-start; gap:9px; padding:9px 10px;
  border-radius:var(--radius-sm); background:var(--bg-subtle);
  border-left:3px solid var(--n-40); font-size:var(--text-sm); line-height:1.4;
}
.alert--bad   { border-left-color:var(--danger);
  background:color-mix(in srgb, var(--danger) 7%, var(--surface)); }
.alert--warn  { border-left-color:var(--warning);
  background:color-mix(in srgb, var(--warning) 8%, var(--surface)); }
.alert--good  { border-left-color:var(--success);
  background:color-mix(in srgb, var(--success) 8%, var(--surface)); }
.alert__body { flex:1; min-width:0; }
.alert__t { font-weight:600; color:var(--text); }
.alert__s { color:var(--text-secondary); font-size:var(--text-xs); margin-top:2px; }
.alert__go { flex:none; align-self:center; }

/* ------------------------------------------------------------- stat strip */

.stats { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:1px;
  background:var(--border); border:1px solid var(--border);
  border-radius:var(--radius-sm); overflow:hidden; }
.stat { background:var(--surface); padding:8px 10px; }
.stat__k { font-size:11px; text-transform:uppercase;
  letter-spacing:var(--tracking-caps); color:var(--text-tertiary); }
.stat__v { font-size:var(--text-md); font-weight:600;
  font-variant-numeric:tabular-nums; letter-spacing:var(--tracking-heading); }
.stat__s { font-size:var(--text-xs); color:var(--text-tertiary); }
.stat--bad .stat__v { color:var(--danger); }
.stat--good .stat__v { color:var(--success); }

/* ------------------------------------------------------- production chain
 * Inputs, an arrow, an output — so "why is nothing being made" is answered by
 * looking rather than by reading. A missing input is struck through.
 */
.chain { display:flex; align-items:center; gap:7px; padding:8px 0;
  border-bottom:1px solid var(--border); font-size:var(--text-sm); }
.chain:last-child { border-bottom:0; }
.chain__glyph { flex:none; }
.chain__body { flex:1; min-width:0; }
.chain__name { display:flex; align-items:baseline; gap:6px; }
.chain__flow { font-size:var(--text-xs); color:var(--text-tertiary);
  margin-top:2px; display:flex; align-items:center; gap:5px; flex-wrap:wrap; }
.chain__in { display:inline-flex; align-items:center; gap:4px; }
.chain__in--short { color:var(--danger); text-decoration:line-through; }
.chain__arrow { color:var(--n-40); }
.chain__rate { margin-left:auto; font-variant-numeric:tabular-nums;
  font-weight:500; white-space:nowrap; }
.chain--idle { opacity:.55; }
.gdot { width:7px; height:7px; border-radius:2px; display:inline-block; flex:none; }

/* --------------------------------------------------------- build picker */

.picker { display:flex; flex-direction:column; gap:2px; }
.pick {
  display:flex; align-items:flex-start; gap:10px; padding:10px 11px; width:100%;
  border:1px solid var(--border); border-radius:var(--radius-md);
  background:var(--surface); text-align:left; cursor:pointer; font:inherit;
  color:var(--text);
}
.picker { gap:6px; }
.pick:active { transform:scale(var(--press-scale-subtle)); }
.pick[disabled] { opacity:.5; cursor:default; }
.pick canvas { margin-top:1px; flex:none; }
.pick__b { flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.pick__top { display:flex; align-items:center; gap:8px; }
.pick__n { flex:1 1 auto; min-width:0; font-size:var(--text-sm); font-weight:600; }
.pick__d { font-size:var(--text-xs); color:var(--text-secondary); }
.pick__c { font-size:11.5px; color:var(--text-tertiary);
  font-variant-numeric:tabular-nums; }
.pick__u { color:var(--text-tertiary); }
.pick__c .short { color:var(--danger); }

/* ---------------------------------------------------------------- market */

/* A deal is a proposition, so it gets a surface of its own — one of the few
 * places in this UI where a card is the right answer rather than the lazy one. */
.deal {
  display:flex; flex-direction:column; gap:8px;
  padding:12px; border:1px solid var(--border); border-radius:var(--radius-md);
  background:var(--surface); transition:border-color var(--duration-fast) var(--ease);
}
.deal + .deal { margin-top:9px; }
.deal__top { display:flex; align-items:baseline; gap:8px; }
.deal__name { font-weight:600; letter-spacing:var(--tracking-heading); }
.deal__tag { font-size:var(--text-xs); color:var(--text-tertiary); }
.deal__gain { margin-left:auto; font-variant-numeric:tabular-nums;
  font-weight:600; color:var(--success); white-space:nowrap; }
.deal__legs { display:flex; flex-direction:column; gap:3px; font-size:var(--text-sm); }
.deal__leg { display:flex; gap:7px; align-items:baseline; }
.deal__dir { font-size:var(--text-xs); color:var(--text-tertiary);
  text-transform:uppercase; letter-spacing:var(--tracking-caps); width:46px;
  flex:none; }
.deal__foot { display:flex; align-items:center; gap:8px; }
.deal__meta { font-size:var(--text-xs); color:var(--text-tertiary); flex:1; }

/* Goods as a grid of small tiles: the price, where it has been, and whether it
 * is moving. Tapping one focuses the order book below it. */
.goods { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:7px; }
.good {
  display:flex; flex-direction:column; gap:3px; padding:8px 9px;
  border:1px solid var(--border); border-radius:var(--radius-sm);
  background:var(--surface); cursor:pointer; text-align:left;
}
.good[aria-pressed="true"] { border-color:var(--n-80); background:var(--bg-subtle); }
.good:active { transform:scale(var(--press-scale-subtle)); }
.good__top { display:flex; align-items:center; gap:6px; }
.good__dot { width:8px; height:8px; border-radius:2px; flex:none; }
.good__name { font-size:var(--text-xs); color:var(--text-secondary);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.good__row { display:flex; align-items:baseline; gap:6px; }
.good__price { font-size:var(--text-base); font-weight:600;
  font-variant-numeric:tabular-nums; }
.good__chg { font-size:11px; font-variant-numeric:tabular-nums; }
.good__spark { height:22px; margin-top:1px; }

/* ------------------------------------------------------------ market data
 * One panel per good: what it is worth, where it has been, and the best bid
 * and ask anybody is actually showing. The point of a market screen is that
 * you can read the whole board without touching anything.
 */
.mkt { padding:12px 0; border-bottom:1px solid var(--border); }
.mkt:last-child { border-bottom:0; }
.mkt__top { display:flex; align-items:baseline; gap:8px; }
.mkt__dot { width:9px; height:9px; border-radius:2px; flex:none; }
.mkt__name { font-weight:600; letter-spacing:var(--tracking-heading); }
.mkt__now { margin-left:auto; font-size:var(--text-md); font-weight:600;
  font-variant-numeric:tabular-nums; }
.mkt__chg { font-size:var(--text-xs); font-variant-numeric:tabular-nums; }
.mkt__chart { margin:6px 0 4px; }
.mkt__book { display:flex; gap:var(--space-4); font-size:var(--text-xs);
  color:var(--text-tertiary); flex-wrap:wrap; }
.mkt__side b { font-variant-numeric:tabular-nums; color:var(--text); }
.mkt__spread { margin-left:auto; }
.mkt--flat { opacity:.55; }

/* ---------------------------------------------------------------- tables */

.tbl { width:100%; border-collapse:collapse; font-size:var(--text-sm); }
.tbl th {
  text-align:left; font-weight:400; font-size:var(--text-xs); color:var(--text-tertiary);
  padding:0 0 7px; border-bottom:1px solid var(--border); white-space:nowrap;
}
.tbl td { padding:8px 0; border-bottom:1px solid var(--border);
  font-variant-numeric:tabular-nums; }
.tbl tr:last-child td { border-bottom:0; }
.tbl .num { text-align:right; }
.tbl .up { color:var(--success); }
.tbl .dn { color:var(--danger); }

.feed { display:flex; flex-direction:column; }
.feed__i { padding:10px 0; border-bottom:1px solid var(--border); font-size:var(--text-sm);
  line-height:1.45; }
.feed__i:last-child { border-bottom:0; }
.feed__m { font-size:var(--text-xs); color:var(--text-tertiary); margin-top:3px; }

/* ---------------------------------------------------------------- mobile */

/* Dialogs hold two-column comparisons — what you carry against what you buy,
 * what you give against what you want. Below this they have to stack or the
 * numbers end up two characters wide. */


/* Very wide screens: the map should get the extra room, not the rails. */

/* Short screens — a laptop in landscape, a phone on its side. */

/* ---- goods strip -------------------------------------------------------- */
.chips { display: flex; gap: 6px; overflow-x: auto; padding: 2px 0 8px;
         scrollbar-width: none; }
.chips::-webkit-scrollbar { display: none; }
.chip { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto;
        padding: 6px 10px; border: 1px solid var(--border); border-radius: 999px;
        background: var(--surface); color: var(--text); cursor: pointer;
        font-size: 12px; line-height: 1; white-space: nowrap;
        transition: border-color .12s, background .12s; }
@media (hover:hover) { .chip:hover { border-color: var(--text-tertiary); } }
.chip[aria-pressed="true"] { background: var(--text); color: var(--surface);
                             border-color: var(--text); }
.chip__dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.chip__n { font-weight: 500; }
.chip__p { opacity: .6; font-variant-numeric: tabular-nums; }
.chip[aria-pressed="true"] .chip__p { opacity: .75; }

/* ---- the book, split by what you would do ------------------------------- */
.ob { border: 1px solid var(--border); border-radius: var(--radius-md);
      background: var(--surface); overflow: hidden; margin-bottom: 10px; }
.ob__h { display: flex; align-items: baseline; gap: 8px; padding: 9px 12px;
         border-bottom: 1px solid var(--border); background: var(--bg-subtle); }
.ob__t { font-weight: 600; font-size: 13px; }
.ob__s { font-size: 11px; color: var(--text-tertiary); }
.ob__none { padding: 14px 12px; font-size: 12px; color: var(--text-tertiary); }
.ob__row { display: flex; align-items: center; gap: 9px; width: 100%;
           padding: 9px 12px; background: none; border: 0; cursor: pointer;
           text-align: left; color: var(--text); font: inherit;
           border-top: 1px solid var(--border); }
.ob__row:first-of-type { border-top: 0; }
@media (hover:hover) { .ob__row:hover { background: var(--bg-subtle); } }
.ob__who { flex: 1; min-width: 0; }
.ob__name { font-weight: 500; font-size: 13px; overflow: hidden;
            text-overflow: ellipsis; white-space: nowrap; }
.ob__sub { font-size: 11px; color: var(--text-tertiary); }
.ob__px { text-align: right; flex: 0 0 auto; }
.ob__big { font-weight: 600; font-size: 14px;
           font-variant-numeric: tabular-nums; }

/* ---- market panel sides ------------------------------------------------- */
.mkt__side { display: flex; align-items: center; gap: 7px; padding: 6px 0;
             font-size: 12px; border-top: 1px solid var(--border); }
.mkt__lbl { color: var(--text-tertiary); }
.mkt__v { font-weight: 600; font-variant-numeric: tabular-nums; }
.mkt__who { flex: 1; min-width: 0; color: var(--text-tertiary); overflow: hidden;
            text-overflow: ellipsis; white-space: nowrap; }
.mkt__side--buy .mkt__v { color: var(--danger); }
.mkt__side--sell .mkt__v { color: var(--success); }
.mkt__spread { font-size: 11px; color: var(--text-tertiary); padding-top: 6px; }

/* ---- the trade ticket --------------------------------------------------- */
.tk { display: flex; flex-direction: column; gap: var(--space-3); }
.tk__qrow { display: flex; align-items: center; gap: var(--space-2); }
.tk__lbl { flex: 1; font-size: var(--text-sm); color: var(--text-secondary); }
.tk__num { width: 110px; text-align: right;
           font-variant-numeric: tabular-nums; }
.tk__slider { width: 100%; margin: 0; accent-color: var(--text);
              height: 22px; }
.tk__ceil { font-size: var(--text-xs); color: var(--text-secondary);
            margin-top: calc(var(--space-2) * -1); }
.tk__caps { color: var(--text-tertiary); }
.tk__legs { display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
            background: var(--border); border: 1px solid var(--border);
            border-radius: var(--radius-md); overflow: hidden; }
.tk__leg { background: var(--surface); padding: var(--space-3); }
.tk__dir { font-size: var(--text-xs); letter-spacing: var(--tracking-caps);
           text-transform: uppercase; color: var(--text-tertiary); }
.tk__v { font-size: var(--text-md); font-weight: 600; margin-top: 2px;
         font-variant-numeric: tabular-nums; }
.tk__road, .tk__eff { font-size: var(--text-sm); color: var(--text-secondary); }
.tk__eff { color: var(--text); }
.tk__warn { font-size: var(--text-sm); color: var(--danger);
            background: color-mix(in srgb, var(--danger) 8%, transparent);
            border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); }

/* ---- how good this ground is for this works ----------------------------- */
.pick__land { display: inline-block; flex: none; white-space: nowrap; font-size: 11px;
              font-weight: 500; padding: 1px 6px; border-radius: 999px;
              border: 1px solid currentColor; }
.land--prime { color: var(--success); }
.land--good  { color: var(--accent-2); }
.land--fair  { color: var(--warning); }
.land--poor  { color: var(--danger); }

/* ---- a mode that is waiting for you to point at something --------------- */
.modebar {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--space-5) + env(safe-area-inset-bottom, 0px));
  display: flex; align-items: center; gap: var(--space-3);
  background: var(--n-99); color: var(--n-00);
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-full);
  box-shadow: var(--shadow-lg); z-index: 40; font-size: var(--text-sm);
  max-width: calc(100vw - 32px);
}
.modebar .btn { background: rgb(255 255 255 / .16); border-color: transparent;
                color: var(--n-00); }

@media (prefers-reduced-motion: reduce) {
  :root { --duration-fast:0ms; --duration-enter:0ms; --duration-exit:0ms;
          --press-scale:1; --press-scale-subtle:1; }
}

@media (hover:hover) {
  .layers button:hover:not([aria-pressed="true"]) { background:var(--surface-hover);
    color:var(--text); }
}

@media (hover:hover) { .row--act:hover { background:var(--surface-hover); } }

@media (hover:hover) { .btn:hover { background:var(--surface-hover);
  border-color:var(--n-40); } }

@media (hover:hover) { .btn--primary:hover { background:var(--n-90);
  border-color:var(--n-90); } }

@media (hover:hover) { .pick:hover { background:var(--surface-hover);
  border-color:var(--border); } }

@media (hover:hover) { .deal:hover { border-color:var(--border-strong); } }

@media (max-width: 620px) {
  .sheet__b [style*="grid-template-columns:1fr 1fr"],
  .sheet__b [style*="grid-template-columns: 1fr 1fr"] {
    grid-template-columns: 1fr !important;
  }
  .sheet { max-width: 100%; }
  .sheet__h { padding: var(--space-4) var(--space-4) var(--space-2); }
  .sheet__b { padding: 0 var(--space-4) var(--space-4); }
  .veil { align-items: flex-end; padding: 0; }
  .sheet { border-radius: var(--radius-lg) var(--radius-lg) 0 0;
           max-height: 92dvh; overflow-y: auto; }
}

@media (max-width: 420px) {
  .tk__legs { grid-template-columns: 1fr; }
}

/* ============================================================== THE SHELL
 * The map is the screen. Everything here floats over it, so depth comes from
 * a hairline plus a real shadow rather than a filled panel — a flat block on
 * a light ground reads as a hole in the map.
 */
#app { height: 100%; display: flex; flex-direction: column;
       background: var(--bg); }

.bar { flex: none; height: 52px; display: flex; align-items: stretch;
       background: var(--surface); border-bottom: 1px solid var(--border);
       padding-top: env(safe-area-inset-top, 0px); box-sizing: content-box; }
.bar__me { display: flex; align-items: center; gap: var(--space-2);
           padding: 0 var(--space-4); background: none; border: 0;
           border-right: 1px solid var(--border); color: var(--text);
           text-align: left; cursor: pointer; flex: none; }
.bar__me:active { background: var(--surface-hover); }
.bar__glyph { width: 21px; height: 21px; background: var(--text); flex: none;
              clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%); }
.bar__n { font-size: var(--text-sm); font-weight: 600; line-height: 1.1;
          letter-spacing: -.01em; }
.bar__s { font-size: var(--text-xs); color: var(--text-tertiary); }
.bar__sp { flex: 1 1 auto; }
.bar__icon { flex: none; width: 34px; margin: 9px var(--space-3) 9px 0;
             background: none; border: 1px solid var(--border);
             border-radius: var(--radius-sm); color: var(--text-secondary);
             cursor: pointer; }

/* Only the goods that are MOVING, then a count. Fourteen chips of digits is a
 * wall, and a wall is not information. */
.purse { display: flex; align-items: center; gap: 5px; padding: 0 var(--space-3);
         min-width: 0; overflow: hidden; }
.pill { display: flex; align-items: center; gap: 7px; padding: 5px 9px; flex: none;
        background: none; border: 1px solid var(--border);
        border-radius: var(--radius-sm); color: var(--text); cursor: pointer;
        text-align: left; }
.pill__dot { width: 8px; height: 8px; border-radius: 2px; flex: none; }
.pill__v { font-size: var(--text-sm); font-weight: 600; line-height: 1.1;
           font-variant-numeric: tabular-nums; }
.pill__d { font-size: 10.5px; line-height: 1.25; }
.pill--more { border-style: dashed; color: var(--text-tertiary);
              font-size: var(--text-xs); font-weight: 500; padding: 7px 9px; }

.jump { display: flex; align-items: center; gap: 7px; flex: none;
        margin: 9px var(--space-2) 9px 0; padding: 0 var(--space-3);
        background: var(--bg-subtle); border: 1px solid var(--border);
        border-radius: var(--radius-full); color: var(--text-tertiary);
        font-size: var(--text-xs); cursor: pointer; }
.clock { display: flex; align-items: center; gap: 6px; flex: none;
         padding: 0 var(--space-2); font-size: var(--text-xs);
         color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.clock__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--success); }
.clock__dot--off { background: var(--n-40); }

.stage { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden; }
#map { position: absolute; inset: 0; width: 100%; height: 100%; display: block;
       touch-action: none; cursor: grab; }
#map.dragging { cursor: grabbing; }

/* ---- the rooms: a rail on a desktop, a thumb bar on a phone ------------- */
.rooms { position: absolute; top: var(--space-3); left: var(--space-3);
         display: flex; flex-direction: column; gap: 2px; padding: 5px;
         background: color-mix(in srgb, var(--surface) 94%, transparent);
         border: 1px solid var(--border); border-radius: var(--radius-md);
         box-shadow: var(--shadow-md); z-index: 40; }
.rooms button { position: relative; width: 36px; height: 34px; display: flex;
                align-items: center; justify-content: center; background: none;
                border: 0; border-radius: var(--radius-sm);
                color: var(--text-secondary); cursor: pointer;
                transition: background var(--duration-fast) var(--ease); }
.rooms button[aria-selected="true"] { background: var(--bg-subtle);
                                      color: var(--text); }
.rooms button:active { transform: scale(var(--press-scale)); }
.rooms__b { position: absolute; top: 1px; right: 0; min-width: 15px; height: 15px;
            padding: 0 4px; box-sizing: border-box; border-radius: 8px;
            font-size: 10px; font-weight: 600; line-height: 15px;
            text-align: center; color: var(--n-00); }

/* ---- what is selected. Half what it was: what it IS and what you can do. */
.card { position: absolute; top: calc(var(--space-3) + 46px); right: var(--space-3);
        width: 300px; max-height: calc(100% - 142px); display: flex;
        flex-direction: column; background: var(--surface);
        border: 1px solid var(--border); border-radius: var(--radius-md);
        box-shadow: var(--shadow-lg); overflow: hidden; z-index: 35;
        animation: rise var(--duration-enter) var(--ease-out); }
.card__head { flex: none; padding: 11px 13px; }
.card__body { flex: 1 1 auto; min-height: 0; overflow-y: auto;
              padding: 0 13px 13px; }
.card__t { display: flex; align-items: center; gap: var(--space-2); }
.card__n { flex: 1 1 auto; font-size: var(--text-md); font-weight: 600;
           letter-spacing: -.015em; }
.card__x { width: 24px; height: 24px; flex: none; background: none;
           border: 1px solid var(--border); border-radius: var(--radius-sm);
           color: var(--text-tertiary); cursor: pointer; }
.card__s { margin-top: 2px; font-size: 11.5px; color: var(--text-tertiary); }

.whereami { position: absolute; right: var(--space-3); bottom: 82px;
            font-size: var(--text-xs); color: var(--text-tertiary);
            font-variant-numeric: tabular-nums; z-index: 11; }

/* ---- a room: a sheet that slides in from the left edge -----------------
 * Flush to the edge and the full height of the map, under the rail, so the
 * rail stays where it was and the room reads as coming out from behind it.
 * No fade, no gap: it slides, and slides back out. */
.room { position: absolute; top: 0; bottom: 0; left: 0; z-index: 30;
        width: min(720px, 100%); display: flex; flex-direction: column;
        padding-left: 64px; box-sizing: border-box;
        background: var(--bg); border-right: 1px solid var(--border);
        box-shadow: 16px 0 40px rgb(23 23 20 / .12);
        transform: translateX(0);
        animation: roomin 240ms cubic-bezier(.2, .8, .2, 1); }
.room.room--out { transform: translateX(-100%);
                  transition: transform 180ms cubic-bezier(.4, 0, 1, 1); }
@keyframes roomin { from { transform: translateX(-100%) } }
@media (prefers-reduced-motion: reduce) {
  .room, .room.room--out { animation: none; transition: none; }
}
.room__bar { flex: none; display: flex; align-items: center;
             gap: var(--space-3); padding: var(--space-3) var(--space-5);
             background: var(--surface); border-bottom: 1px solid var(--border); }
.room__back { width: 31px; height: 31px; flex: none; background: var(--surface);
              border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
              color: var(--text); cursor: pointer; font-size: 15px; }
.room__back:active { transform: scale(var(--press-scale)); }
.room__title { font-size: var(--text-lg); font-weight: 600;
               letter-spacing: var(--tracking-heading); }
.room__sub { flex: 1 1 auto; font-size: var(--text-xs);
             color: var(--text-tertiary); }
.room__body { flex: 1 1 auto; min-height: 0; overflow-y: auto;
              padding: var(--space-4) var(--space-5)
                       calc(var(--space-5) + env(safe-area-inset-bottom, 0px)); }
/* A room is wide, so its sections read as columns rather than one long strip. */
.room__body > div { max-width: 100%; }
.room__cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
              gap: var(--space-4); align-items: start; }

@media (max-width: 1000px) {
  /* A phone cannot hold a rail, so the rooms go on the thumb line and the
     card becomes a sheet. Same four parts, same rules. */
  .rooms { flex-direction: row; top: auto; left: 0; right: 0;
           bottom: 0; gap: 0; padding: 4px 4px calc(4px + env(safe-area-inset-bottom, 0px));
           border-radius: 0; border-left: 0; border-right: 0; border-bottom: 0;
           justify-content: space-around; }
  .rooms button { flex: 1 1 0; height: 44px; }
  .whereami { display: none; }
  .card { top: auto; left: 0; right: 0; bottom: calc(56px + env(safe-area-inset-bottom, 0px));
          width: auto; max-height: 62%; border-radius: var(--radius-lg) var(--radius-lg) 0 0;
          border-left: 0; border-right: 0; }
  .jump span { display: none; }
  .room__body { padding: var(--space-3) var(--space-4); }
  .purse { gap: 4px; }
}
@media (max-width: 620px) {
  .bar__s { display: none; }
  .clock { display: none; }
}

/* ---- learn ---------------------------------------------------------------- */
.learn__now { padding: var(--space-4); background: var(--surface);
              border: 1px solid var(--border); border-radius: var(--radius-md);
              box-shadow: var(--shadow-sm); display: flex; flex-direction: column;
              gap: var(--space-3); max-width: 560px; }
.learn__nowtop { display: flex; align-items: flex-end; gap: var(--space-3); }
.learn__nowtop > div:first-child { flex: 1 1 auto; }
.learn__k { font-size: 10.5px; letter-spacing: var(--tracking-caps);
            text-transform: uppercase; color: var(--text-tertiary); font-weight: 600; }
.learn__nown { font-size: var(--text-md); font-weight: 600; }
.learn__left { font-size: var(--text-sm); font-weight: 600; color: var(--warning);
               font-variant-numeric: tabular-nums; }
.learn__bar { height: 7px; background: var(--bg-sunken); border-radius: 4px;
              overflow: hidden; }
.learn__fill { height: 100%; background: var(--text); border-radius: 4px;
               transition: width var(--duration-enter) var(--ease); }
.learn__now .btn { align-self: flex-start; }
.learn__hd { display: flex; align-items: center; gap: var(--space-3);
             flex-wrap: wrap; margin-bottom: var(--space-3); }
.learn__hd .sec__h { margin: 0; flex: 1 1 auto; }
.learn__seg { display: flex; flex-wrap: wrap; gap: 2px; padding: 3px;
              background: var(--surface); border: 1px solid var(--border);
              border-radius: var(--radius-full); }
.learn__seg button { padding: 5px 11px; background: none; border: 0;
                     border-radius: var(--radius-full); color: var(--text-secondary);
                     font-size: var(--text-xs); font-weight: 500; cursor: pointer; }
.learn__seg button[aria-pressed="true"] { background: var(--text); color: var(--n-00); }
.learn__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
               gap: var(--space-3); }
.tech { display: flex; flex-direction: column; gap: 6px; padding: var(--space-3);
        background: var(--surface); border: 1px solid var(--border);
        border-radius: var(--radius-md); box-shadow: var(--shadow-sm); }
.tech--poor { background: var(--bg-subtle); }
.tech--banned { border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); }
.tech__top { display: flex; align-items: baseline; gap: var(--space-2); }
.tech__n { flex: 1 1 auto; font-size: var(--text-base); font-weight: 600; }
.tech--banned .tech__n { color: var(--danger); }
.tech__sch { font-size: 11px; color: var(--text-tertiary); }
.tech__e { font-size: var(--text-sm); color: var(--text-secondary); line-height: 1.4; }
.tech__ban { font-size: 11.5px; color: var(--danger); line-height: 1.35;
             padding: 6px 8px; border-radius: var(--radius-sm);
             background: color-mix(in srgb, var(--danger) 7%, transparent); }
.tech__foot { display: flex; align-items: center; gap: var(--space-2); margin-top: 2px; }
.tech__c { flex: 1 1 auto; font-size: 11.5px; color: var(--text-tertiary);
           font-variant-numeric: tabular-nums; }
.tech__opens { font-size: 11px; color: var(--text-tertiary); border-top: 1px solid var(--border);
               padding-top: 6px; }
.learn__counts { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
                 gap: var(--space-3); margin-top: var(--space-5); }
.learn__count { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3);
                background: var(--surface); border: 1px solid var(--border);
                border-radius: var(--radius-md); text-align: left; cursor: pointer;
                color: var(--text); }
.learn__count.is-known { border-color: color-mix(in srgb, var(--success) 40%, var(--border)); }
.learn__count.is-banned { border-color: color-mix(in srgb, var(--danger) 40%, var(--border)); }
.learn__cv { font-size: var(--text-xl); font-weight: 600; line-height: 1;
             font-variant-numeric: tabular-nums; }
.learn__count.is-known .learn__cv { color: var(--success); }
.learn__count.is-banned .learn__cv { color: var(--danger); }
.learn__ck { display: block; font-size: var(--text-sm); font-weight: 600; }
.learn__cs { display: block; font-size: 11.5px; color: var(--text-tertiary); }

/* ---- a pager, the same everywhere -------------------------------------- */
.pager { display: flex; align-items: center; gap: 5px; margin-top: var(--space-3);
         flex-wrap: wrap; }
.pager__b { min-width: 28px; height: 27px; padding: 0 7px; background: var(--surface);
            border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
            color: var(--text); font-size: var(--text-xs); font-weight: 500; cursor: pointer; }
.pager__b[aria-pressed="true"] { background: var(--text); border-color: var(--text);
                                  color: var(--n-00); }
.pager__b:disabled { color: var(--n-40); cursor: default; }
.pager__n { font-size: var(--text-xs); color: var(--text-tertiary); margin-left: 4px; }

/* ---- what an army does when the gates give ----------------------------- */
.intent { display: grid; grid-template-columns: auto 1fr; align-items: center;
          gap: 4px var(--space-2); padding: var(--space-2) var(--space-3);
          margin: -4px 0 var(--space-2); border: 1px dashed var(--border-strong);
          border-radius: var(--radius-sm); background: var(--bg-subtle); }
.intent__k { font-size: 11px; letter-spacing: var(--tracking-caps);
             text-transform: uppercase; color: var(--text-tertiary); font-weight: 600; }
.intent__pick { min-height: 30px; padding: 4px 8px; font-size: var(--text-xs); }
.intent__s { grid-column: 1 / -1; font-size: 11.5px; color: var(--text-secondary);
             line-height: 1.35; }
.intent--crime { border-color: color-mix(in srgb, var(--danger) 50%, var(--border));
                 background: color-mix(in srgb, var(--danger) 5%, var(--surface)); }
.intent--crime .intent__s { color: var(--danger); }

/* ---- politics ------------------------------------------------------------- */
.pol__warn { display: flex; flex-direction: column; gap: 6px; padding: var(--space-3);
             margin-bottom: var(--space-2); border-radius: var(--radius-md);
             border: 1px solid color-mix(in srgb, var(--danger) 45%, var(--border));
             background: color-mix(in srgb, var(--danger) 5%, var(--surface)); }
.pol__warn .btn { align-self: flex-start; }
.pol__wt { font-size: var(--text-sm); font-weight: 600; color: var(--danger); }
.pol__ws { font-size: var(--text-xs); color: var(--text-secondary); line-height: 1.4; }
.pol__line { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) auto;
             gap: var(--space-3); align-items: baseline; padding: 8px 0;
             border-top: 1px solid var(--border); font-size: var(--text-sm); }
.pol__who { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pol__why { color: var(--text-secondary); font-size: var(--text-xs); }
.pol__left { color: var(--warning); font-size: var(--text-xs);
             font-variant-numeric: tabular-nums; }
.bloc { display: flex; flex-direction: column; gap: 8px; padding: var(--space-3);
        margin-bottom: var(--space-2); background: var(--surface);
        border: 1px solid var(--border); border-radius: var(--radius-md);
        box-shadow: var(--shadow-sm); }
.bloc__top { display: flex; align-items: center; gap: var(--space-2); }
.bloc__sw { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.bloc__n { flex: 1 1 auto; font-size: var(--text-base); font-weight: 600; }
.bloc__m { font-size: var(--text-xs); color: var(--text-tertiary); }
.bloc__rules, .bloc__pick { display: flex; flex-wrap: wrap; gap: 5px; }
.bloc__rule { padding: 3px 9px; border-radius: var(--radius-full); font-size: 11.5px;
              background: var(--bg-subtle); border: 1px solid var(--border);
              color: var(--text-secondary); }
.bloc__rule.is-ban { color: var(--danger);
                     border-color: color-mix(in srgb, var(--danger) 35%, var(--border));
                     background: color-mix(in srgb, var(--danger) 5%, var(--surface)); }
.bloc__who { font-size: var(--text-xs); color: var(--text-tertiary); }
.bloc__opt { padding: 6px 11px; border-radius: var(--radius-full); font-size: var(--text-xs);
             background: var(--surface); border: 1px solid var(--border-strong);
             color: var(--text-secondary); cursor: pointer; text-align: left; }
.bloc__opt[aria-pressed="true"] { background: var(--text); color: var(--n-00);
                                   border-color: var(--text); }
.bloc__opt.is-ban[aria-pressed="true"] { background: var(--danger); border-color: var(--danger); }
.vote { display: flex; flex-direction: column; gap: 6px; padding: var(--space-3);
        margin-bottom: var(--space-2); background: var(--surface);
        border: 1px solid var(--border); border-radius: var(--radius-md); }
.vote__t { font-size: var(--text-sm); font-weight: 600; }
.vote__s { font-size: var(--text-xs); color: var(--text-tertiary); }

/* ---- the hall --------------------------------------------------------------- */
.hall__tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: var(--space-3); }
.hall__tab { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px;
             border-radius: var(--radius-full); border: 1px solid var(--border-strong);
             background: var(--surface); color: var(--text-secondary);
             font-size: var(--text-xs); font-weight: 500; cursor: pointer; }
.hall__tab::before { content: ""; width: 7px; height: 7px; border-radius: 50%;
                     background: var(--dot, var(--accent)); }
.hall__tab[aria-pressed="true"] { background: var(--text); color: var(--n-00);
                                   border-color: var(--text); }
.hall__older { display: block; margin: 0 auto var(--space-2); }
.hall__log { display: flex; flex-direction: column; gap: 2px; min-height: 240px;
             max-height: min(60vh, 560px); overflow-y: auto; padding: var(--space-2);
             background: var(--surface); border: 1px solid var(--border);
             border-radius: var(--radius-md); }
.hall__line { display: grid; grid-template-columns: minmax(80px, 150px) minmax(0, 1fr) auto;
              gap: var(--space-3); align-items: baseline; padding: 6px 8px;
              border-radius: var(--radius-sm); font-size: var(--text-sm); }
.hall__line.is-mine { background: var(--bg-subtle); }
.hall__who { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hall__body { color: var(--text); overflow-wrap: anywhere; line-height: 1.4; }
.hall__ts { font-size: 11px; color: var(--text-tertiary); white-space: nowrap; }
.hall__form { display: flex; gap: var(--space-2); margin-top: var(--space-3); }
.hall__in { flex: 1 1 auto; }
@media (max-width: 620px) {
  .hall__line { grid-template-columns: minmax(0, 1fr) auto; }
  .hall__body { grid-column: 1 / -1; }
  .pol__line { grid-template-columns: minmax(0, 1fr) auto; }
  .pol__why { grid-column: 1 / -1; order: 3; }
}
.tk__alt { color: var(--text-tertiary); font-size: 11.5px; }
.toll { display: flex; align-items: center; gap: var(--space-3); margin: var(--space-3) 0 6px; }
.toll__k { font-size: var(--text-sm); font-weight: 600; }
.toll__r { flex: 1 1 auto; accent-color: var(--text); }
.toll__v { width: 44px; text-align: right; font-size: var(--text-sm); font-weight: 600;
           font-variant-numeric: tabular-nums; }

/* ---- the book, by how far away it is ------------------------------------ */
.ob__c { margin-left: auto; font-size: 11px; color: var(--text-tertiary);
         font-variant-numeric: tabular-nums; }
.ob__band { display: flex; align-items: baseline; gap: var(--space-2);
            padding: 8px 12px 4px; border-top: 1px solid var(--border); }
.ob__band:first-of-type { border-top: 0; }
.ob__bn { font-size: 10.5px; letter-spacing: var(--tracking-caps); text-transform: uppercase;
          font-weight: 600; color: var(--text-secondary); }
.ob__bs { flex: 1 1 auto; font-size: 11px; color: var(--text-tertiary); }
.ob__bc { font-size: 11px; color: var(--text-tertiary); font-variant-numeric: tabular-nums; }
.ob__pager { padding: 0 12px 10px; margin-top: 4px; }

/* ---- your land, by ring ------------------------------------------------- */
.land { display: flex; flex-direction: column; gap: 6px; }
.land__row { display: grid; grid-template-columns: 76px minmax(0, 1.3fr) minmax(0, 1fr) 104px;
             align-items: center; gap: var(--space-3); width: 100%;
             padding: 9px 12px; background: var(--surface);
             border: 1px solid var(--border); border-radius: var(--radius-md);
             color: var(--text); text-align: left; cursor: pointer; font: inherit; }
.land__row.is-stalled { border-color: color-mix(in srgb, var(--danger) 40%, var(--border)); }
.land__q { font-size: var(--text-sm); font-weight: 600; font-variant-numeric: tabular-nums; }
.land__t { font-size: 11px; color: var(--text-tertiary); }
.land__n { display: flex; align-items: center; gap: 6px; font-size: var(--text-sm);
           font-weight: 600; }
.land__makes { font-size: 11px; color: var(--text-tertiary); overflow: hidden;
               text-overflow: ellipsis; white-space: nowrap; }
.land__gk { display: flex; justify-content: space-between; font-size: 11px;
            color: var(--text-tertiary); }
.land__bar { height: 5px; margin-top: 3px; background: var(--bg-sunken);
             border-radius: 3px; overflow: hidden; }
.land__fill { height: 100%; border-radius: 3px; background: currentColor; }
.land__out { text-align: right; }
.land__v { font-size: var(--text-sm); font-weight: 600; color: var(--success);
           font-variant-numeric: tabular-nums; }
.land__out.is-bad .land__v { color: var(--danger); }
.land__u { font-size: 11px; color: var(--text-tertiary); font-variant-numeric: tabular-nums; }
@media (max-width: 620px) {
  .land__row { grid-template-columns: minmax(0, 1fr) auto; }
  .land__at, .land__grade { display: none; }
}
.mkt__anchor { font-size: 11.5px; color: var(--text-tertiary); margin: 2px 0 4px; }
.mkt__anchor.up { color: var(--danger); }
.mkt__anchor.dn { color: var(--success); }

/* ---- markers: one small thing per place, detail on a click ------------- */
.callouts { position: absolute; inset: 0; pointer-events: none; z-index: 10; }
.callout { position: absolute; left: 0; top: 0; display: flex; flex-direction: column;
           align-items: center; pointer-events: none; will-change: transform; }
.callout__card { pointer-events: auto; max-width: 300px; background: var(--surface);
                 border: 1px solid var(--border); border-radius: 999px;
                 box-shadow: var(--shadow-md); overflow: hidden;
                 transition: border-radius var(--duration-fast) var(--ease); }
.callout.is-open .callout__card { border-radius: var(--radius-md); }
.callout__chip { display: flex; align-items: center; gap: 7px; max-width: 300px;
                 padding: 5px 11px 5px 9px; background: none; border: 0;
                 color: var(--text); font: inherit; cursor: pointer; }
.callout__lvl { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.callout__t { font-size: 12.5px; font-weight: 600; overflow: hidden;
              text-overflow: ellipsis; white-space: nowrap; }
.callout__n { flex: none; padding: 1px 6px; border-radius: 999px;
              background: var(--bg-sunken); color: var(--text-secondary);
              font-size: 11px; font-weight: 600; }
.callout__list { display: flex; flex-direction: column; border-top: 1px solid var(--border); }
.callout__row { display: flex; align-items: flex-start; gap: 8px; padding: 8px 11px; }
.callout__row + .callout__row { border-top: 1px solid var(--border); }
.callout__row .callout__lvl { margin-top: 5px; }
.callout__col { flex: 1 1 auto; min-width: 0; }
.callout__rt { font-size: 12.5px; font-weight: 600; }
.callout__rs { font-size: 11.5px; color: var(--text-secondary); line-height: 1.35;
               margin-top: 1px; }
.callout__go { flex: none; padding: 4px 10px; background: var(--surface);
               border: 1px solid var(--border-strong); border-radius: 999px;
               color: var(--text); font-size: 11.5px; font-weight: 500; cursor: pointer; }
.callout__line { width: 1px; background: var(--text-tertiary); opacity: .45; }
.callout__pin { width: 7px; height: 7px; border-radius: 50%;
                box-shadow: 0 0 0 2px var(--surface); }
@media (max-width: 1000px) {
  .callout__card, .callout__chip { max-width: 220px; }
}

.pill__n { font-size: 11px; font-weight: 500; color: var(--text-secondary);
           line-height: 1.1; }
.pill__row { display: flex; align-items: baseline; gap: 6px; }
.pill__col { display: flex; flex-direction: column; min-width: 0; }

@media (max-width: 1000px) {
  .room { left: 0; width: 100%; padding-left: 0; bottom: calc(52px + env(safe-area-inset-bottom, 0px));
          border-right: 0; box-shadow: none; }
  .zoomer { bottom: calc(116px + env(safe-area-inset-bottom, 0px)); }
}
@media (prefers-reduced-motion: reduce) { .room { animation: none; } }

/* ---- trading dialogs: offer, counter, gift -------------------------------- */
.sheet--wide { max-width: 760px; }
.offer { display: flex; flex-direction: column; gap: var(--space-4); }
.offer__label { font-size: 10.5px; letter-spacing: var(--tracking-caps);
                text-transform: uppercase; color: var(--text-tertiary);
                font-weight: 600; margin-bottom: -8px; }
.offer__who { display: flex; flex-wrap: wrap; gap: 6px; align-items: stretch; }
.whochip { display: flex; flex-direction: column; align-items: flex-start;
           padding: 7px 12px; background: var(--surface);
           border: 1px solid var(--border-strong); border-radius: var(--radius-md);
           color: var(--text); cursor: pointer; text-align: left; font: inherit; }
.whochip[aria-pressed="true"] { background: var(--text); border-color: var(--text);
                                 color: var(--n-00); }
.whochip__n { font-size: var(--text-sm); font-weight: 600; line-height: 1.2; }
.whochip__s { font-size: 11px; opacity: .65; }
.whochip__more { width: auto; min-width: 140px; }
.offer__sides { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
                gap: var(--space-4); }
.bask { display: flex; flex-direction: column; gap: var(--space-2);
        padding: var(--space-3); background: var(--bg-subtle);
        border: 1px solid var(--border); border-radius: var(--radius-md); }
.bask__h { display: flex; align-items: baseline; gap: var(--space-2); }
.bask__t { font-size: var(--text-sm); font-weight: 600; flex: 1 1 auto; }
.bask__v { font-size: 11.5px; color: var(--text-tertiary);
           font-variant-numeric: tabular-nums; }
.bask__rows { display: flex; flex-direction: column; gap: 6px; }
.bask__row { display: flex; align-items: center; gap: var(--space-2);
             padding: 6px 6px 6px 10px; background: var(--surface);
             border: 1px solid var(--border); border-radius: var(--radius-sm); }
.bask__name { flex: 1 1 auto; min-width: 0; font-size: var(--text-sm); font-weight: 500; }
.bask__have { font-size: 11px; color: var(--text-tertiary); font-weight: 400; }
.bask__in { width: 104px; min-height: 34px; padding: 4px 10px; text-align: right;
            font-variant-numeric: tabular-nums; font-weight: 600; }
.bask__x { width: 28px; height: 28px; flex: none; background: none;
           border: 1px solid var(--border); border-radius: var(--radius-sm);
           color: var(--text-tertiary); cursor: pointer; font-size: 15px; }
.bask__empty { font-size: var(--text-xs); color: var(--text-tertiary);
               padding: 10px 2px; }
.bask__chips { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
               gap: 5px; }
.chipg { display: flex; align-items: center; gap: 6px; padding: 6px 8px;
         background: var(--surface); border: 1px solid var(--border);
         border-radius: var(--radius-sm); color: var(--text); cursor: pointer;
         font: inherit; text-align: left; min-width: 0; }
@media (hover: hover) { .chipg:hover:not(:disabled) { border-color: var(--border-strong); } }
.chipg.is-none { opacity: .45; cursor: default; }
.chipg__n { flex: 1 1 auto; min-width: 0; font-size: var(--text-xs); font-weight: 500;
            overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chipg__h { font-size: 11px; color: var(--text-tertiary);
            font-variant-numeric: tabular-nums; }
.bal { display: flex; flex-direction: column; gap: 6px; }
.bal__bar { display: flex; height: 8px; border-radius: 4px; overflow: hidden;
            background: var(--bg-sunken); }
.bal__give { background: var(--text); transition: width var(--duration-fast) var(--ease); }
.bal__want { background: var(--accent); transition: width var(--duration-fast) var(--ease); }
.bal__w { font-size: var(--text-xs); color: var(--text-secondary); }
.bal__w.is-hard { color: var(--danger); }
.offer__more { display: flex; gap: var(--space-3); align-items: center; flex-wrap: wrap; }
.offer__more .field { flex: 1 1 220px; }
.stepper { display: flex; align-items: center; gap: 6px; }
.stepper__k { font-size: var(--text-xs); color: var(--text-secondary); }
.stepper__b { width: 30px; height: 30px; background: var(--surface);
              border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
              color: var(--text); cursor: pointer; font-size: 15px; }
.stepper__v { min-width: 22px; text-align: center; font-weight: 600;
              font-variant-numeric: tabular-nums; }
@media (max-width: 620px) {
  .offer__sides { grid-template-columns: 1fr; }
}

/* ---- war: the attack sheet and the siege, as both sides see it ----------- */
.btn--danger-fill { background: var(--danger); border-color: var(--danger);
                    color: var(--n-00); font-weight: 600; }
@media (hover: hover) { .btn--danger-fill:hover:not(:disabled) { background: color-mix(in srgb, var(--danger) 88%, black); } }
.btn--primary.btn--danger-fill { background: var(--danger); border-color: var(--danger); }
.whochip--crime .whochip__s { color: var(--danger); opacity: 1; }
.whochip--crime[aria-pressed="true"] { background: var(--danger); border-color: var(--danger); }
.whochip--crime[aria-pressed="true"] .whochip__s { color: var(--n-00); opacity: .8; }
.atk__raise { flex-wrap: wrap; }
.atk__n { width: 84px; min-height: 30px; padding: 2px 8px; text-align: center;
          font-weight: 600; font-variant-numeric: tabular-nums; }
.atk__odds { display: flex; flex-direction: column; gap: 6px; }

.siege { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px;
         margin-top: 8px; background: var(--surface);
         border: 1px solid color-mix(in srgb, var(--danger) 35%, var(--border));
         border-radius: var(--radius-md); }
.siege--def { background: color-mix(in srgb, var(--danger) 5%, var(--surface)); }
.siege__h { display: flex; align-items: baseline; gap: 10px; }
.siege__t { flex: 1 1 auto; min-width: 0; font-weight: 600; font-size: var(--text-sm); }
.siege__p { font-size: var(--text-xs); color: var(--danger); font-weight: 600;
            font-variant-numeric: tabular-nums; white-space: nowrap; }
.siege__m { height: 6px; border-radius: 3px; background: var(--bg-sunken); overflow: hidden; }
.siege__f { height: 100%; background: var(--danger);
            transition: width var(--duration-fast) var(--ease); }
.siege__o { display: flex; align-items: center; gap: 8px; padding: 8px 10px;
            background: var(--bg-subtle); border: 1px solid var(--border);
            border-radius: var(--radius-sm); }
.siege__ow { flex: 1 1 auto; min-width: 0; font-size: var(--text-sm); }
.siege .inline { flex-wrap: wrap; }

/* ======================================================= THE ROOM KIT
 * One set of parts for every room: a section header, stat tiles, rows with a
 * meter, compact buttons, banners, chips. Figures are figures, proportions are
 * bars, and nothing inside a row ever wraps onto a second line. */
.k { display: flex; flex-direction: column; gap: 20px; }
.k-sec { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.k-h { display: flex; align-items: center; gap: 8px; min-height: 26px; }
.k-h__t { font-size: 11px; letter-spacing: .07em; text-transform: uppercase;
          color: var(--text-tertiary); font-weight: 600; white-space: nowrap; }
.k-h__line { flex: 1 1 auto; height: 1px; background: var(--border); min-width: 12px; }
.k-h__c { font-size: 11.5px; color: var(--text-tertiary); white-space: nowrap;
          font-variant-numeric: tabular-nums; }

.k-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(126px, 1fr)); gap: 8px; }
.k-tile { --tone: var(--border-strong); min-width: 0; padding: 10px 12px 11px;
          background: var(--surface); border: 1px solid var(--border);
          border-top: 2px solid var(--tone); border-radius: 10px;
          display: flex; flex-direction: column; gap: 2px; }
.k-tile__k { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
             color: var(--text-tertiary); font-weight: 600; white-space: nowrap; }
.k-tile__v { display: flex; align-items: baseline; gap: 6px; font-size: 21px; font-weight: 600;
             line-height: 1.15; font-variant-numeric: tabular-nums; white-space: nowrap; }
.k-tile__d { font-size: 12px; font-weight: 600; color: var(--tone); }
.k-tile__s { font-size: 11.5px; color: var(--text-secondary); white-space: nowrap;
             overflow: hidden; text-overflow: ellipsis; }
.k-tile .k-bar { margin-top: 5px; }

.is-good { --tone: var(--success); }
.is-bad  { --tone: var(--danger); }
.is-warn { --tone: var(--warning); }

.k-bar { --tone: var(--text); height: 5px; background: var(--bg-sunken);
         border-radius: 3px; overflow: hidden; }
.k-bar.is-good { --tone: var(--success); } .k-bar.is-bad { --tone: var(--danger); }
.k-bar.is-warn { --tone: var(--warning); }
.k-bar__f { height: 100%; background: var(--tone); border-radius: 3px;
            transition: width var(--duration-enter) var(--ease); }

.k-list { display: flex; flex-direction: column; gap: 5px; }
.k-row { display: flex; align-items: center; gap: 10px; width: 100%; min-width: 0;
         box-sizing: border-box; padding: 9px 11px; background: var(--surface);
         border: 1px solid var(--border); border-radius: 9px; color: var(--text);
         font: inherit; text-align: left; }
button.k-row { cursor: pointer; transition: border-color var(--duration-fast) var(--ease); }
@media (hover: hover) { button.k-row:hover { border-color: var(--border-strong); } }
.k-row__lead { width: 5px; align-self: stretch; min-height: 26px; border-radius: 3px; flex: none; }
.k-row canvas { flex: none; }
.k-row__main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.k-row__t, .k-row__s { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.k-row__t { font-size: 13.5px; font-weight: 600; }
.k-row__s { font-size: 11.5px; color: var(--text-tertiary); }
.k-row__bar { margin-top: 5px; max-width: 220px; }
.k-row__v { flex: none; display: flex; flex-direction: column; align-items: flex-end; }
.k-row__vv { font-size: 14px; font-weight: 600; white-space: nowrap;
             font-variant-numeric: tabular-nums; color: var(--text); }
.k-row.is-good .k-row__vv { color: var(--success); }
.k-row.is-bad .k-row__vv { color: var(--danger); }
.k-row.is-warn .k-row__vv { color: var(--warning); }
.k-row__vs { font-size: 11px; color: var(--text-tertiary); white-space: nowrap; }
.k-row__acts { flex: none; display: flex; gap: 5px; }

.k-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px;
         min-height: 30px; padding: 0 12px; border-radius: 8px; white-space: nowrap;
         border: 1px solid var(--border-strong); background: var(--surface);
         color: var(--text); font: inherit; font-size: 12.5px; font-weight: 600;
         cursor: pointer; transition: background var(--duration-fast) var(--ease); }
@media (hover: hover) { .k-btn:hover:not(:disabled) { background: var(--surface-hover); } }
.k-btn:active:not(:disabled) { transform: scale(var(--press-scale)); }
.k-btn:disabled { opacity: .45; cursor: default; }
.k-btn--primary { background: var(--text); border-color: var(--text); color: var(--surface); }
@media (hover: hover) { .k-btn--primary:hover:not(:disabled) { background: var(--n-90); } }
.k-btn--danger { color: var(--danger); }
.k-btn--fill { background: var(--danger); border-color: var(--danger); color: var(--n-00); }
@media (hover: hover) { .k-btn--fill:hover:not(:disabled) { background: color-mix(in srgb, var(--danger) 88%, black); } }
.k-btn--ghost { border-color: transparent; background: none; color: var(--text-secondary); }
.k-btn--wide { width: 100%; min-height: 38px; font-size: 13.5px; }
.k-btn--icon { width: 30px; padding: 0; }
.k-acts { display: flex; flex-wrap: wrap; gap: 6px; }
.k-acts--grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* A long label wraps onto a second line rather than being cut in half: a
   button that says "…ise an army to meet th" says nothing. */
.k-acts--grid .k-btn { width: 100%; min-width: 0; white-space: normal; overflow-wrap: anywhere;
                       line-height: 1.2; padding-top: 7px; padding-bottom: 7px; }

.k-banner { --tone: var(--border-strong); display: flex; align-items: center; gap: 12px;
            padding: 10px 12px; border-radius: 10px; background: var(--surface);
            border: 1px solid color-mix(in srgb, var(--tone) 35%, var(--border));
            border-left: 3px solid var(--tone); }
.k-banner.is-bad { background: color-mix(in srgb, var(--danger) 5%, var(--surface)); }
.k-banner__m { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.k-banner__top { display: flex; align-items: baseline; gap: 8px; }
.k-banner__t { flex: 1 1 auto; min-width: 0; font-size: 13.5px; font-weight: 600;
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.k-banner__r { flex: none; font-size: 13px; font-weight: 600; color: var(--tone);
               font-variant-numeric: tabular-nums; }
.k-banner__s { font-size: 12px; color: var(--text-secondary); line-height: 1.35;
               display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
               overflow: hidden; }
.k-banner__s--full { display: block; -webkit-line-clamp: none; overflow: visible; }
.k-banner .k-acts { flex: none; flex-wrap: nowrap; }

.k-seg { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 2px;
         background: var(--surface); border: 1px solid var(--border); border-radius: 8px; }
.k-seg button { padding: 5px 10px; background: none; border: 0; border-radius: 6px;
                color: var(--text-secondary); font: inherit; font-size: 12px;
                font-weight: 600; cursor: pointer; white-space: nowrap; }
.k-seg button[aria-pressed="true"] { background: var(--text); color: var(--surface); }
.k-seg button.is-off { opacity: .4; cursor: not-allowed; text-decoration: line-through; }
/* A letter still on the road: said, but not yet read by anybody. */
.hall__line.is-riding .hall__body { opacity: .62; font-style: italic; }
.hall__line.is-riding .hall__ts { color: var(--warning); }

.k-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.k-chip { padding: 4px 10px; background: var(--surface); border: 1px solid var(--border);
          border-radius: 999px; color: var(--text-secondary); font: inherit;
          font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.k-chip[aria-pressed="true"] { background: var(--text); border-color: var(--text); color: var(--surface); }
.k-chip.is-crime { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 35%, var(--border)); }
.k-chip.is-crime[aria-pressed="true"] { background: var(--danger); border-color: var(--danger); color: var(--n-00); }
span.k-chip { cursor: default; }

.k-more { width: 100%; padding: 6px; background: none; border: 1px dashed var(--border-strong);
          border-radius: 8px; color: var(--text-secondary); font: inherit; font-size: 12px;
          font-weight: 600; cursor: pointer; }
.k-empty { display: flex; flex-direction: column; align-items: center; gap: 8px;
           padding: 14px; border: 1px dashed var(--border-strong); border-radius: 10px;
           font-size: 12.5px; color: var(--text-tertiary); text-align: center; }

.k-split { display: flex; gap: 2px; height: 10px; border-radius: 5px; overflow: hidden;
           background: var(--bg-sunken); }
.k-split__p { flex-basis: 0; min-width: 3px; }

.k-kv { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
        gap: 1px; background: var(--border); border: 1px solid var(--border);
        border-radius: 9px; overflow: hidden; }
.k-kv__i { --tone: var(--text); background: var(--surface); padding: 8px 10px; min-width: 0; }
.k-kv__k { font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase;
           color: var(--text-tertiary); white-space: nowrap; }
.k-kv__v { font-size: 14.5px; font-weight: 600; color: var(--tone); white-space: nowrap;
           overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }

.k-card { display: flex; flex-direction: column; gap: 9px; padding: 12px;
          background: var(--surface); border: 1px solid var(--border); border-radius: 11px; }
.k-card__top { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.k-card__n { flex: 1 1 auto; min-width: 0; font-size: 15px; font-weight: 600;
             white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.k-card__big { font-size: 17px; font-weight: 600; font-variant-numeric: tabular-nums; }
.k-card__s { font-size: 12px; color: var(--text-secondary); white-space: nowrap;
             overflow: hidden; text-overflow: ellipsis; }
.k-meters { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.k-meter__k { display: flex; justify-content: space-between; font-size: 10.5px;
              color: var(--text-tertiary); margin-bottom: 3px; white-space: nowrap; }
.k-toll { display: flex; align-items: center; gap: 10px; }
.k-toll input { flex: 1 1 auto; min-width: 0; accent-color: var(--text); }
.k-toll__v { font-weight: 600; font-variant-numeric: tabular-nums; min-width: 38px; text-align: right; }
.k-foot { display: flex; justify-content: flex-end; }
.k-mkts { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 10px; }
.k-mkt { gap: 7px; }
.k-mkt .k-row { padding: 6px 8px; }
.k-mkt__chg { font-size: 12px; font-weight: 600; color: var(--tone); }
.k-mkt__chart { margin: 2px 0; }
.k-tile--btn { font: inherit; text-align: left; cursor: pointer; color: var(--text); }
@media (hover: hover) { .k-tile--btn:hover { border-color: var(--border-strong); } }
.k-card.tech { gap: 6px; }
.tech__e { font-size: 12.5px; color: var(--text-secondary); line-height: 1.35; }
.tech__c { flex: 1 1 auto; }
.k-card.siege--def { background: color-mix(in srgb, var(--danger) 5%, var(--surface));
                     border-color: color-mix(in srgb, var(--danger) 30%, var(--border)); }
.siege__p { flex: none; font-size: 12.5px; font-weight: 600; color: var(--danger);
            font-variant-numeric: tabular-nums; white-space: nowrap; }
.card__body .k { gap: 14px; padding-top: 2px; }
.card__body .k-kv { grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)); }
.card__body .k-row { padding: 7px 9px; }
.k-amt { display: flex; flex-direction: column; gap: 8px; }
.k-amt__top { display: flex; align-items: center; gap: 10px; }
.k-amt__k { flex: 1 1 auto; font-size: 13px; color: var(--text-secondary); }
.k-amt__n { width: 120px; flex: none; min-height: 38px; font-size: 16px; font-weight: 600; }
.k-amt__u { flex: none; font-size: 12.5px; color: var(--text-tertiary); min-width: 40px; }
.k-amt__r { width: 100%; accent-color: var(--text); }
.sheet .k { gap: 14px; }
.k-steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 8px; }
.k-step { display: flex; gap: 10px; padding: 10px 12px; background: var(--surface);
          border: 1px solid var(--border); border-radius: 10px; }
.k-step__n { flex: none; width: 22px; height: 22px; border-radius: 50%; background: var(--text);
             color: var(--surface); font-size: 12px; font-weight: 600;
             display: flex; align-items: center; justify-content: center; }
.k-step__k { font-size: 13px; font-weight: 600; }
.k-step__s { font-size: 11.5px; color: var(--text-secondary); line-height: 1.35; margin-top: 2px; }
.k-card--go { cursor: pointer; transition: border-color var(--duration-fast) var(--ease); }
@media (hover: hover) { .k-card--go:hover { border-color: var(--border-strong); } }

/* ---- the market: board | chart and tape | ticket ------------------------- */
.room.room--wide { width: min(1260px, 100%); }
.mk { display: grid; grid-template-columns: minmax(250px, 290px) minmax(0, 1fr) minmax(270px, 320px);
      gap: var(--space-4); align-items: start; }
@media (max-width: 1180px) { .mk { grid-template-columns: minmax(0, 1fr) minmax(270px, 320px); }
                             .mk-board { grid-column: 1 / -1; } }
@media (max-width: 760px) { .mk { grid-template-columns: minmax(0, 1fr); } }

.mk-board { display: flex; flex-direction: column; background: var(--surface);
            border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; }
.mk-cols, .mk-row { display: grid; grid-template-columns: minmax(0, 1fr) 62px 56px 58px;
                    gap: 6px; align-items: center; padding: 7px 10px; }
.mk-cols { font-size: var(--text-xs); color: var(--text-tertiary); letter-spacing: var(--tracking-caps);
           text-transform: uppercase; border-bottom: 1px solid var(--border); }
.mk-cols span:not(:first-child) { text-align: right; }
.mk-row { background: none; border: 0; border-bottom: 1px solid var(--border); text-align: left;
          cursor: pointer; font-size: var(--text-sm); }
.mk-row:last-child { border-bottom: 0; }
.mk-row.is-on { background: var(--bg-subtle); box-shadow: inset 2px 0 0 var(--text); }
@media (hover: hover) { .mk-row:hover:not(.is-on) { background: var(--surface-hover); } }
.mk-row__n { display: flex; align-items: center; gap: 7px; min-width: 0; font-weight: 500;
             overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mk-row__p, .mk-row__c { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--font-mono);
                         font-size: 12.5px; }
.mk-spark { display: flex; justify-content: flex-end; }
.is-good.mk-row__c, .mk-price__c.is-good, .mk-q__v.is-good, .mk-tape__d.is-good { color: var(--success); }
.is-bad.mk-row__c, .mk-price__c.is-bad, .mk-q__v.is-bad, .mk-tape__d.is-bad { color: var(--danger); }

.mk-mid { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.mk-top { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.mk-price { display: flex; flex-direction: column; gap: 2px; }
.mk-price__l { font-size: var(--text-xs); color: var(--text-tertiary); }
.mk-price__row { display: flex; align-items: baseline; gap: var(--space-3); }
.mk-price__v { font-size: var(--text-xl); font-weight: 600; letter-spacing: var(--tracking-display);
               font-variant-numeric: tabular-nums; line-height: 1.1; }
.mk-price__c { font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
.mk-card { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3); }
.mk-hilo { display: flex; gap: var(--space-4); flex-wrap: wrap; font-size: var(--text-xs);
           color: var(--text-tertiary); font-variant-numeric: tabular-nums; }
.mk-chart { display: flex; flex-direction: column; gap: 4px; }
.mk-svg { display: block; width: 100%; height: 220px; }
.mk-vol { display: block; width: 100%; height: 46px; }
.mk-chart--none { min-height: 120px; display: grid; place-items: center; }
.mk-tape { display: flex; flex-direction: column; gap: 2px; }
.mk-tape__r { display: grid; grid-template-columns: 76px minmax(0, 1fr) 70px 16px; gap: 8px;
              align-items: center; padding: 4px 2px; font-size: var(--text-sm);
              border-bottom: 1px solid var(--border); font-variant-numeric: tabular-nums; }
.mk-tape__r.is-mine { font-weight: 600; }
.mk-tape__a { color: var(--text-tertiary); font-size: var(--text-xs); }
.mk-tape__p { text-align: right; font-family: var(--font-mono); font-size: 12.5px; }
.mk-tape__d { font-size: 10px; text-align: center; }

.mk-ticket { display: flex; flex-direction: column; gap: var(--space-3); }
.mk-side { display: grid; grid-template-columns: 1fr 1fr; }
.mk-side button { padding: 9px 10px; font-size: var(--text-base); font-weight: 600; }
.mk-form { display: flex; flex-direction: column; gap: 6px; }
.mk-lbl { font-size: var(--text-xs); color: var(--text-tertiary); }
.mk-qty { font-size: var(--text-lg); padding: 8px 12px; height: auto; width: 100%; }
.mk-quote { display: flex; flex-direction: column; gap: 5px; padding: var(--space-3); }
.mk-q { display: flex; justify-content: space-between; gap: var(--space-3); font-size: var(--text-sm); }
.mk-q__k { color: var(--text-secondary); }
.mk-q__v { font-family: var(--font-mono); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.mk-q--total { border-top: 1px solid var(--border); padding-top: 7px; margin-top: 2px; font-weight: 600; }
.mk-q--total .mk-q__v { font-size: var(--text-base); }
.mk-why { padding: 11px 12px; border-radius: var(--radius-md); background: var(--bg-subtle);
          color: var(--text-secondary); font-size: var(--text-sm); text-align: center; }
/* Under the trade button: what the delivery costs in time and in goods. It
   sits tight to the button because it is part of the same decision. */
.mk-haul { margin-top: -2px; text-align: center; line-height: 1.45; }
.k-btn.mk-go { min-height: 48px; font-size: var(--text-base); }
.k-btn.mk-go--buy { background: var(--success); border-color: var(--success); }
.k-btn.mk-go--sell { background: var(--danger); border-color: var(--danger); }
.mk-hold { display: flex; flex-direction: column; }
.mk-hold__r { display: grid; grid-template-columns: minmax(0, 1fr) 70px 70px; gap: 8px; align-items: center;
              padding: 5px 2px; background: none; border: 0; border-bottom: 1px solid var(--border);
              text-align: left; font-size: var(--text-sm); cursor: pointer; font-variant-numeric: tabular-nums; }
.mk-hold__salt { cursor: default; font-weight: 600; border-bottom: 0; }
.mk-hold__q { text-align: right; color: var(--text-tertiary); }
.mk-hold__v { text-align: right; font-family: var(--font-mono); font-size: 12.5px; }
.k-link { background: none; border: 0; padding: 0; color: var(--text); text-decoration: underline;
          text-underline-offset: 2px; cursor: pointer; font: inherit; }

/* ---- a button that is working ------------------------------------------- */
.is-busy { position: relative; color: transparent !important; pointer-events: none; }
.is-busy::after { content: ""; position: absolute; inset: 0; margin: auto; width: 14px; height: 14px;
  border-radius: 50%; border: 2px solid var(--text-tertiary); border-top-color: transparent;
  animation: busyspin 700ms linear infinite; }
.k-btn--primary.is-busy::after, .mk-go.is-busy::after { border-color: var(--surface); border-top-color: transparent; }
@keyframes busyspin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .is-busy::after { animation-duration: 2s; } }

/* ---- tone that survives the cascade --------------------------------------
 * .k-banner and .k-kv__i set their own neutral --tone AFTER .is-good/.is-bad/
 * .is-warn, at the same weight, so a red alert or a failing garrison figure
 * came out grey. The pair beats either alone, as .k-bar.is-* already did. */
.k-banner.is-good, .k-kv__i.is-good { --tone: var(--success); }
.k-banner.is-bad,  .k-kv__i.is-bad  { --tone: var(--danger); }
.k-banner.is-warn, .k-kv__i.is-warn { --tone: var(--warning); }
/* The red borders .k-card's plain border was overriding. */
.k-card.tech--banned { border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); }
.k-card.siege:not(.siege--def) { border-color: color-mix(in srgb, var(--danger) 35%, var(--border)); }

/* ---- a dialog never taller than the screen --------------------------------
 * The sheet had no height limit above 620px wide, and the veil centres it, so
 * a tall dialog on a laptop lost its top and its button off the screen. */
.sheet { max-height: calc(100vh - 2 * var(--space-4)); max-height: calc(100dvh - 2 * var(--space-4));
         overflow-y: auto; overscroll-behavior: contain; }
@media (max-width: 620px) { .sheet { max-height: 92vh; max-height: 92dvh; } }

/* ---- the siege card and the battle report (plan I9, C11) -----------------
 * The way in is a choice the attacker makes on the card, so it sits on its
 * own row like the army settings do. The report is a timeline: one line a
 * tick, each side's weight as a bar and what it lost beside it. */
.siege__way { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
              padding: 6px 0 2px; }
.siege__way-k { flex: none; font-size: var(--text-xs); color: var(--text-tertiary);
                text-transform: uppercase; letter-spacing: .04em; min-width: 54px; }
.siege .note { margin: 0; }

.btl { display: grid; grid-template-columns: 34px 1fr; gap: 4px 10px;
       padding: 6px 0; border-top: 1px solid var(--border); align-items: start; }
.btl:first-of-type { border-top: 0; }
.btl__t { font-variant-numeric: tabular-nums; font-size: var(--text-xs);
          color: var(--text-tertiary); padding-top: 2px; }
.btl__s { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.btl__one { display: grid; grid-template-columns: minmax(0, 7.5em) 1fr 3.4em 3.4em;
            gap: 8px; align-items: center; }
.btl__n { font-size: var(--text-xs); color: var(--text-secondary); overflow: hidden;
          text-overflow: ellipsis; white-space: nowrap; }
.btl__bar { height: 6px; border-radius: 3px; background: var(--bg-sunken); overflow: hidden; }
.btl__fill { height: 100%; background: var(--danger); border-radius: 3px; }
.btl__fill.is-mine { background: var(--accent); }
.btl__v { font-size: var(--text-xs); font-variant-numeric: tabular-nums;
          color: var(--danger); text-align: right; }
.btl__l { font-size: var(--text-xs); font-variant-numeric: tabular-nums;
          color: var(--text-tertiary); text-align: right; }
.btl__w { grid-column: 2; font-size: var(--text-xs); color: var(--text-tertiary); }
@media (max-width: 620px) {
  .btl__one { grid-template-columns: minmax(0, 6em) 1fr 3em; }
  .btl__l { display: none; }
}
