/* Shared styles for pm-connector.hendrikvh.com. Ported from the on-device
   web UI's design tokens (components/pm_connector/web_ui_assets.h) so the
   site and the device feel like the same product. Kept as one plain
   stylesheet, no build step - matches how the rest of this project's web UI
   work is done. */

:root {
  --bg: #f4f6f5;
  --surface: #ffffff;
  --surface-2: #eef1f0;
  --surface-3: #e3e7e5;
  --border: #d8dedb;
  --text: #1b2224;
  --text-dim: #5b6669;
  --text-faint: #6a736f;
  --accent: #eb8500;
  --accent-2: #ffad0a;
  --accent-rgb: 235, 133, 0;
  --accent-ink: #372610;
  --accent-text: #994700;
  --success: #22a050;
  --danger: #c94040;
  --glow: #f9efe2;
  --hero-tint: #f4e9db;
  --radius-lg: 18px;
  --radius-md: 12px;
  --radius-sm: 8px;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0e0f10;
    --surface: #17191b;
    --surface-2: #1e2124;
    --surface-3: #262a2d;
    --border: #2a2d30;
    --text: #f2f4f3;
    --text-dim: #9aa3a0;
    --text-faint: #818a86;
    --accent: #ffa229;
    --accent-2: #ffc552;
    --accent-rgb: 255, 162, 41;
    --accent-ink: #251909;
    --accent-text: #ffa229;
    --success: #69d390;
    --glow: #211609;
    --hero-tint: #291d10;
  }
}

* { box-sizing: border-box; }
html { height: 100%; color-scheme: light dark; }
body {
  min-height: 100%;
  margin: 0;
  background-color: var(--bg);
  background-image:
    repeating-linear-gradient(0deg, rgba(var(--accent-rgb), 0.05) 0 1px, transparent 1px 88px),
    repeating-linear-gradient(90deg, rgba(var(--accent-rgb), 0.05) 0 1px, transparent 1px 88px);
  background-attachment: fixed;
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
  line-height: 1.5;
}
.wrap { max-width: 640px; margin: 0 auto; padding: calc(18px + env(safe-area-inset-top)) 18px 40px; }
.wrap-wide { max-width: 760px; }
h1, h2, h3 { margin: 0; }
a { color: var(--accent-text); }

/* ---------- topbar / brand ---------- */
.topbar { display: flex; align-items: center; justify-content: space-between; padding: 2px 0 22px; }
.topbar a.home-link { text-decoration: none; }
.brand { display: flex; align-items: center; gap: 11px; }
.brand-mark {
  width: 42px; height: 42px; border-radius: 13px; flex: none;
  background: var(--accent);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.16);
  display: flex; align-items: center; justify-content: center;
}
.brand-mark svg { width: 36px; height: 36px; }
.brand-title { font-size: 17px; font-weight: 800; letter-spacing: -0.01em; color: var(--text); }
.brand-sub { font-size: 11px; color: var(--text-faint); margin-top: 1px; }
.back-link {
  font-size: 13px; font-weight: 600; color: var(--text-dim); text-decoration: none;
  display: inline-flex; align-items: center; gap: 4px;
}
.back-link:hover { color: var(--accent-text); }
.back-link svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- hero ---------- */
.hero {
  border-radius: var(--radius-lg); padding: 30px 24px 28px; margin-bottom: 22px;
  background: var(--surface);
  border: 1px solid var(--border); position: relative; overflow: hidden;
}
.hero::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, var(--accent) 0%, var(--accent-2) 50%, var(--accent) 100%);
}
.hero::after {
  content: ""; position: absolute; z-index: 0; width: 200px; height: 200px; right: -90px; top: -100px; border-radius: 50%;
  background: radial-gradient(circle, var(--glow), transparent 72%);
}
.hero > * { position: relative; z-index: 1; }
.hero h1 { font-size: 26px; font-weight: 800; letter-spacing: -0.015em; }
.hero p { margin: 10px 0 0; color: var(--text-dim); font-size: 14.5px; max-width: 40ch; }
.hero-cta { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 18px; }
.hero-cta .btn { padding: 12px 24px; font-size: 15px; }

/* ---------- sections & cards ---------- */
h2.section-title {
  font-size: 13px; font-weight: 700;
  color: var(--text-dim); margin: 30px 0 12px;
}
.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: 16px 18px 18px; margin-bottom: 12px;
}
.card > h2 {
  margin: -16px -18px 14px; padding: 11px 18px;
  background: linear-gradient(180deg, rgba(var(--accent-rgb), 0.06), rgba(var(--accent-rgb), 0.02)), var(--surface-2);
  border-bottom: 1px solid var(--border);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  font-size: 14px; font-weight: 700; color: var(--text);
}
.card > h2::before {
  content: ""; display: inline-block; vertical-align: -1px;
  width: 3px; height: 11px; margin-right: 8px; border-radius: 2px;
  background: var(--accent);
}
.card p { color: var(--text-dim); font-size: 14px; margin: 0 0 10px; }
.card p:last-child { margin-bottom: 0; }
.card .muted { color: var(--text-faint); font-size: 12.5px; }
.card ol { padding-left: 1.2rem; margin: 0; }
.card li { margin: 6px 0; color: var(--text-dim); font-size: 14px; }
.card li strong { color: var(--text); }

/* ---------- signal-chain diagram (site/index.html hero signature) ----------
   A small schematic of what the device actually does: PM3 in over a wire,
   BLE/WiFi/ANT+ out over the air. Deliberately not another icon-badge grid. */
.signal-chain {
  background: var(--hero-tint); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: 18px 18px 14px; margin-bottom: 8px;
}
.signal-chain svg { display: block; width: 100%; height: auto; overflow: visible; }
.signal-chain .sc-line { stroke: var(--text-faint); stroke-width: 2; fill: none; stroke-linecap: round; }
.signal-chain .sc-line-wired { stroke: var(--accent-text); }
.signal-chain .sc-line-wireless { stroke: var(--text-faint); stroke-dasharray: 0.5 7; }
/* An optional physical cable (site/docs/quickstart.html): dashed to say
   "you may not have this one", but a real dash rather than the dotted
   sc-line-wireless above, which reads as a radio link. */
.signal-chain .sc-line-optional { stroke: var(--text-faint); stroke-dasharray: 5 4; }
.signal-chain .sc-box { fill: var(--surface); stroke: var(--border); stroke-width: 1.6; }
.signal-chain .sc-box-product { stroke: var(--accent); stroke-width: 2; }
.signal-chain .sc-label { font-size: 12px; font-weight: 700; fill: var(--text); }
.signal-chain .sc-label-tight { font-size: 10.5px; }
.signal-chain .sc-label-sub { font-size: 8.5px; fill: var(--text-faint); }
.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(--success); 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 destination pills 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(--accent); fill: rgba(var(--accent-rgb), 0.08);
}
.signal-chain a.sc-box-link:focus { outline: none; }
.signal-caption {
  font-size: 12.5px; color: var(--text-faint); text-align: center; margin: 10px 0 26px;
}

/* Expandable connection detail cards, one per pill in the diagram above -
   click a pill to jump to its card, or open any of them directly. */
.conn-list { display: flex; flex-direction: column; gap: 10px; }
.conn-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  scroll-margin-top: 90px; transition: border-color 0.2s;
}
.conn-card[open] { border-color: rgba(var(--accent-rgb), 0.45); }
.conn-card summary {
  display: flex; align-items: center; gap: 10px; padding: 14px 16px;
  cursor: pointer; list-style: none; user-select: none;
}
.conn-card summary::-webkit-details-marker { display: none; }
.conn-card summary:focus-visible { outline: 2px solid var(--accent-text); outline-offset: -2px; border-radius: var(--radius-lg); }
.conn-name { font-size: 15px; font-weight: 700; color: var(--text); }
.conn-hint { flex: 1; font-size: 12.5px; color: var(--text-faint); }
.conn-chev {
  width: 17px; height: 17px; flex: none; stroke: var(--text-faint); 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-body { padding: 0 16px 16px; display: flex; flex-direction: column; gap: 10px; }
.conn-row { display: grid; grid-template-columns: 92px 1fr; gap: 14px; }
@media (max-width: 420px) { .conn-row { grid-template-columns: 1fr; gap: 3px; } }
.conn-dir { font-size: 12.5px; font-weight: 700; color: var(--accent-text); padding-top: 1px; }
.conn-val { font-size: 13.5px; color: var(--text-dim); line-height: 1.5; }

/* ---------- feature spotlights (site/index.html "what it actually gives
   you" section) ----------
   Three theme blocks, each a couple of visual spotlight cards (a real
   on-device screenshot or a small hand-drawn diagram, reusing the
   signal-chain SVG language above) plus a compact list of smaller bulleted
   facts that don't need their own picture. */
.feature-theme { margin-top: 8px; }
.feature-theme + .feature-theme { margin-top: 30px; }
.feature-theme-title {
  font-size: 17px; font-weight: 800; color: var(--text); margin: 0 0 6px;
  display: flex; align-items: center; gap: 9px;
}
.feature-theme-title::before {
  content: ""; width: 3px; height: 15px; border-radius: 2px; background: var(--accent); flex: none;
}
.feature-theme-intro { color: var(--text-dim); font-size: 14px; margin: 0 0 14px; max-width: 58ch; }

.feature-grid { display: grid; grid-template-columns: 1fr; gap: 14px; margin-bottom: 10px; align-items: start; }
@media (min-width: 620px) { .feature-grid { grid-template-columns: 1fr 1fr; } }

.feature-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  overflow: hidden; display: flex; flex-direction: column;
}
.feature-visual { background: var(--surface-2); }
.feature-visual img { display: block; width: 100%; height: auto; }
/* Screenshots ship as a light/dark pair; only one is ever in the DOM's flow
   at a time, picked purely by the visitor's colour scheme - no toggle, no JS. */
.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; }
}
/* A diagram card reuses .signal-chain wholesale for its colours and line
   styles, just smaller and without its own border/background/margin, since
   .feature-card already supplies those one level up. */
.feature-visual .signal-chain.signal-chain-sm {
  margin: 0; border: none; border-radius: 0; background: var(--hero-tint);
  padding: 18px 16px 12px;
}
.feature-body { padding: 14px 16px 16px; }
.feature-title { font-size: 15.5px; font-weight: 800; color: var(--text); margin: 0 0 4px; letter-spacing: -0.005em; }
.feature-teaser { font-size: 13.5px; color: var(--text-dim); margin: 0; line-height: 1.5; }
.feature-more { margin-top: 9px; }
.feature-more > summary {
  cursor: pointer; font-size: 12.5px; font-weight: 700; color: var(--accent-text);
  list-style: none; display: inline-flex; align-items: center; gap: 4px;
}
.feature-more > summary::-webkit-details-marker { display: none; }
.feature-more > summary::after { content: "+"; font-weight: 800; }
.feature-more[open] > summary::after { content: "\2212"; }
.feature-more-body { padding-top: 8px; font-size: 13.5px; color: var(--text-dim); line-height: 1.55; }
.feature-more-body p { margin: 0; }

/* The smaller facts under each theme that don't earn a picture - a plain
   divided list, one bolded lead-in per row, same idiom as .quick-link below
   but read-only (no chevron, nothing to click through to). */
.fact-list { display: flex; flex-direction: column; gap: 0; }
.fact-row { padding: 10px 2px; border-bottom: 1px solid var(--border); font-size: 13.5px; color: var(--text-dim); line-height: 1.5; }
.fact-row:last-child { border-bottom: none; }
.fact-row strong { color: var(--text); }

/* Quick links back into the guided setup, for a returning visitor - a plain
   list, not a repeat of the spec sheet's card treatment. */
.quick-links { display: flex; flex-direction: column; gap: 2px; }
.quick-link {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 4px; text-decoration: none; color: var(--text);
  border-bottom: 1px solid var(--border); font-size: 14px; font-weight: 600;
}
.quick-link:last-child { border-bottom: none; }
.quick-link:hover { color: var(--accent-text); }
.quick-link svg { width: 15px; height: 15px; flex: none; stroke: var(--text-faint); fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.quick-link:hover svg { stroke: var(--accent-text); }

/* ---------- form controls & buttons ---------- */
button, .btn {
  background: var(--accent); color: var(--accent-ink); border: none;
  border-radius: 999px; padding: 11px 18px; cursor: pointer; font-size: 14px; font-weight: 700;
  box-shadow: 0 4px 14px -6px rgba(var(--accent-rgb), 0.6); font-family: inherit;
}
.btn { text-decoration: none; display: inline-block; }
button:hover, .btn:hover { filter: brightness(1.06); }
button:disabled, .btn:disabled { background: var(--surface-3); color: var(--text-faint); cursor: not-allowed; box-shadow: none; }
button:focus-visible, .btn:focus-visible, a:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 2px; }

label { display: block; font-size: 13px; font-weight: 600; color: var(--text-dim); margin-bottom: 5px; }
input[type="text"], input[type="password"] {
  font-size: 14px; padding: 10px 12px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface-2); color: inherit;
  width: 100%; max-width: 22rem; box-sizing: border-box; font-family: inherit;
}
input[type="text"]:focus, input[type="password"]:focus {
  outline: none; border-color: var(--accent); background: var(--surface);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.16);
}

code {
  font-size: 0.92em; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 5px; padding: 0.1em 0.4em;
}

/* ---------- guided setup stepper (site/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: 12px; margin: 0 0 16px; }
.progress-track {
  flex: 1; height: 6px; border-radius: 999px; background: var(--surface-3); overflow: hidden;
}
.progress-fill {
  height: 100%; border-radius: 999px; width: 0;
  background: var(--accent);
  transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
.progress-label { font-size: 12.5px; font-weight: 700; color: var(--text-dim); flex: none; }
.progress-reset {
  font-size: 12px; color: var(--text-faint); text-decoration: none; flex: none;
  border-bottom: 1px dotted currentColor;
}
.progress-reset:hover { color: var(--accent-text); }

.step {
  position: relative; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); margin-bottom: 12px;
  transition: border-color 0.2s;
}
.step.is-open { border-color: rgba(var(--accent-rgb), 0.45); }
.step.is-done { border-color: rgba(34, 160, 80, 0.4); }
/* Connector drawn in the 12px gap below each card, so the five cards read as
   one track. Turns green behind a completed step. */
.step:not(:last-of-type)::after {
  content: ""; position: absolute; left: 33px; top: 100%; width: 2px; height: 12px;
  background: var(--border);
}
.step.is-done:not(:last-of-type)::after { background: rgba(34, 160, 80, 0.45); }

.step-head {
  display: flex; align-items: center; gap: 13px; padding: 14px 16px; cursor: pointer;
  user-select: none;
}
.step-head:focus-visible { outline: 2px solid var(--accent-text); outline-offset: -2px; border-radius: var(--radius-lg); }
.step-badge {
  width: 34px; height: 34px; flex: none; border-radius: 50%; border: none; padding: 0;
  background: var(--surface-3); color: var(--text-dim);
  font-size: 14px; font-weight: 800; box-shadow: none;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.2s, color 0.2s, transform 0.2s;
}
.step-badge:hover { transform: scale(1.08); filter: none; }
.step.is-open .step-badge {
  background: var(--accent); color: var(--accent-ink);
  box-shadow: 0 4px 12px -5px rgba(var(--accent-rgb), 0.7);
}
.step.is-done .step-badge, .step.is-done.is-open .step-badge {
  background: var(--success); color: #fff; box-shadow: none;
}
.step-badge svg { width: 17px; height: 17px; 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: 15px; font-weight: 700; color: var(--text); }
.step.is-done .step-title { color: var(--text-dim); }
.step-sub { display: block; font-size: 12.5px; color: var(--text-faint); margin-top: 1px; }
.step-tag {
  flex: none; font-size: 10.5px; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 999px; background: var(--surface-2);
  border: 1px solid var(--border); color: var(--text-faint);
}
.step-tag.price { background: rgba(var(--accent-rgb), 0.12); border-color: rgba(var(--accent-rgb), 0.35); color: var(--accent-text); }
.step-chev {
  width: 17px; height: 17px; flex: none; stroke: var(--text-faint); 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 16px 16px 63px; }
@media (max-width: 480px) { .step-body { padding-left: 16px; } }
.step-body > p { color: var(--text-dim); font-size: 14px; margin: 0 0 10px; }
.step-body ol, .step-body ul { padding-left: 1.15rem; margin: 0 0 10px; }
.step-body li { margin: 6px 0; color: var(--text-dim); font-size: 14px; }
.step-body li strong { color: var(--text); }
.step-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 14px; }

/* Secondary / ghost button, for "mark as done" and back links inside steps. */
.btn-ghost {
  background: var(--surface-2); color: var(--text-dim); border: 1px solid var(--border);
  box-shadow: none; font-weight: 600;
}
.btn-ghost:hover { filter: none; border-color: rgba(var(--accent-rgb), 0.5); color: var(--text); }
.btn-done { background: rgba(34, 160, 80, 0.14); border-color: rgba(34, 160, 80, 0.45); color: var(--success); }

/* Callouts inside steps: a required-hardware warning, a success result. */
.callout {
  border: 1px solid var(--border); border-left: 3px solid var(--text-faint);
  background: var(--surface-2); border-radius: var(--radius-sm);
  padding: 11px 13px; margin: 0 0 12px; font-size: 13.5px; color: var(--text-dim);
}
.callout strong { color: var(--text); }
.callout.warn { border-left-color: var(--accent); background: rgba(var(--accent-rgb), 0.07); }
.callout.good { border-left-color: var(--success); background: rgba(34, 160, 80, 0.09); }
.callout p { margin: 0 0 6px; }
.callout p:last-child { margin-bottom: 0; }

.hero-note {
  margin: 12px 0 0; font-size: 13px; color: var(--text-faint); max-width: 46ch;
}

/* A photo inside a step: a close-up of the board, bordered rather than plated
   (unlike .board-shot, whose subject sits on its own white background). */
.step-shot { margin: 14px 0; }
.step-shot img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.step-shot figcaption {
  font-size: 12.5px; color: var(--text-faint); margin-top: 7px;
}
.step-shot figcaption strong { color: var(--text-dim); }

/* Product photo of the board. The photo has a white background of its own, so
   the plate stays light in dark mode too rather than framing white in black. */
.board-shot {
  max-width: 460px; margin: 0 auto 14px; background: #ffffff;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 10px 14px 8px;
}
.board-shot img { display: block; width: 100%; height: auto; }
.board-shot figcaption {
  font-size: 12px; color: #6b7280; text-align: center; margin-top: 6px;
}

/* Buy links: one row per retailer. */
.buy-link {
  display: flex; align-items: center; gap: 11px; text-decoration: none;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 11px 13px; margin-bottom: 8px; color: var(--text);
}
.buy-link:hover { border-color: rgba(var(--accent-rgb), 0.5); }
.buy-link-where { flex: 1; font-size: 14px; font-weight: 700; }
.buy-link-note { display: block; font-size: 12px; font-weight: 500; color: var(--text-faint); margin-top: 1px; }
.buy-link svg { width: 16px; height: 16px; flex: none; stroke: var(--text-faint); fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

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

details.helper { margin-top: 12px; }
details.helper > summary {
  cursor: pointer; font-size: 13px; font-weight: 600; color: var(--text-dim);
  list-style: none; display: inline-flex; align-items: center; gap: 5px;
}
details.helper > summary::-webkit-details-marker { display: none; }
details.helper > summary::before { content: "+"; font-weight: 800; color: var(--accent-text); }
details.helper[open] > summary::before { content: "\2212"; }
details.helper > summary:hover { color: var(--accent-text); }
details.helper .helper-body { padding: 9px 0 0 14px; font-size: 13px; color: var(--text-faint); }
details.helper .helper-body p { margin: 0 0 7px; }

/* ---------- WiFi network picker (site/discover.html) ---------- */
.wifi-list { display: flex; flex-direction: column; gap: 8px; margin: 10px 0; max-width: 22rem; }
.wifi-item {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; background: var(--surface-2); color: var(--text); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 10px 14px; text-align: left;
  font-size: 14px; font-weight: 600; box-shadow: none;
}
.wifi-item:hover { border-color: rgba(var(--accent-rgb), 0.5); filter: none; }
.wifi-item-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wifi-item-meta { font-size: 12px; font-weight: 600; color: var(--text-faint); flex: none; }

/* ---------- attention pulse (e.g. site/flash.html's next-step card, once the
   ESP Web Tools install dialog closes) ---------- */
@keyframes pulse-highlight {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0); }
  50% { box-shadow: 0 0 0 6px rgba(var(--accent-rgb), 0.25); }
}
.highlight-pulse { animation: pulse-highlight 1.1s ease-in-out 3; border-color: var(--accent); }

/* ---------- footer ---------- */
.site-footer { margin-top: 30px; padding-top: 18px; border-top: 1px solid var(--border); }
.site-footer p { margin: 0; font-size: 12px; color: var(--text-faint); }

/* ---------- documentation pages (site/docs/) ----------
   The wiring and status-LED pages are the same content the device serves
   from its own /docs/* routes (components/pm_connector/web_ui_docs.h). Those
   pages are standalone and carry their own <style>; here the shared tokens
   above already cover the colours, so only the page-specific rules are
   repeated, scoped to .doc so they cannot leak into the rest of the site.
   Keep these in step with web_ui_docs.h when that changes. */
.doc > h1 { font-size: 22px; font-weight: 800; letter-spacing: -0.015em; margin: 0 0 4px; }
.doc > h2 {
  font-size: 13px; margin: 26px 0 8px; color: var(--text-dim);
  text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700;
}
.doc > h3 { font-size: 15.5px; font-weight: 700; margin: 26px 0 8px; }
.doc > p { line-height: 1.6; margin: 0 0 12px; color: var(--text-dim); font-size: 14.5px; }
.doc p strong, .doc li strong { color: var(--text); }
.doc > p.card { padding: 15px 17px; margin-top: 16px; }
.doc > ol, .doc > ul { padding-left: 1.2rem; margin: 0 0 12px; }
.doc li { margin: 7px 0; color: var(--text-dim); font-size: 14.5px; line-height: 1.55; }
.doc > table { width: 100%; border-collapse: collapse; margin: 0 0 12px; font-size: 13.5px; }
.doc th, .doc td { text-align: left; padding: 8px; border-bottom: 1px solid var(--border); vertical-align: top; }
.doc th { color: var(--text-dim); font-weight: 600; }
.doc td { color: var(--text); }
.doc td.sw { width: 34px; padding-right: 0; }
.doc .what { color: var(--text-dim); }
.doc pre {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 12px 14px; overflow-x: auto; font-size: 12.5px; line-height: 1.5;
}
/* Schematics are hand-authored inline SVG drawn in currentColor, so they
   follow the light/dark theme. On a narrow screen they scroll sideways inside
   the figure rather than shrinking the labels to nothing. */
.doc > figure { margin: 0 0 14px; overflow-x: auto; }
.doc figure svg.schematic { display: block; width: 100%; min-width: 520px; height: auto; }
.doc figcaption { margin-top: 6px; font-size: 12.5px; line-height: 1.45; color: var(--text-faint); }
.doc .back { display: inline-block; margin-top: 26px; font-size: 14px; }

/* 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, so an unlit swatch still reads as an LED. */
.doc .dot {
  display: inline-block; width: 16px; height: 16px; border-radius: 50%; margin-top: 2px;
  border: 1px solid var(--border);  /* a white swatch needs this on a light card */
}
@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, with no dark phase between them. 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. The stops trace the same squared ramp the
   firmware drives, so the swatch dwells near the bottom and sweeps through
   the top the way the real LED does. */
@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: one row per guide ---------- */
.doc-list { display: flex; flex-direction: column; gap: 10px; }
.doc-item {
  display: flex; align-items: center; gap: 13px; text-decoration: none;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 15px 17px; color: var(--text);
}
.doc-item:hover { border-color: rgba(var(--accent-rgb), 0.5); }
.doc-item-text { flex: 1; min-width: 0; }
.doc-item-title { display: block; font-size: 15px; font-weight: 700; }
.doc-item-sub { display: block; font-size: 13px; color: var(--text-faint); margin-top: 3px; line-height: 1.45; }
.doc-item svg {
  width: 16px; height: 16px; flex: none; stroke: var(--text-faint);
  fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.doc-item:hover svg { stroke: var(--accent-text); }
