/* All Out of Space — app shell and the Neocom rail.
 *
 * Dark only, deliberately. This is a space game and EVE has no light mode, so
 * there is no prefers-color-scheme: light block; `color-scheme: dark` below
 * makes scrollbars and form controls follow suit.
 *
 * No webfonts. The CSP Caddy sends for this origin is `font-src 'self' data:`
 * with no font CDN in `style-src`, so a Google Fonts <link> would be blocked
 * outright. The stack reaches for whatever condensed technical face the OS
 * already has — EVE's own Shentox is condensed — before falling back.
 */

:root {
  color-scheme: dark;

  /* Cool desaturated blue-blacks, one pale cyan accent, amber for anything
     asking for attention. Lifted from EVE's palette, not its assets. */
  --void: #05080c;
  --rail-top: #0c131a;
  --rail-bottom: #080d12;
  --panel: #0e161f;

  --line: rgba(150, 196, 224, 0.13);
  --line-strong: rgba(150, 196, 224, 0.28);

  --ink: #c3d3df;
  --ink-bright: #eaf4fb;
  --ink-dim: #76899a;

  /* The accent is one color, set twice: as a color and as channels, so
     tints can be made from it with rgba(). "Accent color" in Settings (any
     color, on the wheel) swaps both, inline on <html> (main.js); everything
     else derives. */
  --accent: #4fb6d9;
  --accent-rgb: 79, 182, 217;
  --accent-wash: rgba(var(--accent-rgb), 0.1);
  --accent-glow: rgba(var(--accent-rgb), 0.5);
  --amber: #e0a83c;
  /* Zoning miners (2026-10-21): the green of the zone's grid. */
  --zone: #5fd17a;
  --zone-rgb: 95, 209, 122;
  --danger: #d2563f;
  /* Caution tape: Developer Alerts and their copies in Achievements. */
  --tape-y: #f2c230;
  --tape-k: #16140f;

  /* Star tiers. Read by starmap.js through getComputedStyle, so these are the
     single source of truth for the map's colours as well as the legend's.
     Tier 1 is 80% of every screen, so it is deliberately the quietest; tier 3
     is the one worth spotting, so it gets the brightest, coolest value. */
  --t1: #8fa9bd;
  --t2: #e0a83c;
  --t3: #7ee0ff;
  /* Tier 4 resources and what is made from them (2026-10-16). */
  --t4: #d79bff;

  /* Unresolved starlight in the baked galaxy layer, as raw channels because
     galaxyfield.js writes them into an ImageData buffer and interpolates
     between them. Arms are blue-white, cores cream — a galaxy's core is not
     a brighter version of its arms, and colouring it as one is most of why a
     density field ends up looking like fog. These two are the home galaxy's
     family (galaxyfield.js, makePalettes); the others are relative to it. */
  --field-arm: 153, 189, 255;
  --field-core: 255, 219, 168;
  /* The faint glow along cosmic filaments, seen only past the zoom where
     individual galaxies stop being drawable. Deliberately dim — a deep field
     is black with things in it, not a lit background. */
  --web-glow: 92, 118, 184;

  --rail-w: 52px;
  --rail-w-open: 214px;
  --row-h: 42px;

  --font: "Saira Condensed", "Roboto Condensed", "Barlow Condensed",
    "Segoe UI", system-ui, -apple-system, sans-serif;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

* { box-sizing: border-box; }

/* Scrollbars, the game's own: a slim bar on a faint rail that lights up in
 * the accent color under the pointer, square like every other edge here.
 * Chromium and Safari draw these from ::-webkit-scrollbar. Firefox only
 * knows the standard properties, and Chromium ignores the pseudo-elements
 * wherever those are set, so they go to Firefox alone. */
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: rgba(150, 196, 224, 0.04); }
::-webkit-scrollbar-thumb {
  background-color: rgba(150, 196, 224, 0.26);
  background-clip: padding-box;
  border: 3px solid transparent;
  min-height: 28px;
}
::-webkit-scrollbar-thumb:hover { background-color: rgba(var(--accent-rgb), 0.7); border-width: 2px; }
::-webkit-scrollbar-thumb:active { background-color: var(--accent); border-width: 2px; }
::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-button { display: none; }

@supports not selector(::-webkit-scrollbar) {
  * { scrollbar-width: thin; scrollbar-color: rgba(150, 196, 224, 0.3) rgba(150, 196, 224, 0.04); }
}

html, body {
  height: 100%;
  margin: 0;
}

body {
  display: flex;
  overflow: hidden; /* app shell: panes scroll, the page never does */
  background: var(--void);
  color: var(--ink);
  font-family: var(--font);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
}

/* ---------------------------------------------------------------- Neocom --
 *
 * EVE's rail: pilot portrait on top, window launchers below in themed groups,
 * clock at the bottom. Icons alone are not self-explanatory, so each row gets
 * a flyout label on hover and on keyboard focus. The rail can also be pinned
 * open to show those labels inline.
 */

#neocom-root {
  flex: 0 0 auto;
  display: flex;
}

.neocom {
  position: relative;
  z-index: 10;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  width: calc(var(--rail-w) + env(safe-area-inset-left, 0px));
  height: 100%;
  padding-left: env(safe-area-inset-left, 0px);
  background: linear-gradient(180deg, var(--rail-top), var(--rail-bottom));
  border-right: 1px solid var(--line);
  /* The hairline of light down the inner edge is most of what makes EVE's
     chrome read as a lit panel rather than a flat block. */
  box-shadow:
    inset -1px 0 0 rgba(150, 196, 224, 0.05),
    2px 0 18px rgba(0, 0, 0, 0.55);
  transition: width 0.18s var(--ease);
}

.neocom.is-open { width: calc(var(--rail-w-open) + env(safe-area-inset-left, 0px)); }

/* Brand cap. The chamfered corner is EVE's signature panel cut. */
.neocom-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 46px;
  padding: 0 12px;
  color: var(--accent);
  border-bottom: 1px solid var(--line);
  background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.08), transparent 70%);
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 9px), calc(100% - 9px) 100%, 0 100%);
  flex: 0 0 auto;
}

.neocom-brand svg { flex: 0 0 auto; filter: drop-shadow(0 0 6px var(--accent-glow)); }

/* Pilot. EVE puts the character portrait at the very top of the rail and
   treats it as the way into everything account-shaped. */
.neocom-pilot {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 58px;
  padding: 0 10px;
  flex: 0 0 auto;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.neocom-portrait {
  position: relative;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  color: var(--ink-dim);
  background: radial-gradient(circle at 50% 35%, #1b2a36, #0b1218);
  box-shadow: 0 0 0 1px var(--line-strong), inset 0 0 10px rgba(0, 0, 0, 0.6);
  transition: box-shadow 0.15s var(--ease), color 0.15s var(--ease);
}

.neocom-pilot:hover .neocom-portrait,
.neocom-pilot:focus-visible .neocom-portrait {
  color: var(--ink-bright);
  box-shadow: 0 0 0 1px var(--accent), 0 0 12px -2px var(--accent-glow);
}

.neocom-pilot-meta { min-width: 0; line-height: 1.25; }

/* Developer accounts: the Settings line that stands in for the hidden email. */
.settings-dev { color: var(--accent); letter-spacing: 0.08em; text-transform: uppercase; font-size: 12px; }

/* Developer accounts wear a tag under the handle (hidden for everyone else). */
.neocom-pilot-tag {
  display: inline-block;
  margin-top: 3px;
  padding: 1px 5px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid currentColor;
  border-radius: 3px;
  line-height: 1.3;
}
.neocom-pilot-tag[hidden] { display: none; }

.neocom-pilot-name {
  display: block;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-bright);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.neocom-pilot-sub {
  display: block;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
  white-space: nowrap;
}

/* Launcher groups */
.neocom-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 6px 0;
}

/* The sidebar's list is narrow: a slimmer bar there. */
.neocom-scroll::-webkit-scrollbar { width: 6px; }
.neocom-scroll::-webkit-scrollbar-thumb { border-width: 1px; }

.neocom-group {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Hairline that fades out at both ends, rather than a hard rule. */
.neocom-group + .neocom-group {
  margin-top: 7px;
  padding-top: 7px;
  border-top: 1px solid transparent;
  border-image: linear-gradient(90deg, transparent, var(--line) 25%, var(--line) 75%, transparent) 1;
}

.neocom-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  height: var(--row-h);
  padding: 0 10px;
  border: 0;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.13s var(--ease), color 0.13s var(--ease);
}

/* Left accent bar: hinted on hover, full on an open window. */
.neocom-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 2px;
  height: 0;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent-glow);
  transform: translateY(-50%);
  transition: height 0.15s var(--ease);
}

.neocom-item:hover,
.neocom-item:focus-visible {
  background: var(--accent-wash);
  color: var(--ink-bright);
  outline: none;
}

.neocom-item:hover::before,
.neocom-item:focus-visible::before { height: 40%; }

.neocom-item:focus-visible {
  box-shadow: inset 0 0 0 1px var(--accent);
}

.neocom-item[aria-pressed="true"] {
  color: var(--ink-bright);
  background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.16), rgba(var(--accent-rgb), 0.02));
}

.neocom-item[aria-pressed="true"]::before { height: 100%; }

.neocom-item[aria-pressed="true"] .neocom-icon {
  filter: drop-shadow(0 0 5px var(--accent-glow));
}

.neocom-icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
}

.neocom-text {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 13px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Collapsed, the rail hides every label and the tooltip stands in for them. */
.neocom:not(.is-open) .neocom-text,
.neocom:not(.is-open) .neocom-pilot-meta,
.neocom:not(.is-open) .neocom-clock-label { display: none; }

.neocom:not(.is-open) .neocom-brand,
.neocom:not(.is-open) .neocom-pilot,
.neocom:not(.is-open) .neocom-item { justify-content: center; padding: 0; }

/* Badge. Collapsed it rides the icon's corner; open it sits at the row end. */
.neocom-badge {
  flex: 0 0 auto;
  min-width: 17px;
  padding: 0 4px;
  border-radius: 2px;
  background: var(--amber);
  color: #16100a;
  font-size: 10px;
  font-weight: 700;
  line-height: 15px;
  letter-spacing: 0.02em;
  text-align: center;
}

.neocom-badge[data-tone="alert"] { background: var(--danger); color: #f6e7e3; }
.neocom-badge[hidden] { display: none; }

.neocom:not(.is-open) .neocom-badge {
  position: absolute;
  top: 5px;
  left: 28px;
  box-shadow: 0 0 0 2px var(--rail-top);
}

/* The Support the game window (ui/support.js). */
.support { display: flex; flex-direction: column; gap: 12px; padding: 4px 2px; }
.support-lead { margin: 0; font-size: 14px; line-height: 1.6; color: var(--ink-bright); }
.support-go { align-self: flex-start; }
.support-note { margin: 0; font-size: 13px; color: var(--accent); }

/* Support the game (tips): one row just above the foot's line, its heart warm. */
.neocom-support-slot { flex: 0 0 auto; padding: 4px 0; }
.neocom-support-slot[hidden] { display: none; }
.neocom-support .neocom-icon { color: #e07a86; }
.neocom-support:hover .neocom-icon,
.neocom-support[aria-pressed="true"] .neocom-icon { color: #f2909b; }

/* Footer: UTC clock, as EVE shows at the foot of the rail, plus the pin. */
.neocom-foot {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 8px calc(7px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--line);
}

.neocom-clock {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding-left: 3px;
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  letter-spacing: 0.08em;
  color: var(--ink);
}

.neocom-clock-label {
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.neocom-pin {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  transition: color 0.13s var(--ease), border-color 0.13s var(--ease);
}

.neocom-pin:hover,
.neocom-pin:focus-visible {
  color: var(--ink-bright);
  border-color: var(--line-strong);
  outline: none;
}

.neocom-pin svg { transition: transform 0.18s var(--ease); }
.neocom.is-open .neocom-pin svg { transform: scaleX(-1); }

/* Settings: a cog beside the clock, lit like a launcher while its window is
   open, and turning a little on hover. */
.neocom-cog {
  position: relative;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  transition: color 0.13s var(--ease), border-color 0.13s var(--ease), background 0.13s var(--ease);
}
.neocom-cog svg { transition: transform 0.3s var(--ease); }
.neocom-cog:hover,
.neocom-cog:focus-visible { color: var(--ink-bright); border-color: var(--line-strong); outline: none; }
.neocom-cog:hover svg { transform: rotate(45deg); }
.neocom-cog[aria-pressed="true"] { color: var(--accent); border-color: rgba(var(--accent-rgb), 0.5); background: var(--accent-wash); }
.neocom .neocom-cog .neocom-badge { position: absolute; top: -4px; left: auto; right: -6px; }
.reduce-motion .neocom-cog svg { transition: none; }

.neocom:not(.is-open) .neocom-foot { flex-direction: column; }
.neocom:not(.is-open) .neocom-clock { align-items: center; padding: 0; font-size: 11px; }

/* Flyout label. One element, parked on <body> and positioned with fixed
 * coordinates, because the rail's launcher list scrolls and anything absolute
 * inside it would be clipped at the edge.
 */
.neocom-tip {
  position: fixed;
  z-index: 60;
  padding: 6px 12px 5px;
  background: linear-gradient(180deg, #17242f, #0d161e);
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 0 100%);
  color: var(--ink-bright);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: translateX(-5px);
  transition: opacity 0.12s var(--ease), transform 0.12s var(--ease);
}

.neocom-tip[data-show] { opacity: 1; transform: none; }

/* Avatar. Fills the portrait ring the glyph otherwise sits in. The ring's
 * box-shadow stays on the parent, so a square Google image reads as round. */
.neocom-avatar {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

.neocom.is-signed-in .neocom-portrait { color: var(--accent); }
.neocom.is-signed-in .neocom-pilot-sub {
  text-transform: none;       /* an email address is not a label */
  letter-spacing: 0.02em;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ----------------------------------------------------------- pilot panel --
 *
 * Flies out beside the portrait button, the way EVE's character sheet hangs
 * off its rail. Parked on <body> and positioned in viewport coordinates for
 * the same reason the flyout label is: the rail is a narrow strip and an
 * absolutely positioned child would be clipped by it.
 */

.pilot-panel {
  position: fixed;
  z-index: 70;
  width: min(290px, calc(100vw - 72px));
  background: linear-gradient(180deg, rgba(20, 31, 42, 0.97), rgba(10, 16, 22, 0.97));
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
  box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.8);
  color: var(--ink);
}

.pilot-panel[hidden] { display: none; }

.pilot-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 9px 10px 8px 12px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(90deg, var(--accent-wash), transparent 75%);
}

.pilot-panel-title {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
}

.pilot-panel-close {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
}

.pilot-panel-close:hover,
.pilot-panel-close:focus-visible {
  color: var(--ink-bright);
  border-color: var(--line-strong);
  outline: none;
}

.pilot-panel-body { padding: 14px 14px 16px; }

/* Signed-in identity card */
.pilot-card {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-bottom: 13px;
}

.pilot-card[hidden] { display: none; }

.pilot-card-portrait {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  color: var(--accent);
  background: radial-gradient(circle at 50% 35%, #1b2a36, #0b1218);
  box-shadow: 0 0 0 1px var(--accent), inset 0 0 10px rgba(0, 0, 0, 0.6);
  overflow: hidden;
}

.pilot-card-avatar {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

.pilot-card-meta { min-width: 0; line-height: 1.3; }

.pilot-card-name {
  display: block;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-bright);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The address is the account key, so it is shown verbatim and allowed to
   wrap rather than being ellipsised into something unrecognisable. */
.pilot-card-email {
  display: block;
  font-size: 12px;
  color: var(--ink-dim);
  overflow-wrap: anywhere;
}

.pilot-note {
  margin: 0 0 13px;
  font-size: 12px;
  line-height: 1.55;
  color: var(--ink-dim);
}

.pilot-facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 12px;
  margin: 0 0 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: 11px;
}

.pilot-facts[hidden] { display: none; }

.pilot-facts dt {
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.pilot-facts dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.pilot-signout {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color 0.13s var(--ease), color 0.13s var(--ease),
    background 0.13s var(--ease);
}

.pilot-signout[hidden] { display: none; }

.pilot-signout:hover,
.pilot-signout:focus-visible {
  border-color: var(--danger);
  background: rgba(210, 86, 63, 0.12);
  color: #f0cfc8;
  outline: none;
}

.pilot-error {
  margin: 12px 0 0;
  padding: 8px 10px;
  border-left: 2px solid var(--danger);
  background: rgba(210, 86, 63, 0.1);
  font-size: 12px;
  line-height: 1.5;
  color: #efc9c1;
}

.pilot-error[hidden] { display: none; }

/* ------------------------------------------------------------- star map --
 *
 * The map is the view: a canvas filling the viewport with an overlay on top.
 * The overlay is pointer-transparent so dragging anywhere that is not a
 * control still pans the map; each control turns pointer events back on.
 */

.viewport {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden; /* the map pans; the element never scrolls */
}

.starmap {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--void);
  cursor: grab;
  touch-action: none; /* we handle pan and pinch ourselves */
}

.starmap:active { cursor: grabbing; }
.starmap:focus-visible { outline: 1px solid var(--accent); outline-offset: -1px; }

.map-ui {
  position: absolute;
  inset: 0;
  pointer-events: none;
  padding: 12px;
  padding-left: max(12px, env(safe-area-inset-left, 0px));
  padding-bottom: max(12px, env(safe-area-inset-bottom, 0px));
}

.map-ui > * { pointer-events: auto; }

/* --- search ---------------------------------------------------------- */

.map-search {
  position: absolute;
  top: 12px;
  left: 12px;
  display: flex;
  gap: 0;
  width: min(380px, calc(100% - 24px));
}

.map-search-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 8px 11px;
  border: 1px solid var(--line-strong);
  border-right: 0;
  background: rgba(10, 16, 22, 0.92);
  color: var(--ink-bright);
  font: inherit;
  font-size: 13px;
}

.map-search-input::placeholder { color: var(--ink-dim); }

.map-search-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent-wash);
}

.map-search-go {
  flex: 0 0 auto;
  padding: 8px 14px;
  border: 1px solid var(--line-strong);
  background: linear-gradient(180deg, #16242f, #0d161e);
  color: var(--ink-bright);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}

.map-search-go:hover,
.map-search-go:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
  outline: none;
}

.map-results {
  position: absolute;
  top: 50px;
  left: 12px;
  width: min(380px, calc(100% - 24px));
  max-height: min(46vh, 380px);
  overflow-y: auto;
  background: rgba(10, 16, 22, 0.96);
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
}

.map-results[hidden] { display: none; }

.map-results-note {
  margin: 0;
  padding: 9px 11px;
  font-size: 11px;
  line-height: 1.5;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
  border-bottom: 1px solid var(--line);
}

.map-result {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding: 7px 11px;
  border: 0;
  border-left: 2px solid transparent;
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.map-result:hover,
.map-result:focus-visible {
  background: var(--accent-wash);
  outline: none;
}

.map-result[data-tier="1"] { border-left-color: var(--t1); }
.map-result[data-tier="2"] { border-left-color: var(--t2); }
.map-result[data-tier="3"] { border-left-color: var(--t3); }

.map-result-name { font-size: 13px; color: var(--ink-bright); }

.map-result-meta {
  flex: 0 0 auto;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-dim);
}

/* --- selected system ------------------------------------------------- */

.map-card {
  position: absolute;
  top: calc(12px + var(--switch-gap, 0px));
  right: 12px;
  width: min(272px, calc(100% - 24px));
  padding: 12px 14px 14px;
  /* Opaque, unlike the pilot panel: windows stack, and at any translucency
     the text of the window behind ghosts through the one in front. */
  background: linear-gradient(180deg, #141f2a, #0a1016);
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--line-strong);
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
}

.map-card[hidden] { display: none; }
.map-card[data-tier="1"] { border-left-color: var(--t1); }
.map-card[data-tier="2"] { border-left-color: var(--t2); }
.map-card[data-tier="3"] { border-left-color: var(--t3); }

.map-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.map-card-kicker {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.map-card-close {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.map-card-close:hover,
.map-card-close:focus-visible {
  color: var(--ink-bright);
  border-color: var(--line-strong);
  outline: none;
}

/* The name is the shareable thing, so it is the biggest text in the card and
   is selectable even though the rest of the overlay is not. */
.map-card-name {
  margin: 4px 0 10px;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--ink-bright);
  overflow-wrap: anywhere;
  user-select: text;
}

.map-card-copy {
  width: 100%;
  margin-bottom: 12px;
  padding: 7px 10px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}

.map-card-copy:hover,
.map-card-copy:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
  outline: none;
}

.map-card-facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 5px 12px;
  margin: 0;
  padding-top: 11px;
  border-top: 1px solid var(--line);
  font-size: 11px;
}

.map-card-facts dt {
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.map-card-facts dd {
  margin: 0;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.map-card-desig {
  user-select: text;
  /* The location code is read aloud and typed back in, so it gets a
     monospace face where 0/8 and B/8 are easy to tell apart. */
  font-family: ui-monospace, 'SF Mono', Consolas, 'Liberation Mono', monospace;
  font-size: 1.08em;
  letter-spacing: 0.04em;
  color: var(--ink-bright);
}

/* --- readouts -------------------------------------------------------- */

.map-readout {
  position: absolute;
  right: 12px;
  bottom: 12px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 10px 8px 12px;
  background: rgba(8, 13, 18, 0.82);
  border: 1px solid var(--line);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.map-readout-pos {
  font-variant-numeric: tabular-nums;
  color: var(--ink-bright);
}

.map-readout-band {
  color: var(--accent);
  letter-spacing: 0.16em;
}

.map-readout-fps {
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

/* Turns amber the moment a frame misses the budget, so a regression is
   visible rather than something you have to go measuring. */
.map-readout-fps[data-slow] { color: var(--amber); }

.map-home {
  padding: 4px 9px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}

.map-home:hover,
.map-home:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
  outline: none;
}

/* --- toast ----------------------------------------------------------- */

.map-toast {
  position: absolute;
  z-index: 30; /* over the windows: a toast is often about one of them */
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  margin: 0;
  padding: 8px 14px;
  max-width: calc(100% - 48px);
  background: rgba(14, 22, 31, 0.95);
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--ink-bright);
  pointer-events: none;
  text-align: center;
}

.map-toast[hidden] { display: none; }

/* ------------------------------------------------------------ map closed --
 * The map is opened and closed from its launcher (main.js, setMapOpen). Closed,
 * everything that belongs to it goes: the canvas, its overlay, and the system
 * view that grows out of it. Windows and toasts stay.
 */

.viewport.is-map-closed .starmap,
.viewport.is-map-closed .map-ui,
.viewport.is-map-closed .sysview,
.viewport.is-map-closed .sysview-canvas,
.viewport.is-map-closed .stationview { display: none; }

.map-closed-hint {
  display: none;
  position: absolute;
  inset: 0;
  margin: 0;
  place-items: center;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-dim);
  opacity: 0.55;
  pointer-events: none;
}

.viewport.is-map-closed .map-closed-hint { display: grid; }

/* ---------------------------------------------------------- handle picker --
 * First visit: choose a handle (handlepicker.js). Covers the game area but not
 * the sidebar, so signing out stays reachable.
 */

.picker-overlay {
  position: absolute;
  inset: 0;
  z-index: 40; /* over windows and toasts' layer below the pilot panel */
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(3, 6, 10, 0.82);
  backdrop-filter: blur(2px);
}

.picker {
  display: grid;
  gap: 12px;
  width: min(440px, 100%);
  padding: 22px 24px 20px;
  background: linear-gradient(180deg, #16222e, #0b131b);
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 0 100%);
  box-shadow: 0 24px 60px -16px rgba(0, 0, 0, 0.9);
}

.picker-kicker { margin: 0; font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); }
.picker-title { margin: 0; font-size: 22px; font-weight: 600; color: var(--ink-bright); }
.picker-lede { margin: 0 0 4px; font-size: 14px; line-height: 1.5; color: var(--ink); }

.picker-at {
  display: flex;
  align-items: center;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.6);
  color: var(--ink-dim);
  font-size: 16px;
}

.picker-at:focus-within { border-color: var(--accent); }
.picker-at > span { padding: 0 2px 0 10px; }
.picker-at .win-input { border: 0; background: transparent; padding-left: 2px; font-size: 16px; }
.picker-ok { margin: 0; font-size: 12px; color: #7fd4a4; }
.settings-handle { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 15px; }

/* --------------------------------------------------------------- windows --
 * Floating windows over the map (windows.js): Comms, Alerts, Settings, and
 * whatever comes next. Same skin as the pilot panel — dark glass, a cyan edge,
 * one clipped corner — so everything that floats reads as one family. The
 * layer is click-through; only the windows themselves take the pointer.
 */

.win-layer {
  position: absolute;
  inset: 0;
  z-index: 20; /* over the map UI and the system view, under toasts and the pilot panel */
  pointer-events: none;
}

.win {
  position: absolute;
  display: flex;
  flex-direction: column;
  min-width: 300px;
  min-height: 220px;
  max-width: calc(100% - 16px);
  max-height: calc(100% - 16px);
  background: linear-gradient(180deg, rgba(20, 31, 42, 0.96), rgba(10, 16, 22, 0.96));
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--line-strong);
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
  box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.8);
  color: var(--ink);
  pointer-events: auto;
  overflow: hidden;
  outline: none;
}

/* Resize grips (windows.js): a thin strip along each edge, a square at each
   corner, over the content. Thin enough to leave a body's scrollbar its
   thumb; the bottom-right corner shows two short lines, where the browser's
   own handle used to be. */
.win-grip { position: absolute; z-index: 3; touch-action: none; }
.win-grip.is-n { top: 0; left: 10px; right: 16px; height: 4px; cursor: ns-resize; }
.win-grip.is-s { bottom: 0; left: 10px; right: 14px; height: 5px; cursor: ns-resize; }
.win-grip.is-e { right: 0; top: 16px; bottom: 14px; width: 4px; cursor: ew-resize; }
.win-grip.is-w { left: 0; top: 10px; bottom: 10px; width: 5px; cursor: ew-resize; }
.win-grip.is-nw { top: 0; left: 0; width: 10px; height: 10px; cursor: nwse-resize; }
.win-grip.is-ne { top: 0; right: 0; width: 18px; height: 18px; cursor: nesw-resize; }
.win-grip.is-sw { bottom: 0; left: 0; width: 10px; height: 10px; cursor: nesw-resize; }
.win-grip.is-se {
  bottom: 0;
  right: 0;
  width: 14px;
  height: 14px;
  cursor: nwse-resize;
  background:
    linear-gradient(135deg, transparent 54%, var(--line-strong) 54%, var(--line-strong) 61%, transparent 61%,
      transparent 74%, var(--line-strong) 74%, var(--line-strong) 81%, transparent 81%);
}
.win-grip.is-se:hover,
.win.is-resizing .win-grip.is-se {
  background:
    linear-gradient(135deg, transparent 54%, var(--accent) 54%, var(--accent) 61%, transparent 61%,
      transparent 74%, var(--accent) 74%, var(--accent) 81%, transparent 81%);
}
.win.is-resizing { user-select: none; }

/* A structure the Factory Floor was asked to show (its menu's "Show on the
   Factory Floor"): lit up for a moment. */
@keyframes factory-flash {
  from { box-shadow: inset 0 0 0 1px var(--accent), inset 0 0 0 999px rgba(var(--accent-rgb), 0.18); }
  to { box-shadow: inset 0 0 0 1px transparent, inset 0 0 0 999px transparent; }
}
.factory-row.is-flash { animation: factory-flash 1.8s var(--ease); }

/* A corporation you gave a nickname (ui/corpnames.js): the nickname in its
   look, its real name after it, small and plain whatever the heading does. */
.corp-nick { display: inline-flex; align-items: baseline; gap: 7px; min-width: 0; flex-wrap: wrap; }
.corp-nick-real {
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--ink-dim);
  white-space: nowrap;
}

.win.is-front { border-left-color: var(--accent); }
/* Hidden for a while, still open where it was (windows.js tuck: the
   tutorial's steps on a bay floor). */
.win.is-tucked { visibility: hidden; }

/* "Window size" in Settings. Scaled from the top-left corner so dragging,
   which works in unscaled left/top, still lands where the pointer is. */
.win { transform: scale(var(--win-scale, 1)); transform-origin: 0 0; }

.win-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  padding: 7px 10px 6px 12px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(90deg, var(--accent-wash), transparent 75%);
  cursor: grab;
  touch-action: none; /* the bar is a drag handle, not a scroller */
  user-select: none;
}

.win.is-dragging .win-bar { cursor: grabbing; }

.win-title {
  flex: 1 1 auto;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.win.is-front .win-title { color: var(--accent); }

.win-close {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

.win-close:hover,
.win-close:focus-visible {
  color: var(--ink-bright);
  border-color: var(--line-strong);
  outline: none;
}

.win-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  padding: 12px;
}

/* ---- shared controls */

.win-button {
  padding: 6px 12px;
  border: 1px solid var(--line-strong);
  background: rgba(150, 196, 224, 0.04);
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
}

.win-button:hover:not(:disabled),
.win-button:focus-visible {
  border-color: var(--accent);
  color: var(--ink-bright);
  outline: none;
}

.win-button:disabled { opacity: 0.45; cursor: default; }

.win-button.is-primary {
  border-color: rgba(var(--accent-rgb), 0.55);
  background: var(--accent-wash);
  color: var(--ink-bright);
}

.win-button.is-danger:hover:not(:disabled),
.win-button.is-danger:focus-visible {
  border-color: var(--danger);
  color: #ffd9cf;
}

.win-input {
  width: 100%;
  padding: 7px 9px;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.6);
  color: var(--ink-bright);
  font: inherit;
  font-size: 14px;
}

.win-input:focus { border-color: var(--accent); outline: none; }

textarea.win-input { resize: vertical; line-height: 1.45; }

.win-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.win-field > span,
.settings-label {
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.win-note,
.win-error {
  margin: 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink-dim);
}

.win-error { color: #f0907a; }
.win-error[hidden] { display: none; }

.win-empty {
  display: grid;
  place-items: center;
  align-content: center;
  gap: 12px;
  height: 100%;
  min-height: 140px;
  padding: 16px;
  text-align: center;
}

.win-empty p { margin: 0; max-width: 32ch; color: var(--ink-dim); line-height: 1.5; }

/* ---- Comms (also the frame Alerts uses) */

.comms {
  display: flex;
  flex-direction: column;
  gap: 10px;
  height: 100%;
}

.comms-toolbar,
.comms-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.comms-toolbar[hidden] { display: none; }

.comms-spacer { flex: 1 1 auto; }

.comms-tab {
  padding: 5px 10px;
  border: 1px solid transparent;
  border-bottom-color: var(--line);
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
}

.comms-tab[aria-pressed="true"] { color: var(--ink-bright); border-bottom-color: var(--accent); }
.comms-tab:hover,
.comms-tab:focus-visible { color: var(--ink-bright); outline: none; }

.comms-pane { flex: 1 1 auto; min-height: 0; overflow: auto; }

.comms-list { list-style: none; margin: 0; padding: 0; }
.comms-list li + li { border-top: 1px solid var(--line); }

.comms-row,
.alerts-row {
  display: grid;
  width: 100%;
  padding: 8px 6px 8px 10px;
  border: 0;
  border-left: 2px solid transparent;
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.comms-row {
  grid-template-columns: 1fr auto;
  grid-template-areas: "who when" "subject subject" "snippet snippet";
  row-gap: 2px;
}

.comms-row:hover,
.comms-row:focus-visible,
.alerts-row:hover,
.alerts-row:focus-visible {
  background: rgba(150, 196, 224, 0.05);
  outline: none;
}

.comms-row.is-unread,
.alerts-row.is-unread { border-left-color: var(--accent); }

.comms-who { grid-area: who; color: var(--ink-bright); font-size: 13px; }
.comms-when { grid-area: when; color: var(--ink-dim); font-size: 11px; white-space: nowrap; }
.comms-subject { grid-area: subject; font-size: 14px; }
.comms-snippet {
  grid-area: snippet;
  color: var(--ink-dim);
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.is-unread .comms-subject,
.is-unread .alerts-title { color: var(--ink-bright); font-weight: 600; }

.comms-message { display: flex; flex-direction: column; gap: 8px; }
.comms-message-subject { margin: 6px 0 0; font-size: 17px; font-weight: 600; color: var(--ink-bright); }
.comms-message-meta { margin: 0; font-size: 12px; color: var(--ink-dim); }
.comms-message-body {
  padding-top: 10px;
  border-top: 1px solid var(--line);
  line-height: 1.55;
  white-space: pre-wrap;   /* the pilot's own line breaks, as written */
  overflow-wrap: anywhere; /* and a pasted 300-character token cannot widen the window */
}

.comms-compose {
  display: flex;
  flex-direction: column;
  gap: 10px;
  height: 100%;
}

.win-field.is-grow { flex: 1 1 auto; }
.win-field.is-grow .win-input { flex: 1 1 auto; min-height: 120px; }

.comms-counter { font-size: 11px; color: var(--ink-dim); }

/* ---- Alerts and Patch Notes: two tabs of the Comms window */

.alerts-pane { display: flex; flex-direction: column; gap: 10px; }

/* ---- Alerts list */

.alerts-row {
  grid-template-columns: 22px 1fr auto;
  grid-template-areas: "glyph title when" "glyph text text";
  column-gap: 8px;
  row-gap: 2px;
  align-items: baseline;
}

.alerts-glyph { grid-area: glyph; color: var(--ink-dim); text-align: center; }
.alerts-row.is-unread .alerts-glyph { color: var(--accent); }
.alerts-row[data-kind="device"].is-unread .alerts-glyph { color: var(--amber); }
.alerts-row[data-kind="announcement"].is-unread .alerts-glyph { color: var(--amber); }
.alerts-title { grid-area: title; font-size: 14px; }
.alerts-text { grid-area: text; font-size: 12px; line-height: 1.45; color: var(--ink-dim); }

/* ---- Settings */

.settings { display: flex; flex-direction: column; gap: 16px; }
.settings-section { display: flex; flex-direction: column; gap: 14px; }

.settings-heading {
  margin: 0;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--line);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
}

.settings-item { display: flex; flex-direction: column; gap: 6px; }
.settings-row { display: flex; gap: 8px; flex-wrap: wrap; }
.settings-row .win-input { flex: 1 1 180px; width: auto; }
.settings-value { margin: 0; color: var(--ink-bright); overflow-wrap: anywhere; }

/* ---- Wallet: a bank account screen */

.wallet {
  display: flex;
  flex-direction: column;
  gap: 14px;
  font-variant-numeric: tabular-nums; /* columns of money line up */
}

.wallet-card {
  display: grid;
  gap: 4px;
  padding: 16px 18px 14px;
  --acct: var(--accent);
  --acct-rgb: var(--accent-rgb);
  border: 1px solid rgba(var(--acct-rgb), 0.35);
  background:
    radial-gradient(120% 140% at 100% 0%, rgba(var(--acct-rgb), 0.18), transparent 55%),
    linear-gradient(135deg, #16283a, #0c1620 70%);
  clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 0 100%);
}

.wallet-card-top {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.wallet-bank { color: var(--accent); font-weight: 600; }
.wallet-product { color: var(--ink-dim); }
.wallet-holder { font-size: 15px; color: var(--ink-bright); }

.wallet-label {
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.wallet-card .wallet-label { margin-top: 8px; }

.wallet-balance { display: flex; align-items: baseline; gap: 8px; }
.wallet-balance-value { font-size: 34px; font-weight: 600; line-height: 1.1; color: var(--ink-bright); }
.wallet-unit { font-size: 14px; letter-spacing: 0.12em; color: var(--ink-dim); }

.wallet-card-foot {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  color: var(--ink-dim);
}

.wallet-mono {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  letter-spacing: 0.06em;
  color: var(--ink);
}

.wallet-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

.wallet-stat {
  display: grid;
  gap: 2px;
  padding: 9px 12px;
  border: 1px solid var(--line);
  background: rgba(150, 196, 224, 0.03);
}

.wallet-stat-value { font-size: 17px; }
.is-in { color: #7fd4a4; }
.is-out { color: var(--ink); }

.wallet-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.wallet-history-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
}

.wallet-history-head .settings-heading { border-bottom: 0; padding-bottom: 0; }
.wallet-filters { display: flex; gap: 2px; }

.wallet-table { display: flex; flex-direction: column; }

.wallet-row {
  display: grid;
  grid-template-columns: 62px minmax(0, 1fr) 112px 112px;
  gap: 10px;
  align-items: baseline;
  width: 100%;
  padding: 8px 6px;
  border: 0;
  border-top: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-variant-numeric: tabular-nums;
  text-align: left;
  cursor: pointer;
}

.wallet-row.is-head {
  padding-top: 4px;
  border-top: 0;
  border-bottom: 1px solid var(--line-strong);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
  cursor: default;
}

.wallet-row.is-head + .wallet-line .wallet-row { border-top: 0; }
.wallet-row:not(.is-head):hover,
.wallet-row:not(.is-head):focus-visible { background: rgba(150, 196, 224, 0.05); outline: none; }
.wallet-row[aria-expanded="true"] { background: rgba(150, 196, 224, 0.04); }

.wallet-row .is-num { text-align: right; white-space: nowrap; }
.wallet-date { color: var(--ink-dim); font-size: 12px; white-space: nowrap; }
.wallet-desc { display: grid; min-width: 0; }
.wallet-desc > span:first-child { color: var(--ink-bright); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wallet-memo { font-size: 12px; color: var(--ink-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wallet-running { color: var(--ink-dim); }

.wallet-detail,
.wallet-review {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 16px;
  margin: 0;
  font-size: 13px;
}

.wallet-detail { padding: 4px 6px 12px 78px; }
.wallet-detail[hidden] { display: none; }
.wallet-detail dt,
.wallet-review dt { color: var(--ink-dim); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; align-self: center; }
.wallet-detail dd,
.wallet-review dd { margin: 0; overflow-wrap: anywhere; }

.wallet-more { align-self: center; margin-top: 10px; }
.wallet-none { padding: 14px 6px; }

.wallet-form { display: flex; flex-direction: column; gap: 12px; }

.wallet-amount-input { font-size: 20px; font-variant-numeric: tabular-nums; }

.wallet-review { padding: 12px 14px; border: 1px solid var(--line); background: rgba(150, 196, 224, 0.03); }
.wallet-review-amount { margin: 0; font-size: 22px; font-weight: 600; color: var(--ink-bright); }

.wallet-receipt { display: grid; justify-items: center; gap: 4px; padding: 8px 0 4px; text-align: center; }
.wallet-receipt-mark {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid rgba(127, 212, 164, 0.6);
  border-radius: 50%;
  color: #7fd4a4;
  font-size: 22px;
}
.wallet-receipt-title { margin: 6px 0 0; font-size: 13px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink-dim); }

.wallet-hero {
  display: grid;
  gap: 4px;
  padding: 14px 18px 16px;
  border: 1px solid rgba(var(--accent-rgb), 0.35);
  background:
    radial-gradient(120% 160% at 100% 0%, rgba(var(--accent-rgb), 0.16), transparent 55%),
    linear-gradient(135deg, #16283a, #0c1620 70%);
}

.wallet-hero .wallet-card-top { margin-bottom: 8px; }
.wallet-hero .wallet-product { text-transform: none; letter-spacing: 0.04em; font-size: 13px; color: var(--ink); }

.wallet-badge {
  margin-left: 8px;
  padding: 1px 6px;
  border: 1px solid rgba(var(--accent-rgb), 0.5);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  vertical-align: 2px;
}

.wallet-accounts { list-style: none; margin: -4px 0 0; padding: 0; display: grid; gap: 6px; }

.wallet-account {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  grid-template-areas: "mark name balance" "mark sub balance";
  column-gap: 12px;
  align-items: center;
  width: 100%;
  padding: 11px 14px 11px 10px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--line-strong);
  background: rgba(150, 196, 224, 0.03);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.wallet-account:hover,
.wallet-account:focus-within { border-left-color: var(--accent); background: rgba(150, 196, 224, 0.06); }

/* The account name: a button for the keyboard, styled as plain text. */
.wallet-account-open {
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.wallet-account-open:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }

.wallet-account-mark {
  grid-area: mark;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border: 1px solid rgba(var(--acct-rgb, var(--accent-rgb)), 0.45);
  background: rgba(var(--acct-rgb, var(--accent-rgb)), 0.1);
  color: var(--acct, var(--accent));
  font-size: 15px;
}

/* An account's colour (wallet-style.js) tints its tile's edge too. */
.wallet-account { --acct: var(--accent); --acct-rgb: var(--accent-rgb); }
.wallet-account:hover { border-color: rgba(var(--acct-rgb), 0.5); }
.wallet-account.is-preview { cursor: default; pointer-events: none; }

/* Choosing an account's look (wallet.js, styleForm). Its colors are the
   color wheel (look.js; the "Color wheel everywhere" block at the end). */
.wallet-fonts { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 8px; }
.wallet-font {
  grid-template-columns: 1fr;
  grid-template-areas: "sample" "label" "note";
  row-gap: 2px;
}
.wallet-font-sample {
  grid-area: sample;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 17px;
  color: var(--ink-bright);
}
.wallet-account-name {
  grid-area: name;
  display: flex;
  flex-wrap: wrap; /* the Primary badge drops below the name on a narrow screen */
  align-items: center;
  gap: 2px 8px;
  min-width: 0;
  color: var(--ink-bright);
  font-size: 15px;
}

.wallet-account-name .wallet-badge { margin-left: 0; }
.wallet-account-sub { grid-area: sub; color: var(--ink-dim); font-size: 12px; }
.wallet-account-balance { grid-area: balance; display: grid; justify-items: end; }
.wallet-account-amount { font-size: 17px; color: var(--ink-bright); }
.wallet-account-avail { font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }

.wallet-recent {
  display: grid;
  grid-template-columns: 62px minmax(0, 1fr) auto;
  gap: 10px;
  align-items: baseline;
  width: 100%;
  padding: 8px 6px;
  border: 0;
  border-top: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-variant-numeric: tabular-nums;
  text-align: left;
  cursor: pointer;
}

.wallet-recent:first-child { border-top: 0; }
.wallet-recent:hover,
.wallet-recent:focus-visible { background: rgba(150, 196, 224, 0.05); outline: none; }
.wallet-recent .is-num { text-align: right; white-space: nowrap; }

.wallet-back {
  align-self: flex-start;
  padding: 2px 0;
  border: 0;
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
}

.wallet-back:hover,
.wallet-back:focus-visible { color: var(--ink-bright); outline: none; }

.wallet-manage { display: grid; gap: 6px; }
.wallet-hint { font-size: 12px; color: var(--ink-dim); text-transform: none; letter-spacing: 0; }
/* Beats `.win-field > span`, which would set a hint in small capitals. */
.win-field > .wallet-hint { font-size: 12px; letter-spacing: 0; text-transform: none; }
.win-field[hidden] { display: none; }
.wallet-modes { align-self: flex-start; }

.wallet-types { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }

.wallet-type {
  display: grid;
  grid-template-columns: 34px 1fr;
  grid-template-areas: "mark label" "mark note";
  column-gap: 10px;
  align-items: center;
  padding: 10px;
  border: 1px solid var(--line);
  background: rgba(150, 196, 224, 0.03);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.wallet-type .wallet-account-mark { grid-area: mark; }
.wallet-type-label { grid-area: label; color: var(--ink-bright); }
.wallet-type .wallet-hint { grid-area: note; }
.wallet-type[aria-checked="true"] { border-color: var(--accent); background: var(--accent-wash); }
.wallet-type:focus-visible { outline: 1px solid var(--accent); }

.wallet-group { display: flex; flex-direction: column; gap: 8px; }

.wallet-group-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 6px;
}

.wallet-group-head .settings-heading {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 0;
  border: 0;
}

.wallet-group[data-kind="corporation"] .settings-heading { color: var(--ink-bright); }
.wallet-group-total { font-size: 13px; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.wallet-group .wallet-accounts { margin: 0; }

/* The overview: one tile per group (Personal, each corporation), each with
   its total. Clicking one opens its accounts. */
.wallet-categories { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }

.wallet-category {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto 14px;
  grid-template-areas: "mark name balance go" "mark sub balance go";
  column-gap: 12px;
  row-gap: 1px;
  align-items: center;
  width: 100%;
  padding: 12px 12px 12px 10px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--line-strong);
  background: rgba(150, 196, 224, 0.03);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.wallet-category[data-kind="corporation"] { border-left-color: rgba(224, 168, 60, 0.55); }
.wallet-category:hover,
.wallet-category:focus-visible { border-left-color: var(--accent); background: rgba(150, 196, 224, 0.06); outline: none; }

.wallet-category-mark {
  grid-area: mark;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border: 1px solid rgba(var(--accent-rgb), 0.45);
  background: var(--accent-wash);
  color: var(--accent);
}

.wallet-category-mark svg { width: 20px; height: 20px; }
.wallet-category-mark.is-corp {
  border-color: rgba(224, 168, 60, 0.55);
  background: rgba(224, 168, 60, 0.08);
  color: var(--amber);
  font-size: 10px;
  letter-spacing: 0.08em;
}

.wallet-category-name { grid-area: name; min-width: 0; overflow: hidden; font-size: 15px; color: var(--ink-bright); text-overflow: ellipsis; white-space: nowrap; }
.wallet-category-sub { grid-area: sub; font-size: 12px; color: var(--ink-dim); }
.wallet-category .wallet-account-balance { grid-area: balance; }
.wallet-category-go { grid-area: go; color: var(--ink-dim); font-size: 18px; }
.wallet-category:hover .wallet-category-go { color: var(--accent); }

.wallet-ticker {
  padding: 1px 6px;
  border: 1px solid var(--amber);
  color: var(--amber);
  font-size: 10px;
  letter-spacing: 0.14em;
}

.wallet-add {
  align-self: flex-start;
  padding: 2px 0;
  border: 0;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.06em;
  cursor: pointer;
}

.wallet-add:hover,
.wallet-add:focus-visible { color: var(--accent); outline: none; }

.wallet-holder { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; }
.wallet-holder .wallet-badge { margin-left: 0; }
.wallet-holder .wallet-account-mark { width: 26px; height: 26px; }
.wallet-holder .wallet-account-mark svg { width: 15px; height: 15px; }

.wallet-edit {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  vertical-align: middle;
}

.wallet-edit[hidden] { display: none; }

.wallet-edit:hover,
.wallet-edit:focus-visible { color: var(--accent); border-color: var(--line-strong); outline: none; }

/* A name being renamed: a text box the size of the name it replaced. */
.wallet-name-input {
  min-width: 0;
  width: min(100%, 22ch);
  padding: 2px 6px;
  border: 1px solid var(--accent);
  background: rgba(5, 8, 12, 0.7);
  color: var(--ink-bright);
  font: inherit;
  letter-spacing: normal;
  text-transform: none;
  outline: none;
}

.wallet-name-input:invalid { border-color: var(--danger); }
.wallet-card-name { font-size: 15px; }

.wallet-ticker-input { text-transform: uppercase; letter-spacing: 0.14em; max-width: 140px; }

/* Hovering an account on the overview: its latest transactions, in a panel
   on <body> beside it (wallet.js, showPreview), over every window. */
.wallet-preview {
  position: fixed;
  z-index: 75;
  width: 440px;
  max-width: calc(100vw - 16px);
  padding: 10px 12px 8px;
  background: linear-gradient(180deg, #16222e, #0b131b);
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.85);
  color: var(--ink);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  pointer-events: none; /* a preview, not a place to click */
}

.wallet-preview[hidden] { display: none; }

.wallet-preview-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  padding-bottom: 6px;
  margin-bottom: 2px;
  border-bottom: 1px solid var(--line);
}

.wallet-preview-title { color: var(--ink-bright); font-weight: 600; }
.wallet-preview-sub { font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }

.wallet-preview-row {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr) auto 92px;
  gap: 8px;
  align-items: baseline;
  padding: 5px 0;
  border-top: 1px solid var(--line);
}

.wallet-preview-row:first-child { border-top: 0; }
.wallet-preview-row .is-num { text-align: right; white-space: nowrap; }
.wallet-preview .wallet-desc > span:first-child { font-size: 13px; }
.wallet-preview-foot { margin: 6px 0 0; font-size: 11px; color: var(--ink-dim); }

select.win-input { appearance: auto; }

@media (max-width: 720px) {
  .wallet-row { grid-template-columns: 52px minmax(0, 1fr) 96px; }
  .wallet-recent { grid-template-columns: 52px minmax(0, 1fr) auto; }
  .wallet-types { grid-template-columns: 1fr; }
  .wallet-running,
  .wallet-row.is-head > :last-child { display: none; }
  .wallet-detail { padding-left: 6px; }
}

/* ---- Corporations */

.corps { display: flex; flex-direction: column; gap: 12px; }
.corps-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }

.corps-card {
  display: grid;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--amber);
  background: rgba(150, 196, 224, 0.03);
}

.corps-head { display: flex; align-items: baseline; gap: 10px; }
.corps-name { font-size: 16px; color: var(--ink-bright); }

.corps-facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 4px 16px;
  margin: 0;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.corps-facts dt { color: var(--ink-dim); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; align-self: center; }
.corps-facts dd { margin: 0; }

.corps-dissolve {
  display: grid;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid rgba(210, 86, 63, 0.45);
  background: rgba(210, 86, 63, 0.06);
}

.corps-warning { margin: 0; color: #f0907a; font-weight: 600; }
.corps-consequences { margin: 0; padding-left: 18px; font-size: 13px; line-height: 1.5; color: var(--ink); }
.win-button.is-danger:not(:disabled) { border-color: rgba(210, 86, 63, 0.55); }
/* A destructive button clicked once, waiting for the second click. */
.win-button.is-armed:not(:disabled) { border-color: var(--danger); background: rgba(210, 86, 63, 0.14); color: #ffd9cf; }

/* The list: invitations, then corporations as cards that open. A narrow
   window stacks the Roles tab, so the window is a size container. */
.corps { container-type: inline-size; }
.corps-section { display: flex; flex-direction: column; gap: 10px; }
.corps-empty { height: auto; min-height: 200px; }
.corps-card.is-invite { border-left-color: var(--accent); }

.corps-card.is-link {
  width: 100%;
  gap: 6px;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.corps-card.is-link:hover,
.corps-card.is-link:focus-visible { border-left-color: var(--accent); background: rgba(150, 196, 224, 0.06); outline: none; }
.corps-go { margin-left: auto; color: var(--ink-dim); font-size: 18px; line-height: 1; }
.corps-card-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; font-size: 12px; color: var(--ink-dim); }
.corps-card-meta .is-num { margin-left: auto; color: var(--ink); font-variant-numeric: tabular-nums; }

/* A role's colour comes in as --role; no colour reads as plain ink. */
.corps-standing { display: inline-flex; align-items: center; gap: 5px; color: var(--role, var(--ink)); }
.corps-standing.is-owner { color: var(--amber); }
.corps-dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: var(--role, var(--ink-dim)); }
.corps-crown { width: 13px; height: 13px; flex: 0 0 auto; fill: var(--amber); vertical-align: -1px; }

/* One corporation: title, tabs, then the tab. */
.corps-title { display: flex; align-items: baseline; gap: 10px; }
.corps-title-name { margin: 0; font-size: 19px; font-weight: 600; color: var(--ink-bright); }
.corps-tabs { display: flex; flex-wrap: wrap; border-bottom: 1px solid var(--line); }
.corps-pane { display: flex; flex-direction: column; gap: 14px; }
.corps-facts dd { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }

.corps-link {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
}

.corps-link:hover,
.corps-link:focus-visible { color: var(--ink-bright); outline: none; }

.corps-can { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.corps-can li { display: grid; gap: 1px; padding-left: 10px; border-left: 2px solid rgba(var(--accent-rgb), 0.45); }
.corps-can-label { font-size: 14px; color: var(--ink-bright); }

/* Role pills, Discord-style: a dot in the role's colour and its name. */
.corps-pills { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; min-width: 0; }

.corps-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 100%;
  padding: 1px 7px;
  border: 1px solid color-mix(in srgb, var(--role, var(--ink-dim)) 55%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--role, var(--ink-dim)) 10%, transparent);
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  line-height: 1.5;
  white-space: nowrap;
}

.corps-pill.is-owner { border-color: rgba(224, 168, 60, 0.55); background: rgba(224, 168, 60, 0.08); color: var(--amber); }

.corps-pill-x {
  margin: 0 -3px 0 0;
  padding: 0 2px;
  border: 0;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  line-height: 1;
  cursor: pointer;
}

.corps-pill-x:hover,
.corps-pill-x:focus-visible { color: #f0907a; outline: none; }

.corps-pill-add { width: 24px; justify-content: center; padding: 1px 0; border-style: dashed; color: var(--ink-dim); cursor: pointer; }
.corps-pill-add:hover,
.corps-pill-add:focus-visible { color: var(--ink-bright); border-color: var(--accent); outline: none; }

/* Members: grouped under their highest role, like Discord's member list. */
.corps-toolbar { flex-wrap: nowrap; }
.corps-toolbar .win-button { flex: 0 0 auto; white-space: nowrap; }
.corps-filter { flex: 1 1 auto; min-width: 0; }
.corps-members { display: flex; flex-direction: column; gap: 12px; }
.corps-group { display: flex; flex-direction: column; gap: 4px; }

.corps-group-head {
  margin: 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--role, var(--ink-dim));
}

.corps-rows { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }

.corps-member {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) minmax(0, auto) 28px;
  align-items: center;
  column-gap: 10px;
  padding: 6px 6px 6px 8px;
  border: 1px solid transparent;
  background: rgba(150, 196, 224, 0.03);
}

.corps-member:hover,
.corps-member:focus-within { border-color: var(--line); background: rgba(150, 196, 224, 0.06); }
.corps-member.is-compact { grid-template-columns: 34px minmax(0, 1fr) 28px; }
.corps-member .corps-pills { justify-content: flex-end; }

.corps-avatar {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--role, var(--ink-dim)) 60%, transparent);
  background: color-mix(in srgb, var(--role, var(--ink-dim)) 18%, #0c141c);
  color: var(--ink-bright);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.corps-member-main { display: grid; min-width: 0; }
.corps-member-name { display: flex; align-items: center; gap: 6px; min-width: 0; overflow: hidden; font-size: 14px; color: var(--ink-bright); white-space: nowrap; }
.corps-member-handle { overflow: hidden; font-size: 12px; color: var(--ink-dim); text-overflow: ellipsis; white-space: nowrap; }

.corps-you {
  padding: 0 5px;
  border: 1px solid var(--line-strong);
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.corps-more {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.corps-more:hover,
.corps-more:focus-visible { color: var(--ink-bright); border-color: var(--line-strong); outline: none; }

.corps-member-wrap { display: grid; gap: 0; }
.corps-member.is-confirming { border-color: rgba(210, 86, 63, 0.45); }

.corps-confirm {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  border: 1px solid rgba(210, 86, 63, 0.45);
  border-top: 0;
  background: rgba(210, 86, 63, 0.06);
  font-size: 13px;
}

.corps-tip { margin-top: -4px; }

.corps-invite { display: grid; gap: 6px; padding: 10px 12px; border: 1px solid rgba(var(--accent-rgb), 0.35); background: var(--accent-wash); }
.corps-invite-row { display: flex; gap: 6px; }
.corps-invite-row .win-input { flex: 1 1 auto; min-width: 0; }
.corps-invite-row .win-button { flex: 0 0 auto; }

.corps-invited {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 6px 6px 6px 10px;
  border-left: 2px dashed var(--line-strong);
  background: rgba(150, 196, 224, 0.03);
}

.corps-invited-who { color: var(--ink-bright); font-size: 14px; white-space: nowrap; }

/* Recruiting (2026-10-23, the test server first): Find a corporation, a
   corporation's public page, applying, and the Applications tab. */
.corps-find-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; }
.corps-find-bar .win-input { flex: 1 1 220px; min-width: 0; }
.corps-check { display: inline-flex; align-items: center; gap: 8px; min-height: 40px; font-size: 13px; color: var(--ink); cursor: pointer; }
.corps-check input { flex: 0 0 auto; width: 18px; height: 18px; margin: 0; accent-color: var(--accent); }
.corps-blurb {
  display: -webkit-box;
  margin: 0;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.corps-open { color: var(--accent); }
.corps-mark {
  margin-left: auto;
  padding: 0 6px;
  border: 1px solid var(--line-strong);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-bright);
}
.corps-about { margin: 0; font-size: 14px; line-height: 1.5; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }
.corps-quote { padding-left: 10px; border-left: 2px solid rgba(var(--accent-rgb), 0.45); }
.corps-apply { display: grid; gap: 8px; }
.corps-apply-text,
.corps-about-input { box-sizing: border-box; width: 100%; min-height: 96px; resize: vertical; }
.corps-app .corps-head { flex-wrap: wrap; }
.corps-empty-actions { flex-wrap: wrap; justify-content: center; }

/* Roles: the list on the left, the chosen role's editor on the right. */
.corps-roles { display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 16px; align-items: start; }
.corps-role-list { display: flex; flex-direction: column; gap: 8px; }
.corps-role-list > .win-button { align-self: stretch; }
.corps-roles-ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }

.corps-role {
  display: grid;
  grid-template-columns: 14px 8px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 8px;
  width: 100%;
  padding: 7px 8px;
  border: 1px solid transparent;
  border-left: 2px solid transparent;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}

.corps-role:hover,
.corps-role:focus-visible { background: rgba(150, 196, 224, 0.05); outline: none; }
.corps-role.is-selected { border-left-color: var(--role, var(--accent)); background: rgba(150, 196, 224, 0.08); color: var(--ink-bright); }
.corps-role.is-dragging { opacity: 0.4; }
.corps-role.is-drop-before { box-shadow: inset 0 2px 0 var(--accent); }
.corps-role.is-drop-after { box-shadow: inset 0 -2px 0 var(--accent); }
.corps-role[draggable="true"] { cursor: grab; }
.corps-role-name { min-width: 0; overflow: hidden; color: var(--role, inherit); text-overflow: ellipsis; white-space: nowrap; }
.corps-role-count { font-size: 11px; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.corps-grip { color: var(--ink-dim); font-size: 11px; letter-spacing: -0.2em; }
svg.corps-grip { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2; opacity: 0.7; }

.corps-role-editor { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.corps-role-title { display: flex; align-items: center; gap: 8px; font-size: 17px; font-weight: 600; color: var(--role, var(--ink-bright)); }
.corps-role-title .win-note { margin-left: auto; font-weight: 400; }
.corps-subtabs { display: flex; flex-wrap: wrap; border-bottom: 1px solid var(--line); }
.corps-lock { padding: 6px 10px; border-left: 2px solid var(--amber); background: rgba(224, 168, 60, 0.06); color: var(--ink); }
.corps-role-pane { display: flex; flex-direction: column; gap: 12px; }
.corps-role-delete { padding-top: 6px; border-top: 1px solid var(--line); }
.corps-perm-group { display: flex; flex-direction: column; }
.corps-perm-group + .corps-perm-group { margin-top: 8px; }
.corps-perm-group .corps-group-head { padding-bottom: 4px; }
.corps-perm.is-danger .settings-pref-label { color: #f0b0a0; }
.corps-perm-lack { color: var(--amber); }
.corps-perm .settings-switch:disabled { opacity: 0.4; cursor: not-allowed; }
.corps-add-member { flex: 1 1 auto; }

/* Discord's "unsaved changes" bar, stuck to the bottom of the window. */
.corps-savebar {
  position: sticky;
  /* Flush with the window's bottom edge, past the body's own padding. */
  bottom: -12px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid rgba(var(--accent-rgb), 0.5);
  background: #0f1d29;
  box-shadow: 0 -8px 20px rgba(0, 0, 0, 0.45);
  font-size: 13px;
  color: var(--ink-bright);
}

.corps-savebar[hidden] { display: none; }

@container (max-width: 560px) {
  .corps-roles { grid-template-columns: minmax(0, 1fr); }
  .corps-member { grid-template-columns: 34px minmax(0, 1fr) 28px; }
  .corps-member .corps-pills { grid-column: 2 / 4; grid-row: 2; justify-content: flex-start; padding-top: 4px; }
  .corps-member .corps-more { grid-column: 3; grid-row: 1; }
  .corps-invited { grid-template-columns: minmax(0, 1fr) auto; }
  .corps-invited .win-note { grid-column: 1; grid-row: 2; }
  .corps-invited .win-button { grid-row: 1 / 3; grid-column: 2; }
}

/* ---- The game's own right-click menu (contextmenu.js), over everything. */

.ctx-menu {
  position: fixed;
  z-index: 80;
  display: flex;
  flex-direction: column;
  min-width: 190px;
  max-width: 280px;
  max-height: calc(100vh - 12px);
  overflow: auto;
  padding: 5px;
  border: 1px solid var(--line-strong);
  background: #0b131b;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.6);
  font-size: 13px;
}

.ctx-menu:focus { outline: none; }

.ctx-heading {
  padding: 5px 8px 4px;
  overflow: hidden;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink-dim);
}

.ctx-sep { height: 1px; margin: 4px 2px; background: var(--line); }

.ctx-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 6px 8px;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.ctx-item:hover:not(:disabled),
.ctx-item:focus-visible { background: var(--accent-wash); color: var(--ink-bright); outline: none; }
.ctx-item:focus:not(:focus-visible) { outline: none; }
.ctx-item:disabled { opacity: 0.4; cursor: default; }
.ctx-item.is-danger { color: #f0907a; }
.ctx-item.is-danger:hover:not(:disabled),
.ctx-item.is-danger:focus-visible { background: rgba(210, 86, 63, 0.16); color: #ffd9cf; }
.ctx-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* A few dim words at the end of a line: "Soon", or a shortcut. */
.ctx-note { margin-left: auto; padding-left: 14px; font-size: 11px; letter-spacing: 0.04em; color: var(--ink-dim); white-space: nowrap; }
.ctx-dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: var(--ctx-color); }

.ctx-box {
  position: relative;
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.6);
}

.ctx-item[aria-checked="true"] .ctx-box { border-color: var(--accent); background: var(--accent); }
/* One of a set (menuitemradio): a ring, filled with a dot when chosen. */
.ctx-item.is-radio .ctx-box { border-radius: 50%; }
.ctx-item.is-radio[aria-checked="true"] .ctx-box { background: rgba(5, 8, 12, 0.6); }
.ctx-item.is-radio[aria-checked="true"] .ctx-box::after {
  left: 3px;
  top: 3px;
  width: 6px;
  height: 6px;
  border: 0;
  border-radius: 50%;
  background: var(--accent);
  transform: none;
}
.ctx-item[aria-checked="true"] .ctx-box::after {
  content: "";
  position: absolute;
  left: 4px;
  top: 1px;
  width: 4px;
  height: 8px;
  border: solid var(--void);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

/* ---- Logistics, after Factorio's space-platform hub: panels of item slots */

.flog { display: flex; flex-direction: column; gap: 10px; }

.flog-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  background: var(--accent-wash);
}

.flog-head-label { font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); white-space: nowrap; }
.flog-head-name { font-size: 15px; font-weight: 600; letter-spacing: 0.03em; color: var(--ink-bright); }
.flog-picker { flex: 1 1 auto; min-width: 0; }

.flog-panels { display: grid; gap: 10px; transition: opacity 0.15s; }
.flog.has-dialog .flog-panels { opacity: 0.3; pointer-events: none; }

/* A frame: a title strip over an inset well of slots. */
.flog-panel {
  display: grid;
  gap: 8px;
  padding: 8px 10px 10px;
  border: 1px solid var(--line);
  background: rgba(150, 196, 224, 0.03);
}

.flog-panel.is-paused .fgrid { opacity: 0.5; }
.flog-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }

.flog-panel-head h3 {
  margin: 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.fgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, 44px);
  gap: 4px;
  padding: 6px;
  background: rgba(2, 4, 6, 0.75);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.85), inset 0 0 0 1px rgba(150, 196, 224, 0.06);
}

/* One slot: an item, its number in the corner, a bar for how full. */
.fslot {
  position: relative;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid rgba(150, 196, 224, 0.16);
  background: linear-gradient(180deg, #121c26, #0b131a);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), inset 0 -2px 4px rgba(0, 0, 0, 0.45);
  color: var(--ink);
  font: inherit;
  cursor: pointer;
}

.fslot:hover,
.fslot:focus-visible { border-color: var(--accent); background: linear-gradient(180deg, #16303d, #0d1b24); outline: none; }

.fslot.is-empty {
  cursor: default;
  border-color: rgba(150, 196, 224, 0.07);
  background: rgba(10, 16, 22, 0.6);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.6);
}

.fslot.is-add {
  border-style: dashed;
  border-color: rgba(var(--accent-rgb), 0.45);
  background: rgba(var(--accent-rgb), 0.05);
  color: var(--accent);
  font-size: 22px;
  line-height: 1;
}

.fslot .item-icon { filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.7)); }

.fslot-count {
  position: absolute;
  right: 3px;
  bottom: 2px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  color: #fff;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 2px #000, 0 1px 1px #000, 1px 0 1px #000, -1px 0 1px #000;
  pointer-events: none;
}

.fslot:has(.fslot-bar) .fslot-count { bottom: 6px; }
.fslot-bar { position: absolute; left: 2px; right: 2px; bottom: 1px; height: 3px; background: rgba(0, 0, 0, 0.65); }
.fslot-bar i { display: block; height: 100%; background: var(--accent); transition: width 0.4s linear; }

/* How a slot is doing: green filled (or waiting for its low point), yellow
   filling, red short with nothing to fill it. */
.fslot { --slot-ok: #5fd17a; --slot-fill: #e9c94c; --slot-bad: #e0564a; }
.fslot.is-full,
.fslot.is-waiting,
.fslot.is-selling { border-color: rgba(95, 209, 122, 0.6); }
.fslot.is-full .fslot-bar i,
.fslot.is-waiting .fslot-bar i,
.fslot.is-selling .fslot-bar i { background: var(--slot-ok); }
.fslot.is-filling { border-color: rgba(233, 201, 76, 0.65); }
.fslot.is-filling .fslot-bar i { background: var(--slot-fill); }
.fslot.is-blocked,
.fslot.is-idle { border-color: rgba(224, 86, 74, 0.75); box-shadow: inset 0 0 0 1px rgba(224, 86, 74, 0.2), inset 0 -2px 4px rgba(0, 0, 0, 0.45); }
.fslot.is-blocked .fslot-bar i,
.fslot.is-idle .fslot-bar i { background: var(--slot-bad); }
/* Waiting for a low point: green, but dashed, since nothing is wanted yet. */
.fslot.is-waiting { border-style: dashed; }
.fslot.is-off { opacity: 0.6; }
.fslot.is-idle .fslot-count { color: var(--ink-dim); }

/* Dragging a slot to a new place. */
.fslot.is-movable { touch-action: none; }
.fslot.is-dragging { opacity: 0.3; }
.flog-panels.is-dragging .fslot:hover { border-color: rgba(150, 196, 224, 0.16); background: linear-gradient(180deg, #121c26, #0b131a); }
.fslot-ghost {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 90;
  pointer-events: none;
  opacity: 0.9;
  border-color: var(--accent) !important;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.7);
}
.fslot.is-drop-before::before,
.fslot.is-drop-after::after {
  content: "";
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 3px;
  background: var(--accent);
  box-shadow: 0 0 6px rgba(var(--accent-rgb), 0.8);
}
.fslot.is-drop-before::before { left: -4px; }
.fslot.is-drop-after::after { right: -4px; }
.fgrid.is-drop-end { box-shadow: inset 0 0 0 1px var(--accent); }

/* A slot that starts a new line (src/rows.js); the empty slots before it are
   added by the window, this only makes sure it is first in its row. */
.fslot.is-line { grid-column-start: 1; }

/* While a slot is dragged, a row under each well it can go in: drop it there
   to start a new line. */
.fgrid-newline {
  display: none;
  grid-column: 1 / -1;
  place-items: center;
  height: 44px;
  border: 1px dashed var(--line-strong);
  color: var(--ink-dim);
  font-size: 11px;
  letter-spacing: 0.08em;
  pointer-events: auto;
}
.flog-panels[data-drag-kind="stock"] .fgrid[data-drop-kind="stock"] .fgrid-newline,
.flog-panels[data-drag-kind="request"] .fgrid[data-drop-kind="request"] .fgrid-newline,
.flog-panels[data-drag-kind="export"] .fgrid[data-drop-kind="export"] .fgrid-newline { display: grid; }
.fgrid-newline.is-drop-here { border-color: var(--accent); border-style: solid; color: var(--ink-bright); background: rgba(var(--accent-rgb), 0.1); }

/* Groups of requests or exports, after Factorio's logistic sections. */
.flog-group { display: grid; gap: 6px; padding: 6px 8px 8px; border: 1px solid var(--line); background: rgba(2, 4, 6, 0.25); }
.flog-group.is-paused .fgrid { opacity: 0.5; }
.flog-group-head { display: flex; align-items: center; gap: 6px; min-width: 0; }
.flog-group-name { font-size: 14px; font-weight: 600; color: var(--ink-bright); }
.flog-group-count { font-size: 11px; color: var(--ink-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.flog-group-more { flex: 0 0 auto; }
.flog-switch.is-small .flog-switch-text { display: none; }
.flog-add-group { justify-self: start; }
/* "Only start buying when stock is below [ n ]": across the whole box, the
   tick right beside its words, the number after them. */
.flog-below { grid-column: 1 / -1; display: grid; gap: 4px; }
.flog-below-row { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; }
.flog-below-label { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink); cursor: pointer; }
.flog-below-label input { flex: 0 0 auto; margin: 0; accent-color: var(--accent); }
.flog-below-input { width: 110px; }
.flog-below-note { margin: 0 0 0 21px; }

/* Tier, marked like Factorio's quality: a pip in an icon's corner. */
.item-tier.is-t2 { fill: var(--t2); }
.item-tier.is-t3 { fill: var(--t3); }
.item-tier.is-t4 { fill: var(--t4); }

.flog-info { min-height: 1.4em; margin: 0; font-size: 12px; line-height: 1.4; color: var(--ink-dim); }

/* On or off for a whole panel. */
.flog-switch {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 4px;
  border: 0;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
}

.flog-switch-knob { position: relative; width: 28px; height: 14px; border-radius: 7px; background: rgba(150, 196, 224, 0.18); transition: background 0.15s; }

.flog-switch-knob::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--ink-dim);
  transition: transform 0.15s, background 0.15s;
}

.flog-switch[aria-checked="true"] { color: var(--accent); }
.flog-switch[aria-checked="true"] .flog-switch-knob { background: rgba(var(--accent-rgb), 0.45); }
.flog-switch[aria-checked="true"] .flog-switch-knob::after { transform: translateX(14px); background: var(--ink-bright); }
.flog-switch:focus-visible { outline: 1px solid var(--accent); }

/* Adding or changing a request or an export. */
.flog-dialog-layer[hidden] { display: none; }

.flog-dialog {
  display: grid;
  gap: 12px;
  padding: 12px 14px 14px;
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  background: linear-gradient(180deg, rgb(22, 34, 46), rgb(12, 19, 26));
  box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.9);
}

.flog-dialog-head { display: flex; align-items: center; gap: 10px; }
.flog-dialog-head h4 { flex: 1 1 auto; margin: 0; font-size: 15px; font-weight: 600; letter-spacing: 0.03em; color: var(--ink-bright); }

.flog-dialog-icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  border: 1px solid var(--line-strong);
  background: rgba(2, 4, 6, 0.7);
}

.flog-dialog-title { flex: 1 1 auto; display: grid; gap: 2px; min-width: 0; }
.flog-dialog-sub { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); }

.flog-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); }

.flog-tab {
  margin-bottom: -1px;
  padding: 6px 12px;
  border: 1px solid transparent;
  border-top-width: 2px;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
}

.flog-tab:hover,
.flog-tab:focus-visible { color: var(--ink-bright); outline: none; }
.flog-tab.is-on { border-color: var(--line); border-bottom-color: transparent; background: rgba(var(--accent-rgb), 0.06); color: var(--ink-bright); }
.flog-tab { display: inline-flex; align-items: center; gap: 7px; }
.flog-tab.is-on { border-top-color: var(--accent); }
.flog-tabs.is-searching .flog-tab { opacity: 0.6; }

/* The item picker: search, a tab per category, a shelf per subgroup. */
.flog-search { width: 100%; }
.flog-shelves { display: grid; gap: 10px; max-height: min(52vh, 460px); overflow-y: auto; padding-right: 2px; }
.flog-shelf { display: grid; gap: 5px; }
.flog-shelf-name {
  margin: 0;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.flog-picks-none { margin: 6px 0; }

.flog-picks { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 6px; }

.flog-pick {
  display: grid;
  justify-items: center;
  gap: 4px;
  padding: 8px 4px;
  border: 1px solid var(--line);
  background: rgba(2, 4, 6, 0.5);
  color: var(--ink);
  font: inherit;
  text-align: center;
  cursor: pointer;
}

.flog-pick:hover:not(:disabled),
.flog-pick:focus-visible { border-color: var(--accent); background: rgba(var(--accent-rgb), 0.08); outline: none; }
.flog-pick:disabled { opacity: 0.4; cursor: default; }
.flog-pick.is-here { border-color: rgba(var(--accent-rgb), 0.45); }
.flog-pick-name { font-size: 12px; color: var(--ink-bright); }
.flog-pick-tier { font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; }
.flog-pick-tier.is-t1 { color: var(--t1); }
.flog-pick-tier.is-t2 { color: var(--t2); }
.flog-pick-tier.is-t3 { color: var(--t3); }
.flog-pick-tier.is-t4 { color: var(--t4); }
.flog-pick-note { min-height: 1.2em; font-size: 10px; letter-spacing: 0.06em; color: var(--accent); }
.flog-pick:disabled .flog-pick-note { color: var(--ink-dim); }

.flog-amount-row { display: grid; grid-template-columns: minmax(0, 1fr) 110px; align-items: center; gap: 10px; }
.flog-slider { width: 100%; accent-color: var(--accent); }

.flog-sources { display: grid; gap: 6px; margin: 0; padding: 0; border: 0; }

.flog-sources legend {
  margin-bottom: 6px;
  padding: 0;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.flog-source { display: grid; gap: 4px; padding: 8px 10px; border: 1px solid var(--line); background: rgba(2, 4, 6, 0.4); }
.flog-source.is-on { border-color: rgba(var(--accent-rgb), 0.55); background: rgba(var(--accent-rgb), 0.06); }
.flog-source.is-disabled { opacity: 0.55; }
.flog-source-label { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.flog-source.is-disabled .flog-source-label { cursor: default; }
.flog-source-label input { margin: 0; accent-color: var(--accent); }
.flog-source-title { font-size: 14px; color: var(--ink-bright); }
.flog-source-detail { margin: 0 0 0 22px; font-size: 12px; line-height: 1.4; color: var(--ink-dim); }
.flog-source-extra { display: grid; grid-template-columns: 1fr 1.6fr; gap: 8px 10px; margin: 4px 0 0 22px; }
.flog-both { color: var(--accent); }

/* "Sell excess" on an export: keep the station's full level, sell the rest. */
.flog-excess { display: grid; gap: 4px; padding: 8px 10px; border: 1px solid var(--line); background: rgba(2, 4, 6, 0.4); }
.flog-excess.is-on { border-color: rgba(var(--accent-rgb), 0.55); background: rgba(var(--accent-rgb), 0.06); }
.flog-excess-label { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; cursor: pointer; }
.flog-excess-label input { align-self: center; margin: 0; accent-color: var(--accent); }
.flog-excess-title { font-size: 14px; color: var(--ink-bright); }
.flog-excess-sub { font-size: 12px; color: var(--ink-dim); }
.flog-source-detail.is-warn { color: var(--amber); }

@media (max-width: 720px) {
  .flog-source-extra { grid-template-columns: 1fr; }
  .flog-amount-row { grid-template-columns: minmax(0, 1fr) 90px; }
}

/* ---- Factory Floor: the building menu, then everything you have built */

.factory { display: flex; flex-direction: column; gap: 10px; }

/* Which system Place puts things in, or how to open one. */
.factory-where {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--line-strong);
  background: rgba(150, 196, 224, 0.03);
}

.factory-where.is-open { border-left-color: var(--accent); background: var(--accent-wash); }
.factory-where .win-note { flex: 1 1 200px; }
.factory-where-label { font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }
.factory-where-name { font-size: 16px; font-weight: 600; letter-spacing: 0.04em; color: var(--ink-bright); }

.factory-heading {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 6px 0 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.factory-count { margin-left: auto; font-weight: 400; letter-spacing: 0.08em; font-variant-numeric: tabular-nums; }

.factory-menu,
.factory-rows { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }

.factory-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--line-strong);
  background: rgba(150, 196, 224, 0.03);
}

.factory-item.is-placing { border-left-color: var(--accent); background: var(--accent-wash); }

/* Place, and for a miner Zone under it (2026-10-21), its green grid mark. */
.factory-place { display: grid; gap: 6px; }
.factory-zone { display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.factory-zone-mark {
  width: 11px;
  height: 11px;
  border: 1px solid var(--zone);
  background-color: rgba(var(--zone-rgb), 0.12);
  background-image: linear-gradient(90deg, rgba(var(--zone-rgb), 0.7) 1px, transparent 1px),
    linear-gradient(rgba(var(--zone-rgb), 0.7) 1px, transparent 1px);
  background-size: 3px 3px;
  background-position: 0.5px 0.5px;
}
.factory-zone:hover:not(:disabled),
.factory-zone:focus-visible { border-color: var(--zone); color: var(--zone); }
.factory-zone:disabled .factory-zone-mark { opacity: 0.5; }

/* A machine goes in a station's slot: which station, and Build, under its
   description rather than beside it. */
.factory-item.is-machine { grid-template-columns: auto minmax(0, 1fr); }
.factory-machine-build { grid-column: 2; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.factory-machine-build .factory-station-pick { flex: 1 1 180px; min-width: 0; }
.factory-machine-build .factory-row-where,
.factory-machine-build .factory-rule { flex: 1 1 160px; }
.factory-machine-build .win-button { margin-left: auto; }

/* A station's build slots under it, each a way in. */
.factory-row.is-station { padding-bottom: 6px; border-bottom: 1px dashed var(--line); }
.factory-row.is-station:last-child { border-bottom: 0; }
.factory-row.is-station { grid-template-columns: auto minmax(0, 1fr) auto auto auto; }
.factory-slots li { display: contents; }
.factory-slot { font: inherit; font-size: 12px; cursor: pointer; }
.factory-slot:hover,
.factory-slot:focus-visible { border-color: var(--accent); outline: none; }
.factory-slot .item-icon { flex: none; }
.factory-slot svg:not(.item-icon) { flex: none; color: var(--ink-dim); }
.factory-slot.is-working { border-color: rgba(95, 209, 122, 0.5); }
.factory-slot.is-working svg:not(.item-icon) { color: #5fd17a; }
.factory-slot.is-waiting { border-color: rgba(233, 201, 76, 0.55); }
.factory-slot.is-waiting svg:not(.item-icon) { color: #e9c94c; }
.factory-slot.is-full { border-color: rgba(var(--accent-rgb), 0.55); }
.factory-slot.is-off,
.factory-slot.is-idle { opacity: 0.65; }
.factory-slot.is-empty { border-style: dashed; color: var(--ink-dim); }
.factory-slot-num {
  display: grid;
  place-items: center;
  width: 16px;
  height: 16px;
  border: 1px dashed var(--line-strong);
  font-size: 10px;
}

.factory-icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.6);
  color: var(--accent);
}

.factory-icon.is-small { width: 30px; height: 30px; }

.factory-text { display: grid; gap: 2px; min-width: 0; }
.factory-name { margin: 0; display: flex; align-items: center; gap: 8px; font-size: 15px; color: var(--ink-bright); }
.factory-blurb { margin: 0; font-size: 13px; line-height: 1.4; color: var(--ink); }
.factory-rule { margin: 0; font-size: 12px; line-height: 1.4; color: var(--ink-dim); }

/* Tiers wear the star map's tier colours. */
.factory-tier {
  padding: 0 5px;
  border: 1px solid currentColor;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  line-height: 15px;
  color: var(--t1);
}

.factory-tier[data-tier="0"] { color: var(--ink-dim); }
.factory-tier[data-tier="2"] { color: var(--t2); }
.factory-tier[data-tier="3"] { color: var(--t3); }

/* What a building costs: credits, or materials as icon chips. */
.factory-cost { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 4px 0 0; font-size: 12px; color: var(--ink); }
.factory-cost-label { font-size: 10px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }
.factory-cost-free { font-weight: 600; color: var(--ink-bright); }
.factory-cost-item { display: inline-flex; align-items: center; gap: 3px; }
.factory-cost-item b { font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink-bright); }
.factory-cost-item.is-short b { color: var(--amber); }
.factory-cost-from { flex-basis: 100%; font-size: 11px; color: var(--ink-dim); }

/* A tier its research has not unlocked: dimmed, with the way to it. */
.factory-item.is-locked { border-left-style: dashed; background: rgba(5, 8, 12, 0.35); }
.factory-item.is-locked .factory-icon { color: var(--ink-dim); border-style: dashed; }
.factory-item.is-locked .factory-blurb { color: var(--ink-dim); }
.factory-lock { margin: 2px 0 0; font-size: 12px; line-height: 1.4; color: var(--amber); }

/* Once the next tier is researched: upgrading one of your buildings. */
.factory-upgrade {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  margin-left: 38px;
  padding: 5px 8px;
  border: 1px dashed rgba(var(--accent-rgb), 0.4);
  background: rgba(var(--accent-rgb), 0.04);
  font-size: 12px;
}
.factory-upgrade.is-armed { border-style: solid; background: var(--accent-wash); }
.factory-upgrade-label { display: inline-flex; align-items: center; gap: 6px; color: var(--accent); }
.factory-upgrade-cost { flex: 1 1 140px; color: var(--ink); }
.factory-upgrade .win-button { padding-top: 3px; padding-bottom: 3px; }
.factory-slot.is-done { border-color: rgba(var(--accent-rgb), 0.55); }

.factory-built { display: grid; gap: 14px; }
.factory-group { display: grid; gap: 6px; }

.factory-group-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 5px;
  border-bottom: 1px solid var(--line);
}

.factory-system { font-size: 14px; font-weight: 600; letter-spacing: 0.04em; color: var(--ink-bright); overflow-wrap: anywhere; }
.factory-here { font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); }

.factory-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 8px;
}

/* A miner has a Split button too, and what it gathers underneath. */
.factory-row.is-miner { grid-template-columns: auto minmax(0, 1fr) auto auto auto; padding-bottom: 6px; border-bottom: 1px dashed var(--line); }
.factory-row.is-miner:last-child { border-bottom: 0; }

/* The two main categories, Miners and Space stations, each folding shut. */
.factory-category { display: grid; gap: 10px; }
.factory-category[open] { padding-bottom: 4px; }
.factory-category-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 10px;
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  background: var(--accent-wash);
  cursor: pointer;
  list-style: none;
}
.factory-category-head::-webkit-details-marker { display: none; }
.factory-category-head::after { content: "▾"; margin-left: auto; color: var(--ink-dim); transition: transform 150ms var(--ease); }
.factory-category:not([open]) .factory-category-head::after { transform: rotate(-90deg); }
.factory-category-head:focus-visible { outline: 1px solid var(--accent); }
.factory-category-title { font-size: 12px; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-bright); }
.factory-category-count {
  min-width: 20px;
  padding: 0 6px;
  border: 1px solid var(--line-strong);
  font-size: 11px;
  text-align: center;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.factory-category-sub { font-size: 12px; color: var(--ink-dim); }

/* What a miner is gathering: a chip per resource with its share and rate. */
.factory-gather { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0 0 0 38px; list-style: none; }
.factory-gather.is-empty { font-size: 12px; color: var(--ink-dim); }
.factory-gather-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px 2px 4px;
  border: 1px solid var(--line);
  background: rgba(2, 4, 6, 0.45);
  font-size: 12px;
  color: var(--ink);
}
.factory-gather-item.is-off { opacity: 0.5; }
.factory-gather-share { color: var(--ink-bright); font-variant-numeric: tabular-nums; }
.factory-gather-rate { color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.factory-split-toggle.is-on { border-color: var(--accent); color: var(--accent); }

/* Changing a miner's split from the Factory Floor. */
.factory-split {
  grid-column: 1 / -1;
  display: grid;
  gap: 6px;
  margin-left: 38px;
  padding: 8px 10px;
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  background: rgba(2, 4, 6, 0.55);
}
.factory-split-row { display: grid; grid-template-columns: auto minmax(70px, 9em) minmax(80px, 1fr) 4.2em 4.8em; align-items: center; gap: 8px; font-size: 13px; }
.factory-split-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-bright); }
.factory-split-slider { width: 100%; accent-color: var(--accent); }
.factory-split-pct { text-align: right; font-variant-numeric: tabular-nums; color: var(--ink-bright); }
.factory-split-rate { text-align: right; font-variant-numeric: tabular-nums; color: var(--ink-dim); }
.factory-split-buttons { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
/* A miner split saving itself (ui/splitsave.js): "Saving…", "Saved.", or why not. */
.split-status { margin: 0; font-size: 12px; color: var(--ink-dim); }
.split-status.is-error { color: #f0907a; }
.split-status:empty { display: none; }
@media (max-width: 520px) {
  .factory-row .factory-age { display: none; }
  .factory-gather, .factory-split { padding-left: 0; margin-left: 0; }
  .factory-split-row { grid-template-columns: auto minmax(0, 1fr) 4.2em; }
  .factory-split-row .factory-split-slider { grid-column: 1 / -1; grid-row: 2; }
  .factory-split-rate { display: none; }
}

.factory-row-main {
  display: grid;
  gap: 1px;
  min-width: 0;
  padding: 3px 6px;
  border: 1px solid transparent;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.factory-row-main:hover,
.factory-row-main:focus-visible { border-color: var(--line-strong); outline: none; }
.factory-row-main .factory-name { font-size: 13px; }
.factory-row-where { overflow: hidden; font-size: 12px; color: var(--ink-dim); text-overflow: ellipsis; white-space: nowrap; }
.factory-age { font-size: 11px; color: var(--ink-dim); white-space: nowrap; }

/* ---- Patch Notes: one message per day; categories open to show detail */

.notes { display: flex; flex-direction: column; gap: 16px; }

.notes-entry {
  display: grid;
  gap: 10px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--line-strong);
  background: rgba(150, 196, 224, 0.03);
}

.notes-entry.is-new { border-left-color: var(--accent); }
.notes-entry-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; }
.notes-title { margin: 0; font-size: 17px; font-weight: 600; color: var(--ink-bright); }
.notes-entry-head .wallet-badge { margin-left: 0; }

.notes-toggle {
  margin-left: auto;
  padding: 3px 9px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
}

.notes-toggle:hover,
.notes-toggle:focus-visible { color: var(--ink-bright); border-color: var(--accent); outline: none; }
.notes-note { margin: 0; font-size: 14px; line-height: 1.5; color: var(--ink); }

.notes-groups { display: grid; gap: 6px; }

.notes-group {
  border: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.35);
}

.notes-group > summary {
  display: grid;
  grid-template-columns: 14px 1fr;
  grid-template-areas: "chevron title" ". summary";
  column-gap: 8px;
  row-gap: 2px;
  padding: 9px 12px;
  list-style: none;
  cursor: pointer;
}

.notes-group > summary::-webkit-details-marker { display: none; }

.notes-group > summary::before {
  content: "";
  grid-area: chevron;
  align-self: center;
  width: 6px;
  height: 6px;
  border-right: 1.5px solid var(--ink-dim);
  border-bottom: 1.5px solid var(--ink-dim);
  transform: rotate(-45deg);
  transition: transform 150ms var(--ease);
}

.notes-group[open] > summary::before { transform: rotate(45deg); }
.notes-group > summary:hover,
.notes-group > summary:focus-visible { background: rgba(150, 196, 224, 0.05); outline: none; }
.notes-group > summary:hover::before { border-color: var(--accent); }

.notes-group-title { grid-area: title; font-size: 14px; font-weight: 600; color: var(--ink-bright); }
.notes-group-summary { grid-area: summary; font-size: 13px; line-height: 1.45; color: var(--ink-dim); }

.notes-list {
  margin: 0;
  padding: 2px 14px 12px 34px;
  display: grid;
  gap: 7px;
  font-size: 13px;
  line-height: 1.5;
  list-style: none;
}

/* One line: its tag (New, Fixed…) in a fixed-width column, then the text.
   The column fits the longest tag, Improved, with room to spare (it was 68px
   and Improved ran into the text: Dev Panel note 2026-10-18). */
.notes-line { display: grid; grid-template-columns: 88px minmax(0, 1fr); column-gap: 10px; align-items: baseline; }
.notes-line > .notes-text:only-child { grid-column: 2; }

.notes-tag {
  justify-self: start;
  padding: 1px 6px;
  border: 1px solid currentColor;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.14em;
  line-height: 1.5;
  text-transform: uppercase;
  white-space: nowrap;
}

.notes-tag.is-new { color: #7fd4a4; background: rgba(127, 212, 164, 0.08); }
.notes-tag.is-improved { color: var(--accent); background: var(--accent-wash); }
.notes-tag.is-changed { color: var(--amber); background: rgba(224, 168, 60, 0.08); }
.notes-tag.is-fixed { color: #b59cf0; background: rgba(181, 156, 240, 0.08); }
.notes-tag.is-removed { color: #f0907a; background: rgba(210, 86, 63, 0.08); }

/* ---- Settings: sections down the side, the chosen one beside them */

.settings-layout { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 14px; height: 100%; }

.settings-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-right: 10px;
  border-right: 1px solid var(--line);
}

.settings-nav-item {
  padding: 8px 10px;
  border: 0;
  border-left: 2px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-align: left;
  cursor: pointer;
}

.settings-nav-item:hover,
.settings-nav-item:focus-visible { color: var(--ink-bright); background: rgba(150, 196, 224, 0.05); outline: none; }
.settings-nav-item[aria-current="true"] { color: var(--ink-bright); border-left-color: var(--accent); background: var(--accent-wash); }

.settings-pane { min-width: 0; overflow: auto; }

.settings-pref {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}

.settings-heading + .settings-pref { border-top: 0; }
.settings-pref.is-choice { flex-wrap: wrap; }
.settings-pref-text { display: grid; gap: 3px; min-width: 0; flex: 1 1 200px; }
.settings-pref-label { font-size: 14px; color: var(--ink-bright); }
.settings-pref-help { font-size: 12px; line-height: 1.45; color: var(--ink-dim); }
.settings-note[hidden] { display: none; }
.settings-try { justify-self: start; padding: 0; }
/* "Apply to all" beside a default for names: a small outlined button. */
.settings-apply-all {
  justify-self: start;
  margin-top: 4px;
  padding: 3px 10px;
  border: 1px solid var(--line-strong);
  color: var(--ink);
}
.settings-apply-all:hover:not(:disabled),
.settings-apply-all:focus-visible { border-color: var(--accent); color: var(--ink-bright); outline: none; }
.settings-apply-all:disabled { opacity: 0.5; cursor: default; }
.settings-extra { padding-top: 6px; }

.settings-switch {
  position: relative;
  flex: 0 0 auto;
  width: 40px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 11px;
  background: rgba(5, 8, 12, 0.6);
  cursor: pointer;
  transition: background 150ms var(--ease), border-color 150ms var(--ease);
}

.settings-switch-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--ink-dim);
  transition: transform 150ms var(--ease), background 150ms var(--ease);
}

.settings-switch[aria-checked="true"] { background: rgba(var(--accent-rgb), 0.3); border-color: var(--accent); }
.settings-switch[aria-checked="true"] .settings-switch-knob { transform: translateX(18px); background: var(--ink-bright); }
.settings-switch:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }

.settings-choice { display: flex; flex-wrap: wrap; gap: 0; }

.settings-choice-option {
  padding: 5px 10px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}

.settings-choice-option + .settings-choice-option { border-left: 0; }
.settings-choice-option[aria-checked="true"] { background: var(--accent-wash); border-color: var(--accent); color: var(--ink-bright); }
.settings-choice-option[aria-checked="true"] + .settings-choice-option { border-left: 1px solid var(--accent); }
.settings-choice-option:hover,
.settings-choice-option:focus-visible { color: var(--ink-bright); outline: none; }
.settings-select { width: auto; min-width: 200px; flex: 0 0 auto; }

/* ---- what some settings do, everywhere */

/* Reduce motion: no transitions or animations anywhere. */
.reduce-motion *,
.reduce-motion *::before,
.reduce-motion *::after { transition: none !important; animation: none !important; scroll-behavior: auto !important; }

/* Hide balances until hovered (or focused). */
.hide-balances :is(.wallet-balance-value, .wallet-account-amount, .wallet-group-total, .wallet-running,
  .wallet-row .is-num, .wallet-recent .is-num, .wallet-preview .is-num, .wallet-stat-value, .corps-holdings .is-num,
  .corps-card-meta .is-num) {
  filter: blur(7px);
  transition: filter 120ms var(--ease);
}

.hide-balances :is(.wallet-card, .wallet-hero, .wallet-account, .wallet-category, .wallet-line, .wallet-recent, .wallet-stat,
  .wallet-group-head, .corps-holdings, .corps-card):is(:hover, :focus-within) :is(.wallet-balance-value, .wallet-account-amount,
  .wallet-group-total, .wallet-running, .is-num, .wallet-stat-value) {
  filter: none;
}

.hide-fps .map-readout-fps { display: none; }

/* Brightness: the map, the inside of a system and the saved background (drawn
   on its own layer above so it can be filtered without the windows). Only set
   away from 100%, so the usual case has no filter at all. */
.has-brightness .starmap,
.has-brightness .sysview-canvas,
.has-brightness .sysview-preview,
.has-brightness .viewport::before { filter: brightness(var(--scene-brightness, 1)); }

.settings-pref.is-range { flex-wrap: wrap; }
.settings-range { display: flex; align-items: center; gap: 10px; flex: 0 1 260px; min-width: 0; }
.settings-range-input { flex: 1 1 140px; min-width: 0; margin: 0; accent-color: var(--accent); cursor: pointer; }
.settings-range-value { flex: 0 0 4ch; text-align: right; font-size: 12px; font-variant-numeric: tabular-nums; color: var(--ink-bright); }
.settings-range-reset { align-self: center; }
.settings-range-reset:disabled { visibility: hidden; }

@media (max-width: 720px) {
  .settings-layout { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); }
  .settings-nav { flex-direction: row; overflow-x: auto; padding: 0 0 6px; border-right: 0; border-bottom: 1px solid var(--line); }
  .settings-nav-item { flex: 0 0 auto; border-left: 0; border-bottom: 2px solid transparent; }
  .settings-nav-item[aria-current="true"] { border-bottom-color: var(--accent); }
  .settings-select { min-width: 0; width: 100%; }
}

/* ---- Help: topics down the side like Settings, the chosen one beside them */

.help { display: grid; grid-template-rows: auto minmax(0, 1fr); gap: 12px; height: 100%; }
.help-toolbar { display: flex; }
.help-search { flex: 1 1 auto; width: auto; }
.help-layout { display: grid; grid-template-columns: 170px minmax(0, 1fr); gap: 14px; min-height: 0; }

.help-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-right: 10px;
  border-right: 1px solid var(--line);
  overflow-y: auto;
}

.help-nav-item {
  padding: 8px 10px;
  border: 0;
  border-left: 2px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-align: left;
  cursor: pointer;
}

.help-nav-item:hover,
.help-nav-item:focus-visible { color: var(--ink-bright); background: rgba(150, 196, 224, 0.05); outline: none; }
.help-nav-item[aria-current="true"] { color: var(--ink-bright); border-left-color: var(--accent); background: var(--accent-wash); }
.help-nav-item.is-out { opacity: 0.35; }

.help-pane { min-width: 0; overflow: auto; padding-right: 4px; outline: none; }
.help-topic { display: flex; flex-direction: column; gap: 14px; max-width: 62ch; }
.help-topic.is-result + .help-topic.is-result { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--line); }
.help-title { margin: 0; font-size: 17px; font-weight: 500; letter-spacing: 0.04em; color: var(--ink-bright); }
.help-title-link { padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.help-title-link:hover,
.help-title-link:focus-visible { color: var(--accent); outline: none; }
.help-summary { margin: -8px 0 0; font-size: 13px; color: var(--ink-dim); }
.help-section { display: flex; flex-direction: column; gap: 8px; }
.help-heading {
  margin: 4px 0 0;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}
.help-text { margin: 0; font-size: 14px; line-height: 1.55; color: var(--ink); }
.help-steps,
.help-points { display: flex; flex-direction: column; gap: 6px; margin: 0; padding-left: 22px; font-size: 14px; line-height: 1.5; color: var(--ink); }
.help-steps li::marker { color: var(--accent); font-variant-numeric: tabular-nums; }
.help-points li::marker { color: var(--ink-dim); }
.help-keys { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 7px 12px; margin: 0; font-size: 13px; line-height: 1.45; }
.help-keys dt { white-space: nowrap; }
.help-keys dd { margin: 0; color: var(--ink); }
.help-keys kbd {
  display: inline-block;
  padding: 1px 6px;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.6);
  font: inherit;
  font-size: 12px;
  color: var(--ink-bright);
}
.help-opens { display: flex; flex-wrap: wrap; gap: 8px; }
.help-mark { padding: 0 1px; background: rgba(var(--accent-rgb), 0.3); color: var(--ink-bright); }
.help-none { margin: 0; font-size: 14px; color: var(--ink-dim); }

@media (max-width: 720px) {
  .help-layout { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); }
  .help-nav { flex-direction: row; overflow-x: auto; overflow-y: hidden; padding: 0 0 6px; border-right: 0; border-bottom: 1px solid var(--line); }
  .help-nav-item { flex: 0 0 auto; border-left: 0; border-bottom: 2px solid transparent; }
  .help-nav-item[aria-current="true"] { border-bottom-color: var(--accent); }
  .help-keys { grid-template-columns: 1fr; gap: 2px 0; }
  .help-keys dd { margin-bottom: 6px; }
}

/* ---- narrow screens: no room to float, so a window fills the viewport */

@media (max-width: 720px) {
  .win {
    inset: 0 !important; /* beats the inline left/top windows.js sets for floating */
    width: auto !important;
    height: auto !important;
    max-width: none;
    max-height: none;
    min-width: 0;
    clip-path: none;
    transform: none; /* full screen already; "Window size" is for floating windows */
  }

  .win-grip { display: none; }

  .win-bar { cursor: default; }
}

/* ------------------------------------------------------------ responsive --
 * Narrow screens keep the rail but never widen it; neocom.js holds the pinned
 * preference and stops honouring it below this width, so the tooltips come
 * back rather than labels being cut off. The pin itself is hidden here.
 */

@media (max-width: 720px) {
  .neocom-pin { display: none; }
  /* The rail never widens here, so the panel gets the rest of the width. */
  .pilot-panel { width: calc(100vw - 68px); }

  /* Search across the top, the card under it, readouts along the bottom —
     the three of them cannot sit in their corners on a 360px screen without
     covering the map entirely. */
  .map-search { width: calc(100% - 24px - var(--switch-room, 0px)); }
  .map-results { width: calc(100% - 24px); max-height: 38vh; }
  .map-card {
    top: auto;
    bottom: 58px;
    right: 12px;
    left: 12px;
    width: auto;
  }
  .map-readout { gap: 8px; padding: 6px 8px; font-size: 10px; }
  .map-readout-span, .map-readout-hint { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; }
}

/* --- star system view ------------------------------------------------- */

/* Star systems are drawn on the map (systemview.js, 2026-10-24: no screen of
   their own). Their canvas lies over the map's and under the map's overlay
   and takes no clicks: the map hands them on. The open system's panel and
   the placing banner are in .sysview, over the overlay, where the map's card
   would be (the card hides while a system is open, .map-ui.has-system). */
.sysview-canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.sysview {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
}

.sysview[hidden] { display: none; }
.sysview > * { pointer-events: auto; }

.map-ui.has-system .map-card { display: none; }

/* The open system's name, code, star and buttons, at the top of its panel,
   staying there while the rest scrolls under it. */
.sysview-head {
  position: sticky;
  top: -12px;
  z-index: 1;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: -12px -14px 10px;
  padding: 12px 14px 10px;
  background: rgb(20, 31, 42);
  border-bottom: 1px solid var(--line);
}

.sysview-title {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  line-height: 1.2;
}

.sysview-head-kicker { color: var(--ink-dim); }

.sysview-name {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--ink-bright);
  overflow-wrap: anywhere;
}

.sysview-spectral {
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

/* Folds the panel to its head (a phone's screen is mostly panel otherwise). */
.sysview-fold {
  flex: none;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
}

.sysview-fold::before {
  content: '';
  width: 7px;
  height: 7px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
}

.sysview-fold[aria-expanded="false"]::before { transform: translateY(2px) rotate(-135deg); }

.sysview-fold:hover,
.sysview-fold:focus-visible { border-color: var(--accent); color: var(--accent); outline: none; }

.sysview-panel.is-folded { bottom: auto; }
.sysview-panel.is-folded .sysview-body { display: none; }
.sysview-panel.is-folded .sysview-head { padding-bottom: 0; margin-bottom: 0; border-bottom: 0; }

/* Clear of the map's readout under it (bottom right). */
.sysview-panel {
  position: absolute;
  top: calc(12px + var(--switch-gap, 0px));
  right: 12px;
  bottom: 56px;
  width: min(280px, calc(100% - 24px));
  overflow-y: auto;
  padding: 12px 14px 14px;
  background: linear-gradient(180deg, rgba(20, 31, 42, 0.95), rgba(10, 16, 22, 0.95));
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
}

.sysview-preview {
  display: block;
  width: 150px;
  height: 150px;
  margin: 2px auto 8px;
}

.sysview-kicker {
  margin: 0;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
}

.sysview-panel-name {
  margin: 3px 0 6px;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-bright);
  overflow-wrap: anywhere;
}

.sysview-note {
  margin: 0 0 10px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink);
}

.sysview-facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 5px 12px;
  margin: 0 0 12px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  font-size: 11px;
}

.sysview-facts dt {
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.sysview-facts dd {
  margin: 0;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* Every body in the system, innermost first, with your stations among them
   as if they were planets: the quick way to step through them without
   hunting for small dots on the canvas. A planet with your miners round it
   has a dropdown listing them. */
.sysview-list,
.sysview-sublist {
  margin: 0;
  padding: 10px 0 0;
  list-style: none;
  border-top: 1px solid var(--line);
}

.sysview-sublist { margin: 0 0 4px 18px; padding: 2px 0 0 6px; border-top: 0; border-left: 1px solid var(--line); }
.sysview-sublist[hidden] { display: none; }

.sysview-row { display: flex; align-items: stretch; gap: 4px; }

.sysview-pick {
  display: grid;
  flex: 1 1 auto;
  grid-template-columns: 12px minmax(18px, auto) 1fr;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 4px 6px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
}

.sysview-pick:hover { border-color: var(--line-strong); }
.sysview-list li.is-on > .sysview-row .sysview-pick { border-color: var(--accent); background: var(--accent-wash); }

/* The dropdown: how many miners, and which way it is open. */
.sysview-caret {
  flex: 0 0 auto;
  padding: 2px 7px;
  border: 1px solid var(--line);
  background: rgba(var(--accent-rgb), 0.06);
  color: var(--accent);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.04em;
  white-space: nowrap;
  cursor: pointer;
}

.sysview-caret:hover,
.sysview-caret:focus-visible { border-color: var(--accent); outline: none; }
.sysview-caret[aria-expanded="true"] { background: var(--accent-wash); }

.sysview-list span { color: var(--ink-bright); font-weight: 600; }
.sysview-list em { font-style: normal; color: var(--ink-dim); }
.sysview-sublist em { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.sysview-list i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #8a8580;
}

.sysview-list i[data-kind="gas giant"] { background: #c9a77d; }
.sysview-list i[data-kind="ice giant"] { background: #6f9fe0; }
.sysview-list i[data-kind="mini-neptune"] { background: #93acc0; }
.sysview-list i[data-kind="terran"] { background: #3f8f6a; }
.sysview-list i[data-kind="ocean"] { background: #2d6fa6; }
.sysview-list i[data-kind="desert"] { background: #c4874f; }
.sysview-list i[data-kind="lava"] { background: #ff6a1f; }
.sysview-list i[data-kind="ice"] { background: #dbe8f0; }
.sysview-list i[data-kind="super-earth"] { background: #8a8f7a; }
.sysview-list i[data-kind="belt"] { background: transparent; border: 1px dotted #a09080; border-radius: 0; }
/* Yours, in the accent colour: a station's hexagon, a miner's diamond. */
.sysview-list i[data-kind="station"] {
  border-radius: 0;
  background: var(--accent);
  clip-path: polygon(25% 4%, 75% 4%, 100% 50%, 75% 96%, 25% 96%, 0 50%);
}

.sysview-list i[data-kind="miner"] {
  width: 8px;
  height: 8px;
  margin-left: 1px;
  border-radius: 0;
  background: var(--accent);
  transform: rotate(45deg);
}

/* Placing a building: what, how, and why not. Centred at the foot of the
   part of the view the panel leaves free (systemview.js sets left and top). */
.sysview-placing {
  position: absolute;
  transform: translate(-50%, calc(-100% - 8px));
  width: max-content;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 3px 14px;
  max-width: min(460px, calc(100% - 24px));
  padding: 9px 12px;
  /* Opaque: on a phone it sits over the panel's text. */
  background: linear-gradient(180deg, rgb(20, 31, 42), rgb(10, 16, 22));
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
}

.sysview-placing[hidden] { display: none; }
.sysview-placing.is-over-panel { transform: translate(-50%, 0); }
.sysview-placing p { grid-column: 1; margin: 0; }

.sysview-placing-what {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
}

.sysview-placing-how { font-size: 12px; line-height: 1.4; color: var(--ink); }
.sysview-placing-error { font-size: 12px; line-height: 1.4; color: #f0907a; }
.sysview-placing-error:empty { display: none; }

.sysview-placing-stop,
.sysview-scrap {
  padding: 7px 12px;
  border: 1px solid var(--line-strong);
  background: rgba(10, 16, 22, 0.9);
  color: var(--ink);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}

.sysview-placing-stop { grid-column: 2; grid-row: 1 / span 3; }

.sysview-placing-stop:hover,
.sysview-placing-stop:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
  outline: none;
}


/* A miner is placed one at a time or zoned (2026-10-21): a pointer and a
   green grid at the banner's left switch between them. On a phone they get
   a row of their own under the words. */
.sysview-placing.has-modes {
  grid-template-columns: auto minmax(0, 1fr) auto;
  max-width: min(540px, calc(100% - 24px));
}
.sysview-placing.has-modes p { grid-column: 2; }
.sysview-placing.has-modes .sysview-placing-stop { grid-column: 3; }
.sysview-placing-modes { grid-column: 1; grid-row: 1 / span 3; display: flex; gap: 4px; }
.sysview-placing-modes[hidden] { display: none; }

.sysview-mode {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--line-strong);
  background: rgba(10, 16, 22, 0.9);
  color: var(--ink-dim);
  cursor: pointer;
}
.sysview-mode svg { width: 20px; height: 20px; fill: currentColor; }
.sysview-mode.is-zone svg { fill: rgba(var(--zone-rgb), 0.12); stroke: currentColor; stroke-width: 1.5; }
.sysview-mode:hover,
.sysview-mode:focus-visible { color: var(--ink-bright); border-color: var(--ink-dim); outline: none; }
.sysview-mode[aria-pressed="true"] { color: var(--accent); border-color: var(--accent); background: var(--accent-wash); }
.sysview-mode.is-zone[aria-pressed="true"] { color: var(--zone); border-color: var(--zone); background: rgba(var(--zone-rgb), 0.1); }
.sysview-placing.has-modes:has(.is-zone[aria-pressed="true"]) { border-left-color: var(--zone); }
.sysview-placing.has-modes:has(.is-zone[aria-pressed="true"]) .sysview-placing-what { color: var(--zone); }

@media (max-width: 560px) {
  .sysview-placing.has-modes { grid-template-columns: minmax(0, 1fr) auto; }
  .sysview-placing.has-modes p { grid-column: 1; }
  .sysview-placing.has-modes .sysview-placing-stop { grid-column: 2; grid-row: 1 / span 3; }
  .sysview-placing-modes { grid-column: 1 / -1; grid-row: 4; margin-top: 4px; }
}

/* A selected structure's own actions, in the panel. */
.sysview-actions { display: grid; gap: 6px; margin: 0 0 12px; }
.sysview-actions[hidden] { display: none; }
.sysview-scrap { border-color: rgba(210, 86, 63, 0.55); }

.sysview-scrap:hover:not(:disabled),
.sysview-scrap:focus-visible,
.sysview-scrap.is-armed {
  border-color: var(--danger);
  background: rgba(210, 86, 63, 0.14);
  color: #ffd9cf;
  outline: none;
}

.sysview-scrap:disabled { opacity: 0.5; cursor: default; }
.sysview-action-error { margin: 0; font-size: 12px; color: #f0907a; }
.sysview-action-error:empty { display: none; }
/* Developers only: how to look inside another pilot's station. */
.sysview-visit { margin: 0; font-size: 12px; line-height: 1.45; color: var(--ink-dim); }

/* What a planet holds, or what a miner mines: one row per resource, with
   its class and how long a unit takes. On your own miner each row has a
   slider, and the sliders between them always make 100% (its split). */
.sysview-res {
  display: grid;
  gap: 9px;
  margin: 0 0 12px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}

.sysview-res[hidden] { display: none; }
.sysview-res-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 22px; }

.sysview-res-head h3 {
  margin: 0;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.sysview-res-row {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) auto;
  align-items: center;
  gap: 3px 9px;
}

.sysview-res-icon { display: flex; width: 26px; height: 26px; }
.sysview-res-name { display: flex; flex-direction: column; min-width: 0; font-size: 12px; color: var(--ink-bright); overflow-wrap: anywhere; }
.sysview-res-name small { font-size: 10px; letter-spacing: 0.04em; color: var(--ink-dim); }
.sysview-res-name small[data-tier="2"] { color: var(--t2); }
.sysview-res-name small[data-tier="3"] { color: var(--t3); }
.sysview-res-name small[data-tier="4"] { color: var(--t4); }
.sysview-res-rate { font-size: 11px; color: var(--accent); font-variant-numeric: tabular-nums; white-space: nowrap; }

.sysview-res-share {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.sysview-res-share b { font-size: 14px; font-weight: 600; color: var(--ink-bright); }
.sysview-res-share small { font-size: 10px; color: var(--ink-dim); }

/* A split's percentage (pctinput.js): click the number to type one. */
.pct-edit { display: inline-flex; align-items: center; justify-content: flex-end; gap: 2px; }
.pct-edit-show {
  padding: 0 2px;
  border: 0;
  border-bottom: 1px dashed transparent;
  background: transparent;
  color: inherit;
  font: inherit;
  font-variant-numeric: tabular-nums;
  cursor: text;
}
.pct-edit-show:hover:not(:disabled),
.pct-edit-show:focus-visible { border-bottom-color: var(--accent); color: var(--ink-bright); outline: none; }
.pct-edit-show:disabled { cursor: default; }
.pct-edit-input {
  width: 3.2em;
  padding: 1px 3px;
  border: 1px solid var(--accent);
  background: rgba(2, 4, 6, 0.8);
  color: var(--ink-bright);
  font: inherit;
  font-variant-numeric: tabular-nums;
  text-align: right;
  -moz-appearance: textfield;
  appearance: textfield;
}
.pct-edit-input::-webkit-outer-spin-button,
.pct-edit-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.pct-edit-input:focus { outline: none; }
.pct-edit-unit { color: var(--ink-dim); }
.sysview-res-share .pct-edit { font-size: 14px; font-weight: 600; color: var(--ink-bright); }
.sysview-res-slider { grid-column: 1 / -1; width: 100%; margin: 0; accent-color: var(--accent); cursor: pointer; }
.sysview-res-slider:disabled { cursor: default; opacity: 0.5; }
.sysview-res-note { margin: 0; font-size: 11px; line-height: 1.45; color: var(--ink-dim); }
.sysview-res-buttons { display: grid; gap: 6px; }

.sysview-res-even,
.sysview-res-all {
  padding: 7px 12px;
  border: 1px solid var(--line-strong);
  background: rgba(10, 16, 22, 0.9);
  color: var(--ink);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}

.sysview-res-even { padding: 3px 9px; font-size: 10px; }

.sysview-res-even:hover:not(:disabled),
.sysview-res-even:focus-visible,
.sysview-res-all:hover:not(:disabled),
.sysview-res-all:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
  outline: none;
}

.sysview-res-even:disabled,
.sysview-res-all:disabled,
.sysview-res-apply:disabled { opacity: 0.45; cursor: default; }
.sysview-res-apply:disabled:hover { background: var(--accent-wash); color: var(--accent); }

/* Into one of your stations, from its panel. Accent-filled like the map
   card's way into a system. */
.sysview-enter {
  padding: 8px 10px;
  border: 1px solid var(--accent);
  background: var(--accent-wash);
  color: var(--accent);
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}

.sysview-enter:hover,
.sysview-enter:focus-visible {
  background: rgba(var(--accent-rgb), 0.2);
  color: var(--ink-bright);
  outline: none;
}

/* --- inside a station: its build mode --------------------------------- */

/* Over the system view (z 5), under the windows (z 20). The station sits in
   the middle in open space (.station-sky, a starfield image stationview.js
   makes once), its build slots round it, in a faint glow of the station's
   color. Nothing here moves. */
.stationview {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  background: var(--void);
}

/* Behind everything in the view, out of the grid: the stars, and the glow
   over them. */
.station-sky {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  pointer-events: none;
}
.station-sky::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 60% 55% at 50% 52%, rgba(var(--accent-rgb), 0.06), transparent 70%);
}

/* The stage's gradients and patterns, out of the grid and out of sight. */
.station-defs { position: absolute; width: 0; height: 0; overflow: hidden; pointer-events: none; }

.stationview[hidden] { display: none; }

.station-bar { display: flex; align-items: center; gap: 14px; padding: 12px; padding-right: calc(12px + var(--switch-room, 0px)); }

.station-back {
  padding: 7px 12px;
  white-space: nowrap;
  border: 1px solid var(--line-strong);
  background: rgba(10, 16, 22, 0.9);
  color: var(--ink);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}

.station-back:hover,
.station-back:focus-visible { border-color: var(--accent); color: var(--accent); outline: none; }

.station-title { display: flex; flex-direction: column; line-height: 1.2; }
/* The station's own upgrade, at the far end of its bar. */
.station-upgrade-open { margin-left: auto; white-space: nowrap; }
.station-name { font-size: 18px; font-weight: 600; letter-spacing: 0.05em; color: var(--ink-bright); }
.station-sub { font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-dim); }
/* A developer visiting someone else's station: handles keep their case. */
.station-visiting { text-transform: none; letter-spacing: 0.04em; color: #e9b44c; }

/* A size container: the station's smallest words hide when the stage is
   small (end of this file, "station view art"). */
/* Its one cell is exactly the stage, so the station's height:100% is the
   room there is and the art (a square viewBox) shrinks to fit it: with an
   auto row the picture was sized by its width alone and ran off the bottom
   at a high browser zoom, out of reach (Dev Panel note 2026-10-20: "when at
   higher zooms, reduce the size of the station"). */
.station-stage { display: grid; grid-template: minmax(0, 1fr) / minmax(0, 1fr); place-items: center; min-height: 0; padding: 8px 16px; container: station / size; }
.station-svg { width: min(100%, 800px); height: 100%; max-height: 800px; overflow: visible; }

/* The slots' orbit, faint, through the middle of every module. */
.station-orbit { fill: none; stroke: rgba(217, 173, 92, 0.12); stroke-dasharray: 2 9; }

.station-slot { cursor: pointer; outline: none; }

/* The line round a module, a little way out from its brass rim, in its
   state's tone (or, for an empty slot, the brackets round its space). Its
   color, not a mix with the accent's numbers, so a near-black accent still
   shows. The art and the rest of the tones are in "station view art" at
   the end of this file. */
.station-slot-frame {
  stroke: var(--tone);
  stroke-opacity: 0.9;
  stroke-width: 1.8;
  stroke-linejoin: round;
  transition: stroke 0.15s;
}

.station-slot-plus { stroke: var(--ink); stroke-width: 2.5; stroke-linecap: round; transition: stroke 0.15s; }
.station-slot text { fill: var(--ink-dim); font-family: var(--font); font-size: 11px; letter-spacing: 0.18em; }

.station-slot:hover .station-slot-frame,
.station-slot:focus-visible .station-slot-frame { stroke: var(--accent-ink); stroke-opacity: 1; }
.station-slot:hover .station-slot-plus,
.station-slot:focus-visible .station-slot-plus { stroke: var(--accent-ink); }
.station-slot:hover text.station-mod-name,
.station-slot:focus-visible text.station-mod-name { fill: var(--accent-ink); }

/* No filter here: a glow behind something that turns would be redrawn every
   frame. The halo (a gradient, under everything) brightens instead. */
.station-hub { cursor: pointer; outline: none; }

/* The core's edge, in the station's color: the brass is everyone's, this
   line says whose station it is. */
.station-hull { stroke: var(--accent-ink); stroke-width: 1.5; stroke-linejoin: round; transition: stroke-width 0.15s; }
.station-hub:hover .station-hull,
.station-hub:focus-visible .station-hull { stroke-width: 2.6; }
.station-hub-label { fill: var(--ink-dim); font-family: var(--font); font-size: 11px; letter-spacing: 0.22em; transition: fill 0.15s; }
.station-hub:hover .station-hub-label,
.station-hub:focus-visible .station-hub-label { fill: var(--accent-ink); }

.station-hint { margin: 0; padding: 0 12px 14px; font-size: 11px; letter-spacing: 0.08em; color: var(--ink-dim); text-align: center; }

/* A slot with a machine in it: a module docked to the station, its state in
   its band (a light and a word), what it makes in the middle, a progress bar
   and its name. Its tone says how it is doing: green working, yellow waiting
   for an input, the accent full (holding its limit) or done, grey off or
   with nothing to make. */
.station-slot {
  --tone: #8396a8;
  --tone-rgb: 131, 150, 168;
  --machine-ok: #5fd17a;
  --machine-wait: #e9c94c;
}
.station-slot.is-loading { cursor: progress; }
.station-slot.has-machine text { fill: var(--ink); font-size: 10px; }
.station-slot-glyph { color: var(--ink-dim); }
.station-slot-glyph.is-big { opacity: 0.55; }
.station-slot-dot { fill: var(--tone); stroke: var(--sv-brass-2); stroke-width: 0.9; }
.station-slot-track { fill: rgba(0, 0, 0, 0.6); }
/* Drawn full width and scaled from its left end (stationview.js syncBar). */
.station-slot-progress { fill: var(--tone); transform-box: fill-box; transform-origin: 0 50%; transform: scaleX(0); }

.station-slot.is-working { --tone: var(--machine-ok); --tone-rgb: 95, 209, 122; }
.station-slot.is-working .station-slot-glyph { color: var(--machine-ok); }
.station-slot.is-waiting { --tone: var(--machine-wait); --tone-rgb: 233, 201, 76; }
.station-slot.is-full { --tone: var(--accent-ink); --tone-rgb: var(--accent-rgb); }
.station-slot.is-off .station-mod { opacity: 0.55; }
.station-slot.is-idle .station-slot-frame { stroke-dasharray: 6 4; }

.station-slot.is-selected .station-slot-frame { stroke: var(--accent-ink); stroke-opacity: 1; stroke-width: 2.4; }
/* A soft glow of the same tone under that line: lit, where brass is not. */
.station-slot-glow { stroke: var(--tone); stroke-opacity: 0.22; stroke-width: 5; stroke-linejoin: round; transition: stroke 0.15s; }
.station-slot:hover .station-slot-glow,
.station-slot:focus-visible .station-slot-glow,
.station-slot.is-selected .station-slot-glow { stroke: var(--accent-ink); stroke-opacity: 0.32; }
.station-slot.is-selected text.station-mod-name { fill: var(--accent-ink); }

/* The panel beside the station for one slot: build in it, or set up the
   machine there. The station moves over to make room. */
.station-panel {
  position: absolute;
  top: 64px;
  right: 12px;
  bottom: 12px;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: min(340px, calc(100% - 24px));
  overflow-y: auto;
  padding: 12px 14px 14px;
  background: linear-gradient(180deg, rgba(20, 31, 42, 0.96), rgba(10, 16, 22, 0.96));
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
}

.station-panel[hidden] { display: none; }
.stationview.has-panel .station-stage { padding-right: 368px; }
/* Moving over for the panel glides, a moment after the click that opened
   it (stationview.js HOLD_STILL_MS), so a double-click lands where it began. */
.station-stage { transition: padding-right 0.22s ease; }
.stationview.has-panel .station-hint { padding-right: 368px; }

.station-panel-head { display: flex; align-items: flex-start; gap: 10px; }
.station-panel-glyph { display: grid; place-items: center; width: 38px; height: 38px; flex: none; border: 1px solid var(--line-strong); color: var(--accent); background: rgba(5, 8, 12, 0.6); }
.station-panel-title { display: grid; gap: 2px; min-width: 0; flex: 1; }
.station-panel-title h3 { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 16px; font-weight: 600; letter-spacing: 0.04em; color: var(--ink-bright); }
.station-panel-sub { font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-dim); }
.station-panel .win-note { margin: 0; }
.station-panel .win-error { margin: 0; }
.station-panel-back { align-self: flex-start; }

.station-builds { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.station-build {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 8px 12px;
  align-items: center;
  padding: 10px 12px;
  border: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.45);
}
.station-build .factory-icon { color: var(--accent); }
.station-build-text { display: grid; gap: 2px; min-width: 0; }
.station-build .win-button { grid-column: 1 / -1; justify-self: end; }

/* How the machine is doing, coloured like its slot. */
.station-status {
  --tone: var(--ink-dim);
  display: grid;
  gap: 2px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--tone);
  background: rgba(5, 8, 12, 0.5);
}
.station-status.is-working { --tone: #5fd17a; }
.station-status.is-waiting { --tone: #e9c94c; }
.station-status.is-full { --tone: var(--accent); }
.station-status-word { font-size: 11px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--tone); }
.station-status-text { font-size: 13px; line-height: 1.4; color: var(--ink); }

.station-progress { height: 4px; margin-top: -6px; background: rgba(0, 0, 0, 0.6); }
.station-progress i { display: block; width: 0; height: 100%; background: var(--ink-dim); }
.station-status.is-working + .station-progress i { background: #5fd17a; }
.station-status.is-waiting + .station-progress i { background: #e9c94c; }
.station-status.is-full + .station-progress i { background: var(--accent); }

.station-panel-section { display: grid; gap: 8px; padding-top: 10px; border-top: 1px solid var(--line); }
.station-panel-section h4 { margin: 0; font-size: 11px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); }
.station-panel-section > .win-button { justify-self: start; }

/* A recipe: inputs, an arrow, the output. */
.station-recipe-line { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.station-parts { display: flex; flex-wrap: wrap; gap: 6px; }
.station-part { display: inline-flex; align-items: center; gap: 3px; font-size: 12px; color: var(--ink); }
.station-part b { font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink-bright); }
.station-arrow { color: var(--ink-dim); }
.station-recipe-line.is-big { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 10px; }
.station-recipe-line.is-big .station-parts { display: grid; gap: 6px; }
.station-recipe-line.is-big .station-arrow { grid-column: 2; grid-row: 1; align-self: center; display: none; }
.station-recipe-line.is-big > .station-part {
  grid-column: 1 / -1;
  padding-top: 6px;
  border-top: 1px dashed var(--line-strong);
}
.station-recipe-line.is-big > .station-part::before { content: '→'; margin-right: 4px; color: var(--ink-dim); }
.station-part-text { display: grid; line-height: 1.2; margin-left: 4px; }
.station-part-name { font-size: 13px; color: var(--ink-bright); }
.station-part-text small { font-size: 11px; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.station-recipe-time { margin: 0; font-size: 12px; color: var(--ink-dim); }

.station-panel-hint {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 8px 10px;
  border: 1px solid rgba(233, 201, 76, 0.4);
  background: rgba(233, 201, 76, 0.06);
  font-size: 12px;
  line-height: 1.4;
  color: var(--ink);
}
.station-panel-hint[hidden] { display: none; }
.station-panel-hint .win-button { justify-self: start; }

.station-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 13px; color: var(--ink); }

.station-limit { display: grid; grid-template-columns: minmax(0, 1fr) 96px auto; align-items: center; gap: 8px; }
.station-limit-label { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink); cursor: pointer; }
.station-limit-label input { accent-color: var(--accent); }
.station-limit-input { width: 100%; }
.station-panel .flog-source-detail { margin: 0; }

.station-panel-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: auto; padding-top: 10px; border-top: 1px solid var(--line); }

/* The recipe list. */
.station-shelves { display: grid; gap: 12px; }
.station-shelf { display: grid; gap: 6px; }
.station-shelf .flog-shelf-name { margin: 0; }
.station-recipe {
  display: grid;
  gap: 6px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.45);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.station-recipe:hover:not(:disabled):not([aria-disabled="true"]),
.station-recipe:focus-visible { border-color: var(--accent); outline: none; background: rgba(var(--accent-rgb), 0.06); }
/* A bay's locked recipe cards are aria-disabled (they still take a
   right-click, for the item menu), the station's are disabled. */
.station-recipe:disabled,
.station-recipe[aria-disabled="true"] { opacity: 0.5; cursor: default; }
.station-recipe.is-current { border-color: rgba(var(--accent-rgb), 0.6); background: var(--accent-wash); }
.station-recipe-head { display: flex; align-items: center; gap: 8px; }
.station-recipe-name { font-size: 14px; color: var(--ink-bright); }
.station-recipe-secs { margin-left: auto; font-size: 11px; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.station-recipe-note { font-size: 11px; letter-spacing: 0.06em; color: var(--accent); }
.station-recipe.is-ready:not(.is-current) .station-recipe-note { color: #5fd17a; }
/* A crafted building's recipe still waiting on research. */
.station-recipe.is-locked { border-style: dashed; }
.station-recipe.is-locked:disabled,
.station-recipe.is-locked[aria-disabled="true"] { opacity: 0.65; }
.station-recipe-note.is-locked { color: var(--amber); letter-spacing: 0; }
.station-recipe-note.is-ready { color: #5fd17a; }
/* What it could make right now, first. */
.station-shelf.is-ready .flog-shelf-name { color: #5fd17a; }
.station-shelf.is-ready { padding-bottom: 12px; border-bottom: 1px solid var(--line); }

/* What a machine (or an upgrade) costs, against what this station holds. */
.station-cost { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin: 4px 0 0; font-size: 12px; color: var(--ink); }
.station-cost-label { font-size: 10px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }
.station-cost-item { display: inline-flex; align-items: center; gap: 3px; }
.station-cost-item b { font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink-bright); }
.station-cost-have { margin-left: 2px; font-size: 11px; color: #5fd17a; font-variant-numeric: tabular-nums; }
.station-cost-item.is-short .station-cost-have { color: var(--amber); }
.station-cost-from { flex-basis: 100%; font-size: 11px; color: var(--ink-dim); }
.station-build.is-locked { border-style: dashed; background: rgba(5, 8, 12, 0.3); }
.station-build.is-locked .factory-icon { color: var(--ink-dim); border-style: dashed; }
.station-build.is-locked .factory-blurb { color: var(--ink-dim); }

.station-upgrade-to { display: grid; gap: 2px; margin: 0; font-size: 12px; line-height: 1.4; color: var(--ink-dim); }
.station-upgrade-to b { font-size: 13px; font-weight: 600; color: var(--ink-bright); }
.station-upgrade-buttons,
.station-row-buttons { display: flex; flex-wrap: wrap; justify-content: flex-start; gap: 8px; }
.station-upgrade-buttons { justify-content: flex-end; }

/* A lab whose project is done, and one step of research as an output. */
.station-status.is-done { --tone: var(--accent); }
.station-status.is-done + .station-progress i { background: var(--accent); }
.station-slot.is-done { --tone: var(--accent-ink); --tone-rgb: var(--accent-rgb); }
.station-part.is-step svg { color: var(--accent); }

/* Research: progress on a project, and the list a lab picks from. */
.research-now { display: grid; gap: 4px; }
.research-now-name { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 15px; font-weight: 600; color: var(--ink-bright); }
.research-now-unlocks { margin: 0; font-size: 12px; color: var(--ink-dim); }
.research-now-steps { display: grid; gap: 1px; margin: 0; font-size: 12px; color: var(--ink); font-variant-numeric: tabular-nums; }
.research-now-steps small { font-size: 11px; color: var(--ink-dim); }
.research-bar { height: 6px; border: 1px solid var(--line); background: rgba(0, 0, 0, 0.6); }
.research-bar i { display: block; width: 0; height: 100%; background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.6), var(--accent)); transition: width 0.6s var(--ease); }
.research-chip {
  padding: 0 6px;
  border: 1px solid rgba(var(--accent-rgb), 0.5);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  line-height: 16px;
  text-transform: uppercase;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.research-chip:empty { display: none; }
.research-pick .station-recipe-secs { white-space: nowrap; }
.research-chip.is-done { border-color: rgba(95, 209, 122, 0.55); color: #5fd17a; }
.research-chip.is-locked { border-color: rgba(224, 168, 60, 0.5); color: var(--amber); }
.research-pick-glyph { display: grid; color: var(--accent); }
.research-pick.is-done .research-pick-glyph { color: #5fd17a; }
.research-pick.is-locked .research-pick-glyph { color: var(--ink-dim); }
.research-pick.is-locked .station-recipe-note { color: var(--amber); }
.research-pick.is-done .station-recipe-note { color: #5fd17a; }

/* On a phone the panel is a sheet across the bottom, under the station. */
@media (max-width: 720px) {
  .station-panel { top: auto; left: 12px; width: auto; max-height: 58%; }
  .stationview.has-panel .station-stage,
  .stationview.has-panel .station-hint { padding-right: 16px; }
  .stationview.has-panel .station-hint { display: none; }
  .stationview.has-panel .station-stage { align-items: start; }
  .stationview.has-panel .station-svg { max-height: 42vh; }
  .station-bar { flex-wrap: wrap; row-gap: 8px; }
  .station-upgrade-open { padding: 6px 10px; font-size: 10px; }
}

/* The card's way in. Accent-filled, since it is the main thing to do with a
   system once you have found one. */
.map-card-enter {
  width: 100%;
  margin-bottom: 6px;
  padding: 8px 10px;
  border: 1px solid var(--accent);
  background: var(--accent-wash);
  color: var(--accent);
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}

.map-card-enter:hover,
.map-card-enter:focus-visible {
  background: rgba(var(--accent-rgb), 0.2);
  color: var(--ink-bright);
  outline: none;
}

/* On a phone the panel moves to the bottom, over the map's readout row, so
   the system stays visible above it; folded, it is one line. */
@media (max-width: 640px) {
  .sysview-panel {
    top: auto;
    left: 12px;
    width: auto;
    bottom: 58px;
    max-height: 42%;
  }

  .sysview-panel.is-folded { bottom: 58px; }
  .sysview-preview { width: 96px; height: 96px; float: right; margin: 0 0 6px 10px; }
  .sysview-fold { width: 40px; height: 40px; }
}

/* 12-hour sidebar clock: AM/PM small, under the time (neocom.js, tick). */
.neocom-clock-value[data-period]:not([data-period=""])::after {
  content: attr(data-period);
  display: block;
  font-size: 9px;
  letter-spacing: 0.1em;
  opacity: 0.75;
}


/* ---- Background: a saved map view behind the closed map (background.js).
   A plain CSS background, so there is nothing to click or zoom. It sits on
   its own layer under everything else so Brightness can filter it alone. */
.viewport.is-map-closed.has-background::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: linear-gradient(rgba(3, 6, 10, 0.25), rgba(3, 6, 10, 0.25)), var(--map-background);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  pointer-events: none;
}

.viewport.has-background .map-closed-hint { display: none; }

.settings-bg { padding-top: 12px; border-top: 1px solid var(--line); }

.settings-bg-preview {
  display: block;
  width: 100%;
  max-width: 360px;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border: 1px solid var(--line-strong);
  background: var(--void);
}

.settings-bg-preview.is-empty {
  display: grid;
  place-items: center;
  font-size: 12px;
  color: var(--ink-dim);
}
/* A photo dragged over the preview: drop it to use it. */
.settings-bg-preview.is-drop { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.35); }

/* ---- Dev Panel: categories across the top; test checklists per request */

.dev { display: flex; flex-direction: column; gap: 12px; }

/* Production (ui/production.js), after Factorio's production statistics:
   ranges across the top, then Production and Consumption side by side, each
   a chart over a list of items with a box that puts its line on. Series wear
   the data palette's eight slots (validated on this background); text never
   does: an item's color is its box. */
.prod { display: flex; flex-direction: column; gap: 10px; height: 100%; min-height: 0; }
.prod-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; }
.prod-ranges { display: inline-flex; border: 1px solid var(--line-strong); }
.prod-range {
  padding: 5px 12px;
  border: 0;
  border-right: 1px solid var(--line);
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.06em;
  cursor: pointer;
}
.prod-range:last-child { border-right: 0; }
.prod-range[aria-checked="true"] { background: var(--accent-wash); color: var(--ink-bright); box-shadow: inset 0 -2px 0 var(--accent); }
.prod-range:hover,
.prod-range:focus-visible { color: var(--ink-bright); outline: none; }
.prod-status { margin: 0; font-size: 12px; }
.prod-panels { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; flex: 1 1 auto; min-height: 0; }
.prod-panel { display: flex; flex-direction: column; gap: 6px; min-width: 0; min-height: 0; padding: 10px 12px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.35); }
.prod-panel-head { display: flex; align-items: baseline; gap: 8px; }
.prod-title { margin: 0; font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-bright); }
.prod-unit { font-size: 11px; color: var(--ink-dim); }
.prod-plot { position: relative; min-height: 198px; }
.prod-plot-empty { margin: 0; padding: 70px 0; text-align: center; }
.prod-line { transition: opacity 0.12s, stroke-width 0.12s; }
.prod-line.is-dim { opacity: 0.18; }
/* The line nearest the pointer, after Factorio. */
.prod-line.is-near { stroke-width: 3.4; }
.devs-tip-row.is-near { color: var(--ink-bright); font-weight: 600; }
.prod-list { list-style: none; margin: 0; padding: 0; overflow: auto; flex: 1 1 auto; min-height: 80px; border-top: 1px solid var(--line); }
.prod-empty { margin: 10px 0; }
.prod-row {
  display: grid;
  grid-template-columns: 14px 20px minmax(0, 1fr) minmax(40px, 0.8fr) auto;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 4px 4px;
  border: 0;
  border-bottom: 1px solid rgba(150, 196, 224, 0.06);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}
.prod-row:hover,
.prod-row:focus-visible { background: var(--accent-wash); outline: none; }
.prod-row.is-dim { opacity: 0.55; }
.prod-row.is-near { background: var(--accent-wash); opacity: 1; }
.prod-box { width: 12px; height: 12px; border: 1px solid var(--line-strong); border-radius: 2px; }
.prod-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prod-meter { display: block; height: 6px; background: rgba(150, 196, 224, 0.08); border-radius: 3px; overflow: hidden; }
.prod-meter > span { display: block; height: 100%; background: rgba(150, 196, 224, 0.45); border-radius: 3px; }
.prod-total { font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink-bright); text-align: right; min-width: 3.5em; }
@media (max-width: 720px) {
  .prod-panels { grid-template-columns: minmax(0, 1fr); }
  .prod-list { max-height: 260px; }
}

/* Dev Panel → Commands (ui/devcommands.js): Claude's slash commands. */
.devc { display: flex; flex-direction: column; gap: 10px; }
.devc-intro { margin: 0; }
.devc-list { display: flex; flex-direction: column; gap: 10px; }
.devc-card { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; border: 1px solid var(--line); border-left: 2px solid var(--accent); background: rgba(5, 8, 12, 0.35); }
.devc-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.devc-name { font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; font-size: 17px; font-weight: 600; color: var(--ink-bright); }
.devc-copy { padding: 3px 9px; font-size: 11px; }
.devc-effect { padding: 2px 8px; border: 1px solid var(--line-strong); border-radius: 999px; font-size: 11px; color: var(--ink-dim); }
.devc-effect.is-read { border-color: rgba(95, 209, 122, 0.5); color: #5fd17a; }
.devc-effect.is-test { border-color: rgba(242, 183, 5, 0.6); color: #f2b705; }
.devc-effect.is-deploys { border-color: rgba(224, 96, 60, 0.6); color: #e8805e; }
.devc-added { font-size: 11px; color: var(--ink-dim); }
.devc-summary { margin: 0; font-size: 14px; color: var(--ink-bright); }
.devc-does { margin: 0; padding-left: 18px; display: grid; gap: 3px; font-size: 13px; line-height: 1.45; color: var(--ink); }
.devc-examples { display: grid; gap: 4px; padding-top: 8px; border-top: 1px solid var(--line); }
.devc-examples-head { margin: 0 0 2px; font-size: 11px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); }
.devc-example { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; font-size: 13px; color: var(--ink-dim); }
.devc-typed {
  padding: 1px 7px;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.6);
  color: var(--ink-bright);
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 12px;
  cursor: copy;
}
.devc-typed:hover,
.devc-typed:focus-visible { border-color: var(--accent); outline: none; }

/* Dev Panel → Notes (ui/devnotes.js): a screenshot and a description each. */
.devn { display: flex; flex-direction: column; gap: 12px; }
.devn-new { display: flex; flex-direction: column; gap: 8px; padding: 12px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.35); }
.devn-new .devs-heading { margin: 0; }
.devn-body { width: 100%; min-height: 64px; resize: vertical; }
.devn-new-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.devn-new-foot .win-note { margin: 0; font-size: 12px; }
.devn-bar { display: flex; align-items: center; gap: 8px; }
.devn-list { display: flex; flex-direction: column; gap: 8px; }
.devn-note { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; border: 1px solid var(--line); border-left: 2px solid var(--accent); background: rgba(5, 8, 12, 0.35); }
.devn-note.is-done { border-left-color: #5fd17a; opacity: 0.72; }
/* On the radar: kept for later, not to be built yet. Amber, like a hold. */
.devn-note.is-radar { border-left-color: #e9b44c; border-left-style: dashed; }
.devn-radar {
  padding: 3px 9px;
  border: 1px dashed var(--line-strong);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.04em;
  cursor: pointer;
}
.devn-radar:hover,
.devn-radar:focus-visible { border-color: #e9b44c; color: var(--ink-bright); outline: none; }
.devn-radar.is-on { border-style: solid; border-color: #e9b44c; background: rgba(233, 180, 76, 0.14); color: #e9b44c; }
.devn-radar-pick { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink); cursor: pointer; }
.devn-radar-note { margin: 0; font-size: 12px; }
/* In progress: a /devnotes run has it. The accent's teal, solid and lit, so
   it reads as "someone's on it" beside the radar's amber hold. */
.devn-note.is-progress { border-left-color: var(--accent); border-left-width: 3px; background: rgba(79, 182, 217, 0.06); }
.devn-progress-tag {
  padding: 2px 8px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: rgba(79, 182, 217, 0.12);
  color: var(--ink-bright);
  font-size: 11px;
  letter-spacing: 0.04em;
}
/* A done note flagged with a problem: back on To do, in red, first. Fixed,
   the flag stays as a quiet line of history. */
.devn-note.is-flagged { border-left-color: #f0907a; }
.devn-flag { display: flex; flex-direction: column; gap: 4px; padding: 8px 10px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.4); }
.devn-flag.is-open { border-color: rgba(240, 144, 122, 0.6); background: rgba(240, 144, 122, 0.08); }
.devn-flag-head { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); }
.devn-flag.is-open .devn-flag-head { color: #f0907a; }
.devn-flag-text { margin: 0; font-size: 13px; line-height: 1.5; white-space: pre-wrap; color: var(--ink); }
.devn-flag-clear { align-self: flex-start; font-size: 12px; }
.devn-flag-form { display: flex; flex-direction: column; gap: 6px; }
.devn-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.devn-head .win-button { padding: 4px 9px; font-size: 11px; }
.devn-meta { font-size: 12px; color: var(--ink-dim); }
.devn-text { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.45; color: var(--ink); }

/* Dev Panel → Server (ui/devserver.js): tiles of numbers now, meters for
   shares, then line charts. Series wear the data palette's first two slots
   (#3987e5, #d95926, checked against this background); text never does. */
.devs { display: flex; flex-direction: column; gap: 12px; }
.devs-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; }
.devs-status { margin: 0; font-size: 12px; }
.devs-body { display: flex; flex-direction: column; gap: 10px; }
.devs-body[hidden] { display: none; }
.devs-heading { margin: 4px 0 0; font-size: 11px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); }
.devs-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(138px, 1fr)); gap: 8px; }
.devs-tile {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.35);
}
.devs-tile-label { font-size: 11px; letter-spacing: 0.08em; color: var(--ink-dim); }
.devs-tile-value { font-size: 22px; font-weight: 600; line-height: 1.1; color: var(--ink-bright); overflow-wrap: anywhere; }
.devs-tile-sub { font-size: 11px; line-height: 1.35; color: var(--ink-dim); overflow-wrap: anywhere; }
.devs-tile.is-high .devs-tile-sub { color: var(--amber); }
.devs-tile.is-critical .devs-tile-sub { color: #f0907a; }
/* A meter: the track is a lighter step of the fill's own color. */
.devs-meter { display: block; height: 4px; border-radius: 2px; background: var(--accent-wash); overflow: hidden; }
.devs-meter[hidden] { display: none; }
.devs-meter-fill { display: block; height: 100%; border-radius: 2px; background: var(--accent); }
.devs-tile.is-high .devs-meter { background: rgba(224, 168, 60, 0.16); }
.devs-tile.is-high .devs-meter-fill { background: var(--amber); }
.devs-tile.is-critical .devs-meter { background: rgba(210, 86, 63, 0.18); }
.devs-tile.is-critical .devs-meter-fill { background: var(--danger); }

.devs-chart { margin: 4px 0 0; padding: 10px 12px 6px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.35); }
.devs-chart-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; margin-bottom: 6px; }
.devs-chart-title { font-size: 13px; font-weight: 600; letter-spacing: 0.04em; color: var(--ink-bright); }
.devs-legend { display: inline-flex; flex-wrap: wrap; gap: 4px 12px; font-size: 12px; color: var(--ink); }
.devs-key { display: inline-flex; align-items: center; gap: 6px; }
.devs-key-line { display: inline-block; width: 14px; height: 2px; border-radius: 1px; flex: none; }
.devs-table-toggle { padding: 2px 8px; font-size: 11px; }
.devs-table-toggle[aria-pressed="true"] { color: var(--ink-bright); border-bottom-color: var(--accent); }
.devs-plot { position: relative; min-height: 60px; }
.devs-svg { display: block; overflow: visible; outline: none; }
.devs-svg:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
.devs-grid { stroke: rgba(150, 196, 224, 0.12); stroke-width: 1; shape-rendering: crispEdges; }
.devs-axis { font-size: 10px; fill: var(--ink-dim); font-variant-numeric: tabular-nums; }
.devs-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.devs-dot { stroke: #0f1820; stroke-width: 2; }
.devs-cross { stroke: rgba(234, 244, 251, 0.45); stroke-width: 1; shape-rendering: crispEdges; }
.devs-hit { fill: transparent; cursor: crosshair; }
.devs-tip {
  position: absolute;
  z-index: 2;
  display: grid;
  gap: 3px;
  min-width: 120px;
  padding: 7px 10px;
  border: 1px solid var(--line-strong);
  background: rgba(8, 13, 18, 0.95);
  pointer-events: none;
  font-size: 12px;
  white-space: nowrap;
}
.devs-tip[hidden] { display: none; }
.devs-tip-time { font-size: 11px; color: var(--ink-dim); }
.devs-tip-row { display: flex; align-items: center; gap: 7px; color: var(--ink-dim); }
.devs-tip-row b { color: var(--ink-bright); font-weight: 600; font-variant-numeric: tabular-nums; }
.devs-empty { margin: 8px 0; }
.devs-table-wrap { max-height: 260px; overflow: auto; }
.devs-table { width: 100%; border-collapse: collapse; font-size: 12px; font-variant-numeric: tabular-nums; }
.devs-table th { position: sticky; top: 0; padding: 4px 8px; background: #0d151d; color: var(--ink-dim); font-weight: 600; text-align: right; }
.devs-table td { padding: 3px 8px; border-top: 1px solid var(--line); color: var(--ink); text-align: right; }
.devs-table th:first-child,
.devs-table td:first-child { text-align: left; }
.dev-tabs { display: flex; flex-wrap: wrap; gap: 4px; border-bottom: 1px solid var(--line); }

.dev-tab {
  margin-bottom: -1px;
  padding: 7px 14px;
  border: 1px solid transparent;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
}

.dev-tab[aria-selected="true"] { border-color: var(--line); border-bottom-color: var(--accent); background: var(--accent-wash); color: var(--ink-bright); }
.dev-tab:hover,
.dev-tab:focus-visible { color: var(--ink-bright); outline: none; }

.dev-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; }

.dev-list {
  display: grid;
  gap: 10px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--amber);
  background: rgba(150, 196, 224, 0.03);
}

.dev-list.is-done { border-left-color: #7fd4a4; }
.dev-list-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; }
.dev-date { font-size: 12px; color: var(--ink-dim); }
.dev-request,
.dev-setup { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink); }
.dev-setup { color: var(--ink-dim); }

.dev-label {
  margin-right: 8px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.dev-progress { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.dev-meter { display: flex; flex: 1 1 160px; height: 6px; overflow: hidden; background: rgba(150, 196, 224, 0.1); }
.dev-meter-pass { background: #7fd4a4; }
.dev-meter-fail { background: var(--danger); }
.dev-progress-text { font-size: 12px; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.dev-progress .notes-toggle { margin-left: 0; }
.dev-reset.is-armed { border-color: var(--danger); color: #ffd9cf; background: rgba(210, 86, 63, 0.14); }
.dev-reset:disabled { opacity: 0.4; cursor: default; }

.dev-items { margin: 0; padding: 0; list-style: none; display: grid; gap: 2px; }

.dev-item {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) 26px;
  column-gap: 10px;
  align-items: start;
  padding: 6px 4px 6px 6px;
  border-left: 2px solid transparent;
  font-size: 13px;
  line-height: 1.45;
}

.dev-item:hover { background: rgba(150, 196, 224, 0.04); }
.dev-item.is-pass .dev-item-text { color: var(--ink-dim); }
.dev-item.is-fail { border-left-color: var(--danger); background: rgba(210, 86, 63, 0.07); }
.dev-item-text { display: grid; gap: 2px; min-width: 0; color: var(--ink); }
.dev-hint { font-size: 12px; color: var(--ink-dim); }

.dev-check {
  position: relative;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  padding: 0;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.6);
  cursor: pointer;
}

.dev-check:hover,
.dev-check:focus-visible { border-color: var(--accent); outline: none; }
.dev-check[aria-checked="true"] { border-color: #7fd4a4; background: #7fd4a4; }
.dev-check[aria-checked="true"]::after {
  content: "";
  position: absolute;
  left: 5px;
  top: 1px;
  width: 5px;
  height: 10px;
  border: solid var(--void);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.dev-flag {
  width: 24px;
  height: 22px;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  opacity: 0.55;
}

.dev-item:hover .dev-flag,
.dev-flag:focus-visible { opacity: 1; }
.dev-flag:hover,
.dev-flag:focus-visible { color: #f0907a; border-color: rgba(210, 86, 63, 0.5); outline: none; }
.dev-flag[aria-pressed="true"] { opacity: 1; color: #ffd9cf; border-color: var(--danger); background: rgba(210, 86, 63, 0.25); }
.dev-note { grid-column: 2 / 4; margin-top: 6px; font-size: 13px; }

/* ---- Dev Panel, Players: every pilot, and everything about one -------- */

.devp { display: flex; flex-direction: column; gap: 12px; container-type: inline-size; }
.devp-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.devp-search { flex: 1 1 220px; min-width: 0; }
.devp-count { font-size: 12px; color: var(--ink-dim); white-space: nowrap; }

.devp-rows { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.devp-row {
  display: grid;
  gap: 4px;
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.45);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.devp-row:hover,
.devp-row:focus-visible { border-left-color: var(--accent); background: rgba(150, 196, 224, 0.06); outline: none; }
.devp-row-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; min-width: 0; }
.devp-name { font-size: 15px; color: var(--ink-bright); }
.devp-handle { font-size: 12px; color: var(--ink-dim); }
.devp-row-facts { display: flex; flex-wrap: wrap; gap: 2px 14px; font-size: 12px; color: var(--ink-dim); }
.devp-row-facts b { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }

.devp-badge {
  padding: 0 5px;
  border: 1px solid var(--amber);
  color: var(--amber);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.12em;
  line-height: 15px;
  text-transform: uppercase;
}

/* Online now: a green dot; otherwise when they were last about. */
.devp-seen { margin-left: auto; font-size: 12px; color: var(--ink-dim); white-space: nowrap; }
.devp-seen.is-online { color: #5fd17a; }
/* The game open, nothing done lately: a hollow amber dot. */
.devp-seen.is-away { color: #e9b44c; }
.devp-seen.is-away::before {
  content: '';
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-right: 6px;
  border: 1px solid #e9b44c;
  border-radius: 50%;
  vertical-align: 1px;
}
.devp-seen.is-online::before {
  content: '';
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 6px;
  border-radius: 50%;
  background: #5fd17a;
  box-shadow: 0 0 6px rgba(95, 209, 122, 0.8);
  vertical-align: 1px;
}

.devp-top { display: flex; align-items: center; gap: 8px; }
.devp-head { display: grid; gap: 4px; padding-bottom: 10px; border-bottom: 1px solid var(--line); }
.devp-head-name { display: flex; align-items: center; gap: 10px; min-width: 0; }
.devp-head-name .devp-name { font-size: 20px; font-weight: 600; }
.devp-head-sub { display: flex; flex-wrap: wrap; gap: 2px 14px; margin: 0; font-size: 12px; color: var(--ink-dim); }
.devp-head-sub .devp-seen { margin-left: 0; }

.devp-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
.devp-tile { display: grid; gap: 2px; padding: 8px 10px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.45); }
.devp-tile-label { font-size: 10px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }
.devp-tile-value { font-size: 15px; font-weight: 600; color: var(--ink-bright); font-variant-numeric: tabular-nums; white-space: nowrap; }
.devp-tile-sub { font-size: 11px; color: var(--ink-dim); }

.devp-body { display: grid; gap: 14px; }
.devp-section { display: grid; gap: 8px; }
.devp-h { display: flex; align-items: baseline; gap: 10px; margin: 0; font-size: 11px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); }
.devp-h-sub { letter-spacing: 0.04em; text-transform: none; font-size: 12px; font-weight: 400; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.devp-note { margin: 0; font-size: 12px; line-height: 1.4; color: var(--ink-dim); }
.devp-tag { padding: 0 6px; border: 1px solid var(--line-strong); font-size: 11px; color: var(--ink); white-space: nowrap; }
.devp-tag.is-accent { border-color: rgba(var(--accent-rgb), 0.6); color: var(--accent); }

/* The activity feed, and lists like it. */
.devp-feed { display: grid; margin: 0; padding: 0; list-style: none; }
.devp-event {
  display: grid;
  grid-template-columns: 74px minmax(0, 1fr) auto;
  grid-template-areas: "kind text side";
  align-items: baseline;
  gap: 4px 10px;
  padding: 6px 4px;
  border-bottom: 1px solid var(--line);
  font-size: 13px;
  color: var(--ink);
}
.devp-event:last-child { border-bottom: 0; }
.devp-event.is-unread .devp-event-text { color: var(--ink-bright); font-weight: 600; }
.devp-event-text { grid-area: text; display: grid; min-width: 0; overflow-wrap: anywhere; }
.devp-side { grid-area: side; display: flex; align-items: baseline; justify-content: flex-end; gap: 10px; }
.devp-event-text small { font-size: 12px; color: var(--ink-dim); }
.devp-kind { grid-area: kind; font-size: 10px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-dim); }
.devp-event.is-build .devp-kind { color: var(--accent); }
.devp-event.is-money .devp-kind { color: #5fd17a; }
.devp-event.is-market .devp-kind { color: var(--amber); }
.devp-event.is-corporation .devp-kind { color: var(--t3); }
.devp-when { font-size: 11px; color: var(--ink-dim); white-space: nowrap; }
.devp-amount { color: #5fd17a; font-variant-numeric: tabular-nums; white-space: nowrap; }
.devp-amount.is-out { color: #f0907a; }

/* Bank accounts and their statements. */
.devp-account { display: grid; gap: 6px; padding: 10px 12px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.45); }
.devp-account.is-closed { opacity: 0.6; }
.devp-account-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.devp-account-name { font-size: 14px; color: var(--ink-bright); }
.devp-balance { font-size: 15px; color: var(--ink-bright); font-variant-numeric: tabular-nums; }
.devp-ledger { width: 100%; border-collapse: collapse; font-size: 12px; }
.devp-ledger td { padding: 5px 4px; border-top: 1px solid var(--line); vertical-align: top; color: var(--ink); }
.devp-ledger td:nth-child(2) { width: 100%; }
.devp-ledger td small { display: block; color: var(--ink-dim); }
.devp-ledger .devp-amount,
.devp-running { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.devp-running { color: var(--ink-dim); }

/* Stations, miners, listings. */
.devp-card { display: grid; gap: 8px; padding: 10px 12px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.45); }
.devp-card-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; color: var(--accent); }
.devp-card-title { font-size: 14px; color: var(--ink-bright); }
.devp-chips { display: flex; flex-wrap: wrap; gap: 5px; margin: 0; padding: 0; list-style: none; }
.devp-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px 2px 4px;
  border: 1px solid var(--line);
  background: rgba(2, 4, 6, 0.5);
  font-size: 12px;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.devp-chip.is-machine svg:not(.item-icon) { color: var(--ink-dim); }
.devp-chip.is-working { border-color: rgba(95, 209, 122, 0.5); }
.devp-chip.is-working svg:not(.item-icon) { color: #5fd17a; }
.devp-chip.is-waiting { border-color: rgba(233, 201, 76, 0.55); }
.devp-chip.is-full { border-color: rgba(var(--accent-rgb), 0.55); }
.devp-chip.is-off,
.devp-chip.is-idle { opacity: 0.65; }
.devp-list { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.devp-line { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; padding: 6px 0; border-bottom: 1px solid var(--line); color: var(--accent); }
.devp-line:last-child { border-bottom: 0; }
.devp-line-main { font-size: 13px; color: var(--ink-bright); }
.devp-line .devp-chips { flex-basis: 100%; padding-left: 26px; }

.devp-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 16px; margin: 0; font-size: 13px; }
.devp-facts dt { color: var(--ink-dim); }
.devp-facts dd { margin: 0; color: var(--ink); overflow-wrap: anywhere; }

.devp-private { display: grid; gap: 8px; padding: 10px 12px; border: 1px dashed var(--line-strong); }
.devp-private > .win-button { justify-self: start; }
.devp-private.is-open { border-style: solid; border-color: rgba(224, 168, 60, 0.5); }

/* Narrow: what kind and when on one line, what happened under them. */
@container (max-width: 480px) {
  .devp-event { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "kind side" "text text"; }
}

/* ------------------------------------------------------------------ looks --
 * Names in their chosen font and colour, with an icon beside them (look.js,
 * src/looks.js). What a look leaves out follows the viewer's defaults, which
 * main.js puts on <html>: has-name-font / has-name-color with --name-font,
 * --name-tt, --name-ls, --name-color, and --icon-color (unset = match the
 * name). Chosen values are inline, so they always win.
 */

.look-label { display: inline-flex; align-items: center; gap: 0.4em; min-width: 0; max-width: 100%; vertical-align: middle; }
.look-label > .look-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.look-icon { flex: 0 0 auto; color: var(--look-icon, var(--icon-color, var(--look-name, var(--name-color, currentColor)))); }
.look-icon.is-match { color: var(--look-name, var(--name-color, currentColor)); }

:root.has-name-font .look-name:not(.has-font) {
  font-family: var(--name-font);
  text-transform: var(--name-tt);
  letter-spacing: var(--name-ls);
}
:root.has-name-color .look-name:not(.has-color):not(.is-plain) { color: var(--name-color); }

/* The editor: one popover for everything renamable. */
.look-pop {
  position: fixed;
  z-index: 70; /* over windows, toasts and the pilot panel; under the right-click menu */
  display: grid;
  gap: 10px;
  width: min(440px, calc(100vw - 16px));
  max-height: calc(100vh - 16px);
  overflow: auto;
  padding: 12px 14px 14px;
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  background: #0b131b;
  box-shadow: 0 18px 40px -8px rgba(0, 0, 0, 0.85);
  color: var(--ink);
}
.look-pop.is-sheet { left: 8px; right: 8px; bottom: 8px; top: auto; width: auto; max-height: 80vh; }
.look-pop-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.look-pop-head h4 { margin: 0; font-size: 11px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); }
.look-preview {
  display: flex;
  align-items: center;
  min-height: 40px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  background: rgba(2, 4, 6, 0.6);
  font-size: 17px;
  color: var(--ink-bright);
}
.look-field { gap: 6px; }
.look-swatches { display: flex; flex-wrap: wrap; gap: 5px; }
.look-swatch {
  position: relative;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid var(--line);
  background: rgba(150, 196, 224, 0.03);
  color: var(--ink);
  cursor: pointer;
}
.look-swatch:hover { border-color: var(--line-strong); color: var(--ink-bright); }
.look-swatch[aria-checked="true"] { border-color: var(--accent); background: var(--accent-wash); color: var(--ink-bright); }
.look-swatch:focus-visible { outline: 1px solid var(--accent); }
.look-swatches > .look-swatch.is-default { width: auto; padding: 0 8px; font: inherit; font-size: 11px; letter-spacing: 0.06em; }
.look-icons .look-swatch-icon.is-default { width: 30px; padding: 0; }
.look-icons .look-swatch-icon.is-default::before {
  content: "";
  position: absolute;
  top: 2px;
  right: 2px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
}
.look-none { font-size: 15px; color: var(--ink-dim); }
/* Icons: a search box over every icon, grouped under headings; searching
   shows the matches in one run. The list scrolls on its own. */
.look-icon-picker { display: grid; gap: 6px; min-width: 0; }
.look-icon-searchrow { display: flex; align-items: center; gap: 8px; }
.look-icon-search { flex: 1; min-width: 0; }
.look-icon-count { flex: none; font-size: 11px; color: var(--ink-dim); }
.look-icon-scroll {
  display: grid;
  align-content: start;
  gap: 8px;
  max-height: 212px;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 2px 4px 2px 2px;
}
.look-icon-heading {
  margin: 2px 0 4px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.look-icon-empty { margin: 4px 0; }
/* Any color, on the wheel (more in "Color wheel everywhere" at the end). */
.look-colors { display: grid; gap: 8px; min-width: 0; }
.look-wheel {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  padding: 10px;
  border: 1px solid var(--line);
  background: rgba(2, 4, 6, 0.55);
}
.look-wheel-pad {
  position: relative;
  flex: none;
  border-radius: 50%;
  cursor: crosshair;
  touch-action: none;
}
.look-wheel-pad:focus-visible { outline: 1px solid var(--accent); outline-offset: 3px; }
.look-wheel-disc { display: block; border-radius: 50%; }
.look-wheel-marker {
  position: absolute;
  width: 14px;
  height: 14px;
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.7), 0 2px 6px rgba(0, 0, 0, 0.6);
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.look-wheel-side { display: grid; gap: 10px; flex: 1; min-width: 140px; }
.look-wheel-label { display: grid; gap: 5px; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-dim); }
.look-wheel-bright {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 12px;
  margin: 0;
  border: 1px solid var(--line);
  background: linear-gradient(90deg, #000, var(--wheel-hue, #fff));
  cursor: pointer;
}
.look-wheel-bright::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 10px;
  height: 18px;
  border: 2px solid #fff;
  background: transparent;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.7);
}
.look-wheel-bright::-moz-range-thumb {
  width: 8px;
  height: 16px;
  border: 2px solid #fff;
  border-radius: 0;
  background: transparent;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.7);
}
.look-wheel-hexrow { display: flex; align-items: center; gap: 8px; }
.look-wheel-chip { flex: none; width: 26px; height: 26px; border: 1px solid var(--line-strong); }
.look-wheel-hex { flex: 1; min-width: 0; font-family: ui-monospace, Menlo, Consolas, monospace; text-transform: lowercase; letter-spacing: 0.04em; }
.look-fonts { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 6px; }
.look-font {
  display: grid;
  gap: 2px;
  padding: 6px 8px;
  border: 1px solid var(--line);
  background: rgba(150, 196, 224, 0.03);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.look-font:hover { border-color: var(--line-strong); }
.look-font[aria-checked="true"] { border-color: var(--accent); background: var(--accent-wash); }
.look-font:focus-visible { outline: 1px solid var(--accent); }
.look-font-sample { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 15px; color: var(--ink-bright); }
.look-font-label { font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-dim); }

/* Settings: each font shown in itself. */
.settings-choice-option[style*="font-family"] { font-size: 14px; }

/* The pin in a window's bar (windows.js): to the top, to the bottom, forced
   (can't be moved or resized), or in the background. */
.win-pin {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  opacity: 0.7;
}
.win-pin:hover,
.win-pin:focus-visible { color: var(--ink-bright); border-color: var(--line-strong); outline: none; opacity: 1; }
.win-pin svg { transition: transform 150ms var(--ease); }
.win[data-pin="top"] .win-pin { color: var(--accent); opacity: 1; }
.win[data-pin="top"] .win-pin svg { transform: rotate(-30deg); }
/* Pinned to the back: the pin turned point up, and the window a touch quieter. */
.win[data-pin="back"] .win-pin { color: var(--amber); opacity: 1; }
.win[data-pin="back"] .win-pin svg { transform: rotate(180deg); }
.win[data-pin="back"] { border-left-color: rgba(224, 168, 60, 0.45); }
.win[data-pin="top"] { border-left-color: var(--accent); }
.win[data-pin="top-lock"] .win-pin { color: var(--accent); opacity: 1; }
.win[data-pin="top-lock"] .win-pin svg { transform: rotate(-30deg); }
.win[data-pin="top-lock"] { border-left-color: var(--accent); }
.win[data-pin="back-lock"] .win-pin { color: var(--amber); opacity: 1; }
.win[data-pin="back-lock"] .win-pin svg { transform: rotate(180deg); }
.win[data-pin="back-lock"] { border-left-color: rgba(224, 168, 60, 0.45); }
/* Forced: a solid pin head, no resize grips, and a bar that doesn't drag. */
.win.is-locked .win-pin svg path:first-child { fill: currentColor; }
.win.is-locked .win-grip,
.win.is-still .win-grip { display: none; }
.win.is-locked .win-bar { cursor: default; }
/* In the background: part of the scenery. Only the pin takes the pointer. */
.win.is-still { pointer-events: none; box-shadow: none; border-left-color: var(--line); }
.win.is-still .win-pin { pointer-events: auto; color: var(--ink-dim); opacity: 1; }
.win.is-still .win-pin svg { transform: rotate(90deg); }
.win.is-still .win-close { visibility: hidden; }
.settings-name { align-items: center; }
.settings-name-value { font-size: 17px; color: var(--ink-bright); }
.corps-role-preview { font-size: 16px; }

/* ---- Market, after EVE's: a tree of items beside the book (market.js) */

/* A window whose panes scroll themselves rather than the window body. */
.win-body.is-flush { padding: 0; overflow: hidden; }

.mkt {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  container-type: inline-size;
  font-variant-numeric: tabular-nums;
}

.mkt-top {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  flex: 0 0 auto;
  padding: 6px 14px 0;
  border-bottom: 1px solid var(--line);
}

.mkt-tabs { display: flex; gap: 2px; }

.mkt-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-bottom: -1px;
  padding: 7px 14px 8px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.16em;
  line-height: 18px;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
}

.mkt-tab[aria-selected="true"] { color: var(--ink-bright); border-bottom-color: var(--accent); }
.mkt-tab:hover,
.mkt-tab:focus-visible { color: var(--ink-bright); outline: none; }

.mkt-tab-badge {
  min-width: 18px;
  padding: 0 5px;
  border: 1px solid rgba(var(--accent-rgb), 0.5);
  color: var(--accent);
  font-size: 10px;
  letter-spacing: 0.04em;
  line-height: 14px;
  text-align: center;
}

.mkt-tabs-note { margin-left: auto; padding-bottom: 9px; font-size: 12px; color: var(--ink-dim); white-space: nowrap; }

.mkt-body { display: flex; flex: 1 1 auto; min-height: 0; }

.mkt-browse {
  display: grid;
  flex: 1 1 auto;
  grid-template-columns: 256px minmax(0, 1fr);
  min-width: 0;
}

.mkt-browse[hidden],
.mkt-page[hidden] { display: none; }

/* The left side: search, Browse / Quickbar, the tree. */
.mkt-side {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  padding: 10px 0 0 10px;
  border-right: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.28);
}

.mkt-search,
.mkt-sidetabs,
.mkt-only { margin-right: 10px; }
.mkt-search { padding: 6px 9px; font-size: 13px; }
.mkt-sidetabs { display: flex; gap: 2px; }
.mkt-sidetabs .comms-tab { flex: 1 1 0; display: inline-flex; justify-content: center; align-items: center; gap: 6px; }
.mkt .comms-tab[aria-selected="true"],
.mkt .comms-tab[aria-checked="true"] { color: var(--ink-bright); border-bottom-color: var(--accent); }

.mkt-only {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  color: var(--ink-dim);
  cursor: pointer;
}

.mkt-only input { margin: 0; accent-color: var(--accent); }
.mkt-only:hover { color: var(--ink); }

.mkt-tree { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 6px 12px 0; }

.mkt-node {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 4px 8px 4px calc(8px + var(--depth, 0) * 14px);
  border: 0;
  border-left: 2px solid transparent;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}

.mkt-node:hover,
.mkt-node:focus-visible { background: rgba(150, 196, 224, 0.06); outline: none; }
.mkt-node[aria-current="true"] { border-left-color: var(--accent); background: var(--accent-wash); color: var(--ink-bright); }
.mkt-node.is-group { padding-top: 6px; padding-bottom: 6px; font-size: 13px; color: var(--ink-bright); }
.mkt-node.is-top { margin-top: 2px; font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); }

.mkt-chevron {
  display: inline-block;
  width: 7px;
  height: 7px;
  margin: 0 2px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  opacity: 0.75;
  transform: rotate(-45deg);
  transition: transform 120ms var(--ease);
}

.mkt-node[aria-expanded="true"] .mkt-chevron { transform: rotate(45deg); }
.mkt-node-name { display: grid; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.mkt-node-name > span { overflow: hidden; text-overflow: ellipsis; }
.mkt-node-sub { font-size: 11px; color: var(--ink-dim); }
.mkt-node-price { font-size: 12px; color: var(--ink); }
.mkt-node-count { font-size: 11px; letter-spacing: 0.02em; color: var(--ink-dim); }
.mkt-node-count.is-active { color: var(--accent); }
.is-none { color: var(--ink-dim); opacity: 0.6; }
.mkt-node-price.is-none { opacity: 0.45; }

.mkt-quick-head {
  padding: 8px 8px 3px 10px;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

/* The right side, and the full-width pages (My orders, Transactions). */
.mkt-detail,
.mkt-page {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  min-height: 0;
  overflow: auto;
  padding: 12px 16px 18px;
}

.mkt-page { flex: 1 1 auto; }
.mkt-page-inner { display: flex; flex-direction: column; gap: 12px; }
.mkt-pad { padding: 12px; }
.mkt-back { display: none; }

.mkt-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; font-size: 12px; color: var(--ink-dim); }
.mkt-crumb { padding: 0; border: 0; background: transparent; color: var(--ink-dim); font: inherit; cursor: pointer; }
button.mkt-crumb:hover,
button.mkt-crumb:focus-visible { color: var(--accent); outline: none; }
.mkt-crumb.is-here { color: var(--ink); cursor: default; }
.mkt-crumb-sep { opacity: 0.6; }

.mkt-link {
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-align: left;
  cursor: pointer;
}

.mkt-link:hover,
.mkt-link:focus-visible { color: var(--accent); outline: none; }

.mkt-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-bright);
}

.mkt-group-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; }
.mkt-head-count { font-size: 12px; color: var(--ink-dim); text-transform: none; letter-spacing: 0; font-weight: 400; }
.mkt-sub-head { display: flex; align-items: baseline; gap: 10px; margin-top: 6px; }
.mkt-sub-head .mkt-link { color: var(--accent); }

/* The exchange at a glance. */
.mkt-hero {
  display: grid;
  gap: 4px;
  padding: 14px 18px 16px;
  border: 1px solid rgba(var(--accent-rgb), 0.35);
  background:
    radial-gradient(120% 160% at 100% 0%, rgba(var(--accent-rgb), 0.16), transparent 55%),
    linear-gradient(135deg, #16283a, #0c1620 70%);
}

.mkt-hero .wallet-card-top { margin-bottom: 8px; }
.mkt-hero-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.mkt-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.mkt-stats.is-fit { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }

.mkt-stat {
  display: grid;
  align-content: start;
  gap: 2px;
  min-width: 0;
  padding: 9px 12px;
  border: 1px solid var(--line);
  background: rgba(150, 196, 224, 0.03);
}

.mkt-hero .mkt-stat { padding: 0; border: 0; background: none; }
/* A figure on its own reads better in proportional digits. */
.mkt-stat-value { overflow: hidden; font-size: 19px; color: var(--ink-bright); font-variant-numeric: normal; text-overflow: ellipsis; white-space: nowrap; }
.mkt-hero .mkt-stat-value { font-size: 24px; font-weight: 600; }
.mkt-stat-sub { overflow: hidden; font-size: 12px; color: var(--ink-dim); text-overflow: ellipsis; white-space: nowrap; }
.mkt-stat-label { display: flex; align-items: center; gap: 6px; min-width: 0; }

/* A "?" saying more about a label (ui/infotip.js; user request 2026-10-15,
   on the Market's tiles). The words show in one bubble on <body>, over
   windows and under the right-click menu. */
.info-q {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  width: 15px;
  height: 15px;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1;
  cursor: help;
}
.info-q:hover, .info-q:focus-visible, .info-q[aria-describedby] {
  border-color: var(--accent);
  color: var(--ink-bright);
  outline: none;
}
.info-tip {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 79;
  max-width: min(300px, calc(100vw - 16px));
  padding: 9px 12px;
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  background: #0b131b;
  box-shadow: 0 12px 28px -6px rgba(0, 0, 0, 0.8);
  color: var(--ink-bright);
  font-size: 13px;
  line-height: 1.45;
  letter-spacing: normal;
  text-transform: none;
  pointer-events: none;
}
.info-tip[hidden] { display: none; }

.mkt-cats { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 6px; margin: 0; padding: 0; list-style: none; }
.mkt-cat { grid-template-columns: 44px minmax(0, 1fr) 14px; grid-template-areas: "mark name go" "mark sub go"; }
.mkt-cat-mark { border-color: var(--line-strong); background: rgba(5, 8, 12, 0.5); }
.wallet-category-mark.mkt-cat-mark svg { width: 26px; height: 26px; }

/* Tables: a grid per row, so columns line up without a <table>. */
.mkt-table { display: flex; flex-direction: column; }

.mkt-row {
  display: grid;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 7px 8px;
  border: 0;
  border-top: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  text-align: left;
}

button.mkt-row { cursor: pointer; }
button.mkt-row:hover,
button.mkt-row:focus-visible { background: rgba(150, 196, 224, 0.06); outline: none; }

.mkt-row.is-head {
  padding-top: 2px;
  padding-bottom: 5px;
  border-top: 0;
  border-bottom: 1px solid var(--line-strong);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.mkt-row.is-head + .mkt-row,
.mkt-row.is-head + .wallet-line .mkt-row { border-top: 0; }
.mkt-row .is-num { text-align: right; white-space: nowrap; }

.mkt-items .mkt-row { grid-template-columns: minmax(0, 1.7fr) repeat(4, minmax(0, 1fr)); }
.mkt-book-table.is-sell .mkt-row { grid-template-columns: minmax(84px, 0.9fr) minmax(84px, 0.9fr) minmax(0, 2.2fr) 74px 74px; }
.mkt-book-table.is-buy .mkt-row { grid-template-columns: minmax(84px, 0.9fr) minmax(84px, 0.9fr) 84px minmax(0, 2.2fr) 74px 74px; }
.mkt-order-table .mkt-row { grid-template-columns: minmax(0, 2.2fr) minmax(96px, 0.9fr) minmax(86px, 0.8fr) minmax(96px, 0.9fr) 70px minmax(132px, auto); }
.mkt-closed .mkt-row { grid-template-columns: minmax(0, 2fr) 104px 96px 118px 64px; }
.mkt-tx .mkt-row { grid-template-columns: 58px minmax(0, 2fr) 84px 96px 120px; }
.mkt-days .mkt-row { grid-template-columns: minmax(0, 1.3fr) repeat(5, minmax(0, 1fr)); }
.mkt-recent .mkt-row { grid-template-columns: minmax(0, 1.3fr) repeat(3, minmax(0, 1fr)); }
.mkt-held-table .mkt-row { grid-template-columns: minmax(0, 1fr) 110px auto; }

.mkt-sort {
  display: flex;
  align-items: center;
  gap: 3px;
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}

.mkt-sort.is-num { justify-content: flex-end; }
.mkt-sort[aria-sort="ascending"],
.mkt-sort[aria-sort="descending"],
.mkt-sort:hover,
.mkt-sort:focus-visible { color: var(--ink-bright); outline: none; }
.mkt-sort-mark { width: 8px; color: var(--accent); }

.mkt-item-cell { display: flex; align-items: center; gap: 9px; min-width: 0; }
.mkt-item-cell svg { flex: 0 0 auto; }
.mkt-item-text { display: grid; min-width: 0; }
.mkt-item-name { overflow: hidden; color: var(--ink-bright); text-overflow: ellipsis; white-space: nowrap; }
.mkt-item-sub { overflow: hidden; font-size: 11px; color: var(--ink-dim); text-overflow: ellipsis; white-space: nowrap; }
.mkt-item-link { display: grid; padding: 0; border: 0; background: transparent; cursor: pointer; }
.mkt-cell-sub { display: block; font-size: 11px; color: var(--ink-dim); }
.mkt-change { margin-left: 6px; font-size: 11px; white-space: nowrap; }
.mkt-row .mkt-change { display: block; margin: 0; }
.mkt-change.is-up { color: #7fd4a4; }
.mkt-change.is-down { color: #f0907a; }

.mkt-tag {
  display: inline-block;
  padding: 0 5px;
  border: 1px solid var(--line-strong);
  font-size: 10px;
  letter-spacing: 0.12em;
  line-height: 15px;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.mkt-item-sub .mkt-tag { margin-right: 6px; }
.mkt-tag.is-mine { border-color: rgba(var(--accent-rgb), 0.5); color: var(--accent); }

/* The book: sellers above buyers, yours marked, the best price brighter. */
.mkt-book { display: flex; flex-direction: column; }
.mkt-book-head { display: flex; align-items: flex-end; gap: 10px; margin-bottom: 4px; }
.mkt-book-head .settings-heading { padding-bottom: 0; border-bottom: 0; }
.mkt-small { padding: 3px 8px; font-size: 11px; }
.mkt-empty-book { padding: 10px 8px; border-top: 1px solid var(--line-strong); }
.mkt-qty { display: flex; flex-direction: row-reverse; justify-content: flex-start; align-items: center; gap: 6px; }
.mkt-book-row.is-mine { background: rgba(var(--accent-rgb), 0.06); box-shadow: inset 2px 0 0 var(--accent); }
.mkt-book-row.is-best .mkt-price { color: var(--ink-bright); font-weight: 600; }
.mkt-loc { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mkt-col-ly,
.mkt-col-exp { color: var(--ink-dim); }
.mkt-held { padding: 8px 10px; border: 1px solid var(--line); }
.mkt-held .mkt-link { color: var(--accent); }

/* One item: its icon, name, groups, and Buy / Sell. */
.mkt-item-head { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 14px; }

.mkt-item-mark {
  display: grid;
  place-items: center;
  width: 58px;
  height: 58px;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.5);
  clip-path: polygon(0 0, calc(100% - 9px) 0, 100% 9px, 100% 100%, 0 100%);
}

.mkt-item-title { min-width: 0; }
.mkt-item-meta { display: flex; flex-wrap: wrap; gap: 3px 12px; margin-top: 3px; font-size: 12px; color: var(--ink-dim); }
.mkt-tier { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; }
.mkt-tier.is-t1 { color: var(--t1); }
.mkt-tier.is-t2 { color: var(--t2); }
.mkt-tier.is-t3 { color: var(--t3); }
.mkt-tier.is-t4 { color: var(--t4); }
.mkt-item-actions { display: flex; gap: 6px; }
.mkt-item-actions .win-button { min-width: 76px; }

.mkt-star {
  padding: 0 4px;
  border: 0;
  background: transparent;
  color: var(--ink-dim);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

.mkt-star.is-on,
.mkt-star:hover,
.mkt-star:focus-visible { color: var(--amber); outline: none; }

.mkt-subtabs { border-bottom: 1px solid var(--line); }

/* Price history. */
.mkt-history { display: flex; flex-direction: column; gap: 12px; }
.mkt-history-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.mkt-chart { position: relative; display: flex; flex-direction: column; gap: 6px; }
.mkt-legend { display: flex; flex-wrap: wrap; gap: 4px 16px; font-size: 12px; color: var(--ink-dim); }
.mkt-legend > span { display: inline-flex; align-items: center; gap: 6px; }

.mkt-chart-empty {
  display: grid;
  gap: 6px;
  padding: 28px 12px;
  border: 1px solid var(--line);
  text-align: center;
}

.mkt-chart-empty p { margin: 0; }

.pchart { position: relative; width: 100%; outline: none; cursor: crosshair; touch-action: pan-y; }
.pchart:focus-visible { box-shadow: 0 0 0 1px var(--accent); }
.pchart-svg { display: block; }
.pchart-grid { stroke: rgba(150, 196, 224, 0.09); stroke-width: 1; shape-rendering: crispEdges; }
.pchart-axis { stroke: var(--line-strong); stroke-width: 1; shape-rendering: crispEdges; }
.pchart-tick { fill: var(--ink-dim); font-family: var(--font); font-size: 11px; font-variant-numeric: tabular-nums; }
.pchart-band { fill: rgba(var(--accent-rgb), 0.12); }
.pchart-range { stroke: rgba(var(--accent-rgb), 0.35); stroke-width: 2; stroke-linecap: round; }
.pchart-line { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.pchart-ma { fill: none; stroke: rgba(195, 211, 223, 0.7); stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.pchart-vol { fill: rgba(150, 196, 224, 0.38); }
.pchart-dot { fill: var(--accent); stroke: #0c141c; stroke-width: 2; }
.pchart-crossline { stroke: rgba(234, 244, 251, 0.4); stroke-width: 1; shape-rendering: crispEdges; }

.pchart-tip {
  position: absolute;
  z-index: 2;
  display: grid;
  gap: 3px;
  min-width: 180px;
  padding: 8px 10px;
  border: 1px solid var(--line-strong);
  background: rgba(8, 13, 18, 0.96);
  box-shadow: 0 10px 24px -8px rgba(0, 0, 0, 0.8);
  font-size: 12px;
  pointer-events: none;
}

.pchart-tip[hidden] { display: none; }
.pchart-tip-date { margin-bottom: 2px; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); }
.pchart-tip-row { display: grid; grid-template-columns: 14px auto 1fr; align-items: center; gap: 7px; }
.pchart-tip-row strong { color: var(--ink-bright); font-weight: 600; font-variant-numeric: tabular-nums; }
.pchart-tip-row span:last-child { color: var(--ink-dim); }
.pchart-key { display: inline-block; width: 14px; height: 2px; background: var(--accent); }
.pchart-key.is-band { height: 8px; background: rgba(var(--accent-rgb), 0.25); }
.pchart-key.is-ma { background: rgba(195, 211, 223, 0.7); }
.pchart-key.is-vol { width: 6px; height: 9px; border-radius: 1.5px 1.5px 0 0; background: rgba(150, 196, 224, 0.38); }

/* Info: what it is, what makes it, what it makes. */
.mkt-about { max-width: 72ch; margin: 0; line-height: 1.5; color: var(--ink); }
.mkt-recipe { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.mkt-recipe-in,
.mkt-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.mkt-recipe-arrow { font-size: 18px; color: var(--ink-dim); }

.mkt-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 9px 4px 5px;
  border: 1px solid var(--line);
  background: rgba(150, 196, 224, 0.03);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}

.mkt-chip:hover,
.mkt-chip:focus-visible { border-color: var(--accent); color: var(--ink-bright); outline: none; }
.mkt-chip-n { color: var(--ink-dim); }

/* My orders. */
.mkt-orders { display: flex; flex-direction: column; }
.mkt-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px; }
.mkt-fill { display: block; width: 64px; height: 3px; margin: 4px 0 0 auto; background: rgba(150, 196, 224, 0.12); }
.mkt-fill > span { display: block; height: 100%; background: #7fd4a4; }
.mkt-modify { display: grid; justify-items: end; gap: 4px; }
.mkt-price-input { width: 104px; padding: 4px 6px; font-size: 13px; text-align: right; }
.mkt-modify-buttons { display: flex; gap: 4px; }
.mkt-inline-error { font-size: 11px; text-align: right; white-space: normal; }
.win-button.is-armed { border-color: var(--danger); color: #ffd9cf; }
.mkt-order.is-flash { animation: mkt-flash 1.8s var(--ease); }
@keyframes mkt-flash { from { background: rgba(var(--accent-rgb), 0.24); } to { background: transparent; } }
.reduce-motion .mkt-order.is-flash { animation: none; background: rgba(var(--accent-rgb), 0.1); }

.mkt-state { font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; }
.mkt-state.is-filled { color: #7fd4a4; }
.mkt-state.is-expired { color: var(--amber); }
.mkt-state.is-canceled,
.mkt-state.is-gone { color: var(--ink-dim); }

/* Transactions. */
.mkt-tx-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.mkt-tx-item { width: auto; min-width: 170px; padding: 5px 8px; font-size: 13px; }

.mkt-side-tag {
  display: inline-block;
  margin-right: 7px;
  padding: 0 5px;
  border: 1px solid var(--line-strong);
  font-size: 10px;
  letter-spacing: 0.12em;
  line-height: 15px;
  text-transform: uppercase;
  vertical-align: 1px;
  color: var(--ink);
}

.mkt-side-tag.is-sell { border-color: rgba(127, 212, 164, 0.45); color: #7fd4a4; }
.mkt-tx-row[aria-expanded="true"] { background: rgba(150, 196, 224, 0.04); }
.mkt-tx-detail { padding: 4px 8px 12px 76px; }

/* Buying and selling: a sheet over the window. */
.mkt-layer { position: absolute; inset: 0; z-index: 5; display: grid; place-items: center; padding: 16px; }
.mkt-layer[hidden] { display: none; }
.mkt-scrim { position: absolute; inset: 0; background: rgba(3, 6, 9, 0.64); }

.mkt-sheet {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: min(580px, 100%);
  max-height: 100%;
  overflow: auto;
  padding: 14px 16px 16px;
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  background: linear-gradient(180deg, rgba(20, 31, 42, 0.99), rgba(10, 16, 22, 0.99));
  box-shadow: 0 24px 50px -16px rgba(0, 0, 0, 0.9);
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
}

.mkt-sheet-head { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 10px; }
.mkt-sheet-title { display: grid; }
.mkt-sheet-title strong { font-size: 18px; font-weight: 600; color: var(--ink-bright); }
.mkt-sheet-form { gap: 14px; }
.mkt-form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.mkt-form-row[hidden] { display: none; }
.mkt-with-button { display: flex; gap: 6px; }
.mkt-with-button .win-input { flex: 1 1 auto; min-width: 0; }
.mkt-with-button .win-button[hidden] { display: none; }
.mkt-units,
.mkt-price-field { font-size: 17px; font-variant-numeric: tabular-nums; }
.mkt-hints { display: flex; flex-wrap: wrap; gap: 4px; }

.mkt-hint {
  display: inline-flex;
  gap: 5px;
  padding: 2px 7px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}

.mkt-hint strong { font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; }
.mkt-hint:hover,
.mkt-hint:focus-visible { border-color: var(--accent); outline: none; }

.mkt-summary {
  display: grid;
  gap: 6px;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  background: rgba(150, 196, 224, 0.03);
}

.mkt-summary p { margin: 0; font-size: 13px; line-height: 1.45; }
.mkt-plan { color: var(--ink); }
.mkt-warn { color: var(--amber); }
.mkt-total { display: flex; justify-content: space-between; align-items: baseline; padding-top: 6px; border-top: 1px solid var(--line); }
.mkt-total span { font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-dim); }
.mkt-total strong { font-size: 20px; font-weight: 600; color: var(--ink-bright); }
.mkt-confirm { min-width: 190px; }
.mkt-receipt { padding-top: 8px; }
.mkt-receipt p { margin: 0; }
.mkt-receipt-amount { font-size: 26px; font-weight: 600; color: var(--ink-bright); }
.mkt-receipt-actions { width: 100%; margin-top: 14px; }
.mkt-sheet-empty { min-height: 0; padding: 24px 8px; }

/* Logistics: a way from an item's request or export to its market page. */
.flog-market-link {
  grid-column: 1 / -1;
  justify-self: start;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}

.flog-market-link:hover,
.flog-market-link:focus-visible { color: var(--ink-bright); outline: none; }

/* A narrow Market (a phone, or a small window): the tree or the page, not
   both, and the less important columns go. */
@container (max-width: 720px) {
  .mkt-browse { grid-template-columns: minmax(0, 1fr); }
  .mkt[data-pane="list"] .mkt-detail,
  .mkt[data-pane="detail"] .mkt-side { display: none; }
  .mkt-side { padding-right: 10px; border-right: 0; }
  .mkt-tree { padding-right: 0; }
  .mkt-back { display: inline-block; }
  .mkt-tabs-note { display: none; }
  .mkt-top { padding: 4px 6px 0; }
  .mkt-tab { padding: 7px 8px 8px; letter-spacing: 0.06em; }
  .mkt-subtabs .comms-tab { padding: 5px 7px; letter-spacing: 0.06em; }
  .mkt-stats,
  .mkt-hero-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mkt-col-ly,
  .mkt-col-exp,
  .mkt-col-min,
  .mkt-col-vol,
  .mkt-col-when,
  .mkt-col-total,
  .mkt-col-price { display: none; }
  .mkt-items .mkt-row { grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr)); }
  .mkt-book-table.is-sell .mkt-row,
  .mkt-book-table.is-buy .mkt-row { grid-template-columns: minmax(70px, 0.8fr) minmax(76px, 0.8fr) minmax(0, 1.6fr); }
  .mkt-order-table .mkt-row { grid-template-columns: minmax(0, 1.8fr) minmax(70px, 0.8fr) minmax(70px, 0.8fr) auto; }
  .mkt-closed .mkt-row { grid-template-columns: minmax(0, 2fr) 80px 80px 96px; }
  .mkt-tx .mkt-row { grid-template-columns: 50px minmax(0, 2fr) 64px 100px; }
  .mkt-item-head { grid-template-columns: auto minmax(0, 1fr); }
  .mkt-item-actions { grid-column: 1 / -1; }
  .mkt-form-row { grid-template-columns: 1fr; }
  .mkt-tx-detail { padding-left: 8px; }
}

/* ------------------------------------------------------------- places
   A location anywhere in the game is a link (ui/places.js): click to go
   there, right-click to name the system or copy its location code. Your
   own name for a system carries its location code beside it. */

.place-link {
  display: inline;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--accent);
  text-align: inherit;
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 40%, transparent);
  text-underline-offset: 2px;
  cursor: pointer;
  overflow-wrap: anywhere;
}

.place-link:hover,
.place-link:focus-visible {
  color: var(--ink-bright);
  text-decoration-color: var(--accent);
  outline: none;
}

.place-code {
  margin-left: 0.45em;
  font-size: 0.86em;
  color: var(--ink-dim);
  letter-spacing: 0.04em;
}

.place-suffix { color: inherit; }

.place-pop { width: min(340px, calc(100vw - 16px)); }

.place-pop-real {
  margin: 0 0 10px;
  font-size: 12px;
  color: var(--ink-dim);
}

.place-pop-real b { color: var(--ink-bright); font-weight: 600; }

.place-pop-note { margin: 2px 0 8px; }

.sysview-name-row {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  pointer-events: auto;
}

.sysview-code {
  margin-left: 0.5em;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.1em;
  color: var(--ink-dim);
}

.sysview-rename { pointer-events: auto; }

/* The map card: your own name for a system over its real one. */
.map-card-real {
  margin: -6px 0 10px;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
  user-select: text;
}

.map-card-buttons {
  display: flex;
  gap: 6px;
  margin-bottom: 12px;
}

.map-card-buttons .map-card-copy { margin-bottom: 0; }
.map-card-buttons .map-card-rename { width: auto; flex: 0 0 auto; }

/* Factory Floor: whose split this is (every miner of yours round the planet). */
.factory-split-for {
  margin: 0;
  font-size: 12px;
  color: var(--ink-dim);
}

/* Logistics: the amount runs up to the most the station holds, "Max". */
.flog-ticks {
  display: flex;
  justify-content: space-between;
  margin: 2px 120px 0 2px;
  font-size: 11px;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}
.flog-tick-max { color: var(--ink); }
.flog-amount-note { margin: 4px 0 0; }
.flog-amount-warn { margin: 4px 0 0; }
@media (max-width: 720px) { .flog-ticks { margin-right: 100px; } }

.flog-panel-sub { font-size: 11px; letter-spacing: 0.04em; color: var(--ink-dim); white-space: nowrap; }

/* An inventory slot at the most its station holds: nothing more comes in. */
.fslot.is-capped { border-color: rgba(233, 201, 76, 0.65); }
.fslot.is-capped .fslot-bar i { background: var(--slot-fill); }

.flog-head-go { flex: 0 0 auto; font-size: 12px; white-space: nowrap; }

/* ---- Comms: the bug report and suggestion boards (ui/feedback.js) */

.comms-tab-gap { width: 10px; }
.comms-compose-button[hidden] { display: none; }

/* The Bug Reports window (ui/bugreports.js): the bug board, out of Comms. */
.bugs-intro { flex: 1 1 260px; min-width: 0; margin: 0; color: var(--ink-dim); font-size: 13px; line-height: 1.4; }

.fb { display: flex; flex-direction: column; gap: 8px; }
.fb-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.fb-sorts .comms-tab[aria-checked="true"],
.fb-views .comms-tab[aria-checked="true"] { color: var(--ink-bright); border-bottom-color: var(--accent); }
/* Open and Archived (2026-10-21), each with how many it holds. */
.fb-views .comms-tab { display: inline-flex; align-items: center; gap: 6px; }
.fb-views .fb-tag-count:empty { display: none; }
.fb-views + .fb-sorts { padding-left: 8px; border-left: 1px solid var(--line); }
.fb-search { flex: 1 1 160px; min-width: 0; }

.fb-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.fb-tags[hidden] { display: none; }

/* A tag: a small pill. Filters and suggestions are buttons; on a post you
   wrote, each has an × to take it off. */
.fb-tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: rgba(150, 196, 224, 0.06);
  color: var(--ink);
  font: inherit;
  font-size: 11px;
  line-height: 1.5;
  white-space: nowrap;
}
button.fb-tag { cursor: pointer; }
button.fb-tag:hover,
button.fb-tag:focus-visible { border-color: var(--accent); color: var(--ink-bright); outline: none; }
.fb-tag.is-on { border-color: var(--accent); background: var(--accent-wash); color: var(--ink-bright); }
.fb-tag.is-offer { border-style: dashed; color: var(--ink-dim); background: transparent; }
.fb-tag-count { color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.fb-tag-x {
  padding: 0 0 0 2px;
  border: 0;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
.fb-tag-x:hover,
.fb-tag-x:focus-visible { color: var(--ink-bright); outline: none; }

.fb-list li { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: start; gap: 10px; padding: 8px 4px; }
.fb-row-main {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  padding: 2px 4px;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.fb-row-main:hover .fb-row-title,
.fb-row-main:focus-visible .fb-row-title { color: var(--accent); }
.fb-row-main:focus-visible { outline: none; }
.fb-row-title { font-size: 14px; color: var(--ink-bright); overflow-wrap: anywhere; }
.fb-row-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.fb-pills { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.fb-row-who { font-size: 11px; color: var(--ink-dim); }

/* The upvote: an arrow over a count, lit once you have upvoted. */
.fb-vote {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  min-width: 40px;
  padding: 4px 6px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  line-height: 1.1;
  cursor: pointer;
}
.fb-vote-arrow { font-size: 11px; }
.fb-vote-count { font-size: 13px; font-weight: 600; color: var(--ink-bright); font-variant-numeric: tabular-nums; }
.fb-vote:hover:not(:disabled),
.fb-vote:focus-visible { border-color: var(--accent); color: var(--accent); outline: none; }
.fb-vote.is-on { border-color: var(--accent); background: var(--accent-wash); color: var(--accent); }
.fb-vote:disabled { cursor: default; opacity: 0.75; }
.fb-vote.is-big { min-width: 48px; padding: 6px 8px; }
.fb-vote.is-big .fb-vote-count { font-size: 16px; }

.fb-post { display: flex; flex-direction: column; gap: 10px; }
.fb-post-head { display: flex; align-items: flex-start; gap: 12px; }
.fb-post-title { min-width: 0; }
.fb-post-title .comms-message-subject { margin-top: 0; overflow-wrap: anywhere; }

.fb-tagrow { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.fb-tagrow-label { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); }
.fb-tag-editor { display: flex; flex-direction: column; gap: 6px; flex: 1 1 260px; min-width: 0; }
.fb-tag-chosen { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
/* The board's tags to pick from (2026-10-21: no typing your own). */
.fb-tag-pick { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.fb-tag.is-pick { background: transparent; color: var(--ink-dim); }
.fb-tag.is-pick.is-on { border-color: var(--accent); background: var(--accent-wash); color: var(--ink-bright); }
.fb-tag.is-pick.is-on::before { content: '✓'; font-size: 10px; }
.fb-tag.is-pick:disabled { opacity: 0.45; cursor: default; }
.fb-tag.is-pick:disabled:hover { border-color: var(--line-strong); color: var(--ink-dim); }
.fb-tag-full { flex-basis: 100%; margin: 2px 0 0; font-size: 12px; }
/* A developer's blacklisted tags, at the end of the filters. */
.fb-banned-label { margin-left: 6px; align-self: center; }
.fb-tag.is-banned { border-style: dashed; background: transparent; color: var(--ink-dim); text-decoration: line-through; }
.fb-badge.is-archived { border-color: rgba(150, 196, 224, 0.45); color: var(--ink-dim); }

.fb-form-head { margin: 0; font-size: 15px; color: var(--ink-bright); }
.fb-form-tags { gap: 6px; }
/* In the form the editor stacks under its label: its 260px basis is meant
   as a width on a post's tag row, not a height here. */
.fb-form-tags .fb-tag-editor { flex: 0 0 auto; }
/* On your own post, + Tags opens the list under your tags. */
.fb-tagrow.is-mine { align-items: flex-start; }
.fb-tagrow.is-mine > .fb-tagrow-label { padding-top: 4px; }

/* Screenshots on bug reports (ui/screenshot.js): the camera button, a
   board row's count, and the tiles in the form and under a post. */
.fb-shot-button { display: inline-flex; align-items: center; gap: 6px; }
.fb-shot-button[hidden] { display: none; }
.fb-shot-button svg { flex: 0 0 auto; }
.fb-row-shots { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; color: var(--ink-dim); }
.fb-shots-row { display: flex; flex-direction: column; gap: 6px; margin-top: 14px; }
.fb-shots { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.fb-form-shots { gap: 6px; }
.fb-shot { position: relative; }
.fb-shot-open {
  display: block;
  padding: 0;
  border: 1px solid var(--line-strong);
  background: #05080c;
  cursor: zoom-in;
}
.fb-shot-open:hover,
.fb-shot-open:focus-visible { border-color: var(--accent); outline: none; }
.fb-shot-open img { display: block; width: 168px; height: 105px; object-fit: cover; }
.fb-shot-x {
  position: absolute;
  top: 4px;
  right: 4px;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.85);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
.fb-shot-x:hover,
.fb-shot-x:focus-visible { border-color: var(--accent); color: var(--ink-bright); outline: none; }
.fb-shot-x.is-armed { border-color: var(--danger); background: rgba(52, 14, 10, 0.94); color: var(--ink-bright); font-size: 11px; }

/* A screenshot shown big, over everything. */
.shot-viewer {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: flex;
  flex-direction: column;
  background: rgba(3, 6, 10, 0.9);
  backdrop-filter: blur(2px);
  outline: none;
}
.shot-viewer-stage {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 16px 16px 10px;
}
.shot-viewer-img {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border: 1px solid var(--line-strong);
  box-shadow: 0 24px 60px -16px rgba(0, 0, 0, 0.9);
}
.shot-viewer-nav {
  flex: 0 0 auto;
  width: 40px;
  height: 64px;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.7);
  color: var(--ink);
  font: inherit;
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
}
.shot-viewer-nav[hidden] { display: none; }
.shot-viewer-nav:hover,
.shot-viewer-nav:focus-visible { border-color: var(--accent); color: var(--ink-bright); outline: none; }
.shot-viewer-bar { display: flex; align-items: center; gap: 8px; padding: 0 16px 16px; }
.shot-viewer-count { font-size: 12px; letter-spacing: 0.08em; color: var(--ink-dim); }
.shot-viewer a.win-button { text-decoration: none; }
.shot-viewer a.win-button[hidden] { display: none; }

@media (max-width: 720px) {
  .fb-shot-open img { width: 132px; height: 82px; }
  .shot-viewer-stage { padding: 8px; gap: 4px; }
  .shot-viewer-nav { width: 32px; }
}

/* ------------------------------------------------------------ Research */

.research { display: flex; flex-direction: column; gap: 10px; }
.research-summary {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 12px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  background: var(--accent-wash);
}
.research-summary-big { font-size: 22px; font-weight: 600; letter-spacing: 0.04em; color: var(--ink-bright); font-variant-numeric: tabular-nums; }
.research-summary-text { font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-dim); }
.research-how { margin: 0; }

.research-nolabs {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 8px 12px;
  padding: 10px 12px;
  border: 1px dashed var(--line-strong);
}
.research-nolabs .win-note { margin: 0; }
.research-nolabs .win-button { grid-column: 1 / -1; justify-self: end; }

.research-labs,
.research-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.research-lab {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 4px 10px;
  padding: 7px 10px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--ink-dim);
  background: rgba(5, 8, 12, 0.45);
}
.research-lab.is-working { border-left-color: #5fd17a; }
.research-lab.is-waiting { border-left-color: #e9c94c; }
.research-lab.is-done { border-left-color: var(--accent); }
.research-lab .factory-icon { color: var(--accent); }
.research-lab-text { display: grid; gap: 1px; min-width: 0; }
.research-lab-name { font-size: 13px; color: var(--ink-bright); }
.research-lab-name small { font-size: 11px; color: var(--ink-dim); }
.research-lab-where { font-size: 12px; color: var(--ink-dim); overflow-wrap: anywhere; }
.research-lab-doing { grid-column: 2; display: flex; flex-wrap: wrap; gap: 2px 8px; font-size: 12px; }
.research-lab-project { color: var(--ink); }
.research-lab-state { color: var(--ink-dim); }
.research-lab.is-working .research-lab-state { color: #5fd17a; }
.research-lab.is-waiting .research-lab-state { color: #e9c94c; }
.research-lab .win-button { grid-column: 3; grid-row: 1 / span 2; }

.research-card {
  display: grid;
  gap: 6px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  background: rgba(150, 196, 224, 0.03);
}
.research-card.is-active { background: var(--accent-wash); }
.research-card.is-locked { border-left-style: dashed; border-left-color: var(--amber); background: rgba(5, 8, 12, 0.35); }
.research-card.is-done { border-left-color: #5fd17a; }
.research-card.is-flash { animation: factory-flash 1.8s var(--ease); }
.research-card-head { display: flex; align-items: center; gap: 8px; }
.research-card-name { font-size: 15px; font-weight: 600; color: var(--ink-bright); }
.research-card-head .research-chip { margin-left: auto; }
.research-card-blurb { margin: 0; font-size: 13px; line-height: 1.4; color: var(--ink); }
.research-card.is-locked .research-card-blurb { color: var(--ink-dim); }
.research-card-line { margin: 0; font-size: 12px; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.research-card-line span:first-child { color: var(--ink); }
.research-card-step { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 12px; color: var(--ink); }
.research-card-label { min-width: 62px; font-size: 10px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }
.research-card-dim { color: var(--ink-dim); }
.research-item { display: inline-flex; align-items: center; gap: 3px; }
.research-item b { font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink-bright); }
.research-unlock { display: inline-flex; align-items: center; gap: 4px; padding: 1px 6px; border: 1px solid var(--line-strong); color: var(--ink-bright); }
.research-unlock svg { color: var(--accent); }
.research-card-labs { margin: 0; font-size: 11px; letter-spacing: 0.06em; color: var(--accent); }
.research-card .factory-lock { margin: 0; }

@media (max-width: 720px) {
  .research-lab { grid-template-columns: auto minmax(0, 1fr); }
  .research-lab .win-button { grid-column: 1 / -1; grid-row: auto; justify-self: end; }
}

/* ---- Favorites (ui/favorites.js, ui/places.js)
 * The star toggle: hollow and dim until a system is a favorite, then gold
 * and filled. Used on the map card, beside the system view's title and on
 * each row of the Favorites window. */
.fav-star {
  display: inline-grid;
  place-items: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  pointer-events: auto;
  transition: color 0.13s var(--ease), border-color 0.13s var(--ease);
}
.fav-star:hover,
.fav-star:focus-visible { color: #e2b55a; border-color: var(--line-strong); outline: none; }
.fav-star.is-on { color: #e2b55a; }
.fav-star.is-on svg path { fill: currentColor; }
.fav-star.is-on:hover svg path { fill: rgba(226, 181, 90, 0.35); }
.map-card-fav { margin-left: auto; width: 22px; height: 22px; }

.favorites { display: flex; flex-direction: column; gap: 10px; min-height: 100%; }
.fav-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.fav-search { flex: 1 1 180px; min-width: 0; }
.fav-sort { flex: 0 0 auto; width: auto; }
.fav-count { margin-left: auto; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); white-space: nowrap; }
.fav-add-slot:empty { display: none; }
.fav-add { display: inline-flex; align-items: center; gap: 6px; }
.fav-add svg { color: #e2b55a; }
.fav-list { flex: 1 1 auto; }
.fav-rows { display: flex; flex-direction: column; gap: 6px; }
.fav-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 4px 10px;
  padding: 8px 10px 8px 6px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--t1);
  background: rgba(150, 196, 224, 0.03);
}
.fav-row:hover { background: var(--accent-wash); }
.fav-row-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.fav-row-head { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.fav-row-name { font-size: 15px; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fav-row-facts,
.fav-row-built { margin: 0; font-size: 12px; line-height: 1.4; color: var(--ink-dim); }
.fav-row-built.is-built { color: var(--ink); }
.fav-row-side { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.fav-row-added { font-size: 11px; color: var(--ink-dim); white-space: nowrap; }
.fav-empty .fav-empty-star { color: #e2b55a; opacity: 0.7; }
.fav-none { margin: 4px 2px; }

@media (max-width: 720px) {
  .fav-row { grid-template-columns: auto minmax(0, 1fr); }
  .fav-row-side { grid-column: 2; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; }
  .fav-row-added { flex: 1 0 100%; }
}

/* ---- Factory Floor: the one line pointing at buildings research unlocks. */
.factory-more {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px 10px;
  margin: 6px 0 0;
  padding: 8px 10px;
  border: 1px dashed var(--line-strong);
  font-size: 12px;
  color: var(--ink-dim);
}

/* ---- Research: buildings a project unlocks, with what they cost. */
.research-unlocks { display: flex; flex-direction: column; gap: 6px; font-size: 12px; }
.research-unlock-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 8px;
  padding: 6px 8px;
  border: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.35);
}
.research-unlock-row .factory-icon svg { color: var(--accent); }
.research-unlock-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.research-unlock-text p { margin: 0; }
.research-unlock-name { font-size: 13px; font-weight: 600; color: var(--ink-bright); }
.research-unlock-blurb { color: var(--ink); line-height: 1.4; }
.research-unlock-cost { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; color: var(--ink); }
.research-unlock-cost .research-card-label { min-width: 0; }
.research-unlock-cost > b { font-weight: 600; color: var(--ink-bright); }

/* ---- Sidebar buttons, renamed and restyled (ui/sidebarstyle.js). The
 * editor's preview draws the button as the sidebar would: open, then
 * collapsed. */
.sidebar-preview { display: flex; align-items: center; gap: 10px; width: 100%; }
.sidebar-preview-row {
  display: flex;
  align-items: center;
  gap: 12px;
  height: var(--row-h);
  padding: 0 12px;
  background: linear-gradient(180deg, var(--rail-top), var(--rail-bottom));
  border: 1px solid var(--line);
  color: var(--ink-bright);
}
.sidebar-preview-row:first-child { flex: 1 1 auto; min-width: 0; }
.sidebar-preview-row.is-collapsed { flex: 0 0 auto; width: var(--row-h); justify-content: center; padding: 0; }
.sidebar-preview .neocom-text { font-size: 13px; }

/* ------------------------------------------------------------------------
   An Assembly Bay's floor (bayview.js): tools down the left, the floor on a
   canvas, the panel for what is selected on the right. Over the station. */
.viewport.is-map-closed .bayview { display: none; }
.bayview {
  position: absolute;
  inset: 0;
  z-index: 7;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  background: var(--void);
}
.bayview[hidden] { display: none; }

.bay-flow { display: flex; flex-wrap: wrap; gap: 6px; margin-left: auto; }

/* Hide tools / Hide panel (2026-10-21: "add a way for me to hide both the
   'tools' and the panel that says 'Basic assembly bay'"): two buttons at the
   right of the top bar. Hidden, the palette goes; the panel goes while it is
   the bay's own (`is-bay`), and comes back for whatever is selected. A
   tutorial that is playing shows the tools anyway, as its steps point at them. */
.bay-views { display: flex; flex: none; gap: 6px; margin-left: auto; }
.bay-flow + .bay-views { margin-left: 0; }
.bay-view-toggle {
  padding: 5px 10px;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.6);
  color: var(--ink);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
}
.bay-view-toggle:hover,
.bay-view-toggle:focus-visible { border-color: var(--accent); color: var(--accent); outline: none; }
.bay-view-toggle[aria-pressed="true"] { border-color: rgba(var(--accent-rgb), 0.55); color: var(--accent); background: var(--accent-wash); }
.bay-body.is-tools-hidden .bay-tools,
.bay-body.is-panel-hidden .station-panel.bay-panel.is-bay { display: none; }
body.tut-playing .bay-body.is-tools-hidden .bay-tools { display: flex; }
/* A phone hides the flow chips, so the buttons go right on their own; a
   finger gets 40 px targets. */
@media (max-width: 720px) {
  .bay-bar .bay-flow + .bay-views { margin-left: auto; }
}
@media (pointer: coarse), (max-width: 720px) {
  .bay-view-toggle { min-height: 40px; }
}
/* Each side keeps its own column, so the floor stays in the middle one
   whichever is hidden (a phone stacks them by rows instead). */
@media (min-width: 721px) {
  .bay-tools { grid-column: 1; grid-row: 1; }
  .bay-stage { grid-column: 2; grid-row: 1; }
  .station-panel.bay-panel { grid-column: 3; grid-row: 1; }
}
.bay-flow-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  border: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.6);
  font-size: 12px;
  color: var(--ink-bright);
  font-variant-numeric: tabular-nums;
}
.bay-flow-chip small { color: var(--ink-dim); }

.bay-body { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; min-height: 0; }

/* The floor's palette down the left (redone 2026-10-17: "redo the inventory
   system to be more streamlined and professional"). Tools: Select, Belt,
   Splitter and Remove two by two, Rotate under them. Edit: copy, cut, paste,
   undo and redo as icons in a row. Machines: a box per kind, its name over
   a chip per tier with how many of it the inventory holds (the column is
   headed In stock), grayed at none, locked ones dim with a lock. */
.bay-tools {
  display: flex;
  flex-direction: column;
  gap: 14px;
  width: 216px;
  padding: 10px 8px 12px;
  border-right: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(14, 22, 31, 0.96), rgba(8, 13, 18, 0.96));
  overflow-y: auto;
}
.bay-pal-top { display: flex; flex-direction: column; gap: 14px; }
.bay-pal { display: flex; flex-direction: column; gap: 4px; }
.bay-pal-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin: 0 0 2px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--line);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
}
.bay-pal-note { font-weight: 400; letter-spacing: 0.12em; color: var(--ink-dim); }
.bay-pal-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px; }
.bay-pal-icons { display: flex; align-items: center; gap: 2px; }
.bay-pal-sep { flex: none; width: 1px; height: 20px; margin: 0 5px; background: var(--line); }
.bay-pal-empty { margin: 2px 0 0; font-size: 11px; line-height: 1.4; color: var(--ink-dim); }
.bay-tool {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  height: 32px;
  padding: 0 8px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
}
.bay-pal-grid .bay-tool { position: relative; gap: 6px; padding: 0 6px; border-color: var(--line); background: rgba(2, 4, 6, 0.35); }
/* Two by two leaves no room for a key beside the name: it sits in the corner. */
.bay-pal-grid .bay-tool kbd { position: absolute; top: 2px; right: 4px; font-size: 9px; }
.bay-tool svg { flex: none; }
.bay-tool-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bay-tool kbd,
.bay-kind-head kbd { flex: none; font: inherit; font-size: 10px; letter-spacing: 0.1em; color: var(--ink-dim); }
.bay-tool:hover,
.bay-tool:focus-visible { border-color: var(--line-strong); color: var(--ink-bright); outline: none; }
.bay-tool.is-on { border-color: var(--accent); background: var(--accent-wash); color: var(--accent); }
.bay-tool.is-on kbd { color: var(--accent); }
.bay-tool.is-icon { flex: none; justify-content: center; width: 32px; padding: 0; }
.bay-tool.is-rotate svg { transform: rotate(var(--dir, 0deg)); transition: transform 0.15s; }
.bay-tool[hidden],
.bay-kind[hidden] { display: none; }
.bay-tool:disabled { opacity: 0.4; cursor: default; }
.bay-tool:disabled:hover { border-color: transparent; color: var(--ink); }

.bay-kind {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 5px 6px 6px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--line-strong);
  background: rgba(2, 4, 6, 0.35);
}
.bay-kind.is-on { border-color: rgba(var(--accent-rgb), 0.45); border-left-color: var(--accent); background: rgba(var(--accent-rgb), 0.05); }
.bay-kind-head {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 1px 0;
  border: 0;
  background: none;
  color: var(--ink-bright);
  font: inherit;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
}
.bay-kind-head svg { flex: none; color: var(--accent); }
.bay-kind-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bay-kind-head:hover .bay-kind-name { color: var(--accent); }
.bay-kind-head:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
.bay-kind-tiers { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 3px; }
.bay-tool.bay-tier {
  justify-content: space-between;
  gap: 4px;
  height: 24px;
  padding: 0 6px;
  border-color: var(--line-strong);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.bay-tier-tag { letter-spacing: 0.04em; color: var(--t1); }
.bay-tier[data-tier="2"] .bay-tier-tag { color: var(--t2); }
.bay-tier[data-tier="3"] .bay-tier-tag { color: var(--t3); }
.bay-tier-n { display: inline-flex; align-items: center; font-weight: 600; color: var(--ink-bright); }
.bay-tool.bay-tier.is-out { border-color: var(--line); opacity: 0.45; }
.bay-tier.is-out .bay-tier-n { color: var(--ink-dim); }
.bay-tier.is-free .bay-tier-n { font-weight: 400; color: var(--ink); }
.bay-tool.bay-tier.is-locked { border-color: var(--line); opacity: 0.35; }
.bay-tool.bay-tier.is-on { border-color: var(--accent); background: var(--accent-wash); opacity: 1; }
.bay-tool.bay-tier.is-on.is-out { opacity: 0.8; }
.bay-tier.is-on .bay-tier-n { color: var(--accent); }

.bay-stage { position: relative; min-width: 0; min-height: 0; overflow: hidden; }
.bay-canvas { position: absolute; inset: 0; display: block; width: 100%; height: 100%; outline: none; touch-action: none; cursor: grab; }
.bay-canvas[data-tool="belt"],
.bay-canvas[data-tool="splitter"],
.bay-canvas[data-tool="machine"],
.bay-canvas[data-tool="remove"] { cursor: crosshair; }
.bay-canvas:focus-visible { box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), 0.5); }

.bay-zoom { position: absolute; left: 10px; bottom: 10px; display: flex; gap: 4px; }
.bay-zoom-btn {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid var(--line-strong);
  background: rgba(10, 16, 22, 0.92);
  color: var(--ink);
  font: inherit;
  font-size: 16px;
  cursor: pointer;
}
.bay-zoom-btn:hover,
.bay-zoom-btn:focus-visible { border-color: var(--accent); color: var(--accent); outline: none; }
.bay-readout {
  position: absolute;
  left: 118px;
  bottom: 16px;
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--ink-dim);
  pointer-events: none;
}
.bay-toast {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  max-width: calc(100% - 48px);
  margin: 0;
  padding: 8px 14px;
  background: rgba(14, 22, 31, 0.95);
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--ink-bright);
  pointer-events: none;
}
.bay-toast.is-bad { border-left-color: var(--danger); }
.bay-toast[hidden] { display: none; }

/* The panel sits in its own column rather than over the floor. */
.station-panel.bay-panel { position: relative; top: auto; right: auto; bottom: auto; width: 340px; margin: 8px 12px 8px 0; }

/* What the tool in hand does: a card beside the tools, over the floor's top
   left corner (it was a line along the foot of the screen). Clicks go
   through it to the floor, all but its Hide button. */
.bay-tip {
  position: absolute;
  top: 10px;
  left: 10px;
  max-width: min(380px, calc(100% - 20px));
  padding: 8px 10px 10px 12px;
  background: rgba(12, 19, 27, 0.92);
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  pointer-events: none;
  transition: opacity 0.15s;
}
.bay-tip.is-under { opacity: 0.12; }
.bay-tip-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.bay-tip-name { font-size: 11px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); }
.bay-tip-toggle {
  padding: 2px 8px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.08em;
  cursor: pointer;
  pointer-events: auto;
}
.bay-tip-toggle:hover,
.bay-tip-toggle:focus-visible { border-color: var(--accent); color: var(--accent); outline: none; }
.bay-tip-text { margin: 6px 0 0; font-size: 12px; line-height: 1.45; color: var(--ink); }
.bay-tip.is-folded { padding-bottom: 8px; }
.bay-tip.is-folded .bay-tip-text { display: none; }

.bay-open { justify-self: stretch; }
.bay-flow-row { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; align-items: center; gap: 8px; font-size: 13px; color: var(--ink); }
.bay-flow-row b { font-weight: 600; color: var(--ink-bright); font-variant-numeric: tabular-nums; }
.bay-flow-label { margin: 4px 0 0; font-size: 11px; letter-spacing: 0.08em; color: var(--ink-dim); }

.bay-recipe { display: grid; gap: 6px; }
.bay-recipe-part { display: grid; grid-template-columns: 24px minmax(0, 1fr) auto; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-bright); }
.bay-recipe-part b { font-weight: 600; font-variant-numeric: tabular-nums; }
.bay-recipe-part small { font-size: 11px; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.bay-recipe-part.is-out { padding-top: 6px; border-top: 1px dashed var(--line-strong); }

.bay-chosen { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.5); }
.bay-chosen div { display: grid; line-height: 1.3; }
.bay-chosen b { font-weight: 600; color: var(--ink-bright); }
.bay-chosen small { font-size: 11px; color: var(--ink-dim); }
.bay-shelf { display: grid; gap: 4px; }
.bay-shelf .flog-shelf-name { margin: 4px 0 0; }
.bay-picks { display: flex; flex-wrap: wrap; gap: 4px; }
.bay-pick {
  position: relative;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.5);
  cursor: pointer;
}
.bay-pick small { position: absolute; right: 2px; bottom: 1px; font-size: 9px; color: var(--ink-bright); text-shadow: 0 0 3px #000, 0 0 2px #000; font-variant-numeric: tabular-nums; }
.bay-pick:hover,
.bay-pick:focus-visible { border-color: var(--accent); outline: none; }
.bay-pick.is-on { border-color: var(--accent); background: var(--accent-wash); box-shadow: inset 0 0 0 1px var(--accent); }
/* The side panel's search and Hide higher tiers box, over an edge input's
   items and a machine's recipes (user request 2026-10-17: "make this a search
   bar also add a hide higher tier recipes check box"). What they hide is
   `hidden`, which these lists' own display rules would otherwise beat. */
.bay-find { display: grid; gap: 6px; }
.bay-find-field { width: 100%; min-width: 0; }
.bay-find-high { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--ink-dim); cursor: pointer; user-select: none; }
.bay-find-high input { margin: 0; accent-color: var(--accent); }
.bay-find-high:hover { color: var(--ink-bright); }
/* A machine's recipes by tier: All, then its own tier and those below it
   (Dev Panel note ea2e93f9, 2026-10-22), in the tiers' colors. */
.bay-find-tiers { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.bay-find-tiers-label { margin-right: 4px; font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }
.bay-find-tier {
  flex: 1 1 0;
  min-width: 52px;
  padding: 4px 8px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.bay-find-tier[data-tier="1"] { color: var(--t1); }
.bay-find-tier[data-tier="2"] { color: var(--t2); }
.bay-find-tier[data-tier="3"] { color: var(--t3); }
.bay-find-tier:hover,
.bay-find-tier:focus-visible { border-color: var(--accent); outline: none; }
.bay-find-tier[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-wash); box-shadow: inset 0 0 0 1px var(--accent); font-weight: 600; }
.bay-find-tier[data-tier="0"][aria-pressed="true"] { color: var(--ink-bright); }
@media (max-width: 720px) {
  .bay-find-tier { min-height: 38px; }
}
.bay-pick-lists { display: grid; gap: 12px; }
.bay-panel [data-find][hidden],
.bay-panel [data-find-group][hidden],
.bay-panel .bay-find-none[hidden] { display: none; }

.bay-how summary { font-size: 11px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); cursor: pointer; }
.bay-how ul { display: grid; gap: 4px; margin: 6px 0 0; padding-left: 18px; font-size: 12px; line-height: 1.4; color: var(--ink); }

.station-slot text.station-slot-count { fill: var(--ink); font-size: 8px; letter-spacing: 0.1em; }
.station-slot.is-bay.is-working .station-slot-count { fill: #5fd17a; }

/* On a phone: the floor on top, the tools in a row under it, the panel a
   sheet at the bottom. */
@media (max-width: 720px) {
  .bay-flow,
  .bay-tip { display: none; }
  .bay-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto auto; }
  .bay-stage { grid-row: 1; }
  .station-panel.bay-panel { grid-row: 3; width: auto; max-height: 36vh; margin: 0; }
  .bay-readout { display: none; }
}

.bay-keys dl { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 10px; margin: 6px 0 0; font-size: 12px; line-height: 1.4; }
.bay-keys dt { white-space: nowrap; }
.bay-keys dd { margin: 0; color: var(--ink); }
.bay-keys kbd {
  display: inline-block;
  padding: 1px 5px;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.6);
  font: inherit;
  font-size: 11px;
  color: var(--ink-bright);
}

/* ------------------------------------------------------------ sign-in gate
 * The whole page until a pilot is signed in (src/gate.js). Nothing of the
 * game shows behind it: the body starts .is-gated and the sidebar and the
 * viewport stay hidden until gate.js boots the game. */
.is-gated #neocom-root,
.is-gated #viewport { display: none; }

.gate {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 24px 16px;
  overflow-y: auto;
  background:
    radial-gradient(ellipse 70% 55% at 72% 18%, rgba(96, 150, 208, 0.13), transparent 70%),
    radial-gradient(ellipse 60% 50% at 18% 85%, rgba(224, 168, 60, 0.06), transparent 70%),
    radial-gradient(ellipse 50% 40% at 50% 50%, rgba(var(--accent-rgb), 0.05), transparent 75%),
    var(--void);
}

.gate-sky {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.gate-card {
  position: relative;
  width: min(420px, 100%);
  padding: 34px 30px 26px;
  border: 1px solid var(--line-strong);
  background: linear-gradient(180deg, rgba(14, 22, 31, 0.94), rgba(8, 13, 18, 0.94));
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.55);
  text-align: center;
}

/* The accent rule across the top, fading out like the sidebar's cap. */
.gate-card::before {
  content: "";
  position: absolute;
  top: -1px;
  left: -1px;
  right: -1px;
  height: 2px;
  background: linear-gradient(90deg, var(--accent), transparent);
}

.gate-mark {
  display: flex;
  justify-content: center;
  color: var(--accent);
}

.gate-mark svg { filter: drop-shadow(0 0 10px var(--accent-glow)); }

.gate-title {
  margin: 14px 0 6px;
  font-size: 24px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink-bright);
  /* The letter spacing trails the last letter; this puts the words back in
     the middle. */
  text-indent: 0.16em;
}

.gate-tag,
.gate-note { text-wrap: balance; }

.gate-tag {
  margin: 0 0 26px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
}

/* Google renders its own button in here; it is left unstyled on purpose,
   since Google's terms cover how that button looks. Only the box is ours.
   The button is an iframe with a light color scheme, and under this dark
   page the browser paints such a frame an opaque white backdrop. Matching
   its scheme here is what makes that backdrop transparent. */
.gate-gsi {
  display: flex;
  justify-content: center;
  min-height: 44px;
  color-scheme: light;
}

.gate.is-busy .gate-gsi { opacity: 0.4; pointer-events: none; }

.gate-error {
  margin: 14px 0 0;
  padding: 8px 10px;
  border-left: 2px solid var(--danger);
  background: rgba(210, 86, 63, 0.1);
  font-size: 13px;
  line-height: 1.5;
  text-align: left;
  color: #efc9c1;
}

.gate-error[hidden],
.gate-retry[hidden] { display: none; }

.gate-retry {
  margin-top: 12px;
  padding: 8px 18px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}

.gate-retry:hover,
.gate-retry:focus-visible {
  border-color: var(--accent);
  background: var(--accent-wash);
  color: var(--ink-bright);
  outline: none;
}

.gate-note {
  margin: 24px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  line-height: 1.55;
  color: var(--ink-dim);
}

/* The idle screen (gate.js showIdle, src/idle.js): why, and the way back. */
.gate.is-idle .gate-tag { margin-bottom: 0; }
.gate.is-idle .gate-note:first-of-type { margin-top: 16px; }
.gate-back {
  margin-top: 20px;
  border-color: rgba(var(--accent-rgb), 0.6);
  background: var(--accent-wash);
  color: var(--ink-bright);
}
.gate-link {
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.gate-link:hover,
.gate-link:focus-visible { color: var(--ink-bright); outline: none; }

/* The minute before the game goes idle: a countdown, gone on any input. */
.idle-warn {
  position: fixed;
  top: 14px;
  left: 50%;
  z-index: 96;
  max-width: min(560px, calc(100vw - 32px));
  padding: 10px 16px;
  transform: translateX(-50%);
  border: 1px solid var(--amber);
  background: rgba(22, 17, 7, 0.96);
  box-shadow: 0 16px 40px -12px rgba(0, 0, 0, 0.9);
  color: var(--ink-bright);
  font-size: 14px;
  line-height: 1.4;
  text-align: center;
}
.idle-warn[hidden] { display: none; }

@media (max-width: 420px) {
  .gate-card { padding: 28px 18px 20px; }
  .gate-title { font-size: 21px; letter-spacing: 0.14em; text-indent: 0.14em; }
}

/* ---- Assets window (ui/assets.js) ---- */
/* After EVE's Assets window: a row per star system you own something in,
   opening to its stations (each with Enter) and miners. The toolbar is the
   Favorites window's (.fav-toolbar), and the rows wear the same skin. */
.assets { display: flex; flex-direction: column; gap: 10px; min-height: 100%; }
.assets .fav-toolbar[hidden] { display: none; }
.asset-list { flex: 1 1 auto; }
.asset-rows { display: flex; flex-direction: column; gap: 6px; }
.asset-sys {
  border: 1px solid var(--line);
  border-left: 2px solid var(--t1);
  background: rgba(150, 196, 224, 0.03);
}
.asset-sys.is-open { border-left-color: var(--accent); }
.asset-head { display: flex; align-items: center; gap: 8px; padding: 8px 10px 8px 6px; cursor: pointer; }
.asset-head:hover { background: var(--accent-wash); }
.asset-toggle {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.asset-toggle::before { content: "▾"; transition: transform 150ms var(--ease); }
.asset-toggle[aria-expanded="false"]::before { transform: rotate(-90deg); }
.asset-toggle:hover:not(:disabled),
.asset-toggle:focus-visible { color: var(--ink-bright); border-color: var(--line-strong); outline: none; }
.asset-toggle:disabled { cursor: default; opacity: 0.6; }
.asset-head-main { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; }
.asset-name { min-width: 0; overflow: hidden; font-size: 15px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
.asset-sum { font-size: 12px; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.asset-body { display: grid; gap: 10px; padding: 10px; border-top: 1px solid var(--line); }
.asset-station { display: grid; gap: 8px; padding: 8px; border: 1px solid var(--line); background: rgba(2, 4, 6, 0.35); }
.asset-station-head { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 10px; }
.asset-station-text,
.asset-miner-text { display: grid; gap: 2px; min-width: 0; }
.asset-station-name { display: flex; align-items: baseline; gap: 8px; min-width: 0; font-size: 14px; color: var(--ink-bright); }
.asset-station-link { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.asset-station-num { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); white-space: nowrap; }
.asset-station-where,
.asset-miner-where { font-size: 12px; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.asset-slots { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.asset-slots li { display: contents; }
.asset-slot-name { color: var(--ink-bright); }
.asset-slot-what { min-width: 0; max-width: 26ch; overflow: hidden; color: var(--ink-dim); text-overflow: ellipsis; white-space: nowrap; }
/* A long slot chip shrinks rather than pushing the window sideways. */
.asset-body,
.asset-station { grid-template-columns: minmax(0, 1fr); }
.asset-slot { max-width: 100%; min-width: 0; }
/* Used up for now: kept in its place, faded. */
.asset-item.is-empty { opacity: 0.45; }
.asset-stock { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 4px; margin: 0; padding: 0; list-style: none; }
.asset-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  padding: 3px 8px 3px 4px;
  border: 1px solid var(--line);
  background: rgba(2, 4, 6, 0.45);
  font-size: 12px;
  color: var(--ink);
}
.asset-item:hover { border-color: var(--line-strong); }
.asset-item-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.asset-item-count { color: var(--ink-bright); font-weight: 600; font-variant-numeric: tabular-nums; }
.asset-item.is-full .asset-item-count { color: var(--amber); }
.asset-subhead {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 4px 0 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.asset-miners { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.asset-miner {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 6px 10px;
  padding-bottom: 6px;
  border-bottom: 1px dashed var(--line);
}
.asset-miner:last-child { padding-bottom: 0; border-bottom: 0; }
.asset-miner-name { font-size: 13px; color: var(--ink-bright); }
.asset-gather { grid-column: 2; display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.asset-empty .factory-icon { opacity: 0.8; }

@media (max-width: 720px) {
  .asset-station-head { grid-template-columns: auto minmax(0, 1fr); }
  .asset-enter { grid-column: 1 / -1; }
  .asset-gather { grid-column: 1 / -1; }
  .asset-stock { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
}

/* ---- Title screen (gate.js) ----
 * The signed-out screen (user request 2026-10-11, after a wireframe): the
 * name and logo across the top; below, what the game is (left), the way in
 * (middle, narrower and lower) and live player stats (right, GET
 * /api/stats). Two rows under the name on a tablet, one column on a phone
 * with the way in first. The idle screen keeps the single .gate-card. */
.gate.is-title { padding: clamp(16px, 4vh, 44px) 24px; }

.title {
  position: relative; /* over the sky */
  display: grid;
  width: min(1280px, 100%);
  grid-template-columns: minmax(0, 1fr) minmax(300px, 340px) minmax(0, 1fr);
  grid-template-areas:
    "notice notice notice"
    "banner banner banner"
    "about signin stats"
    "legal legal legal";
  gap: clamp(18px, 3.2vh, 32px) 28px;
}

/* Early testing: wipes will happen (user request 2026-10-11). Above it all. */
.title-notice {
  grid-area: notice;
  justify-self: center;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: min(880px, 100%);
  margin: 0;
  padding: 10px 16px;
  border: 1px solid rgba(233, 180, 76, 0.55);
  background: rgba(233, 180, 76, 0.1);
  color: #f0cf8a;
  font-size: 13px;
  line-height: 1.5;
}
.title-notice svg { flex: none; margin-top: 1px; color: #e9b44c; }
.title-notice strong { color: #ffe2a6; font-weight: 700; letter-spacing: 0.04em; }

/* The name and logo: a band across the top, its rules fading at the ends. */
.title-banner {
  grid-area: banner;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(18px, 2.4vw, 36px);
  padding: clamp(16px, 3.4vh, 38px) 24px;
  border-block: 1px solid transparent;
  border-image: linear-gradient(90deg, transparent, var(--line-strong) 22%, var(--line-strong) 78%, transparent) 1;
  background: linear-gradient(90deg, transparent, rgba(10, 17, 24, 0.7) 22%, rgba(10, 17, 24, 0.7) 78%, transparent);
}

/* A short lit bar under the middle of the band, like the cards' top rule. */
.title-banner::after {
  content: "";
  position: absolute;
  bottom: -1px;
  left: 50%;
  width: min(260px, 40%);
  height: 2px;
  transform: translateX(-50%);
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
}

.title-logo {
  flex: none;
  width: clamp(64px, 6.6vw, 112px);
  color: var(--accent);
  filter: drop-shadow(0 0 14px var(--accent-glow));
}
.title-logo svg { display: block; width: 100%; height: auto; }

.title-name { min-width: 0; }

.title-h1 {
  margin: 0;
  font-weight: 600;
  line-height: 1;
  text-transform: uppercase;
  color: var(--ink-bright);
}
/* Both lines are exactly as tall as their capitals (1cap), so the logo
   centers on the letters themselves, not on the empty line space under them. */
.title-pre {
  display: block;
  margin: 0 0 0.85em 0.12em;
  font-size: clamp(14px, 1.45vw, 24px);
  line-height: 1cap;
  letter-spacing: 0.62em;
  color: var(--accent);
}
.title-main {
  display: block;
  /* The letter spacing after the last E is not part of the word: without
     the negative margin the logo and name sit left of center. */
  margin-right: -0.3em;
  /* By height too, so a short laptop screen still fits it all in. */
  font-size: clamp(44px, min(6.2vw, 10vh), 104px);
  line-height: 1cap;
  letter-spacing: 0.3em;
  text-shadow: 0 0 30px rgba(var(--accent-rgb), 0.35);
}

/* The three boxes under it share the sign-in card's look. */
.title-box {
  position: relative;
  min-width: 0;
  padding: 20px 24px 18px;
  border: 1px solid var(--line-strong);
  background: linear-gradient(180deg, rgba(14, 22, 31, 0.93), rgba(8, 13, 18, 0.93));
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.5);
}
.title-box::before {
  content: "";
  position: absolute;
  top: -1px;
  left: -1px;
  right: -1px;
  height: 2px;
  background: linear-gradient(90deg, var(--accent), transparent);
}
.title-head {
  margin: 0 0 14px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.16em;
  line-height: 1.4;
  text-transform: uppercase;
  color: var(--ink-bright);
}

/* What the game is. */
.title-about { grid-area: about; }
.title-lead {
  margin: 0 0 14px;
  font-size: 16px;
  line-height: 1.45;
  color: var(--ink-bright);
}
.title-list {
  display: grid;
  gap: 9px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.title-list li {
  position: relative;
  padding-left: 20px;
  font-size: 14px;
  line-height: 1.5;
}
.title-list li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 0.5em;
  width: 6px;
  height: 6px;
  border: 1px solid var(--accent);
  transform: rotate(45deg);
}
.title-later {
  margin: 16px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  line-height: 1.55;
  color: var(--ink-dim);
}

/* The way in: the one box lit in the accent. */
.title-signin {
  grid-area: signin;
  align-self: end;
  text-align: center;
  border-color: rgba(var(--accent-rgb), 0.42);
  box-shadow: 0 0 46px -14px rgba(var(--accent-rgb), 0.45), 0 24px 70px rgba(0, 0, 0, 0.5);
}
.title-signin .title-head { text-wrap: balance; }
.title-how {
  margin: 0 0 18px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink);
  text-wrap: balance;
}
.title-signin .gate-note { margin-top: 18px; }
/* No button coming (Google's script failed): no room kept for one. */
.title-signin:has(.gate-error:not([hidden])) .gate-gsi:empty { display: none; }
.title-signin .gate-gsi:empty + .gate-error { margin-top: 0; }
/* How the game is letting people in (server/access.js), before sign-in. */
.title-mode {
  margin: -6px 0 16px;
  padding: 8px 10px;
  border: 1px solid rgba(233, 180, 76, 0.45);
  background: rgba(233, 180, 76, 0.08);
  font-size: 12px;
  line-height: 1.5;
  color: #f0cf8a;
  text-wrap: balance;
}
.title-mode[data-mode="beta"] { border-color: rgba(var(--accent-rgb), 0.45); background: var(--accent-wash); color: var(--ink-bright); }
/* A key: before sign-in it waits for one; after, it is redeemed at once. */
.title-key { margin-top: 18px; text-align: left; }
.title-key-label { display: block; margin-bottom: 6px; font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-dim); }
.title-key-row { display: flex; gap: 6px; }
.title-key-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 8px 10px;
  border: 1px solid var(--line-strong);
  background: rgba(2, 4, 6, 0.6);
  color: var(--ink-bright);
  font: inherit;
  font-size: 14px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.title-key-input::placeholder { color: var(--ink-dim); letter-spacing: 0.12em; }
.title-key-input:focus-visible { border-color: var(--accent); outline: none; }
.title-key-go {
  flex: none;
  padding: 8px 14px;
  border: 1px solid rgba(var(--accent-rgb), 0.6);
  background: var(--accent-wash);
  color: var(--ink-bright);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}
.title-key-go:hover,
.title-key-go:focus-visible { border-color: var(--accent); outline: none; }
.title-key-go:disabled { opacity: 0.5; cursor: default; }
.title-key-note { min-height: 1.5em; margin: 6px 0 0; font-size: 12px; line-height: 1.5; color: var(--ink); }
.title-key-note:empty { min-height: 0; margin: 0; }
/* Signed in, not in yet: why, and the ways in. */
.title-signin.is-locked { border-color: rgba(233, 180, 76, 0.5); box-shadow: 0 0 46px -14px rgba(233, 180, 76, 0.4), 0 24px 70px rgba(0, 0, 0, 0.5); }
.title-buy {
  width: 100%;
  padding: 10px 18px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
/* Buying (server/payments.js): the price, the Terms box, then the button
   to Stripe, lit like the other ways in once the box is ticked. */
.title-buy-box { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.title-price { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink); }
.title-price b { color: var(--ink-bright); font-size: 18px; font-weight: 600; letter-spacing: 0.02em; }
.title-agree { display: flex; gap: 8px; align-items: flex-start; text-align: left; font-size: 12px; line-height: 1.5; color: var(--ink); cursor: pointer; }
.title-agree input { flex: none; width: 16px; height: 16px; margin: 1px 0 0; accent-color: var(--accent); cursor: pointer; }
.title-agree a { color: var(--accent); }
.title-buy-box .title-buy:not(:disabled) {
  border-color: rgba(var(--accent-rgb), 0.6);
  background: var(--accent-wash);
  color: var(--ink-bright);
  cursor: pointer;
}
.title-buy-box .title-buy:not(:disabled):hover,
.title-buy-box .title-buy:not(:disabled):focus-visible { border-color: var(--accent); outline: none; }
.title-buy-box .title-buy:disabled { opacity: 0.55; cursor: default; }
.title-buy-note { min-height: 1.5em; margin: 0; font-size: 12px; line-height: 1.5; color: var(--ink-dim); }
.title-who { color: var(--ink-bright); font-weight: 600; overflow-wrap: anywhere; }
/* Closed testing: one email when the beta opens (server/betamail.js). */
.title-notify { margin-top: 4px; }
.title-notify-go {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid rgba(var(--accent-rgb), 0.6);
  background: var(--accent-wash);
  color: var(--ink-bright);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}
.title-notify-go:hover,
.title-notify-go:focus-visible { border-color: var(--accent); outline: none; }
.title-notify-go[aria-pressed="true"] { border-color: rgba(var(--accent-rgb), 0.35); background: transparent; color: var(--accent); cursor: default; }
.title-notify-go:disabled { opacity: 0.6; cursor: default; }
.title-notify-note { margin: 6px 0 0; font-size: 12px; line-height: 1.5; color: var(--ink); }
.title-notify-off { margin-left: 4px; }
.deva-mail-line { margin: 0; }

/* Live counts: tiles two across, a big number over its label, the rows
   sharing out the box's height so it fills like the description beside it. */
.title-stats { grid-area: stats; display: flex; flex-direction: column; }
.title-nums {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: minmax(74px, 1fr);
  gap: 0 20px;
  margin: 0;
}
.title-num {
  display: flex;
  flex-direction: column-reverse; /* the number over its label */
  justify-content: center;
  gap: 6px;
  min-width: 0;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
/* An odd one out at the end takes the whole row. */
.title-num:last-child:nth-child(odd) { grid-column: 1 / -1; }
.title-num dt {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.title-num dd {
  margin: 0;
  font-size: clamp(26px, 2.3vw, 38px);
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--ink-bright);
}
.title-stats[aria-busy="true"] dd,
.title-stats.is-quiet dd { color: var(--ink-dim); }
.title-stats.has-online [data-stat="online"]::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 9px;
  border-radius: 50%;
  background: #5fd17a;
  box-shadow: 0 0 8px rgba(95, 209, 122, 0.8);
  vertical-align: 0.2em;
  animation: title-online 2.4s ease-in-out infinite;
}
@keyframes title-online { 50% { opacity: 0.45; } }
.title-when {
  margin: auto 0 0;
  padding-top: 12px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-dim);
}

@media (prefers-reduced-motion: reduce) {
  .title-stats.has-online [data-stat="online"]::before { animation: none; }
}

/* A tablet: the way in on a row of its own, the other two side by side.
   Up to 1120 px, since three columns any narrower push the sign-in button
   below the fold (an iPad in landscape is 1024 wide). */
@media (max-width: 1120px) {
  .title {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "notice notice"
      "banner banner"
      "signin signin"
      "about stats"
      "legal legal";
  }
  .title-signin { justify-self: center; width: min(400px, 100%); }
}

/* A phone: one column, the way in straight after the name. */
@media (max-width: 720px) {
  .gate.is-title { padding: 16px 16px 28px; }
  .title {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "notice" "banner" "signin" "about" "stats" "legal";
    gap: 16px;
  }
  .title-banner { flex-direction: column; gap: 12px; padding: 20px 4px 22px; text-align: center; }
  .title-logo { width: 64px; }
  /* Centered letter-spaced lines: the indent puts the trailing space back. */
  .title-pre { margin: 0 0 0.85em; font-size: 14px; letter-spacing: 0.5em; text-indent: 0.5em; }
  .title-main { margin-right: 0; font-size: clamp(40px, 14vw, 64px); letter-spacing: 0.24em; text-indent: 0.24em; }
  .title-signin { width: 100%; }
  .title-box { padding: 18px 16px 16px; }
}

/* ---- Sidebar order (Settings) ---- */

/* Settings → Sidebar → Button order: the list sits under its label, one row
   per button as the sidebar shows it, divider rows between groups. */
.settings-pref.is-order { flex-direction: column; align-items: stretch; gap: 10px; }
/* In a column, the usual 200px basis would be a height. */
.settings-pref.is-order .settings-pref-text { flex: 0 0 auto; }
.sbo { display: grid; gap: 8px; min-width: 0; }
.sbo-keys { margin: 0; }

.sbo-list {
  max-width: 380px;
  margin: 0;
  padding: 4px;
  list-style: none;
  border: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.35);
}

.sbo-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 36px;
  padding-right: 2px;
  color: var(--ink);
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
}

.sbo-row:hover,
.sbo-row:focus-within { background: rgba(150, 196, 224, 0.05); }

.sbo-row.is-divider { min-height: 28px; }

.sbo-grip {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 28px;
  height: 32px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink-dim);
  cursor: grab;
  touch-action: none; /* a finger on the grip drags instead of scrolling */
}

.sbo-grip:hover { color: var(--ink-bright); }
.sbo-grip:focus-visible { color: var(--ink-bright); outline: 1px solid var(--accent); outline-offset: -2px; }

.sbo-glyph { display: grid; place-items: center; pointer-events: none; }

/* Its name in the sidebar's own lettering, unless the pilot chose a font
   (inline style from the sidebar). */
.sbo-name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 13px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* A divider: the word, then the hairline the sidebar draws between groups. */
.sbo-divider {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  color: var(--ink-dim);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.sbo-divider::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: linear-gradient(90deg, var(--line-strong), transparent);
}

.sbo-move {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
}

.sbo-move:hover:not(:disabled),
.sbo-move:focus-visible { border-color: var(--line-strong); color: var(--ink-bright); outline: none; }
.sbo-move:disabled { opacity: 0.25; cursor: default; }
.sbo-remove:hover:not(:disabled),
.sbo-remove:focus-visible { border-color: var(--danger); color: #ffd9cf; }

/* The row in hand rides over the others. */
.sbo-row.is-dragging {
  z-index: 2;
  background: var(--panel);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(var(--accent-rgb), 0.55);
}

.sbo-row.is-dragging .sbo-grip { color: var(--accent); }
.sbo-list.is-sorting,
.sbo-list.is-sorting * { cursor: grabbing; }

.sbo-status { min-height: 1.45em; margin: 0; }
.sbo-status:empty { display: none; }

/* Opened from the sidebar's "Reorder sidebar…": a moment's glow. */
.settings-pref.is-sought { animation: sbo-sought 1.6s var(--ease); }

@keyframes sbo-sought {
  0%, 40% { background: var(--accent-wash); box-shadow: inset 2px 0 0 var(--accent); }
  100% { background: transparent; box-shadow: inset 2px 0 0 transparent; }
}

/* Fingers: bigger targets, and the list as wide as the screen. */
@media (max-width: 720px), (pointer: coarse) {
  .sbo-list { max-width: none; }
  .sbo-row { min-height: 44px; }
  .sbo-row.is-divider { min-height: 40px; }
  .sbo-grip { width: 40px; height: 44px; }
  .sbo-move { width: 38px; height: 38px; }
}

/* No keys on a touch screen; the line still describes the grips to a screen
   reader (aria-describedby reads hidden text). */
@media (pointer: coarse) {
  .sbo-keys { display: none; }
}

/* ---- Dev Panel → Access (ui/devaccess.js) ---- */
/* Who may play, the friends list, keys and passes: one panel each, like the
   Notes tab's new-note box. Choices (modes, kinds of key) are cards with a
   dot; a mode clicked once goes red until the second click. */
.deva { display: flex; flex-direction: column; gap: 12px; }
.deva-section { display: flex; flex-direction: column; gap: 8px; min-width: 0; padding: 12px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.35); }
.deva-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.deva-head .devs-heading { margin: 0; }
.deva-sub { font-size: 12px; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.deva-choices { display: grid; gap: 6px; }
.deva-choices.is-two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.deva-choice {
  display: grid;
  grid-template-columns: 14px minmax(0, 1fr);
  align-items: start;
  gap: 2px 10px;
  padding: 8px 10px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.deva-choice:hover,
.deva-choice:focus-visible { border-color: var(--accent); outline: none; }
.deva-choice[aria-checked="true"] { border-color: rgba(var(--accent-rgb), 0.6); background: var(--accent-wash); cursor: default; }
.deva-choice.is-armed { border-color: var(--danger); background: rgba(210, 86, 63, 0.12); }
.deva-dot { grid-row: 1 / span 3; width: 14px; height: 14px; margin-top: 1px; border: 1px solid var(--line-strong); border-radius: 50%; }
.deva-choice[aria-checked="true"] .deva-dot { border-color: var(--accent); background: radial-gradient(circle, var(--accent) 0 3.5px, transparent 4.5px); }
.deva-choice.is-armed .deva-dot { border-color: var(--danger); }
.deva-choice-name { font-size: 12px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-bright); }
.deva-choice-text { font-size: 12px; line-height: 1.45; color: var(--ink-dim); }
.deva-choice[aria-checked="true"] .deva-choice-text { color: var(--ink); }
.deva-choice-confirm { font-size: 12px; font-weight: 600; color: #ffd9cf; }
.deva-warn { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 8px 10px; border: 1px solid rgba(210, 86, 63, 0.45); background: rgba(210, 86, 63, 0.06); }
.deva-warn p { flex: 1 1 260px; margin: 0; font-size: 13px; line-height: 1.45; color: #ffd9cf; }
.deva-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.deva-row > .win-input { flex: 1 1 180px; width: auto; min-width: 0; }
.deva-field { display: inline-flex; align-items: center; gap: 8px; }
.deva-label { font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); white-space: nowrap; }
.deva-cap { width: 110px; }
.deva-count { width: 72px; }
.deva-places { font-size: 12px; color: var(--ink); font-variant-numeric: tabular-nums; }
.deva-places.is-full { color: var(--amber); }
.devp-tag.is-warn { border-color: var(--amber); color: var(--amber); }
.deva-make { display: flex; flex-direction: column; gap: 8px; }
.deva-give > .win-input { flex: 1 1 160px; }
.deva-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.deva-bar > .deva-find { flex: 1 1 200px; width: auto; min-width: 0; }
.deva-find { font-size: 13px; }
.deva-reveal { padding: 4px 10px; font-size: 11px; }
.deva-reveal[aria-pressed="true"] { border-color: rgba(224, 168, 60, 0.7); background: rgba(224, 168, 60, 0.12); color: var(--amber); }
.deva-reveal-note { margin: 0; font-size: 12px; color: var(--amber); }
.deva-list { display: grid; margin: 0; padding: 0; list-style: none; }
.deva-item { display: grid; gap: 2px; padding: 7px 0; border-bottom: 1px solid var(--line); min-width: 0; }
.deva-item:last-child { border-bottom: 0; }
.deva-item-main { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; min-width: 0; }
.deva-item-main .win-button { padding: 4px 9px; font-size: 11px; }
.deva-item-sub { display: flex; flex-wrap: wrap; gap: 2px 12px; font-size: 12px; color: var(--ink-dim); }
.deva-email { font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; font-size: 13px; color: var(--ink-bright); overflow-wrap: anywhere; }
.deva-email.is-full { color: var(--amber); }
.deva-pilot { color: var(--ink); }
.deva-pilot.is-none { color: var(--ink-dim); font-style: italic; }
.deva-pilot.is-main { font-size: 13px; color: var(--ink-bright); overflow-wrap: anywhere; }
.deva-code { font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; font-size: 14px; letter-spacing: 0.06em; color: var(--ink-bright); white-space: nowrap; }
.deva-key.is-revoked .deva-code,
.deva-made-code.is-revoked .deva-code { color: var(--ink-dim); text-decoration: line-through; }
.deva-key.is-used .deva-code,
.deva-made-code.is-used .deva-code { color: var(--ink); }
.deva-key-note { font-size: 12px; color: var(--ink); overflow-wrap: anywhere; }
.deva-status.is-unused { color: #5fd17a; }
.deva-status.is-used { color: var(--ink); }
.deva-status.is-revoked { color: #f0907a; }
.deva-more { justify-self: start; align-self: flex-start; margin-top: 6px; }
/* The keys just made: big, in full, with Copy, until Done. */
.deva-made { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; border: 1px solid rgba(95, 209, 122, 0.5); border-left: 2px solid #5fd17a; background: rgba(95, 209, 122, 0.06); }
.deva-made-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.deva-made-head b { font-size: 13px; color: var(--ink-bright); }
.deva-made-codes { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 6px; margin: 0; padding: 0; list-style: none; }
.deva-made-code { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 8px; border: 1px solid var(--line-strong); background: rgba(5, 8, 12, 0.6); }
.deva-made-code .deva-code { font-size: 17px; }
.deva-made-code .win-button { padding: 4px 9px; font-size: 11px; }
@media (max-width: 520px) {
  .deva-choices.is-two { grid-template-columns: minmax(0, 1fr); }
  .deva-section { padding: 10px; }
  /* The box and its button stay on one line; the keys' note gets a line. */
  .deva-give > .win-input { flex-basis: 110px; }
  .deva-make .deva-note { flex-basis: 100%; }
}

/* ---- Resources a miner can't mine (src/mining.js canMine): on its planet
   all the same, grayed out after the ones it can, in the system view's
   panel and the Factory Floor's chips and split editor. */
.sysview-res-row.is-locked,
.factory-gather-item.is-locked,
.factory-split-row.is-locked { opacity: 0.45; filter: grayscale(0.85); }
.sysview-res-row.is-locked .sysview-res-name small { color: var(--ink-dim); }
/* Deposits that ran out (src/deposits.js), and what is left of the rest. */
.sysview-res-row.is-used-up { opacity: 0.5; filter: grayscale(1); }
.sysview-res-row.is-used-up .sysview-res-name small { color: var(--ink-dim); }
.sysview-res-left.is-low { color: var(--amber); }
.sysview-res-share small.sysview-res-lasts { font-variant-numeric: tabular-nums; }
.factory-gather-item.is-locked { border-style: dashed; }
.factory-split-lock { grid-column: 3 / -1; font-size: 11px; letter-spacing: 0.04em; color: var(--ink-dim); }
@media (max-width: 520px) {
  .factory-split-lock { grid-column: 2 / -1; grid-row: 2; }
}
/* The map card's Specialized and Rare rows, in their resources' tier colors. */
.map-card-res[data-tier="1"] { color: var(--t1); }
.map-card-res[data-tier="2"] { color: var(--t2); }
.map-card-res[data-tier="3"] { color: var(--t3); }
.map-card-res[data-tier="4"] { color: var(--t4); }

/* A bay belt's "Brought in": the picker of the edge input feeding it, or a
   row for each of several (2026-10-13). */
.bay-brought { display: grid; gap: 8px; }
.bay-brought-list { display: grid; gap: 4px; }
.bay-brought-row {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.5);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.bay-brought-row:hover,
.bay-brought-row:focus-visible { border-color: var(--accent); outline: none; }
.bay-brought-row small { font-size: 11px; color: var(--ink-dim); }
.bay-brought-name { font-weight: 600; color: var(--ink-bright); }
.bay-brought-none { display: grid; place-items: center; width: 22px; height: 22px; border: 1px dashed var(--line); color: var(--ink-dim); font-weight: 600; }

/* ---- Logistics (2026-10-13): goods between your own stations, and
   resources your miners mine once a better miner is unlocked
   (ui/logistics.js). An export sending to your stations is green like one
   selling; its slot wears two arrows. "Mined later" is amber and dashed,
   with a padlock, like other locked things: in the item picker beside the
   accent "here" look, and on a request from miners waiting for that miner
   (state `later`), instead of a stuck one's red. */
.fslot.is-sending { border-color: rgba(95, 209, 122, 0.6); }
.fslot.is-sending .fslot-bar i { background: var(--slot-ok); }
.fslot.is-later { border-style: dashed; border-color: rgba(224, 168, 60, 0.75); }
.fslot.is-later .fslot-bar i { background: var(--amber); }
.fslot.is-later .item-icon { opacity: 0.6; filter: grayscale(0.6) drop-shadow(0 1px 1px rgba(0, 0, 0, 0.7)); }
.fslot-lock,
.fslot-route {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 11px;
  height: 11px;
  fill: none;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
  filter: drop-shadow(0 0 1px #000);
}
.fslot-lock { stroke: var(--amber); }
.fslot-route { stroke: var(--accent); }
.flog-pick.is-later {
  position: relative;
  border-style: dashed;
  border-color: rgba(224, 168, 60, 0.55);
  background: rgba(224, 168, 60, 0.04);
}
.flog-pick.is-later .item-icon { opacity: 0.55; filter: grayscale(0.7); }
.flog-pick.is-later .flog-pick-name { color: var(--ink); }
.flog-pick.is-later .flog-pick-note { color: var(--amber); }
.flog-pick-lock {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 13px;
  height: 13px;
  fill: none;
  stroke: var(--amber);
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.flog-pick.is-later:hover:not(:disabled),
.flog-pick.is-later:focus-visible { border-color: var(--amber); background: rgba(224, 168, 60, 0.08); }
/* The request dialog's System miners for one: pickable, its words amber. */
.flog-source.is-later .flog-source-detail { color: var(--amber); }

/* Your structures' own names and looks (2026-10-13, ui/structurename.js).
   The point a canvas right-click opens the look editor beside. */
.structure-anchor { position: fixed; width: 1px; height: 1px; pointer-events: none; visibility: hidden; }
.asset-station-name .look-icon { flex: 0 0 auto; margin-right: 4px; vertical-align: -3px; }

/* Color wheel everywhere (2026-10-13, ui/look.js colorChooser): no palette.
   Words for what a color may follow instead (Default, Plain, Match…) above
   an always-open wheel with a brightness slider, R, G and B boxes and a
   hex. Used by the look editor, a bank account's colors, role colors and
   Settings (accent, default name and icon colors). */
.look-means { display: flex; flex-wrap: wrap; gap: 5px; }
.look-mean {
  min-height: 28px;
  padding: 3px 10px;
  border: 1px solid var(--line);
  background: rgba(150, 196, 224, 0.03);
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.03em;
  cursor: pointer;
}
.look-mean:hover { border-color: var(--line-strong); color: var(--ink-bright); }
.look-mean[aria-checked="true"] { border-color: var(--accent); background: var(--accent-wash); color: var(--ink-bright); }
.look-mean:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }
.look-mean:disabled { cursor: default; }
.look-wheel { gap: 12px; max-width: 420px; padding: 10px; }
.look-wheel-side { flex: 1 1 150px; gap: 9px; min-width: 150px; }
.look-wheel .win-input { padding: 4px 7px; font-size: 13px; }
.look-wheel-rgb { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.look-wheel-channel {
  display: flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.look-wheel-channel > span { flex: none; }
.look-wheel-num {
  min-width: 0;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
  text-align: center;
  -moz-appearance: textfield;
  appearance: textfield;
}
/* No spinners: there is no room for them, and Up and Down still step. */
.look-wheel-num::-webkit-inner-spin-button,
.look-wheel-num::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.look-wheel-hexrow .look-wheel-chip { width: 24px; height: 24px; }
/* While a word is chosen the wheel waits, dimmed, until it is touched. */
.look-wheel.is-idle .look-wheel-disc,
.look-wheel.is-idle .look-wheel-side { opacity: 0.55; transition: opacity 120ms var(--ease); }
.look-wheel.is-idle .look-wheel-marker { opacity: 0.45; }
.look-wheel.is-idle:is(:hover, :focus-within) .look-wheel-disc,
.look-wheel.is-idle:is(:hover, :focus-within) .look-wheel-side,
.look-wheel.is-idle:is(:hover, :focus-within) .look-wheel-marker { opacity: 1; }
.look-colors[inert] { opacity: 0.6; }
/* Settings: the label and help, the wheel beside them or under them. */
.settings-pref.is-color { flex-wrap: wrap; align-items: flex-start; }
.settings-color { flex: 0 1 360px; min-width: 0; }

/* Settings → Account → Reset my progress (2026-10-13). */
.settings-reset .settings-row { flex-wrap: wrap; }
.settings-reset-input { flex: 1 1 240px; min-width: 0; max-width: 320px; }

/* The Factory Floor's "Researched in 1 of your 2 stations" line takes a
   row of its own, under the station list, which keeps its full width. */
.factory-machine-build .factory-research-where { flex: 1 0 100%; }

/* Local research (2026-10-13): each project's scope as a small tag beside
   its name (Research window, a lab's panel and project list), and the
   Research window's station picker. */
.research-scope {
  flex: none;
  padding: 0 5px;
  border: 1px solid var(--line);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.12em;
  line-height: 14px;
  text-transform: uppercase;
  color: var(--ink-dim);
  white-space: nowrap;
}
.research-scope.is-global { border-color: rgba(var(--accent-rgb), 0.45); color: var(--accent); }
/* Research bought with credits (2026-10-21: Tier 2 and 3 Buildings): an
   amber Credits tag, the price, what it lets a Building Crafter make, and a
   Buy that takes a second press. */
.research-scope.is-bought { border-color: rgba(224, 168, 60, 0.5); color: var(--amber); }
.research-price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; }
.research-price-amount { font-size: 15px; color: var(--amber); font-variant-numeric: tabular-nums; }
.research-market-note { margin: 0; font-size: 11px; }
.research-buy { min-width: 0; }
/* A finger, or a narrow screen: Buy and Cancel are 40 px targets. */
@media (pointer: coarse), (max-width: 560px) {
  .research-card.is-bought .research-card-queue .win-button { min-height: 40px; padding: 8px 12px; }
}
.research-where {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.35);
}
.research-where-pick { flex: 1 1 220px; min-width: 0; width: auto; }
.research-where-name { flex: 1 1 auto; min-width: 0; font-size: 13px; color: var(--ink-bright); overflow-wrap: anywhere; }
.research-where-note { flex: 1 0 100%; font-size: 11px; color: var(--ink-dim); }
.research-where.is-empty { margin: 0; }
.research-card-where { margin: 0; font-size: 12px; color: var(--ink-dim); }
/* In a lab's project list the tag leads the note line (the row has no room). */
.station-recipe-note .research-scope { display: inline-block; margin-right: 6px; vertical-align: 1px; }

/* Sidebar search + icon size (2026-10-13) ---------------------------------
 *
 * The top of the sidebar is the search (ui/search.js): a magnifying glass
 * while the sidebar is collapsed, the search field itself while it is open.
 * Its panel hangs beside the sidebar in the pilot panel's skin; on a phone it
 * is a sheet over the screen beside the sidebar. The sidebar's icons come in
 * three sizes (Settings → Sidebar → Icon size, neocom.js setIconSize):
 * medium is the sidebar as it always was, and small and large change its
 * width and rows to suit.
 */

.neocom-search {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  transition: color 0.13s var(--ease), background 0.13s var(--ease);
}
.neocom-search:hover,
.neocom-search:focus-visible { color: var(--ink-bright); background: var(--accent-wash); outline: none; }
.neocom-search:focus-visible { box-shadow: inset 0 0 0 1px var(--accent); }
.neocom-search[aria-expanded="true"] {
  color: var(--ink-bright);
  background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.22), rgba(var(--accent-rgb), 0.04));
}
.neocom.is-open .neocom-search,
.neocom:not(.is-open) .neocom-find { display: none; }
.neocom-find { flex: 1 1 auto; min-width: 0; }
.neocom.is-open .neocom-brand { padding: 0 10px 0 8px; }

/* The field: in the open sidebar, or at the top of the panel. */
.search-field {
  display: flex;
  align-items: center;
  gap: 7px;
  height: 32px;
  padding: 0 7px 0 8px;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.6);
  color: var(--ink-dim);
  cursor: text;
  transition: border-color 0.13s var(--ease), color 0.13s var(--ease);
}
.neocom-find .search-field { height: 30px; }
.search-field:hover { border-color: rgba(var(--accent-rgb), 0.45); }
.search-field:focus-within { border-color: var(--accent); color: var(--accent); }
.search-field-glass { flex: 0 0 auto; display: grid; place-items: center; }
.search-field-glass svg { width: 15px; height: 15px; }
.neocom-brand .search-field svg { filter: none; }
.search-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink-bright);
  font: inherit;
  font-size: 14px;
  letter-spacing: 0.02em;
  outline: none;
}
.search-input::placeholder { color: var(--ink-dim); font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase; }
.search-field-key {
  flex: 0 0 auto;
  padding: 0 4px;
  border: 1px solid var(--line-strong);
  font: inherit;
  font-size: 10px;
  line-height: 15px;
  letter-spacing: 0.06em;
  color: var(--ink-dim);
}
.search-field:focus-within .search-field-key { display: none; }

/* The panel, beside the sidebar. */
.search-panel {
  position: fixed;
  z-index: 55; /* over windows and toasts; under the sidebar's labels, the pilot panel and menus */
  top: 6px;
  display: flex;
  flex-direction: column;
  max-height: calc(100% - 12px);
  background: linear-gradient(180deg, rgba(20, 31, 42, 0.98), rgba(10, 16, 22, 0.98));
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
  box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.8);
  color: var(--ink);
}
.search-panel[hidden],
.search-head[hidden] { display: none; }
.search-head {
  flex: 0 0 auto;
  padding: 9px 14px 9px 10px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(90deg, var(--accent-wash), transparent 75%);
}
.search-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 4px 0 8px; }
.search-group + .search-group { margin-top: 2px; }
.search-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin: 0;
  padding: 9px 16px 4px 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
}
.search-count { font-weight: 400; letter-spacing: 0.06em; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
/* Results sit indented under their heading, as in the wireframe. */
.search-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 8px 0 20px;
  padding: 5px 8px;
  border-left: 2px solid transparent;
  color: var(--ink);
  cursor: pointer;
}
.search-row.is-active {
  border-left-color: var(--accent);
  background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.16), rgba(var(--accent-rgb), 0.03));
}
.search-icon { flex: 0 0 auto; display: grid; place-items: center; width: 24px; height: 24px; color: var(--ink-dim); }
.search-row.is-active .search-icon { color: var(--accent); }
.search-icon .neocom-icon,
.search-icon .neocom-icon svg,
.search-glyph svg { width: 18px; height: 18px; }
.search-icon > svg { width: 22px; height: 22px; }
.search-glyph { display: grid; place-items: center; }
.search-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.search-name { font-size: 14px; color: var(--ink-bright); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.search-sub { font-size: 11px; letter-spacing: 0.03em; color: var(--ink-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Why something was found when its name doesn't say: a few of its words. */
.search-quote {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  font-size: 12px;
  line-height: 1.35;
  color: var(--ink);
  opacity: 0.85;
}
.search-note { flex: 0 0 auto; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--amber); white-space: nowrap; }
.search-mark { padding: 0; background: rgba(var(--accent-rgb), 0.28); color: var(--ink-bright); }
.search-all { padding: 4px 8px 4px 42px; font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); }
.search-all.is-active { color: var(--ink-bright); }
/* A search run only when asked for (nearby space). */
.search-button .search-name { font-size: 13px; color: var(--accent); }
.search-button .search-icon svg { width: 16px; height: 16px; filter: none; }
.search-button.is-active .search-name { color: var(--ink-bright); }
.search-cap { margin: 4px 16px 0 62px; font-size: 11px; color: var(--ink-dim); }
/* Every kind but Exact matches starts folded to its heading (user request
   2026-10-15); the heading opens it, with a turning chevron. */
.search-heading.is-fold {
  justify-content: flex-start;
  margin: 0 8px 0 0;
  padding: 7px 8px 7px 12px;
  border-left: 2px solid transparent;
  cursor: pointer;
}
.search-heading.is-fold .search-title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-fold {
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  margin: 0 2px 2px 0;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
}
.search-heading.is-fold[aria-expanded="true"] .search-fold { transform: rotate(45deg); margin-bottom: 4px; }
.search-heading.is-fold[aria-expanded="false"] { color: var(--ink); }
.search-heading.is-fold.is-active {
  border-left-color: var(--accent);
  background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.16), rgba(var(--accent-rgb), 0.03));
  color: var(--ink-bright);
}
.search-group.is-exact { padding-bottom: 4px; border-bottom: 1px solid var(--line); margin-bottom: 4px; }
/* An exact match's own kind, at the end of its row. */
.search-kind { flex: 0 0 auto; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); white-space: nowrap; }
.search-row.is-active .search-kind { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
  .search-fold { transition: none; }
}
.search-hint,
.search-none { margin: 0; padding: 14px 16px 8px; font-size: 13px; line-height: 1.5; color: var(--ink-dim); }
.search-hint p { margin: 0 0 8px; }
.search-foot {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 0;
  padding: 6px 12px;
  border-top: 1px solid var(--line);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
}
.search-keys { white-space: pre; }
.search-foot kbd {
  display: inline-block;
  min-width: 16px;
  margin-right: 3px;
  padding: 0 4px;
  border: 1px solid var(--line-strong);
  font: inherit;
  font-size: 10px;
  line-height: 14px;
  text-align: center;
  color: var(--ink);
}
.search-busy { color: var(--accent); }
.search-busy[hidden] { display: none; }

/* A Help section the search opened at: a moment's glow. */
@keyframes search-sought {
  from { box-shadow: inset 2px 0 0 var(--accent), inset 0 0 0 999px rgba(var(--accent-rgb), 0.14); }
  to { box-shadow: inset 2px 0 0 transparent, inset 0 0 0 999px transparent; }
}
.help-section.is-sought { animation: search-sought 1.6s var(--ease); }
.reduce-motion .help-section.is-sought { animation: none; }

@media (max-width: 720px) {
  .search-panel {
    top: 0;
    right: 0;
    bottom: 0;
    max-height: none;
    border-top: 0;
    border-bottom: 0;
    clip-path: none;
  }
  .search-input { font-size: 16px; } /* a phone zooms in on anything smaller */
  .search-keys,
  .search-field-key { display: none; }
  .search-row { margin-left: 12px; padding-top: 7px; padding-bottom: 7px; }
}

/* Icon size: the rail's width and rows, the icons, the search, the pilot,
   the cog and the badges, for small and large. */
.neocom[data-icons="small"] { --rail-w: 44px; --rail-w-open: 200px; --row-h: 34px; }
.neocom[data-icons="large"] { --rail-w: 62px; --rail-w-open: 230px; --row-h: 52px; }
.neocom[data-icons="small"] .neocom-icon,
.neocom[data-icons="small"] .neocom-icon svg { width: 16px; height: 16px; }
.neocom[data-icons="large"] .neocom-icon,
.neocom[data-icons="large"] .neocom-icon svg { width: 26px; height: 26px; }
.neocom[data-icons="small"] .neocom-item { gap: 10px; }
.neocom[data-icons="large"] .neocom-item { gap: 14px; }
.neocom[data-icons="small"] .neocom-text { font-size: 12px; }
.neocom[data-icons="large"] .neocom-text { font-size: 14px; }
.neocom[data-icons="small"] .neocom-brand { height: 40px; }
.neocom[data-icons="large"] .neocom-brand { height: 54px; }
.neocom[data-icons="small"] .neocom-search svg { width: 15px; height: 15px; }
.neocom[data-icons="large"] .neocom-search svg { width: 23px; height: 23px; }
.neocom[data-icons="large"] .neocom-find .search-field { height: 36px; }
.neocom[data-icons="small"] .neocom-pilot { height: 50px; }
.neocom[data-icons="large"] .neocom-pilot { height: 66px; }
.neocom[data-icons="small"] .neocom-portrait { width: 28px; height: 28px; }
.neocom[data-icons="large"] .neocom-portrait { width: 38px; height: 38px; }
.neocom[data-icons="large"] .neocom-portrait > svg { width: 22px; height: 22px; }
.neocom[data-icons="small"] .neocom-cog { width: 26px; height: 26px; }
.neocom[data-icons="large"] .neocom-cog { width: 36px; height: 36px; }
/* Small: the badge keeps to the rail's right edge, a size down, so "99+"
   fits inside 44 px and leaves the icon showing. */
.neocom[data-icons="small"]:not(.is-open) .neocom-item .neocom-badge {
  top: 2px; left: auto; right: 2px; min-width: 14px; padding: 0 2px; font-size: 9px; line-height: 13px;
}
.neocom[data-icons="large"]:not(.is-open) .neocom-item .neocom-badge { top: 7px; left: 34px; }
.neocom[data-icons="small"]:not(.is-open) .neocom-foot { padding-left: 2px; padding-right: 2px; }
.neocom[data-icons="small"]:not(.is-open) .neocom-clock { font-size: 9px; letter-spacing: 0; }
.neocom[data-icons="large"]:not(.is-open) .neocom-clock { font-size: 12px; }

/* ---- Station view art (2026-10-14, the station view overhaul) ----------
   The station and the modules docked round it (ui/stationart.js draws them,
   ui/stationview.js places them). Colors that follow the accent or a
   machine's state are set here, so a new accent restyles it all without a
   redraw. Everything that moves is a CSS animation of transform or opacity,
   which the compositor runs with no script and no repaint; none runs for
   prefers-reduced-motion or the Reduce motion setting, and they pause while
   a bay's floor covers the view (.is-covered, set by stationview.js). */

/* Gradient stops in the station's color. */
.sv-a { stop-color: var(--accent-ink); }

/* Brass for what is drawn in lines and dots, the same shades as the
   facets' (stationart.js SHADES.brass), darkest first. */
.stationview {
  --sv-brass-0: #36230e;
  --sv-brass-1: #5e3f17;
  --sv-brass-2: #875f25;
  --sv-brass-3: #ad8139;
  --sv-brass-4: #cb9f52;
  --sv-brass-5: #e2c27c;
}

/* The accent where it marks something to read (a selection, a word, a
   badge): any color off the wheel, lifted where it is too dark to see on
   the dark station (#101010 would vanish). Its own hue, at least this light;
   a mix with white where the browser can't do that. */
.stationview { --accent-ink: var(--accent); }
@supports (color: color-mix(in srgb, red, white)) {
  .stationview { --accent-ink: color-mix(in srgb, var(--accent), #fff 35%); }
}
@supports (color: oklch(from red max(l, 0.5) c h)) {
  .stationview { --accent-ink: oklch(from var(--accent) max(l, 0.74) c h); }
}

/* The halo under everything brightens while the station is pointed at. */
.station-halo { opacity: 0.8; transition: opacity 0.2s; pointer-events: none; }
.station-svg:has(.station-hub:hover) .station-halo,
.station-svg:has(.station-hub:focus-visible) .station-halo { opacity: 1; }
.station-hub-focus { stroke: var(--accent-ink); stroke-width: 1; stroke-dasharray: 2 5; opacity: 0; transition: opacity 0.15s; }
.station-hub:focus-visible .station-hub-focus { opacity: 0.7; }

/* Metal: the facets' own shades are set where they are drawn (stationart.js
   SHADES); here are the parts drawn in lines and dots. A row of portholes is
   a dotted line (dashes of no length with round ends): a brass rim, and over
   it the glass, lit in the station's color. */
.station-ports-rim,
.station-ports,
.station-mod-windows,
.station-tube-ports,
.station-tube-lights { fill: none; stroke-linecap: round; }
.station-ports-rim,
.station-tube-ports { stroke: var(--sv-brass-1); }
.station-ports,
.station-mod-windows,
.station-tube-lights {
  stroke: var(--accent-ink);
  stroke: color-mix(in srgb, var(--accent-ink) 78%, #fff);
}
.station-rivets { fill: none; stroke: var(--sv-brass-5); stroke-width: 1.2; stroke-linecap: round; stroke-dasharray: 0 6; opacity: 0.7; }
.station-glint { fill: #fff; opacity: 0.22; pointer-events: none; }

/* The habitat ring: its band stays put (so the light on it does), what is
   on it turns once in two minutes round the core. */
.station-spin { transform-box: view-box; transform-origin: 0 0; animation: sv-spin 120s linear infinite; }
.station-spoke { fill: #22282e; stroke: var(--sv-brass-2); stroke-width: 0.9; }
.station-teeth { fill: #715a2e; stroke: #1f160b; stroke-width: 0.7; stroke-linejoin: round; }
.station-nut { fill: var(--sv-brass-3); stroke: var(--sv-brass-0); stroke-width: 0.8; stroke-linejoin: round; }
.station-ports-rim.is-ring { stroke-width: 7; stroke-dasharray: 0 10; stroke-dashoffset: -5; }
.station-ports.is-ring { stroke-width: 4.2; stroke-dasharray: 0 10; stroke-dashoffset: -5; opacity: 0.85; }

/* Solar wings: brass girders, glass in brass frames, and at each root a
   pinion meshing with the ring, turning the other way (48 teeth to its 8,
   so six times as fast). */
.station-mast { fill: #22282e; stroke: var(--sv-brass-1); stroke-width: 0.8; }
.station-truss { stroke: var(--sv-brass-3); stroke-width: 0.8; }
.station-wing-frame { stroke: var(--sv-brass-3); stroke-width: 1.1; stroke-linejoin: round; }
.station-gimbal {
  fill: #8f7440;
  stroke: #1f160b;
  stroke-width: 0.6;
  transform-box: fill-box;
  transform-origin: center;
  animation: sv-spin-back 20s linear infinite;
}

/* The core: rivets round its rim, portholes round its plate, a cog turning
   under the bezel of its light. */
.station-rivets.is-core { stroke-width: 1.5; stroke-dasharray: 0 4; }
.station-ports-rim.is-core { stroke-width: 6.4; stroke-dasharray: 0 30; stroke-dashoffset: -15; }
.station-ports.is-core { stroke-width: 3.8; stroke-dasharray: 0 30; stroke-dashoffset: -15; opacity: 0.9; }
.station-cog {
  fill: #54401f;
  stroke: #1f160b;
  stroke-width: 0.8;
  stroke-linejoin: round;
  transform-box: view-box;
  transform-origin: 0 0;
  animation: sv-spin-back 50s linear infinite;
}

/* Running lights: red and green at the wing tips, amber lamps. */
.station-light.is-red { fill: #ff6a5c; }
.station-light.is-green { fill: #6ff09a; }
.station-light.is-amber { fill: #ffd98a; }
.station-light-glow { opacity: 0.28; }
.station-light-glow.is-red { fill: #ff4d40; }
.station-light-glow.is-green { fill: #45e07c; }
.station-light-glow.is-amber { fill: #ffa733; }
.station-lights.is-nav { animation: sv-blink 2.6s linear infinite; }
.station-lights.is-strobe { opacity: 0; animation: sv-strobe 3.1s linear infinite; }

/* Docking tubes: copper, portholes along them, and lights running out to a
   module while it works. An empty slot's is dimmer, its portholes dark; a
   slot past the station's own is held by a hazard-striped clamp. */
.station-tube-body { stroke: #1d0c05; stroke-width: 0.8; }
.station-tube-ports { stroke-width: 5.6; stroke-dasharray: 0 20; }
.station-tube-lights { stroke-width: 3.2; stroke-dasharray: 0 20; opacity: 0.85; }
.station-valve { fill: none; stroke: var(--sv-brass-4); stroke-width: 1.3; stroke-linecap: round; }
.station-collar { stroke: var(--sv-brass-0); stroke-width: 0.9; }
.station-tube.is-extra .station-collar { stroke: rgba(224, 168, 60, 0.8); }
.station-tube.is-empty { opacity: 0.7; }
.station-tube.is-empty .station-tube-lights { stroke: #1a2228; opacity: 1; }
.station-tube-flow { fill: #9af5b4; opacity: 0; }
/* A tube takes no click: grayed a little under its lights (stationart.js
   tubeArt), and so is its valve, beside the modules and the station that do. */
.station-tube-veil { fill: #56616b; opacity: 0.55; pointer-events: none; }
.station-tube .station-valve { opacity: 0.55; }
.station-tube.is-working .station-tube-flow { opacity: 1; animation: sv-flow 1.1s linear infinite; }

/* Modules: brackets round the selected (or pointed at) one, a small lift
   under the pointer, the band along the top. */
.station-slot-sel { stroke: var(--accent-ink); stroke-width: 2; opacity: 0; transition: opacity 0.15s; }
.station-slot:hover .station-slot-sel { opacity: 0.5; }
.station-slot:focus-visible .station-slot-sel,
.station-slot.is-selected .station-slot-sel { opacity: 1; }
.station-mod { transition: transform 0.18s var(--ease); }
.station-slot:hover .station-mod { transform: translateY(-2px); }
/* The status plate: dark, tinted and edged in the state's tone. */
.station-mod-band { fill: rgba(12, 8, 4, 0.85); stroke: var(--tone); stroke-opacity: 0.85; stroke-width: 0.8; }
@supports (fill: color-mix(in srgb, red, white)) {
  .station-mod-band { fill: color-mix(in srgb, var(--tone) 16%, #0c0804); }
}
.station-slot text.station-mod-state { fill: var(--tone); font-size: 7.5px; font-weight: 600; letter-spacing: 0.06em; }
.station-slot text.station-mod-tier { fill: var(--ink); fill-opacity: 0.85; font-size: 7px; letter-spacing: 0.1em; }
.station-slot text.station-mod-name { fill: var(--ink); font-size: 9.5px; letter-spacing: 0.16em; }
.station-slot.is-empty text.station-mod-name { fill: var(--ink-dim); }
/* …lit like any other when pointed at, focused or selected. */
.station-slot.is-empty:hover text.station-mod-name,
.station-slot.is-empty:focus-visible text.station-mod-name,
.station-slot.is-empty.is-selected text.station-mod-name { fill: var(--accent-ink); }
.station-slot text.station-mod-extra { fill: var(--amber); font-size: 7.5px; letter-spacing: 0.14em; }
/* Copper pipes up a bay's sides, brass flanges on them. */
.station-mod-rail { stroke: #a9592f; stroke-width: 2.8; }
.station-mod-flanges { stroke: var(--sv-brass-4); stroke-width: 3.8; stroke-dasharray: 1.4 9.6; }
.station-mod-screen { fill: #05090c; stroke: var(--tone); stroke-opacity: 0.6; stroke-width: 1.1; }
.station-mod .station-glint { opacity: 0.09; }
.station-ports-rim.is-mod { stroke-width: 4.8; stroke-dasharray: 0 6.2; }
.station-mod-windows { stroke-width: 3; stroke-dasharray: 0 6.2; opacity: 0.85; }
.station-slot.is-off .station-mod-windows { opacity: 0.12; }

/* A bay's crates run along its conveyor while its floor works, and its
   valve lets off steam, out the side away from its tube. */
.station-crate { fill: #b07c3e; stroke: var(--sv-brass-0); stroke-width: 0.5; opacity: 0; }
.station-mod .station-valve { stroke-width: 0.9; }
.station-slot.is-working .station-crate { animation: sv-belt 2.7s linear infinite; }
.station-slot.is-working .station-crate.is-1 { animation-delay: -0.9s; }
.station-slot.is-working .station-crate.is-2 { animation-delay: -1.8s; }
.station-puff { fill: #f2f5f7; opacity: 0; pointer-events: none; transform-box: fill-box; transform-origin: center; }
.station-slot.is-working .station-puff { animation: sv-puff 2.6s ease-out infinite; }
.station-slot.is-working .station-puff.is-left { animation-name: sv-puff-left; }
.station-slot.is-working .station-puff.is-1 { animation-delay: -0.87s; }
.station-slot.is-working .station-puff.is-2 { animation-delay: -1.73s; }

/* A lab: its dome breathes and its telescope sweeps while it researches;
   its gauges read low while it waits, high while it works (twitching), and
   full once its project is done. */
.station-dome { stroke: var(--tone); stroke-opacity: 0.75; stroke-width: 1.2; stroke-linejoin: round; }
.station-dome-glass { fill-opacity: 0.5; }
.station-dome-ribs { stroke: var(--sv-brass-4); stroke-width: 0.8; stroke-linejoin: round; opacity: 0.7; }
.station-dome-glow { fill: var(--tone); opacity: 0.1; }
.station-slot.is-working .station-dome-glow { animation: sv-breathe 3.2s ease-in-out infinite alternate; }
.station-slot.is-done .station-dome-glow { opacity: 0.35; }
.station-slot-glyph.is-dome { color: var(--tone); }
.station-antenna { fill: none; stroke: #a9592f; stroke-width: 1.5; stroke-linecap: round; }
.station-coil { stroke: #e6a273; stroke-width: 0.9; stroke-linejoin: round; }
.station-dish { transform-box: view-box; transform-origin: 34px -22px; transform: rotate(-24deg); }
.station-scope { fill: var(--sv-brass-4); stroke: var(--sv-brass-0); stroke-width: 0.5; stroke-linejoin: round; }
.station-scope.is-shade { fill: var(--sv-brass-2); }
.station-scope-bands { fill: none; stroke: var(--sv-brass-5); stroke-width: 1.3; }
.station-scope-lens { fill: #73b6b2; }
.station-mod-tip { fill: #ffc861; animation: sv-blink 1.9s linear infinite; }
.station-slot.is-working .station-dish { animation: sv-sweep 9s ease-in-out infinite alternate; }
.station-gauge { fill: #d6c9a4; stroke: var(--sv-brass-0); stroke-width: 0.5; }
.station-gauge-ticks { stroke: var(--sv-brass-0); stroke-width: 0.6; }
.station-gauge-needle { stroke: #a3271d; stroke-width: 0.95; stroke-linecap: round; transform-box: view-box; transform: rotate(-110deg); }
.station-gauge-needle.is-0 { transform-origin: -34px 8px; }
.station-gauge-needle.is-1 { transform-origin: 34px 8px; }
.station-slot.is-waiting .station-gauge-needle { transform: rotate(-50deg); }
.station-slot.is-done .station-gauge-needle { transform: rotate(110deg); }
.station-slot.is-working .station-gauge-needle { transform: rotate(36deg); animation: sv-twitch 1.7s ease-in-out infinite alternate; }
.station-slot.is-working .station-gauge-needle.is-1 { animation-duration: 2.3s; animation-delay: -0.8s; }

/* Waiting for an input: its light blinks. Off: its lights are out. */
.station-slot.is-waiting .station-slot-dot { animation: sv-blink 1.4s linear infinite; }
.station-slot.is-off .station-slot-dot { opacity: 0.25; }

/* An empty slot: an open docking port, beacons at the corners of its space. */
.station-slot.is-empty .station-slot-frame { stroke: rgba(217, 173, 92, 0.42); }
.station-port-guide { stroke: rgba(217, 173, 92, 0.14); stroke-width: 1; stroke-dasharray: 2 3; }
.station-port-ring { stroke: rgba(217, 173, 92, 0.5); stroke-width: 1.2; transition: stroke 0.15s; }
/* Not known yet (the moment before the station's answer comes): an outline. */
.station-port-ring.is-loading { fill: #171b20; stroke-width: 4; }
.station-port-bolts { stroke: var(--sv-brass-0); stroke-width: 1.8; stroke-linecap: round; stroke-dasharray: 0 2; }
.station-port-blades { stroke: #07090b; stroke-width: 0.9; stroke-linecap: round; }
.station-port-beacons { fill: var(--accent-ink); animation: sv-blink 3.4s linear infinite; }
.station-slot text.station-port-cta { fill: var(--ink-dim); font-size: 8px; letter-spacing: 0.14em; }
.station-slot:hover .station-port-ring,
.station-slot:focus-visible .station-port-ring { stroke: var(--accent-ink); }
.station-slot:hover text.station-port-cta,
.station-slot:focus-visible text.station-port-cta { fill: var(--accent-ink); }
.station-slot.is-loading .station-mod { opacity: 0.45; }
/* Sealed: nothing can be built here until research is done. */
.station-slot.is-locked .station-port-ring { stroke: rgba(224, 168, 60, 0.6); stroke-dasharray: 4 3; }
.station-port-lock { stroke: var(--amber); stroke-width: 1.6; stroke-linejoin: round; }
.station-slot.is-locked .station-port-beacons { fill: var(--amber); }
.station-slot.is-locked text.station-port-cta { fill: var(--amber); }

/* A module whose next tier can be built: a medallion in a brass cog. */
.station-mod-up circle { fill: var(--accent-ink); }
.station-mod-up path { stroke: #061018; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.station-mod-up path.station-mod-up-cog { fill: var(--sv-brass-3); stroke: var(--sv-brass-0); stroke-width: 0.6; }

@keyframes sv-spin { to { transform: rotate(360deg); } }
@keyframes sv-spin-back { to { transform: rotate(-360deg); } }
@keyframes sv-puff {
  0% { transform: translate(0, 0) scale(0.4); opacity: 0; }
  15% { opacity: 0.75; }
  100% { transform: translate(4px, -3px) scale(1.4); opacity: 0; }
}
@keyframes sv-puff-left {
  0% { transform: translate(0, 0) scale(0.4); opacity: 0; }
  15% { opacity: 0.75; }
  100% { transform: translate(-4px, -3px) scale(1.4); opacity: 0; }
}
@keyframes sv-twitch { from { transform: rotate(28deg); } to { transform: rotate(46deg); } }
@keyframes sv-blink { 0%, 55% { opacity: 1; } 58%, 100% { opacity: 0.15; } }
@keyframes sv-strobe { 0%, 2% { opacity: 1; } 6%, 100% { opacity: 0; } }
@keyframes sv-flow { to { transform: translateX(16px); } }
@keyframes sv-belt {
  0% { transform: translateX(0); opacity: 0; }
  10%, 88% { opacity: 1; }
  100% { transform: translateX(67px); opacity: 0; }
}
@keyframes sv-breathe { from { opacity: 0.12; } to { opacity: 0.42; } }
@keyframes sv-sweep { from { transform: rotate(-34deg); } to { transform: rotate(14deg); } }

/* Covered by a bay's floor: nothing moves. (Plain selectors, not :is(), so
   the browser only tries each on elements with that class.) */
.stationview.is-covered .station-spin,
.stationview.is-covered .station-cog,
.stationview.is-covered .station-gimbal,
.stationview.is-covered .station-puff,
.stationview.is-covered .station-gauge-needle,
.stationview.is-covered .station-lights,
.stationview.is-covered .station-tube-flow,
.stationview.is-covered .station-crate,
.stationview.is-covered .station-dome-glow,
.stationview.is-covered .station-dish,
.stationview.is-covered .station-mod-tip,
.stationview.is-covered .station-slot-dot,
.stationview.is-covered .station-port-beacons { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .stationview .station-spin,
  .stationview .station-cog,
  .stationview .station-gimbal,
  .stationview .station-puff,
  .stationview .station-gauge-needle,
  .stationview .station-lights,
  .stationview .station-tube-flow,
  .stationview .station-crate,
  .stationview .station-dome-glow,
  .stationview .station-dish,
  .stationview .station-mod-tip,
  .stationview .station-slot-dot,
  .stationview .station-port-beacons { animation: none !important; }
  .station-lights.is-strobe { opacity: 0.6; }
}
.reduce-motion .station-lights.is-strobe { opacity: 0.6; }

/* A small stage (a phone, a short window): the station is drawn small, so
   the names grow and the smallest words go (the light, the tone and the
   panel still say it all). LOGISTICS at its widest here is what
   stationLayout keeps clear (stationart.js LABEL). */
@container station (max-width: 520px) or (max-height: 520px) {
  .station-slot text.station-mod-name { font-size: 13px; letter-spacing: 0.04em; }
  .station-slot text.station-mod-tier,
  .station-slot text.station-mod-state,
  .station-slot text.station-port-cta,
  .station-slot text.station-slot-count,
  .station-slot text.station-mod-extra { display: none; }
  .station-hub-label { font-size: 14px; letter-spacing: 0.12em; }
  /* With the state's word gone, its line and plate say it: wider here. */
  .station-slot-frame { stroke-width: 3; }
  .station-slot.is-selected .station-slot-frame { stroke-width: 3.4; }
  .station-mod-band { stroke-width: 1.4; }
}

/* ------------------------------------------------------------- tutorial */
/* The coach (ui/tutorial.js): a card saying what to do next and a ring round
   the thing to click, with the rest of the screen dimmed round it. Over
   windows, toasts and the search; under the sidebar's labels, the pilot panel
   and menus. Placed by transform, so moving it each frame never lays the page
   out again. Its words are big enough to read at a glance (user, 2026-10-15:
   "increase the size of the text in the tutorial box"), and the card grows
   with the screen and with Settings' Window size (later that day: "set the
   default window size to be larger"): 460 px wide and 17 px words on a
   laptop, up to 640 and 21 on a big screen, all times the window scale. */
.tut-card {
  --tut-scale: var(--win-scale, 1);
  position: fixed;
  left: 0;
  top: 0;
  z-index: 58;
  width: min(calc(clamp(460px, 27vw, 640px) * var(--tut-scale)), calc(100vw - 16px));
  padding: calc(14px * var(--tut-scale)) calc(18px * var(--tut-scale)) calc(16px * var(--tut-scale));
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  background: #0b131b;
  box-shadow: 0 18px 40px -8px rgba(0, 0, 0, 0.85), 0 0 0 1px rgba(0, 0, 0, 0.4);
  color: var(--ink);
  font-size: calc(clamp(15px, 0.85vw, 19px) * var(--tut-scale));
  line-height: 1.5;
}
.tut-card[hidden], .tut-ring[hidden] { display: none; }
/* Held back a moment while what its step checks is still loading. */
.tut-card.is-holding { visibility: hidden; }
.tut-card.is-dragging { opacity: 0.92; }
.tut-head { display: flex; align-items: center; gap: 8px; margin: 0 -4px 6px 0; cursor: grab; user-select: none; touch-action: none; }
.tut-card.is-dragging .tut-head { cursor: grabbing; }
.tut-kicker { font-size: calc(clamp(12px, 0.66vw, 14px) * var(--tut-scale)); font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: var(--accent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tut-count { font-size: calc(clamp(12px, 0.66vw, 14px) * var(--tut-scale)); color: var(--ink-dim); white-space: nowrap; font-variant-numeric: tabular-nums; }
.tut-spacer { flex: 1; }
.tut-icon {
  width: calc(26px * var(--tut-scale));
  height: calc(24px * var(--tut-scale));
  padding: 0;
  border: 1px solid transparent;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: calc(clamp(15px, 0.85vw, 18px) * var(--tut-scale));
  line-height: 1;
  cursor: pointer;
}
.tut-icon:hover, .tut-icon:focus-visible { border-color: var(--line-strong); color: var(--ink-bright); outline: none; }
.tut-bar { height: 2px; margin-bottom: 10px; background: rgba(150, 196, 224, 0.12); }
.tut-bar i { display: block; height: 100%; background: var(--accent); transition: width 0.35s ease; }
.tut-title { margin: 2px 0 8px; font-size: calc(clamp(19px, 1.05vw, 23px) * var(--tut-scale)); font-weight: 600; color: var(--ink-bright); }
.tut-text { margin: 0 0 14px; color: var(--ink-bright); font-size: calc(clamp(17px, 0.95vw, 21px) * var(--tut-scale)); line-height: 1.5; }
.tut-tick { display: inline-block; margin-right: 6px; color: #6fd08c; font-weight: 700; }
.tut-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.tut-button { padding: calc(7px * var(--tut-scale)) calc(14px * var(--tut-scale)); font-size: calc(clamp(13px, 0.74vw, 16px) * var(--tut-scale)); }
.tut-wait { display: inline-flex; align-items: center; gap: 7px; font-size: calc(clamp(12px, 0.66vw, 14px) * var(--tut-scale)); letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); }
.tut-wait i { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); animation: tut-blink 1.4s ease-in-out infinite; }
.tut-card.is-done .tut-wait { color: #6fd08c; }
.tut-card.is-done .tut-wait i { background: #6fd08c; animation: none; }
.tut-link {
  padding: 2px 0;
  border: 0;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: calc(clamp(13px, 0.74vw, 16px) * var(--tut-scale));
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.tut-link:hover, .tut-link:focus-visible { color: var(--ink-bright); outline: none; }
/* Folded away: just the head, so it stays out of the way. */
.tut-card.is-min { width: auto; max-width: min(calc(clamp(460px, 27vw, 640px) * var(--tut-scale)), calc(100vw - 16px)); padding-bottom: 6px; }
.tut-card.is-min > :not(.tut-head) { display: none; }
.tut-card.is-min .tut-head { margin-bottom: 0; }
.tut-ring {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 57;
  border: 2px solid var(--accent);
  border-color: color-mix(in srgb, var(--accent) 70%, #fff);
  border-radius: 6px;
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.35), 0 0 22px rgba(var(--accent-rgb), 0.8), inset 0 0 14px rgba(var(--accent-rgb), 0.35);
  pointer-events: none;
  animation: tut-ring-pulse 1.6s ease-in-out infinite;
}
/* The ring dims less than a mark between beats, so what it rounds stays lit. */
@keyframes tut-ring-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.75; }
}
@keyframes tut-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}
@keyframes tut-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}
/* The dim round the ring (user, 2026-10-15: "when showing elements on the
   screen, darken the rest of it"): a box the ring's size whose shadow covers
   everything else, so the target shows through the hole. It never takes a
   click, so the game stays playable under it, and it fades in and out where
   it last was. Under the ring and the card. What shows through the hole is
   lit up (user, 2026-10-15: "make the highlighted area brighter"): the
   backdrop filter brightens just the box, never the shadow round it. */
.tut-dim {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 56;
  width: 0;
  height: 0;
  border-radius: 6px;
  box-shadow: 0 0 0 200vmax rgba(2, 5, 9, 0.62);
  -webkit-backdrop-filter: brightness(1.55) saturate(1.15);
  backdrop-filter: brightness(1.55) saturate(1.15);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.tut-dim.is-on { opacity: 1; }
/* A red circle round something a step marks as well (a window's resize
   corner). */
.tut-mark {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 57;
  border: 2px solid #ff4d5e;
  border-radius: 50%;
  box-shadow: 0 0 0 3px rgba(255, 77, 94, 0.22), 0 0 14px rgba(255, 77, 94, 0.6);
  pointer-events: none;
  animation: tut-pulse 1.6s ease-in-out infinite;
}
.tut-mark[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .tut-ring, .tut-mark, .tut-wait i { animation: none; }
  .tut-dim { transition: none; }
}
/* A phone: a sheet along the bottom, beside the sidebar. */
@media (max-width: 720px) {
  .tut-card { left: calc(var(--rail-w, 52px) + 6px); right: 6px; top: auto; bottom: 6px; width: auto; font-size: 14px; }
  .tut-text { font-size: 15px; }
  .tut-card.is-min { left: auto; }
  /* Along the top instead, when the bottom would cover what it points at
     (the system view's panel sits at the bottom on a phone). */
  .tut-card.is-top { top: 6px; bottom: auto; }
}

/* Help → Tutorial: one card per part, to play or replay. */
.help-parts { display: grid; gap: 8px; margin: 10px 0 0; padding: 0; list-style: none; }
.help-part {
  display: grid;
  grid-template-columns: 28px 1fr auto;
  align-items: center;
  gap: 4px 12px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  background: rgba(150, 196, 224, 0.03);
}
.help-part.is-playing { border-color: rgba(var(--accent-rgb), 0.55); background: var(--accent-wash); }
.help-part-n {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  font-size: 12px;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}
.help-part.is-done .help-part-n { border-color: rgba(111, 208, 140, 0.6); color: #6fd08c; }
.help-part-name { margin: 0; color: var(--ink-bright); font-size: 14px; }
.help-part-sub { margin: 2px 0 0; color: var(--ink-dim); font-size: 12px; }
.help-part-done { margin-left: 8px; color: #6fd08c; font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; }

/* Home system (2026-10-15): a house beside the favorite star on the map's
   card and the system view's title, lit in your accent while it is home. */
.map-card-home { margin-left: 2px; width: 22px; height: 22px; }
/* The title's three buttons stay whole on a narrow panel: the row wraps
   rather than squeezing them. */
.sysview-title { min-width: 0; }
.sysview-name-row { flex-wrap: wrap; row-gap: 2px; max-width: 100%; }
.sysview-name-row > .fav-star,
.sysview-name-row > .sysview-rename { flex: none; }
.home-mark:hover,
.home-mark:focus-visible { color: var(--accent-ink, var(--accent)); }
.home-mark.is-on { color: var(--accent-ink, var(--accent)); }
.home-mark.is-on svg path { fill: rgba(var(--accent-rgb), 0.35); }
.home-mark.is-on:hover svg path { fill: rgba(var(--accent-rgb), 0.15); }

/* Tutorial, the 2026-10-15 notes (ui/tutorial.js). On a bay's floor, the box
   a step's piece goes on, with an arrow the way it faces (`spot`): dashed,
   or outlined by the ring itself when the ring is round it. Never takes a
   click. Bug Reports' practice report: its button and form say so. */
.tut-spot {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 57;
  display: grid;
  place-items: center;
  border: 2px dashed color-mix(in srgb, var(--accent) 75%, #fff);
  border-radius: 4px;
  background: rgba(var(--accent-rgb), 0.14);
  pointer-events: none;
}
.tut-spot[hidden] { display: none; }
.tut-spot.is-ringed { border-color: transparent; }
.tut-spot-arrow {
  display: none;
  width: var(--arrow, 32px);
  height: var(--arrow, 32px);
  background: color-mix(in srgb, var(--accent) 65%, #fff);
  clip-path: polygon(50% 0, 100% 48%, 67% 48%, 67% 100%, 33% 100%, 33% 48%, 0 48%);
  transform: rotate(var(--dir, 0deg));
  opacity: 0.92;
}
.tut-spot.has-arrow .tut-spot-arrow { display: block; }
.tut-spot-under-tip .bay-tip { visibility: hidden; }
/* "Scroll down" (or up) at the edge of the panel or list a step's target is
   scrolled out of (user request 2026-10-17: "show the player that they need
   to scroll down"). Placed by ui/tutorial.js like the ring; never takes a
   click, so the panel scrolls under it. */
.tut-scroll {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 57;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px solid color-mix(in srgb, var(--accent) 70%, #fff);
  border-radius: 999px;
  background: rgba(8, 12, 20, 0.92);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.3), 0 0 18px rgba(var(--accent-rgb), 0.7);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  pointer-events: none;
  animation: tut-ring-pulse 1.6s ease-in-out infinite;
}
.tut-scroll[hidden] { display: none; }
.tut-scroll-arrow {
  width: 14px;
  height: 14px;
  background: color-mix(in srgb, var(--accent) 65%, #fff);
  clip-path: polygon(33% 0, 67% 0, 67% 52%, 100% 52%, 50% 100%, 0 52%, 33% 52%);
  animation: tut-scroll-nudge 1s ease-in-out infinite;
}
.tut-scroll.is-up .tut-scroll-arrow { transform: rotate(180deg); animation-name: tut-scroll-nudge-up; }
@keyframes tut-scroll-nudge {
  0%, 100% { translate: 0 -2px; }
  50% { translate: 0 3px; }
}
@keyframes tut-scroll-nudge-up {
  0%, 100% { translate: 0 2px; }
  50% { translate: 0 -3px; }
}
@media (prefers-reduced-motion: reduce) {
  .tut-scroll, .tut-scroll-arrow { animation: none; }
}
.reduce-motion .tut-scroll, .reduce-motion .tut-scroll-arrow { animation: none; }
.fb-practice-note { margin: 0; color: var(--amber); }
.fb-form.is-practice { border-left: 2px solid var(--amber); padding-left: 10px; }
.comms-compose-button.is-practice { border-color: var(--amber); color: var(--amber); }

/* ---- Inventory (ui/inventory.js): what your account holds, not a station.
   Redone 2026-10-17: a toolbar, tabs, Ready to build (a row per building,
   a chip per tier), a section of tiles per category, and Move in. */

.inventory { display: flex; flex-direction: column; gap: 10px; min-height: 100%; }
.inv-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.inv-bar[hidden] { display: none; }
.inv-search { flex: 1 1 180px; min-width: 0; }
.inv-sort { flex: 0 0 auto; width: auto; }
.inv-move-open,
.inv-moveout-open { flex: 0 0 auto; }
.inv-move-open[aria-expanded="true"],
.inv-moveout-open[aria-expanded="true"] { border-color: var(--accent); }

.inv-tabs { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0 2px; border-bottom: 1px solid var(--line); }
.inv-tabs[hidden] { display: none; }
.inv-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: -1px;
  padding: 6px 8px 7px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
}
.inv-tab[aria-selected="true"] { color: var(--ink-bright); border-bottom-color: var(--accent); }
.inv-tab:hover,
.inv-tab:focus-visible { color: var(--ink-bright); outline: none; }
.inv-tab-n { font-size: 11px; letter-spacing: 0; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.inv-tabs-note { margin-left: auto; padding: 0 0 8px 10px; font-size: 11px; color: var(--ink-dim); white-space: nowrap; font-variant-numeric: tabular-nums; }

.inv-body { display: flex; flex: 1 1 auto; flex-direction: column; gap: 14px; }
.inv-section { display: flex; flex-direction: column; gap: 6px; }
.inv-section-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 0 0 4px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: none;
  color: var(--ink-dim);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
/* A small arrow: down when open, right when folded. */
.inv-section-head::before {
  content: '';
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  border-left: 5px solid currentColor;
  transform: rotate(90deg);
  transition: transform 0.13s var(--ease);
}
.inv-section.is-folded .inv-section-head::before { transform: none; }
.inv-section-head:hover,
.inv-section-head:focus-visible { color: var(--ink-bright); outline: none; }
.inv-section-label { font-size: 11px; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; }
.inv-section-meta { margin-left: auto; font-size: 11px; font-variant-numeric: tabular-nums; }

.inv-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 4px; margin: 0; padding: 0; list-style: none; }
.inv-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  padding: 4px 9px 4px 5px;
  border: 1px solid var(--line);
  background: rgba(2, 4, 6, 0.45);
  font-size: 12px;
  color: var(--ink);
}
.inv-item:hover,
.inv-item:focus-visible { border-color: var(--line-strong); background: rgba(150, 196, 224, 0.05); outline: none; }
.inv-item-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inv-item-n { color: var(--ink-bright); font-weight: 600; font-variant-numeric: tabular-nums; }

/* Ready to build. */
.inv-builds { display: flex; flex-direction: column; gap: 10px; }
.inv-kind-group { display: flex; flex-direction: column; gap: 4px; }
.inv-kind-group-label { margin: 0; font-size: 11px; letter-spacing: 0.08em; color: var(--ink-dim); }
.inv-kinds { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 4px; margin: 0; padding: 0; list-style: none; }
.inv-kind {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  min-height: 34px;
  padding: 4px 5px 4px 6px;
  border: 1px solid var(--line);
  background: rgba(2, 4, 6, 0.45);
}
.inv-kind-icon { display: grid; place-items: center; width: 22px; height: 22px; color: var(--accent); }
/* A long name ("Chemical Plant") takes a second line rather than an ellipsis. */
.inv-kind-name { overflow: hidden; font-size: 13px; line-height: 1.15; color: var(--ink-bright); overflow-wrap: break-word; }
.inv-tiers { display: flex; gap: 3px; margin: 0; padding: 0; list-style: none; }
.inv-tier {
  display: inline-flex;
  align-items: baseline;
  justify-content: space-between;
  /* Tight enough that a one-word name beside three chips (Assembler) never
     breaks mid-word in a narrow window (2026-10-21). */
  gap: 4px;
  min-width: 40px;
  padding: 2px 5px;
  border: 1px solid var(--line-strong);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.inv-tier-tag { letter-spacing: 0.04em; color: var(--t1); }
.inv-tier[data-tier="2"] .inv-tier-tag { color: var(--t2); }
.inv-tier[data-tier="3"] .inv-tier-tag { color: var(--t3); }
.inv-tier-n { font-weight: 600; color: var(--ink-bright); }
.inv-tier.is-ready { border-color: rgba(var(--accent-rgb), 0.55); background: var(--accent-wash); }
.inv-tier.is-none { border-color: var(--line); opacity: 0.45; }
.inv-tier.is-free .inv-tier-n { font-weight: 400; color: var(--ink); }
.inv-tier:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }

/* Move in. */
/* Move out (2026-10-22) is the same box the other way: its own class so the
   tutorial's Move in steps never take it for Move in. */
.inv-move,
.inv-moveout {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  background: rgba(150, 196, 224, 0.03);
}
.inv-move-head { display: flex; align-items: center; gap: 8px; }
.inv-move-head .win-note { flex: 1 1 auto; }
.inv-move-title { flex: 0 0 auto; font-size: 11px; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-dim); }
.inv-move-station { flex: 1 1 auto; min-width: 0; }
.inv-move-close {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  margin-left: auto;
  border: 1px solid transparent;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}
.inv-move-close:hover,
.inv-move-close:focus-visible { border-color: var(--line-strong); color: var(--ink-bright); outline: none; }
.inv-move-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 4px; max-height: 172px; margin: 0; padding: 0; overflow: auto; list-style: none; }
.inv-move-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 7px;
  width: 100%;
  padding: 3px 8px 3px 4px;
  border: 1px solid var(--line);
  background: rgba(2, 4, 6, 0.45);
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
}
.inv-move-row:hover,
.inv-move-row:focus-visible { border-color: var(--line-strong); outline: none; }
.inv-move-row.is-on { border-color: var(--accent); background: var(--accent-wash); color: var(--ink-bright); }
.inv-move-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inv-move-n { font-weight: 600; color: var(--ink-bright); font-variant-numeric: tabular-nums; }
.inv-move-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding-top: 8px; border-top: 1px solid var(--line); }
.inv-move-pick { display: flex; flex: 1 1 150px; align-items: center; gap: 8px; min-width: 0; }
.inv-move-pick-name { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.inv-move-pick-name b { overflow: hidden; font-size: 13px; font-weight: 600; color: var(--ink-bright); text-overflow: ellipsis; white-space: nowrap; }
.inv-move-pick-name small { font-size: 11px; color: var(--ink-dim); }
.inv-units { flex: 0 1 110px; width: 110px; min-width: 70px; }

.inv-empty { flex: 1 1 auto; }
.inv-empty-icon { display: grid; place-items: center; width: 52px; height: 52px; border: 1px solid var(--line-strong); color: var(--accent); }
.inv-empty .inv-empty-title { font-size: 15px; letter-spacing: 0.04em; color: var(--ink-bright); }

@media (max-width: 720px) {
  .inv-search { flex-basis: 100%; }
  .inv-sort { flex: 1 1 auto; }
  /* The station's full name on a row of its own, under Move in from and ×. */
  .inv-move-head { flex-wrap: wrap; }
  .inv-move-station { order: 3; flex-basis: 100%; }
  .inv-kinds { grid-template-columns: minmax(0, 1fr); }
  .inv-grid,
  .inv-move-list { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
}

/* Dev notes 2026-10-16 (tutorial). A step's `flash` (ui/tutorial.js): what
   to click pulses in the accent color, the sidebar's arrow or the search's
   folded headings. Drawn over its own look with an inset shadow, so it works
   on anything; still, not pulsing, with Reduce motion. */
.tut-flash { animation: tut-flash 1.1s ease-in-out infinite !important; }
@keyframes tut-flash {
  0%, 100% { box-shadow: inset 0 0 0 999px rgba(var(--accent-rgb), 0.04), 0 0 0 1px rgba(var(--accent-rgb), 0.35); }
  50% { box-shadow: inset 0 0 0 999px rgba(var(--accent-rgb), 0.3), 0 0 0 2px rgba(var(--accent-rgb), 1), 0 0 18px rgba(var(--accent-rgb), 0.8); }
}
.reduce-motion .tut-flash { animation: none !important; box-shadow: inset 0 0 0 999px rgba(var(--accent-rgb), 0.24), 0 0 0 2px rgba(var(--accent-rgb), 1) !important; }
@media (prefers-reduced-motion: reduce) {
  .tut-flash { animation: none !important; box-shadow: inset 0 0 0 999px rgba(var(--accent-rgb), 0.24), 0 0 0 2px rgba(var(--accent-rgb), 1) !important; }
}

/* Help → Tutorial's categories: a heading that folds its parts away, like
   the Factory Floor's. */
.help-tutorial { display: grid; gap: 12px; margin-top: 10px; }
.help-cat-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  background: var(--accent-wash);
  cursor: pointer;
  list-style: none;
}
.help-cat-head::-webkit-details-marker { display: none; }
.help-cat-head::after { content: "▾"; margin-left: auto; color: var(--ink-dim); transition: transform 150ms var(--ease); }
.help-cat:not([open]) .help-cat-head::after { transform: rotate(-90deg); }
.help-cat-head:focus-visible { outline: 1px solid var(--accent); }
.help-cat-title { font-size: 12px; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-bright); }
.help-cat-count { font-size: 11px; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.help-cat .help-parts { margin-top: 8px; }

/* Bug Reports: F2's line under Screenshots. */
.fb-shots-key { margin: 6px 0 0; }

/* The item picker's tabs: with System mats first (2026-10-16) six don't fit
   a narrow Logistics window in one row, so they sit in a grid, three across
   when narrow and all six when there is room. */
.flog-tabs { display: grid; grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); row-gap: 2px; }
.flog-tab { justify-content: center; text-align: center; }

/* The card of the machine in hand ends with its Stock line, kept while the
   card is folded (2026-10-17). */
.bay-tip-stock {
  margin: 8px 0 0;
  padding-top: 7px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink-bright);
}
.bay-tip-stock.is-out { color: var(--t2); }

/* On a phone the palette is a strip under the floor: the tools and the Edit
   row as icons on one line, then the machines, which scroll sideways, each
   its icon and its tier chips. */
@media (max-width: 720px) {
  .bay-tools {
    grid-row: 2;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    width: auto;
    padding: 6px 8px 8px;
    border-right: 0;
    border-top: 1px solid var(--line);
    overflow: hidden;
  }
  .bay-pal-top { flex: 1 1 100%; flex-direction: row; gap: 10px; min-width: 0; overflow-x: auto; }
  .bay-pal { flex: none; flex-direction: row; align-items: center; gap: 2px; }
  .bay-pal-head,
  .bay-pal-empty,
  .bay-tool-label,
  .bay-tool kbd,
  .bay-kind-head kbd,
  .bay-kind-name { display: none; }
  .bay-pal-grid { display: flex; gap: 2px; }
  .bay-tool,
  .bay-tool.is-icon,
  .bay-pal-grid .bay-tool { flex: none; justify-content: center; width: 32px; height: 34px; padding: 0; }
  .bay-pal-sep { margin: 0 3px; }
  .bay-pal-machines { flex: 1 1 100%; gap: 6px; min-width: 0; overflow-x: auto; }
  .bay-kind { flex: none; flex-direction: row; align-items: center; gap: 5px; padding: 3px 4px; }
  .bay-kind-tiers { grid-auto-columns: 38px; }
  .bay-tool.bay-tier { flex-direction: column; justify-content: center; gap: 0; width: auto; height: 32px; padding: 0 2px; font-size: 10px; line-height: 1.15; }
}

/* ---- Ship Bay (2026-10-17, Dev Panel note "Make a ship building bay"):
   its module in the station view (ui/stationart.js shipBayParts), its slot
   panel (ui/stationview.js shipPanel) and its window (ui/shipbay.js): the
   Recipes card and list as the user's wireframe drew them, and the
   Assembly slipway. The window's two areas sit side by side when it is
   wide and one above the other when it is narrow (a container query, so a
   window made narrow on a desktop stacks too). */

/* The module: a hangar open at the front, a ship in its cradle. With no
   order the ship is a faint dashed outline; on order, waiting, the outline
   in its state's tone; assembling, brass plating, and a spark at the hook. */
.station-ship-jib { stroke: var(--sv-brass-3); stroke-width: 1.4; stroke-linecap: round; }
.station-ship-gantry { stroke: var(--sv-brass-3); stroke-width: 1.6; stroke-linecap: round; }
.station-ship-trolley { fill: var(--sv-brass-4); stroke: var(--sv-brass-0); stroke-width: 0.6; }
.station-ship-cradle { stroke: #56616c; stroke-width: 1.6; stroke-linecap: round; }
.station-ship-hull { fill: rgba(203, 159, 82, 0.06); stroke: var(--sv-brass-3); stroke-opacity: 0.55; stroke-width: 0.9; stroke-dasharray: 2.2 1.6; stroke-linejoin: round; }
.station-slot.has-order .station-ship-hull { stroke: var(--tone); stroke-opacity: 0.9; }
.station-slot.is-assembling .station-ship-hull { fill: var(--sv-brass-3); stroke: var(--sv-brass-0); stroke-opacity: 1; stroke-dasharray: none; }
.station-ship-glass { fill: #3f878c; opacity: 0; }
.station-ship-lines { stroke: var(--sv-brass-0); stroke-width: 0.6; opacity: 0; }
.station-slot.is-assembling .station-ship-glass,
.station-slot.is-assembling .station-ship-lines { opacity: 1; }
.station-ship-sill { opacity: 0.75; }
.station-ship-lamp { fill: var(--accent-ink); opacity: 0.85; }
.station-slot.is-off .station-ship-lamp { opacity: 0.15; }
.station-ship-spark { fill: #fff3b8; opacity: 0; }
.station-slot.is-working.is-assembling .station-ship-spark { animation: sv-weld 0.9s steps(1, end) infinite; }
@keyframes sv-weld { 0% { opacity: 1; } 18% { opacity: 0.2; } 30% { opacity: 0.9; } 55% { opacity: 0; } 100% { opacity: 0; } }
.stationview.is-covered .station-ship-spark { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .stationview .station-ship-spark,
  .shipbay .sb-spark { animation: none !important; }
}
.reduce-motion .station-ship-spark,
.reduce-motion .shipbay .sb-spark { animation: none !important; }

/* Its slot panel: the order, what it waits for, the hangar. */
.ship-open { justify-self: stretch; }
.station-ship-order { display: flex; align-items: center; gap: 6px; margin: 0; color: var(--accent); }
.station-ship-needs { display: grid; gap: 6px; }
.station-hangar { display: grid; gap: 4px; margin: 0; padding: 0; list-style: none; }
.station-hangar li { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-bright); }
.station-hangar li svg { color: var(--accent); }
.station-hangar b { margin-left: auto; font-weight: 600; font-variant-numeric: tabular-nums; }
.station-panel .station-scrap-note { color: #ffb4a6; }

/* The window. */
.shipbay { display: flex; flex-direction: column; gap: 12px; min-height: 100%; padding: 14px; container-type: inline-size; }
.shipbay .win-empty svg { color: var(--accent); }
.shipbay-loading { margin: 0; }
.shipbay-head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.shipbay-glyph { display: grid; place-items: center; flex: none; width: 34px; height: 34px; border: 1px solid var(--line-strong); color: var(--accent); background: rgba(5, 8, 12, 0.6); }
.shipbay-where { display: grid; flex: 1; gap: 2px; min-width: 0; }
.shipbay-where b { font-size: 14px; font-weight: 600; letter-spacing: 0.04em; color: var(--ink-bright); }
.shipbay-where > span { font-size: 12px; color: var(--ink-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shipbay-state,
.shipbay-status { --tone: var(--ink-dim); }
.shipbay-state.is-working,
.shipbay-status.is-working { --tone: #5fd17a; }
.shipbay-state.is-waiting,
.shipbay-status.is-waiting { --tone: #e9c94c; }
.shipbay-state {
  flex: none;
  padding: 2px 8px;
  border: 1px solid var(--tone);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.16em;
  line-height: 16px;
  text-transform: uppercase;
  color: var(--tone);
}

.shipbay-areas { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 14px; align-items: start; }
.shipbay-area { display: grid; gap: 10px; min-width: 0; padding: 10px 12px 12px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.35); }
.shipbay-area-title { margin: 0; font-size: 11px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); }
.shipbay-box-label { font-size: 10px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }

/* Recipes: the card, as drawn. The picture top left, the name beside it and
   the description under the name; the Resources box with its eight squares
   along the bottom, Build to its right. */
.shipbay-card {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) 100px;
  grid-template-areas: "pic name name" "pic about about" "res res build";
  gap: 8px 10px;
  padding: 10px;
  border: 1px solid var(--line-strong);
  background: linear-gradient(180deg, rgba(20, 31, 42, 0.9), rgba(10, 16, 22, 0.9));
}
.shipbay-pic { grid-area: pic; display: grid; place-items: center; align-self: start; width: 64px; height: 64px; border: 1px solid var(--line-strong); color: var(--accent); background: rgba(5, 8, 12, 0.7); }
.shipbay-card.is-blank .shipbay-pic { border-style: dashed; color: var(--ink-dim); opacity: 0.7; }
.shipbay-name { grid-area: name; margin: 0; font-size: 16px; font-weight: 600; letter-spacing: 0.04em; color: var(--ink-bright); }
.shipbay-card.is-blank .shipbay-name { color: var(--ink); }
.shipbay-about { grid-area: about; display: grid; align-content: start; gap: 4px; min-height: 58px; padding: 6px 8px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.45); }
.shipbay-about p { margin: 0; font-size: 12.5px; line-height: 1.45; color: var(--ink); }
.shipbay-about p.shipbay-about-time { font-size: 11px; color: var(--ink-dim); }
.shipbay-res { grid-area: res; display: grid; gap: 6px; min-width: 0; padding: 5px 8px 8px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.45); }
.shipbay-res .shipbay-box-label { text-align: center; }
.shipbay-squares { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); gap: 4px; }
.shipbay-square {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 2px;
  min-width: 0;
  min-height: 44px;
  padding: 3px 1px 2px;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.75);
  outline: none;
}
.shipbay-square.is-empty { border-color: var(--line); background: rgba(5, 8, 12, 0.3); }
.shipbay-square:focus-visible { border-color: var(--accent); }
.shipbay-square-have { max-width: 100%; overflow: hidden; font-size: 10px; font-variant-numeric: tabular-nums; line-height: 1.1; white-space: nowrap; color: #5fd17a; }
.shipbay-square.is-short { border-color: rgba(210, 86, 63, 0.7); background: rgba(210, 86, 63, 0.1); }
.shipbay-square.is-short .shipbay-square-have { color: #ff8f7a; }
.shipbay-build { grid-area: build; display: grid; align-content: center; gap: 4px; }
.shipbay-build-button { min-height: 46px; font-size: 13px; letter-spacing: 0.14em; text-transform: uppercase; }
.shipbay-build-note { font-size: 11px; line-height: 1.35; text-align: center; color: var(--ink-dim); }

/* …and the box listing every design under it. */
.shipbay-list { min-height: 120px; padding: 6px; border: 1px solid var(--line-strong); background: rgba(5, 8, 12, 0.45); }
.shipbay-list-empty { margin: 0; padding: 32px 12px; font-size: 12.5px; line-height: 1.45; text-align: center; color: var(--ink-dim); }
.shipbay-designs { display: grid; gap: 4px; margin: 0; padding: 0; list-style: none; }
.shipbay-design {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-left: 2px solid transparent;
  background: rgba(10, 16, 22, 0.6);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.shipbay-design:hover:not(:disabled),
.shipbay-design:focus-visible { border-color: var(--accent); outline: none; background: rgba(var(--accent-rgb), 0.06); }
.shipbay-design:disabled { cursor: default; }
.shipbay-design.is-shown { border-color: rgba(var(--accent-rgb), 0.6); background: var(--accent-wash); }
.shipbay-design.is-chosen { border-left-color: var(--accent); }
.shipbay-design-pic { display: grid; color: var(--accent); }
.shipbay-design-name { overflow: hidden; font-size: 13.5px; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-bright); }
.shipbay-design-meta { font-size: 11px; white-space: nowrap; color: var(--amber); }
.shipbay-design-meta.is-ready { color: #5fd17a; }
.shipbay-design-time { font-size: 11px; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--ink-dim); }

/* Assembly: the slipway, drawn (ui/shipbay.js cradleArt). The ship's parts
   go on as the work passes each one; the dashed ghost shows what is still
   to come. */
.shipbay-cradle { border: 1px solid var(--line-strong); background: #070b0f; }
.sb-cradle-art { display: block; width: 100%; height: auto; }
.sb-wall { fill: #0c1217; }
.sb-wall-ribs { stroke: rgba(150, 196, 224, 0.05); stroke-width: 6; }
.sb-floor { fill: #171b20; }
.sb-gantry { fill: none; stroke: #ad8139; stroke-width: 3; stroke-linejoin: round; }
.sb-gantry-bolts { stroke: #e2c27c; stroke-width: 2; stroke-dasharray: 0 12; stroke-linecap: round; opacity: 0.7; }
.sb-cradle { fill: #2f363e; stroke: #875f25; stroke-width: 1.2; }
.sb-ghost { fill: none; stroke: rgba(var(--accent-rgb), 0.5); stroke-width: 1.2; stroke-dasharray: 4 3; stroke-linejoin: round; opacity: 0; transition: opacity 0.3s; }
.sb-cradle-art.is-waiting .sb-ghost,
.sb-cradle-art.is-assembling .sb-ghost,
.sb-cradle-art.is-paused .sb-ghost { opacity: 1; }
.sb-cradle-art.is-waiting .sb-ghost { stroke: rgba(233, 201, 76, 0.65); }
.sb-parts > * { opacity: 0; transition: opacity 0.6s var(--ease); }
.sb-parts > .is-on { opacity: 1; }
.sb-keel { fill: none; stroke: #cb9f52; stroke-width: 4; stroke-linecap: round; }
.sb-rib { fill: none; stroke: #ad8139; stroke-width: 2.2; stroke-linecap: round; }
.sb-plate { fill: #875f25; stroke: #36230e; stroke-width: 1; }
.sb-plate:nth-of-type(even) { fill: #ad8139; }
.sb-fin { fill: #a9592f; stroke: #2e1309; stroke-width: 1; stroke-linejoin: round; }
.sb-glass { fill: var(--accent); fill-opacity: 0.75; }
.sb-engine { fill: #404952; stroke: #0d1013; stroke-width: 1; }
.sb-trolley { transition: transform 1s linear; }
.sb-trolley-box { fill: #cb9f52; stroke: #36230e; stroke-width: 1; }
.sb-cable { stroke: #8fa9bd; stroke-width: 1.2; }
.sb-hook { fill: none; stroke: #cb9f52; stroke-width: 2; stroke-linecap: round; }
.sb-spark { fill: #fff3b8; opacity: 0; }
.sb-cradle-art.is-assembling .sb-spark { animation: sv-weld 0.9s steps(1, end) infinite; }
.sb-cradle-word { fill: var(--ink-dim); font-family: var(--font); font-size: 8.5px; letter-spacing: 0.24em; text-transform: uppercase; }
.sb-cradle-art.is-waiting .sb-cradle-word { fill: #e9c94c; }

.shipbay-status { display: grid; gap: 2px; padding: 8px 10px; border: 1px solid var(--line); border-left: 3px solid var(--tone); background: rgba(5, 8, 12, 0.5); }
.shipbay-status-word { font-size: 11px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--tone); }
.shipbay-status-text { font-size: 13px; line-height: 1.4; color: var(--ink); }
.shipbay-bar { height: 6px; margin-top: -6px; border: 1px solid var(--line); background: rgba(0, 0, 0, 0.6); }
.shipbay-bar i { display: block; width: 0; height: 100%; background: #5fd17a; transition: width 1s linear; }
.shipbay-status.is-off + .shipbay-bar i { background: var(--ink-dim); }
.shipbay-needs { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.shipbay-need { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 3px 8px; font-size: 12.5px; color: var(--ink); }
.shipbay-need .item-icon { grid-row: span 2; }
.shipbay-need-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-bright); }
.shipbay-need-count { font-weight: 600; font-variant-numeric: tabular-nums; color: #5fd17a; }
.shipbay-need.is-short .shipbay-need-count { color: #ff8f7a; }
.shipbay-need-bar { grid-column: 2 / 4; height: 4px; background: rgba(0, 0, 0, 0.6); }
.shipbay-need-bar i { display: block; width: 0; height: 100%; background: #5fd17a; transition: width 0.4s var(--ease); }
.shipbay-need.is-short .shipbay-need-bar i { background: #e9c94c; }
.shipbay-took { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin: 0; font-size: 12px; color: var(--ink); }
.shipbay-took .shipbay-box-label { flex-basis: 100%; }
.shipbay-took-item { display: inline-flex; align-items: center; gap: 4px; }
.shipbay-area .win-note { margin: 0; }
.shipbay-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.shipbay-switch { display: flex; align-items: center; gap: 8px; margin-right: auto; font-size: 13px; color: var(--ink); }
.shipbay-hangar { display: grid; gap: 6px; padding-top: 10px; border-top: 1px solid var(--line); }
.shipbay-hangar .shipbay-box-label { margin: 0; }
.shipbay-hangar-list { display: grid; gap: 4px; margin: 0; padding: 0; list-style: none; }
.shipbay-hangar-list li { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-bright); }
.shipbay-hangar-list b { margin-left: auto; font-weight: 600; font-variant-numeric: tabular-nums; }
.shipbay > .win-error { margin: 0; }

/* Narrow (a phone, or a window made narrow): one area above the other,
   and on the narrowest the Resources take two rows of four, Build under
   them. */
@container (max-width: 640px) {
  .shipbay-areas { grid-template-columns: minmax(0, 1fr); }
}
@container (max-width: 420px) {
  .shipbay-card { grid-template-columns: 56px minmax(0, 1fr); grid-template-areas: "pic name" "pic about" "res res" "build build"; }
  .shipbay-pic { width: 56px; height: 56px; }
  .shipbay-squares { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .shipbay-design { grid-template-columns: auto minmax(0, 1fr) auto; row-gap: 2px; }
  .shipbay-design-pic { grid-row: 1 / span 2; }
  .shipbay-design-meta { grid-column: 2; grid-row: 2; }
  .shipbay-design-time { grid-row: 1 / span 2; grid-column: 3; }
}

/* Curved belts + output to station (2026-10-17) */
/* The floor's Tools grid (ui/bayview.js) holds Select, Belt, Curve,
   Splitter, Remove and Flip, three by two: each its icon over its name, the
   key in the corner. Flip (the curve's other bend) is dim until Curve is in
   hand. A phone's strip leaves Flip off (a second tap on Curve bends it)
   and takes the tools a little narrower, so tools and Edit still fit one
   line at 375 px. A machine's Output switch is an ordinary station row. */
.bay-canvas[data-tool="curve"] { cursor: crosshair; }
@media (min-width: 721px) {
  .bay-pal-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .bay-pal-grid .bay-tool { flex-direction: column; justify-content: center; gap: 2px; height: 42px; padding: 4px 2px 3px; }
  .bay-pal-grid .bay-tool-label { flex: none; max-width: 100%; font-size: 11px; line-height: 1.15; text-align: center; }
  .bay-pal-grid .bay-tool:disabled:hover { border-color: var(--line); }
}
@media (max-width: 720px) {
  .bay-tool.is-flip { display: none; }
  .bay-pal-top { gap: 5px; }
  .bay-tool,
  .bay-tool.is-icon,
  .bay-pal-grid .bay-tool { width: 30px; }
  .bay-pal-sep { margin: 0 1px; }
}

/* ---- Scouts and the operations view (2026-10-17, Dev Panel note: a Tier 1
   scout ship and an operations room). The map's switch between its regular
   and operations views (top left, under search), the operations panel
   (bottom left: your ships), the map card's part (ships here, Send), the
   Operations Room's module in the station view (ui/stationart.js opsParts)
   and the ships-in-this-system lists of the Ship Bay's panel and window.
   The map drawing itself is ui/opsmap.js on the canvas. */
.map-ops-toggle {
  /* --slot: its place among the switches showing (ui/maptoggles.js). */
  position: absolute; top: calc(54px + var(--slot, 0) * 38px); left: 12px;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 10px 6px 9px;
  border: 1px solid var(--line-strong);
  background: rgba(10, 16, 22, 0.92);
  color: var(--ink);
  font: inherit; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
  cursor: pointer;
}
.map-ops-toggle[hidden] { display: none; }
.map-ops-toggle:hover:not(:disabled),
.map-ops-toggle:focus-visible { border-color: var(--accent); color: var(--ink-bright); }
.map-ops-toggle:disabled { cursor: default; opacity: 0.55; }
.map-ops-toggle kbd { padding: 0 5px; border: 1px solid var(--line); font: inherit; font-size: 10px; color: var(--ink-dim); }
.map-ops-toggle-dot { width: 9px; height: 9px; border: 1px solid var(--ink-dim); }
.map-ops-toggle.is-on { border-color: var(--accent); color: var(--accent-ink); background: linear-gradient(180deg, rgba(var(--accent-rgb), 0.18), rgba(10, 16, 22, 0.92)); }
.map-ops-toggle.is-on .map-ops-toggle-dot { background: var(--accent); border-color: var(--accent); box-shadow: 0 0 6px rgba(var(--accent-rgb), 0.7); }

/* In the operations view the left button selects ships, so the map's
   grab hand would say the wrong thing. */
.is-ops-view .starmap { cursor: crosshair; }

.ops-panel {
  position: absolute; left: 12px; bottom: 12px;
  display: grid; gap: 8px;
  width: min(300px, calc(100% - 24px));
  max-height: min(46vh, 420px); overflow: auto;
  padding: 10px 12px 12px;
  background: linear-gradient(180deg, #121c26, #0a1016);
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
}
.ops-panel[hidden] { display: none; }
.ops-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.ops-head h3 { margin: 0; font-size: 11px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent-ink); }
.ops-count { font-size: 12px; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.ops-sub { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0; font-size: 12px; color: var(--ink); }
.ops-hint { margin: 0; font-size: 12px; line-height: 1.45; color: var(--ink-dim); }
.ops-list { display: grid; gap: 4px; margin: 0; padding: 0; list-style: none; }
.ops-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 8px; padding: 4px 0; border-top: 1px solid var(--line); }
.ops-row:first-child { border-top: 0; }
.ops-row-text { display: grid; min-width: 0; }
.ops-row-text b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12.5px; font-weight: 600; color: var(--ink-bright); }
.ops-row-text small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11.5px; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.ops-square { width: 10px; height: 10px; background: var(--accent); box-shadow: 0 0 0 1.5px rgba(4, 7, 12, 0.9); }
.ops-square.is-moving { background: radial-gradient(circle, rgba(4, 7, 12, 0.85) 0 2px, var(--accent) 2.5px); }
.ops-link { padding: 2px 6px; border: 1px solid transparent; background: none; color: var(--accent-ink); font: inherit; font-size: 12px; cursor: pointer; }
.ops-link:hover,
.ops-link:focus-visible { border-color: var(--accent); }
.ops-fleet summary { cursor: pointer; font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }
.ops-fleet[open] summary { margin-bottom: 4px; }

.map-card-ops { display: grid; gap: 6px; margin: 10px 0 0; padding-top: 10px; border-top: 1px solid var(--line); }
.map-card-ops[hidden] { display: none; }
.map-card-ops-line { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0; font-size: 12.5px; color: var(--ink); }
.map-card-ops-note { margin: 0; font-size: 12px; line-height: 1.4; color: var(--ink-dim); }
.map-card-send {
  padding: 7px 10px;
  border: 1px solid var(--accent);
  background: linear-gradient(180deg, rgba(var(--accent-rgb), 0.28), rgba(var(--accent-rgb), 0.12));
  color: var(--ink-bright);
  font: inherit; font-size: 12.5px; font-weight: 600;
  cursor: pointer;
}
.map-card-send:disabled { border-color: var(--line-strong); background: transparent; color: var(--ink-dim); cursor: default; }
.map-card dd.map-card-unscouted { color: var(--ink-dim); font-style: italic; }

@media (max-width: 720px) {
  .map-ops-toggle { top: auto; bottom: calc(64px + var(--slot, 0) * 38px); left: 12px; }
  .ops-panel { bottom: 104px; max-height: 32vh; width: min(280px, calc(100% - 24px)); }
}

/* A star system open on a phone: its panel has the bottom of the screen, so
   the switches go up under the search, as on a wide screen, and the ships'
   panel waits until you zoom back out. */
@media (max-width: 640px) {
  .map-ui.has-system > .map-ops-toggle { top: calc(54px + var(--slot, 0) * 38px); bottom: auto; }
  .map-ui.has-system .ops-panel { display: none; }
}

/* The Operations Room's module: a holo-table of stars in the accent's
   light with a sweep turning over it, ships in a row, and a dish nodding on
   its mast. The sweep and the dish stop when covered or with less motion. */
.station-ops-glow { fill: rgba(var(--accent-rgb), 0.12); }
.station-ops-grid { stroke: var(--accent-ink); stroke-opacity: 0.22; stroke-width: 0.5; }
.station-ops-stars { fill: #cfe3f3; opacity: 0.7; }
.station-ops-star { fill: #ffe7a8; }
.station-ops-ring { stroke: var(--accent-ink); stroke-width: 0.8; stroke-dasharray: 2 1.6; opacity: 0.8; }
.station-ops-ships { fill: var(--accent-ink); stroke: #05080c; stroke-width: 0.5; }
.station-ops-sweep { fill: var(--accent-ink); opacity: 0.22; transform-box: view-box; transform-origin: 0 -5.5px; }
.station-slot.is-working .station-ops-sweep { animation: sv-spin 6s linear infinite; }
.station-ops-dish { transform-box: view-box; transform-origin: 27px -42px; }
.station-ops-dish.is-left { transform-origin: -27px -42px; }
.station-slot.is-working .station-ops-dish { animation: sv-ops-nod 7s ease-in-out infinite alternate; }
@keyframes sv-ops-nod { from { transform: rotate(-16deg); } to { transform: rotate(16deg); } }
.station-ops-dish-face { fill: var(--sv-brass-4); stroke: var(--sv-brass-0); stroke-width: 0.5; }
.station-ops-dish-feed { stroke: var(--sv-brass-2); stroke-width: 0.8; }
.station-ops-dish-tip { fill: var(--accent-ink); }
.station-mod-belt.is-ops { fill: #1b2229; stroke: var(--sv-brass-1); stroke-width: 0.5; }
.stationview.is-covered .station-ops-sweep,
.stationview.is-covered .station-ops-dish { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .stationview .station-ops-sweep,
  .stationview .station-ops-dish { animation: none !important; }
}
.reduce-motion .station-ops-sweep,
.reduce-motion .station-ops-dish { animation: none !important; }

.station-fleet { display: grid; gap: 8px; margin-top: 4px; }
.station-fleet .win-button { justify-self: start; }
.shipbay-fleet { display: grid; gap: 6px; margin-top: 8px; }
.shipbay-fleet .win-button { justify-self: start; }

/* Splitter priorities (2026-10-17) */
/* A splitter's panel: Priority in and Priority out, each a label and a
   chooser on one line, the choosers lined up and filling the rest. */
.bay-priority > span { flex: none; width: 92px; white-space: nowrap; }
.bay-priority > select { flex: 1 1 auto; min-width: 0; }

/* ==== Logistics colors and the Item wiki (2026-10-17, Dev Panel notes) ====

   Logistics colors: every state color the Logistics window draws is the
   pilot's to pick (Settings → Logistics, prefs-schema.js LOGISTICS_COLORS),
   set on <html> by main.js as these custom properties. The :root values are
   the Defaults, the same hexes as LOGISTICS_COLORS (test/stockflow.test.mjs
   checks they agree). The rules below take over the slot colors of the
   "How a slot is doing" rules, the Logistics (2026-10-13) block and the
   capped Stock tile. A Stock tile made faster than it is used, with no
   export running (src/stockflow.js), wears a border of its own: a full ring
   and a faint glow, over the yellow of one at its limit. */
:root {
  --log-full: #5fd17a;
  --log-filling: #e9c94c;
  --log-short: #e0564a;
  --log-later: #e0a83c;
  --log-capped: #e9c94c;
  --log-surplus: #5b7cfa;
}
.fslot { --slot-ok: var(--log-full); --slot-fill: var(--log-filling); --slot-bad: var(--log-short); }
.fslot.is-full,
.fslot.is-waiting,
.fslot.is-selling,
.fslot.is-sending { border-color: color-mix(in srgb, var(--log-full) 60%, transparent); }
.fslot.is-filling { border-color: color-mix(in srgb, var(--log-filling) 65%, transparent); }
.fslot.is-blocked,
.fslot.is-idle {
  border-color: color-mix(in srgb, var(--log-short) 75%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--log-short) 20%, transparent), inset 0 -2px 4px rgba(0, 0, 0, 0.45);
}
.fslot.is-later { border-color: color-mix(in srgb, var(--log-later) 75%, transparent); }
.fslot.is-later .fslot-bar i { background: var(--log-later); }
.fslot-lock { stroke: var(--log-later); }
.flog-pick.is-later { border-color: color-mix(in srgb, var(--log-later) 55%, transparent); background: color-mix(in srgb, var(--log-later) 4%, transparent); }
.flog-pick.is-later .flog-pick-note { color: var(--log-later); }
.flog-pick-lock { stroke: var(--log-later); }
.flog-pick.is-later:hover:not(:disabled),
.flog-pick.is-later:focus-visible { border-color: var(--log-later); background: color-mix(in srgb, var(--log-later) 8%, transparent); }
.flog-source.is-later .flog-source-detail { color: var(--log-later); }
.fslot.is-capped { border-color: color-mix(in srgb, var(--log-capped) 65%, transparent); }
.fslot.is-capped .fslot-bar i { background: var(--log-capped); }
.fslot.is-surplus {
  border-color: var(--log-surplus);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--log-surplus) 85%, transparent),
    0 0 7px 1px color-mix(in srgb, var(--log-surplus) 55%, transparent),
    inset 0 0 10px color-mix(in srgb, var(--log-surplus) 22%, transparent);
}
.fslot.is-surplus:not(.is-capped) .fslot-bar i { background: var(--log-surplus); }

/* Settings → Logistics: a slot in each color above the pickers, drawn by
   the rules above, so a pick shows on it at once. */
.settings-logcolors { gap: 14px 10px; padding: 4px 0 12px; }
.settings-logcolor { display: grid; justify-items: center; gap: 5px; width: 76px; }
.settings-logcolor .fslot { cursor: default; }
.settings-logcolor-name { font-size: 11px; line-height: 1.25; color: var(--ink-dim); text-align: center; }

/* Help → Item wiki (ui/itemwiki.js inside ui/help.js): every item as a
   tile, by category and shelf; an item's page with what it is, Made from
   and Used in, each way a row with its machine's icon. Every item named is
   a link (.wiki-link) to its page; .is-here is the page's own item. */
.help-topic.is-wiki,
.wiki-page { max-width: 820px; }
.wiki-index { display: grid; gap: 18px; margin-top: 4px; }
.wiki-cat { display: grid; gap: 8px; }
.wiki-count { color: var(--ink-dim); letter-spacing: 0.04em; }
.wiki-shelf { display: grid; gap: 6px; }
.wiki-group-title { margin: 4px 0 0; font-size: 11px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); }
.wiki-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
.wiki-tile {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  align-items: center;
  gap: 0 8px;
  padding: 6px 8px;
  border: 1px solid var(--line);
  background: linear-gradient(180deg, #121c26, #0b131a);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.wiki-tile .item-icon { grid-row: 1 / span 2; }
.wiki-tile-name { min-width: 0; overflow: hidden; font-size: 13px; color: var(--ink-bright); text-overflow: ellipsis; white-space: nowrap; }
.wiki-tile:hover,
.wiki-tile:focus-visible { border-color: var(--accent); background: linear-gradient(180deg, #16303d, #0d1b24); outline: none; }

.wiki-nav { display: flex; flex-wrap: wrap; gap: 8px; }
.wiki-head { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 14px; align-items: start; }
.wiki-head-icon {
  display: grid;
  place-items: center;
  width: 68px;
  height: 68px;
  border: 1px solid var(--line-strong);
  background: linear-gradient(180deg, #121c26, #0b131a);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), inset 0 -2px 4px rgba(0, 0, 0, 0.45);
}
.wiki-head-text { display: grid; gap: 6px; min-width: 0; }
.wiki-title { font-size: 20px; }
.wiki-facts { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; margin: 0; font-size: 12px; color: var(--ink-dim); }
.wiki-facts .flog-pick-tier { font-size: 11px; }
.wiki-about { color: var(--ink); }

.wiki-rows { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.wiki-row {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  gap: 10px;
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-left: 2px solid rgba(var(--accent-rgb), 0.45);
  background: rgba(5, 8, 12, 0.45);
}
.wiki-row-icon { display: grid; place-items: start center; padding-top: 1px; color: var(--accent); }
.wiki-row-body { display: grid; gap: 6px; min-width: 0; }
.wiki-row-head { margin: 0; font-size: 13px; color: var(--ink); }
.wiki-machine { font-weight: 600; color: var(--ink-bright); }
.wiki-note { margin: 0; font-size: 12px; line-height: 1.45; color: var(--ink-dim); }
.wiki-none { color: var(--ink-dim); }
.wiki-group { display: grid; gap: 6px; }
.wiki-formula { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.wiki-parts { display: flex; flex-wrap: wrap; gap: 6px; }
.wiki-arrow { color: var(--ink-dim); }
.wiki-link {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 28px;
  padding: 2px 8px 2px 4px;
  border: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.55);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.wiki-link:hover,
.wiki-link:focus-visible { border-color: var(--accent); color: var(--ink-bright); outline: none; }
.wiki-link.is-here { border-color: rgba(var(--accent-rgb), 0.6); background: var(--accent-wash); color: var(--ink-bright); cursor: default; }
.wiki-link.is-bare { padding-right: 4px; }
.wiki-units { color: var(--ink-bright); font-variant-numeric: tabular-nums; }
.wiki-hits { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }

@media (max-width: 720px) {
  .wiki-tiles { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); }
  .wiki-head-icon { width: 56px; height: 56px; }
  .wiki-head-icon .item-icon { width: 44px; height: 44px; }
}

/* ==== end of Logistics colors and the Item wiki ==== */

/* ==== Help: Quick access (2026-10-18) ==== */
.help-quick {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 8px;
}
.help-quick-tile {
  display: grid;
  gap: 4px;
  align-content: start;
  padding: 12px 14px;
  border: 1px solid var(--line);
  background: rgba(150, 196, 224, 0.03);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.help-quick-tile:hover,
.help-quick-tile:focus-visible { border-color: rgba(var(--accent-rgb), 0.55); background: var(--accent-wash); }
.help-quick-label { color: var(--ink-bright); font-size: 14px; }
.help-quick-about { color: var(--ink-dim); font-size: 12px; line-height: 1.4; }
/* ==== end of Help: Quick access ==== */

/* ==== Bug reports: previews, urgent and hidden, Push (2026-10-18) ==== */
.fb-list li:has(> .fb-push) { grid-template-columns: auto minmax(0, 1fr) auto; }
/* A button doesn't stretch to its column by itself: the two lines get the row's width. */
.fb-row-main { width: 100%; }
.fb-row-title { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 6px; }
.fb-row-body {
  align-self: stretch;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink-dim);
  white-space: pre-line;
  overflow-wrap: anywhere;
}
.fb-row.is-urgent { box-shadow: inset 2px 0 0 var(--danger); }
.fb-badges { display: inline-flex; gap: 4px; vertical-align: 1px; }
.fb-badge {
  padding: 1px 6px;
  border: 1px solid var(--line-strong);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.5;
  color: var(--ink-dim);
}
.fb-badge.is-urgent { border-color: rgba(210, 86, 63, 0.7); background: rgba(210, 86, 63, 0.14); color: #ffb9a8; }
.fb-badge.is-hidden { border-color: rgba(224, 168, 60, 0.6); background: rgba(224, 168, 60, 0.08); color: var(--amber); }
.fb-badge.is-pushed { border-color: rgba(var(--accent-rgb), 0.55); color: var(--accent-ink, var(--accent)); }
.comms-message-subject .fb-badges { margin-right: 6px; }
.fb-push.is-small { align-self: center; padding: 3px 10px; font-size: 11px; }

.fb-flags { display: grid; gap: 6px; }
.fb-flag {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 8px;
  align-items: start;
  padding: 7px 10px;
  border: 1px solid var(--line);
  cursor: pointer;
}
.fb-flag input { margin: 2px 0 0; accent-color: var(--accent); }
.fb-flag-text { display: grid; gap: 2px; }
.fb-flag-label { color: var(--ink-bright); font-size: 13px; }
.fb-flag-note { color: var(--ink-dim); font-size: 12px; line-height: 1.4; }
.fb-flag.is-urgent .fb-flag-note { color: #f0a493; }
.fb-flag.is-urgent.is-on { border-color: rgba(210, 86, 63, 0.7); background: rgba(210, 86, 63, 0.1); }
.fb-flag.is-urgent.is-on .fb-flag-note { color: #ffcabd; font-weight: 600; }
.fb-flag.is-hidden.is-on { border-color: rgba(224, 168, 60, 0.6); background: rgba(224, 168, 60, 0.07); }

.fb-push-quote {
  margin: 0;
  padding: 8px 12px;
  border-left: 2px solid var(--line-strong);
  background: rgba(150, 196, 224, 0.03);
  max-height: 240px;
  overflow: auto;
}
.fb-push-quote-title { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; color: var(--ink-bright); font-size: 14px; }
.fb-push-quote-meta { margin: 2px 0 8px; color: var(--ink-dim); font-size: 11px; }
.fb-push-quote-body { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 13px; color: var(--ink); }
/* ==== end of Bug reports: previews, urgent and hidden, Push ==== */

/* ==== Production: Local and Global inside a station (2026-10-18) ==== */
.prod-scopes[hidden] { display: none; }
.prod-scope { min-width: 64px; }
/* ==== end of Production: Local and Global ==== */

/* ==== The station's Factory Floor spot (2026-10-18) ====
   Its own space in the station, bottom left: a brass plate in the station
   art's shades (stationart.js SHADES.brass), the accent lit on hover. */
.station-floor-door {
  position: absolute;
  left: 20px;
  bottom: 48px;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 300px;
  padding: 10px 14px 10px 10px;
  border: 1px solid var(--sv-brass-3);
  border-radius: 3px;
  background:
    linear-gradient(180deg, rgba(226, 194, 124, 0.08), transparent 40%),
    linear-gradient(180deg, #1a1d22, #101216);
  box-shadow: inset 0 0 0 1px rgba(54, 35, 14, 0.9), 0 6px 18px rgba(0, 0, 0, 0.45);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.station-floor-door[hidden] { display: none; }
.station-floor-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  border: 1px solid var(--sv-brass-2);
  border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, rgba(var(--accent-rgb), 0.28), rgba(0, 0, 0, 0.4) 70%);
  color: var(--sv-brass-5);
}
.station-floor-words { display: grid; gap: 2px; min-width: 0; }
.station-floor-name { color: var(--sv-brass-5); font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase; }
.station-floor-sub { color: var(--ink-dim); font-size: 11px; line-height: 1.35; }
.station-floor-door:hover,
.station-floor-door:focus-visible { border-color: var(--accent-ink); outline: none; }
.station-floor-door:hover .station-floor-name,
.station-floor-door:focus-visible .station-floor-name { color: var(--accent-ink); }
.stationview.is-covered .station-floor-door { visibility: hidden; }
@media (max-width: 720px) {
  .station-floor-door { left: 10px; bottom: 10px; max-width: none; padding: 6px 10px 6px 6px; }
  /* Its own row under the hint, so neither covers the other. */
  .stationview:not(.has-panel) .station-hint { padding-bottom: 60px; }
  .station-floor-sub { display: none; }
  .station-floor-icon { width: 30px; height: 30px; }
  .stationview.has-panel .station-floor-door { display: none; }
}
/* ==== end of the station's Factory Floor spot ==== */

/* ==== The research queue (2026-10-18) ==== */
.research-queue { display: grid; gap: 8px; }
.research-queue-how { margin: 0; }
.research-queue-list { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.research-queue-row {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  background: rgba(150, 196, 224, 0.03);
}
.research-queue-row.is-active { border-color: rgba(var(--accent-rgb), 0.45); }
.research-queue-n {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  font-size: 12px;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}
.research-queue-row.is-active .research-queue-n { border-color: var(--accent-ink); color: var(--accent-ink); }
.research-queue-text { display: grid; gap: 3px; min-width: 0; }
.research-queue-name { color: var(--ink-bright); font-size: 13px; }
.research-queue-sub { color: var(--ink-dim); font-size: 11px; }
.research-queue-acts { display: flex; gap: 4px; }
.research-queue-acts .win-button { min-width: 30px; padding: 4px 8px; }
.research-queue-own { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; font-size: 12px; color: var(--ink-dim); }
.research-card-queue { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
.research-chip.is-queued { border-color: rgba(var(--accent-rgb), 0.55); color: var(--accent-ink); }
.research-now-queue { margin: 2px 0 0; font-size: 11px; color: var(--accent-ink); }
.research-follow { border-style: dashed; }
/* ==== end of the research queue ==== */

/* ==== Planet size and output (2026-10-18) ==== */
.factory-rich.is-up { color: #7fd49a; }
.factory-rich.is-down { color: var(--amber); }
/* ==== end of planet size and output ==== */

/* ==== Bay floor: an upgrade with no room (2026-10-18) ==== */
/* A bigger tier (a Tier 2 Assembler, 4 by 5) that cannot grow where the
   machine stands: what is in the way, over the Upgrade buttons. */
.bay-upgrade-room {
  margin: 8px 0 0;
  padding: 6px 9px;
  border-left: 2px solid var(--danger);
  background: rgba(210, 86, 63, 0.09);
  color: #efb9aa;
  font-size: 12px;
  line-height: 1.45;
}
/* ==== end of an upgrade with no room ==== */

/* ==== The title screen's Privacy Policy and Terms (2026-10-18) ==== */
.title-consent {
  margin: 12px 0 0;
  color: var(--ink-dim);
  font-size: 12px;
  line-height: 1.5;
  text-wrap: pretty;
}
.title-consent a,
.title-legal a { color: var(--ink); text-underline-offset: 2px; }
.title-consent a:hover,
.title-legal a:hover { color: var(--accent); }
.title-legal {
  grid-area: legal;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px 22px;
  padding: 16px 0 4px;
  border-top: 1px solid var(--line);
  font-size: 13px;
  color: var(--ink-dim);
}
.title-legal-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 20px; }
.title-legal-note { margin: 0; font-size: 12px; }
/* ==== end of the title screen's Privacy Policy and Terms ==== */

/* ==== Construction Bay (2026-10-18, Dev Panel note f2c04645) ====
   Its module in the station view (ui/stationart.js constructParts), its slot
   panel (ui/stationview.js constructPanel) and its window
   (ui/constructbay.js): Buildings beside Build orders when the window is
   wide, each scrolling on its own; one above the other when it is narrow
   (a container query, so a window made narrow on a desktop stacks too). */

/* The module: a building yard under a gantry crane, a lattice derrick on
   top, crates running out along its conveyor while it builds, warning lamps
   blinking at the yard's corners. */
.station-build-jib { stroke: var(--sv-brass-3); stroke-width: 0.9; stroke-linecap: round; stroke-linejoin: round; }
.station-build-hook { stroke: var(--sv-brass-4); stroke-width: 1.1; stroke-linecap: round; stroke-linejoin: round; }
.station-build-gantry { stroke: var(--sv-brass-3); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.station-build-cable { stroke: #8fa9bd; stroke-width: 0.8; }
.station-build-trolley { fill: var(--sv-brass-4); stroke: var(--sv-brass-0); stroke-width: 0.6; }
.station-build-deck { stroke: #56616c; stroke-width: 1.4; stroke-dasharray: 3 1.5; }
.station-build-lamp { fill: #e9a53a; opacity: 0.2; }
.station-slot.is-working .station-build-lamp { opacity: 1; animation: sv-blink 1.6s steps(1, end) infinite; }
.station-slot.is-full .station-build-lamp { fill: var(--accent-ink); opacity: 0.9; }
.station-slot.is-off .station-build-lamp { opacity: 0.08; }
.station-slot.is-construct .station-build-load { opacity: 0.95; }
.stationview.is-covered .station-build-lamp { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .stationview .station-build-lamp { animation: none !important; }
}
.reduce-motion .station-build-lamp { animation: none !important; }

/* Its slot panel: the building in hand, the orders in short. */
.construct-open { justify-self: stretch; }
.construct-now { color: var(--ink-bright); }
.construct-mini { display: grid; gap: 4px; margin: 0; padding: 0; list-style: none; }
.construct-mini-row { --tone: var(--ink-dim); display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 8px; padding: 3px 0 3px 8px; border-left: 2px solid var(--tone); }
.construct-mini-name { display: grid; min-width: 0; }
.construct-mini-name b { overflow: hidden; font-size: 13px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-bright); }
.construct-mini-name small { overflow: hidden; font-size: 11px; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.construct-mini-state { font-size: 10px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--tone); }

/* An order's state, and the bay's, as a tone: building green, waiting
   yellow, up next cyan, done and full the accent, off gray. */
.construct-mini-row.is-making, .cbay-order.is-making, .cbay-state.is-working, .cbay-now.is-working, .cbay-order-state.is-making { --tone: #5fd17a; }
.construct-mini-row.is-waiting, .cbay-order.is-waiting, .cbay-state.is-waiting, .cbay-now.is-waiting, .cbay-order-state.is-waiting { --tone: #e9c94c; }
.construct-mini-row.is-ready, .cbay-order.is-ready, .cbay-order-state.is-ready { --tone: #6fc6e6; }
.construct-mini-row.is-done, .construct-mini-row.is-full, .cbay-order.is-done, .cbay-order.is-full, .cbay-state.is-done, .cbay-state.is-full,
.cbay-now.is-done, .cbay-now.is-full, .cbay-order-state.is-done, .cbay-order-state.is-full { --tone: var(--accent); }
/* Locked: its research is not done (2026-10-21), amber. */
.construct-mini-row.is-locked, .cbay-order.is-locked, .cbay-order-state.is-locked, .cbay-state.is-locked, .cbay-now.is-locked { --tone: var(--amber); }

/* The window. */
.cbay { height: 100%; container-type: inline-size; }
.cbay .win-empty svg { color: var(--accent); }
.cbay-loading { margin: 0; }
.cbay-in { display: flex; flex-direction: column; gap: 12px; min-height: 100%; padding: 2px; }
.cbay-head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.cbay-glyph { display: grid; place-items: center; flex: none; width: 34px; height: 34px; border: 1px solid var(--line-strong); color: var(--accent); background: rgba(5, 8, 12, 0.6); }
.cbay-where { display: grid; flex: 1; gap: 2px; min-width: 0; }
.cbay-where b { font-size: 14px; font-weight: 600; letter-spacing: 0.04em; color: var(--ink-bright); }
.cbay-where > span { overflow: hidden; font-size: 12px; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-dim); }
.cbay-state { --tone: var(--ink-dim); flex: none; padding: 2px 8px; border: 1px solid var(--tone); font-size: 10px; font-weight: 600; letter-spacing: 0.16em; line-height: 16px; text-transform: uppercase; color: var(--tone); }
.cbay-areas { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 14px; align-items: start; }
.cbay-area { display: flex; flex-direction: column; gap: 10px; min-width: 0; padding: 10px 12px 12px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.35); }
.cbay-area-title { display: flex; align-items: baseline; gap: 10px; margin: 0; font-size: 11px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); }
.cbay-count { margin-left: auto; font-size: 11px; font-weight: 400; letter-spacing: 0.04em; text-transform: none; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.cbay-intro, .cbay-rule { margin: 0; font-size: 12px; line-height: 1.45; color: var(--ink-dim); }
.cbay-area .win-note { margin: 0; }
.cbay-in > .win-error { margin: 0; }
.cbay-find { flex: none; }

/* Buildings: a shelf per kind, a card per tier. */
.cbay-list { display: grid; align-content: start; gap: 12px; }
.cbay-group { display: grid; gap: 6px; }
.cbay-group[hidden], .cbay-build[hidden] { display: none; }
.cbay-group-name { display: flex; align-items: center; gap: 6px; margin: 0; font-size: 10.5px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }
.cbay-group-name svg { color: var(--accent); }
.cbay-build {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 6px 10px;
  padding: 7px 8px;
  border: 1px solid var(--line);
  border-left: 2px solid transparent;
  background: rgba(10, 16, 22, 0.6);
}
.cbay-build.is-ordered { border-left-color: var(--accent); background: var(--accent-wash); }
/* Locked behind research bought with credits (2026-10-21: Tier 2 and 3
   Buildings): dimmed, an amber edge, why, and a way to the Research window. */
.cbay-build.is-locked { border-left-color: var(--amber); }
.cbay-build.is-locked .cbay-build-icon,
.cbay-build.is-locked .cbay-parts { opacity: 0.55; }
.cbay-lock { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; margin: 0; font-size: 12px; color: var(--amber); }
.cbay-lock-go {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.cbay-lock-go:hover, .cbay-lock-go:focus-visible { color: var(--ink-bright); }
.cbay-build-icon { display: grid; }
.cbay-build-text { display: grid; gap: 5px; min-width: 0; }
.cbay-build-name { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; margin: 0; }
.cbay-build-name b { font-size: 13.5px; font-weight: 600; color: var(--ink-bright); }
.cbay-build-time { font-size: 11px; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.cbay-build-ready { font-size: 11px; color: var(--amber); }
.cbay-build-ready.is-ready { color: #5fd17a; }
.cbay-parts { display: flex; flex-wrap: wrap; gap: 4px; }
.cbay-part { display: inline-flex; align-items: center; gap: 4px; padding: 2px 6px 2px 3px; border: 1px solid var(--line-strong); background: rgba(5, 8, 12, 0.75); outline: none; }
.cbay-part:focus-visible { border-color: var(--accent); }
.cbay-part-have { font-size: 10.5px; line-height: 1.1; white-space: nowrap; color: #5fd17a; font-variant-numeric: tabular-nums; }
.cbay-part.is-short { border-color: rgba(210, 86, 63, 0.7); background: rgba(210, 86, 63, 0.1); }
.cbay-part.is-short .cbay-part-have { color: #ff8f7a; }
.cbay-add { min-width: 104px; white-space: nowrap; }

/* Build orders: the building in hand, then the list. */
.cbay-now {
  --tone: var(--ink-dim);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px 12px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--tone);
  background: rgba(5, 8, 12, 0.5);
}
.cbay-now-icon { display: grid; place-items: center; width: 44px; height: 44px; border: 1px solid var(--line-strong); background: rgba(5, 8, 12, 0.7); }
.cbay-now-icon.is-blank { color: var(--ink-dim); border-style: dashed; }
.cbay-now-text { display: grid; gap: 2px; min-width: 0; }
.cbay-now-word { font-size: 10.5px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--tone); }
.cbay-now-name { overflow: hidden; font-size: 14px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-bright); }
.cbay-now-line { font-size: 12px; line-height: 1.4; color: var(--ink); }
.cbay-switch { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-dim); }
.cbay-bar { grid-column: 1 / -1; height: 6px; border: 1px solid var(--line); background: rgba(0, 0, 0, 0.6); }
.cbay-bar i { display: block; width: 0; height: 100%; background: var(--tone); transition: width 1s linear; }
.cbay-orders-wrap { min-height: 0; }
.cbay-orders { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.cbay-empty { margin: 0; padding: 26px 12px; border: 1px dashed var(--line-strong); font-size: 12.5px; line-height: 1.45; text-align: center; color: var(--ink-dim); }
.cbay-order {
  --tone: var(--ink-dim);
  display: grid;
  gap: 6px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--tone);
  background: rgba(10, 16, 22, 0.6);
}
.cbay-order.is-paused { background: rgba(10, 16, 22, 0.35); }
.cbay-order.is-new { animation: cbay-new 1.6s var(--ease); }
@keyframes cbay-new { from { box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.7); } to { box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0); } }
.cbay-order-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.cbay-order-moves { display: inline-flex; flex: none; gap: 2px; }
.cbay-move,
.cbay-remove { flex: none; min-width: 26px; height: 26px; padding: 0 6px; font-size: 13px; letter-spacing: 0; text-transform: none; }
.cbay-remove { margin-left: 2px; }
.cbay-remove.is-armed { border-color: var(--danger); color: #ffd9cf; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; }
.cbay-order-icon { display: grid; flex: none; }
.cbay-order-name { flex: 1 1 auto; min-width: 0; overflow: hidden; font-size: 13.5px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-bright); }
.cbay-order-state { --tone: var(--ink-dim); flex: none; font-size: 10px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--tone); }
.cbay-order .flog-switch { flex: none; }
.cbay-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.cbay-field { display: grid; gap: 3px; min-width: 0; }
.cbay-field-label { font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); }
.cbay-amount { padding: 5px 8px; font-size: 14px; font-variant-numeric: tabular-nums; }
.cbay-amount.is-bad { border-color: var(--danger); }
.cbay-field-note { overflow: hidden; font-size: 11px; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.cbay-order-text { margin: 0; font-size: 12px; line-height: 1.45; color: var(--ink); }
.cbay-armed { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; color: #ffb4a6; }
.cbay-save { min-height: 0; font-size: 11px; color: var(--ink-dim); }
.cbay-save:empty { display: none; }
.cbay-save.is-bad { color: #f0907a; }

/* Wide: the two areas side by side, each scrolling on its own under its
   heading, so the orders stay in sight while you look through buildings. */
@container (min-width: 721px) {
  .cbay-in { height: 100%; min-height: 0; }
  .cbay-areas { flex: 1 1 auto; min-height: 0; grid-template-rows: minmax(0, 1fr); align-items: stretch; }
  .cbay-area { min-height: 0; }
  .cbay-list,
  .cbay-orders-wrap { flex: 1 1 auto; min-height: 0; overflow: auto; padding-right: 2px; }
}
/* Narrow (a phone, or a window made narrow): one above the other, orders
   first, so what it is doing is what you see first. */
@container (max-width: 720px) {
  .cbay-areas { grid-template-columns: minmax(0, 1fr); }
  .cbay-area.is-orders { order: -1; }
}
@container (max-width: 440px) {
  .cbay-build { grid-template-columns: auto minmax(0, 1fr); }
  .cbay-add { grid-column: 1 / -1; justify-self: stretch; }
  .cbay-fields { grid-template-columns: minmax(0, 1fr); }
  .cbay-now { grid-template-columns: auto minmax(0, 1fr); }
  .cbay-switch { grid-column: 1 / -1; }
  .cbay-order-state { display: none; }
  .cbay-order-name { white-space: normal; line-height: 1.25; }
}
@media (prefers-reduced-motion: reduce) {
  .cbay-order.is-new { animation: none; }
}
.reduce-motion .cbay-order.is-new { animation: none; }
/* ==== end of Construction Bay ==== */

/* ==== Developer Alerts (2026-10-18) ====
   A message from us over everything until Continue (ui/devalert.js), framed
   in caution tape. The layer sits above every other layer on the page; the
   page behind it is made inert. The tape crawls slowly unless motion is
   reduced (the .reduce-motion rule stops it like every other animation). */
.devalert-layer {
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  display: grid;
  place-items: center;
  padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  background: rgba(3, 6, 10, 0.86);
  backdrop-filter: blur(3px);
  animation: devalert-fade 0.2s ease-out;
}
.devalert {
  position: relative;
  /* clip, not just hidden: the tape layer reaches past the frame, and a
     hidden overflow can still be scrolled (opening a drop-down did, on a
     phone, sliding the whole alert up inside its tape). */
  overflow: hidden;
  overflow: clip;
  display: flex;
  flex-direction: column;
  width: min(560px, 100%);
  max-height: calc(100dvh - 32px);
  padding: 12px;
  box-shadow: 0 0 0 1px #000, 0 28px 70px rgba(0, 0, 0, 0.7);
  outline: none;
  animation: devalert-in 0.28s var(--ease);
}
/* The tape: a stripe bigger than the frame, slid one stripe along and back
   to the start, so it seems to crawl round without a seam. */
.devalert::before {
  content: "";
  position: absolute;
  inset: -64px;
  background: repeating-linear-gradient(-45deg, var(--tape-y) 0 16px, var(--tape-k) 16px 32px);
  animation: devalert-tape 2.4s linear infinite;
}
.devalert-inner {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: linear-gradient(180deg, #111b25, var(--panel) 40%, #0a1118);
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.75);
}
.devalert-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 16px;
  background: var(--tape-y);
  color: var(--tape-k);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.24em;
  text-transform: uppercase;
}
.devalert-sign {
  display: grid;
  place-items: end center;
  flex: 0 0 auto;
  width: 20px;
  height: 18px;
  padding-bottom: 1px;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
  background: var(--tape-k);
  color: var(--tape-y);
  font-size: 12px;
  font-weight: 900;
  line-height: 1;
  letter-spacing: 0;
}
.devalert-title {
  margin: 18px 20px 8px;
  color: var(--ink-bright);
  font-size: 24px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.02em;
  overflow-wrap: anywhere;
}
.devalert-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 20px; }
.devalert-text {
  color: var(--ink);
  font-size: 15px;
  line-height: 1.55;
  white-space: pre-line;
  overflow-wrap: anywhere;
}
/* A part the player opens if they choose (an alert's `more`). */
.devalert-more { margin-top: 14px; border: 1px solid rgba(242, 194, 48, 0.35); background: rgba(242, 194, 48, 0.04); }
.devalert-more-label {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  color: var(--tape-y);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  list-style: none;
}
.devalert-more-label::-webkit-details-marker { display: none; }
.devalert-more-label::before {
  content: "";
  flex: 0 0 auto;
  width: 0;
  height: 0;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-left: 7px solid currentColor;
  transition: transform 0.15s var(--ease);
}
.devalert-more[open] > .devalert-more-label::before { transform: rotate(90deg); }
.devalert-more-label:hover,
.devalert-more-label:focus-visible { background: rgba(242, 194, 48, 0.08); outline: none; }
.devalert-more-text {
  padding: 2px 12px 12px;
  color: var(--ink);
  font-size: 14px;
  line-height: 1.55;
  white-space: pre-line;
  overflow-wrap: anywhere;
}
.devalert-error { margin: 12px 20px 0; color: #ffb4a3; font-size: 13px; }
.devalert-foot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; padding: 18px 20px 20px; }
.devalert-cancel {
  padding: 11px 22px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
}
.devalert-cancel:hover { border-color: var(--ink); color: var(--ink-bright); }
.devalert-cancel:focus-visible { outline: 2px solid var(--ink-bright); outline-offset: 3px; }
.devalert-go {
  position: relative;
  overflow: hidden;
  min-width: 190px;
  padding: 11px 22px;
  border: 0;
  background: var(--tape-y);
  color: var(--tape-k);
  font: inherit;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
}
.devalert-go:hover:not(:disabled) { background: #ffd65a; }
.devalert-go:focus-visible { outline: 2px solid var(--ink-bright); outline-offset: 3px; }
.devalert-go:disabled {
  background: rgba(242, 194, 48, 0.1);
  box-shadow: inset 0 0 0 1px rgba(242, 194, 48, 0.4);
  color: rgba(242, 194, 48, 0.75);
  cursor: not-allowed;
}
.devalert-count { font-variant-numeric: tabular-nums; }
/* How long until Continue, filling along the button's foot. */
.devalert-fill {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 3px;
  background: var(--tape-y);
  transform: scaleX(0);
  transform-origin: left;
  animation: devalert-fill var(--delay) linear forwards;
}
.devalert-go:not(:disabled) .devalert-fill { display: none; }
@keyframes devalert-fade { from { opacity: 0; } }
@keyframes devalert-in { from { opacity: 0; transform: translateY(10px) scale(0.97); } }
@keyframes devalert-tape { to { transform: translateX(45.2548px); } }
@keyframes devalert-fill { to { transform: scaleX(1); } }
@media (prefers-reduced-motion: reduce) {
  .devalert-layer, .devalert, .devalert::before { animation: none; }
}
@media (max-width: 520px) {
  .devalert { padding: 9px; }
  .devalert-head { padding: 6px 12px; font-size: 12px; letter-spacing: 0.2em; }
  .devalert-title { margin: 14px 14px 6px; font-size: 20px; }
  .devalert-scroll { padding: 0 14px; }
  .devalert-text { font-size: 14px; }
  .devalert-error { margin: 10px 14px 0; }
  .devalert-foot { padding: 14px; }
  .devalert-go, .devalert-cancel { flex: 1 1 100%; min-width: 0; }
  .devalert-go { order: -1; }
}

/* A box beside Continue (an alert's optIn): left, the buttons right. */
.devalert-opt {
  display: flex;
  flex: 1 1 220px;
  align-items: center;
  gap: 10px;
  margin-right: auto;
  color: var(--ink-bright);
  font-size: 14px;
  line-height: 1.35;
  cursor: pointer;
}
.devalert-opt-box { flex: 0 0 auto; width: 18px; height: 18px; margin: 0; accent-color: var(--tape-y); cursor: pointer; }

/* The Pilot panel's way to Achievements. */
.pilot-achievements {
  width: 100%;
  margin-bottom: 8px;
  padding: 8px 10px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}
.pilot-achievements[hidden] { display: none; }
.pilot-achievements:hover,
.pilot-achievements:focus-visible { border-color: var(--accent); background: var(--accent-wash); color: var(--ink-bright); outline: none; }

/* The Achievements window (ui/achievements.js): Developer messages are the
   alerts again, each a strip of tape and a title that opens to its words. */
.ach { display: flex; flex-direction: column; gap: 10px; }
.ach-tabs { display: flex; flex-wrap: wrap; gap: 4px; border-bottom: 1px solid var(--line); }
.ach-note { margin: 0; }
.ach-list { display: flex; flex-direction: column; gap: 6px; }
.ach-msg { position: relative; border: 1px solid var(--line); background: rgba(150, 196, 224, 0.03); }
.ach-msg::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 6px;
  background: repeating-linear-gradient(-45deg, var(--tape-y) 0 5px, var(--tape-k) 5px 10px);
}
.ach-msg-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
  padding: 10px 12px 10px 18px;
  cursor: pointer;
  list-style: none;
}
.ach-msg-head::-webkit-details-marker { display: none; }
.ach-msg-head:hover,
.ach-msg-head:focus-visible { background: rgba(242, 194, 48, 0.06); outline: none; }
.ach-msg-title { color: var(--ink-bright); font-size: 14px; font-weight: 600; overflow-wrap: anywhere; }
.ach-msg[open] .ach-msg-title { color: var(--tape-y); }
.ach-msg-date { color: var(--ink-dim); font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ach-msg-body { padding: 0 12px 12px 18px; }
.ach-msg-text { color: var(--ink); font-size: 14px; line-height: 1.55; white-space: pre-line; overflow-wrap: anywhere; }
.ach-more { margin-top: 12px; }
/* ==== end of Developer Alerts ==== */

/* ==== The Global board, a tab in Comms (ui/globalboard.js, 2026-10-18) ====
   Like a chat: newest at the bottom by the box you write in. */
.gboard { display: flex; flex-direction: column; gap: 8px; height: 100%; min-height: 0; }
.gboard-scroll { position: relative; display: flex; flex: 1 1 auto; min-height: 0; }
.gboard-list { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: auto; padding: 4px 2px 10px; }
.gboard-earlier { align-self: center; margin: 4px 0 8px; }
.gboard-empty { margin: auto; text-align: center; }
.gboard-msg { position: relative; padding: 4px 40px 4px 10px; }
.gboard-msg:not(.is-run) { margin-top: 8px; padding-top: 6px; }
.gboard-msg:hover { background: rgba(150, 196, 224, 0.04); }
.gboard-msg.is-mine { box-shadow: inset 2px 0 0 rgba(var(--accent-rgb), 0.55); }
.gboard-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; margin-bottom: 2px; }
.gboard-who { display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 2px 6px; padding: 0; border: 0; background: none; color: var(--ink-bright); font: inherit; text-align: left; }
button.gboard-who { cursor: pointer; }
button.gboard-who:hover .gboard-name,
button.gboard-who:focus-visible .gboard-name { text-decoration: underline; }
button.gboard-who:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
.gboard-name { font-size: 14px; font-weight: 600; }
.gboard-handle { color: var(--ink-dim); font-size: 12px; }
.gboard-dev { padding: 0 5px; border: 1px solid var(--tape-y); color: var(--tape-y); font-size: 10px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; }
.gboard-time { color: var(--ink-dim); font-size: 11px; font-variant-numeric: tabular-nums; }
.gboard-text { color: var(--ink); font-size: 14px; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
.gboard-del {
  position: absolute;
  top: 4px;
  right: 4px;
  padding: 1px 7px;
  border: 1px solid transparent;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  opacity: 0;
}
.gboard-msg:hover .gboard-del,
.gboard-del:focus-visible,
.gboard-del.is-armed { opacity: 1; }
.gboard-del:hover,
.gboard-del:focus-visible { color: #ffd9cf; outline: none; }
.gboard-del.is-armed { border-color: var(--danger); background: rgba(210, 86, 63, 0.14); color: #ffd9cf; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; }
@media (hover: none) { .gboard-del { opacity: 1; } }
.gboard-fresh {
  position: absolute;
  bottom: 10px;
  left: 50%;
  padding: 5px 12px;
  border: 1px solid var(--accent);
  background: var(--panel);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
  color: var(--ink-bright);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.08em;
  cursor: pointer;
  transform: translateX(-50%);
}
.gboard-fresh[hidden],
.gboard-compose[hidden],
.gboard-nohandle[hidden] { display: none; }
.gboard-compose { display: flex; align-items: flex-end; gap: 8px; }
.gboard-input { flex: 1 1 auto; min-height: 46px; max-height: 140px; resize: vertical; }
.gboard-actions { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.gboard-count { color: var(--ink-dim); font-size: 11px; font-variant-numeric: tabular-nums; }
/* ==== end of the Global board ==== */

/* ==== A reload onto the newest version (ui/updater.js, 2026-10-18) ====
   Across the top, over the game and its windows (under a Developer Alert). */
.update-banner {
  position: fixed;
  top: max(12px, env(safe-area-inset-top));
  left: 50%;
  z-index: 2147482000;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 14px;
  width: max-content;
  max-width: calc(100vw - 32px);
  padding: 10px 14px;
  border: 1px solid var(--accent);
  background: var(--panel);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.55);
  color: var(--ink-bright);
  font-size: 14px;
  transform: translateX(-50%);
}
.update-text { font-variant-numeric: tabular-nums; }
/* ==== end of the reload banner ==== */

/* ==== Dev Panel notes, 2026-10-18 afternoon ==== */
/* Production's All: every item on the graphs, lit while nothing is ticked by hand. */
.prod-all[aria-pressed="true"] { background: var(--accent-wash); color: var(--ink-bright); box-shadow: inset 0 -2px 0 var(--accent); }

/* Replies on bug reports and suggestions (ui/feedback.js): under the post,
   oldest first, then the box to write one. */
.fb-replies { margin-top: 18px; padding-top: 12px; border-top: 1px solid var(--line); }
.fb-replies-head { margin: 0 0 8px; color: var(--ink-dim); font-size: 11px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; }
.fb-reply-list { display: flex; flex-direction: column; gap: 8px; margin: 0 0 12px; padding: 0; list-style: none; }
.fb-reply { padding: 8px 10px; border: 1px solid var(--line); background: rgba(150, 196, 224, 0.03); }
.fb-reply.is-dev { border-color: rgba(240, 200, 60, 0.35); }
.fb-reply-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-bottom: 4px; }
.fb-reply-who { color: var(--ink-bright); font-size: 13px; }
.fb-reply-text { color: var(--ink); font-size: 14px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }
.fb-reply-delete { padding: 2px 8px; font-size: 11px; }
.fb-reply-form { display: flex; flex-direction: column; gap: 8px; }
.fb-reply-input { width: 100%; resize: vertical; }

/* Replying on the Global board (ui/globalboard.js): ↩ beside ×, the quote
   over a reply, the "Replying to" bar over the box, and the message a quote
   was clicked to, lit a moment. */
.gboard-msg { padding-right: 68px; }
.gboard-tools { position: absolute; top: 4px; right: 4px; display: inline-flex; gap: 2px; }
.gboard-tools .gboard-del { position: static; }
.gboard-reply {
  padding: 1px 7px;
  border: 1px solid transparent;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  opacity: 0;
}
.gboard-msg:hover .gboard-reply,
.gboard-reply:focus-visible,
.gboard-msg.is-replying .gboard-reply { opacity: 1; }
.gboard-reply:hover,
.gboard-reply:focus-visible { color: var(--ink-bright); outline: none; }
@media (hover: none) { .gboard-reply { opacity: 1; } }
/* Editing a Dev Announcement (2026-10-21): ✎ beside ×, the words in a box. */
.gboard-edit {
  padding: 1px 7px;
  border: 1px solid transparent;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  opacity: 0;
}
.gboard-msg:hover .gboard-edit,
.gboard-edit:focus-visible { opacity: 1; }
.gboard-edit:hover,
.gboard-edit:focus-visible { color: var(--ink-bright); outline: none; }
@media (hover: none) { .gboard-edit { opacity: 1; } }
.gboard-msg:has(.gboard-edit) { padding-right: 96px; }
.gboard-msg.is-editing { padding-right: 10px; background: rgba(var(--accent-rgb), 0.06); }
.gboard-msg.is-editing .gboard-tools { display: none; }
.gboard-edit-form { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.gboard-edit-input { width: 100%; min-height: 84px; resize: vertical; }
.gboard-edit-form .gboard-actions { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px; }
.gboard-edit-form .gboard-count { margin-right: auto; }
.gboard-edited { color: var(--ink-dim); font-size: 12px; }
.gboard-msg.is-replying { background: rgba(var(--accent-rgb), 0.08); }
.gboard-quote {
  display: block;
  max-width: 100%;
  margin: 0 0 3px;
  padding: 1px 0 1px 8px;
  overflow: hidden;
  border: 0;
  border-left: 2px solid rgba(var(--accent-rgb), 0.55);
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: 12px;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}
button.gboard-quote { cursor: pointer; }
button.gboard-quote:hover,
button.gboard-quote:focus-visible { color: var(--ink); outline: none; }
.gboard-quote b { color: var(--ink); font-weight: 600; }
.gboard-quote.is-gone { font-style: italic; }
.gboard-msg.is-lit { animation: gboard-lit 1.6s ease-out; }
@keyframes gboard-lit { from { background: rgba(var(--accent-rgb), 0.28); } to { background: transparent; } }
.gboard-compose { flex-wrap: wrap; }
.gboard-compose .gboard-input { flex: 1 1 0; min-width: 0; }
.gboard-replying { flex: 1 0 100%; display: flex; align-items: center; gap: 8px; min-width: 0; padding: 4px 4px 4px 8px; border-left: 2px solid var(--accent); background: rgba(var(--accent-rgb), 0.08); font-size: 12px; }
.gboard-replying[hidden] { display: none; }
.gboard-replying-label { flex: none; color: var(--ink-dim); }
.gboard-replying-label b { color: var(--ink-bright); }
.gboard-replying-text { flex: 1 1 auto; min-width: 0; overflow: hidden; color: var(--ink); text-overflow: ellipsis; white-space: nowrap; }
.gboard-replying-x { flex: none; padding: 0 6px; border: 0; background: none; color: var(--ink-dim); font: inherit; font-size: 15px; cursor: pointer; }
.gboard-replying-x:hover,
.gboard-replying-x:focus-visible { color: var(--ink-bright); outline: none; }
/* ==== end of the 2026-10-18 afternoon notes ==== */

/* ==== 2026-10-18 evening notes: What's new popup, moving the Factory Floor spot ==== */
.whatsnew-layer {
  position: fixed;
  inset: 0;
  z-index: 74; /* over windows, the tutorial card and the pilot panel; under tips and menus */
  display: grid;
  place-items: center;
  padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  background: rgba(3, 6, 10, 0.62);
  animation: devalert-fade 0.2s ease-out;
}
.whatsnew {
  display: flex;
  flex-direction: column;
  width: min(520px, 100%);
  max-height: calc(100dvh - 32px);
  background: linear-gradient(180deg, #111b25, var(--panel) 40%, #0a1118);
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 0 100%);
  box-shadow: 0 28px 70px rgba(0, 0, 0, 0.7);
  color: var(--ink);
  animation: devalert-in 0.28s var(--ease);
}
.whatsnew-head { display: flex; align-items: flex-start; gap: 12px; padding: 16px 18px 6px 20px; }
.whatsnew-titles { display: grid; gap: 4px; flex: 1 1 auto; min-width: 0; }
.whatsnew-kicker { color: var(--accent); font-size: 11px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; }
.whatsnew-title { margin: 0; color: var(--ink-bright); font-size: 22px; font-weight: 700; line-height: 1.2; letter-spacing: 0.02em; }
.whatsnew-list {
  display: grid;
  gap: 9px;
  min-height: 0;
  margin: 0;
  padding: 10px 20px 4px;
  overflow: auto;
  list-style: none;
  font-size: 14px;
  line-height: 1.5;
}
/* The tag column fits Improved, as in Patch Notes. */
.whatsnew-line { display: grid; grid-template-columns: 88px minmax(0, 1fr); column-gap: 10px; align-items: baseline; }
.whatsnew-line > .whatsnew-text:only-child { grid-column: 2; }
.whatsnew-text { color: var(--ink); }
.whatsnew-more { margin: 10px 20px 0; padding-top: 10px; border-top: 1px solid var(--line); color: var(--ink-dim); font-size: 13px; line-height: 1.5; }
.whatsnew-link { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.whatsnew-link:hover,
.whatsnew-link:focus-visible { color: var(--ink-bright); outline: none; }
.whatsnew-foot { display: flex; justify-content: flex-end; padding: 14px 20px 16px; }
@media (max-width: 720px) {
  .whatsnew-line { grid-template-columns: 1fr; row-gap: 3px; }
  .whatsnew-line > .whatsnew-text:only-child { grid-column: 1; }
}

/* The station's Factory Floor spot drags anywhere (stationview.js). */
@media (min-width: 721px) {
  .station-floor-door { cursor: grab; touch-action: none; }
  .station-floor-door.is-moving { cursor: grabbing; box-shadow: 0 14px 30px rgba(0, 0, 0, 0.6); }
}
/* ==== end of the 2026-10-18 evening notes ==== */

/* ==== Dev tags on suggestions (2026-10-19, feedback-rules.js DEV_TAGS) ====
   A tone per tag: the badge on a row or post, the filter chip, the
   developer's Dev tag row. */
.fb-badge.is-dev,
.fb-tag.is-dev { --dev-rgb: 150, 196, 224; border-color: rgba(var(--dev-rgb), 0.7); background: rgba(var(--dev-rgb), 0.14); color: rgb(var(--dev-rgb)); }
.fb-badge.is-dev.is-good, .fb-tag.is-dev.is-good { --dev-rgb: 95, 209, 122; }
.fb-badge.is-dev.is-info, .fb-tag.is-dev.is-info { --dev-rgb: 110, 160, 250; }
.fb-badge.is-dev.is-maybe, .fb-tag.is-dev.is-maybe { --dev-rgb: 224, 168, 60; }
.fb-badge.is-dev.is-no, .fb-tag.is-dev.is-no { --dev-rgb: 222, 110, 96; }
.fb-tag.is-dev.is-on { background: rgba(var(--dev-rgb), 0.32); border-color: rgb(var(--dev-rgb)); color: var(--ink-bright); }
button.fb-tag.is-dev:hover,
button.fb-tag.is-dev:focus-visible { border-color: rgb(var(--dev-rgb)); color: var(--ink-bright); }
.fb-badge.is-dev { font-weight: 600; }
.fb-devtagrow { border-top: 1px dashed var(--line); padding-top: 6px; }
/* ==== end of dev tags ==== */

/* ==== Settings → Sounds (2026-10-19): a setting that does nothing while
   Play sounds is off is dimmed, still usable (Try it works regardless). ==== */
.settings-pref.is-idle .settings-pref-label,
.settings-pref.is-idle .settings-pref-help,
.settings-pref.is-idle .settings-switch,
.settings-pref.is-idle .settings-range { opacity: 0.5; }
/* ==== end of Sounds ==== */

/* ==== Logistics: copy and paste groups (2026-10-19, RedCom's suggestion) ====
   + New group and Paste group side by side under a panel, and the line a
   paste leaves when it skipped something. */
.flog-group-adds { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 18px; justify-self: start; min-width: 0; }
.flog-paste-group { text-align: left; overflow-wrap: anywhere; }
.flog-paste-note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0;
  padding: 6px 8px;
  border-left: 2px solid var(--amber);
  background: rgba(224, 168, 60, 0.06);
  color: var(--ink);
  font-size: 12px;
  line-height: 1.4;
}
.flog-paste-note > span { flex: 1 1 auto; min-width: 0; }
.flog-paste-note-close { flex: 0 0 auto; padding: 0 4px; border: 0; background: transparent; color: var(--ink-dim); font: inherit; font-size: 15px; line-height: 1; cursor: pointer; }
.flog-paste-note-close:hover,
.flog-paste-note-close:focus-visible { color: var(--ink-bright); outline: none; }
/* ==== end of copy and paste groups ==== */

/* ==== the test server (src/gate.js markTest) ==== */
/* spacefactory.ryancollective.com, where changes are tried before they go
   live: a tag at the top of the screen from the title screen into the game.
   It takes no clicks, so it never covers a button. */
.test-server-tag {
  position: fixed;
  top: 0;
  left: 50%;
  z-index: 2147483600;
  transform: translateX(-50%);
  padding: 2px 12px 3px;
  border: 1px solid #f2b705;
  border-top: 0;
  border-radius: 0 0 6px 6px;
  background: rgba(242, 183, 5, 0.9);
  color: #1a1400;
  font: 700 11px/1.4 system-ui, sans-serif;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  pointer-events: none;
  user-select: none;
}

/* The way between the live game and the test server (gate.js
   showServerSwitch, 2026-10-23): a tab hanging from the top right, in the
   TEST SERVER tag's colors. Under the windows (z 20), so a window's close
   button is never covered; over the map and the views. While it shows,
   --switch-gap moves the right-side panels down and --switch-room (set from
   its width) keeps the view titles and the phone's map search clear of it. */
html.has-server-switch { --switch-gap: 26px; }
/* The title screen starts below the tab (and the TEST SERVER tag beside it). */
html.has-server-switch .gate { padding-top: 36px; }
.server-switch {
  position: fixed;
  top: 0;
  right: max(12px, env(safe-area-inset-right, 0px));
  z-index: 19;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  box-sizing: border-box;
  min-height: 26px;
  padding: 4px 12px 5px;
  border: 1px solid rgba(242, 183, 5, 0.75);
  border-top: 0;
  border-radius: 0 0 6px 6px;
  background: rgba(14, 12, 4, 0.92);
  color: #f2b705;
  font: 700 11px/1.4 system-ui, sans-serif;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}
/* A finger's worth of target below and beside the slim tab. */
.server-switch::after { content: ''; position: absolute; inset: 0 -6px -12px; }
.server-switch:hover { background: rgba(60, 48, 6, 0.95); color: #ffd23f; }
.server-switch:focus-visible { outline: 2px solid #f2b705; outline-offset: 2px; }
.server-switch-short { display: none; }
@media (max-width: 480px) {
  .server-switch-long { display: none; }
  .server-switch-short { display: inline; }
}
/* Turned away from the test server: the way to the real game, lit like the
   other ways in. */
.title-real {
  display: block;
  box-sizing: border-box;
  margin-top: 4px;
  border-color: rgba(var(--accent-rgb), 0.6);
  background: var(--accent-wash);
  color: var(--ink-bright);
  text-align: center;
  text-decoration: none;
}
.title-real:hover,
.title-real:focus-visible { border-color: var(--accent); outline: none; }
/* ==== end of the test server ==== */

/* ==== Dev Panel charts: the line nearest the pointer (2026-10-20), as in Production ==== */
.devs-line { transition: opacity 0.12s, stroke-width 0.12s; }
.devs-line.is-dim { opacity: 0.18; }
.devs-line.is-near { stroke-width: 3.4; }
.devs-key.is-near { color: var(--ink-bright); font-weight: 600; }
/* ==== end of Dev Panel charts ==== */

/* Logistics priorities + multi-destination exports (2026-10-20). The request
   and export dialogs' rows (ui/logistics.js source) tick any number and keep
   an order: a grip to drag by and arrows to move by, a "1st" on each ticked
   one once more than one is, a priority slider under My other stations, and
   each export place's own settings inside its row. An export slot to more
   than one place wears a fork in its corner. */
/* On the legend's own line, after "Import from" / "Export to". */
.flog-sources-hint { margin-left: 10px; font-size: 11px; letter-spacing: 0.02em; text-transform: none; color: var(--ink-dim); opacity: 0.85; }
.flog-source-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.flog-source-head .flog-source-label { flex: 1 1 auto; min-width: 0; }
.flog-source-grip {
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 16px;
  height: 20px;
  color: var(--ink-dim);
  cursor: grab;
  touch-action: none;
  user-select: none;
}
.flog-source-grip:hover { color: var(--ink-bright); }
.flog-source-grip.is-disabled { opacity: 0.35; cursor: default; }
.flog-source-grip.is-disabled:hover { color: var(--ink-dim); }
.flog-source-grip-dots { width: 14px; height: 18px; fill: none; stroke: currentColor; stroke-width: 3.4; stroke-linecap: round; }
.flog-source-step {
  flex: none;
  padding: 1px 6px;
  border: 1px solid rgba(var(--accent-rgb), 0.45);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}
.flog-source-moves { display: inline-flex; flex: none; gap: 3px; margin: -2px 0 -2px auto; }
.flog-source-move {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--line);
  background: rgba(2, 4, 6, 0.5);
  color: var(--ink-dim);
  cursor: pointer;
}
.flog-source-move:hover:not(:disabled),
.flog-source-move:focus-visible { border-color: var(--accent); color: var(--ink-bright); outline: none; }
.flog-source-move:disabled { opacity: 0.35; cursor: default; }
.flog-source-chevron { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.flog-source-moves .flog-source-grip { margin-right: 2px; }
.flog-source-extra.is-wide { grid-template-columns: minmax(0, 1fr); }
.flog-source-extra > .flog-excess,
.flog-source-extra > .flog-listcap { grid-column: 1 / -1; }
.flog-source-extra > .flog-listcap { margin: 0; }
.flog-source.is-moving {
  position: relative;
  z-index: 2;
  border-color: var(--accent);
  /* Solid, so the row it passes over doesn't show through its words. */
  background: linear-gradient(rgba(var(--accent-rgb), 0.08), rgba(var(--accent-rgb), 0.08)), rgb(18, 28, 38);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.6);
  cursor: grabbing;
}
.flog-source.is-drop-before { box-shadow: 0 -3px 0 var(--accent); }
.flog-source.is-drop-after { box-shadow: 0 3px 0 var(--accent); }
.flog-priority .flog-ticks span:nth-child(2) { color: var(--ink); }
@media (max-width: 720px) {
  .flog-source-move { width: 34px; height: 32px; }
}
/* ==== end of Logistics priorities + multi-destination exports ==== */

/* ==== Comms redesign (2026-10-20): its pages listed down the left, the
   page on the right under a header; a drawer behind ☰ when narrow (a phone).
   Dev Announcements, friends, direct messages, polls and mechanic reviews.
   ui/comms.js and the modules it mounts. ==== */
.win-body:has(> .comms) { padding: 0; overflow: hidden; }
.comms {
  position: relative;
  display: grid;
  grid-template-columns: 214px minmax(0, 1fr);
  gap: 0;
  height: 100%;
  min-height: 0;
}
.comms-nav {
  min-height: 0;
  overflow: auto;
  padding: 10px 8px 14px;
  border-right: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.42);
  scrollbar-width: thin;
}
.comms-nav-section + .comms-nav-section { margin-top: 12px; }
.comms-nav-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 22px;
  margin: 0 0 3px;
  padding: 0 4px 0 8px;
  color: var(--ink-dim);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.comms-nav-add {
  width: 24px;
  height: 22px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 4px;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
}
.comms-nav-add:hover,
.comms-nav-add:focus-visible { border-color: var(--line-strong); color: var(--ink-bright); outline: none; }
.comms-nav .comms-nav-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: 32px;
  padding: 5px 8px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  letter-spacing: 0.02em;
  text-transform: none;
  text-align: left;
  cursor: pointer;
}
.comms-nav .comms-nav-item:hover,
.comms-nav .comms-nav-item:focus-visible { background: rgba(150, 196, 224, 0.07); color: var(--ink-bright); outline: none; }
.comms-nav .comms-nav-item[aria-pressed="true"] { background: rgba(150, 196, 224, 0.15); color: var(--ink-bright); }
.comms-nav-glyph { flex: 0 0 14px; color: var(--ink-dim); font-size: 13px; text-align: center; }
.comms-nav-item[aria-pressed="true"] .comms-nav-glyph { color: var(--ink-bright); }
.comms-nav-glyph.is-dot,
.comms-head-who .comms-nav-glyph.is-dot { flex: 0 0 9px; width: 9px; height: 9px; margin: 0 2px; border-radius: 50%; background: #56636e; }
.comms-nav-glyph.is-dot.is-online { background: #3ed598; box-shadow: 0 0 6px rgba(62, 213, 152, 0.55); }
.comms-nav-glyph.is-dot.is-none { border: 1px solid var(--line-strong); background: transparent; }
.comms-nav-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.comms-nav-count {
  flex: 0 0 auto;
  min-width: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--ink-bright);
  color: var(--void);
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
.comms-nav-item[data-tab="alerts"] .comms-nav-count,
.comms-nav-item[data-tab="news"] .comms-nav-count,
.comms-nav-item[data-tab="notes"] .comms-nav-count { background: var(--danger); color: #fff; }
.comms-nav-empty { margin: 2px 8px; color: var(--ink-dim); font-size: 12px; line-height: 1.4; }
.comms-main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.comms-head { display: flex; align-items: center; gap: 10px; padding: 10px 14px 9px; border-bottom: 1px solid var(--line); }
.comms-head-text { flex: 1 1 auto; min-width: 0; }
.comms-head-title {
  margin: 0;
  overflow: hidden;
  color: var(--ink-bright);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.comms-head-about { margin: 1px 0 0; overflow: hidden; color: var(--ink-dim); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
.comms-head-tools { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px; }
.comms-head-tools:empty { display: none; }
.comms-head-who { display: inline-flex; align-items: center; gap: 6px; }
.comms-head-tools .win-button.is-idle { opacity: 0.6; cursor: default; }
.comms-main > .comms-pane { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 10px 14px 12px; }
.comms[data-page="global"] .comms-pane,
.comms[data-page="news"] .comms-pane,
.comms[data-page="dm"] .comms-pane { display: flex; flex-direction: column; overflow: hidden; padding-bottom: 10px; }
.comms .gboard { flex: 1 1 auto; }
.comms .gboard-compose { padding-top: 8px; border-top: 1px solid var(--line); }
.comms .gboard-input { min-height: 58px; max-height: 220px; resize: none; line-height: 1.45; }
.dm-seen { margin: 2px 10px 0 auto; color: var(--ink-dim); font-size: 11px; }
.comms-subtabs { display: inline-flex; gap: 2px; }
.comms-subtab {
  padding: 6px 10px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
}
.comms-subtab[aria-selected="true"] { border-bottom-color: var(--accent); color: var(--ink-bright); }
.comms-subtab:hover,
.comms-subtab:focus-visible { color: var(--ink-bright); outline: none; }
/* The drawer: only when Comms is narrow (ui/comms.js COMPACT_PX). */
.comms-navtoggle,
.comms-scrim { display: none; }
.comms-navtoggle {
  position: relative;
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  background: rgba(150, 196, 224, 0.05);
  color: var(--ink-bright);
  font: inherit;
  font-size: 18px;
  cursor: pointer;
}
.comms-navtoggle-dot { position: absolute; top: 4px; right: 4px; width: 8px; height: 8px; border-radius: 50%; background: var(--danger); }
.comms-navtoggle-dot[hidden] { display: none; }
.comms.is-compact { grid-template-columns: minmax(0, 1fr); }
.comms.is-compact .comms-navtoggle { display: inline-grid; place-items: center; }
.comms.is-compact .comms-nav {
  position: absolute;
  z-index: 3;
  inset: 0 auto 0 0;
  display: none;
  width: min(290px, 86%);
  background: rgb(10, 16, 22);
  box-shadow: 10px 0 26px rgba(0, 0, 0, 0.55);
}
.comms.is-compact.is-nav-open .comms-nav { display: block; }
.comms.is-compact.is-nav-open .comms-scrim { position: absolute; z-index: 2; inset: 0; display: block; border: 0; background: rgba(0, 0, 0, 0.5); }
.comms.is-compact .comms-head { flex-wrap: wrap; padding: 8px 10px; }
.comms.is-compact .comms-head-tools { justify-content: flex-start; width: 100%; }
.comms.is-compact .comms-main > .comms-pane { padding: 8px 10px 10px; }
.comms.is-compact .comms-nav .comms-nav-item { min-height: 42px; font-size: 15px; }
@media (pointer: coarse) {
  .comms-nav .comms-nav-item { min-height: 40px; }
  .comms-nav-add { width: 40px; height: 36px; }
  .comms-subtab { min-height: 40px; }
  .rev-del,
  .polls-takeback,
  .friends-act { min-height: 40px; }
  .polls-takeback { padding: 0 6px; }
  .polls-talk { min-height: 40px; padding: 0 10px; }
  .fb-tag.is-pick,
  .fb-tag.is-banned,
  .fb-tag-more { min-height: 36px; padding: 4px 12px; }
  .fb-views .comms-tab { min-height: 40px; }
}

/* Friends (ui/friends.js) and a new direct message. */
.friends,
.comms-dmnew-page { display: flex; flex-direction: column; gap: 12px; }
.friends-add-label { display: flex; flex-direction: column; gap: 5px; color: var(--ink-dim); font-size: 11px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; }
.friends-add-row { display: flex; flex-wrap: wrap; gap: 6px; }
.friends-add-row .win-input { flex: 1 1 180px; min-width: 0; }
.friends-add[hidden] { display: none; }
.friends-lists { display: flex; flex-wrap: wrap; gap: 4px; border-bottom: 1px solid var(--line); }
.rev-more { align-self: center; }
.rev-tips { display: flex; flex-direction: column; gap: 6px; padding: 12px 14px; border-left: 2px solid rgba(var(--rev-tone, var(--accent-rgb)), 0.6); background: rgba(150, 196, 224, 0.04); }
.rev-tips-list { display: flex; flex-direction: column; gap: 5px; margin: 0; padding-left: 18px; font-size: 13px; line-height: 1.45; }
.friends-search { width: 100%; }
.friends-count { margin: 0; color: var(--ink-dim); font-size: 12px; }
.friends-more { align-self: center; margin-top: 4px; }
.friends-body { display: flex; flex-direction: column; gap: 8px; }
.friends-list { margin: 0; padding: 0; list-style: none; }
.friends-row { display: flex; align-items: center; gap: 10px; padding: 9px 6px; border-top: 1px solid var(--line); }
.friends-row:first-child { border-top: 0; }
.friends-dot { flex: 0 0 9px; width: 9px; height: 9px; border-radius: 50%; background: #56636e; }
.friends-dot.is-online { background: #3ed598; box-shadow: 0 0 6px rgba(62, 213, 152, 0.55); }
.friends-main { display: flex; flex: 1 1 auto; flex-direction: column; min-width: 0; }
.friends-who { display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 2px 6px; }
.friends-name { color: var(--ink-bright); font-size: 14px; font-weight: 600; }
.friends-handle,
.friends-state { color: var(--ink-dim); font-size: 12px; }
.friends-acts { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
.friends-head,
.polls-head { margin: 4px 0 0; color: var(--ink-dim); font-size: 11px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; }
.friends-empty { margin: 10px 0; }
.comms.is-compact .friends-row { flex-wrap: wrap; }
.comms.is-compact .friends-acts { justify-content: flex-start; width: 100%; padding-left: 19px; }

/* Polls (ui/polls.js). */
.polls,
.polls-list { display: flex; flex-direction: column; gap: 10px; }
.polls-card { padding: 12px 14px; border: 1px solid var(--line); background: rgba(150, 196, 224, 0.03); }
.polls-card.is-open { border-color: rgba(var(--accent-rgb), 0.38); }
.polls-question { margin: 0; color: var(--ink-bright); font-size: 16px; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.polls-meta { margin: 3px 0 10px; color: var(--ink-dim); font-size: 12px; }
/* Pinned and archived polls, and each poll's private discussion (2026-10-21). */
.polls-top { display: flex; align-items: flex-start; gap: 10px; }
.polls-top .polls-question { flex: 1 1 auto; min-width: 0; }
.polls-pin { display: inline-block; margin-right: 8px; padding: 1px 7px; border: 1px solid rgba(var(--accent-rgb), 0.55); border-radius: 999px;
  color: var(--accent); font-size: 11px; font-weight: 600; letter-spacing: 0.04em; vertical-align: 2px; }
.polls-card.is-pinned { border-color: rgba(var(--accent-rgb), 0.6); background: rgba(var(--accent-rgb), 0.05); }
.polls-card.is-archived { opacity: 0.8; }
.polls-talk {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.polls-talk:hover,
.polls-talk:focus-visible,
.polls-talk.is-on { border-color: var(--accent); color: var(--ink-bright); outline: none; }
.polls-talk.is-on { background: var(--accent-wash); }
.polls-talk-count { min-width: 16px; padding: 0 5px; border-radius: 999px; background: rgba(var(--accent-rgb), 0.28); color: var(--ink-bright);
  font-size: 11px; font-variant-numeric: tabular-nums; text-align: center; }
.polls-discuss { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line); }
.polls-discuss-head { margin: 0; color: var(--ink-dim); font-size: 11px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; }
.polls-discuss-none { margin: 0; }
.polls-notes { display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 0; list-style: none; }
.polls-note { padding: 6px 10px; border: 1px solid var(--line); background: rgba(150, 196, 224, 0.03); }
.polls-note.is-dev { border-color: rgba(240, 200, 60, 0.35); }
.polls-note-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--ink-dim); font-size: 12px; }
.polls-note-meta b { color: var(--ink-bright); font-weight: 600; }
.polls-note-text { margin: 4px 0 0; color: var(--ink); font-size: 13px; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
.polls-note-form { display: flex; flex-direction: column; gap: 6px; }
.polls-note-input { width: 100%; resize: vertical; }
.polls-archive-toggle { align-self: flex-start; margin-top: 4px; }
@media (max-width: 560px) {
  .polls-talk-label { display: none; }
}
.polls-options { display: flex; flex-direction: column; gap: 6px; }
.polls-option {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  min-height: 38px;
  padding: 7px 10px;
  overflow: hidden;
  isolation: isolate;
  border: 1px solid var(--line-strong);
  background: rgba(150, 196, 224, 0.04);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  text-align: left;
}
button.polls-option { cursor: pointer; }
button.polls-option:hover,
button.polls-option:focus-visible { border-color: var(--accent); color: var(--ink-bright); outline: none; }
.polls-option.has-results::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 0 auto 0 0;
  width: var(--share, 0%);
  background: rgba(var(--accent-rgb), 0.15);
  transition: width 0.3s var(--ease);
}
.polls-option.is-mine { border-color: var(--accent); color: var(--ink-bright); }
.polls-option.is-mine::before { background: rgba(var(--accent-rgb), 0.28); }
.polls-option-text { min-width: 0; overflow-wrap: anywhere; }
.polls-option-count { flex: 0 0 auto; color: var(--ink-dim); font-size: 12px; font-variant-numeric: tabular-nums; }
.polls-mine { color: var(--accent); }
.polls-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; }
.polls-takeback { padding: 4px 0; border: 0; background: none; color: var(--ink-dim); font: inherit; font-size: 12px; text-decoration: underline; cursor: pointer; }
.polls-takeback:hover,
.polls-takeback:focus-visible { color: var(--ink-bright); outline: none; }
.polls-dev { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.polls-form { display: flex; flex-direction: column; gap: 10px; padding: 12px 14px; border: 1px solid rgba(var(--accent-rgb), 0.38); background: rgba(var(--accent-rgb), 0.05); }
.polls-form-answers { display: flex; flex-direction: column; gap: 6px; }
.polls-form-answer { display: flex; gap: 6px; }
.polls-form-answer .win-input { flex: 1 1 auto; min-width: 0; }
.polls-form-more { align-self: flex-start; }
.polls-form-when { display: flex; flex-wrap: wrap; gap: 6px; }
.polls-form-when [hidden] { display: none; }

/* Mechanic reviews (ui/reviews.js): a wiki's front page. */
.rev-front,
.rev-detail { display: flex; flex-direction: column; gap: 16px; }
.rev-hero { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 16px 6px 2px; text-align: center; }
.rev-title { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: 2px 10px; margin: 0; line-height: 1; }
.rev-title-big { color: #7fe3f3; font-size: 38px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; text-shadow: 0 0 18px rgba(var(--accent-rgb), 0.35); }
.rev-search {
  display: flex;
  align-items: center;
  gap: 10px;
  width: min(640px, 100%);
  height: 48px;
  padding: 0 18px;
  border: 1px solid var(--line-strong);
  border-radius: 24px;
  background: rgba(150, 196, 224, 0.07);
  color: var(--ink-dim);
}
.rev-search:focus-within { border-color: var(--accent); }
.rev-search-icon { display: inline-grid; place-items: center; }
.rev-search-input { flex: 1 1 auto; min-width: 0; border: 0; background: none; color: var(--ink-bright); font: inherit; font-size: 16px; outline: none; }
.rev-try { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px; }
.rev-try-label { margin-right: 2px; color: var(--ink-dim); font-size: 13px; }
.rev-chip,
.rev-cat {
  min-height: 30px;
  padding: 4px 12px;
  border: 1px solid var(--line-strong);
  border-radius: 16px;
  background: rgba(150, 196, 224, 0.06);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.rev-chip:hover,
.rev-chip:focus-visible,
.rev-cat:hover,
.rev-cat:focus-visible { border-color: var(--accent); color: var(--ink-bright); outline: none; }
.rev-cat.is-on { border-color: var(--ink-bright); background: var(--ink-bright); color: var(--void); }
.rev-lede { max-width: 560px; margin: 0; color: var(--ink-dim); font-size: 13px; line-height: 1.45; }
.rev-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 14px; }
.rev-bar-title { margin: 0; color: var(--ink-bright); font-size: 18px; font-weight: 800; letter-spacing: 0.02em; }
.rev-cats { display: flex; flex-wrap: wrap; gap: 6px; }
.rev-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
.rev-card,
.rev-page-head { --rev-tone: 79, 182, 217; }
.rev [data-cat="start"] { --rev-tone: 224, 168, 60; }
.rev [data-cat="map"] { --rev-tone: 128, 146, 255; }
.rev [data-cat="mining"] { --rev-tone: 214, 142, 84; }
.rev [data-cat="floor"] { --rev-tone: 95, 209, 122; }
.rev [data-cat="research"] { --rev-tone: 176, 126, 232; }
.rev [data-cat="trading"] { --rev-tone: 233, 201, 76; }
.rev [data-cat="ships"] { --rev-tone: 232, 112, 92; }
.rev [data-cat="social"] { --rev-tone: 92, 204, 192; }
.rev [data-cat="interface"] { --rev-tone: 152, 172, 192; }
.rev-card {
  display: flex;
  gap: 12px;
  min-height: 148px;
  padding: 14px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: rgba(150, 196, 224, 0.06);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.rev-card:hover,
.rev-card:focus-visible { border-color: var(--line-strong); background: rgba(150, 196, 224, 0.1); outline: none; }
.rev-icon { display: grid; flex: 0 0 52px; place-items: center; width: 52px; height: 52px; border-radius: 8px; background: rgba(var(--rev-tone), 0.2); color: rgb(var(--rev-tone)); }
.rev-icon.is-big { flex-basis: 64px; width: 64px; height: 64px; }
.rev-card-body { display: flex; flex: 1 1 auto; flex-direction: column; gap: 4px; min-width: 0; }
.rev-card-top { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.rev-card-cat { color: var(--ink-dim); font-size: 12px; }
.rev-badge { padding: 1px 7px; border-radius: 9px; font-size: 11px; font-weight: 600; }
.rev-badge.is-mine { background: rgba(91, 124, 250, 0.2); color: #b2c2ff; }
.rev-badge.is-new { background: rgba(62, 213, 152, 0.16); color: #84ebbd; }
.rev-card-name { color: var(--ink-bright); font-size: 16px; font-weight: 700; line-height: 1.2; }
.rev-card-about { display: -webkit-box; overflow: hidden; font-size: 13px; line-height: 1.4; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.rev-card-foot { margin-top: auto; padding-top: 6px; color: var(--ink-dim); font-size: 12px; }
.rev-stars,
.rev-score-stars,
.rev-review-stars { color: #f3c872; }
.rev-none { grid-column: 1 / -1; text-align: center; }
.rev-back { align-self: flex-start; }
.rev-page-head { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 14px; padding: 14px; border-radius: 6px; background: rgba(150, 196, 224, 0.06); }
.rev-page-title { display: flex; flex: 1 1 220px; flex-direction: column; gap: 3px; min-width: 0; }
.rev-page-name { margin: 0; color: var(--ink-bright); font-size: 21px; font-weight: 700; }
.rev-page-about { margin: 0; font-size: 13px; line-height: 1.45; }
.rev-help { align-self: flex-start; margin-top: 4px; padding: 2px 0; border: 0; background: none; color: var(--accent); font: inherit; font-size: 13px; cursor: pointer; }
.rev-help:hover,
.rev-help:focus-visible { color: var(--ink-bright); outline: none; text-decoration: underline; }
.rev-score { display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 96px; }
.rev-score-num { color: var(--ink-bright); font-size: 32px; font-weight: 800; line-height: 1; }
.rev-score-stars { letter-spacing: 2px; }
.rev-score-count { color: var(--ink-dim); font-size: 12px; }
.rev-write { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; border: 1px solid rgba(var(--accent-rgb), 0.32); }
.rev-write-head,
.rev-list-head { margin: 0; color: var(--ink-dim); font-size: 11px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; }
.rev-pick { display: flex; gap: 2px; }
.rev-pick-star { width: 38px; height: 38px; padding: 0; border: 0; background: none; color: var(--ink-dim); font-size: 27px; line-height: 1; cursor: pointer; }
.rev-pick-star.is-on { color: #f3c872; }
.rev-pick-star:hover,
.rev-pick-star:focus-visible { color: #ffdb8f; outline: none; }
.rev-text { min-height: 72px; resize: vertical; }
.rev-reviews { margin: 0; padding: 0; list-style: none; }
.rev-review { padding: 10px 2px; border-top: 1px solid var(--line); }
.rev-reviews.is-own .rev-review { padding: 8px 12px; border-top: 0; background: rgba(var(--accent-rgb), 0.06); }
.rev-review-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.rev-review-stars { letter-spacing: 1px; }
.rev-review-name { color: var(--ink-bright); font-weight: 600; }
.rev-review-when { color: var(--ink-dim); font-size: 12px; }
.rev-review-text { margin: 4px 0 0; line-height: 1.45; overflow-wrap: anywhere; white-space: pre-wrap; }
.rev-del { padding: 2px 8px; font-size: 11px; }
.comms.is-compact .rev-title-big { font-size: 26px; }
.comms.is-compact .rev-grid { grid-template-columns: minmax(0, 1fr); }
.comms.is-compact .rev-card { min-height: 0; }
.comms.is-compact .rev-search { height: 44px; }
/* ==== end of Comms redesign ==== */

/* ==== Ships on the market: Send to station, Send to orbit (2026-10-20, Dev
   Panel note 548903c2). Your ships in the system view's list and panel, the
   station view's Docked ships button and panel, the Ship Bay window's docked
   list, the operations panel's Send to station. ==== */
.sysview-list i[data-kind="fleet"] {
  width: 11px;
  height: 8px;
  border-radius: 0;
  background: var(--accent);
  clip-path: polygon(0 0, 100% 50%, 0 100%, 22% 50%);
}
.sysview-actions .sysview-dock-one {
  padding: 7px 12px;
  border: 1px solid var(--line-strong);
  background: rgba(10, 16, 22, 0.9);
  color: var(--ink);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}
.sysview-actions .sysview-dock-one:hover:not(:disabled),
.sysview-actions .sysview-dock-one:focus-visible { border-color: var(--accent); color: var(--accent); outline: none; }
.sysview-actions .sysview-dock:disabled,
.sysview-actions .sysview-dock-one:disabled { opacity: 0.55; cursor: default; }
.sysview-dock-why { color: var(--ink); }

/* The station view's top bar: Docked ships, before the upgrade. */
.station-docked-open:not([hidden]) { margin-left: auto; white-space: nowrap; }
.station-docked-open:not([hidden]) + .station-upgrade-open { margin-left: 0; }
.station-docked { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.station-docked-row {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  align-items: center;
  gap: 6px 8px;
  padding: 6px 8px;
  border: 1px solid var(--line);
  background: rgba(5, 8, 12, 0.45);
}
/* The panel is narrow: the buttons go under the name, so it stays one line. */
.station-docked-row .station-row-buttons { grid-column: 2; display: flex; flex-wrap: wrap; gap: 4px; }
.station-docked-row .win-button { padding: 4px 8px; font-size: 11px; }
.station-docked-more { min-width: 30px; }
.station-docked-head { margin: 10px 0 4px; font-size: 11px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-dim); }

/* The Ship Bay window: ships docked here, and the buttons under ships in
   the system. */
.shipbay-docked-buttons { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.shipbay-hangar-list li .shipbay-docked-buttons { margin: 0 0 0 8px; }
.shipbay-hangar-list li .win-button { padding: 3px 8px; font-size: 11px; }

/* The operations panel's Send to station, under the selected ships. */
.ops-dock { margin-top: 8px; width: 100%; }

/* A phone: a docked ship's buttons go under its name. */
@media (max-width: 560px) {
  .station-docked-row .station-row-buttons { grid-column: 1 / -1; }
  .shipbay-hangar-list li { flex-wrap: wrap; }
  .shipbay-hangar-list li .shipbay-docked-buttons { flex-basis: 100%; margin: 4px 0 0 28px; }
}
/* A finger, or a narrow screen: every ship button is a 40 px target. */
@media (pointer: coarse), (max-width: 560px) {
  .station-docked-row .win-button,
  .station-fleet .win-button,
  .shipbay-hangar-list li .win-button,
  .shipbay-docked-buttons .win-button { min-height: 40px; padding: 8px 12px; font-size: 12px; }
  .station-docked-more { min-width: 44px; }
  .sysview-actions .sysview-dock,
  .sysview-actions .sysview-dock-one { min-height: 40px; }
  .ops-dock { min-height: 40px; }
}
/* ==== end of Ships on the market ==== */

/* ==== Updates without a black screen (2026-10-21) ==== */
/* index.html's note for a page whose code never came (src/gate.js takes it
   away as it starts), faded in late so a page that loads never shows it. */
.boot-note {
  position: fixed;
  left: 50%;
  top: 45%;
  transform: translate(-50%, -50%);
  width: min(420px, calc(100% - 32px));
  margin: 0;
  color: var(--ink);
  font-size: 14px;
  line-height: 1.5;
  text-align: center;
  opacity: 0;
  animation: boot-note-in 0.4s ease 6s forwards;
}
.boot-note a { color: var(--accent-ink, var(--accent)); }
@keyframes boot-note-in { to { opacity: 1; } }
/* The card when the game didn't load, or while the server is reached again
   (gate.js showLoadFailed, askMe). */
.gate.is-failed .gate-tag,
.gate.is-connecting .gate-tag { margin-bottom: 0; }
.gate.is-failed .gate-wait { margin-top: 18px; padding-top: 14px; }
.gate.is-connecting .gate-title { animation: gate-connecting 1.6s ease-in-out infinite; }
@keyframes gate-connecting { 50% { opacity: 0.55; } }
@media (prefers-reduced-motion: reduce) {
  .gate.is-connecting .gate-title { animation: none; }
}
/* ==== end of Updates without a black screen ==== */

/* ==== Emoji in every writing box (2026-10-21, ui/emoji.js) ==== */
/* Room at the right of every box that gets the button, so words never run
   under it (the same test as ui/emoji.js takesEmoji). */
textarea[spellcheck="true"]:not([data-emoji="off"]),
input[type="text"][spellcheck="true"]:not([data-emoji="off"]),
input:not([type])[spellcheck="true"]:not([data-emoji="off"]),
textarea[data-emoji="on"],
input[data-emoji="on"] { padding-right: 34px !important; }
.emoji-layer {
  position: fixed;
  inset: 0;
  z-index: 76; /* over windows and the What's new card; under tips and menus */
  pointer-events: none;
}
.emoji-button {
  position: absolute;
  left: 0;
  top: 0;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  pointer-events: auto;
  transition: color 120ms var(--ease, ease), background 120ms var(--ease, ease);
}
.emoji-button[hidden] { display: none; }
.emoji-button:hover,
.emoji-button:focus-visible,
.emoji-button.is-open {
  color: var(--accent-ink, var(--accent));
  background: var(--accent-wash);
  outline: none;
}
.emoji-picker {
  position: absolute;
  left: 0;
  top: 0;
  width: 336px;
  height: 372px;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line-strong);
  border-left: 2px solid var(--accent);
  background: linear-gradient(180deg, rgba(20, 31, 42, 0.98), rgba(10, 16, 22, 0.98));
  box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.85);
  pointer-events: auto;
}
.emoji-head { padding: 8px 8px 6px; }
.emoji-search { width: 100%; box-sizing: border-box; }
.emoji-tabs {
  display: flex;
  gap: 2px;
  padding: 0 6px 6px;
  border-bottom: 1px solid var(--line);
}
.emoji-tab {
  flex: 1 1 0;
  min-width: 0;
  height: 30px;
  padding: 0;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  filter: grayscale(0.7);
  opacity: 0.7;
}
.emoji-tab:hover,
.emoji-tab:focus-visible { filter: none; opacity: 1; outline: none; background: var(--accent-wash); }
.emoji-tab[aria-pressed="true"] { filter: none; opacity: 1; border-bottom-color: var(--accent); }
.emoji-tabs.is-searching .emoji-tab { border-bottom-color: transparent; filter: grayscale(0.7); opacity: 0.7; }
.emoji-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 4px 6px 6px;
  overscroll-behavior: contain;
}
.emoji-section-head {
  position: sticky;
  top: -4px;
  margin: 0;
  padding: 6px 4px 4px;
  background: rgba(14, 22, 30, 0.97);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.emoji-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
}
.emoji-cell {
  height: 38px;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: transparent;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}
.emoji-cell:hover,
.emoji-cell:focus-visible { background: var(--accent-wash); outline: none; }
.emoji-none { margin: 18px 8px; color: var(--ink-dim); font-size: 13px; text-align: center; }
.emoji-foot {
  margin: 0;
  padding: 6px 10px;
  border-top: 1px solid var(--line);
  min-height: 16px;
  font-size: 12px;
  color: var(--ink-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* A phone: a sheet along the bottom, bigger targets. */
.emoji-picker.is-sheet {
  position: fixed;
  left: 0;
  right: 0;
  top: auto;
  bottom: 0;
  width: auto;
  height: min(52vh, 420px);
  border-left: 0;
  border-top: 2px solid var(--accent);
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.emoji-picker.is-sheet .emoji-cell { height: 44px; font-size: 26px; }
.emoji-picker.is-sheet .emoji-tab { height: 40px; font-size: 20px; }
@media (pointer: coarse) {
  .emoji-button { width: 34px; height: 34px; }
}
/* ==== end of Emoji in every writing box ==== */
/* Emoji picker (2026-10-21): a phone's sheet at the top, over a box in the
   lower half of the screen. */
.emoji-picker.is-sheet.is-top {
  top: 0;
  bottom: auto;
  border-top: 0;
  border-bottom: 2px solid var(--accent);
  padding-bottom: 0;
  padding-top: env(safe-area-inset-top, 0);
}

/* ==== Miners and stations from the inventory (2026-10-21, Dev Panel note
   b9338192): Build's cost line for a building you can hold whole (one held,
   or its materials) and its Stock line (ui/factory.js wholeCost). ==== */
.factory-costs { display: grid; gap: 2px; min-width: 0; }
.factory-cost-or { font-size: 11px; font-style: italic; color: var(--ink-dim); }
.factory-cost-item.is-whole.is-none b { color: var(--ink-dim); }
.factory-cost-item.is-whole.is-none .item-icon { opacity: 0.55; }
.factory-stock { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; margin: 0; font-size: 12px; line-height: 1.4; color: var(--ink); }
.factory-stock.is-short .factory-stock-text { color: var(--amber); }
/* ==== end of Miners and stations from the inventory ==== */
/* Emoji picker (2026-10-21): only the list gives way when room is short. */
.emoji-head,
.emoji-tabs,
.emoji-foot { flex: none; }
.emoji-body { flex: 1 1 0; }

/* Craft a Tier 1 building in the Inventory (2026-10-21): a button at the end
   of its row, so rows are wider to keep the name whole ("Assembler" needs
   about 65px beside three tier chips and the button). */
.inv-kinds { grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); }
.inv-kind.has-craft { grid-template-columns: auto minmax(0, 1fr) auto auto; }
.inv-craft { min-height: 0; padding: 3px 9px; font-size: 11px; letter-spacing: 0.04em; }
.inv-craft.is-short { opacity: 0.5; }
@media (max-width: 720px) {
  .inv-kinds { grid-template-columns: minmax(0, 1fr); }
}

/* Tier 2/3 floor machines (2026-10-21) */
/* What a floor machine's tier does better (bay.js machineBoostText): a tag
   under its name on the tool card, and beside it in its panel's head. */
.bay-boost {
  display: inline-block;
  padding: 0 6px;
  border: 1px solid rgba(var(--accent-rgb), 0.55);
  border-radius: 2px;
  background: rgba(var(--accent-rgb), 0.1);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  line-height: 16px;
  text-transform: none;
  white-space: nowrap;
  color: var(--accent);
}
.bay-boost[hidden] { display: none; }
.bay-tip-boost { margin-top: 6px; }
.bay-tip.is-folded .bay-tip-boost { display: none; }
.station-panel-title h3:has(> .bay-boost) { flex-wrap: wrap; row-gap: 4px; }
.bay-boost-note { color: var(--ink); }
/* A floor assembler still making a building (from before 2026-10-21). */
.bay-building-note { padding-left: 8px; border-left: 2px solid var(--amber); color: var(--ink); }

/* Public system names (2026-10-21, ui/places.js): the pilot whose station is
   in a system names it for everyone, its location code always after it. The
   map card's code beside a given name; the naming box's buttons fold onto
   two rows on a phone. */
.map-card-code {
  margin-left: 0.45em;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.1em;
  color: var(--ink-dim);
  white-space: nowrap;
}
/* A code never breaks at its dashes, and a name is laid out on its own, so
   a right-to-left one can't carry the code round to its other side. */
.place-code,
.sysview-name .sysview-code { white-space: nowrap; }
.place-name,
.map-result-name { unicode-bidi: isolate; }
.place-pop[data-mode="public"] .win-field > span { color: var(--accent); }
.place-pop-actions .win-button { min-height: 32px; }
@media (max-width: 600px) {
  .place-pop-actions .win-button { min-height: 40px; }
  .place-pop-actions .comms-spacer { flex-basis: 100%; height: 0; }
}

/* ==== Reactions on messages (2026-10-21, ui/chatlog.js createReactions) ====
   #general, direct messages and Dev Announcements: chips under a message
   (emoji and count, lit when one is yours), and the Quick bar (❤️ 👍 👎 +)
   in the message's tools. With a mouse the bar shows on hover, the tools a
   small panel over the message's corner; on a touch screen the smiley (or a
   tap on the message) opens it as a row under the message, 40 px targets. */
.react-strip { display: flex; flex-wrap: wrap; gap: 4px; margin: 4px 0 1px; }
.react-strip[hidden] { display: none; }
.react-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 26px;
  padding: 1px 9px 1px 7px;
  border: 1px solid var(--line);
  border-radius: 13px;
  background: rgba(150, 196, 224, 0.05);
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
}
.react-chip.is-mine { border-color: rgba(var(--accent-rgb), 0.75); background: var(--accent-wash); color: var(--ink-bright); }
.react-chip[aria-disabled="true"] { cursor: default; }
.react-chip:not([aria-disabled="true"]):hover,
.react-chip:focus-visible { border-color: var(--accent); color: var(--ink-bright); outline: none; }
/* The color emoji font first, so ❤️ isn't drawn as a plain text heart. */
.react-emoji,
.react-bar .react-quick { font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Twemoji Mozilla", sans-serif; }
.react-emoji { font-size: 15px; }
.react-count { font-weight: 600; font-variant-numeric: tabular-nums; }
.react-bar { display: none; align-items: center; gap: 1px; }
.react-quick,
.react-more,
.react-open {
  display: inline-grid;
  place-items: center;
  min-width: 28px;
  height: 26px;
  padding: 0 4px;
  border: 1px solid transparent;
  border-radius: 4px;
  background: none;
  color: var(--ink-dim);
  font: inherit;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
.react-more { font-size: 19px; font-weight: 600; }
.react-quick.is-mine { border-color: rgba(var(--accent-rgb), 0.6); background: var(--accent-wash); }
.react-quick:hover,
.react-more:hover,
.react-open:hover,
.react-quick:focus-visible,
.react-more:focus-visible,
.react-open:focus-visible { background: rgba(150, 196, 224, 0.12); color: var(--ink-bright); outline: none; }
.react-open { display: none; }
@media (hover: hover) {
  .gboard-msg:hover .react-bar,
  .gboard-msg:focus-within .react-bar { display: inline-flex; }
  .gboard-msg:hover .gboard-tools:has(.react-bar),
  .gboard-msg:focus-within .gboard-tools:has(.react-bar) {
    z-index: 2;
    top: 2px;
    right: 2px;
    align-items: center;
    padding: 1px;
    border: 1px solid var(--line);
    background: var(--panel);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
  }
}
@media (hover: none) {
  .react-open { display: inline-grid; position: relative; }
  /* A bigger place to tap than it looks. */
  .react-open::after { content: ""; position: absolute; inset: -7px -3px; }
  .gboard-msg.is-reacting { padding-right: 10px; background: rgba(var(--accent-rgb), 0.06); }
  .gboard-msg.is-reacting .react-bar { display: inline-flex; margin-right: auto; }
  .gboard-msg.is-reacting .gboard-tools { position: static; display: flex; flex-wrap: wrap; align-items: center; gap: 2px; margin-top: 6px; }
  .gboard-msg.is-reacting .react-quick,
  .gboard-msg.is-reacting .react-more,
  .gboard-msg.is-reacting .react-open,
  .gboard-msg.is-reacting .gboard-reply,
  .gboard-msg.is-reacting .gboard-del { min-width: 44px; height: 40px; font-size: 20px; }
  .gboard-msg.is-reacting .react-quick,
  .gboard-msg.is-reacting .react-more { border-color: var(--line); background: rgba(150, 196, 224, 0.05); }
  .gboard-msg.is-reacting .react-quick.is-mine { border-color: rgba(var(--accent-rgb), 0.75); background: var(--accent-wash); }
  .react-open[aria-expanded="true"] { background: var(--accent-wash); color: var(--ink-bright); }
  .react-chip { min-height: 36px; padding: 2px 12px 2px 10px; border-radius: 18px; font-size: 13px; }
  .react-emoji { font-size: 18px; }
}
/* ==== end of reactions ==== */

/* Dev Panel notes 2026-10-21 (evening): a floor machine's own switch, a
   bug report's device line and badge (developers only), and Push to the
   radar beside Push to dev notes. */
.bay-machine-switch { margin: 8px 0 2px; }
.fb-badge.is-device { border-color: rgba(150, 196, 224, 0.5); color: #9cc4e0; }
.fb-device { margin-top: 2px; font-size: 11px; opacity: 0.85; }
.fb-push-actions { row-gap: 8px; }
/* The star map's developer view (ui/devstations.js): its switch under the
   operations view's (placed by ui/maptoggles.js), in its look but cyan, and
   a Dev line on the map card. */
.map-dev-toggle.is-on { border-color: #4fd1e0; color: #bdf1f7; background: linear-gradient(180deg, rgba(79, 209, 224, 0.16), rgba(10, 16, 22, 0.92)); }
.map-dev-toggle.is-on .map-ops-toggle-dot { background: #4fd1e0; border-color: #4fd1e0; box-shadow: 0 0 6px rgba(79, 209, 224, 0.7); }
.map-dev-count { color: var(--ink-dim); letter-spacing: 0.04em; }
.map-dev-count:empty { display: none; }
.map-card-dev { margin: 6px 0 0; font-size: 12px; line-height: 1.45; color: #bdf1f7; }
.map-card-dev[hidden] { display: none; }
.map-card-dev-tag { display: inline-block; margin-right: 6px; padding: 0 5px; border: 1px solid rgba(79, 209, 224, 0.6); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: #4fd1e0; }
/* Recently updated (src/mechanics.js `updated`): Help's Quick access tiles,
   with their date, and the tag on Reviews' cards and pages. */
.help-quick-tile.is-updated { border-left: 2px solid #e2b55a; }
.help-recent-date { margin-left: 8px; padding: 0 6px; border: 1px solid rgba(226, 181, 90, 0.5); border-radius: 8px; font-size: 10px; font-weight: 600; letter-spacing: 0.06em; color: #e9c77f; vertical-align: 1px; }
.rev-badge.is-updated { background: rgba(226, 181, 90, 0.16); color: #e9c77f; white-space: nowrap; }
.rev-page-updated { margin: 6px 0 4px; font-size: 13px; line-height: 1.45; color: var(--ink); }
/* ==== end of Dev Panel notes 2026-10-21 (evening) ==== */

/* ==== Dev Panel notes 2026-10-22 ==== */
/* Polls: who can vote, the note for a pilot who can't yet, and the
   developers' line (posted, votes an hour). */
.polls-dev-meta { margin: -6px 0 10px; color: #c9a4ff; font-size: 12px; }
.polls-needs { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; margin: 0 0 10px; padding: 10px 12px;
  border: 1px solid rgba(226, 181, 90, 0.45); border-left-width: 3px; background: rgba(226, 181, 90, 0.07); }
.polls-needs p { margin: 0; color: var(--ink-bright); font-size: 13px; line-height: 1.4; }
.polls-needs .win-note { color: var(--ink-dim); font-size: 12px; }
.polls-form-voters small { display: block; margin-top: 4px; }
.polls-card .polls-option.is-closed:not(.has-results) { cursor: default; }
/* Dev Panel → Reviews (ui/devreviews.js). */
.devr { display: flex; flex-direction: column; gap: 10px; }
.devr-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.devr-bar .win-note { margin: 0; }
.devr-list { display: flex; flex-direction: column; gap: 8px; }
.devr-review { padding: 10px 12px; border: 1px solid var(--line); border-left: 3px solid var(--line-strong); background: rgba(150, 196, 224, 0.03); }
.devr-review.is-low { border-left-color: #d95926; }
.devr-review.is-mid { border-left-color: #c98500; }
.devr-review.is-high { border-left-color: #199e70; }
.devr-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.devr-mechanic { min-height: 32px; padding: 0; font-size: 14px; font-weight: 600; text-align: left; }
.devr-category { color: var(--ink-dim); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; }
.devr-stars { margin-left: auto; color: #e9c77f; letter-spacing: 0.08em; white-space: nowrap; }
.devr-meta { margin: 2px 0 6px; color: var(--ink-dim); font-size: 12px; }
.devr-text { margin: 0; color: var(--ink); font-size: 13px; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
.devr-more { align-self: center; }
.devn-to-todo { white-space: nowrap; }
/* Gift credits (ui/giftform.js): on a Dev Panel note, a board post and the Push screen. */
.gift-form { display: flex; flex-direction: column; gap: 8px; margin: 8px 0; padding: 10px 12px; border: 1px solid rgba(226, 181, 90, 0.45); border-left-width: 3px; background: rgba(226, 181, 90, 0.06); }
.gift-head { margin: 0; color: var(--ink-bright); font-size: 13px; }
.gift-given { color: var(--ink-dim); font-weight: 400; }
.gift-row { display: flex; flex-wrap: wrap; gap: 8px; }
.gift-field { flex: 0 1 140px; min-width: 110px; }
.gift-field.is-wide { flex: 1 1 220px; }
.gift-form .win-note { margin: 0; font-size: 12px; }
.fb-push-gift { flex: 0 0 auto; align-self: flex-start; width: 100%; max-width: 280px; }
.devn-gifted,
.fb-gifted { color: #e9c77f; font-size: 12px; }
.devn-gifted { padding: 1px 7px; border: 1px solid rgba(226, 181, 90, 0.5); border-radius: 999px; font-size: 11px; white-space: nowrap; }
/* Poll discussions like #general (2026-10-22): replies, quotes and reactions
   on comments, drawn with the board's own classes. */
.polls-note.gboard-msg { position: relative; margin-top: 0; padding: 6px 68px 6px 10px; }
.polls-note.gboard-msg:not(.is-run) { margin-top: 0; padding-top: 6px; }
.polls-note.is-replying { box-shadow: inset 2px 0 0 var(--accent); }
.polls-note-quote { display: block; margin: 4px 0 0; }
.polls-replying { flex: none; }
/* Discussions (Polls until 2026-10-22, Dev Panel note 15c31993): All /
   Questions / Polls over the list, each card's kind, a question's details and
   its newest answer while the discussion is shut, and the form's kind. */
.polls-kinds,
.polls-form-kind { display: flex; flex-wrap: wrap; gap: 2px; }
.polls-kinds .comms-tab[aria-checked="true"],
.polls-form-kind .comms-tab[aria-checked="true"] { color: var(--ink-bright); border-bottom-color: var(--accent); }
.polls-kinds-n { color: var(--ink-dim); letter-spacing: 0.04em; }
.polls-kinds .comms-tab[aria-checked="true"] .polls-kinds-n { color: var(--accent); }
.polls-kind { display: inline-block; margin-right: 8px; padding: 1px 7px; border: 1px solid; border-radius: 3px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; vertical-align: 3px; }
.polls-kind.is-question { border-color: rgba(95, 209, 122, 0.45); background: rgba(95, 209, 122, 0.08); color: #8fd9a4; }
.polls-kind.is-poll { border-color: rgba(201, 164, 255, 0.45); background: rgba(201, 164, 255, 0.08); color: #c9a4ff; }
.polls-details { margin: -4px 0 10px; color: var(--ink); font-size: 13px; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
.polls-latest { display: flex; align-items: baseline; gap: 6px; width: 100%; padding: 6px 10px; border: 1px solid var(--line);
  background: rgba(150, 196, 224, 0.03); color: var(--ink-dim); font: inherit; font-size: 12px; text-align: left; cursor: pointer; }
.polls-latest b { flex: none; color: var(--ink-bright); font-weight: 600; }
.polls-latest .gboard-dev { flex: none; }
.polls-latest-text { flex: 1 1 auto; min-width: 0; overflow: hidden; color: var(--ink); white-space: nowrap; text-overflow: ellipsis; }
.polls-latest-more { flex: none; color: var(--accent); }
.polls-latest:hover,
.polls-latest:focus-visible { border-color: var(--accent); outline: none; }
.polls-form-details { width: 100%; resize: vertical; }
.polls-form-note { margin: 0; }
.comms.is-compact .polls-kinds .comms-tab,
.comms.is-compact .polls-form-kind .comms-tab { min-height: 40px; }
.comms.is-compact .polls-latest { min-height: 40px; align-items: center; }

/* ==== Pictures in Comms (ui/chatimages.js, 2026-10-22) ====
   User: "allow me (the dev) to attach images in any chat box". The
   developers' picture button beside a box (#general, Dev Announcements,
   direct messages, a board reply), the pictures waiting
   over the box (bug report tiles, smaller, busy while they upload), and a
   message's pictures under its words, which shrink to fit a phone. */
.chat-attach-wrap { display: inline-flex; flex: none; align-self: flex-end; }
.chat-attach-wrap[hidden],
.chat-attach-tray[hidden] { display: none; }
.chat-attach {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--line-strong);
  background: rgba(150, 196, 224, 0.04);
  color: var(--ink-dim);
  cursor: pointer;
}
.chat-attach:hover,
.chat-attach:focus-visible { border-color: var(--accent); color: var(--ink-bright); outline: none; }
.chat-attach.is-full { opacity: 0.5; }
.chat-attach-tray { display: flex; flex-wrap: wrap; gap: 6px; }
.gboard-compose > .chat-attach-tray { flex: 1 0 100%; }
.chat-attach-item .fb-shot-open img,
.chat-attach-blank { display: block; width: 72px; height: 54px; object-fit: cover; }
.chat-attach-blank { border: 1px dashed var(--line-strong); background: #05080c; }
.chat-attach-busy {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(5, 8, 12, 0.66);
  color: var(--ink);
  font-size: 10px;
  letter-spacing: 0.06em;
  pointer-events: none;
}
.chat-attach-item .fb-shot-x { top: 2px; right: 2px; min-width: 22px; height: 22px; padding: 0 5px; }
/* The row is a size container, so a thumbnail's limit is a share of the
   row's width (cqw) and never a percentage of the button around it, which
   would leave the button as wide as the picture's own width. */
.chat-imgs { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 6px; margin: 6px 0 2px; container-type: inline-size; }
.chat-img {
  display: block;
  flex: none;
  max-width: 100%;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  overflow: hidden;
  background: #05080c;
  line-height: 0;
  cursor: zoom-in;
}
.chat-img:hover,
.chat-img:focus-visible { border-color: var(--accent); outline: none; }
.chat-img img { display: block; max-width: min(240px, calc(100cqw - 2px)); max-height: 240px; min-width: 48px; min-height: 48px; object-fit: contain; }
.chat-imgs.is-many .chat-img img { max-width: min(160px, calc(100cqw - 2px)); max-height: 160px; }
.fb-reply .chat-imgs { margin-top: 8px; }
@media (hover: none) {
  .chat-attach-item .fb-shot-x { min-width: 28px; height: 28px; }
}
/* ==== end of Pictures in Comms ==== */

/* ==== Contracts (Dev Panel note 4cd17ba1, 2026-10-22) ====
   The Contracts Office's window (ui/contracts.js): three tabs of contract
   cards, Buy the rest's quote, held goods and the Post a contract form; its
   module in a station slot (stationart.js contractsParts); and the Dev
   Panel's Contracts tab (ui/devcontracts.js). A size container, so a narrow
   window or a phone stacks the cards' parts and the form's fields, with
   tap targets about 40 px. */
.ctr { display: flex; flex-direction: column; gap: 10px; height: 100%; min-height: 0; padding: 2px; container-type: inline-size; }
.ctr .win-empty svg { color: var(--accent); }
.ctr-loading { margin: 0; }
.ctr-head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ctr-glyph { display: grid; place-items: center; flex: none; width: 34px; height: 34px; border: 1px solid var(--line-strong); color: var(--accent); background: rgba(5, 8, 12, 0.6); }
.ctr-where { display: grid; flex: 1; gap: 2px; min-width: 0; }
.ctr-where b { font-size: 14px; font-weight: 600; letter-spacing: 0.04em; color: var(--ink-bright); }
.ctr-where > span { overflow: hidden; font-size: 12px; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-dim); }
.ctr-warn { margin: 0; color: var(--amber); }
.ctr-tabs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; }
.ctr-tab {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 2px 8px;
  min-height: 38px;
  padding: 7px 10px;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.55);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
  cursor: pointer;
}
.ctr-tab:hover, .ctr-tab:focus-visible { color: var(--ink-bright); border-color: var(--accent); outline: none; }
.ctr-tab.is-on { border-color: var(--accent); background: var(--accent-wash); color: var(--ink-bright); box-shadow: inset 0 -2px 0 var(--accent); }
.ctr-tab-count { font-size: 11px; font-weight: 400; letter-spacing: 0.02em; text-transform: none; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.ctr-tab.is-on .ctr-tab-count { color: var(--accent); }
.ctr-body { display: flex; flex: 1 1 auto; flex-direction: column; gap: 10px; min-height: 0; overflow: auto; padding-right: 2px; }
.ctr-error { margin: 0; }
.ctr-intro { margin: 0; font-size: 12px; line-height: 1.45; color: var(--ink-dim); }
.ctr-empty { margin: 0; padding: 26px 12px; border: 1px dashed var(--line-strong); font-size: 12.5px; line-height: 1.45; text-align: center; color: var(--ink-dim); }

/* A contract's card: its title and pay, who it is from and its time, what it
   says, the items it asks for, and what you can do. */
.ctr-card {
  --tone: var(--accent);
  display: grid;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--tone);
  background: rgba(10, 16, 22, 0.6);
}
.ctr-card.is-player { --tone: var(--amber); }
.ctr-card.is-done { --tone: var(--ink-dim); opacity: 0.8; }
.ctr-card.is-mine { --tone: var(--accent); }
.ctr-card.is-mine.is-fulfilled { --tone: #5fd17a; }
.ctr-card.is-mine.is-canceled, .ctr-card.is-mine.is-expired { --tone: var(--ink-dim); background: rgba(10, 16, 22, 0.35); }
.ctr-card-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; min-width: 0; }
.ctr-card-title { flex: 1 1 12em; min-width: 0; margin: 0; font-size: 14.5px; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; color: var(--ink-bright); }
.ctr-pay { flex: none; padding: 2px 8px; border: 1px solid rgba(95, 209, 122, 0.45); background: rgba(95, 209, 122, 0.08); font-size: 13px; font-weight: 600; color: #8fe3a4; font-variant-numeric: tabular-nums; }
.ctr-state { --tone: var(--ink-dim); flex: none; font-size: 10px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--tone); }
.ctr-state.is-open { --tone: var(--accent); }
.ctr-state.is-fulfilled { --tone: #5fd17a; }
.ctr-meta { display: flex; flex-wrap: wrap; gap: 2px 0; margin: 0; font-size: 12px; color: var(--ink-dim); }
.ctr-meta > * + *::before { content: '·'; margin: 0 7px; color: var(--line-strong); }
.ctr-time { font-variant-numeric: tabular-nums; }
.ctr-about { margin: 0; font-size: 12.5px; line-height: 1.45; white-space: pre-line; overflow-wrap: anywhere; color: var(--ink); }
.ctr-items { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.ctr-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 34px;
  padding: 3px 9px 3px 4px;
  border: 1px solid var(--line-strong);
  background: rgba(5, 8, 12, 0.75);
}
.ctr-item-name { font-size: 12.5px; color: var(--ink-bright); }
.ctr-item-units { font-size: 12.5px; color: var(--ink); font-variant-numeric: tabular-nums; }
.ctr-item-have { font-size: 11px; color: #5fd17a; font-variant-numeric: tabular-nums; }
.ctr-item.is-short { border-color: rgba(210, 86, 63, 0.7); background: rgba(210, 86, 63, 0.1); }
.ctr-item.is-short .ctr-item-have { color: #ff8f7a; }
.ctr-foot { display: grid; gap: 6px; }
.ctr-note { margin: 0; font-size: 12px; line-height: 1.45; color: var(--ink-dim); }
.ctr-note.is-ready { color: #8fe3a4; }
.ctr-note.is-short { color: #ffb4a6; }
.ctr-note.is-done { color: var(--ink-dim); font-style: italic; }
.ctr-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.ctr-actions .win-button { min-height: 36px; }
.ctr-fulfill.is-armed, .ctr-cancel.is-armed { box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.35); }
.ctr-cancel.is-armed { box-shadow: 0 0 0 2px rgba(210, 86, 63, 0.4); }

/* Buy the rest: a line for each item missing, the total, and Buy and fulfill. */
.ctr-quote { display: grid; gap: 6px; padding: 8px 10px; border: 1px solid var(--line-strong); background: rgba(5, 8, 12, 0.6); }
.ctr-quote-lines { display: grid; gap: 4px; margin: 0; padding: 0; list-style: none; }
.ctr-quote-line { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 2px 8px; font-size: 12.5px; color: var(--ink); }
.ctr-quote-line b { font-variant-numeric: tabular-nums; color: var(--ink-bright); }
.ctr-quote-line small { grid-column: 2 / -1; font-size: 11px; color: var(--ink-dim); }
.ctr-quote-line.is-short { color: #ffb4a6; }
.ctr-quote-total { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 12px; margin: 0; padding-top: 6px; border-top: 1px solid var(--line); font-size: 12.5px; color: var(--ink-dim); }
.ctr-quote-total b { color: var(--ink-bright); font-variant-numeric: tabular-nums; }

/* My contracts: the head with Post a contract, held goods, the form. */
.ctr-mine-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.ctr-section-title { margin: 0; font-size: 11px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); }
.ctr-held { display: grid; gap: 8px; padding: 10px 12px; border: 1px solid rgba(224, 168, 60, 0.4); background: rgba(224, 168, 60, 0.06); }
.ctr-held-list { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.ctr-held-line { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 6px 10px; }
.ctr-held-text { display: grid; gap: 2px; min-width: 0; }
.ctr-held-text b { font-size: 13px; color: var(--ink-bright); }
.ctr-held-text small { font-size: 11.5px; color: var(--ink-dim); }
.ctr-held-send { display: flex; gap: 6px; align-items: center; }
.ctr-held-send select { max-width: 220px; }
.ctr-form { display: grid; gap: 10px; padding: 12px; border: 1px solid var(--accent); background: rgba(var(--accent-rgb), 0.05); }
.ctr-field { min-width: 0; }
.ctr-label { font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }
.ctr-field-note { font-size: 11px; line-height: 1.35; color: var(--ink-dim); }
.ctr-form-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.ctr-about-box { min-height: 64px; resize: vertical; }
.ctr-lines { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.ctr-line { display: grid; gap: 4px; }
.ctr-line-row { display: grid; grid-template-columns: minmax(0, 1fr) 110px auto; gap: 6px; align-items: center; }
.ctr-pick-open { display: flex; align-items: center; gap: 6px; min-height: 36px; min-width: 0; justify-content: flex-start; text-align: left; letter-spacing: 0.02em; text-transform: none; }
.ctr-pick-open span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ctr-pick-open.is-empty { border-style: dashed; color: var(--ink-dim); }
.ctr-units { font-variant-numeric: tabular-nums; }
.ctr-line-remove { min-width: 34px; min-height: 34px; }
.ctr-add-line { justify-self: start; }
.ctr-picker { display: grid; gap: 6px; padding: 8px; border: 1px solid var(--line-strong); background: rgba(5, 8, 12, 0.85); }
.ctr-picks { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 4px; max-height: 220px; overflow: auto; }
.ctr-pick {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 38px;
  padding: 3px 8px 3px 4px;
  border: 1px solid var(--line);
  background: rgba(10, 16, 22, 0.7);
  font: inherit;
  font-size: 12px;
  text-align: left;
  color: var(--ink);
  cursor: pointer;
}
.ctr-pick[hidden] { display: none; }
.ctr-pick:hover, .ctr-pick:focus-visible { border-color: var(--accent); color: var(--ink-bright); outline: none; }
.ctr-pick.is-on { border-color: var(--accent); background: var(--accent-wash); }
.ctr-pick span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Narrow: a phone, or a window made narrow. */
@container (max-width: 560px) {
  .ctr-tab { padding: 6px 4px; letter-spacing: 0.04em; }
  .ctr-tab-count { flex-basis: 100%; text-align: center; }
  .ctr-form-row { grid-template-columns: minmax(0, 1fr); }
  .ctr-line-row { grid-template-columns: minmax(0, 1fr) 84px auto; }
  .ctr-held-line { grid-template-columns: auto minmax(0, 1fr); }
  .ctr-held-send { grid-column: 1 / -1; }
  .ctr-held-send select { flex: 1 1 auto; max-width: none; }
  .ctr-actions .win-button { flex: 1 1 auto; min-height: 40px; }
  .ctr-picks { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
}

/* Its module in a station slot: a notice board of pinned contracts, and a
   beacon that blinks while it stands. */
.station-deal-cards { fill: #d9cfae; fill-opacity: 0.88; stroke: #05080c; stroke-width: 0.5; }
.station-deal-lines { stroke: #4a5560; stroke-width: 0.9; stroke-linecap: round; }
.station-deal-tick { stroke: #2f9a4a; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.station-deal-pins { fill: #d2563f; }
.station-deal-mast { stroke: var(--sv-brass-2); stroke-width: 1; }
.station-deal-beacon { fill: var(--amber); }
.station-slot.is-working .station-deal-beacon { animation: ctr-beacon 2.4s ease-in-out infinite; }
@keyframes ctr-beacon { 0%, 60%, 100% { opacity: 0.35; } 75% { opacity: 1; } }
.stationview.is-covered .station-deal-beacon { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .stationview .station-deal-beacon { animation: none !important; }
}
.reduce-motion .station-deal-beacon { animation: none !important; }

/* The Dev Panel's Contracts tab. */
.devc-form .win-field { gap: 6px; }
.devc-about { min-height: 60px; resize: vertical; }
.devc-line { flex-wrap: nowrap; }
.devc-line-icon { display: grid; flex: none; }
.devc-line > .devc-item { flex: 1 1 160px; }
.devc-line > .devc-units { flex: 0 1 110px; width: 110px; }
.devc-hours { width: 96px; }
.devc-check { cursor: pointer; }
.devc-check input { width: 16px; height: 16px; }
.devc-each { display: flex; flex-wrap: wrap; gap: 4px; }
.devc-row { display: grid; gap: 6px; padding: 10px; border: 1px solid var(--line); border-left: 3px solid var(--ink-dim); background: rgba(10, 16, 22, 0.5); }
.devc-row.is-open { border-left-color: var(--accent); }
.devc-row-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.devc-row-title { flex: 1 1 12em; min-width: 0; font-size: 14px; color: var(--ink-bright); overflow-wrap: anywhere; }
.devc-state { font-size: 10px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-dim); }
.devc-state.is-open { color: var(--accent); }
.devc-pay { font-weight: 600; color: #8fe3a4; font-variant-numeric: tabular-nums; }
.devc-row .deva-sub, .devc-about-text { margin: 0; }
.devc-about-text { font-size: 12.5px; line-height: 1.45; white-space: pre-line; color: var(--ink); }
.devc-items { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.devc-items li { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px 2px 3px; border: 1px solid var(--line-strong); font-size: 12px; color: var(--ink); }
@container (max-width: 480px) {
  .devc-line { flex-wrap: wrap; }
}
/* ==== end of Contracts ==== */
/* Dev Panel → Contracts: times each pilot may do it (2026-10-22), a short box. */
.devc-each { align-items: center; }
.devc-each .win-input { flex: none; width: 96px; }
/* Contracts: Buy the rest's profit line (2026-10-22). */
.ctr-quote-profit { border-top: 0; padding-top: 0; }
.ctr-quote-profit b { color: #4fd18b; }
.ctr-quote-profit.is-loss b { color: #ff8a73; }
/* /devnotes 2026-10-22 afternoon. A System Miners group's Make default (ui/look.js `option`). */
.look-option { display: flex; gap: 10px; align-items: flex-start; min-height: 40px; cursor: pointer; }
.look-option input { flex: none; width: 18px; height: 18px; margin: 1px 0 0; accent-color: var(--accent); }
.look-option span { display: grid; gap: 3px; }
.look-option b { color: var(--ink-bright); font-weight: 600; font-size: 12.5px; }
.look-option small { color: var(--ink-dim); font-size: 11.5px; line-height: 1.4; }
/* The Market's Seller column (note c34d2bb0): who sells each sell order. */
.mkt-book-table.is-sell .mkt-row { grid-template-columns: minmax(78px, 0.8fr) minmax(78px, 0.8fr) minmax(0, 1.3fr) minmax(0, 2fr) 74px 74px; }
.mkt-seller { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mkt-seller-name { display: inline; }
@container (max-width: 720px) {
  .mkt-book-table.is-sell .mkt-row { grid-template-columns: minmax(58px, 0.7fr) minmax(64px, 0.7fr) minmax(0, 1fr) minmax(0, 1.3fr); }
}
/* Dev Panel → Notes: Details from Claude on a done note (note fc72559b). */
.devn-details { border: 1px solid var(--line); border-left: 2px solid var(--accent); background: rgba(var(--accent-rgb), 0.05); }
.devn-details-head { padding: 8px 10px; cursor: pointer; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); }
.devn-details-head::marker { color: var(--accent); }
.devn-details[open] .devn-details-head { border-bottom: 1px solid var(--line); }
.devn-details-text { margin: 0; padding: 8px 10px 10px; font-size: 13px; line-height: 1.55; white-space: pre-wrap; color: var(--ink); }
/* Reviews' subcategories (note 0e5e7d28): named on the parent's card, listed on its page. */
.rev-card-subs { overflow: hidden; color: var(--ink-dim); font-size: 12px; line-height: 1.4; text-overflow: ellipsis; white-space: nowrap; }
.rev-card-subs-n { color: rgb(var(--rev-tone, var(--accent-rgb))); font-weight: 600; }
.rev-parent { padding: 0; border: 0; background: none; color: var(--accent); font: inherit; cursor: pointer; }
.rev-parent:hover,
.rev-parent:focus-visible { color: var(--ink-bright); outline: none; text-decoration: underline; }
.rev-subs { display: flex; flex-direction: column; gap: 8px; }
.rev-subs-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 8px; }
.rev-sub { display: flex; align-items: center; gap: 10px; min-height: 52px; padding: 8px 10px; border: 1px solid transparent; border-radius: 6px; background: rgba(150, 196, 224, 0.06); color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.rev-sub:hover,
.rev-sub:focus-visible { border-color: var(--line-strong); background: rgba(150, 196, 224, 0.1); outline: none; }
.rev-sub .rev-icon { flex-basis: 36px; width: 36px; height: 36px; }
.rev-sub-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rev-sub-name { color: var(--ink-bright); font-weight: 600; }
.rev-sub-foot { display: flex; align-items: center; gap: 4px; color: var(--ink-dim); font-size: 12px; }
.comms.is-compact .rev-subs-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* Comms → Discord servers (note 550d0041): pilots' own servers, upvoted, with Join. */
.dsc { display: flex; flex-direction: column; gap: 12px; }
.dsc-cta { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; padding: 12px 14px; border: 1px solid rgba(88, 101, 242, 0.45); border-radius: 6px; background: rgba(88, 101, 242, 0.1); }
.dsc-cta-text { display: flex; flex: 1 1 220px; flex-direction: column; gap: 2px; }
.dsc-cta-text b { color: var(--ink-bright); }
.dsc-cta-text span { color: var(--ink-dim); font-size: 13px; }
.dsc-form { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; border: 1px solid rgba(var(--accent-rgb), 0.32); }
.dsc-form-head,
.dsc-list-head { margin: 0; color: var(--ink-dim); font-size: 11px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; }
.dsc-field { display: flex; flex-direction: column; gap: 4px; }
.dsc-field-note { color: var(--ink-dim); font-size: 12px; }
.dsc-about-input { min-height: 64px; resize: vertical; }
.dsc-own { display: flex; flex-direction: column; gap: 8px; }
.dsc-list { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; list-style: none; }
.dsc-card { display: flex; align-items: flex-start; gap: 12px; padding: 12px; border: 1px solid transparent; border-radius: 6px; background: rgba(150, 196, 224, 0.06); }
.dsc-card.is-own { border-color: rgba(88, 101, 242, 0.45); }
.dsc-votes { display: flex; flex: none; flex-direction: column; align-items: center; justify-content: center; gap: 1px; width: 48px; min-height: 52px; padding: 4px 0; border: 1px solid var(--line-strong); border-radius: 6px; background: rgba(5, 8, 12, 0.35); color: var(--ink-dim); font: inherit; cursor: pointer; }
.dsc-votes b { color: var(--ink-bright); font-size: 15px; }
.dsc-votes .dsc-up-mark { font-size: 12px; line-height: 1; }
button.dsc-votes:hover:not([disabled]),
button.dsc-votes:focus-visible { border-color: rgba(88, 101, 242, 0.8); color: #aab3ff; outline: none; }
.dsc-votes.is-on { border-color: rgba(88, 101, 242, 0.9); background: rgba(88, 101, 242, 0.22); color: #c3c9ff; }
.dsc-votes.is-own { cursor: default; opacity: 0.8; }
.dsc-votes[disabled] { cursor: default; opacity: 0.6; }
.dsc-body { display: flex; flex: 1 1 auto; flex-direction: column; gap: 4px; min-width: 0; }
.dsc-name { margin: 0; color: var(--ink-bright); font-size: 16px; font-weight: 700; overflow-wrap: anywhere; }
.dsc-about { margin: 0; font-size: 13px; line-height: 1.45; overflow-wrap: anywhere; white-space: pre-wrap; }
.dsc-by { margin: 0; color: var(--ink-dim); font-size: 12px; }
.dsc-owner { color: var(--ink); font-weight: 600; }
.dsc-actions { display: flex; flex: none; flex-direction: column; align-items: stretch; gap: 6px; }
.dsc-join { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 36px; text-decoration: none; }
.dsc-del { font-size: 11px; }
.comms.is-compact .dsc-card { flex-wrap: wrap; }
.comms.is-compact .dsc-body { flex-basis: calc(100% - 60px); }
.comms.is-compact .dsc-actions { flex: 1 1 100%; flex-direction: row; flex-wrap: wrap; }
.comms.is-compact .dsc-actions > * { flex: 1 1 auto; min-height: 40px; }

/* ------------------------------------------------------------------
   A pilot's name that opens their menu (ui/pilotmenu.js, 2026-10-22:
   "let me click on player names"): the Market's sellers, Reviews, the
   Discord servers list, contracts, the Leaderboard.
   ------------------------------------------------------------------ */
.pilot-name { cursor: pointer; border-radius: 3px; }
.pilot-name:hover > *,
.pilot-name:focus-visible > * { text-decoration: underline; text-underline-offset: 2px; }
.pilot-name:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
/* A finger gets a bigger target than the name's own line, without moving it. */
@media (pointer: coarse) {
  .pilot-name { display: inline-block; padding: 9px 6px; margin: -9px -6px; }
}

/* ------------------------------------------------------------------
   The Leaderboard (ui/leaderboard.js, 2026-10-22): board chips (a picker
   in a narrow window), your place, then the top 100.
   ------------------------------------------------------------------ */
.lb { display: flex; flex-direction: column; gap: 10px; min-height: 100%; }
.lb-head { display: flex; flex-direction: column; gap: 8px; }
.lb-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.lb-chip {
  min-height: 30px;
  padding: 4px 12px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.06em;
  cursor: pointer;
}
.lb-chip[aria-selected="true"] { background: var(--accent-wash); color: var(--ink-bright); border-color: var(--accent); }
.lb-chip:hover,
.lb-chip:focus-visible { color: var(--ink-bright); outline: none; border-color: var(--accent); }
.lb-picker { display: none; min-height: 40px; }
.lb.is-compact .lb-chips { display: none; }
.lb.is-compact .lb-picker { display: block; }
.lb-about { margin: 0; font-size: 12px; color: var(--ink-dim); }
.lb-updated { opacity: 0.8; }
.lb-link { padding: 0; border: 0; background: none; color: var(--accent); font: inherit; cursor: pointer; }
.lb-link:hover,
.lb-link:focus-visible { text-decoration: underline; outline: none; }
.lb-you { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; padding: 8px 12px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.35); }
.lb-you:empty { display: none; }
.lb-you .win-note { margin: 0; }
.lb-you-label { font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-dim); }
.lb-you-rank { font-size: 18px; font-weight: 600; color: var(--ink-bright); }
.lb-you-of { font-size: 12px; color: var(--ink-dim); }
.lb-you-value { margin-left: auto; font-variant-numeric: tabular-nums; color: var(--ink-bright); }
.lb-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.lb-row { display: grid; grid-template-columns: 52px minmax(0, 1fr) auto; align-items: center; gap: 10px; min-height: 34px; padding: 4px 10px; border-bottom: 1px solid var(--line); }
.lb-row.is-you { background: var(--accent-wash); box-shadow: inset 2px 0 0 var(--accent); }
.lb-rank { font-variant-numeric: tabular-nums; color: var(--ink-dim); }
.lb-row.is-top .lb-rank { font-weight: 600; }
.lb-row.is-top-1 .lb-rank { color: #f2c94c; }
.lb-row.is-top-2 .lb-rank { color: #c9d1db; }
.lb-row.is-top-3 .lb-rank { color: #d89a5b; }
.lb-name { display: flex; align-items: baseline; gap: 6px; min-width: 0; overflow: hidden; white-space: nowrap; }
.lb-name > .pilot-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.lb-handle { font-size: 11px; color: var(--ink-dim); overflow: hidden; text-overflow: ellipsis; }
.lb-value { font-variant-numeric: tabular-nums; color: var(--ink-bright); text-align: right; }
.lb-empty,
.lb-more { padding: 10px; }
.lb-pilot { padding: 10px 12px; border: 1px solid var(--accent); background: rgba(5, 8, 12, 0.5); }
.lb-pilot-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.lb-pilot-name { font-size: 15px; font-weight: 600; }
.lb-pilot-close { margin-left: auto; }
.lb-pilot-hint { font-size: 11px; color: var(--ink-dim); }
/* One tile a board (ui/leaderboard.js rankTiles; note fc652eb2, 2026-10-23):
   name, the rank big, "of N", the value. Four across, two in a narrow window. */
.lb-tiles { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.lb-tile-body { display: grid; grid-template-rows: auto auto auto; grid-template-columns: auto 1fr; align-items: baseline; column-gap: 6px; width: 100%; min-height: 72px; padding: 7px 9px; border: 1px solid var(--line); background: rgba(255, 255, 255, 0.02); color: inherit; font: inherit; text-align: left; }
button.lb-tile-body { cursor: pointer; }
button.lb-tile-body:hover { border-color: var(--accent); background: var(--accent-wash); }
button.lb-tile-body:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }
.lb-tile.is-current .lb-tile-body { border-color: var(--accent); box-shadow: inset 0 2px 0 var(--accent); }
.lb-tile-label { grid-column: 1 / -1; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lb-tile-rank { font-size: 20px; font-weight: 600; line-height: 1.3; font-variant-numeric: tabular-nums; color: var(--ink-bright); }
.lb-tile-of { font-size: 11px; color: var(--ink-dim); white-space: nowrap; }
.lb-tile-value { grid-column: 1 / -1; font-size: 12px; font-variant-numeric: tabular-nums; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lb-tile.is-top-1 .lb-tile-rank { color: #f2c94c; }
.lb-tile.is-top-2 .lb-tile-rank { color: #c9d1db; }
.lb-tile.is-top-3 .lb-tile-rank { color: #d89a5b; }
.lb.is-compact .lb-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.lb.is-compact .lb-pilot-hint { display: none; }
@media (max-width: 600px) { .lb-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.devp-lb { display: flex; flex-direction: column; gap: 8px; }
.lb.is-compact .lb-row { min-height: 40px; grid-template-columns: 44px minmax(0, 1fr) auto; padding: 4px 6px; }
.lb.is-compact .lb-handle { display: none; }
.lb.is-compact .lb-pilot-close { width: 40px; height: 40px; }

/* ------------------------------------------------------------------
   Auto complete on a developer contract's card (ui/contracts.js autoBox,
   2026-10-22: "add a simple check box that says auto complete"): the box and
   its label a finger tall, a note under it when it is on here or elsewhere. */
.ctr-auto { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; min-height: 40px; padding: 2px 0; cursor: pointer; }
.ctr-auto-box { width: 18px; height: 18px; margin: 0; accent-color: var(--accent); cursor: pointer; }
.ctr-auto-label { font-size: 13px; color: var(--ink); }
.ctr-auto.is-on .ctr-auto-label { color: var(--accent); }
.ctr-auto-note { flex-basis: 100%; padding-left: 26px; font-size: 12px; line-height: 1.4; color: var(--ink-dim); }

/* ==== Communal contracts (Dev Panel note b36ff703, 2026-10-22) ====
   The Contracts window's Communal tab (ui/communal.js): a card per communal
   contract with the overall bar, a line per item (its bar, points a unit and
   Contribute), your share and the top contributors; and the Dev Panel's
   Communal switch, form and rows (ui/devcontracts.js). The tabs lay out
   however many there are; a narrow window (a phone) puts them two by two and
   stacks a line's parts, with tap targets about 40 px. */
.ctr-tabs { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
.ctr-card.is-communal { --tone: #b48cff; }
.ctr-card.is-communal.is-completed { --tone: #5fd17a; }
.ctr-card.is-communal.is-ended { --tone: var(--ink-dim); background: rgba(10, 16, 22, 0.4); }
.ctr-com-tag {
  flex: none;
  padding: 1px 7px;
  border: 1px solid rgba(180, 140, 255, 0.55);
  background: rgba(180, 140, 255, 0.1);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #d4bfff;
}
.ctr-com-overall { display: grid; gap: 5px; }
.ctr-com-overall-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 10px; font-size: 12px; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.ctr-com-overall-head b { font-size: 13px; color: var(--ink-bright); }
.ctr-com-bar { position: relative; height: 8px; overflow: hidden; border: 1px solid var(--line-strong); background: rgba(5, 8, 12, 0.8); }
.ctr-com-bar.is-overall { height: 12px; }
.ctr-com-fill { position: absolute; inset: 0 auto 0 0; background: var(--tone, var(--accent)); opacity: 0.85; }
.ctr-com-lines { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.ctr-com-line { display: grid; gap: 6px; padding: 8px 10px; border: 1px solid var(--line); background: rgba(5, 8, 12, 0.55); }
.ctr-com-line.is-met { border-color: rgba(95, 209, 122, 0.45); }
.ctr-com-line.is-met .ctr-com-fill { background: #5fd17a; }
.ctr-com-line.is-gone { opacity: 0.7; }
.ctr-com-line-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-width: 0; }
.ctr-com-line-head .ctr-com-name { flex: 1 1 8em; min-width: 0; font-size: 13px; color: var(--ink-bright); overflow-wrap: anywhere; }
.ctr-com-mult { flex: none; padding: 1px 6px; border: 1px solid rgba(180, 140, 255, 0.45); font-size: 11.5px; color: #d4bfff; font-variant-numeric: tabular-nums; }
.ctr-com-count { flex: none; font-size: 13px; color: var(--ink-bright); font-variant-numeric: tabular-nums; }
.ctr-com-have { font-size: 11px; color: #5fd17a; font-variant-numeric: tabular-nums; }
.ctr-com-give { display: grid; gap: 6px; }
.ctr-com-give-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.ctr-com-units { flex: 0 1 120px; width: 120px; min-height: 38px; font-variant-numeric: tabular-nums; }
.ctr-com-contribute { min-height: 38px; }
.ctr-com-result { color: var(--ink); }
.ctr-card.is-completed .ctr-com-result { color: #8fe3a4; }
.ctr-com-you { display: grid; gap: 4px; margin: 0; padding: 8px 10px; border: 1px solid rgba(180, 140, 255, 0.35); background: rgba(180, 140, 255, 0.06); font-size: 12.5px; color: var(--ink); }
.ctr-com-you p { margin: 0; }
.ctr-com-you b { color: var(--ink-bright); }
.ctr-com-you.is-none { border-style: dashed; color: var(--ink-dim); }
.ctr-com-estimate { display: flex; flex-wrap: wrap; gap: 2px 14px; font-size: 12px; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.ctr-com-top-box { display: grid; gap: 4px; }
.ctr-com-top-title { margin: 0; font-size: 11px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }
.ctr-com-top { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
.ctr-com-who { display: grid; grid-template-columns: 26px minmax(0, 1fr) auto auto; align-items: center; gap: 2px 10px; min-height: 30px; padding: 2px 8px; border: 1px solid transparent; font-size: 12.5px; }
.ctr-com-who:nth-child(odd) { background: rgba(5, 8, 12, 0.45); }
.ctr-com-who.is-you { border-color: rgba(180, 140, 255, 0.5); background: rgba(180, 140, 255, 0.08); }
.ctr-com-rank { color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.ctr-com-pilot { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 6px; min-width: 0; overflow: hidden; }
.ctr-com-pilot .pilot-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; }
.ctr-com-handle { font-size: 11px; color: var(--ink-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ctr-com-pts, .ctr-com-share { color: var(--ink-bright); text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ctr-com-share { color: var(--ink); }
.ctr-com-gap { padding-left: 12px; color: var(--ink-dim); }
@container (max-width: 560px) {
  .ctr-tabs { grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ctr-com-units { flex: 1 1 auto; width: auto; min-height: 40px; }
  .ctr-com-contribute { flex: 1 1 auto; min-height: 40px; }
  .ctr-com-who { grid-template-columns: 22px minmax(0, 1fr) auto; min-height: 40px; }
  .ctr-com-share { grid-column: 2 / -1; text-align: left; font-size: 11.5px; color: var(--ink-dim); }
}

/* The Dev Panel: the Communal switch, its form's lines and its rows. */
.devc-kind { align-items: center; }
.devc-kind .win-button.is-on { border-color: var(--accent); background: var(--accent-wash); color: var(--ink-bright); }
.devc-com-line > .devc-units { flex: 0 1 96px; width: 96px; }
.devc-com-line > .devc-mult { flex: 0 1 68px; width: 68px; font-variant-numeric: tabular-nums; }
.devc-times { color: var(--ink-dim); }
.devc-mult-word { margin: 0; }
.devc-tag { font-size: 10px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: #d4bfff; }
.devc-row.is-communal { border-left-color: rgba(180, 140, 255, 0.5); }
.devc-row.is-communal.is-open { border-left-color: #b48cff; }
.devc-com-mult { margin-left: 4px; font-weight: 400; color: #d4bfff; }
.devc-warn { color: var(--amber); }
.devc-paid { color: #8fe3a4; }
/* ==== end of Communal contracts ==== */

/* ==== The production planner (Dev Panel note 7c84b7f3, 2026-10-22: "It
   should resemble UE5 BPs or Satisfactory planner"; reworked 2026-10-23,
   note 6496d0c2; redone the same day, note 7e7e8ec6: "like ue5 bp space where
   the player can move the space around"): Help → Production planner and an
   item wiki page's Production line (ui/planner.js). An endless grid like a
   Blueprint's graph: a fine line every 16 px and a strong one every 128, moved
   with --plan-gx/--plan-gy and sized with the zoom (--plan-g, --plan-gg; the
   fine ones fade out with --plan-fine). Nodes over it carry their machine's
   color in the header, input pins down the left and the output on the right;
   dashed wires flow between them with rate tags. Around it: the items to make
   across the top, the item list on the left, This plan on the right; the
   panels lie over the grid when the planner is narrow (`is-over`). `k-<kind>`
   gives anything a step's color as --kind. */
:root {
  --plan-flow: #4cc9a2;
  --plan-flow-rgb: 76, 201, 162;
  --plan-target: #63d48a;
  /* A selected node's outline, a Blueprint's orange. */
  --plan-pick: #f0a73a;
  --plan-raw: #c2ae63;
}
.k-furnace { --kind: #e0844f; }
.k-press { --kind: #7d9fd0; }
.k-chemical { --kind: #5fbf7a; }
.k-cryo { --kind: #5cc8e0; }
.k-refinery { --kind: #c9a04a; }
.k-assembler { --kind: #a985e6; }
.k-mine { --kind: var(--plan-raw); }
.k-construct { --kind: #e07fb0; }
.k-shipyard { --kind: #b3cf5e; }
.k-other { --kind: #76899a; }
.k-target { --kind: var(--plan-target); }

/* Help: the planner fills the pane (as tall as the pane, at least its
   min-height, past which the pane scrolls). */
.help-pane.is-planner { display: flex; flex-direction: column; }
.help-topic.is-planner { flex: 1 1 auto; gap: 8px; max-width: none; }
.help-topic.is-planner > .help-summary { display: none; }
.help-topic.is-planner > .help-section { display: flex; flex: 1 1 0; min-height: 560px; }
/* Full screen: the Help window over the whole screen, its search and topics
   hidden, so the planner has all of it. */
.win.is-full {
  top: 8px !important;
  left: 8px !important;
  width: calc(100% - 16px) !important;
  height: calc(100% - 16px) !important;
  max-width: none;
  max-height: none;
  transform: none;
}
.win.is-full .win-grip { display: none; }
.help.is-plan-full { grid-template-rows: minmax(0, 1fr); }
.help.is-plan-full > .help-toolbar,
.help.is-plan-full .help-nav,
.help.is-plan-full .help-topic.is-planner > .help-title { display: none; }
.help.is-plan-full .help-layout { grid-template-columns: minmax(0, 1fr); }

.plan { position: relative; display: flex; flex: 1 1 auto; flex-direction: column; gap: 8px; min-width: 0; }
.plan-field-label { font-size: 10px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }

/* The bar across the top: what to make, then the tools. */
.plan-top { display: flex; flex-direction: column; gap: 6px; }
.plan-make,
.plan-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.plan-tools-gap { flex: 1 1 auto; }
.plan-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  box-sizing: border-box;
  height: 34px;
  padding: 0 2px 0 8px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--plan-target);
  background: rgba(99, 212, 138, 0.05);
}
.plan-chip-icon { display: grid; flex: none; place-items: center; }
.plan-chip-name { overflow: hidden; max-width: 160px; padding: 0; border: 0; background: none; color: var(--ink-bright); font: inherit; font-size: 13px; font-weight: 600;
  white-space: nowrap; text-overflow: ellipsis; cursor: pointer; }
.plan-chip-name:hover,
.plan-chip-name:focus-visible { color: var(--accent); outline: none; }
.plan-rate { position: relative; display: block; }
.plan-rate-field { box-sizing: border-box; width: 92px; height: 28px; padding: 2px 34px 2px 6px; text-align: right; font-variant-numeric: tabular-nums; }
.plan-rate-field.is-bad { border-color: var(--danger); }
.plan-rate-unit { position: absolute; top: 50%; right: 7px; color: var(--ink-dim); font-size: 11px; transform: translateY(-50%); pointer-events: none; }
.plan-chip-remove { width: 28px; height: 28px; padding: 0; border: 1px solid transparent; background: none; color: var(--ink-dim); font: inherit; font-size: 17px; line-height: 1; cursor: pointer; }
.plan-chip-remove:hover,
.plan-chip-remove:focus-visible { border-color: var(--line-strong); color: var(--danger); outline: none; }
.plan-add { white-space: nowrap; }
.plan-add-count { flex: none; color: var(--ink-dim); font-size: 11px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.plan-units { display: flex; }
.plan-unit { padding: 5px 9px; border: 1px solid var(--line-strong); background: transparent; color: var(--ink-dim); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
.plan-unit + .plan-unit { border-left: 0; }
.plan-unit:hover,
.plan-unit:focus-visible { color: var(--ink-bright); outline: none; }
.plan-unit[aria-checked="true"] { background: var(--accent-wash); color: var(--ink-bright); box-shadow: inset 0 0 0 1px var(--accent); }
.plan-tiers { display: flex; align-items: center; gap: 3px; }
.plan-tiers .plan-field-label { margin: 0 5px 0 6px; }
.plan-tier { min-width: 34px; padding: 5px 7px; border: 1px solid var(--line-strong); background: transparent; font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
.plan-tier.is-t1 { color: var(--t1); }
.plan-tier.is-t2 { color: var(--t2); }
.plan-tier.is-t3 { color: var(--t3); }
.plan-tier:hover,
.plan-tier:focus-visible { border-color: var(--accent); outline: none; }
.plan-tier[aria-checked="true"] { border-color: var(--accent); background: var(--accent-wash); box-shadow: inset 0 0 0 1px var(--accent); }
.plan-reset { padding: 0; border: 0; background: none; color: var(--ink-dim); font: inherit; font-size: 12px; text-decoration: underline; cursor: pointer; }
.plan-reset:hover { color: var(--ink-bright); }
.plan-toggle[aria-pressed="true"],
.plan-full[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-wash); color: var(--ink-bright); }

/* The item list, the grid and This plan. The body's own content never sizes
   it (basis 0), so the panels scroll inside it. */
.plan-body { position: relative; display: flex; flex: 1 1 0; gap: 8px; min-height: 0; }
.plan-stage { position: relative; display: flex; flex: 1 1 auto; min-width: 0; }
.plan-items,
.plan-side { display: flex; flex: none; flex-direction: column; box-sizing: border-box; min-height: 0; border: 1px solid var(--line); background: rgba(10, 16, 22, 0.6); }
.plan-items[hidden],
.plan-side[hidden] { display: none; }
.plan-items { width: 224px; gap: 6px; padding: 8px; }
.plan-side { width: 284px; overflow-y: auto; padding: 10px 12px 12px; }
.plan-items.is-over,
.plan-side.is-over { position: absolute; z-index: 6; top: 0; bottom: 0; max-width: calc(100% - 24px); background: rgba(12, 19, 26, 0.98); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.6); }
.plan-items.is-over { left: 0; }
.plan-side.is-over { right: 0; }

.plan-items-find { box-sizing: border-box; width: 100%; }
.plan-shelves { display: flex; flex-wrap: wrap; gap: 4px; }
.plan-shelf { padding: 3px 7px; border: 1px solid var(--line); background: transparent; color: var(--ink-dim); font: inherit; font-size: 11px; cursor: pointer; }
.plan-shelf:hover,
.plan-shelf:focus-visible { color: var(--ink-bright); outline: none; }
.plan-shelf[aria-checked="true"] { border-color: var(--accent); background: var(--accent-wash); color: var(--ink-bright); }
.plan-items-list { display: flex; flex: 1 1 0; flex-direction: column; min-height: 120px; overflow-y: auto; }
.plan-item { display: flex; flex: none; align-items: center; gap: 8px; min-height: 40px; padding: 3px 6px; border: 0; background: none; color: var(--ink); font: inherit; text-align: left; cursor: grab; }
.plan-item:hover,
.plan-item:focus-visible { background: var(--accent-wash); outline: none; }
.plan-item:disabled { opacity: 0.45; cursor: default; }
.plan-item-icon { display: grid; flex: none; place-items: center; width: 24px; }
.plan-item-names { display: flex; flex-direction: column; min-width: 0; }
.plan-item-name { overflow: hidden; color: var(--ink-bright); font-size: 13px; white-space: nowrap; text-overflow: ellipsis; }
.plan-item-shelf { color: var(--ink-dim); font-size: 11px; }
.plan-item.is-in .plan-item-shelf { color: var(--plan-flow); }
.plan-items-hint { margin: 0; color: var(--ink-dim); font-size: 11px; }
.plan-ghost { position: fixed; z-index: 1000; display: flex; align-items: center; gap: 6px; padding: 5px 9px; border: 1px solid var(--plan-flow); background: rgba(10, 16, 22, 0.95);
  color: var(--ink-bright); font-size: 12px; white-space: nowrap; transform: translate(12px, 8px); pointer-events: none; }

/* This plan. */
.plan-side-head { margin: 0 0 8px; color: var(--accent); font-size: 11px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; }
.plan-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.plan-stat { display: flex; flex-direction: column; gap: 2px; padding: 8px 9px; border: 1px solid var(--line); background: rgba(150, 196, 224, 0.04); }
.plan-stat-n { color: var(--ink-bright); font-size: 18px; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.plan-stat-label { color: var(--ink-dim); font-size: 11px; line-height: 1.3; }
.plan-side-sub { margin: 14px 0 6px; color: var(--ink-dim); font-size: 10px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; }
.plan-meters { display: flex; flex-direction: column; gap: 9px; margin: 0; padding: 0; list-style: none; }
.plan-meter {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) auto;
  grid-template-areas: "icon name n" "icon track track" "icon miners miners";
  align-items: center;
  gap: 3px 6px;
  font-size: 12px;
}
.plan-meter > .plan-total-icon { grid-area: icon; align-self: start; }
.plan-meter-name { overflow: hidden; grid-area: name; color: var(--ink); white-space: nowrap; text-overflow: ellipsis; }
.plan-meter-n { grid-area: n; color: var(--ink-bright); font-variant-numeric: tabular-nums; }
.plan-meter-track { overflow: hidden; grid-area: track; height: 6px; border-radius: 3px; background: rgba(150, 196, 224, 0.08); }
.plan-meter-track i { display: block; height: 100%; border-radius: 0 3px 3px 0; background: var(--plan-raw); }
.plan-meter-miners { grid-area: miners; color: var(--ink-dim); font-size: 11px; }
.plan-total-list { display: flex; flex-direction: column; gap: 5px; margin: 0; padding: 0; list-style: none; }
.plan-total { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.plan-total-icon { display: grid; flex: none; place-items: center; width: 18px; }
.plan-total-name { overflow: hidden; flex: 1 1 auto; min-width: 0; color: var(--ink); white-space: nowrap; text-overflow: ellipsis; }
.plan-total-exact { flex: none; color: var(--ink-dim); font-size: 11px; }
.plan-total-n { flex: none; min-width: 26px; color: var(--ink-bright); text-align: right; font-variant-numeric: tabular-nums; }
.plan-notes { display: flex; flex-direction: column; gap: 6px; margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--line); }
.plan-note { margin: 0; color: var(--ink-dim); font-size: 11.5px; line-height: 1.5; }

/* Add an item: from Add item, or where the grid was right-clicked. */
.plan-pick { position: absolute; z-index: 8; display: flex; flex-direction: column; gap: 6px; box-sizing: border-box; width: 290px; max-width: calc(100% - 8px); padding: 8px;
  border: 1px solid var(--line-strong); background: var(--panel); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.6); }
.plan-pick[hidden] { display: none; }
.plan-pick-head { margin: 0; color: var(--ink-dim); font-size: 10px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; }
.plan-pick-find { box-sizing: border-box; width: 100%; }
.plan-pick-list { max-height: 300px; overflow-y: auto; }
.plan-hit { display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 8px; border: 0; background: none; color: var(--ink); font: inherit; font-size: 13px; text-align: left; cursor: pointer; }
.plan-hit span { flex: 1 1 auto; min-width: 0; }
.plan-hit:hover,
.plan-hit:focus-visible { background: var(--accent-wash); color: var(--ink-bright); outline: none; }
.plan-hit-in { color: var(--plan-flow); font-size: 11px; white-space: nowrap; }
.plan-hits-none { margin: 0; padding: 8px 10px; }

/* The grid. */
.plan-graph { position: relative; display: flex; flex: 1 1 auto; min-width: 0; min-height: 0; }
.plan-graph.is-compact { flex: none; height: 340px; }
.plan-view {
  --plan-g: 16px;
  --plan-gg: 128px;
  --plan-gx: 0px;
  --plan-gy: 0px;
  --plan-fine: 0.06;
  position: relative;
  overflow: hidden;
  flex: 1 1 auto;
  min-height: 240px;
  border: 1px solid var(--line-strong);
  background-color: #0a1016;
  background-image:
    linear-gradient(to right, rgba(150, 196, 224, 0.11) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(150, 196, 224, 0.11) 1px, transparent 1px),
    linear-gradient(to right, rgba(150, 196, 224, var(--plan-fine)) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(150, 196, 224, var(--plan-fine)) 1px, transparent 1px);
  background-size: var(--plan-gg) var(--plan-gg), var(--plan-gg) var(--plan-gg), var(--plan-g) var(--plan-g), var(--plan-g) var(--plan-g);
  background-position: var(--plan-gx) var(--plan-gy);
  cursor: grab;
  outline: none;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}
.plan-graph.is-compact .plan-view { min-height: 0; }
.plan-view:focus-visible { border-color: var(--accent); }
.plan-view.is-panning { cursor: grabbing; }
.plan-view.is-moving,
.plan-view.is-moving .plan-node { cursor: grabbing; }
.plan-view.is-boxing { cursor: crosshair; }
.plan-graph.is-drop .plan-view { border-color: var(--plan-flow); box-shadow: inset 0 0 0 1px var(--plan-flow); }
.plan-world { position: absolute; top: 0; left: 0; transform-origin: 0 0; }
.plan-wires { position: absolute; top: 0; left: 0; overflow: visible; pointer-events: none; }
.plan-wire { fill: none; stroke: var(--plan-flow); stroke-width: 2.6; stroke-dasharray: 9 6; opacity: 0.9; animation: plan-flow 1.1s linear infinite; }
.plan-wire.is-target { stroke: var(--plan-target); }
@keyframes plan-flow { to { stroke-dashoffset: -15; } }
.plan-marquee { position: absolute; z-index: 3; border: 1px solid var(--plan-pick); background: rgba(240, 167, 58, 0.08); pointer-events: none; }
.plan-marquee[hidden] { display: none; }
/* Over the grid, never in the way of it: the zoom at the top right and the
   name at the bottom right, faint, as a Blueprint's graph has them; a line
   of how to move at the bottom left; the zoom buttons. */
.plan-zoom-n { position: absolute; top: 8px; right: 12px; color: rgba(150, 196, 224, 0.45); font-size: 13px; font-weight: 600; letter-spacing: 0.04em; font-variant-numeric: tabular-nums;
  pointer-events: none; }
.plan-mark { position: absolute; right: 16px; bottom: 8px; color: rgba(150, 196, 224, 0.09); font-size: 32px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  white-space: nowrap; pointer-events: none; }
.plan-hint { overflow: hidden; position: absolute; top: 9px; right: 120px; left: 10px; margin: 0; color: var(--ink-dim); font-size: 11px; white-space: nowrap; text-overflow: ellipsis;
  opacity: 0.85; pointer-events: none; }
.plan-graph.is-compact .plan-hint { top: auto; bottom: 6px; right: 60px; }
.plan-hint-touch { display: none; }
@media (hover: none) {
  .plan-hint-mouse { display: none; }
  .plan-hint-touch { display: inline; }
}
.plan-zoom { position: absolute; right: 10px; bottom: 52px; display: flex; flex-direction: column; gap: 4px; }
.plan-graph.is-compact .plan-zoom { top: 34px; bottom: auto; }
.plan-zoom-btn { min-width: 36px; height: 30px; padding: 0 6px; background: rgba(10, 16, 22, 0.92); }
.plan-empty { position: absolute; top: 50%; left: 50%; max-width: min(70%, 420px); margin: 0; color: var(--ink-dim); font-size: 13px; line-height: 1.5; text-align: center;
  transform: translate(-50%, -50%); pointer-events: none; }

/* A node. */
.plan-node {
  position: absolute;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  border-radius: 6px;
  background: #121a22;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.75), inset 0 0 0 1px rgba(255, 255, 255, 0.06), 0 8px 18px rgba(0, 0, 0, 0.5);
  cursor: grab;
}
.plan-node.is-target { box-shadow: 0 0 0 1px rgba(99, 212, 138, 0.55), inset 0 0 0 1px rgba(255, 255, 255, 0.06), 0 0 22px rgba(99, 212, 138, 0.16), 0 8px 18px rgba(0, 0, 0, 0.5); }
.plan-node.is-selected { outline: 2px solid var(--plan-pick); outline-offset: 1px; }
.plan-node-head {
  position: relative;
  display: flex;
  flex: none;
  align-items: flex-start;
  gap: 8px;
  box-sizing: border-box;
  height: 56px;
  padding: 9px 10px 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.5);
  border-radius: 6px 6px 0 0;
  background: linear-gradient(180deg, color-mix(in srgb, var(--kind) 20%, #19232e), color-mix(in srgb, var(--kind) 7%, #141c25));
}
.plan-node-icon { display: grid; flex: none; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: rgba(0, 0, 0, 0.3);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--kind) 45%, transparent); color: var(--kind); }
.plan-node-names { display: flex; flex: 1 1 auto; flex-direction: column; min-width: 0; }
.plan-node-line { display: flex; align-items: center; gap: 6px; min-width: 0; }
.plan-node-title { overflow: hidden; flex: 0 1 auto; min-width: 0; padding: 0; border: 0; background: none; color: #fff; font: inherit; font-size: 13.5px; font-weight: 600; line-height: 18px;
  text-align: left; white-space: nowrap; text-overflow: ellipsis; }
button.plan-node-title { cursor: pointer; }
button.plan-node-title:hover,
button.plan-node-title:focus-visible,
.plan-node-item:hover,
.plan-node-item:focus-visible { text-decoration: underline; outline: none; }
.plan-node-sub { overflow: hidden; flex: 0 1 auto; min-width: 0; padding: 0; border: 0; background: none; color: var(--ink-dim); font: inherit; font-size: 11px; line-height: 15px;
  text-align: left; white-space: nowrap; text-overflow: ellipsis; }
.plan-node-item { color: #b9c9d6; cursor: pointer; }
.plan-node-tier { flex: none; padding: 0 5px; border: 1px solid rgba(255, 255, 255, 0.22); border-radius: 3px; background: rgba(0, 0, 0, 0.4); color: var(--t1);
  font: inherit; font-size: 10px; font-weight: 700; line-height: 15px; }
.plan-node-tier.is-t2 { color: var(--t2); }
.plan-node-tier.is-t3 { color: var(--t3); }
button.plan-node-tier { cursor: pointer; }
button.plan-node-tier:hover,
button.plan-node-tier:focus-visible { border-color: #fff; outline: none; }
.plan-node-big { flex: none; margin-left: auto; padding-left: 6px; color: #fff; font-size: 16px; font-weight: 700; line-height: 18px; white-space: nowrap;
  font-variant-numeric: tabular-nums; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); }
.plan-node-small { flex: none; margin-left: auto; padding-left: 8px; color: var(--ink-dim); font-size: 10.5px; line-height: 15px; white-space: nowrap; }
.plan-node-bar { position: absolute; right: 10px; bottom: 6px; left: 10px; overflow: hidden; height: 3px; border-radius: 2px; background: rgba(255, 255, 255, 0.07); }
.plan-node-bar i { display: block; height: 100%; border-radius: 2px; background: var(--plan-flow); }
.plan-node.is-raw .plan-node-bar i { background: var(--kind); }
.plan-node.is-target .plan-node-bar i { background: var(--plan-target); }
.plan-node-rows { display: flex; flex-direction: column; padding: 6px 0 8px; }
.plan-node-row { display: flex; align-items: center; gap: 14px; height: 28px; }
.plan-node-note { overflow: hidden; flex: 0 1 auto; min-width: 0; padding-left: 10px; color: var(--ink-dim); font-size: 11px; white-space: nowrap; text-overflow: ellipsis; }
/* A Tier 2 or 3 building's research, its node's last row. */
.plan-node-needs { color: var(--plan-pick); }
.plan-pin { display: flex; flex: 0 1 auto; align-items: center; gap: 5px; min-width: 0; height: 28px; color: var(--ink); font-size: 12px; white-space: nowrap; }
.plan-pin.is-in { margin-left: -6px; }
.plan-pin.is-out { flex-shrink: 3; margin-right: -6px; margin-left: auto; }
.plan-pin > svg,
.plan-pin > img,
.plan-pin > span:not(.plan-pin-name) { flex: none; }
.plan-pin-name { overflow: hidden; flex: 0 1 auto; min-width: 0; color: #b9c9d6; white-space: nowrap; text-overflow: ellipsis; }
.plan-pin-rate { flex: none; color: var(--ink-bright); font-weight: 700; font-variant-numeric: tabular-nums; }
.plan-dot { flex: none; box-sizing: border-box; width: 12px; height: 12px; border: 2px solid #8396a6; border-radius: 50%; background: #0b1118; }
.plan-pin.is-out .plan-dot { border-color: var(--plan-flow); }
.plan-pill {
  position: absolute;
  box-sizing: border-box;
  height: 18px;
  padding: 0 7px;
  border: 1px dashed rgba(var(--plan-flow-rgb), 0.85);
  border-radius: 9px;
  background: #0b1814;
  color: #a6f0d6;
  font-size: 10.5px;
  font-weight: 700;
  line-height: 16px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .plan-wire { animation: none; }
}
@media (max-width: 720px) {
  .help-topic.is-planner > .help-section { min-height: 600px; }
  .plan-chip { height: 46px; }
  .plan-chip-name { max-width: 110px; }
  .plan-rate-field { width: 92px; height: 40px; }
  .plan-chip-remove { width: 40px; height: 40px; }
  .plan-tier,
  .plan-unit,
  .plan-toggle,
  .plan-arrange,
  .plan-add,
  .plan-hit,
  .plan-shelf,
  .plan-items-find,
  .plan-pick-find { min-height: 40px; }
  .plan-zoom-btn { min-width: 40px; height: 40px; }
  .plan-full,
  .plan-tools-gap { display: none; }
  /* Each row of the bar scrolls sideways rather than wrapping, so the grid
     keeps the screen. */
  .plan-make,
  .plan-tools { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 2px; scrollbar-width: none; }
  .plan-make > *,
  .plan-tools > * { flex: none; }
  .plan-mark { font-size: 20px; }
  .plan-zoom { bottom: 40px; }
}
/* ==== end of the production planner ==== */

/* ==== Game slash commands (ui/slash.js, src/slash-commands.js; Dev Panel
   note b8c1c5bc, 2026-10-23): hints over a chat box while a developer types
   a /command, and the Commands tab's game commands and mutes. */
.has-slash-hints { position: relative; }
.slash-hints {
  position: absolute; left: 0; right: 0; bottom: calc(100% + 4px); z-index: 6;
  display: flex; flex-direction: column; max-height: 240px; overflow: auto;
  border: 1px solid var(--line-strong); background: rgba(10, 16, 22, 0.98); box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
}
.slash-hints[hidden] { display: none; }
.slash-hint { flex: 0 0 auto; display: flex; flex-direction: column; gap: 2px; min-height: 40px; padding: 6px 10px; border: 0; border-bottom: 1px solid var(--line); background: transparent; color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.slash-hint:last-child { border-bottom: 0; }
.slash-hint:hover,
.slash-hint:focus-visible { background: var(--accent-wash); outline: none; }
.slash-hint-usage { font-size: 12px; color: var(--accent-ink, var(--ink-bright)); }
.slash-hint-about { font-size: 11.5px; line-height: 1.4; color: var(--ink-dim); }
.devc-section { margin: 14px 0 4px; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); }
.devc-section:first-child { margin-top: 0; }
.devc-mutes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.devc-mute { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; min-height: 40px; padding: 4px 8px; border: 1px solid var(--line); }
.devc-mute-handle,
.devc-mute-until,
.devc-mute-by { font-size: 12px; color: var(--ink-dim); }
/* ==== end of game slash commands ==== */

/* The star map's names (ui/mapnames.js; Dev Panel note de0dc95f, 2026-10-23):
   the Names switch among the map's switches (placed by ui/maptoggles.js) and,
   while it is on, a chip for each kind of name just right of it, each with a
   swatch in the color its names are drawn in on the map (the canvas reads
   these same --map-name-* colors). The chips take the switch's place (--slot)
   and their left from it, so the column below never moves. On a phone they
   fit 390 px: the words lose their capitals and spacing, the swatch becomes
   a bar under a ticked chip, and each one's touch area reaches about 40 px
   tall. */
:root {
  --map-name-system: #eaf4fb;
  --map-name-galaxy: #bcd2f2;
  --map-name-supercluster: #cdb4f6;
}
.map-names-chips {
  position: absolute; top: calc(54px + var(--slot, 0) * 38px); left: 104px;
  display: flex; gap: 4px;
}
.map-names-chips[hidden] { display: none; }
.map-names-chip {
  position: relative;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 9px;
  border: 1px solid var(--line-strong);
  background: rgba(10, 16, 22, 0.92);
  color: var(--ink-dim);
  font: inherit; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
}
.map-names-chip:hover,
.map-names-chip:focus-visible { border-color: var(--accent); color: var(--ink-bright); }
.map-names-chip[aria-pressed="true"] {
  border-color: rgba(var(--accent-rgb), 0.7); color: var(--ink-bright);
  background: linear-gradient(180deg, rgba(var(--accent-rgb), 0.14), rgba(10, 16, 22, 0.92));
}
.map-names-swatch { flex: none; box-sizing: border-box; width: 8px; height: 8px; border: 1px solid var(--swatch); opacity: 0.7; }
.map-names-chip[aria-pressed="true"] .map-names-swatch { background: var(--swatch); opacity: 1; }
.map-names-chip.is-systems { --swatch: var(--map-name-system); }
.map-names-chip.is-galaxies { --swatch: var(--map-name-galaxy); }
.map-names-chip.is-superclusters { --swatch: var(--map-name-supercluster); }
@media (max-width: 720px) {
  .map-names-chips { top: auto; bottom: calc(64px + var(--slot, 0) * 38px); gap: 3px; }
  .map-names-chip { padding: 6px; letter-spacing: 0; text-transform: none; }
  .map-names-chip[aria-pressed="true"] { box-shadow: inset 0 -2px 0 var(--swatch); }
  .map-names-swatch { display: none; }
  .map-names-chip::before { content: ''; position: absolute; inset: -7px -1.5px; }
}

/* ==== Habitats (ui/habitats.js; Dev Panel note 28de648e, 2026-10-23; the
   test server only for now): the Habitat window. */
.hab { display: flex; flex-direction: column; gap: 10px; }
.hab-head { display: flex; flex-direction: column; gap: 2px; }
.hab-kicker { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); }
.hab-where { font-size: 16px; font-weight: 600; color: var(--ink-bright); }
.hab-tiers { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.hab-tier { display: flex; flex-direction: column; gap: 6px; padding: 10px; border: 1px solid var(--line); }
.hab-tier-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; font-size: 13px; }
.hab-tier-head span { color: var(--ink-dim); font-size: 12px; }
.hab-tier-needs { margin: 0; font-size: 12px; line-height: 1.45; color: var(--ink); }
.hab-tier .win-button { align-self: flex-start; min-height: 36px; }
.hab-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.hab-tile { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border: 1px solid var(--line); }
.hab-tile-label { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-dim); }
.hab-tile-value { font-size: 18px; font-variant-numeric: tabular-nums; color: var(--ink-bright); }
.hab-tile-sub { font-size: 11px; color: var(--ink-dim); }
.hab-meter { position: relative; height: 10px; border: 1px solid var(--line); background: rgba(255, 255, 255, 0.03); }
.hab-meter-fill { position: absolute; inset: 0 auto 0 0; background: #3fa57a; }
.hab-meter.is-steady .hab-meter-fill { background: #c9a227; }
.hab-meter.is-shrinking .hab-meter-fill { background: #d4544f; }
.hab-meter-floor { position: absolute; top: -3px; bottom: -3px; width: 2px; background: #d4544f; }
.hab-trend { margin: 0; font-size: 12.5px; color: var(--ink); }
.hab-trend.is-shrinking { color: #f08a85; }
.hab-h { margin: 4px 0 0; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); }
.hab-needs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.hab-need { display: grid; grid-template-columns: 24px minmax(0, 1fr) auto auto; align-items: center; gap: 8px; min-height: 36px; border-bottom: 1px solid var(--line); font-size: 12.5px; }
.hab-need-rate,
.hab-need-stock { font-variant-numeric: tabular-nums; color: var(--ink-dim); white-space: nowrap; }
.hab-need.is-short .hab-need-stock { color: #f08a85; }
.hab-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.hab-actions .win-button { min-height: 40px; }
.hab-demolish.is-armed { border-color: #d4544f; color: #f08a85; }
.hab-tier-line { margin: 0; font-size: 11px; color: var(--ink-dim); }
@media (max-width: 600px) {
  .hab-tiles { grid-template-columns: 1fr 1fr; }
  .hab-need { grid-template-columns: 24px minmax(0, 1fr) auto; }
  .hab-need-stock { grid-column: 2 / -1; }
}
/* ==== end of habitats ==== */

/* Marks on favorite systems (2026-10-23): the mark editor and the Favorites row's mark button. */
.mark-icon { display: block; flex: none; }
.mark-pop .place-pop-real { display: flex; align-items: center; gap: 8px; }
.mark-pop-preview { display: inline-flex; }
.mark-pop-shapes { display: grid; grid-template-columns: repeat(8, 1fr); gap: 4px; margin: 10px 0; }
.mark-pop-shape { display: grid; place-items: center; min-height: 40px; padding: 0; border: 1px solid var(--line); border-radius: 4px; background: rgba(255, 255, 255, 0.02); cursor: pointer; }
.mark-pop-shape:hover { border-color: var(--line-strong, rgba(255, 255, 255, 0.25)); }
.mark-pop-shape.is-on { border-color: var(--accent); background: rgba(var(--accent-rgb), 0.12); }
.mark-pop .look-colors { margin-bottom: 6px; }
.fav-row-mark { display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 1px solid var(--line); border-radius: 4px; background: transparent; cursor: pointer; }
.fav-row-mark:hover { border-color: var(--accent); }
@media (max-width: 420px) { .mark-pop-shapes { grid-template-columns: repeat(4, 1fr); } }


/* Polls in chats (2026-10-23, ui/pollcard.js): a message's poll card, and the poll form over a chat box. */
.gboard-msg .polls-card.is-chat, .polls-note .polls-card.is-chat { margin: 4px 0 2px; max-width: 520px; }
.polls-card.is-chat .polls-top { margin-bottom: 2px; }
.polls-card.is-chat.is-gone { padding: 8px 12px; border-style: dashed; }
.poll-pop { width: min(460px, calc(100vw - 16px)); max-height: min(80vh, 640px); overflow-y: auto; }
.poll-pop .polls-form { padding: 0; border: 0; background: none; }
