:root {
  --text-md: 12pt;
  --text-sm: 10pt;
  /* Primary buttons: light blue to light teal-chartreuse. */
  --button-start: #bfe1f8;
  --button-end: #c6f3d6;
  --button-start-hover: #a7d4f3;
  --button-end-hover: #b0eac4;
  --button-ink: #16344a;
  --button-border: rgb(52 118 150 / 35%);
  /* Playback and background selection controls. */
  --header-bar-height: 40px;
  --header-bar-radius: 14px;
  --header-bar-bg: rgb(247 249 235 / 90%);
  /* Page margin, widened to clear the notch on landscape phones. */
  --page-gutter: max(24px, env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
  color-scheme: light;
  font-family: "Avenir Next", Avenir, "Segoe UI", sans-serif;
  font-size: var(--text-md);
  background: #edf1de;
  color: #24322b;
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  /* Keep iOS from enlarging text when a phone turns to landscape. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
button, input, select { font: inherit; }
button, a, input, select { -webkit-tap-highlight-color: transparent; }
button { cursor: pointer; touch-action: manipulation; }
:is(a, button, input, select):focus-visible { outline: 2px solid #3b6552; outline-offset: 3px; }

/* The synchronous preference bootstrap sets the holding colour before CSS is
   parsed and keeps the body out of the first paint. The chosen engine reveals
   the complete page only after it has rendered its first frame. */
html.is-background-booting[data-background-choice="compass-topography"] { background: #8bdcd2; }
html.is-background-booting[data-background-choice="nautical"] { background: #d9edf0; }
html.is-background-booting[data-background-choice="desert-terrain"] { background: #f0e5d0; }
html.is-background-booting body { visibility: hidden; }

html, body {
  width: 100%;
  min-height: 100%;
  margin: 0;
  overflow: hidden;
}

body {
  min-height: 100vh;
  min-height: 100svh;
}

.site-header {
  position: fixed;
  z-index: 10;
  inset: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: max(20px, env(safe-area-inset-top)) max(24px, env(safe-area-inset-right)) 0 max(24px, env(safe-area-inset-left));
  pointer-events: none;
}

.header-center {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  margin-inline: auto;
  gap: inherit;
}

.background-options {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.background-picker {
  display: flex;
  align-items: center;
  gap: 8px;
  height: var(--header-bar-height);
  padding: 0 12px;
  border-radius: var(--header-bar-radius);
  background: var(--header-bar-bg);
  font-size: var(--text-sm);
  pointer-events: auto;
}
.background-picker select {
  min-height: 32px;
  max-width: 100%;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: inherit;
  cursor: pointer;
}
/* iOS zooms into a focused form field whose text is smaller than 16px. */
@supports (-webkit-touch-callout: none) {
  .background-picker select { font-size: var(--text-md); }
}
.animation-scene,
#topography-scene {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.animation-scene {
  isolation: isolate;
  background:
    radial-gradient(ellipse at 15% 20%, #f6f7e9, transparent 65%),
    linear-gradient(140deg, #edf1de, #c8dcc8);
}

/* Do not paint the fallback scene while the saved background is starting. */
.animation-scene:not(.is-background-ready) { opacity: 0; }

/* Camera translation moves chart, water and hull together. Touch controls
   stay in the stationary scene so sailing never drags the joystick around. */
.chart-world { position: absolute; inset: 0; }
body.has-water-surface .animation-scene { background: #102a38; }
#topography-scene { position: absolute; z-index: 0; }

.compass-topography-sheet,
.special-animation-nautical-sheet,
.special-animation-topo-sheet {
  position: absolute;
  inset: 0;
  overflow: hidden;
  contain: strict;
}

.compass-topography-stage-layer,
.compass-topography-paper,
.compass-topography-ink,
.special-animation-topo-stage,
.special-animation-topo-paper,
.special-animation-topo-ink,
.special-animation-nautical-chart {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* Phone toolbars change the visible height as they slide in and out, and the
   engines are not rebuilt for that. The map is sized to
   the tallest viewport instead (100vh on phones), so it keeps covering the
   screen; any part behind a toolbar is simply out of view. */
#topography-scene { bottom: auto; height: 100vh; }
.compass-topography-sheet { width: 100% !important; height: 100% !important; }
/* Scale rather than stretch whenever a drawing and its box differ in shape. */
.compass-topography-paper,
.compass-topography-ink,
.special-animation-topo-ink { object-fit: cover; }
/* Fill either orientation without distorting the terrain. Boat camera motion
   reveals the uniformly scaled overflow while keeping the viewport covered. */
#topography-scene[data-background="nautical"] { bottom: 0; height: auto; }
.special-animation-nautical-chart { object-fit: cover; }
.transport {
  --transport-button-width: 28px;
  --transport-padding-x: 6px;
  --transport-gap: 6px;
  position: relative;
  flex-shrink: 0;
  color: #24322b;
  pointer-events: none;
  font-size: var(--text-sm);
}
.transport-controls {
  display: flex;
  align-items: center;
  gap: var(--transport-gap);
  height: var(--header-bar-height);
  padding: 0 var(--transport-padding-x);
  border-radius: var(--header-bar-radius);
  background: var(--header-bar-bg);
  pointer-events: auto;
  opacity: 1;
  visibility: visible;
  transition: opacity 220ms ease, visibility 0s;
}
/* Playback speed slider. */
.transport-speed { display: flex; align-items: center; flex-shrink: 0; gap: 7px; width: 111px; padding-left: 6px; }
.transport-speed input {
  width: 56px;
  min-width: 0;
  height: 16px;
  flex: 1;
  margin: 0;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  cursor: pointer;
}
/* Match the slider track and thumb to the playback button. */
.transport-speed input::-webkit-slider-runnable-track {
  height: 6px;
  border: 1px solid var(--button-border);
  border-radius: 999px;
  background: linear-gradient(90deg, var(--button-start), var(--button-end));
}
.transport-speed input::-moz-range-track {
  height: 6px;
  border: 1px solid var(--button-border);
  border-radius: 999px;
  background: linear-gradient(90deg, var(--button-start), var(--button-end));
}
.transport-speed input::-webkit-slider-thumb {
  width: 14px;
  height: 14px;
  margin-top: -5px;
  border: 1px solid rgb(52 118 150 / 65%);
  border-radius: 50%;
  background: linear-gradient(135deg, var(--button-start-hover), var(--button-end-hover));
  -webkit-appearance: none;
  appearance: none;
}
.transport-speed input::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border: 1px solid rgb(52 118 150 / 65%);
  border-radius: 50%;
  background: linear-gradient(135deg, var(--button-start-hover), var(--button-end-hover));
}
.transport-buttons { display: flex; align-items: center; }
.icon-button {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: var(--transport-button-width, 28px);
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 7px;
  color: inherit;
  background: transparent;
}
.icon-button:hover:not(:disabled) { background: rgb(52 118 150 / 14%); }
.transport button:focus { outline: none; }
.transport button:focus-visible { color: #17668e; }
.icon-button:disabled { opacity: .3; cursor: default; }
/* A 14.5px box with a 2.4-unit stroke draws each glyph about 9.9px tall, the
   cap height of the 10pt nav text. */
.icon-button svg { width: 14.5px; height: 14.5px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
#background-play { background: linear-gradient(135deg, var(--button-start), var(--button-end)); }
#background-play[aria-pressed="true"] .play-icon,
#background-play[aria-pressed="false"] .pause-icon { display: none; }

.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* Chart, wake and boat move together inside the same pinch-zoomed scene. */
.water-surface { pointer-events: none; }
.boat-layer { position: absolute; inset: 0; z-index: 2; overflow: hidden; pointer-events: auto; touch-action: pinch-zoom; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.boat-player { position: absolute; left: 0; top: 0; width: 0; height: 0; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.boat-touch-target { position: absolute; left: 0; top: 0; width: 56px; height: 56px; transform: translate(-50%, -50%); margin: 0; padding: 0; border: 0; border-radius: 50%; background: transparent; pointer-events: auto; touch-action: pinch-zoom; }
.boat-joystick { position: absolute; width: 128px; height: 128px; border: 1px solid rgb(231 251 246 / 38%); border-radius: 50%; background: rgb(213 244 236 / 7%); box-shadow: 0 0 0 1px rgb(7 42 57 / 13%), inset 0 0 24px rgb(11 41 53 / 8%); opacity: .62; pointer-events: none; transition: opacity 160ms ease; }
.boat-joystick-thumb { position: absolute; left: calc(50% - 16px); top: calc(50% - 16px); width: 32px; height: 32px; border: 1px solid rgb(232 255 249 / 72%); border-radius: 50%; background: rgb(221 250 239 / 26%); box-shadow: 0 1px 5px rgb(6 33 47 / 24%); }
.boat-throttle { position: absolute; width: 56px; height: 160px; border: 1px solid rgb(231 251 246 / 38%); border-radius: 28px; background: rgb(213 244 236 / 7%); box-shadow: 0 0 0 1px rgb(7 42 57 / 13%), inset 0 0 24px rgb(11 41 53 / 8%); opacity: .62; pointer-events: none; transition: opacity 160ms ease; }
.boat-throttle::before { content: ""; position: absolute; top: 16px; bottom: 16px; left: 50%; width: 1px; background: rgb(231 251 246 / 20%); }
.boat-throttle::after { content: ""; position: absolute; top: 50%; left: 5px; right: 5px; height: 1px; background: rgb(231 251 246 / 24%); }
.boat-throttle-thumb { position: absolute; left: calc(50% - 16px); top: calc(50% - 16px); width: 32px; height: 32px; border: 1px solid rgb(232 255 249 / 72%); border-radius: 50%; background: rgb(221 250 239 / 26%); box-shadow: 0 1px 5px rgb(6 33 47 / 24%); }
.boat-joystick.is-active,
.boat-throttle.is-active { opacity: 1; }
.mobile-control { transition: opacity 250ms ease; }
.mobile-control:not(.is-visible) { opacity: 0; pointer-events: none; }
.game-pause-indicator {
  position: absolute;
  z-index: 4;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 1px solid rgb(231 251 246 / 45%);
  border-radius: 50%;
  background: rgb(12 43 56 / 30%);
  pointer-events: none;
}
.pause-bars { width: 18px; height: 22px; border-inline: 6px solid rgb(232 255 249 / 85%); }
/* This horizontal chart control belongs to the stationary UI, not the boat. */
.chart-speed-control {
  --chart-safe-bottom: env(safe-area-inset-bottom, 0px);
  position: absolute;
  z-index: 3;
  transform-origin: center bottom;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  color: #e6f8f3;
  text-shadow: 0 1px 3px #123b49;
  font-size: 11px;
  line-height: 14px;
  text-align: center;
  pointer-events: auto;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
.chart-speed-control input {
  width: 100%;
  height: 44px;
  margin: 0;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  touch-action: none;
}
.chart-speed-control input::-webkit-slider-runnable-track {
  height: 16px;
  border: 1px solid rgb(231 251 246 / 38%);
  border-radius: 999px;
  background: rgb(213 244 236 / 10%);
}
.chart-speed-control input::-moz-range-track {
  height: 14px;
  border: 1px solid rgb(231 251 246 / 38%);
  border-radius: 999px;
  background: rgb(213 244 236 / 10%);
}
.chart-speed-control input::-webkit-slider-thumb {
  width: 32px;
  height: 32px;
  margin-top: -9px;
  border: 1px solid rgb(232 255 249 / 72%);
  border-radius: 50%;
  background: rgb(221 250 239 / 35%);
  box-shadow: 0 1px 5px rgb(6 33 47 / 24%);
  appearance: none;
  -webkit-appearance: none;
}
.chart-speed-control input::-moz-range-thumb {
  width: 30px;
  height: 30px;
  border: 1px solid rgb(232 255 249 / 72%);
  border-radius: 50%;
  background: rgb(221 250 239 / 35%);
  box-shadow: 0 1px 5px rgb(6 33 47 / 24%);
}
@media (any-pointer: coarse) {
  .boat-layer .boat-notice { bottom: auto; top: max(20px, env(safe-area-inset-top)); }
}
.boat-sprite { position: absolute; width: 12px; height: 26px; filter: drop-shadow(0 1px 1px rgb(0 25 39 / 55%)); }
.boat-sprite img { position: absolute; inset: 0; width: 100%; height: 100%; }
.boat-bow { clip-path: inset(0 0 50% 0); }
.boat-stern { clip-path: inset(50% 0 0 0); }
.is-wrecked .boat-bow { transform: translate(-2px, -2px) rotate(-14deg); opacity: .65; }
.is-wrecked .boat-stern { transform: translate(2px, 2px) rotate(18deg); opacity: .65; }
.boat-notice { position: absolute; bottom: max(28px, env(safe-area-inset-bottom)); left: 50%; transform: translateX(-50%); width: max-content; max-width: calc(100% - 32px); margin: 0; padding: 9px 15px; border-radius: 9px; background: rgb(238 248 246 / 94%); color: #163b49; font-size: 13px; text-align: center; box-shadow: 0 2px 12px rgb(10 40 52 / 15%); }

.site-header { justify-content: center; }
.header-center { flex-wrap: wrap; max-width: 100%; }
@media (max-width: 1400px) {
  .transport-speed { width: 75px; }
  .speed-label { display: none; }
}
@media (max-width: 1560px) {
  .background-picker { padding-inline: 8px; }
  .background-picker > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
}
@media (max-width: 700px) {
  .site-header { padding: max(12px, env(safe-area-inset-top)) max(8px, env(safe-area-inset-right)) 0 max(8px, env(safe-area-inset-left)); gap: 8px 6px; }
  .background-picker { padding-inline: 4px; }
  .transport { --transport-padding-x: 2px; --transport-gap: 2px; }
  .transport-speed { width: 69px; }
}
@media (pointer: coarse) {
  .icon-button { position: relative; }
  .icon-button::after { content: ""; position: absolute; inset: -8px 0; }
  .transport-speed input { height: 32px; }
  .background-picker select { min-height: 36px; }
}
@media (max-height: 540px) and (min-width: 600px) {
  .site-header { padding-top: 8px; }
}
@media (max-width: 400px) {
  .site-header { column-gap: 4px; }
  .transport-speed { width: 58px; }
}
@media (prefers-reduced-motion: reduce) {
  .site-header :is(.transport, .background-picker), .transport-controls,
  .boat-joystick, .boat-throttle, .chart-speed-control { transition: none; }
}

/* Only shown for an actual persistence failure; the current chart stays playable. */
.chart-storage-notice {
  position: fixed; z-index: 30; top: 1rem; left: 50%; transform: translateX(-50%);
  width: min(34rem, 85vw); padding: .7rem 1rem; border-radius: .5rem;
  color: #f7f2df; background: rgba(24, 38, 40, .92); font: 14px/1.4 system-ui;
  pointer-events: none;
}

/* Developer preview uses one viewport surface; normal sailing stays mounted. */
.stream-preview { position: absolute; inset: 0; z-index: 20; background: #172f38; overflow: hidden; pointer-events: auto; }
.stream-map { position: absolute; inset: 0; width: 100%; height: 100%; touch-action: none; cursor: grab; }
.stream-map:active { cursor: grabbing; }
.stream-toolbar { position: absolute; top: max(12px, env(safe-area-inset-top)); left: 12px; display: flex; flex-wrap: wrap; gap: 6px; max-width: calc(100% - 24px); }
.stream-toolbar button { padding: 8px 12px; border: 1px solid #a5c9c055; border-radius: 6px; background: #102c32dd; color: #f5f0d7; cursor: pointer; }
.stream-error { position: absolute; bottom: max(12px, env(safe-area-inset-bottom)); left: 12px; right: 12px; width: fit-content; max-width: calc(100% - 24px); padding: 8px 12px; border-radius: 6px; background: #102c32e8; color: #f5f0d7; font: 12px/1.5 system-ui; pointer-events: none; }
.stream-error { background: #583c28f2; }
.is-stream-preview .chart-world, .is-stream-preview .boat-layer, .is-stream-preview .mobile-control, .is-stream-preview .game-pause-indicator { visibility: hidden; }
.stream-controls { margin-block: 12px; }
