:root {
  /* Naval palette: deep-water page, sand/paper cards, steel-grey ships. */
  --ocean-deep: #0a1f33;
  --ocean: #103a5c;
  --sea: #3f8fc4;
  --sea-light: #62a8d6;
  --sea-dark: #0b3c5d;
  --card: #f5f9fc;
  --card-border: #c9dbe8;
  --ink: #142a3d;
  --ink-soft: #4a6378;
  --hull: #6b7a8f;
  --hull-edge: #3e4a5a;
  --deck: #9aa8b8;
  --detail: #2f3e4d;
  --hull-sunk: #4a3030;
  --deck-sunk: #6a5050;
  --hit: #d64545;
  --miss: #2f3e4d;
  --miss-marker: #cfd8e3;
  --sunk: #7b1e1e;
  --preview-ok: #4caf7d;
  --preview-bad: #e0534f;
  --hover: #8fc4e6;
  --accent: #f2b33d;
  --cell-gap: 2px;
  /* Largest a cell may get; reached on desktop, where the board is 362px as
     before. Below that the board is sized from its container rather than from
     the viewport, so a scrollbar appearing can never push a column out of
     view. */
  --cell-max: 34px;
  /* 10 cells + 9 inner gaps + the padding on both sides */
  --board-cap: calc(var(--cell-max) * 10 + var(--cell-gap) * 11);
  --cell-min: 14px;
  --board-min: calc(var(--cell-min) * 10 + var(--cell-gap) * 11);
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 12px;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  background:
    radial-gradient(ellipse at top, rgba(63, 143, 196, 0.25), transparent 60%),
    linear-gradient(180deg, var(--ocean) 0%, var(--ocean-deep) 100%);
  background-attachment: fixed;
  color: var(--ink);
}

header {
  text-align: center;
  color: #fff;
}

h1 {
  margin: 0 0 4px;
  font-size: 1.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

h2 {
  font-size: 0.8rem;
  margin: 0 0 8px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
}

main {
  max-width: 900px;
  margin: 0 auto;
}

.status {
  margin: 0 0 12px;
  font-weight: 600;
  min-height: 1.4em;
  color: #e6f1f9;
}

.hint {
  margin: 0 0 8px;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

.panel {
  background: var(--card);
  border: 1px solid var(--card-border);
  border-radius: 10px;
  padding: 12px;
  margin-bottom: 12px;
  box-shadow: 0 6px 18px rgba(4, 18, 32, 0.25);
}

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

/* Buttons: secondary by default (outlined steel), .primary for the one action
   that moves the game on, and unmistakably washed out when disabled. */
button {
  font: inherit;
  font-weight: 600;
  padding: 8px 12px;
  border: 1px solid var(--sea-dark);
  border-radius: 6px;
  background: #fff;
  color: var(--sea-dark);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, opacity 0.15s ease;
}

/* Board cells are buttons too, but their hover affordance is phase-driven and
   handled by the `.board.interactive` rules, so exclude them here. */
button:not(.cell):hover:not(:disabled) {
  background: var(--sea-dark);
  color: #fff;
}

button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  border-style: dashed;
}

button.primary {
  background: var(--accent);
  border-color: #c98c15;
  color: var(--ink);
}

button.primary:not(.cell):hover:not(:disabled) {
  background: #ffc75a;
  color: var(--ink);
}

.boards {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: center;
  margin-bottom: 12px;
}

.board-wrapper {
  flex: 1 1 320px;
  min-width: 0;
  background: var(--card);
  border: 1px solid var(--card-border);
  border-radius: 10px;
  padding: 12px;
  box-shadow: 0 6px 18px rgba(4, 18, 32, 0.25);
}

/* Ten equal tracks in a square box: the board fills the width its wrapper
   gives it (capped at the desktop size) and every track is an equal fraction
   of that, so the geometry depends only on the container - never on cell
   state, and never on the viewport width, which would include a scrollbar. */
.board {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  grid-template-rows: repeat(10, 1fr);
  gap: var(--cell-gap);
  width: 100%;
  aspect-ratio: 1;
  /* Lets the markers inside be sized as a fraction of the board (cqw). */
  container-type: size;
  max-width: var(--board-cap);
  margin: 0 auto;
  background: var(--sea-dark);
  padding: var(--cell-gap);
  border-radius: 6px;
  touch-action: manipulation;
}

.cell {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  /* Marker size follows the board, not the viewport: 6.6% of the board width
     is ~0.7 of a cell at every size. */
  font-size: 6.6cqw;
  /* Water: a faint highlight in the upper left reads as a ripple. */
  background:
    radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.18), transparent 55%),
    var(--sea);
  border: none;
  border-radius: 2px;
  padding: 0;
  overflow: hidden;
  color: #fff;
  cursor: default;
  transition: background 0.15s ease;
}

/* Markers are absolutely positioned so they can never influence layout. */
.cell::after {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  line-height: 1;
  font-size: 1em;
}

/* Hover affordance is opt-in per board: `interactive` is set only on the board
   the player can actually click during the current phase. */
.board.interactive .cell:not(.fired) {
  cursor: crosshair;
}

.board.interactive .cell:not(.fired):hover {
  background: var(--hover);
}

/* A placed ship under the pointer during placement: the click picks it up. */
.board.interactive .cell.ship:not(.fired) {
  cursor: grab;
}

/* Ship graphics: grid items spanning the ship's cells, drawn above the water
   but below fired cells so hit and miss markers stay on top. They never take
   pointer events; the cell buttons underneath do. */
.ship-graphic {
  z-index: 2;
  width: 100%;
  height: 100%;
  pointer-events: none;
  /* An off-board preview shows only the on-board part of the hull. */
  overflow: hidden;
}

.ship-graphic .hull {
  fill: var(--hull);
  stroke: var(--hull-edge);
  stroke-width: 4;
  stroke-linejoin: round;
}

.ship-graphic .deck {
  fill: var(--deck);
  stroke: var(--hull-edge);
  stroke-width: 3;
}

.ship-graphic .turret {
  fill: var(--deck);
  stroke: var(--hull-edge);
  stroke-width: 3;
}

.ship-graphic .detail {
  fill: var(--detail);
}

.ship-graphic .barrel,
.ship-graphic .mast {
  stroke: var(--detail);
  stroke-width: 6;
  stroke-linecap: round;
}

.ship-graphic .deck-line {
  stroke: #e3e9f0;
  stroke-width: 4;
}

/* Sunk: darkened, scorched hull so it reads as a wreck, not a healthy ship. */
.ship-graphic.sunk .hull {
  fill: var(--hull-sunk);
  stroke: #1f1414;
}

.ship-graphic.sunk .deck,
.ship-graphic.sunk .turret {
  fill: var(--deck-sunk);
  stroke: #1f1414;
}

.ship-graphic.sunk .detail,
.ship-graphic.sunk .barrel,
.ship-graphic.sunk .mast {
  fill: #1f1414;
  stroke: #1f1414;
}

.ship-graphic.sunk .deck-line {
  stroke: #7a6a6a;
}

/* Placement preview: the ship itself, tinted green when it fits and red
   when it would overlap or run off the board. */
.ship-graphic.preview {
  z-index: 4;
  opacity: 0.9;
}

.ship-graphic.preview-ok .hull,
.ship-graphic.preview-ok .deck,
.ship-graphic.preview-ok .turret {
  fill: var(--preview-ok);
  stroke: #1f6b47;
}

.ship-graphic.preview-bad .hull,
.ship-graphic.preview-bad .deck,
.ship-graphic.preview-bad .turret {
  fill: var(--preview-bad);
  stroke: #8a1f1f;
}

.ship-graphic.preview-pending .hull {
  stroke-width: 8;
}

/* Fired cells sit above the ship graphics; on a ship the fill is translucent
   so the hull shows through under the marker. */
.cell.fired {
  z-index: 3;
}

.cell.ship {
  background: var(--sea);
}

/* Miss: dark slate fill with a small round dot, so it differs from a hit in
   both colour and marker shape. */
.cell.miss {
  background: var(--miss);
}

.cell.miss::after {
  content: "";
  width: 30%;
  height: 30%;
  border-radius: 50%;
  background: var(--miss-marker);
}

.cell.hit {
  background: rgba(214, 69, 69, 0.3);
  box-shadow: inset 0 0 0 2px var(--hit);
}

.cell.hit::after {
  content: "✕";
  font-weight: 700;
  color: var(--hit);
  -webkit-text-stroke: 0.06em #fff;
  text-shadow: 0 0 3px rgba(0, 0, 0, 0.7);
}

.cell.sunk {
  background: rgba(40, 10, 10, 0.15);
  box-shadow: inset 0 0 0 2px var(--sunk);
}

.cell.sunk::after {
  content: "✕";
  font-weight: 700;
  color: #f0b3b3;
  text-shadow: 0 0 3px rgba(0, 0, 0, 0.9);
}

/* The placement preview must win over the hover highlight: the hovered cell is
   the anchor of the preview, and the `.board.interactive ... :hover` selectors
   above are more specific than a bare `.cell.preview-*`, so the preview is
   restated here at matching specificity (and later in the file). */
.cell.preview-ok,
.board.interactive .cell.preview-ok:not(.fired):hover {
  background: #b9e3cb;
}

.cell.preview-bad,
.board.interactive .cell.preview-bad:not(.fired):hover {
  background: #f3b8b6;
}

/* A tap-selected (armed) preview: outlined so it reads as a pending choice
   rather than a transient hover, since touch has no hover to fall back on. */
.cell.preview-pending {
  outline: 2px solid var(--ink);
  outline-offset: -2px;
}

.fleet-list {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  font-size: 0.8rem;
}

.fleet-list li {
  padding: 3px 8px;
  border-radius: 999px;
  background: #e3eef7;
  border: 1px solid var(--card-border);
  color: var(--ink);
}

.fleet-list li.sunk-ship {
  background: var(--sunk);
  border-color: var(--sunk);
  color: #fff;
  text-decoration: line-through;
}

/* Placement phase: only the player's board is in the document, with the fleet
   picker and the placement controls in a column beside it. `main.placement`
   is toggled by game.js together with the enemy board's presence. */
main.placement {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(240px, 300px);
  grid-template-rows: auto auto auto;
  grid-template-areas:
    "boards picker"
    "boards controls"
    "log    log";
  column-gap: 16px;
  align-items: start;
}

main.placement .boards {
  grid-area: boards;
}

#fleet-picker-panel {
  grid-area: picker;
}

#placement-panel {
  grid-area: controls;
}

main.placement > .footer {
  grid-area: log;
}

/* The picker already lists the fleet, so the status pills under the board
   only appear once the battle starts. */
main.placement .fleet-list {
  display: none;
}

/* Live readout of the selected ship and its orientation; stays visible in
   every layout, unlike the help text in .hint. */
.placement-state {
  margin: 0 0 6px;
  font-size: 0.9rem;
  min-height: 1.3em;
}

#placement-panel.no-selection #placement-detail {
  display: none;
}

.fleet-picker {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* One entry per ship: its name and a small silhouette of it. */
.fleet-picker .fleet-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 6px 10px;
  font-size: 0.85rem;
  font-weight: 500;
  text-align: left;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--card-border);
  border-radius: 6px;
}

.fleet-picker .fleet-option:hover:not(:disabled) {
  background: #e3eef7;
  color: var(--ink);
}

.fleet-picker .fleet-option.selected {
  background: #fff;
  border-color: var(--sea-dark);
  box-shadow: inset 0 0 0 2px var(--sea-dark);
  font-weight: 700;
}

.fleet-picker .fleet-option.placed {
  text-decoration: line-through;
  border-style: solid;
}

.fleet-silhouette {
  --silhouette-cell: 18px;
  flex: 0 0 auto;
  height: var(--silhouette-cell);
  width: calc(var(--ship-length) * var(--silhouette-cell));
}

.fleet-option.placed .fleet-silhouette {
  opacity: 0.6;
}

/* Start game is the one action that moves the game on, so it is the largest
   control on the placement screen. */
#start-game-btn {
  display: block;
  width: 100%;
  margin-top: 10px;
  padding: 12px;
  font-size: 1.05rem;
  font-weight: 700;
  box-shadow: 0 3px 0 #c98c15;
}

#start-game-btn:disabled {
  box-shadow: none;
}

/* Below the boards: the game controls (New game, with room beside it for a
   later Rules button) and the battle log side by side. */
.footer {
  display: flex;
  gap: 12px;
  align-items: stretch;
}

.game-controls {
  flex: 0 0 auto;
}

.log-panel {
  flex: 1 1 auto;
  min-width: 0;
}

.log {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 180px;
  overflow-y: auto;
  font-size: 0.9rem;
}

.log li {
  padding: 4px 8px;
  border-left: 3px solid var(--card-border);
  margin-bottom: 3px;
  background: #fff;
  border-radius: 0 4px 4px 0;
  line-height: 1.35;
}

.log li:first-child {
  border-left-color: var(--accent);
  font-weight: 600;
}

/* End-of-game overlay: the boards stay visible behind the translucent scrim. */
.overlay {
  position: fixed;
  inset: 0;
  /* Above the cells and ship graphics, which carry z-indexes of their own. */
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(6, 24, 41, 0.7);
  padding: 16px;
}

.overlay[hidden] {
  display: none;
}

.overlay-card {
  background: var(--card);
  border-radius: 12px;
  padding: 24px;
  text-align: center;
  max-width: 320px;
  border-top: 6px solid var(--accent);
  box-shadow: 0 10px 30px rgba(4, 18, 32, 0.5);
}

.overlay-card h2 {
  font-size: 1.5rem;
  margin-bottom: 8px;
  color: var(--ink);
  letter-spacing: 0.04em;
}

.overlay-card p {
  margin: 0 0 16px;
  color: var(--ink-soft);
}

.overlay-card button {
  background: var(--sea-dark);
  color: #fff;
}

/* Rules dialog: sits above the end-of-game overlay in case the game ends
   while it is open, and scrolls itself when taller than the viewport. */
.rules-overlay {
  z-index: 101;
  align-items: flex-start;
  overflow-y: auto;
}

.rules-card {
  position: relative;
  text-align: left;
  max-width: 480px;
  width: 100%;
  margin: auto 0;
  padding: 20px 24px 22px;
  font-size: 0.95rem;
  line-height: 1.45;
}

.rules-card h2 {
  margin-right: 36px;
}

.rules-card h3 {
  margin: 16px 0 4px;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--sea-dark);
}

.rules-card p {
  margin: 0;
  color: var(--ink);
}

.rules-card ul {
  margin: 0;
  padding-left: 20px;
}

.rules-card li + li {
  margin-top: 4px;
}

.rules-card .rules-fleet {
  margin-top: 8px;
  padding: 6px 10px;
  border-radius: 6px;
  background: #e3eef7;
  color: var(--ink-soft);
  font-size: 0.85rem;
}

/* Sticky so the X stays on screen while a tall dialog is scrolled. */
.rules-card .close-btn {
  position: sticky;
  top: 0;
  float: right;
  margin: -8px -12px 0 0;
  width: 32px;
  height: 32px;
  padding: 0;
  line-height: 1;
  font-size: 1.3rem;
  border-radius: 50%;
  background: #fff;
  color: var(--sea-dark);
}

/* Inline swatches matching the board markers. */
.rules-card .legend {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.1em;
  height: 1.1em;
  vertical-align: -0.15em;
  border-radius: 3px;
  font-size: 0.85em;
  font-weight: 700;
  line-height: 1;
}

.rules-card .legend-hit {
  background: rgba(214, 69, 69, 0.3);
  box-shadow: inset 0 0 0 2px var(--hit);
  color: var(--hit);
}

.rules-card .legend-miss {
  background: var(--miss);
  position: relative;
}

.rules-card .legend-miss::after {
  content: "";
  width: 30%;
  height: 30%;
  border-radius: 50%;
  background: var(--miss-marker);
}

.rules-card .legend-sunk {
  background: var(--hull-sunk);
  box-shadow: inset 0 0 0 2px var(--sunk);
  color: #f0b3b3;
}

/* Compact viewports - phones in either orientation. The page becomes a column
   that fills the viewport, which gives the row holding the boards a definite
   height; .board-area is a size container inside it, so each board can be the
   smaller of the space available across (100cqw) and down (100cqh). Sizing
   against one axis only is what made the board overflow the other one. */
@media (max-width: 700px), (max-height: 600px) and (orientation: landscape) {
  body {
    display: flex;
    flex-direction: column;
    min-height: 100svh;
  }

  main {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
  }

  .boards {
    flex: 1 1 auto;
    min-height: 0;
    flex-wrap: nowrap;
    align-items: stretch;
  }

  .board-wrapper {
    display: flex;
    flex-direction: column;
    flex: 1 1 0;
    min-height: 0;
  }

  .board-area {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    justify-content: center;
    container-type: size;
  }

  .board {
    width: min(100cqw, 100cqh, var(--board-cap));
    height: min(100cqw, 100cqh, var(--board-cap));
    max-width: none;
    aspect-ratio: auto;
  }

  .panel,
  .board-wrapper {
    box-shadow: none;
  }
}

/* Phone layout: both boards must be on screen at once during the firing
   phase, so they stay side by side and everything around them is compressed
   rather than stacked. */
@media (max-width: 700px) {
  body {
    padding: 8px;
  }

  h1 {
    font-size: 1.2rem;
  }

  .status {
    margin-bottom: 8px;
    font-size: 0.9rem;
  }

  .boards {
    flex-wrap: nowrap;
    gap: 8px;
    margin-bottom: 8px;
  }

  .board-wrapper {
    flex: 1 1 0;
    padding: 6px;
  }

  .board-wrapper h2 {
    font-size: 0.7rem;
    margin-bottom: 4px;
  }

  .panel {
    padding: 8px;
    margin-bottom: 8px;
  }

  .controls button {
    padding: 8px 10px;
    font-size: 0.85rem;
  }

  .fleet-list {
    margin-top: 6px;
    gap: 3px;
    font-size: 0.65rem;
  }

  .fleet-list li {
    padding: 2px 5px;
  }

  .footer {
    gap: 8px;
  }

  .log {
    max-height: 96px;
    font-size: 0.8rem;
  }

  .log li {
    padding: 2px 6px;
    margin-bottom: 2px;
  }

  .fleet-picker {
    gap: 4px;
  }

  /* Narrow column beside the board: name above the silhouette. */
  .fleet-picker .fleet-option {
    flex-direction: column;
    align-items: flex-start;
    gap: 3px;
    padding: 4px 6px;
    font-size: 0.7rem;
  }

  .fleet-silhouette {
    --silhouette-cell: 11px;
  }

  #start-game-btn {
    margin-top: 8px;
    padding: 10px;
    font-size: 0.95rem;
  }
}

/* Portrait phones during placement: the board takes the width the picker
   leaves it (height is plentiful here), the controls go underneath. */
@media (max-width: 700px) and (orientation: portrait) {
  main.placement {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "boards   picker"
      "controls controls"
      "log      log";
    column-gap: 8px;
    align-items: stretch;
  }

  main.placement .board-area {
    container-type: inline-size;
    /* Stretching would override the aspect ratio and make the cells tall. */
    align-items: flex-start;
  }

  main.placement .board {
    width: min(100cqw, var(--board-cap), 40svh);
    height: auto;
    aspect-ratio: 1;
  }
}

/* Very narrow phones (320px and down): trim the chrome around the grids
   further so the cells keep some size instead of bottoming out on the floor
   of the clamp. */
@media (max-width: 360px) {
  body {
    padding: 4px;
  }

  .boards {
    gap: 6px;
  }

  .board-wrapper {
    padding: 4px;
  }

  .fleet-list {
    font-size: 0.6rem;
  }

  h1 {
    font-size: 1.05rem;
  }

  .hint {
    font-size: 0.8rem;
    margin-bottom: 6px;
  }

  .panel {
    margin-bottom: 6px;
  }

  .controls {
    gap: 6px;
  }

  .controls button {
    padding: 6px 8px;
    font-size: 0.8rem;
  }

  .log {
    max-height: 60px;
  }
}

/* A board must stay tappable even when the height available collapses, so in
   landscape it stops shrinking at --cell-min and the placement screen scrolls
   instead - the same trade already accepted at 320px portrait. The floor is a
   min-height on the container (the page then grows) rather than a min on the
   board, and it is gated on a width that can fit two floored boards, because
   flooring against width is what caused the 320px overflow in R18. */
@media (min-width: 420px) and (max-height: 600px) and (orientation: landscape) {
  .board-wrapper {
    min-height: calc(var(--board-min) + 3.5rem);
  }
}

/* Landscape phones: height is the scarce dimension, so the chrome above and
   below the boards is trimmed hard to leave the grids as much of it as
   possible. */
@media (max-height: 600px) and (orientation: landscape) {
  body {
    padding: 6px;
  }

  /* Title and status share one line, and the battle log sits next to the New
     game button, so the vertical chrome is roughly two lines instead of six. */
  header {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 10px;
    margin-bottom: 6px;
  }

  h1 {
    font-size: 1rem;
    margin: 0;
  }

  .status {
    margin: 0;
    font-size: 0.85rem;
  }

  .footer {
    gap: 6px;
  }

  .footer .panel {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .footer h2 {
    margin: 0;
    font-size: 0.65rem;
  }

  .log-panel .log {
    flex: 1 1 auto;
  }

  .hint {
    font-size: 0.8rem;
    margin-bottom: 6px;
  }

  .panel {
    padding: 6px;
    margin-bottom: 6px;
  }

  .boards {
    gap: 8px;
    margin-bottom: 6px;
  }

  .board-wrapper {
    padding: 6px;
  }

  .board-wrapper h2 {
    font-size: 0.7rem;
    margin-bottom: 4px;
  }

  .controls button {
    padding: 6px 10px;
    font-size: 0.8rem;
  }

  .fleet-list {
    margin-top: 4px;
    gap: 3px;
    font-size: 0.6rem;
  }

  .fleet-list li {
    padding: 2px 5px;
  }

  .log {
    max-height: 44px;
    font-size: 0.75rem;
  }

  .log li {
    padding: 1px 6px;
    margin-bottom: 2px;
  }

  /* Placement in landscape: the picker and the controls each take a column
     beside the board, so the scarce vertical budget goes to the grid instead
     of a stack of buttons. */
  main.placement {
    grid-template-columns: minmax(0, 1fr) auto minmax(120px, 26%);
    grid-template-rows: minmax(0, 1fr) auto;
    grid-template-areas:
      "boards picker controls"
      "log    log    log";
    column-gap: 8px;
    align-items: stretch;
  }

  #fleet-picker-panel,
  #placement-panel {
    margin-bottom: 6px;
    min-height: 0;
    overflow-y: auto;
  }

  #fleet-picker-panel h2,
  #placement-panel h2 {
    font-size: 0.7rem;
    margin-bottom: 4px;
  }

  #placement-panel .controls {
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
  }

  /* The status line repeats what the hint says; the buttons need the room.
     The live state line stays, just smaller. */
  #placement-panel .hint {
    display: none;
  }

  #placement-panel .placement-state {
    font-size: 0.7rem;
    margin-bottom: 4px;
  }

  .fleet-picker {
    gap: 4px;
  }

  .fleet-picker .fleet-option {
    flex-direction: column;
    align-items: flex-start;
    gap: 3px;
    padding: 4px 6px;
    font-size: 0.7rem;
  }

  .fleet-silhouette {
    --silhouette-cell: 9px;
  }

  #start-game-btn {
    margin-top: 6px;
    padding: 8px;
    font-size: 0.9rem;
  }
}

/* Very short landscape (568x320 and similar): with the boards floored at
   --cell-min, the firing phase only fits if the log and the labels around the
   grids give up their remaining slack - per the rule that the chrome shrinks
   before the boards do. */
@media (max-height: 360px) and (orientation: landscape) {
  .footer .panel {
    padding: 4px 6px;
  }

  .log {
    max-height: 22px;
  }

  .board-wrapper h2 {
    font-size: 0.65rem;
    margin-bottom: 2px;
  }

  .fleet-list {
    margin-top: 2px;
    font-size: 0.55rem;
  }

  #placement-panel .controls button {
    padding: 4px 8px;
    font-size: 0.75rem;
  }
}
