/* OwnHLS — "Master control" (studios/design/own-storage-hls-hosting/design-spec.md). Tokens copied from spec §2.1. */
@font-face { font-family: "Barlow Condensed"; font-style: normal; font-weight: 600; font-display: swap; src: url(/fonts/barlow-condensed-latin-600-normal.woff2) format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 400; font-display: swap; src: url(/fonts/ibm-plex-sans-latin-400-normal.woff2) format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 500; font-display: swap; src: url(/fonts/ibm-plex-sans-latin-500-normal.woff2) format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 600; font-display: swap; src: url(/fonts/ibm-plex-sans-latin-600-normal.woff2) format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url(/fonts/ibm-plex-mono-latin-400-normal.woff2) format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url(/fonts/ibm-plex-mono-latin-500-normal.woff2) format("woff2"); }

/* tokens:own-storage-hls-hosting */
:root {
  color-scheme: light dark;
  --c-canvas: #F2F3F1;
  --c-surface: #FFFFFF;
  --c-well: #E7E9E6;
  --c-border: #D2D6D1;
  --c-border-strong: #7A827A;
  --c-text: #131517;
  --c-text-muted: #50575E;
  --c-signal: #3B6E0F;
  --c-signal-fill: #3B6E0F;
  --c-signal-fill-hover: #325E0C;
  --c-on-signal: #FFFFFF;
  --c-signal-tint: #E6F2D6;
  --c-warn: #8A5A00;
  --c-warn-fill: #F2B544;
  --c-on-warn: #1A1204;
  --c-warn-tint: #FFF1D2;
  --c-stop: #B3261E;
  --c-stop-fill: #B3261E;
  --c-stop-fill-hover: #921E17;
  --c-on-stop: #FFFFFF;
  --c-stop-tint: #FBE3E1;
  --c-led-off: #D5D9D3;
  --c-led-signal: #3B6E0F;
  --c-led-warn: #9A6700;
  --c-led-stop: #B3261E;
  --c-code-bg: #E9ECE8;
  --c-code-text: #131517;
  --c-focus: #131517;
  --c-scrim: rgba(19, 21, 23, 0.48);
  --c-shadow: rgba(19, 21, 23, 0.16);
  --p-bg: #000000;
  --p-card: #0B0C0E;
  --p-text: #E8EAED;
  --p-muted: #A3ABB5;
  --p-play: #FFFFFF;
  --p-on-play: #000000;
}
@media (prefers-color-scheme: dark) {
  :root {
    --c-canvas: #0E1012;
    --c-surface: #16191D;
    --c-well: #1D2126;
    --c-border: #2C3138;
    --c-border-strong: #6B747F;
    --c-text: #E8EAED;
    --c-text-muted: #A3ABB5;
    --c-signal: #A3E45C;
    --c-signal-fill: #A3E45C;
    --c-signal-fill-hover: #B8EC7D;
    --c-on-signal: #0D1604;
    --c-signal-tint: #18240D;
    --c-warn: #F2B544;
    --c-warn-fill: #F2B544;
    --c-on-warn: #1A1204;
    --c-warn-tint: #2A2111;
    --c-stop: #FF6B63;
    --c-stop-fill: #C4302B;
    --c-stop-fill-hover: #B8302A;
    --c-on-stop: #FFFFFF;
    --c-stop-tint: #2E1413;
    --c-led-off: #262B31;
    --c-led-signal: #A3E45C;
    --c-led-warn: #F2B544;
    --c-led-stop: #FF6B63;
    --c-code-bg: #0A0B0D;
    --c-code-text: #D7DCE1;
    --c-focus: #E8EAED;
    --c-scrim: rgba(0, 0, 0, 0.64);
    --c-shadow: rgba(0, 0, 0, 0.5);
  }
}
/* end tokens */

:root {
  --f-display: "Barlow Condensed", "Arial Narrow", "Roboto Condensed", sans-serif;
  --f-body: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --f-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --s-1: 2px; --s-2: 4px; --s-3: 8px; --s-4: 12px; --s-5: 16px; --s-6: 20px; --s-7: 24px; --s-8: 32px; --s-9: 40px; --s-10: 48px; --s-11: 64px; --s-12: 96px;
  --r-1: 2px; --r-2: 4px; --r-3: 8px;
  --m-fast: 120ms; --m-base: 200ms; --ease: cubic-bezier(.2, 0, 0, 1);
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--c-canvas); color: var(--c-text); font: 400 16px/24px var(--f-body); overflow-x: hidden; }
img, svg, video, iframe { max-width: 100%; }
a { color: var(--c-signal); }
h1, h2, h3, p, dl, dd, blockquote, figure { margin: 0; } /* dl: its UA 1em margin pushed the CONNECTED panel body to 40 px (design review cycle 5) */
.h2-look { font: 600 clamp(21px, 1vw + 14px, 24px)/1.25 var(--f-body); }
h1 { font: 600 clamp(30px, 2.5vw + 12px, 40px)/calc(1em + 4px) var(--f-display); letter-spacing: -0.005em; text-transform: none; }
h2 { font: 600 clamp(21px, 1vw + 14px, 24px)/1.25 var(--f-body); }
h3 { font: 600 clamp(17px, 0.3vw + 15px, 18px)/24px var(--f-body); }
.label { font: 600 13px/16px var(--f-display); letter-spacing: 0.08em; text-transform: uppercase; color: var(--c-text-muted); margin: 0; }
.small { font-size: 14px; line-height: 20px; }
.muted { color: var(--c-text-muted); }
.mono { font-family: var(--f-mono); font-size: 14px; line-height: 22px; overflow-wrap: anywhere; }
/* --t-mono steps down to 13/20 below 640 px (spec 2.3); only 400 and 500 Plex Mono faces ship, so a mono <strong> is 500, never a faked bold */
@media (max-width: 639px) { .mono { font-size: 13px; line-height: 20px; } }
strong.mono, .mono strong, b.mono { font-weight: 500; }
/* the Disconnected status block takes focus on arrival (it is role=status, tabindex=-1, not a control): no focus frame (review cycle 8 m4) */
[data-disconnected]:focus { outline: none; }
[data-forgot-dismissed]:focus { outline: none; }
.readout { font: 500 clamp(28px, 2.084vw + 14.66px, 36px)/calc(1em + 4px) var(--f-mono); font-variant-numeric: tabular-nums; }
.timecode { font: 500 13px/16px var(--f-mono); font-variant-numeric: tabular-nums; }
.stack > * + * { margin-top: var(--s-5); }
.stack-s > * + * { margin-top: var(--s-3); }
.row { display: flex; gap: var(--s-4); align-items: center; flex-wrap: wrap; }
.skip { position: absolute; left: -9999px; top: 8px; z-index: 100; background: var(--c-surface); padding: 8px 12px; }
.skip:focus { left: 8px; }
.icon { flex: none; vertical-align: middle; }
:focus-visible { outline: 2px solid var(--c-focus); outline-offset: 2px; }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
@media (max-width: 639px) { .hide-phone { display: none !important; } }
@media (min-width: 640px) { .only-phone { display: none !important; } }

/* buttons */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--s-3); min-height: 44px; padding: 0 var(--s-6); border-radius: var(--r-2); font: 500 16px/24px var(--f-body); text-decoration: none; cursor: pointer; border: 1px solid transparent; background: transparent; color: var(--c-text); white-space: nowrap; }
.btn.primary { background: var(--c-signal-fill); color: var(--c-on-signal); }
.btn.primary:hover { background: var(--c-signal-fill-hover); }
.btn.secondary { border-color: var(--c-border-strong); color: var(--c-text); }
.btn.secondary:hover { background: var(--c-well); }
.btn.ghost { color: var(--c-signal); }
.btn.ghost:hover { text-decoration: underline; }
.btn.danger { background: var(--c-stop-fill); color: var(--c-on-stop); }
.btn.danger:hover { background: var(--c-stop-fill-hover); }
.btn.danger-outline { border-color: var(--c-stop); color: var(--c-stop); }
.btn.size-s { min-height: 44px; padding: 0 var(--s-5); }
.btn[disabled], .btn[aria-disabled="true"] { background: var(--c-well); color: var(--c-text-muted); border-color: transparent; cursor: not-allowed; }
.btn.full { width: 100%; }
/* a ghost action lines up with the text above it: no inline padding, a 44 px target kept by its height and min-width
   (design review cycle 3 m3); an icon-only ghost (it carries an aria-label) keeps its icon centred */
.btn.ghost, .btn.ghost.size-s { padding-left: 0; padding-right: 0; min-width: 44px; justify-content: flex-start; }
.btn.ghost[aria-label] { justify-content: center; }
/* a link that stands alone in a message is a 44 px target (§2.4; design review cycle 3 m5) */
a.target { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; }
.link { display: inline-flex; gap: 4px; align-items: center; color: var(--c-signal); min-height: 24px; }
button.linkish { background: none; border: 0; color: var(--c-signal); font: inherit; cursor: pointer; padding: 0; text-decoration: underline; min-height: 44px; }

/* fields */
.field { display: flex; flex-direction: column; gap: var(--s-2); }
.field label, .field .field-label { font: 500 14px/20px var(--f-body); color: var(--c-text); }
.input { height: 48px; width: 100%; background: var(--c-surface); color: var(--c-text); border: 1px solid var(--c-border-strong); border-radius: var(--r-2); padding: 0 12px; font: 400 16px/24px var(--f-body); }
textarea.input { height: auto; padding: 12px; font-family: var(--f-mono); font-size: 16px; }
.input::placeholder { color: var(--c-text-muted); opacity: 1; }
.input[aria-invalid="true"] { border: 2px solid var(--c-stop); }
.help { font-size: 14px; line-height: 20px; color: var(--c-text-muted); }
.error { display: flex; gap: 6px; align-items: flex-start; color: var(--c-stop); font-size: 14px; line-height: 20px; }
.prefix-wrap { position: relative; }
.prefix-wrap .prefix { position: absolute; left: 12px; top: 12px; color: var(--c-text-muted); }
.prefix-wrap .input { padding-left: 28px; }
.check-row { display: flex; gap: var(--s-3); align-items: center; min-height: 44px; }
.check-row input { width: 20px; height: 20px; accent-color: var(--c-signal-fill); }
select.input { appearance: auto; }

/* tally */
/* a wrapped row keeps its mark on the first 20 px line (design review cycle 10 m): 16 px marks 2 px down, the 10 px dot 5 px */
.tally { display: inline-flex; align-items: flex-start; gap: var(--s-3); font: 500 14px/20px var(--f-body); color: var(--c-text); }
.tally > .icon, .tally > .dot.ok { margin-top: 2px; }
.tally > .dot:not(.ok) { margin-top: 5px; }
.tally .dot { width: 10px; height: 10px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; flex: none; }
.tally .dot.idle { border: 1.5px solid var(--c-border-strong); }
.tally .dot.ok { background: var(--c-signal); color: var(--c-surface); width: 16px; height: 16px; }
.tally .dot.ok .icon { width: 10px; height: 10px; stroke-width: 3; }
/* nav rail and menu sheet: one 16 px slot per mark, centred, so the column is straight (design review cycle 4 m2) */
.nav-mark { width: 16px; height: 16px; justify-content: center; gap: 0; flex: none; }
.nav-mark .icon { width: 16px; height: 16px; }
/* the price: the number in the readout face, "/month" in body text (spec §6.2, §6.15; design review cycle 4 m5) */
.per { font: 400 16px/24px var(--f-body); margin-left: 2px; }
/* an expandable row shows it opens: a chevron that turns when open (spec §2.5; design review cycle 4 m3) */
summary { list-style: none; }
summary::-webkit-details-marker { display: none; }
summary .chev { transition: transform var(--m-fast) var(--ease); }
details[open] > summary .chev { transform: rotate(180deg); }
details.faq summary { justify-content: space-between; gap: var(--s-5); }
.estimate > summary .chev { margin-left: var(--s-3); }
.tally[data-state="warn"] .icon { color: var(--c-warn); }
.tally[data-state="stop"] .icon { color: var(--c-stop); }
.tally[data-state="warn"] .tally-word { color: var(--c-warn); }
.tally[data-state="stop"] .tally-word { color: var(--c-stop); }

/* segment strip */
.strip { display: inline-flex; gap: 2px; vertical-align: middle; flex-wrap: nowrap; max-width: 100%; }
.strip i { display: block; width: 6px; height: 12px; border-radius: var(--r-1); background: var(--c-led-off); flex: 0 1 6px; min-width: 2px; }
.strip.size-l i { width: 10px; height: 20px; flex-basis: 10px; }
.strip i.on { background: var(--c-led-signal); }
.strip i.stop { background: var(--c-led-stop); }
.strip.indeterminate i { animation-timing-function: steps(1); animation-iteration-count: infinite; animation-delay: calc(var(--i, 0) * 400ms); }
/* one lit cell per 400 ms, left to right (design-spec §3.5): each cell is lit for 1/count of a count × 400 ms cycle, delayed by its step */
.strip.indeterminate[data-cells="4"] i { animation-name: step4; animation-duration: 1.6s; }
.strip.indeterminate[data-cells="8"] i { animation-name: step8; animation-duration: 3.2s; }
.strip.indeterminate[data-cells="32"] i { animation-name: step32; animation-duration: 12.8s; }
/* each cell goes dark 16 ms before the next one lights: cells whose animations start a frame apart never show two lit at once
   (cycle 10: 4 of 12 runs of cycle6 D1 sampled two lit cells with the exact 25% / 12.5% / 3.125% boundaries) */
@keyframes step4 { 0% { background: var(--c-led-signal); } 24% { background: var(--c-led-off); } }
@keyframes step8 { 0% { background: var(--c-led-signal); } 12% { background: var(--c-led-off); } }
@keyframes step32 { 0% { background: var(--c-led-signal); } 3% { background: var(--c-led-off); } }

/* ceiling meter */
.meter { position: relative; width: 100%; }
.meter { --meter-gap: 3px; }
.meter-cells { display: grid; grid-template-columns: repeat(50, minmax(0, 1fr)); gap: var(--meter-gap); }
.meter.cells-25 .meter-cells { grid-template-columns: repeat(25, minmax(0, 1fr)); gap: 2px; }
.meter-cells i { display: block; height: 28px; border-radius: var(--r-1); background: var(--c-led-off); }
.meter.cells-25 .meter-cells i { height: 16px; }
.meter-cells i.sig { background: var(--c-led-signal); }
.meter-cells i.warn { background: var(--c-led-warn); }
.meter-cells i.stop { background: var(--c-led-stop); }
.meter.dim .meter-cells i { opacity: 0.25; }
.meter-marks { position: relative; height: 22px; margin-top: 4px; }
/* the tick line is the label's RIGHT border, centred in the gap between cell 40 and cell 41 (§3.6): cell 41 starts at 80% + 0.8 gap
   and cell 40 ends at 80% - 0.2 gap, so the gap's centre is 80% + 0.3 gap. The label sits left of the line, clear of LIMIT
   (design review cycle 3 D1: a translateX(-50%) on the label moved the line itself to 67-76%). */
.meter-tick { position: absolute; top: 0; right: calc(20% - 0.3 * var(--meter-gap) - 0.5px); border-right: 1px solid var(--c-text-muted); padding-right: 4px; font: 600 13px/16px var(--f-display); letter-spacing: 0.08em; text-transform: uppercase; color: var(--c-text-muted); white-space: nowrap; }
.meter-limit { position: absolute; top: 0; right: 0; border-right: 2px solid var(--c-text); padding-right: 4px; font: 600 13px/16px var(--f-display); letter-spacing: 0.08em; text-transform: uppercase; color: var(--c-text); white-space: nowrap; }
@media (max-width: 639px) {
  .meter { --meter-gap: 2px; } .meter-cells i { height: 24px; }
  /* phone: the full labels on two rows, so "80% WARNING" and "LIMIT $10" never overlap (design review m2) */
  .meter-marks { height: 40px; }
  .meter-limit { top: 20px; }
}
.nowrap { white-space: nowrap; }
.estimate > summary { display: flex; align-items: center; min-height: 44px; cursor: pointer; color: var(--c-signal); font-weight: 500; }
.estimate[open] > summary { margin-bottom: var(--s-5); }
@media (min-width: 640px) { .estimate > summary { display: none; } }

/* ladder */
.ladder { list-style: none; margin: 0 0 var(--s-3); padding: 0; display: flex; flex-direction: column; gap: 6px; }
.ladder li { display: grid; grid-template-columns: 56px 1fr; align-items: center; gap: var(--s-3); }
.rung-label { font: 500 13px/16px var(--f-mono); }
.rung { display: block; height: 20px; border-radius: var(--r-1); background: var(--c-well); border: 1px solid var(--c-border-strong); }
.rung.top { background: var(--c-signal-fill); border-color: var(--c-signal-fill); }

/* panels */
.panel { background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--r-2); min-width: 0; }
.panel-bar { min-height: 40px; display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); padding: 0 var(--s-5); border-bottom: 1px solid var(--c-border); flex-wrap: wrap; }
.panel-body { padding: var(--s-7); min-width: 0; }
@media (max-width: 639px) { .panel-body { padding: var(--s-5); } }
.panels > * + * { margin-top: var(--s-7); }
.block { display: flex; gap: var(--s-4); align-items: flex-start; padding: var(--s-4) var(--s-5); border-radius: var(--r-2); background: var(--c-well); }
.block.ok { background: var(--c-signal-tint); }
.block.ok > .icon { color: var(--c-signal); }
.block.warn { background: var(--c-warn-tint); }
.block.warn > .icon { color: var(--c-warn); }
.block.stop { background: var(--c-stop-tint); }
.block.stop > .icon { color: var(--c-stop); }
.block > div > * + * { margin-top: var(--s-2); }
.block .btn { white-space: normal; text-align: center; }
@media (max-width: 639px) { .block .row { flex-direction: column; align-items: stretch; } .block .row .btn { width: 100%; } }
.code-box { background: var(--c-code-bg); color: var(--c-code-text); border: 1px solid var(--c-border); border-radius: var(--r-2); padding: var(--s-5); font: 400 14px/22px var(--f-mono); white-space: pre-wrap; word-break: break-all; max-height: 200px; overflow: auto; margin: 0; }
.credit { font-size: 14px; line-height: 20px; color: var(--c-text-muted); }
.empty { max-width: 520px; }
.empty > * + * { margin-top: var(--s-4); }

/* banners */
.banners { position: relative; z-index: 20; }
.banner { display: flex; gap: var(--s-4); align-items: flex-start; padding: var(--s-4) var(--s-5); border-bottom: 1px solid var(--c-border); flex-wrap: wrap; }
.banner .text { flex: 1 1 240px; min-width: 0; }
/* the icon marks the first line, as in a .block (design review cycle 9 m2): 20 px icon centred in the 24 px first line box */
.banner > .icon { margin-top: 2px; flex: none; }
.banner.warn { background: var(--c-warn-tint); }
.banner.warn > .icon { color: var(--c-warn); }
.banner.stop { background: var(--c-stop-tint); }
.banner.stop > .icon { color: var(--c-stop); }
.banner.info { background: var(--c-well); }
.banner.info > .icon { color: var(--c-text-muted); }

/* public pages */
.pub-inner { max-width: 1200px; margin: 0 auto; padding: 0 var(--s-9); }
@media (max-width: 1023px) { .pub-inner { padding: 0 var(--s-7); } }
@media (max-width: 639px) { .pub-inner { padding: 0 var(--s-5); } }
.pub-header { background: var(--c-canvas); border-bottom: 1px solid var(--c-border); }
/* sticky on desktop (design-spec §6.1), so the header's Start is at hand once the hero's has scrolled away */
@media (min-width: 1024px) { .pub-header { position: sticky; top: 0; z-index: 30; } html:has(.pub-header) { scroll-padding-top: 72px; } }
.pub-header .pub-inner { display: flex; align-items: center; justify-content: space-between; min-height: 64px; gap: var(--s-4); }
/* 24 px between header links: a ghost link has no inline padding (cycle 3 m3), so the gap is the only space between two of them
   (design review cycle 4 D1: "Pricing Sign in" read as one link at 6 px) */
.pub-nav { display: flex; gap: var(--s-7); align-items: center; }
/* one "Start" on the first screen of / (ux-plan F1.1): the header's shows once the hero's has scrolled away (common.js) */
.pub-nav [data-follows-hero]:not(.shown) { display: none; }
.logo { display: inline-flex; align-items: center; gap: var(--s-3); text-decoration: none; color: var(--c-text); min-height: 44px; }
.logo .wordmark { font: 600 22px/1 var(--f-display); letter-spacing: 0.02em; }
.logo-dot { fill: var(--c-stop); }
.logo-on { fill: var(--c-led-signal); }
.logo-off { fill: var(--c-led-off); }
.pub-footer { border-top: 1px solid var(--c-border); margin-top: var(--s-11); padding: var(--s-9) 0 var(--s-7); }
.footer-inner { display: flex; gap: var(--s-7); align-items: center; flex-wrap: wrap; }
.footer-links { display: flex; gap: var(--s-5); flex-wrap: wrap; }
.footer-links a { min-height: 44px; display: inline-flex; align-items: center; }
.hero { padding: var(--s-12) 0 var(--s-11); display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--s-9); align-items: start; }
@media (max-width: 1023px) { .hero { grid-template-columns: minmax(0, 1fr); padding: var(--s-8) 0 var(--s-9); } }
.hero h1 { font: 600 clamp(40px, 4.2vw + 8px, 60px)/1.03 var(--f-display); letter-spacing: -0.005em; }
.lead { font: 400 clamp(17px, 0.3vw + 15px, 18px)/1.55 var(--f-body); color: var(--c-text-muted); max-width: 36em; }
@media (max-width: 639px) { .lead-rest { display: none; } }
.section { padding: var(--s-9) 0 0; }
.section > h2 { margin-bottom: var(--s-5); }
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-7); }
.section.grid-2 { align-items: start; }
.section.grid-2.equal { align-items: stretch; }
.instrument { background: var(--c-well); border-radius: var(--r-2); padding: var(--s-5); min-height: 160px; display: flex; flex-direction: column; justify-content: space-between; gap: var(--s-4); }
.panel.price-centre { max-width: 560px; margin-left: auto; margin-right: auto; }
.pricing > * + * { margin-top: var(--s-7); }
.pricing > .section { padding-top: 0; }
.pay-ledger { display: grid; grid-template-columns: minmax(0, 1fr) 40px minmax(0, 1fr); align-items: start; }
.pay-plus { align-self: stretch; position: relative; font: 500 20px/24px var(--f-mono); color: var(--c-text-muted); }
.pay-plus::before { content: ""; position: absolute; left: 50%; top: 0; bottom: 0; border-left: 1px solid var(--c-border); }
.pay-plus > span { position: relative; display: block; width: 24px; margin: var(--s-10) auto 0; text-align: center; background: var(--c-surface); }
@media (max-width: 767px) {
  .pay-ledger { grid-template-columns: minmax(0, 1fr); }
  .pay-plus { height: 24px; margin: var(--s-5) 0; }
  .pay-plus::before { left: 0; right: 0; top: 50%; bottom: auto; border-left: 0; border-top: 1px solid var(--c-border); }
  .pay-plus > span { margin: 0 auto; }
}
@media (max-width: 767px) { .grid-2 { grid-template-columns: minmax(0, 1fr); } }
.list-plain { list-style: none; margin: 0; padding: 0; }
.list-plain > li { display: flex; gap: var(--s-3); align-items: flex-start; padding: var(--s-3) 0; border-bottom: 1px solid var(--c-border); }
.list-plain > li:last-child { border-bottom: 0; }
.list-plain > li > .icon { margin-top: 2px; color: var(--c-signal); }
.quote { border-left: 2px solid var(--c-stop); padding-left: var(--s-5); }
.steps { margin: 0; padding-left: var(--s-7); }
.steps > li + li { margin-top: var(--s-3); }
.steps > li::marker { font: 500 14px/20px var(--f-mono); color: var(--c-text-muted); }
.price-panel { max-width: 560px; }
.ledger { width: 100%; border-collapse: collapse; }
.ledger th, .ledger td { text-align: left; vertical-align: top; padding: var(--s-4) var(--s-3); border-bottom: 1px solid var(--c-border); font-size: 14px; line-height: 20px; }
.ledger thead th { background: var(--c-well); font: 600 13px/16px var(--f-display); letter-spacing: 0.08em; text-transform: uppercase; color: var(--c-text-muted); }
@media (max-width: 767px) {
  .ledger thead { display: none; }
  .ledger, .ledger tbody, .ledger tr, .ledger td, .ledger th { display: block; width: 100%; }
  .ledger tr { border: 1px solid var(--c-border); border-radius: var(--r-2); margin-bottom: var(--s-4); padding: var(--s-3); }
  .ledger td, .ledger th[scope="row"] { border: 0; padding: var(--s-2) 0; }
  .ledger td[data-label]::before { content: attr(data-label); display: block; font: 600 13px/16px var(--f-display); letter-spacing: 0.08em; text-transform: uppercase; color: var(--c-text-muted); }
}
details.faq { border-bottom: 1px solid var(--c-border); }
details.faq summary { min-height: 56px; display: flex; align-items: center; cursor: pointer; font-weight: 500; }
details.faq p { padding: 0 0 var(--s-5); }
.reading { max-width: 680px; }
.reading h2 { margin-top: var(--s-9); }
.reading p { margin-top: var(--s-4); line-height: 26px; }
.center-panel { max-width: 440px; margin: var(--s-12) auto 0; }
@media (max-width: 639px) { .center-panel { margin-top: var(--s-8); } }
.nosignal { aspect-ratio: 16 / 9; max-width: 360px; background: var(--c-code-bg); color: var(--c-code-text); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-4); border-radius: var(--r-2); font: 600 20px/1 var(--f-display); letter-spacing: 0.08em; text-transform: uppercase; }

/* app shell */
.topbar { position: sticky; top: 0; z-index: 30; height: 56px; background: var(--c-surface); border-bottom: 1px solid var(--c-border); display: flex; align-items: center; justify-content: space-between; padding: 0 var(--s-5); gap: var(--s-4); }
.topbar .who { display: flex; align-items: center; gap: var(--s-3); min-width: 0; }
.topbar .email { font-size: 14px; color: var(--c-text-muted); max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.signal-strip { display: none; gap: 6px; }
.signal-strip .sdot { width: 8px; height: 8px; border-radius: 999px; border: 1.5px solid var(--c-border-strong); }
.signal-strip .sdot[data-state="ok"] { background: var(--c-signal); border-color: var(--c-signal); }
.signal-strip .sdot[data-state="warn"] { background: var(--c-warn-fill); border-color: var(--c-warn); }
.signal-strip .sdot[data-state="stop"] { background: var(--c-stop); border-color: var(--c-stop); border-radius: 1px; }
.menu-btn { display: none; }
.shell { display: grid; grid-template-columns: 240px minmax(0, 1fr); min-height: calc(100vh - 56px); }
.rail { background: var(--c-canvas); border-right: 1px solid var(--c-border); padding: var(--s-5); }
.rail a, .menu-sheet nav a { display: flex; align-items: center; gap: var(--s-3); min-height: 44px; padding: 0 var(--s-4); color: var(--c-text); text-decoration: none; font-weight: 500; border-left: 2px solid transparent; border-radius: 0 var(--r-2) var(--r-2) 0; }
.rail a[aria-current="page"], .menu-sheet nav a[aria-current="page"] { border-left-color: var(--c-signal); background: var(--c-surface); }
.rail a .nav-label, .menu-sheet nav a .nav-label { flex: 1; }
.main-app { padding: var(--s-8) var(--s-9) var(--s-11); max-width: 1160px; min-width: 0; }
.main-app > h1 + .lead, .main-app > h1 + p { margin-top: var(--s-3); }
.main-app > .page-head { margin-bottom: var(--s-7); }
.page-head > * + * { margin-top: var(--s-3); }
.menu-sheet { position: fixed; inset: 0; z-index: 40; background: var(--c-canvas); padding: var(--s-5); overflow: auto; }
.menu-sheet .menu-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--s-5); }
.menu-sheet nav a { min-height: 56px; }
.menu-account { margin-top: var(--s-7); border-top: 1px solid var(--c-border); padding-top: var(--s-5); }
.menu-account > p { margin: 0 0 var(--s-4); }
.menu-scrim { position: fixed; inset: 0; z-index: 39; background: var(--c-scrim); }
/* from 1024 px the menu is a 360 px side sheet over a scrim, not the phone sheet stretched to 992 px rows (design review cycle 3 m4) */
@media (min-width: 1024px) {
  .menu-sheet { left: auto; width: 360px; border-left: 1px solid var(--c-border); box-shadow: 0 12px 32px var(--c-shadow); }
}
@media (max-width: 1279px) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  .rail { display: none; }
  .menu-btn { display: inline-flex; }
  .signout-desktop, .topbar .email { display: none; }
  .signal-strip { display: inline-flex; }
  .main-app { padding: var(--s-6) var(--s-7) var(--s-10); }
}
@media (max-width: 639px) { .main-app { padding: var(--s-6) var(--s-5) var(--s-10); } }
.toast { position: fixed; right: var(--s-7); bottom: var(--s-7); z-index: 60; background: var(--c-text); color: var(--c-canvas); padding: var(--s-4) var(--s-5); border-radius: var(--r-2); box-shadow: 0 12px 32px var(--c-shadow); }
@media (max-width: 639px) { .toast { left: var(--s-5); right: var(--s-5); bottom: var(--s-5); } }
.modal-scrim { position: fixed; inset: 0; background: var(--c-scrim); z-index: 50; display: flex; align-items: center; justify-content: center; padding: var(--s-5); }
.modal { background: var(--c-surface); color: var(--c-text); border: 0; border-radius: var(--r-3); max-width: 480px; width: calc(100% - 32px); max-height: calc(100% - 32px); margin: auto; padding: var(--s-7); box-shadow: 0 12px 32px var(--c-shadow); }
.modal::backdrop { background: var(--c-scrim); }
.modal > * + *, .modal > form > * + * { margin-top: var(--s-4); }
.modal .actions { display: flex; justify-content: flex-end; gap: var(--s-3); flex-wrap: wrap; margin-top: var(--s-7); }
@media (max-width: 639px) { .modal .actions { flex-direction: column; } .modal .actions .btn { width: 100%; } }

/* tables as the log */
.log { width: 100%; border-collapse: collapse; table-layout: fixed; }
.log th { background: var(--c-well); font: 600 13px/16px var(--f-display); letter-spacing: 0.08em; text-transform: uppercase; color: var(--c-text-muted); text-align: left; padding: 12px; }
.log td { border-bottom: 1px solid var(--c-border); padding: 12px; vertical-align: top; font-size: 14px; line-height: 20px; min-width: 0; overflow-wrap: anywhere; }
/* a link that is the whole content of a cell is a 44 px target (§2.4; design review m5) */
.log td > a { display: inline-flex; align-items: center; min-height: 44px; }
/* the action column: right-aligned, its 44 px button starting at the row's top so the label sits on the first text line (design
   review cycle 4 m4) */
.log td.action { text-align: right; padding-top: 0; padding-bottom: 0; }
.log td.action .btn.ghost { justify-content: flex-end; }
.log td .cell-label { display: none; font: 600 13px/16px var(--f-display); letter-spacing: 0.08em; text-transform: uppercase; color: var(--c-text-muted); }
.code-box.meta-box { word-break: normal; overflow-wrap: anywhere; }
@media (max-width: 899px) {
  .log thead { display: none; }
  .log, .log tbody, .log tr, .log td { display: block; width: 100%; }
  .log tr { border: 1px solid var(--c-border); border-radius: var(--r-2); padding: var(--s-3) var(--s-4); margin-bottom: var(--s-4); background: var(--c-surface); }
  .log td { border: 0; padding: var(--s-2) 0; }
  .log td .cell-label { display: inline; }
  .log tr.has-code { margin-bottom: 0; border-bottom: 0; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
  .log tr[data-row-code] { border-top: 1px dashed var(--c-border); border-top-left-radius: 0; border-top-right-radius: 0; }
  [data-upload-table] tr { display: grid; grid-template-columns: 120px minmax(0, 1fr); column-gap: var(--s-4); }
  [data-upload-table] td:first-child { grid-row: 1 / span 5; padding-top: var(--s-2); }
  [data-upload-table] td:first-child .thumb { width: 120px; height: 68px; }
  [data-upload-table] td:empty { display: none; }
}

/* videos */
.thumb { width: 96px; height: 54px; border-radius: var(--r-1); background: var(--c-well); object-fit: cover; display: flex; align-items: center; justify-content: center; color: var(--c-text-muted); }
.upload-label { position: relative; }
.upload-label input[type=file] { position: absolute; inset: 0; opacity: 0; width: 100%; cursor: pointer; }
.upload-label input[type=file]:disabled { cursor: not-allowed; }
.video-layout { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--s-7); align-items: start; }
@media (max-width: 1023px) { .video-layout { grid-template-columns: minmax(0, 1fr); } }
.frame { position: relative; padding-top: 56.25%; background: var(--p-bg); border-radius: var(--r-2); overflow: hidden; }
.frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* the signal path (design-spec §4) */
.signal-panel > .panel-body { padding: var(--s-6); }
@media (max-width: 639px) { .signal-panel > .panel-body { padding: var(--s-5); } }
.signal-wrap { container-type: inline-size; }
.signal { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0; }
.signal > li.node, .signal .branch > li.node { position: relative; max-width: 560px; }
.node-card { background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--r-2); padding: var(--s-4); min-height: 88px; display: flex; flex-direction: column; gap: var(--s-3); min-width: 0; }
.node-head { display: flex; align-items: center; gap: var(--s-3); min-width: 0; }
.node-head .label { color: var(--c-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; min-width: 0; }
.node-head .tally .dot.ok .icon { width: 10px; height: 10px; stroke-width: 3; }
.badge { font: 500 13px/20px var(--f-mono); width: 20px; height: 20px; border-radius: var(--r-1); background: var(--c-well); text-align: center; flex: none; }
.node-readout { font-size: 14px; line-height: 20px; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.node-readout .mono { font-size: 13px; line-height: 20px; }
/* the limit's state word on its own line under the money readout, never broken after "Paused:" (design review cycle 3 m1) */
.node-word { display: block; }
.node[data-state="stop"] > .node-card { border-color: var(--c-stop); }
.node[data-state="warn"] > .node-card { border-color: var(--c-warn); }
.node-card .btn { white-space: normal; text-align: center; max-width: 100%; }
/* a ~186 px node holds its button on one line (design review cycle 3 m1): a filled or outlined node button spans the card, so its
   inline padding can be 8 px without the label crowding the edge ("Resume this month" measures 138 px in a 160 px button) */
.node-card .btn.size-s:not(.ghost) { display: flex; width: 100%; padding-left: var(--s-3); padding-right: var(--s-3); }
.node-card .row { flex-direction: column; align-items: stretch; gap: var(--s-3); }
.line { list-style: none; position: relative; height: 16px; margin-left: 28px; width: 2px; background: var(--c-signal); }
.line[data-line="dashed"], .line[data-line="off"] { background: repeating-linear-gradient(to bottom, var(--c-border-strong) 0 6px, transparent 6px 12px); }
.line[data-line="warn"] { background: var(--c-warn); }
.line[data-line="stop-dashed"] { background: repeating-linear-gradient(to bottom, var(--c-stop) 0 6px, transparent 6px 12px); }
.line[data-line="gap"] { background: none; height: 56px; }
.line[data-line="gap"]::before, .line[data-line="gap"]::after { content: ""; position: absolute; left: 0; width: 2px; height: 12px; background: var(--c-stop); }
.line[data-line="gap"]::before { top: 0; }
.line[data-line="gap"]::after { bottom: 0; }
/* the icon sits in a 2 px line: the global svg max-width rule would squeeze it to 2 px (design review D2) */
.line .gap-icon { position: absolute; top: 16px; left: -11px; z-index: 1; max-width: none; width: 22px; height: 22px; color: var(--c-stop); background: var(--c-surface); }
.line .gap-caption { position: absolute; top: 18px; left: 20px; white-space: nowrap; color: var(--c-stop); font-size: 14px; line-height: 20px; }
.line .seg { display: none; }
.branch { list-style: none; margin: 0; padding: 0 0 0 16px; }
.branch .branch-stub { display: block; width: 2px; height: 16px; margin-left: 12px; background: var(--c-border-strong); }
/* horizontal chain on desktop only (≥ 1024 px) and only when four 180 px nodes fit (design review D3) */
@media (min-width: 1024px) {
  @container (min-width: 840px) {
    .signal { display: grid; grid-template-columns: minmax(180px, 1fr) 40px minmax(180px, 1fr) 40px minmax(180px, 1fr) 40px minmax(180px, 1fr); grid-template-rows: auto auto; align-items: start; }
    .signal > li.node { display: grid; grid-row: 1 / span 2; grid-template-rows: subgrid; max-width: none; }
    /* each card keeps its own height: the paused SPEND LIMIT card is taller and must not stretch the others (design review M3) */
    .signal > li.node > .node-card { grid-row: 1; min-height: 132px; align-self: start; }
    /* stopped: the gap after SPEND LIMIT is wider, so its caption sits UNDER the gap and inside it (§4.2) */
    /* ...and the stopped SPEND LIMIT card, which holds two buttons, takes 20% more width (design review cycle 3 m1) */
    .signal:has(> li.line[data-line="gap"]) { grid-template-columns: minmax(180px, 1fr) 40px minmax(180px, 1fr) 40px minmax(200px, 1.2fr) 80px minmax(180px, 1fr); }
    .signal > li.node > .branch { grid-row: 2; }
    .signal .branch > li.node { max-width: none; }
    /* a long label wraps to a second line instead of being cut ("YOUR BUNNY LIB…" at 1024; §4.3 draws labels on two lines) */
    .signal .node-head .label { white-space: normal; overflow: visible; text-overflow: clip; }
    .signal > li.line { grid-row: 1; }
    .line { height: 2px; width: auto; margin: 19px 0 0; background: var(--c-signal); }
    .line[data-line="dashed"], .line[data-line="off"] { background: repeating-linear-gradient(to right, var(--c-border-strong) 0 6px, transparent 6px 12px); }
    .line[data-line="stop-dashed"] { background: repeating-linear-gradient(to right, var(--c-stop) 0 6px, transparent 6px 12px); }
    .line[data-line="gap"] { height: 2px; }
    .line[data-line="gap"]::before, .line[data-line="gap"]::after { width: calc(50% - 8px); height: 2px; top: 0; bottom: auto; }
    .line[data-line="gap"]::before { left: 0; }
    .line[data-line="gap"]::after { left: auto; right: 0; }
    .line .gap-icon { top: -10px; left: calc(50% - 11px); }
    /* 8 px clear of both cards (design review cycle 3 m2) */
    .line .gap-caption { top: 16px; left: 8px; width: calc(100% - 16px); white-space: normal; text-align: center; font-size: 13px; line-height: 16px; }
    .line[data-line="done"] .seg { display: block; position: absolute; top: -1px; width: 4px; height: 4px; background: var(--c-signal); left: 18px; animation: seg 1.2s steps(1) infinite; }
    .branch { padding: 0; }
    .branch .branch-stub { height: 32px; margin-left: 24px; visibility: hidden; }
    /* the connector runs from the parent card's bottom, however tall that card is, to the branch card (cards no longer stretch) */
    .signal > li.node { position: relative; overflow: hidden; }
    .signal > li.node > .node-card { position: relative; z-index: 1; }
    .signal > li.node > .branch { position: relative; }
    .signal > li.node > .branch::before { content: ""; position: absolute; left: 24px; top: -2000px; width: 2px; height: calc(2000px + 32px); background: var(--c-border-strong); }
  }
}
@keyframes seg { 0% { left: 0; } 50% { left: 24px; } }
/* the landing hero draws the same chain, all done, with example data (design-spec §6.1) */
.hero-signal .node-card { min-height: 72px; gap: var(--s-2); }
/* static (reduced motion) the square rests at the LOWER end: the signal flows down the chain (design review m6) */
.hero-signal .line[data-line="done"] .seg { display: block; position: absolute; left: -1px; width: 4px; height: 4px; background: var(--c-signal); top: calc(100% - 6px); animation: segv 1.2s steps(1) infinite; }
@keyframes segv { 0% { top: 0; } 50% { top: 10px; } }
@media (max-width: 639px) { .hero-signal .node-card { min-height: 56px; padding: var(--s-3) var(--s-4); } .hero-signal .line { height: 12px; } }
/* 1024–1279: the tablet shell (menu button + signal strip, no rail) keeps the horizontal chain; the labelled rail starts at
   1280 (design-lead ruling on build cycle 2, M2: an icon-only rail is rejected) */
@media (min-width: 1024px) and (max-width: 1279px) {
  .main-app { padding: var(--s-8) var(--s-9) var(--s-11); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0s !important; animation-iteration-count: 1 !important; transition-duration: 0s !important; }
  /* a working strip still shows work: its first 8 cells lit and still (design-spec §3.5; design review cycle 5 D1) */
  .strip.indeterminate i { animation: none !important; }
  /* still, never all cells lit (review cycle 6 m1): 4 cells → 1 and 3; 8 cells → 1, 3, 5, 7; 32 cells → the first 8, as before */
  .strip.indeterminate[data-cells="4"] i:nth-child(odd),
  .strip.indeterminate[data-cells="8"] i:nth-child(odd),
  .strip.indeterminate[data-cells="32"] i:nth-child(-n+8) { background: var(--c-led-signal); }
}
