.head-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
a.ghost { color: var(--ink); text-decoration: none; }
main { margin-top: 20px; }

.primary {
  background: var(--ink); color: var(--surface); border: 0; border-radius: 6px;
  padding: 8px 16px; font-weight: 600; cursor: pointer;
}
.primary:hover { filter: brightness(1.2); }
.primary:disabled { opacity: 0.5; cursor: default; }

.new-form { display: flex; gap: 12px; align-items: flex-end; margin-top: 12px; flex-wrap: wrap; }
.new-form input[type="text"] { padding: 5px 8px; min-width: 0; font: inherit; color: var(--ink); background: var(--surface); border: 1px solid var(--axis); border-radius: 4px; }
.new-form input::placeholder { color: var(--muted); }
.crew-names { flex: 1 1 100%; border: 1px solid var(--grid); border-radius: 6px; padding: 8px 12px 12px; margin: 0; min-width: 0; }
.crew-names legend { font-weight: 600; padding: 0 4px; }
.crew-names .sub { margin: 0 0 10px; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.crew-names-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px 14px; }
.crew-name { display: block; font-weight: 600; }
.crew-role { display: block; font-size: 12px; color: var(--ink-2); }
.saves-list { list-style: none; padding: 0; margin: 8px 0 0; display: flex; flex-direction: column; gap: 6px; }
.saves-list li { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; padding: 8px 0; border-bottom: 1px solid var(--grid); }
.saves-list .what { flex: 1 1 240px; }
.saves-list .when { color: var(--muted); font-size: 12.5px; }

/* ---- prompt -------------------------------------------------------------- */
.prompt h2 { margin-bottom: 4px; }
.prompt .why { color: var(--ink-2); margin: 0 0 14px; }
.roll-row { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
.dice { display: inline-flex; gap: 8px; }
.die {
  width: 40px; height: 40px; border-radius: 8px; border: 1.5px solid var(--ink); background: var(--surface);
  display: inline-grid; grid-template: repeat(3, 1fr) / repeat(3, 1fr); padding: 6px; box-sizing: border-box;
  place-items: center;
}
.die .pip { width: 7px; height: 7px; border-radius: 50%; background: var(--ink); }
.die .numeral { grid-area: 1 / 1 / -1 / -1; font-weight: 700; font-size: 18px; color: var(--ink); }
.die.tens .numeral { color: var(--surface); }
.die.tens { background: var(--ink); } /* the coloured die read as tens on G-3 / B-3 */
.die.tens .pip { background: var(--surface); }

/* A fresh roll: the dice tumble (play-prompt.js swaps the faces), land with a bounce, then the result shows. */
/* While the dice tumble, the prompt's next step waits with the rest of the page (play.js render). */
#game.dice-rolling #prompt > :not(.last) { visibility: hidden; }
.dice.rolling .die { animation: die-tumble 650ms cubic-bezier(0.3, 0.7, 0.4, 1) both; }
.dice.landed .die { animation: die-land 260ms ease-out both; }
.dice.settling .die { animation: die-fade 150ms ease-out both; }
.result.hidden-until-landed { opacity: 0; }
.result.revealed { animation: result-in 220ms ease-out both; }
@keyframes die-tumble {
  0%   { transform: translate(-28px, -14px) rotate(-200deg) scale(0.7); opacity: 0; }
  20%  { opacity: 1; }
  45%  { transform: translate(6px, -8px) rotate(40deg); }
  70%  { transform: translate(-3px, 0) rotate(-14deg); }
  100% { transform: none; }
}
@keyframes die-land {
  0%   { transform: scale(1.14); box-shadow: 0 0 0 4px var(--ring); }
  100% { transform: none; box-shadow: 0 0 0 0 transparent; }
}
@keyframes die-fade { from { opacity: 0.3; } to { opacity: 1; } }
@keyframes result-in { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }
.manual { color: var(--ink-2); font-size: 12.5px; display: inline-flex; gap: 6px; align-items: center; }
.manual select { padding: 2px 4px; }
.kbd { font-size: 11.5px; color: var(--muted); }
.last { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--grid); }
.last .result { font-weight: 600; }

/* ---- briefing ------------------------------------------------------------ */
.brief-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin: 8px 0 16px; }
.brief-grid .label { color: var(--ink-2); font-size: 12.5px; }
.brief-grid .value { font-size: 18px; font-weight: 600; }
.route { display: flex; gap: 2px; flex-wrap: wrap; }
.route .zone { flex: 1 1 64px; padding: 8px 6px; background: var(--page); border-radius: 4px; text-align: center; min-width: 64px; }
.route .zone.target { box-shadow: inset 0 0 0 2px var(--ink); }
.route .z { font-size: 11.5px; color: var(--ink-2); }
.route .m { font-weight: 700; font-variant-numeric: tabular-nums; }
.route .t { font-size: 11.5px; color: var(--muted); }
.mods { margin: 12px 0 0; padding-left: 18px; color: var(--ink-2); font-size: 12.5px; }
.next-stage { margin-top: 14px; color: var(--ink-2); font-size: 12.5px; }

/* ---- log ------------------------------------------------------------------ */
.log { list-style: none; margin: 0; padding: 0; font-size: 13px; }
.log li { display: grid; grid-template-columns: 64px 92px 1fr; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--grid); }
.log .tbl a { color: var(--ink-2); font-weight: 600; }
.log .log-name { font-weight: 600; }
.log li.new { background: color-mix(in srgb, var(--series-1) 10%, transparent); box-shadow: inset 3px 0 0 var(--series-1); padding-left: 6px; animation: log-new 600ms ease-out; }
@keyframes log-new { from { background: color-mix(in srgb, var(--series-1) 28%, transparent); } }
.log .rl { color: var(--ink-2); font-variant-numeric: tabular-nums; }
@media (max-width: 560px) { .log li { grid-template-columns: 52px 1fr; } .log .rl { display: none; } }

.toast {
  position: fixed; bottom: 16px; left: 50%; transform: translateX(-50%); max-width: min(560px, calc(100% - 32px));
  background: #d03b3b; color: #fff; padding: 10px 14px; border-radius: 8px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
}

/* ---- stage 2: combat ------------------------------------------------------- */
/* The game screen fits the window with nothing to scroll but the log: the header, then the stage (map, plane
   and the rail, three columns watched during combat, which scale to the height left), then crew and damage
   (checked rather than watched) in a compact strip. Narrow windows fall back to an ordinary scrolling page. */
.game[hidden] { display: none; } /* .game sets display, which would otherwise beat the hidden attribute */
body:has(#game:not([hidden])) { max-width: none; height: 100vh; height: 100dvh; padding: 10px 16px 12px; display: flex; flex-direction: column; overflow: hidden; }
body:has(#game:not([hidden])) .page-head { margin-bottom: 8px; flex: none; align-items: center; }
body:has(#game:not([hidden])) .page-head h1 { font-size: 20px; margin: 0; }
body:has(#game:not([hidden])) main { margin-top: 0; }
.game { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 12px; }
.game .card { padding: 12px 14px; margin: 0; border-radius: 10px; }
.game .card-head { margin-bottom: 6px; }
.game h2 { font-size: 15px; }
/* The map (checked occasionally) is given less room than the plane and the rail (both read every combat beat);
   the rail is a real column now, not a fixed sidebar, so the prompt's dropdowns have room to breathe. */
.stage { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr) minmax(340px, 1.3fr); gap: 12px; }
/* The drawings shrink to the room they have (viewBox scaling keeps their shape). */
.stage > .card { min-height: 0; display: flex; flex-direction: column; }
.stage #map { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; }
.stage .map-card svg.map { flex: 1 1 0; min-height: 0; width: 100%; height: 100%; }
.game-grid { flex: none; display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 3fr); gap: 12px; min-height: 0; }
/* The crew table sets the strip's height; the damage panel takes that height and scrolls only if its lists outgrow it. */
#damage { contain: size; overflow-y: auto; }
.game-rail { min-height: 0; display: flex; flex-direction: column; gap: 12px; }
.game-rail .prompt { flex: 0 1 auto; min-height: 0; overflow-y: auto; }
/* A tall prompt (assigning nine guns) scrolls inside its box; its buttons stay in view at the bottom. */
.game-rail .prompt .actions { position: sticky; bottom: -12px; background: var(--surface); padding: 8px 0 12px; margin-bottom: -12px; border-top: 1px solid var(--grid); z-index: 1; }
.log-card { flex: 1 1 0; min-height: 140px; display: flex; flex-direction: column; padding-bottom: 6px; }
.log-card .log { flex: 1 1 auto; min-height: 0; overflow-y: auto; margin-right: -8px; padding-right: 8px; font-size: 12.5px; }
.log-card .log li { grid-template-columns: 44px 76px 1fr; gap: 6px; padding: 4px 0; }

/* The compact strip under the drawings. */
#crew .status-table td { padding: 2px 6px 2px 0; white-space: nowrap; }
#crew .status-table td:first-child { max-width: 0; width: 42%; overflow: hidden; text-overflow: ellipsis; }
#crew .status-table th { padding: 2px 6px 3px 0; }
#crew .crew-name, #crew .crew-role { display: inline; }
#crew .crew-role { margin-left: 5px; font-size: 11.5px; }
#crew .status-table td { vertical-align: middle; }
#damage h3.panel { margin: 8px 0 3px; }
#damage .damage-list { margin: 2px 0 6px; }
.briefing { flex: none; margin-top: 8px; font-size: 12.5px; }
.briefing .facts { display: flex; flex-wrap: wrap; gap: 2px 14px; margin-bottom: 6px; }
.briefing .fact .label { color: var(--ink-2); }
.briefing .fact .value { font-weight: 600; }
.briefing .route { display: flex; gap: 3px; flex-wrap: wrap; align-items: stretch; }
.briefing .route-label { color: var(--ink-2); align-self: center; margin-right: 4px; }
.briefing .route .zone { flex: 1 1 0; min-width: 40px; padding: 2px 4px; display: flex; justify-content: space-between; gap: 4px; align-items: baseline; }
.briefing .route .z { font-size: 11px; }
.briefing .next-stage { margin: 6px 0 0; }

@media (max-width: 1180px), (max-height: 640px) {
  body:has(#game:not([hidden])) { height: auto; overflow: visible; display: block; padding-bottom: 32px; }
  /* .stage flattens into .game's own flex column, so the prompt (order -1, via .game-rail below) can hoist
     above the map and plane, and the log (order 1) can sink below crew and damage — one ordering context
     spanning what used to be two nested ones, now that the rail lives inside .stage on the desktop layout. */
  .stage { display: contents; }
  /* .stage #map and .plane-card > div are "flex: 1 1 0" so they share out a definite height from their
     ancestors on the desktop layout (body's fixed 100vh, above). Once that chain is gone here (body goes back
     to its natural height), flex: 1 1 0 has no free space to grow into and both collapse to 0 height, hiding
     the map and the B-17 and letting the cards after them overlap their headings. Size them to their content
     (the SVGs, each now given an aspect ratio) instead. */
  .stage #map, .stage .plane-card > div { flex: none; }
  .stage .map-card svg.map { height: auto; flex: none; aspect-ratio: 1098 / 798; }
  .stage .plane-card svg { height: auto; flex: none; aspect-ratio: 1 / 1; max-height: 560px; }
  #damage { contain: none; }
  /* The name column's ellipsis (above) keeps this fitting down to phone-ish widths, but a crewman on two guns,
     or the status chip, can still add up to more than the card has at the narrowest phones; scroll the table
     itself rather than letting it push the card — and the page — wider than the screen. */
  #crew .status-table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .game-rail { display: contents; }
  .game-rail .prompt { order: -1; }
  .log-card { order: 1; flex: none; }
  .log-card .log { max-height: 55vh; }
}
@media (max-width: 900px) { .game-grid { grid-template-columns: minmax(0, 1fr); } }

.plane-card > div { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; }
.plane-card svg { display: block; width: 100%; flex: 1 1 0; min-height: 0; }
.plane-card .ring { fill: none; stroke: var(--grid); }
.plane-card .ring-label { fill: var(--muted); font-size: 10px; }
.plane-card .clock { fill: var(--muted); font-size: 11px; font-weight: 600; }
.plane-card .b17 .airframe { fill: var(--axis); }
/* The line drawing (tools/trace-b17.js): its three line weights, kept hairline at any size. */
.plane-card .b17 .art { fill: none; vector-effect: non-scaling-stroke; stroke-linecap: round; stroke-linejoin: round; }
.plane-card .b17 .art.lines { stroke: var(--ink-2); stroke-width: 0.9px; }
.plane-card .b17 .art.details { stroke: var(--ink-2); stroke-width: 0.6px; opacity: 0.8; }
.plane-card .b17 .art.fine { stroke: var(--muted); stroke-width: 0.5px; opacity: 0.55; }
.plane-card .card-head { margin-bottom: 4px; }
.plane-card .hit-shade { fill: #d03b3b; }
.plane-card .engine-out rect { fill: #d03b3b; fill-opacity: 0.75; }
.plane-card .b17 .feathered { stroke: var(--ink); stroke-width: 0.9; stroke-linecap: round; }
.plane-card .b17 .windmill { fill: none; stroke: #d03b3b; stroke-width: 0.5; stroke-dasharray: 1.2 1.2; }
.plane-card .engine-label { fill: var(--ink-2); font-size: 2.6px; font-weight: 700; }
.plane-card .fire-glow { fill: #f08a24; opacity: 0.35; animation: fire-pulse 900ms ease-in-out infinite alternate; }
.plane-card .fire-flame { fill: #f08a24; stroke: #c4420e; stroke-width: 1; }
@keyframes fire-pulse { from { opacity: 0.2; transform: scale(0.85); } to { opacity: 0.5; transform: scale(1.1); } }
/* Tracers from the latest action: blue for the B-17's guns, red for German fire. Solid hits, dashed misses. */
.plane-card .tracer { stroke-width: 2.5; stroke-linecap: round; pointer-events: stroke; }
.plane-card .tracer.ours { stroke: var(--series-1); }
.plane-card .tracer.theirs { stroke: #d03b3b; }
.plane-card .tracer.miss { stroke-dasharray: 0.04 0.03; opacity: 0.75; }
.plane-card .tracer.hit { stroke-dasharray: 1; animation: tracer-draw 320ms ease-out both; }
.plane-card .tracer.miss { animation: tracer-fade 320ms ease-out both; }
.plane-card .flash { fill: none; stroke: #d03b3b; stroke-width: 2.5; animation: flash 700ms ease-out both; }
@keyframes tracer-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes tracer-fade { from { opacity: 0; } }
@keyframes flash { from { r: 4; opacity: 1; } to { r: 16; opacity: 0.6; } }
@media (prefers-reduced-motion: reduce) { .plane-card .tracer, .plane-card .flash, .plane-card .fire-glow { animation: none !important; } }
.plane-legend .ln { display: inline-block; width: 16px; height: 0; border-top: 2.5px solid; margin-right: 5px; vertical-align: 3px; }
.plane-legend .ln.ours { border-color: var(--series-1); }
.plane-legend .ln.theirs { border-color: #d03b3b; }
.plane-card .comp-hit { fill: #d03b3b; }
.plane-card .comp-hit-text { fill: #fff; font-size: 9px; font-weight: 700; }
/* Fighters: their silhouettes, coloured by damage, outlined in the background colour so they stand off the rings. */
.plane-card .fighter .silhouette { fill: var(--ink); stroke: var(--surface); stroke-width: 1.2px; vector-effect: non-scaling-stroke; paint-order: stroke; }
.plane-card .fighter.FCA .silhouette { fill: #c98500; }
.plane-card .fighter.FBOA .silhouette { fill: #d95926; }
.plane-card .fighter.destroyed { opacity: 0.4; }
.plane-card .fighter.destroyed .silhouette { fill: var(--muted); }
.plane-card .fighter-x { fill: #d03b3b; font-size: 14px; font-weight: 700; pointer-events: none; }
.plane-card .fighter-type { fill: var(--ink-2); font-size: 9px; font-weight: 700; pointer-events: none; paint-order: stroke; stroke: var(--surface); stroke-width: 3px; }
/* A fighter shown past the bomber for the tail guns' passing shot (9.2): faded, with its dashed path through. */
.plane-card .fighter.ghost { opacity: 0.8; }
.plane-card .fighter.passed { opacity: 0.3; }
.plane-card .fighter.ghost .silhouette { stroke-dasharray: 2 2; }
.plane-card .pass-path { stroke: var(--muted); stroke-width: 1.2; stroke-dasharray: 3 4; opacity: 0.7; }
.plane-card .attack-ring { fill: none; stroke: #d03b3b; stroke-width: 1.5; animation: attack-ring 1s ease-out infinite; }
.plane-card .fighter.attacking .airframe-frame { animation: lunge 700ms ease-in-out both; }
@keyframes attack-ring { from { r: 14; opacity: 0.9; } to { r: 24; opacity: 0; } }
@keyframes lunge { 0%, 100% { transform: none; } 45% { transform: translateY(-12px); } } /* toward the bomber: the nose is up */
@media (prefers-reduced-motion: reduce) { .plane-card .attack-ring, .plane-card .fighter.attacking .airframe-frame { animation: none !important; } }
.plane-card .empty-sky { fill: var(--muted); font-size: 12px; }
.plane-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 12px; color: var(--ink-2); margin-top: 6px; }
.plane-legend .sw { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 5px; vertical-align: -1px; }

.choices { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 12px; }
.pick-list { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 12px; }
.pick-list label { display: flex; gap: 8px; align-items: center; cursor: pointer; }
.gun-table { border-collapse: collapse; width: 100%; margin: 4px 0 12px; font-size: 13px; }
.gun-table td { padding: 5px 8px 5px 0; border-bottom: 1px solid var(--grid); vertical-align: middle; }
.gun-table td.who { color: var(--ink-2); font-size: 12px; }
.gun-table select { width: 100%; max-width: 320px; }
.actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.banner { padding: 12px 14px; border-radius: 8px; background: var(--page); border-left: 4px solid var(--ink); margin-bottom: 12px; }
.banner.bad { border-left-color: #d03b3b; }

.status-table { border-collapse: collapse; width: 100%; font-size: 12.5px; }
.status-table th { text-align: left; color: var(--ink-2); font-weight: 600; padding: 4px 8px 4px 0; border-bottom: 1px solid var(--axis); }
.status-table td { padding: 4px 8px 4px 0; border-bottom: 1px solid var(--grid); vertical-align: top; }
.gun-line { display: grid; grid-template-columns: 8.2em 46px 3.4em auto; align-items: center; column-gap: 6px; font-variant-numeric: tabular-nums; }
.gun-line .bar { height: 6px; background: var(--grid); border-radius: 3px; overflow: hidden; }
.gun-line .bar span { display: block; height: 100%; background: var(--series-1); }
.gun-line .count { text-align: right; }
.gun-line .chip { margin: 0 4px 0 2px; }
/* Pills: a fixed height with the text centred in it. (The theme's typewriter face sits high in its own line box,
   so mission-theme.css nudges it down a little.) */
.chip {
  display: inline-flex; align-items: center; height: 20px; box-sizing: border-box; font-size: 11.5px; line-height: 1;
  padding: 0 8px; border-radius: 999px; border: 1px solid var(--axis); color: var(--ink-2); margin: 0 4px 2px 0;
  white-space: nowrap; vertical-align: middle;
}
.chip.warn { border-color: #c98500; color: var(--ink); }
.chip.bad { border-color: #d03b3b; color: var(--ink); font-weight: 600; }
.damage-list { margin: 4px 0 10px; padding-left: 18px; font-size: 12.5px; }
.damage-list li { margin-bottom: 2px; }
.muted { color: var(--muted); }
h3.panel { font-size: 12.5px; margin: 12px 0 4px; color: var(--ink-2); text-transform: uppercase; letter-spacing: 0.03em; }
.route .zone.here { background: var(--ring); }

/* ---- stage 7: polish ------------------------------------------------------- */
.bear-list { margin: 0 0 10px; padding-left: 18px; font-size: 12.5px; color: var(--ink-2); }
.bear-list strong { color: var(--ink); font-weight: 600; }
.crew-group h3.panel { margin-top: 8px; }

/* The printed mission report: the title, the result and each crewman's fate, the briefing and the map, the crew
   and guns, the B-17's damage (drawing and list), then the whole log. */
@media print {
  @page { margin: 14mm 12mm; }
  :root, :root[data-theme="dark"] { --page: #fff; --surface: #fff; --ink: #000; --ink-2: #333; --muted: #666; --grid: #d6d6d6; --axis: #9a9a9a; --ring: rgba(0, 0, 0, 0.12); color-scheme: light; }
  .map-card, :root[data-theme="dark"] .map-card { --map-sea: #e3edf7; --map-land: #efede4; --map-coast: #a9b4bf; }
  body { max-width: none !important; padding: 0 !important; font-size: 10.5px; height: auto !important; overflow: visible !important; display: block !important; }
  .head-actions, .roll-row, .actions, .choices, .kbd, .last, .toast, #start, #campaign, button, .plane-legend { display: none !important; }
  .page-head { margin-bottom: 10px !important; }
  .card { border: 0 !important; padding: 0 !important; margin: 0 0 12px !important; border-radius: 0; box-shadow: none; }
  .card h2 { font-size: 13px; border-bottom: 1.5px solid #000; padding-bottom: 2px; margin-bottom: 6px; }
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }

  /* One column: the result first, the log last. .stage, .game-rail and .game-grid all flatten (display: contents)
     so their children — map, plane, prompt, log, crew, damage — become one set of grid items on .game itself,
     positioned by order and grid-column rather than by the nested rows/columns the screen layout uses. */
  .game { display: grid !important; grid-template-columns: 1fr 1fr; gap: 0 18px; overflow: visible; }
  .stage, .game-rail, .game-grid { display: contents !important; }
  .game-rail .prompt { order: -1; grid-column: 1 / -1; max-height: none; overflow: visible; }
  .log-card { order: 4; grid-column: 1 / -1; display: block; min-height: 0; }
  /* The map, then the crew, then the B-17's damage drawn and listed side by side. */
  .stage > .map-card { grid-column: 1 / -1; order: 1; break-inside: avoid; }
  #crew { grid-column: 1 / -1; order: 2; break-inside: avoid; }
  .plane-card { grid-column: 1; order: 3; break-inside: avoid; display: block; }
  #damage { grid-column: 2; order: 3; contain: none !important; overflow: visible !important; break-inside: avoid; }

  /* Fixed sizes on paper: on screen these flex to fill the window, which on paper is no room at all. */
  .stage > .card, .stage #map, .plane-card > div { display: block !important; flex: none !important; min-height: 0; }
  .stage .map-card svg.map { height: 10.5cm !important; width: 100%; flex: none !important; }
  .plane-card svg { height: 7.5cm !important; width: 100%; flex: none !important; }
  .log-card .log { overflow: visible !important; max-height: none !important; flex: none !important; margin: 0; padding: 0; }

  /* The result and the fates, the fates in two columns. */
  .prompt .banner { border-left-width: 3px; padding: 6px 10px; }
  .prompt .status-table tbody { display: grid; grid-template-columns: 1fr 1fr; column-gap: 24px; }
  .prompt .status-table tr { display: flex; justify-content: space-between; border-bottom: 1px solid var(--grid); }
  .prompt .status-table td { border: 0; }
  .prompt .crew-name, .prompt .crew-role, #crew .crew-name, #crew .crew-role { display: inline; }
  .prompt .crew-role { margin-left: 5px; }

  #crew .status-table td:first-child { max-width: none; width: auto; white-space: nowrap; }
  /* The log in one column, top to bottom, so its order reads at a glance. (body.mission .log sets the screen size.) */
  .log, body.mission .log { font-size: 9.5px; columns: auto; }
  .log li { grid-template-columns: 34px 88px 1fr !important; gap: 4px !important; padding: 1.5px 0 !important; break-inside: avoid; background: none !important; box-shadow: none !important; animation: none !important; }
  .log .tbl a { color: inherit; text-decoration: none; }
}


/* ---- strategic map ----------------------------------------------------------- */
.map-card .card-head { margin-bottom: 8px; align-items: baseline; }
.map-card { --map-sea: #e3edf7; --map-land: #efede4; --map-coast: #a9b4bf; }
:root[data-theme="dark"] .map-card { --map-sea: #142030; --map-land: #262622; --map-coast: #3c4a58; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .map-card { --map-sea: #142030; --map-land: #262622; --map-coast: #3c4a58; }
}
.map-card svg.map { width: 100%; height: auto; display: block; background: var(--map-sea); border-radius: 6px; }
/* Zoom: the buttons sit at the right of the map's header; once zoomed, the map is dragged around (and on a touch
   screen the page doesn't scroll from it; unzoomed, a swipe still scrolls the page and a pinch zooms the map). */
.map-zoom { display: flex; gap: 4px; align-self: center; }
.map-card .card-head .sub { margin-left: auto; }
.map-zoom button { min-width: 28px; padding: 2px 8px; font-size: 13px; line-height: 1.4; }
.map-card svg.map { touch-action: pan-x pan-y; user-select: none; }
.map-card svg.map.zoomed { cursor: grab; touch-action: none; }
.map-card svg.map.zoomed.dragging { cursor: grabbing; }
.map .map-land { fill: var(--map-land); stroke: var(--map-coast); stroke-width: 1.5; stroke-linejoin: round; }
.map .map-border { fill: none; stroke: var(--map-coast); stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; opacity: 0.8; }
.map .map-ring { fill: none; stroke: var(--axis); stroke-width: 1.5; opacity: 0.75; }
.map .map-cover { fill: none; stroke: var(--axis); stroke-width: 5; }
.map .map-board-edge { fill: none; stroke: var(--ink-2); stroke-width: 1.2; stroke-dasharray: 4 6; opacity: 0.5; }
.map .map-world { opacity: 0.75; } /* off the board: the same map, a little quieter */
.map .map-zone1 { fill: var(--ring); stroke: var(--axis); stroke-width: 1.5; }
.map .map-zone { fill: var(--muted); font-size: 15px; font-weight: 600; }
.map .map-cover-label { fill: var(--muted); font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase; }
.map .map-country { fill: var(--muted); opacity: 0.55; font-size: 17px; font-weight: 700; letter-spacing: 0.12em; }
.map .map-base { fill: var(--ink); font-size: 15px; font-weight: 700; }
.map .map-base-sub { fill: var(--muted); font-size: 12px; }
.map .map-city circle { fill: var(--muted); }
.map .map-city text { fill: var(--ink-2); font-size: 13px; }
.map .map-city.candidate circle { fill: var(--series-1); }
.map .map-city.candidate text { fill: var(--ink); font-weight: 600; }
.map .map-city.target circle { fill: var(--series-1); }
.map .map-city.target .map-target-ring { fill: none; stroke: var(--series-1); stroke-width: 2.5; }
.map .map-city.target text { fill: var(--ink); font-weight: 700; font-size: 15px; }
.map .map-route-planned { stroke: var(--series-1); stroke-width: 2; stroke-dasharray: 6 6; opacity: 0.6; }
.map .map-route-flown { stroke: var(--series-1); stroke-width: 4; stroke-linecap: round; }
/* The B-17 on the map: ink with a thick outline in the paper colour, inside a locator ring that pulses. */
.map .map-b17 .body .airframe { fill: var(--ink); }
.map .map-b17 .halo .airframe { fill: var(--surface); stroke: var(--surface); stroke-width: 7; stroke-linejoin: round; }
.map .map-b17.straggler .body .airframe { fill: #c98500; }
.map .map-b17-ring { fill: color-mix(in srgb, var(--series-1) 16%, transparent); stroke: var(--series-1); stroke-width: 2; }
.map .map-b17-pulse { fill: none; stroke: var(--series-1); stroke-width: 1.5; transform-box: fill-box; transform-origin: center; animation: map-b17-pulse 2.2s ease-out infinite; }
.map .map-b17.straggler .map-b17-ring, .map .map-b17.straggler .map-b17-pulse { stroke: #c98500; }
.map .map-b17.down .map-b17-ring, .map .map-b17.down .map-b17-pulse { stroke: #d03b3b; }
.map .map-b17-name { font-size: 13px; font-weight: 700; fill: var(--ink); paint-order: stroke; stroke: var(--surface); stroke-width: 3.5px; stroke-linejoin: round; }
@keyframes map-b17-pulse { from { transform: scale(1); opacity: 0.8; } to { transform: scale(1.9); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .map .map-b17-pulse { animation: none; opacity: 0; } }
.map .map-down { fill: #d03b3b; font-size: 22px; font-weight: 700; }

/* ---- campaign ------------------------------------------------------------------- */
.start-choices { flex: 1 1 100%; display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px; }
.start-choice { border: 1px solid var(--grid); border-radius: 8px; padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
.start-choice h3 { margin: 0; color: var(--ink); font-size: 15px; }
.start-choice .sub { font-size: 12.5px; }

body:has(#campaign:not([hidden])) { max-width: 1680px; }
.campaign-head { display: flex; flex-wrap: wrap; gap: 16px 28px; align-items: center; margin-bottom: 16px; }
.tally { display: flex; gap: 10px; }
.tally-box { min-width: 92px; padding: 8px 12px; border-radius: 8px; background: var(--surface); border: 1px solid var(--ring); }
.tally-box .n { font-size: 26px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.1; }
.tally-box .label { font-size: 12px; color: var(--ink-2); }
.tally-box.good .n { color: var(--series-1); }
.tally-box.bad .n { color: #d03b3b; }
/* The tour: one pip per mission, coloured by its result once flown. */
.tour { display: grid; grid-template-columns: repeat(25, 14px); gap: 4px; }
.tour .pip { width: 14px; height: 14px; border-radius: 3px; border: 1.5px solid var(--axis); }
.tour .pip.good { background: var(--series-1); border-color: var(--series-1); }
.tour .pip.bad { background: #d03b3b; border-color: #d03b3b; }
.tour .pip.draw { background: var(--axis); }
@media (max-width: 700px) { .tour { grid-template-columns: repeat(13, 14px); } }

.campaign-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 16px; align-items: start; }
/* The next mission, the crew and the record take the full width; the B-17s and former crew share a row. */
.campaign-grid .campaign-next, .campaign-grid .campaign-crew, .campaign-grid .campaign-record { grid-column: 1 / -1; }
.campaign .status-table { font-size: 14px; }
.campaign .status-table td, .campaign .status-table th { padding: 6px 12px 6px 0; }
.campaign .crew-role { font-size: 12.5px; }
/* Full width: the name column fits its names, so the counts sit beside them and the last column takes the rest. */
.campaign-crew .career-table td:first-child, .campaign-crew .career-table th:first-child { width: 1%; white-space: nowrap; padding-right: 28px; }
.campaign-crew .career-table td:last-child { width: auto; }
@media (max-width: 900px) { .campaign-grid { grid-template-columns: minmax(0, 1fr); } }
/* The crew, B-17 and mission-record tables don't reflow at phone widths (too many columns to drop without
   losing data); scroll the table itself sideways rather than widening the whole page. */
@media (max-width: 700px) {
  .campaign .status-table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
}
.campaign-next h2 { margin-bottom: 4px; }
.campaign-next .sub { margin-bottom: 12px; }
.replacements { margin-bottom: 14px; display: flex; flex-direction: column; gap: 10px; }
.replacements input { padding: 5px 8px; font: inherit; color: var(--ink); background: var(--surface); border: 1px solid var(--axis); border-radius: 4px; }
.status-table td.num { font-variant-numeric: tabular-nums; }
/* Career tables: the name column takes the room; counts, the Ace badge and the rating stay narrow. */
.career-table td, .career-table th { vertical-align: middle; }
.career-table th.num, .career-table td.num { width: 4.5em; padding-right: 14px; text-align: center; }
.career-table td.badge { width: 3.5em; }
.career-table .chip.ace { margin-left: 0; }
.status-table td.losses { font-size: 12px; color: var(--ink-2); }
/* A flown mission in the record opens its report. */
.mission-row { cursor: pointer; }
.mission-row:hover td, .mission-row:focus-visible td { background: color-mix(in srgb, var(--ink) 7%, transparent); }
.mission-row:focus-visible { outline: 2px solid var(--axis); outline-offset: -2px; }
.status-table .damage-note { font-size: 11.5px; }
.plane-list { list-style: none; margin: 8px 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
/* A B-17's painted nose (b17-nose.js): the drawing in ink, her marks and name in paint. */
.b17-nose { display: block; width: 100%; max-width: 520px; height: auto; margin-bottom: 4px; }
.b17-nose .art { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.b17-nose .art.lines { stroke: var(--ink); stroke-width: 1; }
.b17-nose .art.details { stroke: var(--ink-2); stroke-width: 0.6; }
.b17-nose .art.fine { stroke: var(--muted); stroke-width: 0.3; }
.b17-nose .mark { fill: var(--ink); }
.b17-nose .more { fill: var(--ink); font-size: 8px; font-weight: 700; }
.b17-nose .name { fill: var(--ink); font-family: var(--stencil, sans-serif); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
.plane-list .chip { margin-left: 8px; }
.chip.good { border-color: var(--series-1); color: var(--ink); }
.chip.ace { border-color: #c98500; color: #c98500; font-weight: 700; margin-left: 6px; }
/* Crew experience (house rule): the campaign crew table's XP cell — the XP, then each ability side by side,
   wrapping only when the table is narrow. */
.xp-cell { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; }
.xp-line { display: flex; align-items: center; gap: 6px; min-width: 20.5em; } /* fits "Piloting +2" + its button, so the lines line up row to row */
.xp-cell > .chip { min-width: 4.5em; text-align: center; }
.xp-line .chip.ace { margin-left: 0; }
.xp-line button { white-space: nowrap; }
/* A checkbox and its label on one line (the same rule as proof.css). */
.check { display: inline-flex; gap: 6px; align-items: center; cursor: pointer; color: var(--ink-2); }

/* ---- dice distributions (dice-chart.js): the Dice page and a finished mission's dice ------------------------- */
/* The columns' blue was checked with the dataviz palette validator against the paper (#f4edd9) and the dark card
   (#26281b): lightness band, chroma and 3:1 contrast all pass. */
.dice-chart { --dice-bar: #30548f; margin: 0; }
:root[data-theme="dark"] .dice-chart { --dice-bar: #6a8ecc; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .dice-chart { --dice-bar: #6a8ecc; } }
.dice-plot { position: relative; }
.dice-svg { display: block; width: 100%; max-width: 760px; height: auto; overflow: visible; }
.dice-svg .bar { fill: var(--dice-bar); }
.dice-svg .fair { stroke: var(--ink); stroke-width: 2; stroke-linecap: round; }
.dice-svg .grid { stroke: var(--grid); stroke-width: 1; }
.dice-svg .axis { stroke: var(--axis); stroke-width: 1; }
.dice-svg .tick { fill: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.dice-svg .face { fill: var(--ink-2); font-size: 13px; font-weight: 600; }
.dice-svg .hit { fill: transparent; cursor: default; }
.dice-svg .total { transition: opacity 120ms; }
.dice-svg .total.dim { opacity: 0.45; }
.dice-tip { position: absolute; pointer-events: none; background: var(--surface); color: var(--ink); border: 1px solid var(--axis);
  border-radius: 6px; padding: 6px 9px; font-size: 12.5px; line-height: 1.35; white-space: nowrap; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18); z-index: 2; }
.dice-legend { display: flex; gap: 16px; font-size: 12.5px; color: var(--ink-2); margin-bottom: 6px; }
.dice-legend .key { display: inline-flex; align-items: center; gap: 6px; }
.dice-legend .swatch { display: inline-block; }
.dice-legend .bar-key { width: 10px; height: 12px; background: var(--dice-bar); border-radius: 3px 3px 0 0; }
.dice-legend .fair-key { width: 16px; height: 2px; background: var(--ink); border-radius: 1px; }
.dice-mean { font-size: 13px; color: var(--ink-2); margin: 6px 0; }
.dice-table summary { cursor: pointer; font-size: 12.5px; color: var(--ink-2); }
.dice-table table { max-width: 420px; margin-top: 6px; }
.dice-table .num { text-align: right; }

/* The Dice page's controls: segmented choices in one row above the chart. */
.dice-controls { display: flex; flex-wrap: wrap; gap: 12px 24px; align-items: center; margin-bottom: 14px; }
.segmented { display: inline-flex; border: 1px solid var(--axis); border-radius: 6px; overflow: hidden; }
.segmented button { border: 0; border-radius: 0; background: none; color: var(--ink-2); padding: 5px 12px; font: inherit; font-size: 13px; cursor: pointer; }
.segmented button + button { border-left: 1px solid var(--axis); }
.segmented button[aria-pressed="true"] { background: var(--ink); color: var(--surface); }
.dice-controls .label { font-size: 12.5px; color: var(--ink-2); margin-right: 8px; }

/* A finished mission's dice, in a modal. */
.dice-dialog { border: 1px solid var(--axis); border-radius: 8px; background: var(--surface); color: var(--ink); padding: 16px 20px; width: min(760px, calc(100vw - 32px)); }
.dice-dialog::backdrop { background: rgba(0, 0, 0, 0.45); }
.dice-dialog .dialog-head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.dice-dialog .dialog-head h2 { margin: 0; }
.dice-dialog .dialog-head .close { margin-left: auto; }
@media print { .dice-dialog { display: none !important; } }
