/* Shared styles for ergdog.hendrikvh.com, in the product's own visual style: the firmware's
   docs/STYLE_GUIDE.md ("Under the waterline"). A night sky across the top holds the header and the
   page's headline, the mascot rows on the waterline under it, a royal-blue sea sits fixed behind
   everything, and the detail floats on flat, cut-cornered plates. The scene is drawn by scene.js
   (generated from the firmware, so it matches the device and the share card) and placed by
   site.js. One plain stylesheet, no build step.

   No web fonts: the faces are the ones iOS and macOS ship (DIN Condensed, Futura, Avenir Next),
   with the nearest thing each other system has, so nothing is fetched from anyone else to show a
   page about keeping your data to yourself. */

:root {
  --sky-top: #0d1430;
  --sky-bottom: #2a3d68;
  --sea-1: #2f7bdc;
  --sea-2: #2a6dd0;
  --sea-3: #2460c4;
  --shallows: #6cc2f7;
  /* Text set on the sky, which light mode turns dark. */
  --sky-text: #ffffff;
  --sky-dim: #b9d3e8;
  --text: #ffffff;
  --text-dim: #c8dbeb;
  --text-faint: #9db9d2;
  --line: rgba(255, 255, 255, 0.14);
  --rule: rgba(255, 255, 255, 0.3);
  --well: rgba(255, 255, 255, 0.1);
  --plate-solid: #12347a;
  --ink: #0a1830;
  --accent: #ffa229;
  --moon: #ffefb8;
  /* The wordmark's two halves (img/wordmark.svg reads these): "Erg" in the sky's text colour,
     "Dog" in the moon's, warm orange by day. */
  --wm-erg: var(--sky-text);
  --wm-dog: var(--moon);
  --good: #6ee7a8;
  --warn: #ffbf4d;
  --bad: #ff7a6b;
  --glow: #7fe6ff;
  --accent-text: var(--glow);
  --success: var(--good);
  --danger: var(--bad);
  --font-body: "Avenir Next", Avenir, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-display: "DIN Condensed", "Bahnschrift Condensed", "Avenir Next Condensed", "Roboto Condensed", "Arial Narrow", sans-serif-condensed, sans-serif;
  --font-caps: Futura, "Century Gothic", "Avenir Next", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  /* The cut-cornered shapes, as 9-slice images: plates cut 12px, buttons 7px, tags and chips 5px.
     The corners stay exact at any size, the edge included, and they cost no layout. */
  --img-plate: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48'%3E%3Cpath d='M12 0.75H36L47.25 12V36L36 47.25H12L0.75 36V12Z' fill='%230a2160' fill-opacity='0.8' stroke='%23fff' stroke-opacity='0.22' stroke-width='1.5'/%3E%3C/svg%3E");
  --img-plate-hover: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48'%3E%3Cpath d='M12 0.75H36L47.25 12V36L36 47.25H12L0.75 36V12Z' fill='%230a2160' fill-opacity='0.88' stroke='%23fff' stroke-opacity='0.45' stroke-width='1.5'/%3E%3C/svg%3E");
  --img-plate-solid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cpath d='M8 0.75H24L31.25 8V24L24 31.25H8L0.75 24V8Z' fill='%2312347a' stroke='%23fff' stroke-opacity='0.3' stroke-width='1.5'/%3E%3C/svg%3E");
  --img-tag: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20'%3E%3Cpath d='M5 0.625H15L19.375 5V15L15 19.375H5L0.625 15V5Z' fill='none' stroke='%23fff' stroke-opacity='0.4' stroke-width='1.25'/%3E%3C/svg%3E");
  --img-tag-ink: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20'%3E%3Cpath d='M5 0.625H15L19.375 5V15L15 19.375H5L0.625 15V5Z' fill='none' stroke='%230a1830' stroke-opacity='0.5' stroke-width='1.25'/%3E%3C/svg%3E");
  --img-btn: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28'%3E%3Cpath d='M7 0.75H21L27.25 7V21L21 27.25H7L0.75 21V7Z' fill='%23fff' fill-opacity='0.04' stroke='%23fff' stroke-opacity='0.6' stroke-width='1.5'/%3E%3C/svg%3E");
  --img-btn-ink: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28'%3E%3Cpath d='M7 0.75H21L27.25 7V21L21 27.25H7L0.75 21V7Z' fill='none' stroke='%230a1830' stroke-opacity='0.55' stroke-width='1.5'/%3E%3C/svg%3E");
  --img-btn-hover: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28'%3E%3Cpath d='M7 0.75H21L27.25 7V21L21 27.25H7L0.75 21V7Z' fill='%23fff' fill-opacity='0.14' stroke='%23fff' stroke-opacity='0.9' stroke-width='1.5'/%3E%3C/svg%3E");
  --img-btn-primary: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28'%3E%3Cpath d='M7 0H21L28 7V21L21 28H7L0 21V7Z' fill='%23ffa229'/%3E%3C/svg%3E");
  --img-btn-primary-hover: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28'%3E%3Cpath d='M7 0H21L28 7V21L21 28H7L0 21V7Z' fill='%23ffb54d'/%3E%3C/svg%3E");
  --img-btn-danger: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28'%3E%3Cpath d='M7 0H21L28 7V21L21 28H7L0 21V7Z' fill='%23ff7a6b'/%3E%3C/svg%3E");
  --img-btn-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28'%3E%3Cpath d='M7 0.75H21L27.25 7V21L21 27.25H7L0.75 21V7Z' fill='%23fff' fill-opacity='0.03' stroke='%23fff' stroke-opacity='0.2' stroke-width='1.5'/%3E%3C/svg%3E");
  --img-chip: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20'%3E%3Cpath d='M5 0.625H15L19.375 5V15L15 19.375H5L0.625 15V5Z' fill='none' stroke='%23fff' stroke-opacity='0.22' stroke-width='1.25'/%3E%3C/svg%3E");
  --img-chip-on: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20'%3E%3Cpath d='M5 0.625H15L19.375 5V15L15 19.375H5L0.625 15V5Z' fill='%23fff' fill-opacity='0.14' stroke='%23fff' stroke-opacity='0.8' stroke-width='1.25'/%3E%3C/svg%3E");
  --img-callout-warn: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cpath d='M8 0.75H24L31.25 8V24L24 31.25H8L0.75 24V8Z' fill='%23ffbf4d' fill-opacity='0.12' stroke='%23ffbf4d' stroke-opacity='0.5' stroke-width='1.5'/%3E%3C/svg%3E");
  --img-callout-good: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cpath d='M8 0.75H24L31.25 8V24L24 31.25H8L0.75 24V8Z' fill='%236ee7a8' fill-opacity='0.1' stroke='%236ee7a8' stroke-opacity='0.5' stroke-width='1.5'/%3E%3C/svg%3E");
  --img-callout-info: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cpath d='M8 0.75H24L31.25 8V24L24 31.25H8L0.75 24V8Z' fill='%237fe6ff' fill-opacity='0.09' stroke='%237fe6ff' stroke-opacity='0.4' stroke-width='1.5'/%3E%3C/svg%3E");
  --img-banner-good: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cpath d='M8 0H24L32 8V24L24 32H8L0 24V8Z' fill='%236ee7a8'/%3E%3C/svg%3E");
  --img-track-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20'%3E%3Cpath d='M5 0.625H15L19.375 5V15L15 19.375H5L0.625 15V5Z' fill='%23fff' fill-opacity='0.12' stroke='%23fff' stroke-opacity='0.28' stroke-width='1.25'/%3E%3C/svg%3E");
  --img-track-on: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20'%3E%3Cpath d='M5 0H15L20 5V15L15 20H5L0 15V5Z' fill='%237fe6ff'/%3E%3C/svg%3E");
  --mark-good: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 8.5l3.2 3.2L13 4.8' fill='none' stroke='%236ee7a8' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --mark-warn: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='6.6' fill='none' stroke='%23ffbf4d' stroke-width='1.8'/%3E%3Cpath d='M8 4.6v4.2' stroke='%23ffbf4d' stroke-width='2' stroke-linecap='round'/%3E%3Ccircle cx='8' cy='11.4' r='1.1' fill='%23ffbf4d'/%3E%3C/svg%3E");
  --mark-note: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3.2' fill='%23ffefb8'/%3E%3C/svg%3E");
  --pad: 20px;
  --water-gap: 84px;
}
/* Daytime at the surface rather than an inverted dark mode: a pale sky with dark text on it and
   shallower water. The plates, and everything on them, stay as they are. */
@media (prefers-color-scheme: light) {
  :root {
    --sky-top: #5fb0ee;
    --sky-bottom: #cfeeff;
    --sea-1: #3b8fe6;
    --sea-2: #3381dd;
    --sea-3: #2c72d2;
    --sky-text: #0a1830;
    --sky-dim: #2a4f7c;
    --wm-erg: #0a1830;
    --wm-dog: #a5520a;
  }
}
@media (min-width: 760px) { :root { --pad: 26px; --water-gap: 96px; } }

* { box-sizing: border-box; }
html { background: var(--sea-3); }
body {
  min-height: 100vh; margin: 0; color: var(--text); background: transparent;
  font-family: var(--font-body); font-size: 15.5px; font-weight: 500; line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  /* The sky and the seabed run the full width of the window, past the column's edges. */
  overflow-x: hidden;
}
@supports (overflow-x: clip) { body { overflow-x: clip; } }
.wrap { max-width: 680px; margin: 0 auto; padding: calc(20px + env(safe-area-inset-top)) 16px 0; }
.wrap-wide { max-width: 800px; }
h1, h2, h3, h4 { margin: 0; }
a { color: var(--glow); }
:focus-visible { outline: 2px solid var(--glow); outline-offset: 2px; }

/* ---------- the scene ---------- */
.sea {
  position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: -2; pointer-events: none; overflow: hidden;
  background: linear-gradient(172deg, var(--sea-1) 0%, var(--sea-2) 50%, var(--sea-3) 100%);
}
.sea svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
.sky {
  position: absolute; left: 0; top: 0; width: 100%; height: 320px; z-index: -1; pointer-events: none;
  background: linear-gradient(180deg, var(--sky-top), var(--sky-bottom));
}
/* The bright first stretch of water under the surface, fading into the sea. */
.sky::after {
  content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 110px;
  background: linear-gradient(180deg, var(--shallows), rgba(63, 147, 230, 0.75) 45%, rgba(43, 114, 214, 0));
}
.sky svg { position: absolute; left: 0; top: 0; overflow: visible; }

/* ---------- header (on the sky) ---------- */
.topbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 2px var(--pad) 0; min-height: 40px; }
.topbar a.home-link { text-decoration: none; }
.brand { display: flex; align-items: center; gap: 11px; }
/* The rowing dog on the waterline is the mark here, as on the device. */
.brand-mark { display: none; }
/* The ErgDog wordmark, drawn from img/wordmark.svg (generated from the device's header). */
.brand-title { line-height: 0; }
.wordmark { display: block; height: 32px; width: auto; overflow: visible; }
.brand-sub { font-size: 13px; color: var(--sky-dim); margin-top: 5px; }
@media (max-width: 420px) { .wordmark { height: 26px; } }
.back-link {
  display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
  font-family: var(--font-caps); font-weight: 700; font-size: 12.5px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--sky-text);
}
.back-link:hover { color: var(--sky-dim); }
.back-link svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.back-link svg.wordmark { width: auto; height: 24px; stroke: none; }

/* ---------- the headline (on the sky, no box) ---------- */
.hero { position: relative; padding: 0 var(--pad); margin: 34px 0 var(--water-gap); color: var(--sky-text); }
.hero h1 {
  font-family: var(--font-display); font-weight: 700; font-size: clamp(44px, 11vw, 74px);
  line-height: 0.98; letter-spacing: 0; max-width: 18ch; padding-top: 0.06em; text-wrap: balance;
}
.hero p { margin: 16px 0 0; color: var(--sky-dim); font-size: 17px; line-height: 1.55; max-width: 42ch; }
.hero p a { color: inherit; text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
.hero-cta { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 26px; }
.hero-cta .btn { padding: 14px 22px; font-size: 13px; }
@media (max-width: 480px) {
  .hero-cta { gap: 10px; }
  .hero-cta .btn { padding: 12px 15px; font-size: 12px; letter-spacing: 0.12em; }
  .hero-cta .btn:first-child { flex-basis: 100%; }
}
.hero-note { margin: 14px 0 0; font-size: 14px; color: var(--sky-dim); max-width: 46ch; }
/* Outlines on the sky turn ink in daylight. */
@media (prefers-color-scheme: light) {
  .hero .btn-ghost { color: var(--ink); border-image-source: var(--img-btn-ink); }
  .hero .btn-ghost:hover { background: rgba(10, 24, 48, 0.06); }
}

/* ---------- headings, plates ---------- */
/* A heading: spaced capitals, with a 3px underline as long as the letters (the trailing letter
   spacing is left out of it). */
h2.section-title, .card > h2, .feature-theme-title, .doc > h1 {
  position: relative; display: table; color: var(--text);
  font-family: var(--font-caps); font-weight: 700; font-size: 13.5px; letter-spacing: 0.2em;
  text-transform: uppercase; line-height: 1.35; padding-bottom: 10px;
}
h2.section-title::after, .card > h2::after, .feature-theme-title::after, .doc > h1::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 3px; width: calc(100% - 0.2em); background: currentColor;
}
/* A heading set straight on the water, between plates. */
h2.section-title { margin: 44px var(--pad) 18px; font-size: 14.5px; }
.card {
  position: relative; border-image: var(--img-plate) 16 fill / 16px;
  padding: 22px var(--pad) 24px; margin-bottom: 18px;
}
.card > h2 { margin: 0 0 18px; }
.card p { color: var(--text-dim); font-size: 15px; margin: 0 0 12px; }
.card p:last-child { margin-bottom: 0; }
.card .muted, .muted { color: var(--text-dim); font-size: 13.5px; }
.card ol { padding-left: 1.2rem; margin: 0; }
.card li { margin: 7px 0; color: var(--text-dim); font-size: 15px; }
.card li strong, .card p strong { color: var(--text); }
/* Text set straight on the open water is white, never dim: the sea is too bright for it. */
.wrap > p { color: var(--text); padding: 0 var(--pad); font-size: 14.5px; }

/* ---------- diagrams ----------
   Small friendly explainers of what plugs into what: flat boxes, a solid line for a cable, a
   dotted line with round dots for anything over the air, and the device itself the one box in
   the brand's orange. */
.signal-chain { padding: 6px 0 2px; }
.signal-chain svg { display: block; width: 100%; height: auto; overflow: visible; }
.signal-chain .sc-line { stroke: var(--text-dim); stroke-width: 2; fill: none; stroke-linecap: round; }
.signal-chain .sc-line-wired { stroke: var(--text); }
.signal-chain .sc-line-wireless { stroke: var(--glow); stroke-width: 2.6; stroke-dasharray: 0.1 7; }
/* An optional physical cable: dashed to say "you may not have this one", a real dash rather
   than the round dots of a radio link. */
.signal-chain .sc-line-optional { stroke: var(--text-dim); stroke-dasharray: 5 4; }
.signal-chain .sc-box { fill: rgba(4, 14, 48, 0.45); stroke: rgba(255, 255, 255, 0.4); stroke-width: 1.5; rx: 0; }
.signal-chain .sc-box-product { fill: rgba(255, 162, 41, 0.14); stroke: var(--accent); stroke-width: 2.2; }
.signal-chain .sc-label { font-family: var(--font-body); font-size: 12px; font-weight: 700; fill: var(--text); }
.signal-chain .sc-label-tight { font-size: 10.5px; }
.signal-chain .sc-label-sub { font-family: var(--font-body); font-size: 9px; font-weight: 600; fill: var(--text-dim); }
.signal-chain .sc-icon { stroke: var(--text-dim); fill: none; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.signal-chain .sc-led { fill: var(--good); animation: sc-blink 2.6s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .signal-chain .sc-led { animation: none; } }
@keyframes sc-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
/* The three destinations in the landing diagram are also links down into .conn-list below. */
.signal-chain a.sc-box-link { cursor: pointer; }
.signal-chain a.sc-box-link .sc-box { transition: stroke 0.15s, fill 0.15s; }
.signal-chain a.sc-box-link:hover .sc-box, .signal-chain a.sc-box-link:focus .sc-box { stroke: var(--glow); fill: rgba(127, 230, 255, 0.14); }
.signal-chain a.sc-box-link:focus { outline: none; }
.signal-caption { font-size: 14px; color: var(--text-dim); text-align: center; margin: 12px 0 0; }
/* On its own on the water (the quickstart), the diagram sits on a plate of its own. */
.wrap > .signal-chain { border-image: var(--img-plate) 16 fill / 16px; padding: 22px var(--pad) 18px; }
.wrap > .signal-chain + .signal-caption { color: var(--text); margin: 12px 0 26px; }

/* What each connection does, one row per destination in the diagram above, opening in place. */
.conn-list { margin-top: 18px; border-top: 1.5px solid var(--rule); }
.conn-card { border-bottom: 1px solid var(--line); scroll-margin-top: 90px; }
.conn-card summary { display: flex; align-items: baseline; gap: 12px; padding: 14px 2px; cursor: pointer; list-style: none; user-select: none; }
.conn-card summary::-webkit-details-marker { display: none; }
.conn-name { font-size: 16px; font-weight: 700; color: var(--text); }
.conn-hint { flex: 1; font-size: 14px; color: var(--text-dim); }
.conn-chev { align-self: center; width: 18px; height: 18px; flex: none; stroke: var(--text-dim); fill: none; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; transition: transform 0.25s; }
.conn-card[open] .conn-chev { transform: rotate(180deg); }
.conn-card[open] .conn-name { color: var(--glow); }
.conn-body { padding: 0 2px 16px; display: flex; flex-direction: column; gap: 10px; }
.conn-row { display: grid; grid-template-columns: 110px 1fr; gap: 14px; }
@media (max-width: 420px) { .conn-row { grid-template-columns: 1fr; gap: 3px; } }
.conn-dir { font-size: 14px; font-weight: 600; color: var(--moon); }
.conn-val { font-size: 14.5px; color: var(--text-dim); line-height: 1.55; }

/* ---------- what it gives you ----------
   Each theme is one plate: its heading and a line of introduction, two spotlights side by side
   split by a thin divider (a screenshot of the real thing or a small diagram over a title and a
   line), then the smaller facts as a plain list. */
.feature-theme { border-image: var(--img-plate) 16 fill / 16px; padding: 24px var(--pad) 10px; margin-bottom: 18px; }
.feature-theme-title { margin: 0 0 14px; }
.feature-theme-intro { color: var(--text-dim); font-size: 15.5px; margin: 0 0 22px; max-width: 58ch; }
.feature-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 26px; margin-bottom: 22px; align-items: start; }
@media (min-width: 620px) {
  .feature-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 44px; }
  .feature-grid > .feature-card + .feature-card::before {
    content: ""; position: absolute; left: -22.75px; top: 0; bottom: 0; width: 1.5px; background: rgba(255, 255, 255, 0.2);
  }
}
.feature-card { position: relative; display: flex; flex-direction: column; min-width: 0; }
.feature-visual img { display: block; width: 100%; height: auto; border: 1.5px solid rgba(255, 255, 255, 0.25); }
/* Screenshots ship as a light/dark pair; only one is in the flow at a time, picked by the
   visitor's colour scheme. */
.feature-visual img.shot-dark { display: none; }
@media (prefers-color-scheme: dark) {
  .feature-visual img.shot-light { display: none; }
  .feature-visual img.shot-dark { display: block; }
}
.feature-visual .signal-chain.signal-chain-sm { margin: 0; padding: 8px 0 4px; background: none; }
.feature-body { padding: 16px 0 0; }
.feature-title { font-size: 17px; font-weight: 700; line-height: 1.35; color: var(--text); margin: 0 0 6px; }
.feature-teaser { font-size: 15px; color: var(--text-dim); margin: 0; line-height: 1.55; }
.feature-more { margin-top: 10px; }
.feature-more > summary {
  cursor: pointer; font-size: 14px; font-weight: 600; color: var(--glow);
  list-style: none; display: inline-flex; align-items: center; gap: 6px;
}
.feature-more > summary::-webkit-details-marker { display: none; }
.feature-more > summary::after { content: "+"; font-weight: 700; }
.feature-more[open] > summary::after { content: "\2212"; }
.feature-more-body { padding-top: 8px; font-size: 15px; color: var(--text-dim); line-height: 1.6; }
.feature-more-body p { margin: 0; }

/* The smaller facts that don't earn a picture: a plain divided list, a bold lead-in per row. */
.fact-list { display: flex; flex-direction: column; border-top: 1.5px solid var(--rule); }
.fact-row { padding: 13px 0; border-bottom: 1px solid var(--line); font-size: 15px; color: var(--text-dim); line-height: 1.55; }
.fact-row:last-child { border-bottom: none; }
.fact-row strong { color: var(--text); font-weight: 600; }

/* Quick links back into the guided setup, for a returning visitor: rows on one plate. */
.quick-links { display: flex; flex-direction: column; border-image: var(--img-plate) 16 fill / 16px; padding: 8px var(--pad); margin-bottom: 18px; }
.quick-link {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 14px 0; text-decoration: none; color: var(--text);
  border-bottom: 1px solid var(--line); font-size: 15.5px; font-weight: 600;
}
.quick-link:last-child { border-bottom: none; }
.quick-link:hover { color: var(--glow); }
.quick-link svg { width: 16px; height: 16px; flex: none; stroke: var(--text-dim); fill: none; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.quick-link:hover svg { stroke: var(--glow); }

/* ---------- buttons and form controls ----------
   A button is spaced capitals in a cut-cornered outline. The one primary action on a screen (a
   plain <button> or .btn) is filled with the brand's orange. */
button, .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font-caps); font-weight: 700; font-size: 12px; letter-spacing: 0.16em;
  text-transform: uppercase; line-height: 1.2; text-decoration: none; cursor: pointer;
  color: var(--ink); background: none; border: 0; padding: 12px 18px;
  border-image: var(--img-btn-primary) 10 fill / 10px;
}
button:hover, .btn:hover { border-image-source: var(--img-btn-primary-hover); }
button:disabled, .btn:disabled { color: var(--text-faint); border-image-source: var(--img-btn-off); cursor: not-allowed; }
.btn-ghost, button.btn-ghost { color: var(--text); border-image-source: var(--img-btn); }
.btn-ghost:hover, button.btn-ghost:hover { border-image-source: var(--img-btn-hover); }
.btn-done, button.btn-done { color: var(--good); }

label { display: block; font-size: 14px; font-weight: 600; color: var(--text-dim); margin-bottom: 6px; }
input[type="text"], input[type="password"] {
  font: inherit; font-size: 15px; padding: 10px 12px; border-radius: 0;
  border: 1.5px solid rgba(255, 255, 255, 0.28); background: rgba(4, 14, 48, 0.42); color: var(--text);
  width: 100%; max-width: 24rem;
}
input[type="text"]:focus, input[type="password"]:focus { outline: none; border-color: var(--glow); }
input::placeholder { color: var(--text-faint); }

code { font-family: inherit; font-weight: 600; font-size: 0.95em; color: var(--text); background: var(--well); padding: 0.05em 0.35em; }

/* ---------- guided setup (getting-started.html) ----------
   Alpine drives the open/done state; everything here is presentation only. */
[x-cloak] { display: none !important; }

.progress-bar { display: flex; align-items: center; gap: 14px; margin: 0 var(--pad) 18px; }
.progress-track { flex: 1; height: 6px; background: rgba(255, 255, 255, 0.18); overflow: hidden; }
.progress-fill { height: 100%; width: 0; background: var(--moon); transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1); }
.progress-label { font-family: var(--font-display); font-weight: 700; font-size: 20px; line-height: 1; padding-top: 3px; color: var(--text); flex: none; }
.progress-reset { font-size: 14px; color: var(--text); text-decoration: underline; text-underline-offset: 3px; flex: none; }

/* One plate per step, joined by a short line in the gap, so the six read as one track. */
.step { position: relative; border-image: var(--img-plate) 16 fill / 16px; margin-bottom: 14px; }
.step.is-open { border-image-source: var(--img-plate-hover); }
.step:not(:last-of-type)::after {
  content: ""; position: absolute; left: calc(var(--pad) + 17px); top: 100%; width: 2px; height: 14px; background: rgba(255, 255, 255, 0.35);
}
.step.is-done:not(:last-of-type)::after { background: var(--good); }
.step-head { display: flex; align-items: center; gap: 14px; padding: 16px var(--pad); cursor: pointer; user-select: none; }
/* The step's number, a cut-cornered square: outlined while it waits, orange while it is open,
   green with a tick once it is done. It is also the button that marks the step done. */
.step-badge, button.step-badge {
  width: 36px; height: 36px; flex: none; padding: 0; letter-spacing: 0;
  font-family: var(--font-display); font-weight: 700; font-size: 20px; line-height: 1;
  color: var(--text); border-image: var(--img-btn) 10 fill / 10px;
  transition: transform 0.2s;
}
.step-badge span { padding-top: 3px; }
.step-badge:hover { transform: scale(1.06); border-image-source: var(--img-btn-hover); }
.step.is-open .step-badge { color: var(--ink); border-image-source: var(--img-btn-primary); }
.step.is-done .step-badge, .step.is-done.is-open .step-badge { color: var(--ink); border-image-source: var(--img-banner-good); }
.step-badge svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.step-headings { flex: 1; min-width: 0; }
.step-title { display: block; font-size: 17px; font-weight: 700; color: var(--text); line-height: 1.35; }
.step.is-done .step-title { color: var(--text-dim); }
.step-sub { display: block; font-size: 14px; color: var(--text-dim); margin-top: 2px; }
.step-tag {
  flex: none; font-family: var(--font-caps); font-size: 10px; font-weight: 700; letter-spacing: 0.16em;
  text-transform: uppercase; padding: 5px 9px 4px; color: var(--text-dim); border-image: var(--img-tag) 7 fill / 7px;
}
.step-tag.price { color: var(--moon); }
.step-chev { width: 18px; height: 18px; flex: none; stroke: var(--text-dim); fill: none; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; transition: transform 0.25s; }
.step.is-open .step-chev { transform: rotate(180deg); }
.step-body { padding: 0 var(--pad) 20px calc(var(--pad) + 50px); }
@media (max-width: 480px) { .step-body { padding-left: var(--pad); } }
.step-body > p { color: var(--text-dim); font-size: 15px; margin: 0 0 12px; }
.step-body p strong, .step-body li strong { color: var(--text); }
.step-body ol, .step-body ul { padding-left: 1.15rem; margin: 0 0 12px; }
.step-body li { margin: 7px 0; color: var(--text-dim); font-size: 15px; }
.step-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 16px; }

/* Callouts: something to get right (amber), something that worked (green). */
.callout {
  border-image: var(--img-callout-info) 12 fill / 12px; padding: 13px 15px; margin: 0 0 14px;
  font-size: 14.5px; color: var(--text-dim);
}
.callout strong { color: var(--text); }
.callout.warn { border-image-source: var(--img-callout-warn); }
.callout.good { border-image-source: var(--img-callout-good); }
.callout p { margin: 0 0 6px; }
.callout p:last-child { margin-bottom: 0; }
.wrap > .callout { margin-left: 0; margin-right: 0; background-color: rgba(13, 20, 48, 0.4); }

/* A photo inside a step, edged rather than plated. */
.step-shot { margin: 16px 0; }
.step-shot img { display: block; width: 100%; height: auto; border: 1.5px solid rgba(255, 255, 255, 0.25); }
.step-shot figcaption { font-size: 13.5px; color: var(--text-dim); margin-top: 8px; }
.step-shot figcaption strong { color: var(--text); }

/* The board's product photo has a white background of its own, so it sits on a white card with
   cut corners rather than framing white in blue. */
.board-shot {
  max-width: 460px; margin: 0 auto 16px; background: #ffffff; padding: 12px 16px 10px;
  clip-path: polygon(10px 0, calc(100% - 10px) 0, 100% 10px, 100% calc(100% - 10px), calc(100% - 10px) 100%, 10px 100%, 0 calc(100% - 10px), 0 10px);
}
.board-shot img { display: block; width: 100%; height: auto; }
.board-shot figcaption { font-size: 12.5px; color: #4a5a6e; text-align: center; margin-top: 6px; }

/* Where to buy: one row per shop. */
.buy-link {
  display: flex; align-items: center; gap: 12px; text-decoration: none; color: var(--text);
  border-image: var(--img-chip) 7 fill / 7px; padding: 12px 14px; margin-bottom: 8px;
}
.buy-link:hover { border-image-source: var(--img-chip-on); }
.buy-link-where { flex: 1; font-size: 15px; font-weight: 700; }
.buy-link-note { display: block; font-size: 13px; font-weight: 500; color: var(--text-dim); margin-top: 1px; }
.buy-link svg { width: 16px; height: 16px; flex: none; stroke: var(--text-dim); fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Inline status with an optional spinner, used by the Bluetooth flows. */
.status-line { display: flex; align-items: center; gap: 10px; font-size: 14.5px; color: var(--text-dim); margin: 14px 0 0; }
.spinner { width: 15px; height: 15px; flex: none; border-radius: 50%; border: 2px solid rgba(255, 255, 255, 0.2); border-top-color: var(--glow); animation: spin 0.7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.device-link { display: inline-flex; align-items: center; gap: 7px; font-size: 16px; font-weight: 700; word-break: break-all; }

details.helper { margin-top: 14px; }
details.helper > summary { cursor: pointer; font-size: 14px; font-weight: 600; color: var(--text-dim); list-style: none; display: inline-flex; align-items: center; gap: 6px; }
details.helper > summary::-webkit-details-marker { display: none; }
details.helper > summary::before { content: "+"; font-weight: 700; color: var(--glow); }
details.helper[open] > summary::before { content: "\2212"; }
details.helper > summary:hover { color: var(--text); }
details.helper .helper-body { padding: 10px 0 0 16px; font-size: 14px; color: var(--text-dim); }
details.helper .helper-body p { margin: 0 0 8px; }

/* The WiFi network picker in step 4. */
.wifi-list { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; max-width: 24rem; }
button.wifi-item {
  justify-content: space-between; gap: 12px; width: 100%; padding: 12px 14px; text-align: left;
  font-family: var(--font-body); font-size: 15px; font-weight: 600; letter-spacing: 0; text-transform: none;
  color: var(--text); border-image-source: var(--img-chip);
}
button.wifi-item:hover { border-image-source: var(--img-chip-on); }
.wifi-item-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wifi-item-meta { font-size: 13px; font-weight: 600; color: var(--text-dim); flex: none; }

/* A one-off attention pulse on the next step, once the flashing dialog closes. */
@keyframes pulse-highlight { 0%, 100% { outline-color: rgba(127, 230, 255, 0); } 50% { outline-color: rgba(127, 230, 255, 0.8); } }
.highlight-pulse { outline: 2px solid transparent; outline-offset: 3px; animation: pulse-highlight 1.1s ease-in-out 3; }
@media (prefers-reduced-motion: reduce) { .highlight-pulse { animation: none; } }

/* ---------- footer, on the seabed ----------
   site.js draws the seabed into --floor; the footer's text sits on the floor under the reef. */
.site-footer { position: relative; margin-top: 70px; padding: 132px var(--pad) calc(30px + env(safe-area-inset-bottom)); }
.site-footer::before {
  content: ""; position: absolute; z-index: -1; top: 0; bottom: 0; left: calc(50% - 50vw); width: 100vw;
  background: var(--floor, none) top center / 100% 120px no-repeat, linear-gradient(transparent 117px, #1a49a3 117px);
}
.site-footer p { margin: 0; max-width: 64ch; font-size: 13px; line-height: 1.6; color: var(--text-dim); }

/* ---------- documentation (site/docs/) ----------
   The guides are the same content the device serves from its own /docs/* routes
   (components/pm_connector/web_ui_docs.h), and wear the same look there: the page on one plate
   in the water. Only the body is ported; this wrapper is the site's own. */
.doc { border-image: var(--img-plate) 16 fill / 16px; padding: 24px var(--pad) 26px; margin-top: var(--water-gap); }
.doc > h1 { font-size: 15px; margin: 0 0 22px; }
.doc > h2 {
  font-family: var(--font-caps); font-size: 12px; font-weight: 700; letter-spacing: 0.18em;
  text-transform: uppercase; margin: 30px 0 10px; color: var(--text);
}
.doc > h3 { font-size: 16.5px; font-weight: 700; margin: 26px 0 8px; }
.doc > p { line-height: 1.65; margin: 0 0 12px; color: var(--text-dim); font-size: 15.5px; }
.doc p strong, .doc li strong { color: var(--text); }
/* A lead paragraph or an aside: a lighter well inside the plate, not a box of its own. */
.doc > p.card { border-image: none; background: rgba(255, 255, 255, 0.07); padding: 15px 17px; margin: 16px 0 14px; color: var(--text); }
.doc > ol, .doc > ul { padding-left: 1.2rem; margin: 0 0 12px; }
.doc li { margin: 7px 0; color: var(--text-dim); font-size: 15.5px; line-height: 1.6; }
.doc > table { width: 100%; border-collapse: collapse; margin: 0 0 14px; font-size: 14.5px; }
.doc th, .doc td { text-align: left; padding: 9px 8px; border-bottom: 1px solid var(--line); vertical-align: top; }
.doc th { color: var(--text-dim); font-weight: 600; border-bottom: 1.5px solid var(--rule); }
.doc td { color: var(--text); }
.doc td.sw { width: 34px; padding-right: 0; }
.doc .what { color: var(--text-dim); }
.doc pre { background: rgba(4, 14, 48, 0.4); padding: 12px 14px; overflow-x: auto; font-size: 13px; line-height: 1.5; }
/* Schematics are hand-authored inline SVG drawn in currentColor, so they follow the text colour.
   On a narrow screen they scroll sideways inside the figure rather than shrinking the labels. */
.doc > figure { margin: 0 0 16px; overflow-x: auto; }
.doc figure svg.schematic { display: block; width: 100%; min-width: 520px; height: auto; }
.doc figcaption { margin-top: 8px; font-size: 13.5px; line-height: 1.5; color: var(--text-dim); }
.doc .back { display: inline-block; margin-top: 26px; font-size: 15px; font-weight: 600; }

/* Status-LED swatches. They animate at the device's own blink timings, so a row can be held next
   to the real LED and compared. Off is dimmed rather than fully transparent. */
.doc .dot { display: inline-block; width: 16px; height: 16px; border-radius: 50%; margin-top: 2px; border: 1px solid rgba(255, 255, 255, 0.3); }
@keyframes b60 { 0%,59.9% { opacity: 1 } 60%,100% { opacity: 0.12 } }
@keyframes b50 { 0%,49.9% { opacity: 1 } 50%,100% { opacity: 0.12 } }
@keyframes b30 { 0%,29.9% { opacity: 1 } 30%,100% { opacity: 0.12 } }
@keyframes b15 { 0%,14.9% { opacity: 1 } 15%,100% { opacity: 0.12 } }
@keyframes b5  { 0%,4.9%  { opacity: 1 } 5%,100%  { opacity: 0.12 } }
/* Both links up: cyan for one second, then green for the next, lit the whole time. Animations
   outrank the inline background, which stays as the still-frame colour when motion is reduced. */
@keyframes bdual { 0%,49.9% { background: #00ffff; opacity: 1 } 50%,100% { background: #00ff00; opacity: 1 } }
/* Sleep fades instead of blinking, along the same squared ramp the firmware drives. */
@keyframes breathe { 0%,100% { opacity: 0.08 } 25% { opacity: 0.25 } 50% { opacity: 1 } 75% { opacity: 0.25 } }
.doc .blink { animation-iteration-count: infinite; animation-timing-function: linear; }
@media (prefers-reduced-motion: reduce) { .doc .blink { animation: none } }

/* ---------- docs index and the quickstart: rows on one plate ---------- */
.doc-list { display: flex; flex-direction: column; border-image: var(--img-plate) 16 fill / 16px; padding: 8px var(--pad); margin-bottom: 18px; }
.doc-item { display: flex; align-items: center; gap: 14px; text-decoration: none; color: var(--text); padding: 16px 0; border-bottom: 1px solid var(--line); }
.doc-item:last-child { border-bottom: none; }
.doc-item-text { flex: 1; min-width: 0; }
.doc-item-title { display: block; font-size: 16.5px; font-weight: 700; }
.doc-item-sub { display: block; font-size: 14.5px; color: var(--text-dim); margin-top: 3px; line-height: 1.5; }
.doc-item svg { width: 16px; height: 16px; flex: none; stroke: var(--text-dim); fill: none; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.doc-item:hover .doc-item-title { color: var(--glow); }
.doc-item:hover svg { stroke: var(--glow); }

/* The quickstart's numbered steps, all on one plate and divided by rules rather than a plate each. */
.qs-steps { border-image: var(--img-plate) 16 fill / 16px; padding: 8px var(--pad); margin-bottom: 18px; }
.qs-step { padding: 20px 0; border-bottom: 1px solid var(--line); }
.qs-step:last-child { border-bottom: none; }
.qs-step > h3 { display: flex; align-items: baseline; gap: 12px; font-size: 17px; font-weight: 700; margin: 0 0 10px; }
.qs-step > h3 .n { font-family: var(--font-display); font-size: 26px; line-height: 1; color: var(--moon); min-width: 1.1em; }
.qs-step p, .qs-step li { color: var(--text-dim); font-size: 15px; }
.qs-step p { margin: 0 0 10px; }
.qs-step p:last-child { margin-bottom: 0; }
.qs-step strong { color: var(--text); }
.qs-step ol, .qs-step ul { padding-left: 1.2rem; margin: 0 0 10px; }
.qs-steps > .callout { margin: 18px 0; }
