/* Permanent game-presentation contract. Reference: v512 at 1536 × 752 CSS px.
   Scale lengths, never ancestors: fixed overlays and DOMRect animations must
   continue to share the browser's real viewport coordinate system. */
.status-card.is-card-pulsing { animation: credit-pulse .6s ease-out both; }
:root.is-game-layout {
  font-size: var(--game-rem);
  --layout-vw: var(--game-vw);
  --layout-vh: var(--game-vh);
  --layout-svh: var(--game-vh);
  --layout-dvh: var(--game-vh);
}
.is-game-layout body { min-width: 0; overflow: hidden; }
.is-game-layout .game-screen { width: 100%; height: 100dvh; min-height: 0; }
.is-game-layout .game-stage { display: contents; }
.is-game-layout .game-screen .game-layout {
  grid-template-columns: var(--game-panel) minmax(0, 1fr) var(--game-panel);
  height: 100%;
}
.is-game-layout .game-screen .space-panel {
  padding: .9rem;
}
.is-game-layout .game-screen .roll-panel {
  padding: 1.8rem 1.344rem;
}
/* Give the extra viewport height to the three gaps between the four hand
   rows. Card slots keep their reference height and bottom-edge clearance. */
.is-game-layout .current-card-grid {
  row-gap: calc(.9rem + var(--game-band) * 2 / 3);
}
.is-game-layout .board-area { background: #076e9a; }
.is-game-layout .board-shell { width: var(--game-board); height: var(--game-board); }
.is-game-layout .captain-detail-panel { padding-block: 1.1rem; }
.is-game-layout .captain-detail-close { top: 2.2rem; }

/* All three transaction overlays stretch their bars between the screen-edge
   rails. The bars hug the viewport top/bottom, independent of board bands. */
.is-game-layout :is(.market-event, .hand-limit-panel, .debt-sale-panel) {
  grid-template-columns: var(--game-panel) minmax(0, 1fr) var(--game-board) minmax(0, 1fr) var(--game-panel);
  grid-template-rows: 3.196rem minmax(0, 1fr) 3.478rem;
}
.is-game-layout :is(.market-side, .hand-limit-content, .debt-sale-content) {
  grid-row: 1 / -1;
  padding-block: calc(.72rem + var(--game-band));
}
.is-game-layout .market-side-left { grid-column: 1; }
.is-game-layout :is(.market-side-right, .hand-limit-content, .debt-sale-content) { grid-column: 5; }
.is-game-layout :is(.market-topbar, .hand-limit-topbar, .debt-sale-topbar) { grid-column: 2 / 5; grid-row: 1; }
.is-game-layout :is(.market-bottombar, .hand-limit-bottombar, .debt-sale-bottombar) { grid-column: 2 / 5; grid-row: 3; }
.is-game-layout .market-deal-panel { padding-block: calc(.72rem + var(--game-band)); }

/* Move only MARKET's captain status, including its dealing-animation copy.
   Keep its flow space so BUY/SELL headings and all offers remain in place. */
.is-game-layout .market-side-left .market-captain-status {
  position: relative;
  top: calc(-1 * var(--game-band));
}

/* These selling rails use the screen edges. Preserve the reference row
   heights and their existing offsets below the timer/controls. */
.is-game-layout :is(.hand-limit-content, .debt-sale-content) {
  padding-block: .72rem;
}
.is-game-layout #hand-limit-card-grid {
  row-gap: calc(.9rem + var(--game-band) * 2 / 3);
}
/* The two ship-sale buttons form the fifth and final debt-sale row. Share
   extra height equally across all FOUR gaps, including the gap above ships,
   while retaining the baseline card geometry and ship bottom clearance.
   Rebalance the existing 2.7rem gap budget (3 x .77rem + .39rem) to account
   for card/price row offsets and make the visible gaps equal as well. */
.is-game-layout .debt-sale-content {
  --debt-extra-row-gap: calc(var(--game-band) / 2);
}
.is-game-layout #debt-sale-card-grid {
  row-gap: calc(.77rem + var(--debt-extra-row-gap));
}
.is-game-layout .debt-sale-ships {
  margin-top: calc(.39rem + var(--debt-extra-row-gap));
}

/* Equal outer tracks keep MARKET itself at the midpoint; its eye occupies
   the start of the right track instead of shifting the title off-center. */
.is-game-layout .market-topbar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
}
.is-game-layout .market-topbar h2 { grid-column: 2; grid-row: 1; justify-self: center; }
.is-game-layout .market-topbar .market-eye-toggle { grid-column: 3; grid-row: 1; justify-self: start; }
.is-game-layout .market-balance {
  top: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* The action/exit pair stays centered even when BUY and SELL totals differ.
   Hand Limit already uses the same equal-outer-track arrangement. */
.is-game-layout .market-bottombar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto minmax(0, 1fr);
}
.is-game-layout .market-bottombar .market-total:first-child { justify-self: start; margin: 0 0 0 .6rem; }
.is-game-layout .market-bottombar .market-total:nth-of-type(2) { justify-self: end; margin: 0 .6rem 0 0; }

/* The timer and four controls retain their existing offsets from the SCREEN
   top, not from the board. Their rem sizes follow the same uniform scale. */
.is-game-layout .turn-timer { top: .99rem; }
.is-game-layout .game-audio-controls { top: .72rem; }
.is-game-layout :is(.ship-placement-toggle, .game-control-button, .coin-placement-control, .bottom-next-players) {
  bottom: calc(1rem + var(--game-band));
}
.is-game-layout .game-screen.is-developer-controls .test-die-faces {
  bottom: calc(1rem + var(--game-band));
}

/* Geometry layers must cover the real viewport, not the reference rectangle. */
.is-game-layout .market-locate-line { width: 100vw; height: 100dvh; }
.is-game-layout .market-locate-line line { stroke-width: .1875rem; }
.is-game-layout .money-float-layer { inset: 0; }
.is-game-layout .point-banner {
  width: 100%;
  left: 0;
  right: 0;
}
/* All central banner copy uses the unembellished Caribbean face, including
   the <strong> Battleship title. Avoid synthesized bold on mobile browsers. */
.point-banner,
.point-banner :is(span, strong, b, button) {
  font-family: "Caribbean", Georgia, serif;
  font-weight: 400;
  font-style: normal;
  font-synthesis: none;
  text-shadow: none;
  -webkit-text-stroke: 0;
}
/* Reveal at the final text scale. Horizontal scaling can stretch a cached
   text layer on Safari; clipping alone retains the existing reveal/timing. */
@keyframes point-banner {
  0%, 100% { opacity: 0; clip-path: inset(0 50% 0 50%); }
  14%, 77% { opacity: 1; clip-path: inset(0); }
}
@keyframes opening-turn-banner {
  0%, 100% { opacity: 0; clip-path: inset(0 50% 0 50%); }
  14%, 86% { opacity: 1; clip-path: inset(0); }
}
@keyframes sale-banner-in {
  from { opacity: 0; clip-path: inset(0 50% 0 50%); }
  to { opacity: 1; clip-path: inset(0); }
}
.is-game-layout :is(.admin-dialog, .admin-inventory-dialog, .game-control-dialog) {
  width: var(--game-reference-width);
  height: var(--game-board);
  inset: 0;
  margin: auto;
}
.is-game-layout :is(.rulebook-close, .rulebook-zoom-controls) { position: absolute; }
.is-game-layout dialog { max-height: calc(100dvh - 2rem); }
.is-game-layout :is(.rulebook-dialog, .admin-dialog, .admin-inventory-dialog, .game-control-dialog, .victory-dialog) { max-height: none; }

/* The Rulebook is the user's full-window reading surface, in every screen. */
.rulebook-dialog {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100dvh;
  max-width: none;
  max-height: none;
  margin: 0;
  border-radius: 0;
}
.rulebook-layout { height: calc(100% - 4.6rem); min-height: 0; }
.rulebook-nav, .rulebook-viewport { min-height: 0; }
.rulebook-viewport { overflow: auto; }
.rulebook-viewport img {
  /* All 34 source pages are 816 x 1158. Width and auto height preserve ratio. */
  width: calc(var(--rulebook-fit-height) * var(--rulebook-zoom) * 816 / 1158);
  max-width: none;
  height: auto;
  flex: none;
  align-self: flex-start;
  margin-inline: auto;
}
/* Legacy mobile rules must not reflow the locked game composition. */
.is-game-layout .battleship-sides { gap: .7rem; }
.is-game-layout .battleship-fleet img { width: 4.8rem; }
.is-game-layout .battleship-winner .battleship-fleet img { width: 6.2rem; }
