/* HARVESTIQ 2.0 - light, natural design system. Tokens first; components read from them. */
:root {
  --ivory: #FAFAF6;
  --white: #FFFFFF;
  --sage: #E8F0E6;
  --sage-2: #DCE8D9;
  --forest: #285C43;
  --forest-2: #1F4A35;
  --leaf: #78A878;
  --amber: #E8AD45;
  --sky: #DCECF5;
  --wind: #7398AD;
  --text: #25312B;
  --muted: #738078;
  --muted-strong: #5C695F; /* small text on ivory: >= 5:1 contrast */
  --line: #E3E8E1;
  --line-2: #D3DBD0;
  --warn: #B7791F;
  --err: #B94040;
  --solar: #E8AD45;
  --piezo: #8E7CB3;
  --battery: #285C43;
  --light: #8B9A90;
  --sim-ink: #6B4A00;
  --font: "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif;
  --serif: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Georgia, serif;
  --mono: "Cascadia Mono", Consolas, ui-monospace, monospace;
  --radius: 14px;
  --shadow: 0 1px 2px rgba(37, 49, 43, 0.05), 0 10px 28px -14px rgba(37, 49, 43, 0.14);
  --ease: cubic-bezier(0.22, 0.7, 0.2, 1);
}

* { box-sizing: border-box; }
html { color-scheme: light; scroll-behavior: smooth; scroll-padding-top: 76px; }
body {
  margin: 0; min-height: 100vh; color: var(--text); background: var(--ivory);
  font: 14px/1.5 var(--font); -webkit-font-smoothing: antialiased;
}
button, input { font: inherit; color: inherit; }
h1, h2, h3, p { margin: 0; }
code { font-family: var(--mono); font-size: 0.92em; color: var(--forest); background: var(--sage); padding: 0 4px; border-radius: 4px; }
small { color: var(--muted-strong); }
a { color: inherit; text-decoration: none; }
[hidden] { display: none !important; }
:focus-visible { outline: 2px solid var(--forest); outline-offset: 2px; border-radius: 6px; }

/* ---------- navigation ---------- */
.nav { position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: 20px; padding: 10px 28px; background: rgba(250, 250, 246, 0.94); border-bottom: 1px solid var(--line); backdrop-filter: blur(6px); }
body[data-mode="demo"] .nav { top: 31px; }
.brand { display: flex; align-items: center; gap: 10px; color: var(--forest); font-weight: 800; letter-spacing: 0.2em; font-size: 15px; }
.mark { width: 30px; height: 30px; }
.mainnav { display: flex; align-items: center; gap: 4px; white-space: nowrap; }
@media (max-width: 1599px) { #lastData { display: none; } }
.mainnav a, .navbtn { padding: 6px 12px; border-radius: 8px; color: var(--muted-strong); font-size: 13px; font-weight: 600; background: none; border: 0; cursor: pointer; transition: background 0.2s, color 0.2s; }
.mainnav a:hover, .navbtn:hover { background: var(--sage); color: var(--forest); }
.mainnav a[aria-current] { color: var(--forest); background: var(--sage); }
.linkblock { display: flex; flex-direction: column; gap: 2px; margin-left: auto; min-width: 0; align-items: flex-end; }
.linkblock small { font-size: 11.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.linkblock .badge, .actions { white-space: nowrap; }
.actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }

.seg { display: inline-flex; padding: 3px; border: 1px solid var(--line-2); border-radius: 10px; background: var(--sage); }
.seg button { border: 0; background: transparent; color: var(--muted-strong); padding: 5px 14px; border-radius: 7px; cursor: pointer; font-weight: 700; font-size: 12px; letter-spacing: 0.08em; transition: background 0.2s, color 0.2s; }
.seg button:disabled { opacity: 0.45; cursor: not-allowed; }
.seg button[aria-pressed="true"] { background: var(--white); color: var(--forest); box-shadow: 0 1px 3px rgba(37, 49, 43, 0.14); }
.seg button[data-mode-btn="demo"][aria-pressed="true"] { color: var(--sim-ink); }
.seg.small button { padding: 3px 10px; font-size: 11.5px; letter-spacing: 0.02em; }

.btn { border: 1px solid var(--line-2); background: var(--white); color: var(--text); padding: 7px 14px; border-radius: 9px; cursor: pointer; font-weight: 600; font-size: 13px; transition: transform 0.15s var(--ease), background 0.2s, border-color 0.2s, box-shadow 0.2s; }
.btn:hover:not(:disabled) { border-color: var(--leaf); background: var(--sage); }
.btn:active:not(:disabled) { transform: translateY(1px) scale(0.985); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn.primary { background: var(--forest); border-color: var(--forest); color: var(--white); }
.btn.primary:hover:not(:disabled) { background: var(--forest-2); border-color: var(--forest-2); }
.btn.ghost { background: transparent; }
.btn.small { padding: 4px 11px; font-size: 12px; }

.badge { display: inline-flex; align-items: center; gap: 7px; padding: 3px 11px; border-radius: 99px; font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; border: 1px solid var(--line-2); color: var(--muted-strong); background: #F2F5F0; white-space: nowrap; }
.badge i { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.badge.ok { color: var(--forest); border-color: #BFD6BC; background: var(--sage); }
.badge.ok i { animation: pulse 2s ease-out infinite; }
.badge.sim { color: var(--sim-ink); border-color: #E6CB87; background: #FBF0D6; }
.badge.warn { color: var(--warn); border-color: #E8CF9C; background: #FBF1DC; }
.badge.crit { color: var(--err); border-color: #EBBDBD; background: #F9E6E6; }
#linkBadge .badge, #heroLink .badge { font-size: 11.5px; padding: 4px 13px; }

.health-chip { display: inline-flex; align-items: baseline; gap: 8px; padding: 5px 12px; border: 1px solid var(--line-2); border-radius: 10px; background: var(--white); }
.health-chip small { font-size: 9.5px; letter-spacing: 0.14em; color: var(--muted); }
.health-chip b { font-size: 12px; letter-spacing: 0.08em; }
.health-chip.ok b { color: var(--forest); } .health-chip.warning b { color: var(--warn); } .health-chip.critical b { color: var(--err); } .health-chip.offline b { color: var(--muted); }

.sim-banner { position: sticky; top: 0; z-index: 30; height: 31px; display: flex; align-items: center; justify-content: center; gap: 14px; padding: 0 16px; font-size: 12px; color: var(--sim-ink); font-weight: 600; background: repeating-linear-gradient(-45deg, #F6E3B0 0 12px, #F0D68F 12px 24px); border-bottom: 1px solid #E0C57C; }
.sim-banner b { letter-spacing: 0.18em; }
.sim-banner span { font-weight: 500; }

.notice { margin: 12px 28px 0; padding: 10px 14px; border-radius: 10px; border: 1px solid var(--line-2); background: var(--white); display: flex; justify-content: space-between; gap: 12px; align-items: center; animation: rise 0.35s var(--ease); }
.notice.warn { border-color: #E8CF9C; background: #FBF1DC; }
.notice.crit { border-color: #EBBDBD; background: #F9E6E6; }
.notice .x { border: 0; background: transparent; color: var(--muted-strong); font-size: 20px; cursor: pointer; line-height: 1; }
.file-warn { margin: 0; border-radius: 0; border-width: 0 0 1px; padding: 14px 28px; font-size: 14px; }

/* ---------- demo bar ---------- */
.demobar { display: grid; gap: 8px; padding: 10px 28px; background: #FDF7E6; border-bottom: 1px solid #EBDDB4; animation: rise 0.35s var(--ease); }
.demo-row { display: flex; align-items: center; gap: 16px; justify-content: space-between; min-width: 0; }
.demo-label { font-size: 11px; letter-spacing: 0.16em; color: var(--sim-ink); white-space: nowrap; }
.scenarios { display: flex; gap: 6px; flex-wrap: wrap; flex: 1; }
.scn { display: inline-flex; align-items: center; gap: 8px; padding: 4px 11px 4px 5px; border-radius: 9px; border: 1px solid #E5D7AE; background: var(--white); color: var(--muted-strong); cursor: pointer; font-size: 12.5px; transition: border-color 0.2s, color 0.2s, background 0.2s; }
.scn b { display: grid; place-items: center; width: 22px; height: 22px; border-radius: 6px; background: var(--sage); color: var(--forest); font-size: 12px; }
.scn:hover { color: var(--text); border-color: var(--amber); }
.scn[aria-pressed="true"] { color: var(--text); border-color: var(--amber); background: #FBF0D6; }
.scn[aria-pressed="true"] b { background: var(--amber); color: #3F2B00; }
.demo-run { display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--muted-strong); font-variant-numeric: tabular-nums; }
.progress { width: 130px; height: 5px; border-radius: 3px; background: #E9DDB7; overflow: hidden; }
.progress i { display: block; height: 100%; width: 100%; background: var(--amber); transform: scaleX(0); transform-origin: left; transition: transform 0.9s linear; }
.demo-blurb { font-size: 12.5px; color: var(--muted-strong); flex: 1; }

/* ---------- layout ---------- */
main { display: grid; gap: 18px; padding: 20px 28px 8px; max-width: 1560px; margin: 0 auto; }
.panel { border: 1px solid var(--line); border-radius: var(--radius); background: var(--white); box-shadow: var(--shadow); padding: 18px 20px; min-width: 0; }
.panel-h { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.panel-h h2 { font: 700 11.5px var(--font); letter-spacing: 0.18em; text-transform: uppercase; color: var(--forest); }
.hint { font-size: 12px; color: var(--muted-strong); }
.split { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 18px; align-items: start; }
.foot { max-width: 1560px; margin: 4px auto 0; padding: 14px 28px 32px; font-size: 12px; color: var(--muted-strong); }

/* ---------- hero ---------- */
.hero { display: grid; grid-template-columns: minmax(300px, 5fr) minmax(0, 8fr); border: 1px solid var(--line); border-radius: 20px; background: linear-gradient(180deg, #EAF3F8 0%, var(--ivory) 70%); overflow: hidden; box-shadow: var(--shadow); min-height: 420px; }
.hero-copy { padding: 32px 8px 24px 34px; display: flex; flex-direction: column; gap: 12px; z-index: 1; }
.eyebrow { font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--forest); font-weight: 700; }
.hero h1 { font: 600 clamp(28px, 3vw, 40px) / 1.1 var(--serif); color: var(--forest); letter-spacing: -0.01em; }
.lede { color: var(--muted-strong); font-size: 15px; max-width: 34ch; }
.hero-status { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; margin: 4px 0 6px; }
.hero-status small { font-variant-numeric: tabular-nums; font-size: 12px; }
.hero-art { position: relative; min-width: 0; display: grid; align-items: end; }
.hero-scene { width: 100%; -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 15%); mask-image: linear-gradient(90deg, transparent 0, #000 15%); }

.pipeline { display: grid; gap: 6px; margin-top: auto; }
.stage { display: flex; align-items: center; gap: 12px; padding: 5px 12px; border: 1px solid var(--line); border-radius: 11px; background: rgba(255, 255, 255, 0.78); transition: border-color 0.3s, background 0.3s; }
.stage[data-lit="1"] { border-color: #BFD6BC; background: var(--white); }
.stage-n { display: grid; place-items: center; width: 24px; height: 24px; flex: none; border-radius: 50%; border: 1px solid var(--line-2); font-size: 11px; font-weight: 700; color: var(--muted-strong); transition: all 0.3s; }
.stage[data-lit="1"] .stage-n { background: var(--forest); border-color: var(--forest); color: var(--white); }
.stage b { display: block; font-size: 10.5px; letter-spacing: 0.18em; color: var(--forest); }
.stage small { display: block; font-size: 12px; line-height: 1.3; }
.stage small em { font-style: normal; color: var(--muted); }
.stage.ok small { color: var(--forest); } .stage.warn small { color: var(--warn); } .stage.accent small { color: var(--forest-2); font-weight: 600; }
.stage-arrow { display: none; }

/* ---------- source cards ---------- */
.cards { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.card { --c: var(--forest); display: flex; flex-direction: column; gap: 3px; padding: 14px 16px 12px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--white); box-shadow: var(--shadow); position: relative; overflow: hidden; transition: border-color 0.3s, opacity 0.3s; }
.card[data-card="solar"] { --c: #C98E1F; } .card[data-card="wind"] { --c: #4F7A91; } .card[data-card="piezo"] { --c: #6F5C99; } .card[data-card="battery"] { --c: var(--forest); }
.card::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--c); opacity: 0; transition: opacity 0.4s; }
.card[data-state="live"]::before { opacity: 1; }
.card header { display: flex; justify-content: space-between; align-items: center; gap: 6px; }
.card h3 { font-size: 11px; letter-spacing: 0.2em; color: var(--muted-strong); font-weight: 700; }
.card .metric { display: flex; align-items: baseline; gap: 6px; margin-top: 4px; }
.card .val { font: 600 34px/1 var(--serif); letter-spacing: -0.01em; font-variant-numeric: tabular-nums; color: var(--c); }
.card .val.tick { animation: tick 0.5s var(--ease); }
.card .unit { font-size: 13px; color: var(--muted-strong); }
.card .sub { font-size: 12.5px; color: var(--muted-strong); min-height: 36px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.card footer { font-size: 10.5px; color: var(--muted); line-height: 1.35; margin-top: auto; padding-top: 6px; }
.spark-wrap { flex: 1; min-height: 34px; max-height: 60px; margin-top: 2px; display: flex; align-items: flex-end; }
.spark { width: 100%; height: 100%; min-height: 34px; display: block; overflow: visible; }
.spark path { fill: none; stroke-width: 1.9; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.spark-empty { stroke: var(--line-2); stroke-width: 1; stroke-dasharray: 3 4; }
.spark-hatch { width: 100%; height: 34px; border-radius: 6px; background: repeating-linear-gradient(-45deg, var(--line) 0 3px, transparent 3px 8px); }
.card[data-state="stale"] .val, .card[data-state="stale"] .spark { opacity: 0.4; }
.card[data-state="stale"] { border-color: #E8CF9C; }
.card[data-state="unavailable"] .val, .card[data-state="waiting"] .val { color: var(--muted); }
.card[data-state="error"] { border-color: #EBBDBD; }
.card[data-state="error"] .val { color: var(--err); }
.card[data-card="battery"]::after { content: ""; position: absolute; left: 0; bottom: 0; height: 3px; width: 100%; background: var(--leaf); transform: scaleX(var(--p, 0)); transform-origin: left; transition: transform 0.8s var(--ease); }

/* ---------- hero scene (all motion is gated by data-* state set from real measurements) ---------- */
.hero-svg { width: 100%; height: auto; display: block; --spin: 5s; }
.hero-svg text { font-family: var(--font); }
.hero-svg .cloud ellipse { fill: #fff; opacity: 0.85; }
.hero-svg .c1 { animation: drift 80s steps(160) infinite alternate; }
.hero-svg .c2 { animation: drift 110s steps(220) infinite alternate-reverse; }
.ground-line { stroke: #CFDACB; stroke-width: 1.5; }
.sun { transition: opacity 0.8s; }
.hero-svg[data-light="night"] .sun { opacity: 0.3; }
.hero-svg[data-light="offline"] .sun, .hero-svg[data-light="unavailable"] .sun { opacity: 0.55; }
.sun-core { fill: #F3C969; stroke: var(--amber); stroke-width: 2; }
.sun-shine { fill: #fff; opacity: 0.55; }
.sun-rays line { stroke: var(--amber); stroke-width: 3; stroke-linecap: round; opacity: calc(0.2 + 0.7 * var(--ray, 0.8)); transition: opacity 0.8s; }
.sun-rays.rev line { stroke: #F3C969; stroke-width: 2; opacity: calc(0.15 + 0.55 * var(--ray, 0.8)); }
.sun-rays { transform-origin: 0 0; }
.sun-rays.slow { animation: spin 150s steps(450) infinite; }
.sun-rays.rev { animation: spin 100s steps(300) infinite reverse; }
.sun-glow { animation: breathe 7s steps(14) infinite; transform-origin: 0 0; }
/* Scenery only moves while a current light reading exists; with no data the whole scene holds still. */
.hero-svg:not([data-light="bright"]):not([data-light="dim"]) :is(.sun-rays, .sun-glow, .cloud) { animation-play-state: paused; }
.streaks line { stroke: var(--amber); stroke-width: 2.6; stroke-linecap: round; stroke-dasharray: 12 24; opacity: 0; transition: opacity 0.7s; }
.hero-svg[data-light="bright"] .streaks line { opacity: calc(0.25 + 0.7 * var(--ray, 0.8)); animation: streak 1.6s steps(12) infinite; }
.hero-svg[data-light="dim"] .streaks line { opacity: calc(0.2 + 0.7 * var(--ray, 0.3)); animation: streak 3s steps(14) infinite; }

.pole, .foot { fill: #B9C6BC; }
.panel-frame { fill: var(--sage); stroke: #BFCDC2; stroke-width: 6; stroke-linejoin: round; }
.panel-cells { fill: url(#gCell); transition: opacity 0.5s; }
.cell-lines line { stroke: rgba(255, 255, 255, 0.3); stroke-width: 1; }
.sheen { opacity: 0; transform-origin: 0 0; }
.hero-svg[data-solar="on"] .sheen { animation: glint 6.5s ease-in-out infinite; }
.hero-svg:not([data-solar-state="live"]) .panel-cells { opacity: 0.5; }
.motor-core { fill: var(--forest); }
.ring-bg { fill: none; stroke: #D8E2D5; stroke-width: 3.5; }
.ring { fill: none; stroke: var(--amber); stroke-width: 3.5; stroke-linecap: round; opacity: 0; transition: stroke-dashoffset 0.4s linear, opacity 0.3s; }
.hero-svg[data-clean="on"] .ring { opacity: 1; }
.ripple { fill: none; stroke: var(--forest); stroke-width: 2; stroke-linecap: round; opacity: 0; }
.hero-svg[data-clean="on"] .ripple { animation: ripple 0.55s ease-out infinite; }
.hero-svg[data-clean="on"] .r2 { animation-delay: 0.12s; }
.hero-svg[data-clean="on"] .panel-body { animation: buzz 0.09s linear infinite; }

.pill rect { fill: var(--white); stroke: var(--line-2); stroke-width: 1; }
.pill text { font: 700 11.5px var(--font); letter-spacing: 0.05em; fill: var(--text); }
.hero-svg:not([data-solar-state="live"]) .p-solar text, .hero-svg:not([data-wind-state="live"]) .p-wind text,
.hero-svg:not([data-piezo="live"]) .p-piezo text, .hero-svg:not([data-battery="live"]) .p-batt text { fill: var(--muted); }
.hero-svg:not([data-cleaner]) .p-clean text, .hero-svg[data-cleaner="UNKNOWN"] .p-clean text { fill: var(--muted); }
.hero-svg[data-clean="on"] .p-clean rect { stroke: var(--amber); fill: #FFF8E8; }

.esp-box { fill: var(--white); stroke: var(--forest); stroke-width: 1.5; }
.esp-title { font: 700 9.5px var(--font); letter-spacing: 0.16em; fill: var(--muted-strong); }
.esp-screen { fill: #EEF4EC; }
.esp-text { font: 700 10.5px var(--mono); fill: var(--forest); }
.esp-pins line { stroke: #B9C6BC; stroke-width: 3; stroke-linecap: round; }
.esp-led { fill: #C9D3CB; }
.hero-svg[data-esp="live"] .esp-led { fill: var(--leaf); animation: blink 2s ease-in-out infinite; }
.hero-svg[data-esp="stale"] .esp-led { fill: var(--amber); }

.batt-body { fill: var(--white); stroke: var(--forest); stroke-width: 2; }
.batt-cap { fill: var(--forest); }
.batt-fill { fill: url(#gCharge); transform-box: fill-box; transform-origin: 0 50%; transform: scaleX(0); transition: transform 0.9s var(--ease); }
.hero-svg:not([data-battery="live"]) .batt-fill { fill: url(#hatchLight); }
.batt-ticks line { stroke: rgba(255, 255, 255, 0.55); stroke-width: 1.5; }
.batt-shine { opacity: 0; }
.hero-svg[data-charging="on"] .batt-shine { opacity: 1; animation: shine 2.4s linear infinite; }
.bolt { fill: var(--amber); opacity: 0; transition: opacity 0.4s; }
.hero-svg[data-charging="on"] .bolt { opacity: 1; }
.batt-pct { font: 700 17px var(--serif); fill: var(--text); }

.tower { fill: #F3F6F1; stroke: #BFCDC2; stroke-width: 1.4; }
.nacelle { fill: var(--white); stroke: var(--wind); stroke-width: 1.6; }
.blades { transform-origin: 832px 178px; animation: spin var(--spin) linear infinite; animation-play-state: paused; }
.hero-svg[data-wind="on"] .blades { animation-play-state: running; }
.blade { fill: var(--white); stroke: var(--wind); stroke-width: 1.7; stroke-linejoin: round; }
.hub { fill: var(--wind); }
.hero-svg:not([data-wind-state="live"]) .blade { stroke-dasharray: 5 4; opacity: 0.7; }
.windlines path { fill: none; stroke: var(--wind); stroke-width: 2; stroke-linecap: round; stroke-dasharray: 46 74; opacity: 0; transition: opacity 0.6s; }
.hero-svg[data-wind="on"] .windlines path { opacity: 0.65; animation: windflow 2.4s steps(24) infinite; }
.hero-svg[data-wind="on"] .windlines path:nth-child(2) { animation-delay: -0.6s; }
.hero-svg[data-wind="on"] .windlines path:nth-child(3) { animation-delay: -1.2s; }
.hero-svg[data-wind="on"] .windlines path:nth-child(4) { animation-delay: -1.8s; }

.tile-base { fill: #C9D3CB; }
.tile-plate rect { fill: var(--sage); stroke: var(--leaf); stroke-width: 1.5; }
.tile-plate ellipse { fill: var(--leaf); opacity: 0.55; }
.hero-svg:not([data-piezo="live"]) .tile-plate rect { fill: url(#hatchLight); stroke: #B7C2B9; stroke-dasharray: 5 4; }
.hero-svg:not([data-piezo="live"]) .tile-plate ellipse { opacity: 0.15; }
.tile-pulse { fill: none; stroke: var(--amber); stroke-width: 2; opacity: 0; transform-origin: 151px 410px; }
.tile-bolt { fill: var(--amber); opacity: 0; }
.tile.hit .tile-plate { animation: press 0.55s ease-out; }
.tile.hit .tile-pulse { animation: pulsering 0.9s ease-out; }
.tile.hit .tile-bolt { animation: boltup 1s ease-out; }

.path { fill: none; stroke: #CBD5CB; stroke-width: 2; stroke-linecap: round; stroke-dasharray: 3 7; transition: stroke 0.4s; }
.path.energy { stroke-dasharray: none; }
.hero-svg[data-solar="on"] [data-flow="solar"] .path { stroke: var(--amber); stroke-width: 3; stroke-dasharray: 8 8; animation: dash 1s steps(8) infinite; }
.hero-svg[data-charging="on"] [data-flow="charge"] .path { stroke: var(--leaf); stroke-width: 3; stroke-dasharray: 8 8; animation: dash 0.8s steps(8) infinite; }
.hero-svg[data-wind="on"] [data-flow="wind"] .path { stroke: var(--wind); stroke-dasharray: 4 7; animation: dash 1.4s steps(8) infinite; }
.hero-svg.piezo-live [data-flow="piezo"] .path { stroke: var(--amber); }
.hero-svg[data-clean="on"] [data-flow="control"] .path { stroke: var(--forest); stroke-width: 2.4; animation: dash 0.7s steps(8) infinite; }
.particle { display: none; }
circle.p-solar { fill: var(--amber); } circle.p-charge { fill: var(--leaf); } circle.p-wind { fill: var(--wind); } circle.p-piezo { fill: var(--amber); } circle.p-control { fill: var(--forest); }
.hero-svg[data-solar="on"] circle.p-solar, .hero-svg[data-charging="on"] circle.p-charge, .hero-svg[data-wind="on"] circle.p-wind, .hero-svg.piezo-live circle.p-piezo, .hero-svg[data-clean="on"] circle.p-control { display: inline; }
.hero-svg[data-solar-level="1"] circle.p-solar:nth-of-type(n + 2) { display: none; }
.hero-svg[data-solar-level="2"] circle.p-solar:nth-of-type(n + 3) { display: none; }
.scene-note { font-size: 10.5px; fill: var(--muted-strong); }

/* sensor-fault badges: shown only when a channel is faulty while the link is live */
.fault { opacity: 0; transition: opacity 0.4s; pointer-events: none; }
.fault circle { fill: #FBF1DC; stroke: var(--warn); stroke-width: 2; }
.fault text { font: 800 15px var(--font); fill: var(--warn); }
.hero-svg[data-fault-solar="on"] [data-fault="solar"], .hero-svg[data-fault-wind="on"] [data-fault="wind"],
.hero-svg[data-fault-battery="on"] [data-fault="battery"], .hero-svg[data-fault-light="on"] [data-fault="light"] { opacity: 1; }
.hero-svg[data-fault-solar="on"] .p-solar rect, .hero-svg[data-fault-wind="on"] .p-wind rect, .hero-svg[data-fault-battery="on"] .p-batt rect { stroke: var(--warn); fill: #FFF8E8; }
.hero-svg[data-fault-solar="on"] .p-solar text, .hero-svg[data-fault-wind="on"] .p-wind text, .hero-svg[data-fault-battery="on"] .p-batt text { fill: var(--warn); }
.batt-est { font: 600 8.5px var(--font); letter-spacing: 0.1em; text-transform: uppercase; fill: var(--muted-strong); }

/* ---------- verification ---------- */
.track { list-style: none; margin: 0 0 10px; padding: 0; display: flex; align-items: center; gap: 8px; }
.track li { display: inline-flex; align-items: center; gap: 8px; padding: 5px 12px; border: 1px solid var(--line-2); border-radius: 99px; font-size: 11px; letter-spacing: 0.12em; font-weight: 700; color: var(--muted); transition: all 0.3s; }
.track li i { width: 8px; height: 8px; border-radius: 50%; background: var(--line-2); }
.track li em { font-style: normal; font-size: 10px; letter-spacing: 0.04em; color: var(--warn); font-weight: 600; }
.track li[data-on="1"] { color: var(--forest); border-color: var(--leaf); background: var(--sage); }
.track li[data-on="1"] i { background: var(--forest); }
.track li[data-st="CLEANING"][data-on="1"] { border-color: var(--amber); background: #FBF0D6; color: var(--sim-ink); }
.track li[data-st="CLEANING"][data-on="1"] i { background: var(--amber); animation: pulse 0.9s ease-out infinite; }
.track-arrow { width: 14px; height: 1px; background: var(--line-2); }
.vstatus { font-size: 12.5px; color: var(--muted-strong); margin-bottom: 12px; }
.vresult { border: 1px solid var(--line-2); border-left-width: 4px; border-radius: 12px; padding: 14px 16px; background: #FBFCFA; } /* no animation: re-rendered on every countdown tick */
.vresult.ok { border-left-color: var(--forest); } .vresult.warn { border-left-color: var(--warn); } .vresult.muted { border-left-color: var(--muted); }
.vresult.inconclusive { border-left-color: var(--wind); border-style: dashed; border-left-style: solid; }
.vresult.empty { border-left-color: var(--line-2); color: var(--muted-strong); font-size: 12.5px; }
.vresult.empty b { display: block; color: var(--text); margin-bottom: 4px; }
.vhead { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.vout { font: 600 20px var(--serif); letter-spacing: 0.02em; }
.vresult.ok .vout { color: var(--forest); } .vresult.warn .vout { color: var(--warn); } .vresult.inconclusive .vout { color: var(--wind); } .vresult.muted .vout { color: var(--muted-strong); }
.vhead time { margin-left: auto; font-size: 11.5px; color: var(--muted-strong); }
.chip { display: inline-block; padding: 2px 9px; border-radius: 99px; border: 1px solid var(--line-2); font-size: 10.5px; letter-spacing: 0.06em; color: var(--muted-strong); background: transparent; }
.chip.q-GOOD { color: var(--forest); border-color: #BFD6BC; background: var(--sage); }
.chip.q-LIMITED { color: var(--warn); border-color: #E8CF9C; background: #FBF1DC; }
.chip.q-CONFOUNDED, .chip.q-INSUFFICIENT { color: var(--err); border-color: #EBBDBD; background: #F9E6E6; }
.chip.pick { cursor: pointer; } .chip.pick.on { color: var(--forest); border-color: var(--forest); background: var(--sage); }
.vgrid { display: grid; grid-template-columns: 1fr auto 1fr; gap: 12px; align-items: center; }
.vtile { padding: 10px 12px; border-radius: 10px; background: var(--white); border: 1px solid var(--line); }
.vtile small { display: block; font-size: 10px; letter-spacing: 0.14em; }
.vtile b { font: 600 26px var(--serif); font-variant-numeric: tabular-nums; }
.vtile b i, .vdelta b i { font: 400 12px var(--font); color: var(--muted-strong); }
.vtile span { display: block; font-size: 11.5px; color: var(--muted-strong); }
.vdelta { text-align: center; }
.vdelta b { display: block; font: 600 20px var(--serif); font-variant-numeric: tabular-nums; }
.vdelta span { font-size: 12px; color: var(--muted-strong); }
.vresult.ok .vdelta b { color: var(--forest); } .vresult.warn .vdelta b { color: var(--warn); }
.vbars { display: grid; gap: 6px; margin: 12px 0 4px; }
.vbars > div { display: grid; grid-template-columns: 48px 1fr; align-items: center; gap: 8px; font-size: 11px; color: var(--muted-strong); }
.vbar { height: 8px; background: var(--line); border-radius: 4px; overflow: hidden; }
.vbar i { display: block; height: 100%; background: #B8C4BB; border-radius: 4px; transition: width 0.8s var(--ease); }
.vbar.after i { background: var(--forest); }
.vmeta { margin: 10px 0 6px; }
.vexp { font-size: 12.5px; }
.vreasons { margin: 8px 0 0; padding-left: 18px; font-size: 12px; color: var(--muted-strong); }
.vnone { font-size: 12.5px; color: var(--muted-strong); }
.vhist { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }

/* ---------- diagnostics + sensors ---------- */
.diag-list { list-style: none; margin: 0; padding: 0 2px 0 0; display: grid; gap: 10px; max-height: 620px; overflow: auto; }
.diag { border: 1px solid var(--line-2); border-left: 3px solid var(--muted); border-radius: 10px; padding: 11px 13px; background: #FBFCFA; } /* no animation: the list is rebuilt every second and would flicker */
.diag.warning { border-left-color: var(--warn); background: #FFFBF1; } .diag.critical { border-left-color: var(--err); background: #FEF6F6; } .diag.info { border-left-color: var(--wind); }
.diag-h { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.diag-h b { font-size: 13px; }
.diag-h time { margin-left: auto; font-size: 11px; color: var(--muted-strong); white-space: nowrap; }
.sev { font-size: 9px; letter-spacing: 0.14em; font-weight: 700; padding: 2px 6px; border-radius: 4px; background: var(--sage); color: var(--muted-strong); }
.diag.warning .sev { color: var(--warn); background: #FBF1DC; } .diag.critical .sev { color: var(--err); background: #F9E6E6; } .diag.info .sev { color: #4F7A91; background: #E5F0F6; }
.diag p { font-size: 12px; color: var(--muted-strong); }
.evidence { margin: 6px 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 5px; }
.evidence li { font: 11px var(--mono); padding: 2px 7px; border-radius: 5px; background: var(--white); border: 1px solid var(--line); color: var(--text); }
.diag .action { color: var(--text); margin-top: 4px; }
.diag .action b { color: var(--forest); font-weight: 700; }
.diag .conf { font-size: 11px; font-style: italic; color: var(--muted); margin-top: 3px; }
.diag-empty { padding: 14px; border: 1px dashed var(--line-2); border-radius: 10px; color: var(--muted-strong); font-size: 12.5px; }
.diag-empty.ok { background: var(--sage); border-style: solid; border-color: #BFD6BC; }
.diag-empty.ok b { color: var(--forest); }
.diag-empty b { display: block; margin-bottom: 2px; }
.diag-group { font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); margin-top: 6px; }
.sensor-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.sensor-list li { display: grid; grid-template-columns: 130px auto 1fr; gap: 10px; align-items: center; padding: 9px 4px; border-bottom: 1px solid var(--line); font-size: 12.5px; }
.sensor-list li:last-child { border-bottom: 0; }
.sensor-list b { font-weight: 600; }
.sensor-list small { font-size: 11.5px; overflow-wrap: anywhere; }

/* ---------- charts ---------- */
.chart-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 24px; }
.chart-grid figure { margin: 0; min-width: 0; }
.chart-grid figcaption { font-size: 12.5px; font-weight: 600; margin-bottom: 2px; }
.chart-grid figcaption small { font-weight: 400; margin-left: 6px; }
.chart { position: relative; height: 176px; }
.chart-svg { position: absolute; inset: 0; }
.chart-svg svg { display: block; }
.chart text.axis { font-size: 10px; fill: var(--muted); font-variant-numeric: tabular-nums; }
.chart .grid { stroke: #ECF0E9; stroke-width: 1; }
.chart .line { fill: none; stroke-width: 2.1; stroke-linejoin: round; stroke-linecap: round; }
.chart .area { opacity: 0.14; }
.chart .band { fill: rgba(120, 168, 120, 0.1); }
.chart .band.cleaning { fill: rgba(120, 168, 120, 0.26); }
.chart .band-label { font-size: 9px; letter-spacing: 0.14em; fill: var(--forest); font-weight: 700; }
.chart .threshold { stroke: var(--warn); stroke-width: 1; stroke-dasharray: 4 4; opacity: 0.85; }
.chart .threshold-label { font-size: 9.5px; fill: var(--warn); }
.chart .cross { stroke: var(--muted); stroke-dasharray: 2 3; }
.chart .empty { font-size: 12px; fill: var(--muted); }
.chart-tip { position: absolute; top: 8px; z-index: 5; pointer-events: none; padding: 7px 10px; border-radius: 8px; background: var(--white); border: 1px solid var(--line-2); box-shadow: var(--shadow); font-size: 11.5px; min-width: 120px; }
.chart-tip .tip-t { color: var(--muted-strong); margin-bottom: 3px; font-variant-numeric: tabular-nums; }
.chart-tip i { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 6px; }
.chart-tip b { margin-left: 4px; font-variant-numeric: tabular-nums; }

/* ---------- timeline ---------- */
.timeline { list-style: none; margin: 0; padding: 0; max-height: 480px; overflow: auto; }
.ev { display: grid; grid-template-columns: 14px 62px 1fr; gap: 8px; padding: 8px 4px; border-bottom: 1px solid var(--line); font-size: 12px; }
.ev:last-child { border-bottom: 0; }
.ev-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); margin-top: 5px; }
.ev.success .ev-dot { background: var(--leaf); } .ev.warning .ev-dot { background: var(--warn); } .ev.critical .ev-dot { background: var(--err); box-shadow: 0 0 0 3px #F3D5D5; } .ev.info .ev-dot { background: var(--wind); }
.ev time { color: var(--muted-strong); font-variant-numeric: tabular-nums; font-size: 11.5px; }
.ev b { font-weight: 600; }
.ev p { color: var(--muted-strong); font-size: 11.5px; margin-top: 1px; }
.tag { display: inline-block; font-size: 8.5px; letter-spacing: 0.14em; font-weight: 700; padding: 1px 5px; margin-right: 7px; border-radius: 3px; background: var(--sage); color: var(--forest); vertical-align: 1px; }
.ev.new { animation: evin 1.1s var(--ease); }

/* ---------- console ---------- */
.console { padding: 0; }
.console summary { cursor: pointer; padding: 12px 20px; font-size: 11.5px; letter-spacing: 0.18em; text-transform: uppercase; font-weight: 700; color: var(--forest); list-style-position: inside; }
.console summary span { margin-left: 12px; letter-spacing: 0; text-transform: none; font-weight: 400; color: var(--muted-strong); }
.console-lines { max-height: 220px; overflow: auto; padding: 0 20px 14px; font: 11.5px var(--mono); }
.cl { display: grid; grid-template-columns: 64px 70px 1fr; gap: 8px; padding: 1px 0; color: var(--muted-strong); }
.cl span { color: var(--muted); } .cl code { color: inherit; background: none; padding: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.cl.json code { color: var(--text); } .cl.malformed code, .cl.rejected code, .cl.malformed span, .cl.rejected span { color: var(--warn); }

/* ---------- dialog / report ---------- */
.dialog { border: 1px solid var(--line-2); border-radius: 16px; background: var(--white); color: var(--text); padding: 22px 24px; width: min(480px, 92vw); box-shadow: 0 20px 60px -20px rgba(37, 49, 43, 0.4); }
.dialog::backdrop { background: rgba(37, 49, 43, 0.4); }
.dialog h2 { font: 600 20px var(--serif); margin-bottom: 4px; color: var(--forest); }
.dialog-note { font-size: 12px; color: var(--muted-strong); margin-bottom: 14px; }
.dialog label { display: grid; gap: 4px; font-size: 13px; margin-bottom: 12px; }
.dialog label small { font-size: 11.5px; }
.dialog input[type="number"] { background: var(--ivory); border: 1px solid var(--line-2); border-radius: 8px; padding: 7px 10px; width: 100%; }
.dialog label.check { grid-template-columns: auto 1fr; align-items: start; column-gap: 10px; }
.dialog label.check small { grid-column: 2; }
.dialog-error { color: var(--err); font-size: 12px; min-height: 16px; }
.dialog-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 6px; }
.report-view { position: fixed; inset: 0; z-index: 50; overflow: auto; background: #fff; color: #111; }
.report-bar { position: sticky; top: 0; display: flex; justify-content: space-between; align-items: center; padding: 10px 24px; background: var(--forest); color: #fff; }
.report { max-width: 820px; margin: 24px auto 60px; padding: 0 24px; font: 13.5px/1.5 var(--font); color: #111; }
.report h1 { font-size: 24px; margin-bottom: 8px; } .report h2 { font-size: 15px; margin: 22px 0 6px; border-bottom: 1px solid #ccc; padding-bottom: 3px; }
.report table { width: 100%; border-collapse: collapse; } .report th { text-align: left; width: 210px; vertical-align: top; padding: 4px 8px 4px 0; color: #444; font-weight: 600; } .report td { padding: 4px 0; }
.report ul { padding-left: 20px; } .report .none { color: #666; } .report .sim-note { padding: 10px 12px; background: #fff3cd; border: 1px solid #e0b100; margin: 10px 0; }

/* ---------- live power summary ---------- */
.summary { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; }
.sum { padding: 10px 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--white); box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.sum small { font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted-strong); font-weight: 700; }
.sum b { font: 600 22px var(--serif); font-variant-numeric: tabular-nums; color: var(--forest); overflow-wrap: anywhere; }
.sum.off b { color: var(--muted); }
.sum span { font-size: 11.5px; color: var(--muted-strong); }

/* ---------- sensor health center ---------- */
.health-panel { padding-bottom: 20px; }
.hsum { display: flex; gap: 6px; flex-wrap: wrap; }
.hs { font-size: 11px; font-weight: 700; padding: 2px 10px; border-radius: 99px; border: 1px solid var(--line-2); background: #F2F5F0; color: var(--muted-strong); }
.hs.s-healthy { color: var(--forest); background: var(--sage); border-color: #BFD6BC; }
.hs.s-warning, .hs.s-stale { color: var(--warn); background: #FBF1DC; border-color: #E8CF9C; }
.hs.s-suspected-failure, .hs.s-disconnected { color: var(--err); background: #F9E6E6; border-color: #EBBDBD; }
.health-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); gap: 12px; }
.htile { border: 1px solid var(--line); border-left: 4px solid var(--line-2); border-radius: 12px; padding: 12px 14px; background: #FBFCFA; display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.htile header { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.htile h3 { font-size: 13px; font-weight: 700; }
.gpio { font: 10.5px var(--mono); color: var(--muted-strong); text-align: right; }
.hbadges { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.hbadge { font-size: 10.5px; font-weight: 800; letter-spacing: 0.08em; padding: 2px 9px; border-radius: 6px; background: #EEF2EB; color: var(--muted-strong); cursor: help; }
.conf { font-size: 9.5px; font-weight: 700; letter-spacing: 0.1em; padding: 2px 7px; border-radius: 6px; border: 1px solid var(--line-2); color: var(--muted-strong); cursor: help; }
.hread { font: 600 16px var(--serif); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; min-height: 22px; }
.hread.hist { color: var(--muted); }
.hread i { font: 700 9.5px var(--font); font-style: normal; letter-spacing: 0.1em; text-transform: uppercase; color: var(--warn); margin-right: 4px; }
.hmeta { font-size: 11.5px; color: var(--muted-strong); }
.herr { font-size: 12px; color: var(--text); }
.hact { font-size: 12px; } .hact b { color: var(--forest); }
.hnote { font-size: 11px; color: var(--muted-strong); font-style: italic; }
.htile.s-healthy { border-left-color: var(--leaf); } .hbadge.s-healthy { background: var(--sage); color: var(--forest); }
.htile.s-warning, .htile.s-stale { border-left-color: var(--amber); background: #FFFCF4; } .hbadge.s-warning, .hbadge.s-stale { background: #FBF1DC; color: var(--warn); }
.htile.s-suspected-failure { border-left-color: var(--err); background: #FEF8F8; } .hbadge.s-suspected-failure { background: #F9E6E6; color: var(--err); }
.htile.s-disconnected { border-left-color: var(--err); } .hbadge.s-disconnected { background: #F9E6E6; color: var(--err); }
.htile.s-not-configured { border-left-color: var(--line-2); background: repeating-linear-gradient(-45deg, #FAFBF8 0 8px, #F4F7F2 8px 16px); } .htile.s-not-configured .hread { color: var(--muted); }
.htile.s-unknown { border-left-color: var(--line-2); }

/* ---------- serial connection panel ---------- */
.serial-panel dl { margin: 0; display: grid; }
.serial-panel dl div { display: grid; grid-template-columns: 150px 1fr; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 12.5px; }
.serial-panel dt { color: var(--muted-strong); } .serial-panel dd { margin: 0; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.sbanner { padding: 9px 12px; border-radius: 10px; font-weight: 700; font-size: 12px; letter-spacing: 0.05em; margin-bottom: 8px; }
.sbanner.ok { background: var(--sage); color: var(--forest); } .sbanner.sim { background: #FBF0D6; color: var(--sim-ink); } .sbanner.warn { background: #FBF1DC; color: var(--warn); }
.serial-actions { margin-top: 12px; display: flex; gap: 8px; }

/* ---------- diagnostics lifecycle ---------- */
.diag.error { border-left-color: var(--err); background: #FEF6F6; } .diag.error .sev { color: var(--err); background: #F9E6E6; }
.diag.recovered { background: #F7FAF6; border-left-color: var(--leaf); }
.diag .times { font-size: 11px; color: var(--muted-strong); margin-bottom: 3px; }
.diag .recov { font-size: 11.5px; margin-top: 3px; } .diag .recov b { color: var(--forest); }
.sub-chip { font-size: 10px; font-weight: 700; letter-spacing: 0.06em; padding: 1px 7px; border-radius: 99px; background: var(--sage); color: var(--forest); }
.st { margin-left: auto; font-size: 9.5px; font-weight: 800; letter-spacing: 0.12em; }
.st.act { color: var(--warn); } .st.rec { color: var(--forest); }
.diag-h .st + time { margin-left: 8px; }
.ev.error .ev-dot { background: var(--err); }
.health-chip.error b { color: var(--err); }
.vtrigger { font-size: 12px; margin: 6px 0; color: var(--muted-strong); } .vtrigger b { color: var(--forest); }

/* ---------- demo scenario selector ---------- */
.scn-select { min-width: 280px; max-width: 100%; padding: 6px 10px; border-radius: 9px; border: 1px solid #E5D7AE; background: var(--white); color: var(--text); font-weight: 600; font-size: 13px; }
.demo-row .btn.primary { white-space: nowrap; }

/* ---------- motion ---------- */
@keyframes pulse { 0% { box-shadow: 0 0 0 0 currentColor; } 70% { box-shadow: 0 0 0 7px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
@keyframes tick { 0% { transform: translateY(3px); opacity: 0.5; } 100% { transform: none; opacity: 1; } }
@keyframes rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes evin { 0% { opacity: 0; transform: translateX(-10px); background: #E3EFDF; } 40% { opacity: 1; transform: none; } 100% { background: transparent; } }
@keyframes dash { to { stroke-dashoffset: -16; } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes breathe { 0%, 100% { transform: scale(1); opacity: 0.85; } 50% { transform: scale(1.08); opacity: 1; } }
@keyframes streak { to { stroke-dashoffset: -36; } }
@keyframes glint { 0% { transform: translateX(160px) skewX(-14deg); opacity: 0; } 12% { opacity: 1; } 45% { transform: translateX(520px) skewX(-14deg); opacity: 0.9; } 55%, 100% { transform: translateX(520px) skewX(-14deg); opacity: 0; } }
@keyframes windflow { to { stroke-dashoffset: -120; } }
@keyframes buzz { 0% { transform: translate(0, 0); } 25% { transform: translate(1.3px, -1px); } 50% { transform: translate(-1px, 1.2px); } 75% { transform: translate(1px, 1px); } 100% { transform: translate(0, 0); } }
@keyframes ripple { 0% { opacity: 0.9; transform: scale(0.85); } 100% { opacity: 0; transform: scale(1.35); } }
@keyframes drift { from { transform: translateX(-30px); } to { transform: translateX(50px); } }
@keyframes shine { from { transform: translateX(0); } to { transform: translateX(150px); } }
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
@keyframes press { 0% { transform: translateY(0); } 30% { transform: translateY(5px); } 100% { transform: translateY(0); } }
@keyframes pulsering { 0% { opacity: 0.9; transform: scale(0.6); } 100% { opacity: 0; transform: scale(1.7); } }
@keyframes boltup { 0% { opacity: 0; transform: translateY(14px); } 25% { opacity: 1; } 100% { opacity: 0; transform: translateY(-18px); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
  .particle { display: none !important; }
}

/* ---------- responsive ---------- */
@media (max-width: 1180px) {
  .hero { grid-template-columns: minmax(0, 1fr); }
  .hero-copy { padding: 26px 24px 8px; }
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .split { grid-template-columns: minmax(0, 1fr); }
  .nav { flex-wrap: wrap; gap: 10px 16px; } .mainnav { order: 5; width: 100%; overflow-x: auto; }
  .linkblock { margin-left: 0; align-items: flex-start; }
  .demo-row { flex-wrap: wrap; }
}
@media (max-width: 720px) {
  main { padding: 12px; } .nav { padding: 10px 14px; } .notice { margin: 10px 14px 0; } .demobar { padding: 10px 14px; }
  .cards, .chart-grid, .vgrid, .summary { grid-template-columns: minmax(0, 1fr); }
  .sensor-list li { grid-template-columns: 1fr auto; } .sensor-list small { grid-column: 1 / -1; }
}

/* ---------- print: only the report ---------- */
@media print {
  body[data-report="1"] #app, body[data-report="1"] .report-bar, body[data-report="1"] dialog { display: none !important; }
  body[data-report="1"] .report-view { position: static; overflow: visible; }
}

/* laptop widths: the connection state is in the hero and the serial panel, so the nav drops its duplicate badge */
@media (max-width: 1499px) { .nav .linkblock { display: none; } .nav { gap: 14px; } .mainnav a, .navbtn { padding: 6px 9px; } }
