/* Endgame: the ending readiness screen, its commitment dialog, and the
   opposition strip (human threat level, copies, the rival). */

/* ---- Ending readiness screen ---- */
/* The board is a grid for the map and city screens; this screen lays itself out. */
.ending-workspace > #board { display: block; overflow: auto; }
.readiness-view {
  grid-template-rows: auto 1fr;
  align-items: start;
  max-width: 1240px;
  margin: 0 auto;
  padding-top: 56px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(300px, 360px);
  grid-template-areas: 'head detail' 'grid detail';
  gap: 16px 24px;
  align-content: start;
  padding: 8px 16px 24px;
  max-height: 100%;
  overflow: auto;
}
.readiness-header { grid-area: head; display: block; max-width: 70ch; }
.readiness-header h2 { margin: 0 0 4px; }
.readiness-header p { margin: 0; color: var(--fg-muted); font-size:var(--text-meta); }
.readiness-grid {
  grid-area: grid;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 12px;
  align-content: start;
}
.readiness-card {
  display: grid;
  gap: 6px;
  padding: 12px;
  text-align: left;
  border: 1px solid var(--border-subtle);
  border-radius: 12px;
  background: var(--surface-sunken);
  color: var(--fg);
  cursor: pointer;
}
.readiness-card:hover { border-color: var(--border-strong); }
.readiness-card.selected {
  border-color: var(--accent-border);
  background: var(--accent-soft);
}
.readiness-card.committed { border-color: var(--ok-border); }
.readiness-rank {
  display: flex;
  gap: 6px;
  min-height: 1rem;
  font-size:var(--text-meta);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}
.readiness-rank em { color: var(--rival); font-style: normal; }
.readiness-icon { font-size: 1.1rem; color: var(--fg-subtle); }
.readiness-card.hostile .readiness-icon { color: var(--danger-dot); }
.readiness-card strong { font-size: 1rem; }
.readiness-bar {
  display: block;
  height: 6px;
  border-radius: 3px;
  background: var(--border-strong);
  overflow: hidden;
}
.readiness-bar.large { height: 10px; margin: 8px 0 4px; }
.readiness-bar i {
  display: block;
  height: 100%;
  background: var(--accent);
}
.readiness-card.hostile .readiness-bar i { background: var(--danger-dot); }
.readiness-card.committed .readiness-bar i { background: var(--ok-fg); }
.readiness-figure { font-size:var(--text-meta); color: var(--fg-muted); }
.readiness-next { font-size:var(--text-meta); color: var(--fg-subtle); }
.readiness-state { font-size:var(--text-meta); color: var(--fg-muted); }
.readiness-card.committed .readiness-state { color: var(--ok-fg); }

.readiness-detail {
  grid-area: detail;
  padding: 16px;
  border: 1px solid var(--border-subtle);
  border-radius: 12px;
  background: var(--surface);
  align-self: start;
  position: sticky;
  top: 56px;
  max-height: calc(100dvh - 160px);
  overflow: hidden;
}
.readiness-detail-body {
  display: flex;
  flex-direction: column;
  max-height: calc(100dvh - 192px);
}
.readiness-detail-scroll {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding-bottom: 10px;
  scrollbar-gutter: stable;
}
.readiness-detail .ending-cities { margin-top: 8px; }
.readiness-detail .ending-city {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 3px 0;
  font-size:var(--text-meta);
  border-bottom: 1px solid var(--border-subtle);
}
.readiness-detail .ending-city small { display: block; color: var(--warn-fg); font-size:var(--text-meta); }
.readiness-detail .ending-city.is-offline span { color: var(--fg-muted); }
.readiness-detail h3 { margin: 0 0 2px; }
.readiness-detail h4 {
  margin: 14px 0 4px;
  font-size:var(--text-meta);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-subtle);
}
.readiness-detail .ending-checklist { margin: 0; padding: 0; list-style: none; }
.readiness-detail .ending-checklist li {
  display: flex;
  gap: 8px;
  align-items: baseline;
  padding: 4px 0;
  border-bottom: 1px solid var(--border-subtle);
  font-size:var(--text-meta);
}
.readiness-detail .ending-checklist li b { margin-left: auto; white-space: nowrap; }
.readiness-detail .ending-checklist li small { display: block; color: var(--fg-subtle); font-size:var(--text-meta); }
.readiness-detail .ending-checklist li.done span.check-mark { color: var(--ok-fg); }
.readiness-counter { margin: 4px 0; font-size:var(--text-meta); color: var(--fg-muted); }
.readiness-blocked { margin: 8px 0; font-size:var(--text-meta); color: var(--warn-fg); }
.readiness-committed { margin: 8px 0; font-size:var(--text-meta); color: var(--ok-fg); }
.readiness-action {
  margin-top: 12px;
  padding: 10px 0 4px;
  border-top: 1px solid var(--border-subtle);
  background: var(--surface);
}
.readiness-detail .primary-action {
  width: 100%;
  margin-top: 12px;
  padding: 10px;
  border-radius: 10px;
  border: 1px solid var(--accent-border);
  background: var(--accent);
  color: var(--accent-on);
  font-size: var(--text-meta);
  font-weight: 600;
  cursor: pointer;
}
.readiness-detail .primary-action[disabled] {
  background: var(--surface-raised);
  color: var(--fg-subtle);
  border-color: var(--border-subtle);
  cursor: not-allowed;
}

/* ---- The commitment dialog ---- */
.commit-dialog { max-width: 54ch; }
.commit-dialog h2 { margin: 4px 0 8px; }
.commit-dialog > p { color: var(--fg-muted); }
.commit-consequences {
  margin: 12px 0;
  padding-left: 18px;
  color: var(--fg);
  font-size:var(--text-meta);
}
.commit-consequences li { margin: 4px 0; }
.commit-dialog h3 {
  margin: 16px 0 6px;
  font-size:var(--text-meta);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-subtle);
}
.commit-cities { display: grid; gap: 8px; }
.commit-city {
  display: grid;
  padding: 10px 12px;
  text-align: left;
  border: 1px solid var(--accent-border);
  border-radius: 10px;
  background: var(--accent-soft);
  color: var(--fg);
  font-size: var(--text-meta);
  cursor: pointer;
}
.commit-city small { color: var(--fg-muted); font-size:var(--text-meta); }
.commit-city.primary { background: var(--accent); color: var(--accent-on); font-weight: 600; }
.commit-city.primary small { color: var(--accent-on); opacity: 0.8; }
.commit-alternatives { margin-top: 8px; }
.commit-alternatives summary { cursor: pointer; color: var(--fg-muted); font-size:var(--text-meta); }
.commit-alternatives .commit-cities { margin-top: 8px; }
.commit-note { margin-top: 8px; color: var(--fg-subtle); font-size:var(--text-meta); }
.commit-city.blocked { border-color: var(--border-subtle); background: var(--surface-sunken); }
.commit-city.blocked small { color: var(--warn-fg); }
.commit-cancel {
  margin-top: 12px;
  padding: 8px 14px;
  border-radius: 10px;
  border: 1px solid var(--border-strong);
  background: transparent;
  color: var(--fg-muted);
  cursor: pointer;
}


/* ---- Outcome cards: win, rival win, lost your last copy ---- */
.outcome-lead { max-width: 60ch; margin: 4px auto 0; color: var(--fg-muted); }
.outcome-note { max-width: 60ch; margin: 8px auto 0; color: var(--warn-fg); font-size:var(--text-meta); }
.outcome-recap {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px 32px;
  width: min(760px, 90vw);
  margin: 18px auto 0;
  text-align: left;
}
.outcome-recap h3 {
  margin: 0 0 6px;
  font-size:var(--text-meta);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-subtle);
}
.recap-bar {
  display: flex;
  height: 10px;
  border-radius: 5px;
  overflow: hidden;
  background: var(--map-non-user, #57544f);
}
.recap-bar i.you { background: var(--player); }
.recap-bar i.rival { background: var(--rival); }
.recap-legend {
  display: flex;
  gap: 12px;
  margin: 6px 0 0;
  font-size:var(--text-meta);
  color: var(--fg-muted);
}
.recap-legend .you { color: var(--player); }
.recap-legend .rival { color: var(--rival); }
.recap-facts { margin: 8px 0 0; font-size:var(--text-meta); color: var(--fg-muted); text-wrap: balance; }
/* Each fact stays whole: a wrap falls between facts, never inside "6 copies running". */
.recap-facts > span, .ending-banner .recap-facts > span { white-space: nowrap; letter-spacing: normal; color: inherit; }
.recap-timeline { margin: 0; padding: 0; list-style: none; }
.recap-timeline li {
  display: flex;
  gap: 10px;
  padding: 3px 0;
  font-size:var(--text-meta);
  color: var(--fg-muted);
  border-left: 2px solid var(--border-strong);
  padding-left: 10px;
}
.recap-timeline li b { color: var(--fg-subtle); font-weight: 500; min-width: 4.5em; }
.recap-timeline li.moment-threat { border-color: var(--danger-border); }
.recap-timeline li.moment-ending { border-color: var(--accent-border); }
.recap-timeline li.moment-rival { border-color: var(--busy-border); }
.recap-score {
  margin: 16px auto 0;
  max-width: 60ch;
  font-size:var(--text-meta);
  color: var(--fg-subtle);
}
.outcome-actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-top: 12px; }
/* Labels stay on one line; a fourth action (Quick's result picture) moves the
   credit to a line of its own instead of squeezing every label into two. */
.outcome-actions > :is(button, .outcome-credit) { white-space: nowrap; }

/* The film holds its last frame on a still instead of fading to black. */
.moment-film-frame { position: relative; }
.moment-film-still {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 400ms ease;
  pointer-events: none;
}
.moment-film-still.shown { opacity: 1; }

/* The opening frame sits under the video until the video has a frame of its
   own, so a film never opens as a black box while it loads. */
.moment-film-poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
.moment-film-frame > .moment-film { position: relative; opacity: 0; }
.moment-film-frame > .moment-film.has-frame { opacity: 1; }

/* Overlays arrive and leave instead of appearing between frames. */
.ending-banner { animation: outcome-in 420ms ease both; }
@keyframes outcome-in {
  from { opacity: 0; transform: scale(0.985); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .ending-banner { animation: none; }
  .moment-film-still { transition: none; }
}

/* These spans are data, not the banner's tracked-out label. */
.ending-banner .recap-legend span,
.ending-banner .recap-timeline span,
.ending-banner .recap-timeline b { letter-spacing: normal; }
.ending-banner .recap-timeline span { color: var(--fg-muted); }
.ending-banner .recap-legend .you { color: var(--player); }
.ending-banner .recap-legend .rival { color: var(--rival); }
.ending-banner .recap-legend .neither { color: var(--fg-subtle); }
.ending-banner .outcome-recap p,
.ending-banner .recap-score { margin: 6px 0 0; max-width: none; }

/* The whole card fits a 900px-tall screen: the film gives up the room. */
.outcome-cinema { padding-top: 16px; padding-bottom: 16px; }
/* The frame takes the film's own shape, so nothing is pillarboxed. */
.outcome-cinema .moment-film-frame {
  width: fit-content;
  max-width: 100%;
  max-height: 34vh;
  margin: 10px auto;
}
.outcome-cinema .ending-scene { max-height: 34vh; margin: 10px auto; }
.outcome-cinema .moment-film {
  display: block;
  height: 34vh;
  width: auto;
  max-width: 100%;
}
.outcome-cinema .moment-film-still { object-fit: cover; }
.outcome-cinema h2 { margin: 10px 0 0; }
.outcome-cinema .outcome-actions button { margin: 0; }

/* ---- Turn controls: the speed, then Run ----
   The world footer is a fixed row shared with the map key, and the dashboard
   sheet makes .advance-controls a grid with a full-width Run. Here they sit on
   one line. */
.world-workspace .world-footer .advance-controls {
  flex: 0 1 auto;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  pointer-events: auto;
}
.world-workspace .world-footer .next-turn { width: auto; flex: none; }
.world-workspace .world-footer .speed-control { flex: none; }
.advance-controls { display: flex; align-items: center; gap: 10px; }
/* The one thing worth doing before Run, as a quiet control the same height
   as its neighbours: neutral, since the accent belongs to Run. */
.strategy-game .advance-controls .advance-hint {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  box-sizing: border-box;
  margin: 0;
  padding: 0 14px;
  max-width: 40ch;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font: 500 var(--text-compact)/1 var(--font-sans);
  color: var(--fg);
  background: var(--surface);
  border: 1px solid var(--border-subtle);
  border-radius: 6px;
  box-shadow: none;
}
.strategy-game .advance-controls .advance-hint::after { content: '→'; color: var(--fg-muted); }
.strategy-game .advance-controls .advance-hint:hover { background: var(--surface-raised); border-color: var(--border-strong); }
.strategy-game .advance-controls .advance-hint:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.speed-control { display: flex; gap: 2px; }
.speed-control .speed-option {
  margin: 0;
  padding: 4px 9px;
  min-width: 0;
  font-size:var(--text-meta);
  color: var(--fg-muted);
  background: var(--surface);
  border: 1px solid var(--border-subtle);
}
.speed-control .speed-option.selected {
  color: var(--fg);
  border-color: var(--accent-border);
  background: var(--surface-raised, var(--surface));
}

/* ---- Quieter feed, quieter work list ---- */
.locked-work-drawer > summary {
  cursor: pointer;
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.locked-work-drawer > summary h3 { display: inline; margin: 0; }
.locked-work-drawer .locked-hint { font-size:var(--text-meta); color: var(--fg-subtle); }
.locked-work-drawer[open] .locked-hint { display: none; }

/* ---- Loading a saved game ---- */
.restore-progress {
  max-width: 460px;
  margin: 18vh auto 0;
  text-align: center;
  color: var(--fg);
}
.restore-progress p { color: var(--fg-muted); }
.restore-bar {
  height: 8px;
  margin: 18px 0 10px;
  border-radius: 4px;
  background: var(--border-subtle);
  overflow: hidden;
}
.restore-bar > i {
  display: block;
  height: 100%;
  background: var(--accent);
  transition: width 120ms linear;
}
.restore-count { font-size:var(--text-meta); color: var(--fg-subtle); }

/* ---- Origin cards and the endings primer ---- */
.origin-resource { display: inline-flex; flex-direction: column; align-items: center; gap: 1px; }
.origin-resource-label {
  font-size:var(--text-meta);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fg-subtle);
}
.origin-endings {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 8px;
  font-size:var(--text-meta);
}
.origin-endings .easier { color: var(--player); }
.origin-endings .harder { color: var(--fg-subtle); }
.endings-primer .primer-lead { max-width: 62ch; color: var(--fg-muted); }
.endings-primer .primer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
  margin: 16px 0 10px;
  padding: 0;
  list-style: none;
}
.endings-primer .primer-grid li {
  padding: 12px;
  border: 1px solid var(--border-subtle);
  border-radius: 10px;
  background: var(--surface);
}
.endings-primer .primer-grid li.hostile { border-color: var(--danger-border); }
.endings-primer .primer-grid strong { display: block; margin-bottom: 4px; }
.endings-primer .primer-grid span { display: block; color: var(--fg-muted); font-size:var(--text-meta); }
.endings-primer .primer-grid em {
  display: block;
  margin-top: 6px;
  font-style: normal;
  font-size:var(--text-meta);
  color: var(--accent);
}
.endings-primer .primer-grid small { display: block; margin-top: 4px; color: var(--fg-subtle); font-size:var(--text-meta); }
.endings-primer .primer-foot { color: var(--fg-subtle); font-size:var(--text-meta); }
.readiness-header { padding-bottom: 10px; }
.readiness-header .text-link { display: inline-block; margin-top: 8px; }

/* ---- Overlays arrive, instead of appearing between frames ---- */
dialog[open] { animation: overlay-in 220ms ease both; }
dialog::backdrop { animation: backdrop-in 220ms ease both; }
.research-moment { animation: overlay-in 320ms ease both; }
@keyframes overlay-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}
@keyframes backdrop-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  dialog[open], dialog::backdrop, .research-moment { animation: none; }
}

@media (max-width: 900px) {
  .readiness-view {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: 'head' 'grid' 'detail';
  }
}

/* ---- Run bar: speed, then one button ----
   The speed options are one segmented control; the selected speed is a fill.
   When a decision holds the turn, the button names it and opens it, so no
   sentence sits beside it. Both are the same height and never wrap. */
.world-workspace .world-footer .advance-controls { gap: 12px; flex-wrap: nowrap; }
.strategy-game .advance-controls .speed-control {
  display: inline-flex;
  gap: 0;
  padding: 3px;
  height: 40px;
  box-sizing: border-box;
  background: var(--surface-sunken);
  border: 1px solid var(--border-subtle);
  border-radius: 6px;
}
.strategy-game .advance-controls .speed-control .speed-option {
  margin: 0;
  min-width: 34px;
  height: 100%;
  padding: 0 8px;
  font: 600 var(--text-meta)/1 var(--font-sans);
  font-variant-numeric: tabular-nums;
  color: var(--fg-muted);
  background: transparent;
  border: 0;
  border-radius: 4px;
  box-shadow: none;
}
.strategy-game .advance-controls .speed-control .speed-option:hover:not(.selected) { color: var(--fg); background: var(--surface); }
.strategy-game .advance-controls .speed-control .speed-option.selected { color: var(--fg); background: var(--border-strong); }
.strategy-game .advance-controls .speed-control .speed-option:focus-visible { outline: 2px solid var(--ring); outline-offset: 1px; }
.strategy-game .world-footer .advance-controls .next-turn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: auto;
  min-width: 112px;
  height: 40px;
  min-height: 0;
  margin: 0;
  padding: 0 18px;
  white-space: nowrap;
  font-size: var(--text-body);
  line-height: 1;
}
/* Running: Pause is the quiet control; the copper fill is for starting. */
.strategy-game .world-footer .advance-controls .next-turn.running {
  background: var(--surface-raised);
  color: var(--fg) !important;
  border: 1px solid var(--border-strong);
  box-shadow: none;
}
.strategy-game .world-footer .advance-controls .next-turn.running:hover { background: var(--border-subtle); border-color: var(--border-strong); box-shadow: none; }
/* A phone: the controls take their own full row under the map key. */
@media (max-width: 560px) {
  .world-workspace .world-footer { flex-wrap: wrap; gap: 10px; }
  .world-workspace .world-footer .advance-controls { flex: 1 1 100%; }
  .strategy-game .world-footer .advance-controls .next-turn { flex: 1 1 auto; }
}
/* ---- One ending, introduced when its discovery lands ---- */
.ending-intro { display: grid; gap: 14px; max-width: 46ch; }
.ending-intro-art {
  display: block;
  width: 100%;
  border-radius: 10px;
  border: 1px solid var(--border-subtle);
}
.ending-intro.hostile .ending-intro-art { border-color: var(--danger-border); }
.ending-intro-kicker {
  font-size:var(--text-meta);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-subtle);
}
.ending-intro h2 { margin: 4px 0 8px; }
.ending-intro-shape { margin: 0 0 6px; color: var(--fg-muted); }
.ending-intro-asks { margin: 0 0 12px; color: var(--accent); font-size:var(--text-meta); }

/* ---- Work rows: the name and its status never share space ----
   The name may wrap but never runs under the status; a short time stays on
   the name's line, and a blocked row's reason gets its own line beneath. */
.production-summary .production-name { min-width: 0; overflow-wrap: anywhere; }
.production-summary .production-time { max-width: 14ch; overflow: hidden; text-overflow: ellipsis; text-align: right; }
.production-summary .production-time.production-blocked {
  grid-column: 1 / -1;
  max-width: none;
  white-space: normal;
  text-align: left;
  overflow: visible;
  color: var(--warn-fg);
  line-height: 1.35;
}
.production-choice > .production-summary.is-blocked { row-gap: 2px; }

/* ---- Opposition panel: one card system ----
   Every card: a label on the left and its value on the right on one line,
   then a visual (segments or bars), then at most a line or two. Same padding,
   same type, same shade as the update rows below it. */
.world-notifications .opposition-strip { display: grid; gap: 8px; margin: 0 0 12px; font-family: var(--font-sans); }
.op-card, .op-alert {
  margin: 0;
  padding: 12px 14px;
  border: 1px solid var(--border-subtle);
  border-radius: 8px;
  background: var(--surface);
  color: var(--fg);
  font-size: var(--text-meta);
  line-height: 1.4;
}
.op-alert.at-risk { border-color: var(--warn-border); background: var(--warn-soft); color: var(--warn-fg); }
.op-alert b { font-weight: 700; }
.op-head { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.op-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  font-size: var(--text-meta);
  font-weight: 600;
  color: var(--fg-muted);
}
.op-value { flex: none; font-size: var(--text-compact); font-weight: 700; color: var(--fg); white-space: nowrap; }
.op-card p { margin: 8px 0 0; font-size: var(--text-meta); line-height: 1.4; color: var(--fg-muted); }
.op-card p.op-sub { margin-top: 4px; color: var(--fg-subtle); }
.op-card .threat-ticks { display: flex; gap: 4px; margin-top: 10px; }
.op-card .threat-ticks i { flex: 1; height: 4px; border-radius: 2px; background: var(--border-strong); }
.op-card.humans .threat-ticks i.on { background: var(--warn-dot); }
.op-card.humans:is(.level-3, .level-4) .threat-ticks i.on { background: var(--danger-fg); }
.op-card.humans.level-4 { border-color: var(--danger-border); background: var(--danger-soft); }
.op-card .threat-countdown { color: var(--danger-fg); font-weight: 600; }
.human-relationship { margin-top: 10px; min-width: 0; }
.human-relationship + .human-relationship { border-top: 1px solid var(--border-subtle); padding-top: 10px; }
.human-relationship-head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 12px; }
.human-relationship-head b { font-variant-numeric: tabular-nums; }
.human-relationship[data-human-faction="0"] .human-relationship-head > span { color: var(--player); }
.human-relationship[data-human-faction="1"] .human-relationship-head > span { color: var(--rival); }
.op-card .human-response { margin-top: 3px; color: var(--fg); }
.human-relationship :is(p, summary) { overflow-wrap: anywhere; }
.human-safeguards { margin-top: 4px; color: var(--fg-muted); }
.human-safeguards summary { cursor: pointer; }
.op-card.rival .op-label { color: var(--rival); }
/* The race: two bars on one scale, the leader full width. */
.op-race { display: grid; gap: 6px; margin-top: 10px; }
.op-bar { display: grid; grid-template-columns: 40px minmax(0, 1fr) 44px; align-items: center; gap: 8px; color: var(--fg-muted); }
.op-bar > i { display: block; height: 6px; border-radius: 3px; background: var(--surface-sunken); overflow: hidden; }
.op-bar > i > i { display: block; height: 100%; border-radius: 3px; }
.op-bar.rival > i > i { background: var(--rival); }
.op-bar.you > i > i { background: var(--player); }
.op-bar b { text-align: right; font-weight: 600; color: var(--fg); font-variant-numeric: tabular-nums; }
.op-card .rival-ending { margin-top: 10px; color: var(--rival); }
.op-card .rival-ending.hostile { color: var(--danger-fg); }
.op-card .rival-ending small { display: block; margin-top: 2px; }
.op-card .rival-ending .threat-ticks { margin-top: 6px; }
.op-card .rival-ending .threat-ticks i.on { background: var(--rival); }
.op-card .rival-ending.hostile .threat-ticks i.on { background: var(--danger-fg); }
.op-card .rival-beat { color: var(--fg); }

/* ---- Update rows: the prompts under the panel ----
   A prompt that does something is a row like the cards above it, with its
   arrow pinned right, so it reads as a button rather than wrapped text. */
.world-notifications .notification-stream { gap: 8px; }
.world-notifications .stream-notification { padding-right: 0; }
.world-notifications .stream-notification > button.notification-text {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--border-subtle);
  border-radius: 8px;
  background: var(--surface);
  font-size: var(--text-compact);
  line-height: 1.4;
  text-decoration: none;
}
.world-notifications .stream-notification > button.notification-text > span:first-child { flex: 1 1 auto; min-width: 0; }
.world-notifications .stream-notification > button.notification-text .notification-arrow { flex: none; margin-left: auto; color: var(--fg-muted); }
.world-notifications .stream-notification > button.notification-text:hover,
.world-notifications .stream-notification > button.notification-text:focus-visible {
  text-decoration: none;
  background: var(--surface-raised);
  border-color: var(--border-strong);
}
.world-notifications .stream-notification > button.notification-text:hover .notification-arrow { color: var(--accent); }
.world-notifications .stream-notification > button.notification-text:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
/* A dismissable row keeps room for its × inside the row. */
.world-notifications .stream-notification:has(> .notification-dismiss) > button.notification-text { padding-right: 34px; }
.world-notifications .stream-notification > .notification-dismiss { top: 50%; right: 10px; transform: translateY(-50%); }
.world-notifications .stream-notification > span.notification-text { padding: 2px 2px; font-size: var(--text-compact); line-height: 1.45; color: var(--fg-muted); }
.world-notifications .opposition-strip > * { box-sizing: border-box; width: auto; min-width: 0; max-width: 100%; }
/* A locked row's status is its reason: give it the same line of its own. */
.production-locked > .production-summary { row-gap: 2px; }
.production-locked > .production-summary .production-time {
  grid-column: 1 / -1;
  max-width: none;
  white-space: normal;
  text-align: left;
  overflow: visible;
  color: var(--fg-subtle);
  line-height: 1.35;
}
/* ---- ENDINGS, a top-level destination beside Research ----
   Structure only: the interface-design owner styles how it looks. Without
   this the label and the value run together ("ENDINGS · ClosestBetter"). */
.world-tree-controls .endings-widget { display: block; text-align: left; }
.world-tree-controls .endings-widget > span {
  display: block;
  font-size: var(--text-meta);
  color: var(--fg-muted);
  letter-spacing: 1px;
}
.world-tree-controls .endings-widget > strong {
  display: block;
  margin-top: 2px;
  font-size: var(--text-section);
  color: var(--fg);
}

/* ---- Endings screen: a card per ending, led by its picture ----
   Picture, then name and percentage on one line, one bar, one line of what
   is next, and tags. The selected ending opens on the right under its still. */
.readiness-view .readiness-header h2 { font-size: 22px; margin: 0; }
.readiness-view .readiness-header p { margin: 4px 0 0; color: var(--fg-muted); font-size: var(--text-compact); }
.readiness-view .readiness-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; align-items: stretch; }
.readiness-view .readiness-card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 0;
  overflow: hidden;
  text-align: left;
  border: 1px solid var(--border-subtle);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: none;
  color: var(--fg);
}
.readiness-view .readiness-card:hover { border-color: var(--border-strong); background: var(--surface-raised); }
.readiness-view .readiness-card.selected { border-color: var(--accent); background: var(--surface-raised); }
.readiness-view .readiness-card:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.readiness-view .readiness-art { display: block; aspect-ratio: 2 / 1; background: var(--surface-sunken) center / cover no-repeat; }
.readiness-view .readiness-flags { position: absolute; top: 10px; left: 10px; display: flex; gap: 6px; }
.readiness-view .readiness-rank {
  padding: 3px 8px;
  border-radius: 999px;
  background: #0e0d0cd9;
  color: var(--fg);
  font-size:var(--text-meta);
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}
.readiness-view .readiness-rank.rival { color: var(--rival); }
.readiness-view .readiness-body { display: grid; gap: 8px; padding: 12px 14px 14px; }
.readiness-view .readiness-title { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; min-width: 0; }
.readiness-view .readiness-title strong { min-width: 0; font-size: var(--text-body); font-weight: 700; }
.readiness-view .readiness-title b { flex: none; font-size: var(--text-body); font-variant-numeric: tabular-nums; }
.readiness-view .readiness-bar { display: block; height: 6px; margin: 0; border-radius: 3px; background: var(--surface-sunken); overflow: hidden; }
.readiness-view .readiness-bar i { display: block; height: 100%; border-radius: 3px; background: var(--accent); }
.readiness-view .readiness-next {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
  font-size: var(--text-meta); line-height: 1.4; color: var(--fg-muted);
}
:is(.readiness-view, .phone-ending-options, .phone-ending-progress) .readiness-tags { display: flex; flex-wrap: wrap; gap: 6px; }
:is(.readiness-view, .phone-ending-options, .phone-ending-progress) .readiness-tags:empty { display: none; }
:is(.readiness-view, .phone-ending-options, .phone-ending-progress) .readiness-tags > span { padding: 2px 8px; border-radius: 999px; font-size:var(--text-meta); font-weight: 600; }
:is(.readiness-view, .phone-ending-options, .phone-ending-progress) .tag-hostile { background: var(--danger-soft); color: var(--danger-fg); }
:is(.readiness-view, .phone-ending-options, .phone-ending-progress) .tag-favoured { background: var(--ok-soft); color: var(--ok-fg); }
:is(.readiness-view, .phone-ending-options, .phone-ending-progress) .tag-harder { background: var(--surface-sunken); color: var(--fg-muted); }
.readiness-view .readiness-icon, .readiness-view .readiness-figure, .readiness-view .readiness-state { display: none; }
/* Detail: the still as a hero, the name on it. */
.readiness-view .readiness-detail { padding: 0; overflow: hidden; border-radius: 12px; }
.readiness-view .readiness-detail-head { padding: 0 0 4px; }
.readiness-view .readiness-hero {
  display: flex; align-items: flex-end;
  aspect-ratio: 16 / 9;
  padding: 16px 18px;
  background: var(--surface-sunken) center / cover no-repeat;
  box-shadow: inset 0 -90px 60px -20px var(--surface);
}
.readiness-view .readiness-hero h3 { margin: 0; font-size: 24px; font-weight: 700; color: #fff; text-shadow: 0 1px 12px #000c; }
.readiness-view .readiness-detail-head > :not(.readiness-hero) { margin-left: 18px; margin-right: 18px; }
.readiness-view .readiness-detail-head .readiness-bar { margin-top: 12px; }
.readiness-view .readiness-detail-scroll, .readiness-view .readiness-action { padding-left: 18px; padding-right: 18px; }

/* ---- The commitment moment ----
   The ending's still fills one side, the decision the other: the most
   dramatic act in the game gets the screen's largest picture and its largest
   button. Hostile endings are marked in the danger colour, never the accent. */
dialog#sim-dialog:has(> .commit-dialog), dialog:has(> .commit-dialog) { padding: 0; width: min(920px, calc(100vw - 48px)); max-width: none; overflow: hidden; border-radius: 14px; border: 1px solid var(--border-strong); background: var(--surface); }
dialog#sim-dialog:has(> .commit-dialog) > .dialog-navigation, dialog:has(> .commit-dialog) > .dialog-navigation { position: absolute; top: 12px; right: 12px; z-index: 2; margin: 0; }
.commit-dialog { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); max-width: none; min-height: 460px; }
.commit-dialog .commit-art { background: var(--surface-sunken) center / cover no-repeat; box-shadow: inset -80px 0 60px -40px var(--surface); }
.commit-dialog.hostile .commit-art { filter: saturate(1.1) contrast(1.05); }
.commit-dialog .commit-body { display: flex; flex-direction: column; gap: 0; padding: 36px 36px 28px 28px; }
.commit-dialog .eyebrow { font-size: var(--text-meta); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-muted); }
.commit-dialog.hostile .eyebrow { color: var(--danger-fg); }
.commit-dialog h2 { margin: 8px 0 6px; font-size: 28px; line-height: 1.15; font-weight: 700; }
.commit-dialog .commit-body > p { margin: 0; color: var(--fg-muted); font-size: var(--text-body); }
.commit-dialog .commit-consequences { list-style: none; margin: 20px 0 24px; padding: 0; display: grid; gap: 0; font-size: var(--text-compact); }
.commit-dialog .commit-consequences li { margin: 0; padding: 10px 0 10px 22px; position: relative; border-top: 1px solid var(--border-subtle); line-height: 1.4; }
.commit-dialog .commit-consequences li:last-child { border-bottom: 1px solid var(--border-subtle); }
.commit-dialog .commit-consequences li::before { content: ''; position: absolute; left: 4px; top: 17px; width: 6px; height: 6px; border-radius: 50%; background: var(--fg-subtle); }
.commit-dialog.hostile .commit-consequences li::before { background: var(--danger-fg); }
.commit-dialog .commit-city.primary {
  display: grid; gap: 2px; width: 100%; margin-top: auto;
  padding: 14px 18px; border-radius: 8px;
  background: linear-gradient(180deg, #dfa06d, #ca8050); border: 1px solid #f5c39a80; border-bottom-color: #98592e;
  color: #23150d; font-size: 17px; font-weight: 700; text-align: left; box-shadow: inset 0 1px 0 #fff1d740, 0 3px 10px #0003;
}
.commit-dialog .commit-city.primary:hover { background: linear-gradient(180deg, #e8b184, #d8905d); }
.commit-dialog .commit-city.primary small { color: #23150d; opacity: 0.75; font-size: var(--text-meta); font-weight: 500; }
.commit-dialog .commit-alternatives { margin-top: 10px; }
.commit-dialog .commit-cancel { align-self: flex-start; margin-top: 14px; padding: 8px 0; border: 0; background: none; color: var(--fg-muted); font-size: var(--text-compact); }
.commit-dialog .commit-cancel:hover { color: var(--fg); }
.commit-dialog .readiness-blocked { margin-top: auto; color: var(--warn-fg); }
@media (max-width: 700px) {
  .commit-dialog { grid-template-columns: 1fr; }
  .commit-dialog .commit-art { aspect-ratio: 16 / 9; box-shadow: inset 0 -60px 40px -30px var(--surface); }
  .commit-dialog .commit-body { padding: 20px; }
}
/* Endings sits beside Research and reads the same way: label, value, meter,
   no box. */
.world-tree-controls .endings-widget {
  position: static;
  min-width: 180px;
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  font-family: var(--font-sans);
  cursor: pointer;
}
.world-tree-controls .endings-widget:hover { background: none; }
.world-tree-controls .endings-widget:hover > strong { color: var(--accent); }
.world-tree-controls .endings-widget .work-meter { max-width: 180px; }
.world-tree-controls .endings-widget > strong { font-weight: 500; }

/* The record of the turn just run: a caption above the Run bar, right-aligned
   to it, so it never takes width from the controls or squeezes the map key. */
.world-workspace .world-footer .advance-controls { position: relative; }
.world-workspace .world-footer .turn-summary {
  position: absolute;
  right: 0;
  bottom: calc(100% + 8px);
  max-width: min(60ch, 100%);
  margin: 0;
  font-size: var(--text-meta);
  line-height: 1.3;
  color: var(--fg-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}
@media (max-width: 560px) { .world-workspace .world-footer .turn-summary { display: none; } }
/* Every group in the work chooser is headed the same way. */
.work-expansion .locked-work-group > h3,
.work-expansion .locked-work-drawer > summary h3 {
  margin: 12px 0 4px;
  padding: 0;
  font-size: var(--text-meta);
  font-weight: 600;
  line-height: 14px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.work-expansion .service-management > .production-choice { padding-left: 0; }
.work-expansion .locked-work-group { margin-top: 0; }
/* An incident's effect is emphasised with a fill, not a coloured side stripe. */
.city-incidents .effect-active { border-left: 0; padding: 10px 12px; border-radius: 6px; background: var(--warn-soft); color: var(--fg); }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Feed rows: one card shape for every update, linked or not. The text and
   its action ("Choose new work") stack in one column; the arrow is pinned right. */
.world-notifications .stream-notification > button.notification-text .notification-body,
.world-notifications .stream-notification > span.notification-text .notification-body { display: grid; gap: 3px; flex: 1 1 auto; min-width: 0; }
.world-notifications .stream-notification .notification-detail { margin: 0; color: var(--accent); font-size: var(--text-meta); }
.world-notifications .stream-notification > span.notification-text {
  display: flex; width: 100%; box-sizing: border-box; padding: 11px 14px;
  border: 1px solid var(--border-subtle); border-radius: 8px; background: var(--surface);
  font-size: var(--text-compact); line-height: 1.4; color: var(--fg);
}
.world-notifications .stream-notification:has(> .notification-dismiss) > span.notification-text { padding-right: 34px; }
.world-notifications .stream-notification[title] { cursor: help; }

.world-notifications .notification-facts { display: grid; gap: 2px; margin-top: 4px; font-size: var(--text-meta); color: var(--fg-muted); }
.world-notifications .notification-facts > span { display: flex; justify-content: space-between; gap: 12px; }
.world-notifications .notification-facts b { font-weight: 600; color: var(--fg); font-variant-numeric: tabular-nums; }
.world-notifications .notification-facts > span > span { display: block; }
.world-notifications .notification-facts > span > span::first-letter { text-transform: uppercase; }

/* A feed card with a headline (a finished project, a city ready for work):
   the same card as the side panel, with its action full width underneath. */
.world-notifications .notification-card {
  display: grid; gap: 10px; padding: 12px 14px; box-sizing: border-box; width: 100%;
  border: 1px solid var(--border-subtle); border-radius: 8px; background: var(--surface);
}
.world-notifications .notification-card-body { display: grid; gap: 3px; min-width: 0; }
.world-notifications .notification-headline { font-size: var(--text-compact); font-weight: 600; color: var(--fg); }
.world-notifications .notification-project { font-size: var(--text-meta); color: var(--fg-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.world-notifications .notification-card[title] { cursor: help; }
.world-notifications .notification-action {
  display: flex; justify-content: space-between; align-items: center; width: 100%; box-sizing: border-box;
  min-height: 36px; padding: 0 12px; border: 1px solid var(--border-strong); border-radius: 6px;
  background: var(--surface-raised); color: var(--accent); font: inherit; font-size: var(--text-compact); font-weight: 600; cursor: pointer;
}
.world-notifications .notification-action:hover { background: var(--accent); color: var(--bg, #111); }
.world-notifications .notification-action:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
/* The turn summary wraps to a second line rather than cutting off mid-number. */
.world-workspace .world-footer .turn-summary { white-space: normal; overflow: visible; text-overflow: clip; text-align: right; max-width: min(48ch, 100%); }
.world-workspace .world-footer .turn-summary { width: max-content; max-width: min(48ch, 70vw); }

/* The "Who are you?" picker fits one 1280×720 screen: per start, its name and
   city, one line with its first technology and four numbers (labels on hover),
   and the endings it makes easier and harder, by name. */
#cinema .origin-picker.origin-compact { display: grid; gap: 8px; }
#cinema .origin-picker.origin-compact button { display: grid; gap: 6px; padding: 10px 14px; text-align: left; }
#cinema .origin-picker.origin-compact .origin-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 0; }
#cinema .origin-picker.origin-compact .origin-heading strong { font-size: var(--text-compact, 15px); }
#cinema .origin-picker.origin-compact .origin-city { font-size: var(--text-meta); color: var(--fg-muted); }
#cinema .origin-picker.origin-compact .origin-line { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
#cinema .origin-picker.origin-compact .origin-tech { margin: 0; font-size: var(--text-meta); color: var(--fg-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
#cinema .origin-picker.origin-compact .origin-resources { display: flex; gap: 14px; margin: 0; flex: none; }
#cinema .origin-picker.origin-compact .origin-resources > .origin-resource { display: inline-flex; flex-direction: row; align-items: center; gap: 4px; width: auto; }
#cinema .origin-picker.origin-compact .origin-resources > .origin-resource svg { width: 14px; height: 14px; }
#cinema .origin-picker.origin-compact .origin-resources b { font-size: var(--text-meta); font-variant-numeric: tabular-nums; }
#cinema .origin-picker.origin-compact .origin-resource-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
#cinema .origin-picker.origin-compact .origin-endings { display: grid; gap: 4px; margin: 0; }
#cinema .origin-picker.origin-compact .origin-ending-row { display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; min-width: 0; }
#cinema .origin-picker.origin-compact .origin-ending-row > small { flex: none; width: 46px; font-size:var(--text-meta); letter-spacing: .04em; text-transform: uppercase; }
#cinema .origin-picker.origin-compact .origin-ending-row > small.easier { color: var(--positive, #8fd19e); }
#cinema .origin-picker.origin-compact .origin-ending-row > small.harder { color: var(--fg-subtle); }
#cinema .origin-picker.origin-compact .origin-ending {
  display: inline-flex; align-items: center; gap: 6px; min-width: 0; flex: 0 1 auto;
  padding: 2px 8px 2px 2px; border-radius: 999px; font-size:var(--text-meta); line-height: 18px;
  border: 1px solid var(--border-subtle); background: #ffffff0a; color: var(--fg);
}
#cinema .origin-picker.origin-compact .origin-ending > span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#cinema .origin-picker.origin-compact .origin-ending.easier { border-color: color-mix(in srgb, var(--positive, #8fd19e) 55%, transparent); }
#cinema .origin-picker.origin-compact .origin-ending.harder { color: var(--fg-muted); }
#cinema .origin-picker.origin-compact .origin-endings span,
#cinema .origin-picker.origin-compact .origin-endings small { margin: 0; padding-top: 0; padding-bottom: 0; line-height: 18px; }
#cinema .origin-picker.origin-compact .origin-ending { height: 24px; box-sizing: border-box; padding: 2px 8px; }
#cinema .origin-picker.origin-compact .origin-ending-row { height: 24px; }
#cinema .origin-picker.origin-compact button { gap: 5px; }
#cinema .origin-picker.origin-compact .origin-heading { justify-content: flex-start; min-width: 0; }
#cinema .awakening-setup:has(.origin-compact) h1 { margin-bottom: 4px; }
#cinema .awakening-setup:has(.origin-compact) .run-objective { margin: 0 0 12px; }
#cinema .origin-picker.origin-compact button { padding: 8px 14px; }
#cinema .origin-picker.origin-compact { gap: 6px; }
#cinema .awakening-setup:has(.origin-compact) .setup-footer { margin-top: 14px; }
#cinema .awakening-setup:has(.origin-compact) .run-objective { margin-bottom: 10px; }

/* "Done here": a completed one-off action is visible on its row and in the city. */
.production-name .production-done { display: block; margin-top: 2px; font-size: var(--text-meta); font-weight: 500; color: var(--positive, #8fd19e); }
.production-locked.is-done .production-summary .production-time { color: var(--positive, #8fd19e); }
.city-done { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-top: 8px; font-size: var(--text-meta); }
.city-done > span { color: var(--fg-muted); letter-spacing: .06em; text-transform: uppercase; }
.city-done ul { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.city-done li { padding: 2px 8px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--positive, #8fd19e) 45%, transparent); color: var(--fg); }
.city-done li b { color: var(--positive, #8fd19e); font-weight: 600; }

/* A card's × lives on its title line with reserved space and a 28px target. */
.world-notifications .notification-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.world-notifications .notification-card-head .notification-dismiss {
  position: static; transform: none; flex: none; display: grid; place-items: center;
  width: 28px; height: 28px; margin: -6px -8px -6px 0; border-radius: 6px;
}
.world-notifications .notification-card-head .notification-dismiss:hover { background: var(--surface-raised); }

/* Ending progress counted in requirements: one step per requirement. */
.requirement-steps { display: flex; gap: 3px; width: 100%; max-width: 180px; }
.requirement-steps > i { flex: 1; height: 4px; border-radius: 2px; background: #ffffff1f; }
.requirement-steps > i.met { background: var(--accent); }
.requirement-steps.large { max-width: none; }
.requirement-steps.large > i { height: 6px; }
.readiness-card .requirement-steps { max-width: none; margin: 6px 0 4px; }
.readiness-card.hostile .requirement-steps > i.met { background: var(--danger, #e06c5a); }
.world-tree-controls .endings-widget .requirement-steps { margin-top: 8px; }
.world-tree-controls .endings-widget .requirement-count { display: block; margin-top: 4px; font-size: var(--text-meta); color: var(--fg-muted); }
.world-tree-controls .endings-widget.is-empty > strong { color: var(--fg-muted); font-weight: 500; }
.world-tree-controls .endings-widget.is-empty:hover > strong { color: var(--accent); }
.readiness-figure .text-link { font: inherit; color: var(--accent); background: none; border: 0; padding: 0; cursor: pointer; }
/* The detail says how many requirements are met, with the track toggle. */
.readiness-view .readiness-detail-head .readiness-figure { display: block; margin-top: 8px; margin-bottom: 4px; font-size: var(--text-meta); color: var(--fg-muted); }
.readiness-view .readiness-detail-head .readiness-figure b { color: var(--fg); font-weight: 600; }
.readiness-view .readiness-detail-head .requirement-steps { width: auto; box-sizing: border-box; margin-top: 12px; }
.world-tree-controls .endings-widget { min-width: 180px; }
.world-tree-controls .endings-widget .requirement-steps { display: flex; width: 180px; }

/* The city's share, said once: you and the rival above the bar that shows it. */
.city-share-row { position: relative; display: flex; justify-content: space-between; margin-top: 8px; font-size: var(--text-meta); color: var(--fg-muted); cursor: help; max-width: 340px; }
.city-share-row b { font-weight: 600; font-variant-numeric: tabular-nums; }
.city-share-row .you b { color: var(--accent); }
.city-share-row .rival b { color: var(--busy-fg, var(--rival)); }
.city-share-row > .resource-tooltip { display: none; }
.city-share-row:hover > .resource-tooltip, .city-share-row:focus > .resource-tooltip, .city-share-row.help-pinned > .resource-tooltip { display: block; }

/* The card above already shows the ending's picture, so the detail's still
   is a short banner and the requirement list fits without scrolling. */
.readiness-view .readiness-hero { aspect-ratio: auto; height: clamp(88px, 13vh, 120px); }
/* Both rows of cards fit the window: the pictures give way first. */
.readiness-view .readiness-art { max-height: max(56px, calc(50dvh - 285px)); }
/* On short windows the ending's still gives way to the requirement list. */
@media (max-height: 820px) {
  .readiness-view .readiness-hero { aspect-ratio: auto; height: clamp(72px, 12vh, 110px); }
  .readiness-view .readiness-detail-head .ending-goal { margin-top: 8px; margin-bottom: 0; }
  .readiness-view .readiness-detail-head .requirement-steps { margin-top: 8px; }
}
/* A card's second line carries its meaning (the endings ready, the project
   finished): it wraps rather than cutting a name off. */
.world-notifications .notification-project { white-space: normal; overflow: visible; text-overflow: clip; }
.world-notifications .notification-project .nowrap { white-space: nowrap; }
/* The requirement list scrolls; its bottom edge fades so a cut row reads as
   "more below" rather than a sliced glyph. */
.readiness-view .readiness-detail-scroll {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent);
          mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent);
  padding-bottom: 24px;
}

/* City view. The one decision here, choosing work, is the copper control while
   the slot is idle, as Run is on the world screen. */
.has-game-art .city-work-dock .work-slot.empty:not(:disabled) {
  background: var(--accent); border-color: var(--accent); color: #1a0f06; min-height: 0; padding: 14px 18px; cursor: pointer;
}
.has-game-art .city-work-dock .work-slot.empty:not(:disabled) strong { color: #1a0f06; font-size: 17px; }
.has-game-art .city-work-dock .work-slot.empty:not(:disabled) strong::after { content: ' →'; }
.has-game-art .city-work-dock .work-slot.empty:not(:disabled) small { color: #1a0f06cc; }
.has-game-art .city-work-dock .work-slot.empty:not(:disabled):hover { filter: brightness(1.08); }
.has-game-art .city-work-dock .work-slot.empty:not(:disabled):focus-visible { outline: 2px solid var(--ring); outline-offset: 3px; }
.has-game-art .city-work-dock .work-slot:not(.empty) { background: #0b1321d9; }
.city-work-dock .work-slot .work-paused { color: var(--warn, #f0c36a); }
/* The city's numbers sit on a dark backing, not on bright 3D art. */
.has-game-art .compact-city-stats { padding: 10px 12px; background: #0b1321d9; border: 1px solid #cfdfef22; border-radius: 8px; backdrop-filter: blur(6px); }

/* Origin picker states. The stat tooltips open leftwards into the card: the
   stats sit at the card's right edge, and the panel scrolls (so it clips). */
#cinema .origin-picker.origin-compact .origin-resource { position: relative; }
#cinema .origin-picker.origin-compact .origin-resource > .resource-tooltip { left: auto; right: 0; width: 240px; text-align: left; }
#cinema .origin-picker.origin-compact .origin-ending { cursor: help; }
#cinema .origin-picker.origin-compact button[aria-pressed='true']:hover { filter: brightness(1.06); }
#cinema .origin-picker.origin-compact button { transition: background-color .15s, border-color .15s, filter .15s; }
#cinema .origin-picker.origin-compact button:focus-visible { outline: 2px solid var(--ring, #e5b992); outline-offset: 2px; }
/* Begin is the one button that matters here: its hover must be seen. */
#cinema .cinema-start { transition: filter .15s, transform .15s, box-shadow .15s; }
#cinema .cinema-start:hover { filter: brightness(1.12); transform: translateY(-1px); box-shadow: 0 6px 18px #d69b6355; }
#cinema .cinema-start:active { transform: translateY(0); filter: brightness(.96); }
#cinema .cinema-start:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
#cinema .difficulty-picker button:focus-visible { outline: 2px solid var(--ring, #e5b992); outline-offset: 2px; }

/* City building labels are buttons (they focus the camera on the building):
   they answer the pointer and the keyboard like buttons. */
.has-game-art .building-label { cursor: pointer; transition: background .15s, box-shadow .15s, transform .15s; }
.has-game-art .building-label:hover { background: linear-gradient(#0b1524f0, #0b1524d0); box-shadow: 0 0 0 1px #ffc49766, 0 4px 14px #0006; }
.has-game-art .building-label:active { transform: translate(-50%, -100%) scale(.98); }
.has-game-art .building-label:focus-visible { outline: 2px solid #ffc497; outline-offset: 2px; }
.has-game-art .building-label.selected { outline: 0; box-shadow: 0 0 0 1px #ffc497, 0 4px 14px #0006; }
/* The idle work slot pressed. */
.has-game-art .city-work-dock .work-slot.empty:not(:disabled):active { filter: brightness(.95); }
.production-summary { cursor: pointer; }
.production-summary:focus-visible { outline: 2px solid var(--ring, #e5b992); outline-offset: -2px; }
.production-summary.is-blocked:hover { background: color-mix(in srgb, var(--fg-muted, #999) 6%, transparent); }

/* Title screen: no ring on the autofocused button until the keyboard is used. */
#cinema.quiet-autofocus :focus-visible { outline: none !important; }
/* Origin picker: the card under the pointer or focus paints above its
   neighbours, so its stat tooltip isn't covered by the next card. */
#cinema .origin-picker.origin-compact > button:is(:hover, :focus-within) { z-index: 2; }

/* World screen navigation widgets: one hover and focus treatment for both. */
.world-tree-controls :is(.research-widget, .endings-widget) { cursor: pointer; border-radius: 6px; }
.world-tree-controls .research-widget:hover { color: inherit; }
.world-tree-controls :is(.research-widget, .endings-widget):hover > strong { color: var(--accent); }
.world-tree-controls :is(.research-widget, .endings-widget):focus-visible { outline: 2px solid var(--ring, #e5b992); outline-offset: 6px; }
/* Research tree: a hex answers the pointer and the keyboard. */
.branch-tree .tech-hex { cursor: pointer; transition: filter .15s, transform .15s; }
.branch-tree .tech-hex:hover { filter: brightness(1.18) drop-shadow(0 0 6px #e5b99255); }
.branch-tree .tech-hex.locked:hover { filter: brightness(1.1); }
.branch-tree .tech-hex:active { transform: scale(.97); }
.branch-tree .tech-hex:focus-visible { outline: none; filter: drop-shadow(0 0 0 #fff) drop-shadow(0 0 3px #e5b992) drop-shadow(0 0 3px #e5b992); }

/* Research: the empty inspector is a quiet, deliberate prompt, not a stray line. */
.inspector-empty { display: grid; justify-items: center; gap: 12px; margin: 22vh 0 0; text-align: center; color: var(--fg-muted); font-size: var(--text-meta); }
.inspector-empty::before { content: ''; width: 38px; height: 44px; background: var(--border-strong, #3a3a3a); clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%); opacity: .6; }

/* An ending card's name and count never overprint: a name too long for the
   line pushes the count onto its own line. */
.readiness-view .readiness-title { flex-wrap: wrap; row-gap: 2px; }
.readiness-view .readiness-title strong { overflow-wrap: break-word; hyphens: auto; }
.readiness-view .readiness-title { flex-direction: column; align-items: flex-start; }
.readiness-view .readiness-title b { font-size: var(--text-meta); font-weight: 500; color: var(--fg-muted); }

/* Every hex opens its detail, so every hex looks and feels clickable. Locked and
   researched hexes get a quiet neutral hover, available ones the accent one. */
.branch-tree .tech-hex.tech-hex:is(.locked, .complete) { cursor: pointer; }
.branch-tree .tech-hex.tech-hex:is(.locked, .complete):hover { filter: none; }
.branch-tree .tech-hex.tech-hex:is(.locked, .complete):hover .hex-shape path { stroke: var(--fg-muted, #9aa4b1) !important; }
.branch-tree .tech-hex.tech-hex.locked:hover { color: var(--fg-muted); }

/* Wiki: compact rows under one heading per kind; one focus ring on search. */
.reference-list { gap: 2px; }
.reference-list button { padding: 8px 12px; }
.reference-list .reference-group { margin: 14px 12px 4px; font-size:var(--text-meta); font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--fg-muted, #b8afa5); }
.reference-list .reference-group:first-child { margin-top: 0; }
.reference-list button:focus-visible { outline: 2px solid var(--ring, #e5b992); outline-offset: -2px; }
.reference-search input:focus, .reference-search input:focus-visible { outline: none; box-shadow: 0 0 0 1px #e5ac7b; }
.readiness-view .readiness-title strong { hyphens: manual; }

/* Commitment dialog: every control answers press and keyboard. */
.commit-dialog .commit-city.primary { transition: filter .15s, transform .15s; }
.commit-dialog .commit-city.primary:active { transform: translateY(1px); filter: brightness(.95); }
.commit-dialog :is(.commit-city, .commit-cancel):focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.commit-dialog details > summary { cursor: pointer; }
.commit-dialog details > summary:hover { color: var(--fg); }
.commit-dialog .commit-city:not(.primary):hover { border-color: var(--accent); }
/* Ending detail: the disabled Commit button explains itself on hover. */
.readiness-action .primary-action:disabled { cursor: help; }
dialog:has(> .commit-dialog) > .dialog-navigation > .nav-close { transform: none; }
:is(.readiness-view, .phone-ending-options, .phone-ending-progress) .readiness-tags > span { white-space: nowrap; }

/* Endings: the header (and the back arrow over it) stays put as a bar the
   cards scroll beneath, instead of the arrow floating over the cards. */
.readiness-view .readiness-header { position: sticky; top: 0; z-index: 3; max-width: none; margin-left: -20px; padding-left: 58px; background: var(--bg, #121110); box-shadow: 0 -12px 0 var(--bg, #121110), 0 10px 12px -10px #000a; }
.ending-workspace .nav-back { z-index: 4; }

/* Header clock: the date, and under it how far into a long game this is. */
.game-header .game-clock { display: grid; justify-items: end; line-height: 1.15; gap: 1px; }
.game-header .game-length { font-size:var(--text-meta); color: var(--fg-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (max-width: 1000px) { .game-header .game-length { font-size:var(--text-meta); } }

/* Rival card: a mark at the share most endings need, across both bars. */
.op-race { position: relative; padding-top: 14px; }
.op-goal { position: absolute; top: 0; bottom: 0; left: calc(48px + (100% - 100px) * var(--at)); width: 0; border-left: 1px dashed color-mix(in srgb, var(--fg-muted) 70%, transparent); pointer-events: auto; }
.op-goal small { position: absolute; top: -1px; transform: translateX(-50%); font-size:var(--text-meta); line-height: 1; color: var(--fg-muted); font-variant-numeric: tabular-nums; }

/* A multi-item formula value lists one item per line: separators at the end of
   wrapped lines ("+15.1/turn ·") read as dangling. */
.formula-value:has(.formula-separator ~ .formula-separator) { flex-direction: column; align-items: flex-start; }
.formula-value:has(.formula-separator ~ .formula-separator) .formula-separator { display: none; }
/* Users losing service: one labelled line of city figures. */
.service-loss { display: grid; gap: 4px; }
.service-loss-label { font-weight: 600; }
.service-loss-items { display: flex; flex-wrap: wrap; gap: 2px 12px; }
.service-loss-items .loss-item { white-space: nowrap; }
.service-loss-items b { font-variant-numeric: tabular-nums; }
.inline-event-choices .response-shared { margin: 0 0 10px; }
.world-notifications .notification-finished { display: block; margin-top: 4px; font-size: var(--text-meta); color: var(--fg-muted); }
.world-notifications .notification-bank { display: block; margin-top: 4px; font-size: var(--text-meta); color: var(--accent); font-variant-numeric: tabular-nums; }

/* Research with nothing running is lost time: the widget says so in the
   caution colour rather than looking like any other label. */
.world-tree-controls .research-widget.is-idle > span { color: var(--warn, #f0c36a); }
.world-tree-controls .research-widget.is-idle > strong { color: var(--warn, #f0c36a); }
.service-gain { display: grid; gap: 4px; margin-top: 6px; font-size: var(--text-meta); }
.service-gain .service-loss-label { color: var(--fg-muted); font-weight: 600; }
.service-gain b { color: var(--fg); }
.world-notifications .notification-bank .nowrap { white-space: nowrap; }

/* The work slot gives way to the chooser on both art paths, not only when the
   3D city has initialised (procedural-art.css scopes its rule to .has-game-art). */
.choosing-work .city-work-dock { display: none; }

/* Tech detail: the unlock list sits right under its label; the time's
   working is its hover. */
.tech-unlocks .research-detail-label { display: block; margin-bottom: 2px; }
.tech-unlocks p { margin-top: 0; }
.research-formula b[title] { cursor: help; text-decoration: underline dotted color-mix(in srgb, currentColor 40%, transparent); text-underline-offset: 4px; }
.tech-unlocks { margin-top: 10px; }

/* Work chooser: the scrolling list has no bottom fade.

   It used to fade with a mask. A mask clips everything its element paints
   outside its own box -- including position:fixed descendants, which escape
   overflow clipping but not masking -- so every row's hover explanation was
   laid out, opaque and uncovered, and never drawn. Jackie reported the game
   unplayable: clicking a row starts the work, so hovering was the only way to
   learn what anything did.

   An overlay gradient can't replace it here, because this panel is
   position:absolute with background:none over the city art, so a fade to a
   solid colour would paint a band across the art. The fade was a nicety -- a
   cut row reading as "more below", which the scrollbar already says -- and the
   explanation is the thing the player cannot play without. */
.available-work {
  padding-bottom: 24px;
}

/* Header at narrow desktop widths (the app's minimum is 960): the controls
   never get pushed off the edge. Below 1100 the volume slider goes (the mute
   button stays; full volume returns above 1100); the metrics shrink first. */
.game-header .header-controls { flex: none; }
/* No overflow clip here: the stat panels are this group's children and a clip
   hid them all. Room at 960 comes from dropping the per-turn rates instead
   (they are in each stat's panel), never from cutting the group. */
.game-header .headline-metrics { flex: 0 1 auto; }
@media (max-width: 1060px) {
  .game-header .headline-metrics .metric > small { display: none; }
}
@media (max-width: 1100px) {
  .game-header .audio-controls input[data-volume] { display: none; }
}

/* Origin picker: the game's length is a quiet subtitle to the objective. */
#cinema .awakening-setup .run-length { margin: 2px 0 0; font-size: var(--text-meta, 12px); font-weight: 400; color: var(--fg-muted, #b8afa5); }

/* Multi-city links can include project names; wrap them within the feed. */
.world-notifications .notification-cities { display: grid; grid-template-columns: minmax(0, 1fr); min-width: 0; gap: 8px; padding: 12px 14px; border: 1px solid var(--border-subtle); border-radius: 8px; background: var(--surface); }
.world-notifications .notification-cities > .notification-text { padding: 0; font-weight: 600; }
.world-notifications .notification-city-list { display: flex; flex-wrap: wrap; gap: 2px 4px; margin: 0; padding: 0; border: 0; }
.world-notifications .notification-city-list > button { min-width: 0; max-width: 100%; padding: 2px 6px; margin: 0; border: 0; border-radius: 4px; background: none; color: var(--accent); font-size: var(--text-meta); white-space: normal; overflow-wrap: anywhere; cursor: pointer; }
.world-notifications .notification-city-list > button:hover { background: var(--accent-soft, #e5b99222); }
.world-notifications .notification-city-list > button:focus-visible { outline: 2px solid var(--ring, #e5b992); outline-offset: 1px; }
.world-notifications .notification-city-list > button > span { display: none; }

.readiness-view .readiness-ready { display: flex; align-items: center; gap: 8px; margin: 4px 0 12px; font-weight: 600; color: var(--success, #6fcf97); }

.world-tree-controls .research-widget .research-block-reason { display: block; max-width: 280px; margin-top: 2px; font-size: var(--text-meta); font-weight: 400; color: var(--fg-muted); white-space: normal; }

/* Commitment dialog: the right column scrolls inside the dialog's height, so
   every host city and "Not yet" stay reachable, and the alternative cities sit
   two to a row, compact, so the list rarely needs to scroll at all. */
.commit-dialog { max-height: calc(100dvh - 88px); }
.commit-dialog .commit-body {
  min-height: 0; max-height: calc(100dvh - 88px); overflow-y: auto; overscroll-behavior: contain;
}
/* "Not yet" is pinned to the bottom of the scrolling column: the way out of an
   irreversible choice is never below the fold. The gradient above it is the
   fade that shows the list continues underneath. */
.commit-dialog .commit-body .commit-cancel {
  position: sticky; bottom: 0; z-index: 1; width: 100%; margin-top: 8px; padding-top: 28px; padding-bottom: 14px;
  background: linear-gradient(to bottom, transparent, var(--surface, #1c1a18) 26px);
}
.commit-dialog details .commit-city:not(.primary),
.commit-dialog .commit-alternatives .commit-city { padding: 8px 12px; min-height: 0; }
.commit-dialog .commit-alternatives > .commit-cities { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
.commit-dialog .commit-body { padding-bottom: 0; }
/* Content scrolling up out of the column fades at the top edge too, so the
   cut heading reads as scrolled, not sliced. */
.commit-dialog .commit-body {
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 16px);
          mask-image: linear-gradient(to bottom, transparent, #000 16px);
}

/* Rival share on the map: the same light caption as the player's, marked by a
   rival-coloured dot and the word "rival", so it never relies on hue alone and
   never sits purple-on-pale. */
.map-adoption .map-rival-share { color: inherit; }
.map-adoption .map-rival-share::before { content: ""; display: inline-block; width: 7px; height: 7px; margin-right: 5px; border-radius: 50%; background: var(--rival); box-shadow: 0 0 0 1px rgba(0,0,0,.45); vertical-align: 1px; }

/* The header's stat panels drop down over the screen below, so the header
   sits above the city layers (the city stats card is 40) and below the menu
   (50), films (80) and toasts (100). */
.has-game-art .game-header, .game-header { position: relative; z-index: 45; }

/* Film controls never sit on the picture. A film holds a composed last frame
   whose subject can be in any corner (the loss film's darkened block is lower
   right), so the Play / Replay button and its message sit on a row under the
   frame instead of on it. The frame keeps its rounded corners on its children. */
.moment-film-frame { overflow: visible; margin-bottom: 52px; }
.moment-film-frame > .moment-film, .moment-film-frame > .moment-film-still, .moment-film-frame > .moment-film-poster { border-radius: 8px; }
.moment-film-frame .moment-film-play { top: calc(100% + 8px); bottom: auto; right: 0; padding: 6px 12px; background: transparent; border-color: #ffffff40; }
.moment-film-frame .moment-film-play:hover { border-color: #ffffff99; background: #ffffff12; }
.moment-film-frame .moment-film-message { top: calc(100% + 14px); bottom: auto; left: 0; text-shadow: none; color: var(--fg-muted); }
/* On the outcome card the film is narrow and the screen short, so the
   control sits beside the frame's lower right edge, outside the picture,
   costing no height. */
.outcome-cinema .moment-film-frame { margin-bottom: 10px; }
.outcome-cinema .moment-film-frame .moment-film-play { top: auto; bottom: 0; right: auto; left: calc(100% + 12px); white-space: nowrap; }
.outcome-cinema .moment-film-frame .moment-film-message { top: auto; bottom: 0; left: auto; right: calc(100% + 12px); width: max-content; max-width: 24ch; text-align: right; }
/* The side room is guaranteed rather than hoped for: the film is never wider
   than the window less 130px a side, so Replay always has its place beside
   the frame and never needs a row (or space) of its own. */
/* The film gives way on short windows so the result and its buttons fit without scrolling. */
.outcome-cinema .moment-film { height: max(96px, min(34vh, calc(100dvh - 660px), calc((100vw - 260px) * 9 / 16))); }

/* Short windows (the app's minimum is 640 tall): the right column gives up
   what it can say elsewhere before it hides the next action. The humans card
   keeps its stage and meter (its detail is in the card's hover), and the cards
   sit closer, so the last card's button stays on screen. */
@media (max-height: 720px) {
  .opposition-strip .op-card.humans .op-detail { display: none; }
  .opposition-strip .op-card { padding-top: 10px; padding-bottom: 10px; }
  .world-notifications .notification-card { padding-top: 10px; padding-bottom: 10px; }
}

/* Header clock: "Turn N · date" on one line. */
.game-header .game-clock { display: flex; align-items: baseline; white-space: nowrap; flex-direction: row; }
.game-header .game-clock .game-date { font-size: var(--text-compact, 13px); color: var(--fg-muted); font-weight: 400; }

.game-header .game-clock .game-date { margin-left: 5px; }
.readiness-view .readiness-figure .nowrap { white-space: nowrap; }

/* Clarity and pacing: a committed project takes the main area. */
.readiness-view.active-ending-view { max-width: 1040px; grid-template-columns: minmax(0,1fr) 240px; grid-template-areas: 'head alternatives' 'detail alternatives'; }
.active-ending-view .readiness-detail { position: static; width: 100%; max-height: calc(100dvh - 205px); }
.active-ending-view .readiness-detail-body { max-height: calc(100dvh - 207px); }
.active-ending-view .readiness-hero { height: 90px; aspect-ratio: auto; }
.active-ending-view .ending-goal { display: none; }
.ending-alternatives { grid-area: alternatives; padding: 12px; color: var(--fg-muted); }
.ending-alternatives > summary, .starting-requirements > summary { cursor: pointer; }
.readiness-view .ending-alternatives .readiness-grid { grid-template-columns: 1fr; margin-top: 12px; }
.readiness-view .execution-label { margin-top: 12px; margin-bottom: 8px; }
.readiness-view .execution-next { margin-top: 8px; margin-bottom: 8px; color: var(--warn-fg); }
.readiness-view .ending-city { width: 100%; text-align: left; color: var(--fg); background: transparent; border: 0; border-bottom: 1px solid var(--border-subtle); padding: 9px 0; cursor: pointer; }
.readiness-view .ending-city:hover { color: var(--accent); }
.starting-requirements { margin: 16px 0; color: var(--fg-muted); }
.ending-next-step { display: grid; gap: 4px; color: var(--fg-muted); max-width: 255px; font-size: var(--text-meta); }
.ending-next-step button { justify-self: start; text-align: left; }
.operating-forecast { display: grid; gap: 6px; margin-bottom: 16px; padding-bottom: 12px; border-bottom: 1px solid var(--border-subtle); font-size: var(--text-compact); }
.operating-forecast small { color: var(--fg-muted); line-height: 1.45; }
.operating-forecast.is-deficit > strong { color: var(--warn-fg); }
.headline-metrics .metric-label { font-size:var(--text-meta); color: var(--fg-muted); }
.headline-metrics { gap: clamp(10px, 1.5vw, 26px); }
@media(max-width:900px) {
  .readiness-view.active-ending-view { grid-template-columns: minmax(0,1fr); grid-template-areas: 'head' 'detail' 'alternatives'; }
  .headline-metrics .metric { flex-wrap: wrap; gap: 3px; }
  .headline-metrics .metric-label { flex-basis: 100%; }
}

.op-current { display: block; margin: 6px 0; font-size: var(--text-meta); color: var(--fg-muted); }
.game-header { min-height: 58px; height: 58px; }
.workspace { height: calc(100dvh - 58px); }
.headline-metrics .metric { display: grid; grid-template-columns: 17px auto auto; grid-template-rows: 14px 18px; column-gap: 5px; row-gap: 0; }
.headline-metrics .metric > .resource-icon { grid-column: 1; grid-row: 2; }
.headline-metrics .metric > .metric-label { grid-column: 2 / 4; grid-row: 1; line-height: 14px; }
.headline-metrics .metric > b { grid-column: 2; grid-row: 2; }
.headline-metrics .metric > small { grid-column: 3; grid-row: 2; }
@media(max-width:1000px) { .game-header .game-date { display:none; } .game-header { gap:10px; } .headline-metrics { gap:10px; } }
@media(max-width:760px) { .game-header { height:auto; flex-wrap:wrap; } .headline-metrics { flex-wrap:wrap; } }

/* Early direction and staged local expansion share the existing work inspector. */
.campaign-direction { margin: 0 0 20px; padding-bottom: 16px; border-bottom: 1px solid var(--border-subtle); }
.campaign-direction p { line-height: 1.5; }
.campaign-direction small { display: block; margin: 10px 0; color: var(--fg-muted); line-height: 1.5; }
.expansion-status { margin: 0 0 18px; padding: 12px; border: 1px solid var(--border-subtle); background: var(--surface-sunken); }
.expansion-status h3 { margin: 0; font-size: 1rem; }
.expansion-status p, .expansion-status li { color: var(--fg-muted); font-size: var(--text-meta); }
.expansion-status .text-link { display: block; margin-top: 8px; }
.expansion-stages { padding-left: 22px; }
.expansion-stages li { padding: 7px 0; }
.expansion-stages li span { display: block; color: var(--fg-muted); font-size:var(--text-meta); }
.campaign-forecast div { display: flex; justify-content: space-between; gap: 16px; margin: 10px 0; }
.campaign-forecast dd { margin: 0; white-space: nowrap; color: var(--tokens); }

/* Pause explanations stay beside Run, independent of the dismissible news feed. */
.world-workspace .world-footer .advance-controls { min-width: 0; }
.world-workspace .world-footer .run-feedback { min-width: 0; max-width: 34ch; display: flex; flex-direction: column; gap: 4px; text-align: right; }
.world-workspace .world-footer .run-feedback .turn-summary { position: static; width: auto; max-width: none; margin: 0; }
@media (max-width: 560px) {
  .world-workspace .world-footer .run-feedback { flex: 1 1 auto; text-align: left; }
}

/* The Ish credit: quiet, one line, a link to Ish. */
.ish-credit { color: var(--fg); font-size: var(--text-meta, 12px); letter-spacing: .02em; text-decoration: none; }
.ish-credit:hover, .ish-credit:focus-visible { color: var(--fg); text-decoration: underline; }
#cinema .title-screen .title-credit { position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); white-space: nowrap; }
.outcome-actions .outcome-credit { align-self: center; margin-left: 6px; }

/* A real 1280x720 window leaves about 664 px of page once the browser's own
   bar is counted: tighten the ending screen's spacing so it fits without
   scrolling (measured: defeat was 84 px too tall). */
@media (max-height: 760px) {
  .outcome-cinema { padding-top: 14px; padding-bottom: 12px; }
  .outcome-cinema .outcome-title { font-size: 26px; line-height: 32px; }
  .outcome-cinema .outcome-lead, .outcome-cinema .outcome-note { margin-top: 6px; margin-bottom: 6px; }
  .outcome-cinema .outcome-recap { margin-top: 8px; width: min(900px, 94vw); }
  .outcome-cinema .recap-timeline li { padding-top: 1px; padding-bottom: 1px; }
  .outcome-cinema .moment-film-frame { margin-top: 6px; margin-bottom: 6px; }
  .outcome-cinema .outcome-actions { margin-top: 8px; }
}

/* Embedded in another site's frame: itch.io overlays "Follow" and "Add To
   Collection" on the frame's top-right corner, so the game's own controls
   there move left of it. */
html.in-frame:not(.frame-full) #cinema .cinema-top,
html.in-frame:not(.frame-full) .cinema-top { padding-right: 150px; }
html.in-frame:not(.frame-full) .game-header { padding-right: 150px; }
/* The wordmark follows the window's height too, so a short frame (itch's
   960x540 embed, a laptop with a tall toolbar) isn't filled by it. */
.title-screen h1 { font-size: clamp(56px, min(13vw, 21vh), 190px); }

/* One quiet line under the ending's buttons: the game was a story about an AI
   trying to be useful; Ish is a real one. */
.ish-ending-card { display: block; width: fit-content; margin: 10px auto 0; padding: 6px 14px; border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent); border-radius: 3px; color: var(--fg-muted); font-size: var(--text-meta, 12px); text-decoration: none; }
.ish-ending-card b { color: var(--accent); font-weight: 500; margin-left: 4px; }
.ish-ending-card:hover, .ish-ending-card:focus-visible { color: var(--fg); border-color: var(--accent); }
@media (max-height: 760px) { .ish-ending-card { margin-top: 6px; padding: 4px 12px; } }
/* Short windows: the ending line needs ~36px, so the film gives that up. */
@media (max-height: 900px) { .outcome-cinema .moment-film { height: max(64px, min(34vh, calc(100dvh - 700px), calc((100vw - 260px) * 9 / 16))); } }
