:root {
  --bg: #071e29;
  --panel: #0b2b3a;
  --panel-2: #0f3547;
  --ink: #eaf2f6;
  --body: #cfdde5;
  --muted: #98a7b0;
  --line: #1c4457;
  --fresh: #2fa463;
  --recent: #e8a13b;
  --stale: #e4574c;
  --accent: #4a90d9;
  --calc: #5fa8e8;
  --eyebrow: #8fc4ef;
  --radius: 14px;
}

* {
  box-sizing: border-box;
}
html {
  scroll-behavior: smooth;
}
body {
  margin: 0;
  font:
    16px/1.55 system-ui,
    -apple-system,
    "Segoe UI",
    Roboto,
    sans-serif;
  color: var(--ink);
  /* Solid brand background is the fallback whenever the wave canvas is absent
     (WebGL/Three failure, prefers-reduced-motion cannot start it, etc.). */
  background:
    radial-gradient(1200px 600px at 80% -10%, rgba(74, 144, 217, 0.18), transparent 60%),
    radial-gradient(900px 500px at -10% 10%, rgba(95, 168, 232, 0.12), transparent 55%), var(--bg);
  min-height: 100vh;
}
/* Links are visibly links by default: accent + underline (structural links —
   nav, brand, buttons-as-links — override below as before). */
a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
a:hover {
  color: var(--calc);
}
/* One focus token for every interactive element (WCAG 2.4.7). Keyboard focus
   is always visible; --accent re-maps per phone theme, so rings inside the
   emulator take that theme's accent automatically. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* --- Interactive wave background --- */
#mt-wave {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  pointer-events: none;
  display: block;
}
#mt-wave-tint {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(1100px 600px at 78% -8%, rgba(74, 144, 217, 0.14), transparent 60%),
    linear-gradient(
      180deg,
      rgba(6, 26, 36, 0.42) 0%,
      rgba(6, 26, 36, 0.16) 28%,
      rgba(6, 26, 36, 0.3) 60%,
      rgba(6, 26, 36, 0.5) 100%
    );
}
/* Legibility treatment reused on copy blocks that sit over the wave. */
.scrim {
  position: relative;
  padding: 20px 26px 22px;
  margin: -20px -26px -22px;
  border-radius: 28px;
  background: radial-gradient(
    125% 100% at 18% 38%,
    rgba(5, 20, 29, 0.66),
    rgba(5, 20, 29, 0.34) 52%,
    transparent 80%
  );
}
.shadow {
  text-shadow: 0 1px 12px rgba(4, 16, 24, 0.7);
}

.page {
  position: relative;
}

.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 24px;
  position: sticky;
  top: 0;
  z-index: 5;
  backdrop-filter: blur(8px);
  background: rgba(7, 30, 41, 0.7);
  border-bottom: 1px solid var(--line);
}
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.3px;
  color: var(--ink);
  text-decoration: none;
}
.nav {
  display: flex;
  align-items: center;
  gap: 20px;
}
.nav a {
  color: var(--muted);
  text-decoration: none;
  font-size: 14px;
}
.nav a:hover {
  color: var(--ink);
}

.btn {
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--ink);
  border-radius: 999px;
  padding: 11px 20px;
  font-size: 15px;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition:
    transform 0.08s ease,
    background 0.2s ease;
}
.btn:hover {
  transform: translateY(-1px);
}
.btn.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #04141d;
  font-weight: 650;
}
.btn.ghost {
  background: transparent;
}

/* Bands run full-bleed; each band's content sits in a centred .wrap. */
.wrap {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 24px;
}

/* Anchor-link targets (#try, #features, #how, #live-dashboard) scroll to sit
   below the sticky topbar rather than hiding under it. */
section[id] {
  scroll-margin-top: 76px;
}

.hero {
  padding: 70px 0 60px;
}
.hero-grid {
  display: grid;
  /* minmax(0, …): a nowrap label inside a card must never widen the track. */
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: 40px;
  align-items: center;
}
.eyebrow {
  text-transform: uppercase;
  letter-spacing: 2.2px;
  font-size: 12.5px;
  font-weight: 800;
  color: var(--eyebrow);
  margin: 0 0 10px;
}
.hero h1 {
  font-size: clamp(34px, 5vw, 52px);
  line-height: 1.05;
  margin: 0 0 18px;
  letter-spacing: -0.5px;
}
.lede {
  color: var(--body);
  font-size: 18px;
  margin: 0 0 24px;
  max-width: 42ch;
}
.hero-cta {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.hero-card {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 16px;
  box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.6);
}
/* Hero mini-cards carry the full card anatomy (R3): label + badge, value,
   provenance footer. The site-scale badge is sized up from the emulator base. */
.mini-card {
  background: rgba(7, 30, 41, 0.55);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 13px 13px 11px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.mini-card.wide {
  grid-column: 1 / -1;
  flex-direction: row;
  align-items: center;
  gap: 12px;
  padding: 13px 13px;
}
.mc-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}
.mini-card .badge {
  font-size: 8.5px;
  letter-spacing: 0.4px;
  padding: 2px 5px;
}
.mc-title {
  font-size: 10px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--muted);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mc-value {
  font-size: 30px;
  font-weight: 750;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.mc-value small {
  font-size: 13px;
  font-weight: 650;
  color: var(--muted);
  margin-left: 5px;
}
.mc-src {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 650;
  color: var(--muted);
  white-space: nowrap;
}
.mc-from {
  margin-left: auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mc-noaa-txt {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  min-width: 0;
}
.mc-sub {
  color: var(--body);
  font-size: 14px;
  font-weight: 650;
}
.chip-sample {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: var(--recent);
  background: color-mix(in srgb, var(--recent) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--recent) 40%, transparent);
  border-radius: 5px;
  padding: 2px 6px;
  vertical-align: 1px;
}
.mc-loc {
  flex: none;
  appearance: none;
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--eyebrow);
  background: rgba(74, 144, 217, 0.18);
  border: 1px solid rgba(74, 144, 217, 0.5);
  border-radius: 10px;
  padding: 8px 14px;
}
.mc-loc:hover {
  background: rgba(74, 144, 217, 0.28);
}
.mc-loc:disabled {
  opacity: 0.55;
  cursor: default;
}
.mc-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex: none;
}
.mc-dot.fresh {
  background: var(--fresh);
}
.mc-dot.recent {
  background: var(--recent);
}

/* --- Try it section --- */
.tryit {
  padding: 56px 0;
  border-top: 1px solid #10344a;
  background: rgba(9, 36, 49, 0.5);
}
.tryit-tip {
  margin: 14px 0 0;
  font-size: 12.5px;
  font-weight: 650;
  color: var(--muted);
}
.tryit-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 48px;
  align-items: center;
}
.tryit-copy h2 {
  font-size: clamp(26px, 3.4vw, 34px);
  text-align: left;
  margin: 0 0 16px;
  letter-spacing: -0.3px;
}
.tryit-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.tryit-list li {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--ink);
  font-size: 15px;
}
.bullet {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
}
.bullet.fresh {
  background: var(--fresh);
}
.bullet.accent {
  background: var(--accent);
}
.bullet.recent {
  background: var(--recent);
}

/* --- Phone preview (Deepwater theme) --- */
/* The phone preview carries the real iOS app theme tokens (design source of
   truth), scoped so they never leak into the blue marketing page. Semantic
   colours are shared across themes; the theme picker on the Boat screen swaps
   data-theme to re-colour the whole preview, exactly like the app's Appearance
   setting. */
.phone-screen {
  --fresh: #2fa463;
  --recent: #e8a13b;
  --stale: #e4574c;
  --info: #4a90d9;
  --calc: #5fa8e8;
}
.phone-screen[data-theme="deepwater"] {
  --bg: #0c2138;
  --panel: #153350;
  --panel-2: #1c405f;
  --ink: #eaf4fb;
  --muted: #8fb0c4;
  --accent: #ff7a66;
  --accent2: #3fd0c9;
  --chip: #1c405f;
  --line: rgba(255, 255, 255, 0.12);
}
.phone-screen[data-theme="nightwatch"] {
  --bg: #0a1117;
  --panel: #121d26;
  --panel-2: #15242e;
  --ink: #d9f3ef;
  --muted: #6e958f;
  --accent: #29d3c2;
  --accent2: #ffc845;
  --chip: #15242e;
  --line: rgba(255, 255, 255, 0.12);
}
.phone-screen[data-theme="daybreak"] {
  --bg: #f2f8fb;
  --panel: #ffffff;
  --panel-2: #e3f1f9;
  --ink: #0b2b3a;
  --muted: #5e7e8e;
  --accent: #0a7fdb;
  --accent2: #ff6b57;
  --chip: #e3f1f9;
  --line: rgba(0, 0, 0, 0.12);
}

.phone {
  justify-self: center;
  /* The single-column try band centres its copy; the app inside the phone is
     always left-set, like every design surface. */
  text-align: left;
  width: 320px;
  height: 660px;
  border-radius: 54px;
  background: #04121a;
  border: 2px solid #14313f;
  /* Device depth: bezel-edge highlight ring inside the frame ring, plus a
     second, tighter drop shadow under the long one. */
  box-shadow:
    0 40px 90px -30px rgba(0, 0, 0, 0.8),
    0 16px 36px -18px rgba(0, 0, 0, 0.55),
    inset 0 0 0 2px #2c4d60,
    inset 0 0 0 8px #0a1f29;
  padding: 10px;
}
.phone-screen {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 44px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  /* Promote to a compositing + stacking context. The Leaflet map paints its tiles
     on their own composited layer with high internal z-indexes; without this the
     layer escapes the rounded overflow clip and paints over the sticky top nav
     when the page scrolls. This confines the whole app inside the phone frame. */
  transform: translateZ(0);
  isolation: isolate;
}
.phone-status {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 44px;
  z-index: 3;
  /* Decorative device chrome: content scrolls beneath it, so it must never
     swallow taps meant for whatever is under the strip (the [hidden]/overlay
     bug family — see the nav-HUD entries in PROGRESS.md). */
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 26px;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
}
/* Dynamic-Island-style pill: hardware black in every theme, with a faint
   lens dot. */
.phone-notch {
  position: absolute;
  left: 50%;
  top: 8px;
  transform: translateX(-50%);
  width: 104px;
  height: 26px;
  border-radius: 999px;
  background: #000;
}
.phone-notch::after {
  content: "";
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #1d3a4d 0 30%, #06121a 70%);
}
.phone-status-icons {
  display: flex;
  align-items: center;
}
.phone-status-icons svg {
  display: block;
  fill: currentColor;
}
.phone-status-icons .wifi {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
}
.phone-status-icons .batt-case {
  fill: none;
  stroke: currentColor;
  stroke-width: 1;
  opacity: 0.45;
}
.phone-status-icons .batt-nub {
  opacity: 0.45;
}
.phone-scroll {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow-y: auto;
  overflow-x: hidden;
  /* Content scrolls beneath the floating tab pill; the bottom padding keeps
     the last row readable above it. */
  padding: 50px 13px 92px;
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-behavior: smooth;
}
.phone-scroll::-webkit-scrollbar {
  display: none;
}
.app-view {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* Home hierarchy (board 3b): source banner → instruments → community preview.
   Visual order only, via flex `order` — DOM order and ids stay untouched for
   app.js bindings and #app-reports re-homing (§5.9: no DOM moves). Everything
   unlisted (greet, preview label, reports feed, crew rows) shares order 3 and
   keeps its source order within the group. */
.app-view[data-view="home"] > * {
  order: 3;
}
.app-view[data-view="home"] > .app-nav {
  order: 0;
}
/* The 3b hierarchy: alert banner, then the bridge banner (both order 1 — the
   banner precedes the source card in DOM order, so it renders first). */
.app-view[data-view="home"] > .app-alert {
  order: 1;
}
.app-view[data-view="home"] > .app-source {
  order: 1;
}
.app-view[data-view="home"] > .app-cards {
  order: 2;
}
.app-view[data-view="home"] > .app-foot {
  order: 4;
}
/* Trips fills the screen (board 3c — no dead zone): the export line pins to
   the bottom of the visible area when the history is short. */
.app-view[data-view="trips"] {
  min-height: 100%;
}
.app-view[data-view="trips"] .app-foot {
  margin-top: auto;
}
/* `display: flex` above outranks the UA `[hidden] { display: none }`, so restore
   it for the elements the preview toggles (screens, map card, recording row). */
.app-view[hidden],
.map-card[hidden],
.trip[hidden],
.rp-result[hidden],
.rp-status[hidden],
.app-cards[hidden],
.app-source-note[hidden],
.app-boater[hidden],
.bridge-placeholder[hidden] {
  display: none;
}
.app-boathead {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 2px 4px 10px;
}
.app-eyebrow {
  font-size: 10px;
  font-weight: 800;
  color: var(--muted);
  letter-spacing: 1.8px;
}
.app-boatname {
  font-size: 23px;
  font-weight: 800;
  color: var(--ink);
}
.app-boatsub {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
}
.app-mates {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 11px 13px;
  border-radius: 16px;
  background: var(--accent);
  margin-bottom: 10px;
}
.app-mates-txt {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}
.app-mates-txt strong {
  font-size: 13px;
  color: #fff;
}
.app-mates-txt span {
  font-size: 11px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.85);
}
.app-mates-cta {
  font-size: 12px;
  font-weight: 800;
  color: #fff;
}
.app-bridge {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 13px;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
  margin-bottom: 10px;
}
.app-bridge-txt {
  display: flex;
  flex-direction: column;
}
.app-bridge-txt strong {
  font-size: 13px;
  color: var(--ink);
}
.app-bridge-txt span {
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
}
.dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex: none;
}
.app-bridge .dot {
  width: 8px;
  height: 8px;
}
.dot.fresh {
  background: var(--fresh);
}
.dot.recent {
  background: var(--recent);
}
.app-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px;
  /* Named query container: the grid's width decides the cards' side padding
     (a container query cannot restyle the container itself, so the card's own
     padding is driven from here). */
  container: app-cards / inline-size;
}
/* Canonical value-card anatomy (design board 3a): label row with a fixed badge
   slot, value + unit on one baseline, optional sub-value, provenance footer
   (dot + age, source right-aligned and truncated). Radius from the shared
   scale: 14 cards · 10 chips · 22 sheets · 5 badges · 999 pills. */
.app-card {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
  padding: 12px 12px 10px;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
  /* Query container so the value text sizes itself to this card's width
     (see .app-card-val) — long values shrink instead of escaping the border. */
  container-type: inline-size;
}
.app-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 5px;
}
.app-card-label {
  font-size: 9px;
  font-weight: 800;
  color: var(--muted);
  letter-spacing: 0.4px;
  text-transform: uppercase;
  /* The label truncates; the badge never wraps under it (3a rule 1 — the
     wrapped badge at phone widths was a shipped-bug family, §5.10). */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Badge recipe, every surface: tint text · 14% tint fill · 40% tint ring ·
   radius 5 (iOS ProvenanceBadge is the reference implementation). Sized to the
   emulator scale so the label keeps most of the row before it truncates. */
.badge {
  flex: none;
  font-size: 7.5px;
  font-weight: 800;
  letter-spacing: 0.3px;
  padding: 1.5px 4px;
  border-radius: 5px;
  background: var(--bg);
  border: 1px solid transparent;
}
.badge.measured {
  color: var(--fresh);
  background: color-mix(in srgb, var(--fresh) 14%, transparent);
  border-color: color-mix(in srgb, var(--fresh) 40%, transparent);
}
.badge.calc {
  color: var(--calc);
  background: color-mix(in srgb, var(--calc) 14%, transparent);
  border-color: color-mix(in srgb, var(--calc) 40%, transparent);
}
.badge.device {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}
.dot.stale {
  background: var(--stale);
}
/* Home: data-source control (Bridge boat vs this phone's sensors) */
/* Home alert banner (board 3b): the amber band above the bridge banner. It is
   one big tap target whose whole face is the View action. */
.app-alert {
  appearance: none;
  cursor: pointer;
  font-family: inherit;
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  text-align: left;
  margin: 2px 0 0;
  padding: 11px 13px;
  border: 0;
  border-radius: var(--radius);
  background: var(--recent);
  color: #fff;
}
.app-alert-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.65);
}
.app-alert-txt {
  flex: 1;
  min-width: 0;
  font-size: 12.5px;
  font-weight: 800;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-alert-cta {
  flex: none;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.3px;
}
.app-source {
  margin: 2px 0 10px;
  padding: 10px 11px;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
}
.app-source[data-mode="device"] {
  border-color: var(--accent);
}
.app-source-row {
  display: flex;
  align-items: center;
  gap: 9px;
}
/* Board 3b: the banner leads with a status dot — green while the (demo) boat
   network is the source, amber while this phone's own sensors are. */
.app-source-ic {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--fresh);
}
.app-source[data-mode="device"] .app-source-ic {
  background: var(--recent);
}
/* Position-source chip (board 3b / iOS StatusBanner parity): which GPS feeds
   the demo right now. */
.app-source-chip {
  flex: none;
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 10.5px;
  font-weight: 800;
  color: var(--ink);
  background: var(--chip);
  border-radius: 10px;
  padding: 5px 9px;
}
.app-source-txt {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.app-source-txt strong {
  font-size: 12px;
  font-weight: 800;
  color: var(--ink);
}
.app-source-txt span {
  font-size: 10px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-source-btn {
  appearance: none;
  cursor: pointer;
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 800;
  color: #fff;
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 10px;
  padding: 7px 11px;
  /* Its own row under the banner text (board 3b keeps the banner line clean
     for the source chip), full width so the demo affordance stays prominent. */
  display: block;
  width: 100%;
  margin-top: 9px;
}
.app-source-btn.ghost {
  color: var(--accent);
  background: none;
}
.app-source-note {
  margin: 8px 0 0;
  font-size: 10px;
  line-height: 1.45;
  color: var(--muted);
}
.app-card-val {
  font-size: 21px; /* fallback where container queries are unsupported */
  /* Sized to the CARD, not the viewport: cqi is 1% of the card's content box
     (104.5px at the design width), so 20.1cqi resolves to exactly 21px there
     and shrinks on a narrower phone instead of letting a long value wrap out
     past the card border. */
  font-size: clamp(15px, 20.1cqi, 21px);
  font-weight: 800;
  color: var(--ink);
  line-height: 1;
  min-width: 0;
  font-variant-numeric: tabular-nums;
  /* A long value (a full lat/lon) wraps inside the card rather than pushing
     past its edge. */
  overflow-wrap: anywhere;
}
.app-card-val small {
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
  margin-left: 2px;
}
/* Row 3 (optional): angle, trend, second reading. */
.app-card-sub {
  font-size: 10px;
  font-weight: 700;
  color: var(--muted);
}
/* Row 4: freshness dot + age on the left, source right-aligned. The source is
   the part that truncates — the dot and age never do. */
.app-card-src {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 9px;
  font-weight: 700;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-card-from {
  margin-left: auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Tight two-column layout (the 320px-phone stress case, 3a). */
@container app-cards (max-width: 292px) {
  .app-card {
    padding-left: 10px;
    padding-right: 10px;
  }
}
/* Tight single card — these resolve against the .app-card container: compact
   the badge and label so only the longest labels truncate; the badge never
   wraps and never truncates. */
@container (max-width: 118px) {
  .app-card-top {
    gap: 4px;
  }
  .app-card-label {
    font-size: 8px;
    letter-spacing: 0.2px;
  }
  .app-card .badge {
    font-size: 7px;
    letter-spacing: 0.2px;
    padding: 1.5px 3px;
  }
}
/* Floating pill tab bar (approved design, board 3b): the bar floats above the
   safe-area with content scrolling beneath it; the active tab is a chip.
   Below the full-screen map (z 40) and the nav HUD (z 50), above content. */
.phone-tabs {
  position: absolute;
  bottom: 14px;
  left: 10px;
  right: 10px;
  z-index: 5;
  display: flex;
  padding: 5px 4px;
  border-radius: 24px;
  background: color-mix(in srgb, var(--panel) 92%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--line);
  box-shadow: 0 8px 24px rgba(0, 10, 20, 0.22);
}
.phone-tabs .tab {
  appearance: none;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: inherit;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 5px 0 4px;
  border-radius: 17px;
  font-size: 8.5px;
  font-weight: 800;
  color: var(--muted);
}
.phone-tabs .tab svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.phone-tabs .tab.active {
  color: var(--accent);
  background: var(--chip);
}

/* ---- Interactive app preview: shared screen components ---- */
.app-nav {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 2px 4px;
}
.app-nav-ic {
  color: var(--accent);
  display: flex;
}
.app-nav-ic svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* Home header (board 3b): the primary Matey roundel (the real logo asset,
   design/matey-logo.png) + boat identity under the title. The image keeps its
   own brand colours in every phone theme; the hairline ring keeps its edge
   visible on the dark themes. */
.app-nav-logo {
  display: flex;
  flex: none;
}
.app-nav-logo img {
  display: block;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  box-shadow: 0 0 0 1px var(--line);
}
.app-nav-txt {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
}
.app-nav-sub {
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-nav-title {
  font-size: 20px;
  font-weight: 800;
  color: var(--ink);
  flex: 1;
}
/* Inside the header text stack the title is one line of the column, not the
   row-filler it is on the plain view headers. */
.app-nav-txt .app-nav-title {
  flex: none;
  line-height: 1.15;
}
.app-live {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  font-weight: 700;
  color: var(--muted);
}
.app-foot {
  text-align: center;
  font-size: 10px;
  color: var(--muted);
  padding: 8px 0 2px;
}

/* Home: community feed */
/* Home network section head (board 3b): MATEY NETWORK · PREVIEW · N mates. */
.app-nethead {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px 2px 0;
}
.app-nethead-title {
  /* Sized so title + PREVIEW + "3 mates nearby" all fit the 320px phone whole
     — the live count must never be the thing that truncates. */
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--muted);
}
/* PREVIEW chip on the badge recipe (3a): tint text · tint fill · tint ring. */
.chip-preview {
  font-size: 8.5px;
  font-weight: 800;
  letter-spacing: 0.4px;
  color: var(--recent);
  background: color-mix(in srgb, var(--recent) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--recent) 40%, transparent);
  border-radius: 5px;
  padding: 2px 5px;
}
.app-nethead-count {
  flex: 1;
  min-width: 0;
  text-align: right;
  font-size: 10px;
  font-weight: 700;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-preview-label {
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0.4px;
  color: var(--muted);
  padding: 2px 2px 0;
}
.app-preview-note {
  font-size: 10px;
  color: var(--muted);
  padding: 0 2px;
}
.app-boater {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 10px;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
}
.app-boater-ava {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--chip);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.app-boater-ava svg {
  fill: currentColor;
}
.app-boater-txt {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}
.app-boater-txt strong {
  font-size: 12px;
  color: var(--ink);
}
.app-boater-txt span {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--muted);
}
.thank {
  appearance: none;
  cursor: pointer;
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 800;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--accent);
  padding: 5px 11px;
  border-radius: 999px;
  flex: none;
}
.thank.is-on {
  color: #fff;
  background: var(--accent);
}
/* Crew-row dismiss (board 3b): the soft × chip beside Thank. */
.dismiss {
  appearance: none;
  cursor: pointer;
  font-family: inherit;
  flex: none;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
  color: var(--muted);
  background: var(--chip);
  border: 0;
  border-radius: 50%;
  padding: 0;
}
.dismiss:hover {
  color: var(--ink);
}
/* The 3b sample footnote is a <p>; keep it on the shared note style without
   the UA paragraph margins pushing the section apart. */
.app-mates-note {
  margin: 2px 0 0;
}
.app-card.wide {
  grid-column: 1 / -1;
}
.app-card-val.small {
  font-size: 14px;
  /* Same rule on the full-width cards (position): 5.74cqi is exactly 14px at
     the design content width (244px), smaller on a narrower phone. */
  font-size: clamp(11px, 5.74cqi, 14px);
}

/* Conditions: alerts, NOAA comparison, groups */
.app-section-title {
  font-size: 14px;
  font-weight: 800;
  color: var(--ink);
  padding-top: 2px;
}
.app-section-title.inline {
  padding: 0;
  font-size: 13px;
}
.alert {
  display: flex;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
  overflow: hidden;
}
.alert-bar {
  width: 4px;
  flex: none;
}
.alert-bar.recent {
  background: var(--recent);
}
.alert-bar.accent {
  background: var(--accent);
}
.alert-body {
  padding: 9px 11px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.alert-head {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.alert-head strong {
  font-size: 12px;
  color: var(--ink);
}
.alert-ic {
  display: flex;
  align-items: center;
}
.alert-svg {
  width: 15px;
  height: 15px;
}
.alert-ic.recent {
  color: var(--recent);
}
.alert-ic.accent {
  color: var(--accent);
}
.chip-marine {
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: var(--bg);
  background: var(--info);
  padding: 2px 5px;
  border-radius: 5px;
}
.alert-sev {
  display: flex;
  align-items: center;
  gap: 3px;
}
.sev-seg {
  width: 15px;
  height: 3px;
  border-radius: 2px;
  background: var(--line);
}
.sev-seg.on.recent {
  background: var(--recent);
}
.sev-label {
  font-size: 9px;
  font-weight: 800;
  margin-left: 3px;
}
.sev-label.recent {
  color: var(--recent);
}
.alert-sub {
  font-size: 10px;
  color: var(--muted);
}
.noaa-head {
  display: flex;
  align-items: center;
  gap: 7px;
  padding-top: 4px;
}
.chip-noaa {
  font-size: 9px;
  font-weight: 800;
  color: var(--bg);
  background: var(--info);
  padding: 3px 6px;
  border-radius: 999px;
}
.noaa-station {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 0 2px;
}
.noaa-station strong {
  font-size: 12.5px;
  color: var(--ink);
}
.noaa-station span {
  font-size: 10px;
  color: var(--muted);
}
.cmp-table {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
}
.cmp-row {
  display: grid;
  grid-template-columns: 1fr 44px 44px 40px;
  align-items: center;
  font-size: 11px;
  color: var(--ink);
}
.cmp-row span:not(.cmp-name) {
  text-align: right;
  font-weight: 700;
}
.cmp-row.cmp-head span {
  font-size: 9.5px;
  font-weight: 800;
  color: var(--muted);
}
.cmp-name {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
}
.agree {
  font-style: normal;
  font-size: 8px;
  font-weight: 800;
  padding: 1px 5px;
  border-radius: 999px;
  background: var(--bg);
}
.agree.fresh {
  color: var(--fresh);
}
.agree.recent {
  color: var(--recent);
}
.grp-title {
  font-size: 12.5px;
  font-weight: 800;
  color: var(--muted);
  padding: 6px 2px 0;
}

/* Map screen */
.app-map {
  position: relative;
  height: 300px;
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--line);
  background: radial-gradient(120% 90% at 30% 8%, #12507e, #0b2f4c 60%, #0a2740);
  /* Own compositing context so the map's tile layer is clipped to this rounded
     card rather than overflowing it. */
  transform: translateZ(0);
}
/* Full-screen map mode: the card fills the phone screen. `makeFullscreenToggle()`
   re-homes `.app-map` directly under `.phone-screen` (#app-preview) and this uses
   `position: absolute` — NOT `fixed`. A fixed box inside the phone frame's
   `transform`ed ancestor is mis-hit-tested by WebKit (Safari / iOS), leaving the
   map controls visible but untappable; absolute-in-frame hit-tests reliably. The
   map covers the status bar, app content and tab bar within the frame. The same
   map instance is kept (route/zoom/chart layer/selection all persist); the engine
   just re-measures on toggle. Exit via the toggle (now a collapse icon) or Escape. */
.app-map.is-fullscreen {
  position: absolute;
  inset: 0;
  z-index: 40;
  height: auto;
  border-radius: 0;
  border: 0;
}
/* The interactive map host — Apple MapKit or Leaflet/OpenStreetMap renders into
   it. Always shown; whichever engine boots fills the frame with real tiles.
   `isolation: isolate` makes this its own stacking context so the engine's
   internal layers (MapKit's tile/annotation canvases, Leaflet's map pane at
   z-index 400) stay contained here and cannot paint over the sibling overlay
   pills/buttons — which sit at z-index 3 in the parent `.app-map` context.
   Without it, MapKit's high-z-index canvases leak up and hide every control
   (the layer/zoom/recenter buttons and the GPS + layer-name pills). */
.map-live {
  position: absolute;
  inset: 0;
  isolation: isolate;
  background: #0a2740;
}
.map-live .mk-map-view {
  width: 100%;
  height: 100%;
}
/* Leaflet's attribution, scaled down for the phone frame (OSM requires it). */
.map-live .leaflet-control-attribution {
  font-size: 8.5px;
  background: rgba(255, 255, 255, 0.82);
}
.map-live .leaflet-control-attribution a {
  color: #2b6390;
}
/* Honest "imagery unavailable" state (shown only when the base tiles never load).
   Below the map controls (z-index 3) so the layer/zoom/recenter buttons stay usable. */
.map-imagery-down {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 24px;
  text-align: center;
  background: rgba(8, 31, 51, 0.9);
  color: #eaf2f6;
}
.map-imagery-down strong {
  font-size: 14px;
}
.map-imagery-down span {
  font-size: 11.5px;
  color: #9db6c6;
  max-width: 220px;
  line-height: 1.4;
}
.map-imagery-down button {
  margin-top: 4px;
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 999px;
  padding: 6px 16px;
  background: rgba(255, 255, 255, 0.08);
  color: #eaf2f6;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}
/* Chart-layer name pill — shows the active base/overlay (Apple Maps or
   OpenStreetMap / NOAA ENC / OpenSeaMap), mirroring the iOS ChartLayer selector. */
.map-topleft,
.map-controls,
.map-card {
  z-index: 3;
}
/* Position source + active chart layer, stacked top-left and held clear of the
   right-hand control column (report/zoom/etc.), so no control can overlap the
   chart-layer label on the fixed 300px map card. */
.map-topleft {
  position: absolute;
  top: 10px;
  left: 10px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  /* Leave room for the 34px control column at right:10 so a long layer name
     ellipsizes rather than sliding under the buttons. */
  max-width: calc(100% - 62px);
}
.map-chip {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 10px;
  font-weight: 700;
  color: #eaf2f6;
  background: rgba(6, 20, 28, 0.82);
  padding: 5px 9px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.14);
}
/* The EMODnet conditions pill is a real button (it toggles the station pins),
   restyled to sit in the top-left chip stack like the status pills. */
.map-chip-toggle {
  font: inherit;
  font-size: 10px;
  font-weight: 700;
  cursor: pointer;
}
.map-chip-toggle:disabled {
  cursor: default;
  opacity: 0.8;
}
.map-chip-toggle.is-off {
  opacity: 0.62;
}
/* Icon-first map chips (top-left stack): only the symbol shows at rest; the
   label expands briefly on click (`.is-expanded`, wired in app.js with a 3 s
   auto-collapse) and while keyboard-focused. The title/aria-label always
   carry the same text. */
.icon-chip {
  gap: 0;
  padding: 5px 6px;
}
.icon-chip .icon-chip-ic {
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.icon-chip .icon-chip-label {
  max-width: 0;
  margin-left: 0;
  overflow: hidden;
  white-space: nowrap;
  transition:
    max-width 0.22s ease,
    margin-left 0.22s ease;
}
.icon-chip.is-expanded .icon-chip-label,
.icon-chip:focus-visible .icon-chip-label {
  max-width: 190px;
  margin-left: 5px;
}
/* Boat-GPS chip: the live position provenance — glyph in the fresh green. */
.gps-chip .icon-chip-ic {
  color: var(--fresh);
}
/* Wind-station chip: the glyph carries the feed state — green available ·
   red unavailable · amber none-near · muted while checking. */
.wind-chip[data-state="loading"] .icon-chip-ic {
  color: #98a7b0;
}
.wind-chip[data-state="ok"] .icon-chip-ic {
  color: var(--fresh);
}
.wind-chip[data-state="none"] .icon-chip-ic {
  color: var(--recent);
}
.wind-chip[data-state="down"] .icon-chip-ic {
  color: var(--stale);
}
.wind-chip.is-off .icon-chip-ic {
  opacity: 0.55;
}
@keyframes boat-halo {
  0%,
  100% {
    transform: scale(0.85);
    opacity: 0.55;
  }
  50% {
    transform: scale(1.15);
    opacity: 0.25;
  }
}
/* Map markers — shared by MapKit annotations and Leaflet divIcons so both
   engines look identical. The engine positions the wrapper; we style the marker. */
.mk-pin {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  cursor: pointer;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.45);
}
.mk-pin svg {
  width: 16px;
  height: 16px;
  color: #fff;
}
.mk-pin.obs {
  background: var(--info);
}
.mk-pin.mate {
  background: var(--accent2);
}
/* EMODnet Physics in-situ wind stations — violet, distinct from the crowd
   observation blue and every report-type colour. The arrow inside rotates to
   the wind's FROM direction (set inline per station). */
.mk-pin.emodnet {
  background: #8b5cf6;
}
.mk-pin.hazard {
  background: var(--stale);
}
.mk-pin.report {
  background: var(--accent);
}
.mk-pin.report.is-hazard {
  background: var(--stale);
}
/* Each report type its own colour (matches REPORT_TYPES + the feed/composer). */
.mk-pin.report.report-weather {
  background: #3b82f6;
}
.mk-pin.report.report-harbour {
  background: #10b981;
}
.mk-pin.report.report-water {
  background: #06b6d4;
}
.mk-pin.report.report-hazard {
  background: #f59e0b;
}
.mk-pin.report svg {
  fill: none;
  stroke: #fff;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.mk-dest {
  width: 28px;
  height: 28px;
  border-radius: 50% 50% 50% 2px;
  background: #0b2b3a;
  border: 2px solid #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.45);
}
.mk-dest svg {
  width: 15px;
  height: 15px;
  color: var(--accent);
}
.mk-boat {
  position: relative;
  width: 42px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.mk-boat-halo {
  position: absolute;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    color-mix(in srgb, var(--accent) 42%, transparent),
    transparent 70%
  );
  animation: boat-halo 2.4s ease-in-out infinite;
}
.mk-boat svg {
  position: relative;
  width: 27px;
  height: 35px;
  color: var(--accent);
  filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.55));
}
/* This device's own live GPS location (recenter-on-me) — a blue dot with a soft
   pulsing halo, deliberately distinct from the accent boat pointer so a phone
   fix never looks like boat-instrument data. */
.mk-device {
  position: relative;
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.mk-device::after {
  content: "";
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #2b83e0;
  border: 2.5px solid #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
}
.mk-device-halo {
  position: absolute;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(43, 131, 224, 0.35), transparent 70%);
  animation: boat-halo 2.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .mk-boat-halo,
  .mk-device-halo {
    animation: none;
  }
}
.map-controls {
  position: absolute;
  right: 10px;
  bottom: 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.map-ctrl {
  appearance: none;
  cursor: pointer;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 0;
  background: rgba(255, 255, 255, 0.96);
  color: #0b2b3a;
  font-family: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.28);
  transition: transform 0.1s ease;
}
.map-ctrl:active {
  transform: scale(0.92);
}
.ctrl-ic {
  width: 19px;
  height: 19px;
  color: #274a5c;
}
.map-card {
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 10px;
  padding: 10px 12px;
  border-radius: var(--radius);
  background: rgba(6, 20, 28, 0.94);
  border: 1px solid rgba(255, 255, 255, 0.14);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.map-card-close {
  position: absolute;
  top: 6px;
  right: 8px;
  appearance: none;
  border: 0;
  background: none;
  color: #8fb0c4;
  line-height: 1;
  cursor: pointer;
  display: flex;
}
.map-card-tag {
  font-size: 8.5px;
  font-weight: 800;
  letter-spacing: 0.6px;
  color: var(--calc);
}
.map-card strong {
  font-size: 12.5px;
  color: #eaf2f6;
}
.map-card span:not(.map-card-tag) {
  font-size: 10px;
  color: #9db6c6;
}

/* ---- Community report: toolbar "Report" button + composer sheet on the map ---- */
/* The Report action lives in the right-hand map toolbar (a ⚠️ glyph) rather than
   a floating pill, so it never covers a selected pin's info card. Accent fill +
   white glyph mark it as the primary action among the toolbar controls. */
.map-ctrl-report {
  background: var(--accent, #2f6fed);
}
.map-ctrl-report .ctrl-ic {
  color: #fff;
}
/* `.map-ctrl` sets `display: flex`, which would otherwise defeat the `hidden`
   attribute the composer toggles while the sheet is open. */
.map-ctrl-report[hidden] {
  display: none;
}
.report-sheet {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 8px;
  z-index: 4;
  /* Never taller than the map card it sits in — the expanded composer (four
     types + up to eight hazard presets + note) is taller than the 300px map,
     so cap its height and let the body scroll instead of overflowing the top
     of the map (where `.app-map { overflow: hidden }` would clip it away). */
  max-height: calc(100% - 16px);
  padding: 12px;
  border-radius: 22px; /* sheet radius on the shared scale */
  background: rgba(6, 20, 28, 0.97);
  border: 1px solid rgba(255, 255, 255, 0.14);
  display: flex;
  flex-direction: column;
  gap: 9px;
  overflow: hidden;
}
.report-sheet[hidden] {
  display: none;
}
/* Header and the post/cancel actions + privacy note stay pinned; only the
   middle (types, presets, note) scrolls when the sheet is capped. */
.report-sheet-head,
.report-sheet .report-actions,
.report-sheet .report-privacy {
  flex: 0 0 auto;
}
.report-body {
  display: flex;
  flex-direction: column;
  gap: 9px;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  /* Room so focus rings on edge controls aren't clipped by the scroll box. */
  margin: 0 -2px;
  padding: 2px;
}
.report-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.report-sheet-head strong {
  font-size: 13px;
  color: #eaf2f6;
}
.report-types {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 6px;
}
.report-type {
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 8px 4px;
  border-radius: 11px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.04);
  color: #cfe0ec;
  font-size: 9.5px;
  font-weight: 700;
  cursor: pointer;
}
.report-type svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}
.report-type.is-active {
  border-color: var(--accent, #2f6fed);
  background: color-mix(in srgb, var(--accent, #2f6fed) 22%, transparent);
  color: #fff;
}
/* Each type's chip icon carries its own colour (matches the pins + feed). */
.report-type[data-report-type="weather"] svg {
  stroke: #3b82f6;
}
.report-type[data-report-type="harbour"] svg {
  stroke: #10b981;
}
.report-type[data-report-type="water"] svg {
  stroke: #06b6d4;
}
.report-type[data-report-type="hazard"] svg {
  stroke: #f59e0b;
}
/* Hazard photo attach (composer thumbnail + feed thumbnail). */
.report-photo {
  display: flex;
  align-items: center;
  gap: 8px;
}
.report-photo-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 10px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(255, 255, 255, 0.06);
  color: #cfe0ec;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
}
.report-photo-btn svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}
.report-photo-thumb {
  width: 44px;
  height: 44px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.18);
}
.app-report-photo {
  display: block;
  width: 100%;
  max-height: 160px;
  object-fit: cover;
  border-radius: 8px;
  margin-top: 6px;
}
.report-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}
.report-presets:empty {
  display: none;
}
.report-preset {
  padding: 5px 9px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.05);
  color: #cfe0ec;
  font-size: 10px;
  cursor: pointer;
}
.report-preset.is-active {
  border-color: var(--accent, #2f6fed);
  color: #fff;
  background: color-mix(in srgb, var(--accent, #2f6fed) 22%, transparent);
}
.report-note {
  width: 100%;
  box-sizing: border-box;
  padding: 8px 10px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.06);
  color: #eaf2f6;
  font-size: 11.5px;
}
.report-note::placeholder {
  color: #7f9bad;
}
.report-boatname {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.report-boatname label {
  font-size: 9px;
  color: #8fb0c4;
}
.report-status {
  margin: 0;
  font-size: 9.5px;
  line-height: 1.4;
  color: var(--accent, #2f6fed);
  font-weight: 700;
}
.report-actions {
  display: flex;
  gap: 8px;
}
.report-post {
  flex: 1 1 auto;
  padding: 9px;
  border: 0;
  border-radius: 10px;
  background: var(--accent, #2f6fed);
  color: #fff;
  font-size: 12px;
  font-weight: 800;
  cursor: pointer;
}
.report-cancel {
  padding: 9px 12px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 10px;
  background: none;
  color: #cfe0ec;
  font-size: 12px;
  cursor: pointer;
}
.report-privacy {
  margin: 0;
  font-size: 9px;
  line-height: 1.4;
  color: #8fb0c4;
}

/* ---- Hazard proximity prompt (confirm still-there / cleared) ---- */
.map-ctrl.is-on {
  background: var(--accent);
}
.map-ctrl.is-on .ctrl-ic {
  color: #fff;
}
.hazard-prompt {
  position: absolute;
  left: 8px;
  right: 8px;
  top: 44px;
  z-index: 4;
  padding: 10px 12px;
  border-radius: var(--radius);
  background: rgba(6, 20, 28, 0.97);
  border: 1px solid var(--stale, #e0a15a);
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.hazard-prompt[hidden] {
  display: none;
}
.hazard-prompt-body {
  display: flex;
  align-items: center;
  gap: 9px;
}
.hazard-prompt-ic {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: color-mix(in srgb, var(--stale, #e0a15a) 22%, transparent);
  color: var(--stale, #e0a15a);
}
.hazard-prompt-ic svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}
.hazard-prompt-txt {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.hazard-prompt-txt strong {
  font-size: 12.5px;
  color: #eaf2f6;
}
.hazard-prompt-txt span {
  font-size: 10px;
  color: #9db6c6;
  overflow-wrap: anywhere;
}
.hazard-prompt-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}
.hazard-btn {
  border: 0;
  border-radius: 9px;
  padding: 8px 10px;
  font-size: 11.5px;
  font-weight: 800;
  cursor: pointer;
}
.hazard-btn.confirm {
  flex: 1 1 auto;
  background: var(--accent, #2f6fed);
  color: #fff;
}
.hazard-btn.clear {
  flex: 1 1 auto;
  background: color-mix(in srgb, var(--stale, #e0a15a) 24%, transparent);
  color: var(--stale, #e0a15a);
  border: 1px solid var(--stale, #e0a15a);
}
.hazard-btn.dismiss {
  flex: 0 0 auto;
  background: none;
  color: #8fb0c4;
  padding: 6px;
  display: flex;
}

/* ---- Your reports on the Home feed ---- */
.app-reports {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin-bottom: 8px;
}
.app-reports[hidden] {
  display: none;
}
.app-report {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 9px 10px;
  border-radius: var(--radius);
  border: 1px solid var(--line, rgba(0, 0, 0, 0.1));
  background: color-mix(in srgb, var(--accent, #2f6fed) 8%, var(--panel, #fff));
}
.app-report-ic {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent, #2f6fed) 18%, transparent);
  color: var(--accent, #2f6fed);
}
.app-report-ic svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}
.app-report-ic.is-hazard {
  background: color-mix(in srgb, var(--stale) 20%, transparent);
  color: var(--stale);
}
.app-report-txt {
  min-width: 0;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.app-report-txt strong {
  font-size: 12px;
  color: var(--ink, #0b2b3a);
}
.app-report-txt .app-report-note {
  font-size: 11px;
  color: var(--ink, #0b2b3a);
  overflow-wrap: anywhere;
}
.app-report-txt .app-report-meta {
  font-size: 9.5px;
  color: var(--muted, #5a7180);
}
.app-report-del {
  flex: 0 0 auto;
  appearance: none;
  border: 0;
  background: none;
  color: var(--muted, #5a7180);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
}
.route-card {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 12px;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
}
.route-card-head {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin-bottom: 2px;
}
.route-card-head strong {
  font-size: 12.5px;
  color: var(--ink);
}
.route-card-head span {
  font-size: 10.5px;
  color: var(--muted);
}
.route-row {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
}
.route-row span:first-child {
  color: var(--muted);
}
.route-row span:last-child {
  color: var(--ink);
  font-weight: 700;
}
.route-note {
  font-size: 9.5px;
  color: var(--muted);
}

/* ---- Blended "wind near you" card (crowd + NOAA current-location estimate) ---- */
.wind-card {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 12px;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
}
.wind-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.wind-card-title {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
}
.wind-conf {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: none;
  font-size: 9.5px;
  font-weight: 700;
  color: var(--muted);
}
.wind-conf .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--muted);
}
.wind-conf.is-high .dot {
  background: var(--fresh);
}
.wind-conf.is-medium .dot {
  background: var(--recent);
}
.wind-conf.is-low .dot {
  background: var(--stale);
}
.wind-main {
  display: flex;
  align-items: center;
  gap: 12px;
}
.wind-arrow {
  flex: none;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--info);
}
.wind-arrow svg {
  width: 22px;
  height: 22px;
  transition: transform 0.2s ease;
}
.wind-readout {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.wind-readout strong {
  font-size: 16px;
  color: var(--ink);
}
.wind-readout span {
  font-size: 11px;
  color: var(--muted);
}
.wind-prov {
  font-size: 10px;
  color: var(--muted);
  line-height: 1.35;
}
.wind-sources-toggle {
  align-self: flex-start;
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: 10.5px;
  font-weight: 700;
  color: var(--info);
  cursor: pointer;
}
.wind-sources {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.wind-source {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 10px;
  color: var(--muted);
  min-width: 0;
}
.wind-source-bar {
  flex: none;
  width: 40px;
  height: 5px;
  border-radius: 3px;
  background: var(--panel-2);
  overflow: hidden;
}
.wind-source-bar > span {
  display: block;
  height: 100%;
  background: var(--info);
}
.wind-source-tag {
  flex: none;
  font-weight: 800;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  font-size: 8.5px;
  color: var(--calc);
}
.wind-source-txt {
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wind-note {
  font-size: 9px;
  color: var(--muted);
  line-height: 1.4;
}

/* ---- Full-screen GPS-guided navigation (course-up view + HUD) ---- */
.rp-start {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin-top: 2px;
  padding: 9px 12px;
  border: 0;
  border-radius: 11px;
  background: var(--accent);
  color: #fff;
  font: inherit;
  font-size: 12.5px;
  font-weight: 800;
  cursor: pointer;
}
.rp-start svg {
  width: 16px;
  height: 16px;
}
.nav-overlay {
  /* Absolute — NOT fixed. A `position: fixed` box inside the phone frame's
     `transform`ed ancestor (`.phone-screen`) is mis-hit-tested by WebKit
     (Safari / iOS): the HUD paints correctly but taps land nowhere, so every
     button — including End — is visible yet dead. bind() re-homes this node
     directly under `.phone-screen` (its absolute containing block) so `inset: 0`
     still fills the whole frame, with reliable hit-testing on every browser. */
  position: absolute;
  inset: 0;
  z-index: 50;
  overflow: hidden;
  background: #081f33;
  /* Opt the whole nav view out of the browser's native pan/zoom. `touch-action`
     resolves against the touch's start element, so setting it only on the gesture
     layer would let a pinch that starts on the top banner or bottom metrics run
     WebKit's page-zoom instead; on the overlay it covers every touch point while
     taps still route to the z-index-3 HUD buttons. */
  touch-action: none;
}
.nav-view {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  /* Decorative course-up canvas — must never intercept taps meant for the HUD
     buttons (on some mobile browsers it otherwise swallowed every tap, leaving
     the controls, incl. End, unresponsive). */
  pointer-events: none;
}
/* Keep every interactive HUD panel above the canvas (explicit z-index rather
   than relying on paint order, which some mobile browsers get wrong). */
.nav-turn,
.nav-offroute,
.nav-alert,
.nav-verify,
.nav-metrics,
.nav-report,
.nav-exit,
.nav-preview-tag {
  z-index: 3;
}
/* These HUD panels set an explicit `display` (flex), which outranks the UA
   `[hidden] { display: none }` rule — so toggling the `hidden` attribute in JS
   (setVerify, togglePresets, the off-route/alert banners) would leave them on
   screen. That froze the HUD: the verify dialog never dismissed, and the preset
   sheet (z-index 4) stayed permanently over the End/Report buttons so the screen
   couldn't be exited. Restore `hidden` for every nav panel the JS toggles. */
.nav-offroute[hidden],
.nav-alert[hidden],
.nav-verify[hidden],
.nav-presets[hidden],
.nav-toast[hidden] {
  display: none;
}
.nav-turn {
  position: absolute;
  top: 12px;
  left: 12px;
  right: 12px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 13px;
  border-radius: 14px;
  background: rgba(6, 20, 28, 0.86);
  border: 1px solid rgba(255, 255, 255, 0.12);
}
.nav-turn-ic {
  flex: none;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 11px;
  background: rgba(47, 111, 237, 0.22);
  color: #8fd0ff;
}
.nav-turn-ic svg {
  width: 26px;
  height: 26px;
}
.nav-turn-ic.is-left svg {
  transform: scaleX(-1);
}
.nav-turn-txt {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.nav-turn-txt strong {
  font-size: 15px;
  color: #eaf2f6;
}
.nav-turn-txt span {
  font-size: 11px;
  color: #9db6c6;
}
.nav-offroute,
.nav-alert {
  position: absolute;
  top: 84px;
  left: 12px;
  right: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 12px;
  border-radius: 11px;
  font-size: 11.5px;
  font-weight: 700;
  color: #fff;
}
.nav-offroute {
  background: rgba(228, 87, 76, 0.94);
}
.nav-alert {
  background: rgba(232, 161, 59, 0.96);
  color: #21160a;
}
/* When both banners show, drop the hazard alert below the off-route banner. */
.nav-offroute:not([hidden]) ~ .nav-alert:not([hidden]) {
  top: 128px;
}
.nav-offroute svg,
.nav-alert svg {
  width: 18px;
  height: 18px;
  flex: none;
}
.nav-metrics {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 92px;
  display: flex;
  gap: 8px;
}
.nav-metric {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 9px 10px;
  border-radius: 12px;
  background: rgba(6, 20, 28, 0.86);
  border: 1px solid rgba(255, 255, 255, 0.12);
}
.nav-metric span {
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: #8fb0c4;
}
.nav-metric strong {
  font-size: 15px;
  color: #eaf2f6;
}
.nav-metric.is-shallow {
  background: rgba(228, 87, 76, 0.24);
  border-color: rgba(228, 87, 76, 0.6);
}
.nav-metric.is-shallow strong {
  color: #ffd9d4;
}
.nav-preview-tag {
  position: absolute;
  bottom: 66px;
  left: 0;
  right: 0;
  text-align: center;
  font-size: 9px;
  color: #7f9bad;
}
.nav-exit {
  position: absolute;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 18px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  background: rgba(6, 20, 28, 0.9);
  color: #eaf2f6;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}
.nav-exit svg {
  width: 15px;
  height: 15px;
}
/* Passing-hazard verify prompt (reuses the community confirm/clear). */
.nav-verify {
  position: absolute;
  top: 84px;
  left: 12px;
  right: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 11px 13px;
  border-radius: 12px;
  background: rgba(6, 20, 28, 0.94);
  border: 1px solid rgba(232, 161, 59, 0.85);
}
.nav-offroute:not([hidden]) ~ .nav-verify:not([hidden]) {
  top: 128px;
}
.nav-verify-txt {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.nav-verify-txt strong {
  font-size: 13px;
  color: #eaf2f6;
}
.nav-verify-txt span {
  font-size: 10.5px;
  color: #9db6c6;
}
.nav-verify-actions {
  display: flex;
  gap: 8px;
}
.nav-vbtn {
  flex: 1 1 0;
  appearance: none;
  border: 0;
  border-radius: 9px;
  padding: 8px 10px;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}
.nav-vbtn.is-confirm {
  background: #2f6fed;
  color: #fff;
}
.nav-vbtn.is-clear {
  background: rgba(232, 161, 59, 0.18);
  color: #e8a13b;
  border: 1px solid rgba(232, 161, 59, 0.5);
}
.nav-vbtn:disabled {
  opacity: 0.55;
  cursor: default;
}
/* Report-a-hazard-under-way button + preset chooser. */
.nav-report {
  position: absolute;
  bottom: 16px;
  left: 12px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 14px;
  border: 0;
  border-radius: 999px;
  background: rgba(232, 161, 59, 0.96);
  color: #21160a;
  font: inherit;
  font-size: 12px;
  font-weight: 800;
  cursor: pointer;
}
.nav-report svg {
  width: 15px;
  height: 15px;
}
.nav-presets {
  position: absolute;
  bottom: 12px;
  left: 12px;
  right: 12px;
  z-index: 4;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 12px;
  border-radius: 14px;
  background: rgba(6, 20, 28, 0.97);
  border: 1px solid rgba(255, 255, 255, 0.14);
}
.nav-preset {
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 999px;
  padding: 6px 10px;
  background: rgba(255, 255, 255, 0.06);
  color: #eaf2f6;
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
}
.nav-preset.is-cancel {
  background: none;
  color: #9db6c6;
}
.nav-toast {
  position: absolute;
  bottom: 150px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  padding: 8px 14px;
  border-radius: 999px;
  background: rgba(47, 164, 99, 0.96);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
}
/* Verify prompt header: label + a dismiss (×) so it can always be closed. */
.nav-verify-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}
.nav-verify-x {
  flex: none;
  appearance: none;
  border: 0;
  background: none;
  padding: 2px;
  margin: -2px -2px 0 0;
  color: #9db6c6;
  cursor: pointer;
  display: flex;
}
.nav-verify-x svg {
  width: 18px;
  height: 18px;
}
/* Interactive perspective (Waze-style): gesture surface + zoom/overview/recenter.
   The gesture surface sits above the decorative course-up canvas (z-index 0) but
   below the HUD panels (z-index 3), so pinch/drag/scroll pan & zoom the map while
   Still here / Cleared / Report / End stay tappable. `touch-action: none` keeps
   the browser from stealing the drag as a page scroll/zoom. */
.nav-gestures {
  position: absolute;
  inset: 0;
  z-index: 1;
  touch-action: none;
  cursor: grab;
}
.nav-gestures:active {
  cursor: grabbing;
}
.nav-controls {
  position: absolute;
  right: 12px;
  /* Anchored to the lower-right and growing upward, so the column can never rise
     into the top-anchored turn/off-route/verify stack on short or narrow phones
     (a vertically-centred column would on ~320px viewports). Stays clear of the
     metrics row (bottom: 92px) too. */
  bottom: 150px;
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.nav-ctrl {
  appearance: none;
  cursor: pointer;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 0;
  background: rgba(255, 255, 255, 0.96);
  color: #0b2b3a;
  font-family: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.3);
  transition: transform 0.1s ease;
}
.nav-ctrl:active {
  transform: scale(0.94);
}
.nav-ctrl svg {
  width: 20px;
  height: 20px;
}
.nav-ctrl.is-on {
  background: #2f6fed;
  color: #fff;
}
/* Re-center pill — appears only when not following (panned / zoomed / overview).
   Sits above the toast slot (bottom: 150px) so a report toast never covers it. */
.nav-recenter {
  position: absolute;
  left: 50%;
  bottom: 200px;
  transform: translateX(-50%);
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 16px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.96);
  color: #0b2b3a;
  font: inherit;
  font-size: 12px;
  font-weight: 800;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.32);
  cursor: pointer;
}
.nav-recenter svg {
  width: 15px;
  height: 15px;
}
/* `.nav-recenter` sets `display: inline-flex`, which would defeat the `hidden`
   attribute — restore it (same reason as the other toggled nav panels above). */
.nav-recenter[hidden] {
  display: none;
}

/* Route planner (interactive water-only routing) */
.route-planner {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 12px;
  border-radius: 14px;
  background: var(--panel);
  border: 1px solid var(--line);
}
.rp-field {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0 8px;
}
.rp-dot {
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.15);
}
.rp-dot.start {
  background: var(--accent2, #58c0a0);
}
.rp-dot.dest {
  background: var(--accent);
}
.rp-input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: none;
  color: var(--ink);
  font-family: inherit;
  font-size: 12px;
  padding: 9px 0;
  outline: none;
}
.rp-input::placeholder {
  color: var(--muted);
}
.rp-icon {
  flex: none;
  appearance: none;
  border: 0;
  background: none;
  cursor: pointer;
  padding: 4px;
  display: flex;
  color: var(--accent);
}
.rp-icon svg {
  width: 18px;
  height: 18px;
}
.rp-icon.is-armed {
  color: #fff;
  background: var(--accent);
  border-radius: 8px;
}
.rp-actions {
  display: flex;
  gap: 8px;
}
.rp-go,
.rp-clear {
  appearance: none;
  border: 0;
  cursor: pointer;
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  border-radius: 10px;
  padding: 9px 12px;
}
.rp-go {
  flex: 1;
  background: var(--accent);
  color: #06202c;
}
.rp-go:disabled {
  opacity: 0.5;
  cursor: default;
}
.rp-clear {
  background: var(--panel-2);
  color: var(--muted);
  border: 1px solid var(--line);
}
.rp-status {
  font-size: 10.5px;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 6px;
}
.rp-status.error {
  color: var(--stale, #e0a15a);
}
.rp-status.note {
  color: var(--accent, #2f6fed);
}
.rp-status.busy::before {
  content: "";
  width: 11px;
  height: 11px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: rp-spin 0.7s linear infinite;
}
@keyframes rp-spin {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .rp-status.busy::before {
    animation: none;
  }
}
.rp-result {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 4px;
  border-top: 1px solid var(--line);
}
/* Route endpoint markers (Leaflet/MapKit divIcons) */
.rt-marker {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.5);
}
.rt-marker.start {
  background: var(--accent2, #58c0a0);
}
.rt-marker.dest {
  background: var(--accent);
}
.rt-marker svg {
  width: 13px;
  height: 13px;
  color: #fff;
}

/* Trips screen */
.trip {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 11px 12px;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
}
.trip.recording {
  border-color: var(--fresh);
}
/* History rows (board 3c): the 52×40 track-sparkline chip leads the row; the
   date + stats stack beside it and the export affordance keeps its slot. */
.trip.history {
  flex-direction: row;
  align-items: center;
  gap: 11px;
}
/* Swipe-to-delete (approved Turn 2 interaction): each history row rides above
   its Delete action; dragging left (wired by initTripSwipe) reveals it. The
   row's opaque panel background covers the action while closed. */
.trip-swipe {
  position: relative;
}
.trip-delete {
  appearance: none;
  cursor: pointer;
  font-family: inherit;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  width: 84px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  font-size: 10.5px;
  font-weight: 800;
  color: #fff;
  background: var(--stale);
  border: 0;
  border-radius: var(--radius);
}
.trip-delete svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.trip-swipe .trip.history {
  position: relative;
  z-index: 1;
  /* Horizontal drags are ours; vertical scrolling stays the browser's. */
  touch-action: pan-y;
  user-select: none;
  transition: transform 0.18s ease-out;
}
.trip-swipe.is-dragging .trip.history {
  transition: none;
}
.trip-swipe.is-open .trip.history {
  transform: translateX(-84px);
}
/* Keyboard path: tabbing to the Delete button slides its row open. */
.trip-swipe:has(.trip-delete:focus-visible) .trip.history {
  transform: translateX(-84px);
}
.trips-empty {
  margin: 0;
  padding: 8px 0;
  text-align: center;
  font-size: 10.5px;
  color: var(--muted);
}
.trip-spark {
  flex: none;
  background: var(--panel-2);
  border-radius: 10px;
}
.trip-spark polyline {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.trip-txt {
  display: flex;
  flex-direction: column;
  gap: 5px;
  flex: 1;
  min-width: 0;
}
.trip-txt .trip-stats {
  flex-wrap: wrap;
  gap: 4px 10px;
}
.trip-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.trip-date {
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
}
.trip-badge {
  font-size: 8.5px;
  font-weight: 800;
  color: var(--fresh);
  background: var(--bg);
  padding: 2px 7px;
  border-radius: 999px;
}
.trip-exp {
  color: var(--accent);
  display: flex;
}
.exp-ic {
  width: 16px;
  height: 16px;
}
.trip-stats {
  display: flex;
  gap: 12px;
}
.trip-stat {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--muted);
}
.stat-ic {
  width: 13px;
  height: 13px;
  color: var(--muted);
  flex: none;
}
.close-ic {
  width: 16px;
  height: 16px;
}
.rec-btn {
  appearance: none;
  border: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 5px;
  font-family: inherit;
  font-size: 11px;
  font-weight: 800;
  color: var(--accent);
  background: none;
}
.rec-btn .rec-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 2px solid var(--accent);
}
.rec-btn.on {
  color: var(--stale);
}
.rec-btn.on .rec-dot {
  border-color: var(--stale);
  background: var(--stale);
  border-radius: 2px;
}

/* Boat screen form */
.form-section {
  display: flex;
  flex-direction: column;
  padding: 11px 12px;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
}
.form-title {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--muted);
  padding-bottom: 3px;
}
.form-note {
  font-size: 10px;
  color: var(--muted);
  padding-top: 5px;
}
.connect-btn {
  appearance: none;
  border: 0;
  cursor: pointer;
  margin-top: 8px;
  font-family: inherit;
  font-size: 12px;
  font-weight: 800;
  color: #fff;
  background: var(--accent);
  padding: 9px;
  border-radius: 11px;
}
.form-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 0;
  border-top: 1px solid var(--line);
  font-size: 12.5px;
  color: var(--ink);
}
.form-section .form-row:first-of-type {
  border-top: 0;
}
.form-row.stack {
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
}
.form-row-txt {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.form-row-txt span {
  font-size: 12.5px;
  color: var(--ink);
}
.form-row-txt small {
  font-size: 10px;
  color: var(--muted);
}
.form-val {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--muted);
}
/* Read-only unit rows say why they are fixed and visibly are not controls
   (board 3d): muted italic — no value dressed as a control. */
.form-val.fixed {
  font-style: italic;
  font-weight: 650;
}
.form-val.mono {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.5px;
  color: var(--accent);
}
.seg {
  display: flex;
  gap: 4px;
  background: var(--bg);
  padding: 3px;
  border-radius: 10px;
}
.seg-opt {
  flex: 1;
  /* Allow the options to shrink to share the row on very narrow phones instead
     of forcing the segmented control past the screen edge. */
  min-width: 0;
  appearance: none;
  border: 0;
  cursor: pointer;
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 700;
  color: var(--muted);
  background: none;
  padding: 6px 4px;
  border-radius: 8px;
}
.seg-opt.active {
  color: var(--ink);
  background: var(--panel);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}
/* Compact °C/°F quick toggle — used in the Conditions nav bar (right where the
   temperatures are read) and in Boat → Display units. Display-only: it changes
   the scale shown, never the stored reading. */
.unit-seg {
  display: inline-flex;
  flex: none;
  gap: 2px;
  padding: 2px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 999px;
}
.unit-seg-opt {
  appearance: none;
  border: 0;
  cursor: pointer;
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 800;
  line-height: 1;
  color: var(--muted);
  background: none;
  padding: 5px 9px;
  border-radius: 999px;
}
.unit-seg-opt.active {
  color: var(--ink);
  background: var(--panel);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}
.toggle {
  appearance: none;
  border: 0;
  cursor: pointer;
  width: 40px;
  height: 24px;
  border-radius: 999px;
  background: var(--line);
  position: relative;
  flex: none;
  transition: background 0.15s;
}
.toggle.is-on {
  background: var(--fresh);
}
.toggle-knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  transition: left 0.15s;
}
.toggle.is-on .toggle-knob {
  left: 18px;
}
.stepper {
  display: flex;
  align-items: center;
  gap: 2px;
  background: var(--bg);
  border-radius: 9px;
  padding: 2px;
}
.step-btn {
  appearance: none;
  border: 0;
  cursor: pointer;
  width: 26px;
  height: 24px;
  border-radius: 7px;
  background: var(--panel);
  color: var(--ink);
  font-size: 15px;
  font-weight: 700;
  font-family: inherit;
}
.step-val {
  min-width: 48px;
  text-align: center;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--ink);
}

section h2 {
  font-size: clamp(24px, 3.4vw, 34px);
  text-align: center;
  margin: 0 0 32px;
  letter-spacing: -0.3px;
}

/* Embedded live bridge dashboard */
.bridge-embed {
  padding: 64px 0 84px;
  border-top: 1px solid #10344a;
}
.bridge-window {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
  overflow: hidden;
  background: var(--panel);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.35);
}
.bridge-chrome {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
}
.bridge-dots {
  display: inline-flex;
  gap: 6px;
  flex: none;
}
.bridge-dots i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--line);
}
.bridge-addr {
  font-size: 12px;
  color: var(--muted);
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bridge-open {
  margin-left: auto;
  flex: none;
  font-size: 12px;
  font-weight: 700;
  color: var(--accent);
  text-decoration: none;
}
.bridge-stage {
  position: relative;
  height: clamp(420px, 68vh, 680px);
  background: var(--panel);
}
.bridge-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
.bridge-placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
  padding: 24px;
  color: var(--muted);
}
.bridge-placeholder svg {
  width: 34px;
  height: 34px;
  color: var(--accent);
}
.bridge-placeholder strong {
  color: var(--ink);
  font-size: 16px;
}
.bridge-placeholder span {
  max-width: 48ch;
  font-size: 13px;
  line-height: 1.5;
}
.bridge-placeholder code {
  background: var(--panel-2);
  padding: 1px 5px;
  border-radius: 5px;
  font-size: 12px;
}
.bridge-note {
  margin-top: 12px;
  font-size: 12px;
  color: var(--muted);
}

/* --- The conditions network band (full-bleed, R6) --- */
.network {
  position: relative;
  overflow: hidden;
  border-top: 1px solid #10344a;
}
.net-stage {
  position: absolute;
  inset: 0;
}
.net-map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
.net-depth {
  fill: #4d84a0;
  font-size: 13px;
  font-style: italic;
  font-family: Georgia, serif;
}
.net-pin,
.net-station,
.net-vessel {
  position: absolute;
  left: var(--x);
  top: var(--y);
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.net-pin.dim {
  opacity: 0.9;
}
.net-pin.dimmer {
  opacity: 0.72;
}
.net-pin-ring {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 2px solid var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(10, 39, 57, 0.5);
}
.net-pin-ring svg {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.net-pin-tag {
  font-size: 11px;
  font-weight: 800;
  color: var(--ink);
  background: var(--panel);
  border: 1px solid var(--line);
  padding: 2px 9px;
  border-radius: 999px;
  white-space: nowrap;
}
.net-station-ic {
  width: 38px;
  height: 38px;
  border-radius: 11px;
  background: #f2c14e;
  border: 2.5px solid rgba(255, 255, 255, 0.9);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
}
.net-station-ic svg {
  fill: none;
  stroke: #5c4308;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.net-station-tag {
  font-size: 10px;
  font-weight: 900;
  color: #5c4308;
  background: #f9e2a6;
  padding: 2px 8px;
  border-radius: 999px;
  white-space: nowrap;
}
.net-vessel svg {
  position: relative;
  transform: rotate(-16deg);
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.35));
}
.net-vessel svg path {
  fill: var(--accent);
  stroke: #fff;
  stroke-width: 2.5;
  stroke-linejoin: round;
}
.net-vessel-halo {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 46px;
  height: 46px;
  margin: -23px 0 0 -23px;
  border-radius: 50%;
  background: var(--accent);
  animation: net-pulse 2.4s ease-out infinite;
}
@keyframes net-pulse {
  0% {
    transform: scale(1);
    opacity: 0.55;
  }
  100% {
    transform: scale(2.6);
    opacity: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .net-vessel-halo {
    animation: none;
    opacity: 0.25;
  }
}
.net-wind {
  position: absolute;
  right: 4.5%;
  top: 44px;
  width: 280px;
  background: rgba(7, 30, 41, 0.92);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 15px 16px;
  display: flex;
  flex-direction: column;
  gap: 9px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.4);
}
.net-wind-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.net-wind-title {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1.2px;
  color: var(--muted);
  text-transform: uppercase;
}
.net-wind-conf {
  font-size: 10px;
  font-weight: 800;
  color: var(--fresh);
}
.net-wind-main {
  display: flex;
  align-items: center;
  gap: 11px;
}
.net-wind-main svg path {
  fill: var(--accent);
}
.net-wind-readout {
  display: flex;
  flex-direction: column;
}
.net-wind-readout strong {
  font-size: 24px;
  font-weight: 800;
  color: var(--ink);
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.net-wind-readout span {
  font-size: 12px;
  font-weight: 650;
  color: var(--muted);
}
.net-wind-prov {
  font-size: 11px;
  font-weight: 650;
  color: var(--muted);
  line-height: 1.45;
}
.net-wrap {
  position: relative;
  height: 520px;
  display: flex;
  align-items: center;
}
.net-copy {
  max-width: 430px;
  border-radius: 22px;
  padding: 24px 26px;
  background: radial-gradient(
    130% 110% at 20% 40%,
    rgba(5, 20, 29, 0.85),
    rgba(5, 20, 29, 0.55) 60%,
    rgba(5, 20, 29, 0.2)
  );
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.net-eyebrow-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.net-eyebrow-row .eyebrow {
  margin: 0;
}
.net-copy h2 {
  margin: 0;
  text-align: left;
  font-size: clamp(26px, 3vw, 33px);
  line-height: 1.14;
  letter-spacing: -0.5px;
  text-wrap: balance;
}
.net-copy .lede {
  margin: 0;
  font-size: 15.5px;
  line-height: 1.6;
}
.net-caption {
  font-size: 11px;
  font-weight: 650;
  color: var(--muted);
}
@media (max-width: 820px) {
  .net-wrap {
    height: auto;
    padding-top: 40px;
    padding-bottom: 300px;
  }
  .net-copy {
    max-width: 560px;
  }
  .net-stage {
    top: auto;
    height: 280px;
    bottom: 0;
  }
  .net-wind {
    right: 12px;
    top: 10px;
    width: 240px;
    padding: 11px 12px;
  }
  .net-wind-readout strong {
    font-size: 19px;
  }
}
/* Tiny screens: the chart stage is small — compact the illustrative wind card
   so the observation pins stay visible (the honest caption lives in the copy
   panel above). */
@media (max-width: 560px) {
  .net-wind {
    width: 180px;
    gap: 6px;
  }
  .net-wind-prov {
    display: none;
  }
  .net-wind-readout span {
    font-size: 10.5px;
  }
}

.features {
  padding: 64px 0 56px;
  border-top: 1px solid #10344a;
}
/* One band-head pattern for every section: eyebrow, left-set h2, lede. */
.band-head {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 720px;
  margin-bottom: 30px;
}
.band-head h2 {
  text-align: left;
  margin: 0;
  font-size: clamp(26px, 3.4vw, 36px);
  line-height: 1.12;
  letter-spacing: -0.6px;
}
.band-head .eyebrow {
  margin: 0;
}
.band-head .lede {
  margin: 4px 0 0;
  font-size: 16.5px;
  max-width: 58ch;
}
.grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
.feature {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.feature-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.feature-ic {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.feature-ic .ic-fill {
  fill: var(--accent);
  stroke: none;
}
.feature h3 {
  margin: 0;
  font-size: 17.5px;
  font-weight: 750;
}
.feature p {
  color: var(--muted);
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  text-wrap: pretty;
}
/* Honest status chips — the only claims-language for flag-gated work. */
.chip-status {
  flex: none;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.6px;
  border-radius: 5px;
  padding: 3px 8px;
}
.chip-status.preview {
  color: var(--recent);
  background: color-mix(in srgb, var(--recent) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--recent) 40%, transparent);
}
.chip-status.coming {
  color: var(--eyebrow);
  background: rgba(74, 144, 217, 0.14);
  border: 1px solid rgba(74, 144, 217, 0.4);
}
.chip-status.built {
  color: var(--fresh);
  background: color-mix(in srgb, var(--fresh) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--fresh) 40%, transparent);
}
.chip-status.neutral {
  color: var(--muted);
  background: rgba(152, 167, 176, 0.12);
  border: 1px solid rgba(152, 167, 176, 0.35);
}
.slipway {
  margin-top: 16px;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  background: rgba(11, 43, 58, 0.5);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  padding: 16px 22px;
}
.slipway-label {
  flex: none;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1.4px;
  color: var(--muted);
  text-transform: uppercase;
}
.slipway-items {
  display: flex;
  gap: 9px;
  flex-wrap: wrap;
  min-width: 0;
}
.slipway-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 650;
  color: var(--body);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 7px 13px;
}

.how {
  padding: 64px 0;
  border-top: 1px solid #10344a;
  background: rgba(9, 36, 49, 0.5);
}
.steps {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
.steps li {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 20px 22px;
}
.step-n {
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(74, 144, 217, 0.16);
  border: 1px solid rgba(74, 144, 217, 0.5);
  color: var(--eyebrow);
  font-size: 15px;
  font-weight: 800;
  display: grid;
  place-items: center;
}
.steps h3 {
  margin: 0 0 6px;
  font-size: 16px;
  font-weight: 750;
}
.steps p {
  margin: 0;
  color: var(--muted);
  font-size: 13.5px;
  line-height: 1.55;
}

.foot {
  border-top: 1px solid #10344a;
  background: rgba(6, 26, 36, 0.6);
  padding: 26px 0 40px;
  font-size: 13.5px;
}
.foot-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px 24px;
  flex-wrap: wrap;
}
.foot-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--muted);
  font-weight: 650;
}
.foot-note {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
}
.muted {
  color: var(--muted);
}

/* --- Auth dialog --- */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(3, 12, 18, 0.72);
  backdrop-filter: blur(4px);
  display: grid;
  place-items: center;
  padding: 20px;
  z-index: 20;
  animation: mt-overlay 0.18s ease-out;
}
.overlay[hidden] {
  display: none;
}
.auth-card {
  width: min(420px, 100%);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 28px 26px 22px;
  position: relative;
  box-shadow: 0 40px 80px -30px rgba(0, 0, 0, 0.7);
  animation: mt-pop 0.24s cubic-bezier(0.2, 0.9, 0.3, 1);
}
.auth-close {
  position: absolute;
  top: 10px;
  right: 14px;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  z-index: 2;
}
.auth-view[hidden] {
  display: none;
}
.auth-card h2 {
  margin: 4px 0 6px;
  font-size: 22px;
}
.auth-sub {
  color: var(--muted);
  margin: 0 0 20px;
  font-size: 15px;
}
.providers {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.google-slot {
  min-height: 44px;
  display: flex;
  justify-content: center;
}
.google-slot[hidden] {
  display: none;
}
.provider-btn {
  width: 280px;
  max-width: 100%;
  height: 44px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  cursor: pointer;
}
/* Interaction states (R16): hover elevation, pressed reset, disabled fade —
   visual only, the provider markup and flow stay untouched. */
.provider-btn {
  transition:
    transform 0.08s ease,
    box-shadow 0.15s ease,
    filter 0.15s ease;
}
.provider-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
}
.provider-btn:active {
  transform: translateY(0);
}
.provider-btn:disabled,
.btn-fill:disabled,
.btn:disabled {
  opacity: 0.5;
  cursor: default;
  transform: none;
  box-shadow: none;
}
.provider-btn[hidden] {
  display: none;
}
.provider-btn.google {
  background: #131314;
  border: 1px solid #3c4043;
  color: #e3e3e3;
}
.provider-btn.apple {
  background: #000;
  border: 1px solid #000;
  color: #fff;
  gap: 8px;
}
.apple-btn {
  width: 280px;
  max-width: 100%;
  height: 44px;
  border-radius: 999px;
  border: none;
  background: #000;
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  cursor: pointer;
}
.apple-btn[hidden] {
  display: none;
}
.apple-btn:hover {
  background: #111;
}
.auth-note {
  color: var(--recent);
  font-size: 13px;
  min-height: 18px;
  text-align: center;
  margin: 14px 0 0;
}
.auth-note:empty {
  min-height: 0;
  margin: 0;
}
.auth-legal {
  color: var(--muted);
  font-size: 12px;
  text-align: center;
  margin: 18px 0 0;
}
.auth-link {
  display: block;
  width: 100%;
  text-align: center;
  margin-top: 14px;
  font-size: 13px;
  color: var(--muted);
  background: none;
  border: none;
  cursor: pointer;
}
.auth-link:hover {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.auth-link:disabled {
  opacity: 0.5;
  cursor: default;
  text-decoration: none;
}

/* Google chooser (demo) */
.g-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
}
.g-head span {
  font-size: 15px;
  color: #e3e3e3;
  font-weight: 500;
}
.g-sheet {
  background: #1f1f1f;
  border: 1px solid #3c4043;
  border-radius: 12px;
  padding: 20px 18px;
}
.g-title {
  margin: 0 0 4px;
  font-size: 20px;
  color: #e8eaed;
  font-weight: 400;
}
.g-sub {
  margin: 0 0 16px;
  font-size: 13px;
  color: #9aa0a6;
}
.g-sub span {
  color: #8ab4f8;
}
.g-acct {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 8px;
  border-radius: 8px;
  cursor: pointer;
  width: 100%;
  background: none;
  border: none;
  text-align: left;
}
.g-acct:hover {
  background: #2a2b2d;
}
.g-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #7e57c2;
  color: #fff;
  display: grid;
  place-items: center;
  font-weight: 600;
  font-size: 15px;
  flex: none;
}
.g-avatar.ghost {
  background: #3c4043;
}
.g-acct-txt {
  display: flex;
  flex-direction: column;
  font-size: 14px;
  color: #e8eaed;
}
.g-acct-txt small {
  font-size: 13px;
  color: #9aa0a6;
}

/* Apple sheet (demo) */
.a-sheet {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 6px 0 2px;
}
.a-logo {
  fill: var(--ink);
}
.a-title {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  text-align: center;
}
.a-detail {
  width: 100%;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 4px;
}
.a-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.a-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--line);
  display: grid;
  place-items: center;
  flex: none;
}
.a-acct-txt {
  display: flex;
  flex-direction: column;
}
.a-acct-txt strong {
  font-size: 14px;
}
.a-acct-txt small {
  font-size: 13px;
  color: var(--muted);
}
.a-hide {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-top: 1px solid var(--line);
  padding-top: 10px;
  font-size: 13px;
  color: var(--muted);
}
.a-on {
  color: var(--accent);
  font-weight: 600;
}
.btn-fill {
  width: 100%;
  height: 46px;
  border-radius: 12px;
  background: var(--accent);
  color: #04141d;
  font-weight: 700;
  font-size: 15px;
  display: grid;
  place-items: center;
  border: none;
  cursor: pointer;
  transition:
    transform 0.08s ease,
    filter 0.15s ease;
}
.btn-fill:hover {
  transform: translateY(-1px);
  filter: brightness(1.08);
}
.btn-fill:active {
  transform: translateY(0);
}
.a-sheet .btn-fill {
  height: 44px;
  background: var(--ink);
  margin-top: 2px;
}

/* Signing in */
.signing {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 26px 0;
  color: var(--muted);
  font-size: 15px;
}
.spinner {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 3px solid var(--line);
  border-top-color: var(--accent);
  animation: mt-spin 0.8s linear infinite;
}

/* Signed in */
.signed {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 8px 0 2px;
}
.signed-avatar {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--accent);
  color: #04141d;
  display: grid;
  place-items: center;
  font-weight: 800;
  font-size: 22px;
}
.signed h2 {
  margin: 0;
  font-size: 22px;
}
.signed-sub {
  margin: 0;
  color: var(--muted);
  font-size: 15px;
  text-align: center;
}
.signed-sub strong {
  color: var(--ink);
}
.signed-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  margin-top: 4px;
}
.signed-actions .btn {
  width: 100%;
}

@keyframes mt-overlay {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes mt-pop {
  from {
    opacity: 0;
    transform: translateY(14px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes mt-spin {
  to {
    transform: rotate(360deg);
  }
}

@media (max-width: 820px) {
  .hero {
    padding: 40px 0;
  }
  .hero-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .hero-card {
    order: -1;
  }
  .tryit-grid {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    text-align: center;
  }
  .tryit-copy h2 {
    text-align: center;
  }
  .tryit-list {
    text-align: left;
    display: inline-flex;
  }
  /* Single-column: the phone becomes fluid so it shrinks to fit narrow
     viewports (≤360px) instead of overflowing. Here the column is full-width,
     so `100%` resolves cleanly (unlike the desktop `auto` grid track, which
     keeps the fixed 320×660). aspect-ratio holds the 320:660 proportions. */
  .phone {
    width: min(320px, 100%);
    height: auto;
    aspect-ratio: 320 / 660;
  }
  /* On a single column the scrim's copy blocks span the full gutter, so their
     background bleed must not exceed it — otherwise it pushes 2px past the
     viewport and creates a horizontal scrollbar. Keep the bleed inside the
     24px page gutter while the text stays aligned to it. */
  .scrim {
    margin-left: -20px;
    margin-right: -20px;
    padding-left: 20px;
    padding-right: 20px;
  }
  .grid,
  .steps {
    grid-template-columns: minmax(0, 1fr);
  }
  .nav a {
    display: none;
  }
}

/* Extra-small phones: tighten the biggest vertical gaps so the fold isn't
   mostly empty space, and let the hero mini-cards stack to one column when
   two no longer fit comfortably. */
@media (max-width: 400px) {
  .hero {
    padding: 28px 0;
  }
  .hero-card {
    grid-template-columns: minmax(0, 1fr);
  }
  .mini-card.wide {
    grid-column: auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .overlay,
  .auth-card {
    animation: none;
  }
  .spinner {
    animation-duration: 2s;
  }
}

/* ===================== The design band + pitch deck ===================== */
/* Cards are real renders of the working design boards; the deck viewer
   reads its slides from the cards (initDesignDeck). */
.design-band {
  padding: 84px 0 96px;
  background: rgba(12, 40, 54, 0.45);
  border-top: 1px solid var(--line);
}
.deck-play {
  margin-top: 18px;
  width: auto;
  align-self: flex-start;
}
.design-grid {
  margin-top: 34px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 14px;
}
.design-card {
  appearance: none;
  cursor: pointer;
  font: inherit;
  text-align: left;
  color: var(--ink);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px 10px 12px;
  background: rgba(7, 30, 41, 0.72);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition:
    transform 0.16s ease,
    border-color 0.16s ease;
}
.design-card:hover {
  transform: translateY(-2px);
  border-color: rgba(74, 144, 217, 0.55);
}
.design-thumb {
  display: block;
  height: 200px;
  overflow: hidden;
  border-radius: 10px;
  background: #0c2330;
}
.design-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}
.design-card-txt {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 0 3px;
}
.design-card-txt strong {
  font-size: 14.5px;
}
.design-card-txt span {
  font-size: 12px;
  line-height: 1.45;
  color: var(--muted);
}
.design-card .chip-status {
  align-self: flex-start;
  margin: 0 3px;
}

/* The deck viewer. `display: flex` outranks the UA [hidden] rule, so the
   override below keeps `hidden` honest (the recurring §5.10 family). */
.deck-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px;
  background: rgba(3, 14, 20, 0.82);
  backdrop-filter: blur(6px);
}
.deck-overlay[hidden] {
  display: none;
}
.deck {
  width: min(960px, 100%);
  max-height: 94vh;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px 16px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
}
.deck-top {
  display: flex;
  align-items: center;
  gap: 10px;
}
.deck-title {
  font-size: 16px;
  color: var(--ink);
}
.deck-count {
  margin-left: auto;
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.deck-zoom {
  appearance: none;
  cursor: pointer;
  font: inherit;
  font-size: 11.5px;
  font-weight: 800;
  color: var(--muted);
  background: none;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 4px 10px;
}
.deck-zoom[aria-pressed="true"] {
  color: var(--ink);
  border-color: var(--accent);
}
.deck-close {
  appearance: none;
  cursor: pointer;
  border: 0;
  background: none;
  color: var(--muted);
  font-size: 22px;
  line-height: 1;
  padding: 2px 6px;
}
.deck-close:hover {
  color: var(--ink);
}
.deck-stage {
  min-height: 0;
  flex: 1;
  overflow: auto;
  border-radius: 12px;
  background: #0c2330;
  /* Horizontal swipes drive the deck; vertical scrolling stays native. */
  touch-action: pan-y;
}
.deck-img {
  display: block;
  max-width: 100%;
  max-height: 64vh;
  width: auto;
  height: auto;
  margin: 0 auto;
  user-select: none;
}
.deck.is-zoomed .deck-img {
  max-width: none;
  max-height: none;
  width: 100%;
}
.deck-desc {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}
.deck-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
}
.deck-arrow {
  appearance: none;
  cursor: pointer;
  font: inherit;
  font-size: 20px;
  line-height: 1;
  color: var(--ink);
  background: rgba(74, 144, 217, 0.14);
  border: 1px solid var(--line);
  border-radius: 999px;
  width: 38px;
  height: 38px;
}
.deck-arrow:hover {
  border-color: var(--accent);
}
.deck-dots {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: center;
}
.deck-dot {
  appearance: none;
  cursor: pointer;
  border: 0;
  padding: 0;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(152, 167, 176, 0.4);
}
.deck-dot.is-on {
  background: var(--accent);
}
@media (max-width: 560px) {
  .design-grid {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  }
  .design-thumb {
    height: 150px;
  }
}
