/* NotePerfect - hand-written CSS, no framework, built on the TOKENS below (appi/docs/UI_GUIDE.md section 7): no raw colours, font sizes or ad-hoc spacing outside this block.
   An app overrides ONLY the accent (--p-* in the palette rules); the neutrals, type scale, radii, spacing and motion are shared.
   One layout for every form factor: a bottom tab bar under 860px, a side rail from 860px; modals are full-screen sheets under 640px. */
:root {
  /* the accent: a light and a dark value, chosen by the palette (data-palette); the default palette is 'ink' (NotePerfect's blue) */
  --p-brand: #1d4ed8; --p-brand-fg: #ffffff; --p-soft: #dbe7ff; --p-brand-d: #6ea0ff; --p-brand-fg-d: #07142e; --p-soft-d: #172a4f;
  /* neutrals, light */
  --brand: var(--p-brand); --brand-fg: var(--p-brand-fg); --brand-soft: var(--p-soft);
  --bg: #f5f7f7; --panel: #ffffff; --fg: #14191b; --muted: #596366; --line: #dce2e4;
  --good: #1a7f45; --bad: #c0392b; --warn: #8a5500; --warn-bg: #fff1cc;
  --shadow: 0 1px 2px rgb(20 25 27 / .06), 0 4px 14px rgb(20 25 27 / .05); --shadow-pop: 0 12px 40px rgb(0 0 0 / .3);
  --scrim: rgb(0 0 0 / .45); --media-bg: #000000; --media-fg: #ffffff;
  /* type: three sizes */
  --font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --text-sm: .85rem; --text-md: 1rem; --text-lg: 1.4rem;
  /* spacing (4px scale), radii (12 / 16, and 6 for tiny parts), tap target */
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 24px; --space-6: 32px;
  --radius: 12px; --radius-lg: 16px; --radius-xs: 6px; --radius-pill: 999px; --gap: var(--space-4); --tap: 44px;
  /* motion: three durations and three easings (animate transform and opacity only) */
  --dur-1: 120ms; --dur-2: 200ms; --dur-3: 320ms; --ease: cubic-bezier(.2, .7, .2, 1); --ease-spring: cubic-bezier(.34, 1.4, .64, 1); --ease-exit: cubic-bezier(.4, 0, 1, 1);
  --dur-loop: 1400ms; --dur-breathe: 2400ms; --boot-slow-after: 10s;          /* the startup screen's loops, and when it explains a slow start */
  /* RHYTHM (UI guide, "Rhythm and type"; the sign-in card is the baseline): bands in a surface 16, titled sections 24, items in a group 8, a title and its subtitle 4; cards pad 24, inset blocks 16 */
  --stack: var(--space-4); --stack-section: var(--space-5); --stack-tight: var(--space-2); --stack-snug: var(--space-1); --pad-card: var(--space-5); --pad-inset: var(--space-4);
  --control: 52px; --avatar: 32px; --measure: 860px;
  --shade-1: rgb(0 0 0 / .38); --shade-2: rgb(0 0 0 / .55); --shade-3: rgb(0 0 0 / .62); --shade-4: rgb(0 0 0 / .75); --veil: rgb(255 255 255 / .45);
  --nav-h: 64px; --top-h: 52px;
  --scroll-thumb: color-mix(in srgb, var(--muted) 45%, transparent); --scroll-thumb-hover: color-mix(in srgb, var(--muted) 75%, transparent);
  --z-nav: 5; --z-top: 6; --z-call: 30; --z-modal: 40; --z-confirm: 50; --z-toast: 60;
  color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-mode=light]) {
    --brand: var(--p-brand-d); --brand-fg: var(--p-brand-fg-d); --brand-soft: var(--p-soft-d);
    --bg: #0f1213; --panel: #171b1d; --fg: #e9eef0; --muted: #94a0a4; --line: #272e31;
    --good: #5ee59a; --bad: #ff8a7a; --warn: #f0c24f; --warn-bg: #3a3112; --shadow: none;
  }
}
/* LIBRARY COLOURS (2026-11-04, user: "Library colours and icons"): a small named palette; the badge's text and icon sit on it (4.5:1 or better in both modes) */
:root { --lib-blue: #1d5fbf; --lib-green: #1e7a3e; --lib-orange: #b04a00; --lib-purple: #6a3fb5; --lib-red: #b3261e; --lib-grey: #59636a; --lib-fg: #ffffff; }
@media (prefers-color-scheme: dark) { :root:not([data-mode=light]) { --lib-blue: #7fb2ff; --lib-green: #6fd68f; --lib-orange: #ffa45c; --lib-purple: #c3a6ff; --lib-red: #ff8f86; --lib-grey: #b3bcc2; --lib-fg: #0f1213; } }
:root[data-mode=dark] { --lib-blue: #7fb2ff; --lib-green: #6fd68f; --lib-orange: #ffa45c; --lib-purple: #c3a6ff; --lib-red: #ff8f86; --lib-grey: #b3bcc2; --lib-fg: #0f1213; }
:root[data-mode=light] { color-scheme: light; }
:root[data-mode=dark] {
  color-scheme: dark;
  --brand: var(--p-brand-d); --brand-fg: var(--p-brand-fg-d); --brand-soft: var(--p-soft-d);
  --bg: #0f1213; --panel: #171b1d; --fg: #e9eef0; --muted: #94a0a4; --line: #272e31;
  --good: #5ee59a; --bad: #ff8a7a; --warn: #f0c24f; --warn-bg: #3a3112; --shadow: none;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--bg); color: var(--fg); font: var(--text-md)/1.5 var(--font); }
h1, h2 { line-height: 1.15; margin: 0; letter-spacing: -.01em; }
h1 { font-size: var(--text-lg); font-weight: 700; } h2 { font-size: var(--text-md); font-weight: 700; }      /* TITLE = lg 700 (the app and the page); a section heading = md 700 */
p { margin: 0; } small, .muted { color: var(--muted); }
/* META = sm, muted: the line under a title, hints, helper text, captions, footers (one role, one size, wherever it appears) */
.lead, .hint, p.muted, small, .field-hint, .gate-foot, .empty p, .row-sub { font-size: var(--text-sm); }
.lead { color: var(--muted); margin-top: var(--stack-snug); }
button, input, select, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; scroll-behavior: auto !important; } }

/* ---- controls ---- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); min-height: var(--tap); padding: 0 var(--space-4); border-radius: var(--radius); border: 1px solid var(--line); background: var(--panel); cursor: pointer; }
.btn.primary { background: var(--brand); border-color: var(--brand); color: var(--brand-fg); font-weight: 600; }
.btn.ghost { background: transparent; border-color: transparent; }
.btn.danger { color: var(--bad); } .btn.wide { width: 100%; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.icon-btn { padding: 0 var(--space-3); } .icon { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.link { background: none; border: 0; color: var(--brand); cursor: pointer; padding: var(--space-2) 0; min-height: var(--tap); }
input, select, textarea { font-size: var(--text-md); width: 100%; min-height: var(--tap); padding: var(--space-2) var(--space-3); border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); }
select { appearance: none; -webkit-appearance: none; padding-right: calc(var(--space-4) + var(--space-3) * 2); background-repeat: no-repeat; background-position: right var(--space-3) center; background-size: var(--space-4); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a96a3' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); }      /* one chevron with room on its right, for every select (the browser's own sits against the edge) */
textarea { resize: vertical; }
.field { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--text-sm); color: var(--muted); min-width: 0; } .field.inline { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--space-3); } .field.inline input { max-width: 160px; }
.row { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; margin-top: var(--space-3); }
.chip { display: inline-block; padding: var(--space-1) var(--space-3); border-radius: var(--radius-pill); background: var(--brand-soft); color: var(--brand); font-size: var(--text-sm); }

/* ---- shell: bottom bar on phones, side rail on wide screens ---- */
.app { min-height: 100dvh; display: flex; flex-direction: column; }
.nav { position: fixed; inset: auto 0 0 0; z-index: 5; display: flex; background: var(--panel); border-top: 1px solid var(--line); padding-bottom: env(safe-area-inset-bottom); }
.nav .brand, .nav .nav-foot { display: none; }
.tab { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-1); min-height: var(--nav-h); background: none; border: 0; color: var(--muted); font-size: var(--text-sm); cursor: pointer; }
.tab.current { color: var(--brand); font-weight: 600; }
.tab.unavailable, .btn.unavailable { opacity: .45; cursor: default; }          /* a destination this session cannot use (a visitor): shown, never removed */
.content { flex: 1; width: 100%; max-width: 1080px; margin: 0 auto; padding: var(--gap) var(--gap) calc(var(--nav-h) + var(--gap) + env(safe-area-inset-bottom)); }
.update { position: sticky; top: 0; z-index: 6; display: flex; gap: var(--space-3); align-items: center; justify-content: center; padding: var(--space-2); background: var(--brand); color: var(--brand-fg); flex-wrap: wrap; }
.update .btn { min-height: 34px; background: var(--brand-fg); color: var(--brand); }
@media (min-width: 860px) {
  .app { flex-direction: row; flex-wrap: wrap; }
  .update { flex: 1 0 100%; position: static; }
  .nav { position: sticky; top: 0; inset: auto; height: 100dvh; flex: none; flex-direction: column; gap: var(--space-1); padding: var(--space-3); border-top: 0; border-right: 1px solid var(--line); }
  .nav .brand { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-4); white-space: nowrap; } .nav .nav-foot { display: flex; align-items: center; gap: var(--space-2); margin-top: auto; padding: var(--space-2); }
  .tab { flex: none; flex-direction: row; justify-content: flex-start; gap: var(--space-3); min-height: var(--tap); padding: 0 var(--space-3); border-radius: var(--radius); font-size: var(--text-sm); }
  .tab.current { background: var(--brand-soft); }
  .content { flex: 1; min-width: 0; padding: var(--space-5) var(--space-6) var(--space-6); }
}
.dot { width: 9px; height: 9px; border-radius: 50%; background: var(--muted); } .dot.on { background: var(--good); } .dot.off { background: var(--bad); }
.logo { display: grid; place-items: center; width: 56px; height: 56px; border-radius: var(--radius-lg); background: var(--brand); color: var(--brand-fg); font-weight: 800; font-size: var(--text-lg); } .logo.small { width: 34px; height: 34px; border-radius: var(--radius); font-size: var(--text-sm); }

/* ---- onboarding ---- */
.gate { min-height: 100dvh; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-4); padding: var(--gap); }
.gate-card { width: min(420px, 100%); background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: var(--pad-card); display: flex; flex-direction: column; gap: var(--stack); box-shadow: var(--shadow); }
.gate-card .lead { margin: 0; } .hint { font-size: var(--text-sm); color: var(--muted); }
.banner { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); } .banner .btn.icon-only { border-color: transparent; background: transparent; } .banner, .banner-inline { padding: var(--space-3) var(--space-4); border-radius: var(--radius); background: var(--brand-soft); margin-bottom: var(--gap); } .banner.bad, .banner-inline.bad { background: var(--warn-bg); color: var(--bad); }

/* ---- views ---- */
.view { display: flex; flex-direction: column; gap: var(--stack-section); }
.view-head.row-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-3); flex-wrap: wrap; }
.view-head.row-head > .lead { flex: 1 1 12rem; min-width: 0; margin: 0; }          /* the lead line shares the row with the add buttons (the page name is in the top bar) */
.view-head.row-head > .row { margin-top: 0; flex-wrap: nowrap; }          /* the header's buttons (Add from a file, New) sit level with the lead line */
.section-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--space-2); }
section { display: flex; flex-direction: column; gap: var(--stack-tight); }
.card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: var(--space-4); box-shadow: var(--shadow); display: flex; flex-direction: column; gap: var(--space-3); text-align: left; }
.empty { padding: var(--space-5); border: 1px dashed var(--line); border-radius: var(--radius); color: var(--muted); display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3); } .empty.tall { min-height: 40vh; justify-content: center; align-items: center; text-align: center; }
.quick { display: flex; gap: var(--space-2); }
.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); }
.stat { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: var(--space-3); display: flex; flex-direction: column; } .stat strong { font-size: var(--text-lg); line-height: 1.1; } .stat span { color: var(--muted); font-size: var(--text-sm); } .stat.good strong { color: var(--good); } .stat.bad strong { color: var(--bad); }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr)); gap: var(--space-3); }
.card.metric { cursor: pointer; font: inherit; color: inherit; }
.card.metric:hover { border-color: var(--brand); }
.metric-head { display: flex; justify-content: space-between; gap: var(--space-2); } .metric-value { font-size: var(--text-lg); font-weight: 700; line-height: 1; } .metric-value small { font-size: var(--text-sm); font-weight: 400; }
.bar { height: 8px; border-radius: var(--radius-pill); background: var(--line); overflow: hidden; } .bar.big { height: 12px; } .bar span { display: block; height: 100%; background: var(--brand); border-radius: inherit; }
.list { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel); overflow: hidden; }
.row-item { display: flex; flex-direction: row; gap: var(--space-3); align-items: center; text-align: left; padding: var(--space-3) var(--space-4); background: none; border: 0; border-bottom: 1px solid var(--line); cursor: pointer; width: 100%; min-height: var(--tap); }
.row-item:last-child { border-bottom: 0; } .row-item.active { background: var(--brand-soft); } .row-item .muted { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-item.flat { flex-direction: row; align-items: center; justify-content: space-between; cursor: default; } .row-item.flat .row-main { flex: 1; } .row-item.flat .row-main .muted { flex: none; text-align: left; padding: 0; } .row-item.flat .muted { flex: 1; text-align: right; padding: 0 var(--space-2); }
.row-meta { display: flex; gap: var(--space-2); align-items: center; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-3); } .form-row { display: grid; grid-template-columns: 1fr 1fr auto; gap: var(--space-3); align-items: end; }
@media (max-width: 520px) { .form-row { grid-template-columns: 1fr 1fr; } .form-row .btn { grid-column: 1 / -1; } }
.facts { margin: 0; padding-left: var(--space-4); color: var(--muted); display: flex; flex-direction: column; gap: var(--space-1); }

/* ---- TABS (ui.js tabs/tabPanel): the sections of one page. The look follows the UI style: soft = a segmented control, crisp = an underline, bold = filled tabs ---- */
.tabs { display: flex; gap: var(--space-1); width: fit-content; max-width: 100%; overflow-x: auto; padding: var(--space-1); border: 1px solid var(--line); border-radius: var(--radius-pill); background: var(--panel); scrollbar-width: none; }
.tabs-tab { flex: none; min-height: var(--tap); padding: 0 var(--space-4); border: 0; border-radius: var(--radius-pill); background: transparent; color: var(--muted); font-weight: 600; white-space: nowrap; cursor: pointer; transition: background-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease); }
.tabs-tab:hover { color: var(--fg); }
.tabs-tab.on { background: var(--brand-soft); color: var(--brand); }
.tabs-panel { display: flex; flex-direction: column; gap: var(--stack); }
/* the Notes page: its tabs (Notes | Videos) give way to an open note on phones */
@media (max-width: 859px) { .view:has(> .tabs-panel > .split.has-selection) > .tabs { display: none; } }

/* ---- notes: drill-down on phones, two panes from 860px ---- */
.split { display: grid; grid-template-columns: 1fr; gap: var(--gap); }
.split .detail-pane { display: none; } .split.has-selection .list-pane { display: none; } .split.has-selection .detail-pane { display: flex; }
.pane { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.pane-head { display: flex; gap: var(--space-2); align-items: center; } .pane-head .status { margin-left: auto; font-size: var(--text-sm); }
.title-input { font-size: var(--text-lg); font-weight: 700; border-color: transparent; background: transparent; padding-left: 0; } .tag-input { max-width: 320px; }
.body-input { min-height: 46dvh; line-height: 1.6; field-sizing: content; }
@media (min-width: 860px) {
  .split { grid-template-columns: 340px 1fr; align-items: start; }
  .split .detail-pane, .split.has-selection .list-pane, .split.has-selection .detail-pane { display: flex; }
  .split .detail-pane { position: sticky; top: 28px; } .back { display: none; } .body-input { min-height: 56dvh; }
}

/* ---- charts (SVG; colours come from the tokens so they follow the theme) ---- */
.chart-card { padding: var(--space-2) var(--space-2) var(--space-1); } .chart { width: 100%; max-width: 560px; height: auto; display: block; margin-inline: auto; } .chart-empty { padding: var(--space-6) var(--space-3); text-align: center; color: var(--muted); }
.chart-grid { stroke: var(--line); stroke-width: 1; } .chart-label { fill: var(--muted); font-size: 13px; /* ui-lint-ignore: SVG user units */ } .chart-line { fill: none; stroke: var(--brand); stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.chart-dot { fill: var(--panel); stroke: var(--brand); stroke-width: 2.5; } .chart-goal { stroke: var(--good); stroke-width: 1.5; stroke-dasharray: 6 5; } .chart-goal-label { fill: var(--good); font-size: 13px; /* ui-lint-ignore: SVG user units */ }
.spark { width: 100%; height: 36px; } .spark-line { fill: none; stroke: var(--brand); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; } .spark-dot { fill: var(--brand); } .spark-flat { stroke: var(--line); stroke-width: 2; stroke-dasharray: 3 4; }

/* ---- libraries ---- */
.lib-card { cursor: pointer; font: inherit; color: inherit; } .lib-card:hover { border-color: var(--brand); } .lib-card.general { background: var(--brand-soft); }
.lib-desc { min-height: 1.4em; } .chip.lib { background: transparent; border: 1px solid var(--line); color: var(--muted); }
.note-meta { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); } @media (max-width: 520px) { .note-meta { grid-template-columns: 1fr; } }
.gate-device { width: 100%; text-align: left; }

/* ---- video notes (video.b9f2aa246a.js) ---- */
.chip.vid { background: var(--brand-soft); color: var(--brand); }
.vc { display: flex; flex-direction: column; gap: var(--space-3); flex: 1; }
.vc-page { flex: 1; display: flex; flex-direction: column; }
.vc-page > * { margin-block: auto; }      /* each page sits in the middle of the window, both ways (margins, not justify-content, so a tall page scrolls from its top) */
.vc-process { width: 100%; max-width: calc(var(--tap) * 14); margin-inline: auto; justify-items: stretch; }
.vc-process .vc-facts, .vc-process .row { justify-content: flex-start; text-align: left; }      /* the column is centred in the window; what is inside it is left-aligned */
.vc-stage { background: var(--media-bg); border-radius: var(--radius); overflow: hidden; }
.vc-video { display: block; width: 100%; max-height: 56vh; }
.vc-controls { display: grid; gap: var(--space-3); }
.vc-actions { flex-wrap: wrap; }
.vc-actions .spacer { flex: 1; }
.vc-clip .vc-clip-name::placeholder { color: inherit; opacity: 1; }      /* the default name reads like a name, not like an empty box */
.vc-readout { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
.vc-work { display: grid; gap: var(--space-3); }
.vc-empty { display: grid; place-items: center; min-height: calc(var(--tap) * 6); padding: var(--space-5) var(--space-4); text-align: center; }
.vc-empty-body { display: grid; gap: var(--space-3); justify-items: center; max-width: calc(var(--tap) * 12); }
.vc-empty-body p { margin: 0; font-size: var(--text-sm); }
.vc-drop { border: 2px dashed var(--line); border-radius: var(--radius-lg); background: transparent; transition: border-color .15s, background .15s; }
.vc-drop.over { border-color: var(--brand); background: var(--brand-soft); }
.vc-menu { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); padding: var(--space-3); border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel); }
.vc-menu .field select { width: 100%; min-height: var(--control); }
.vc-settings.on { background: var(--brand-soft); border-color: var(--brand); }
.sc.fixed .sc-sel:focus-visible { outline: 3px solid var(--fg); outline-offset: 2px; }
.vc-clips { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.vc-clip { display: flex; align-items: center; gap: var(--space-2); min-height: var(--tap); padding: 0 var(--space-1) 0 var(--space-3); border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); cursor: pointer; }
.vc-clip:hover { border-color: var(--brand); }
.vc-clip.playing { border-color: var(--brand); background: var(--brand-soft); }
.vc-clip .vc-clip-name { flex: 0 1 auto; width: auto; max-width: 55%; min-width: calc(var(--tap) * 1.5); min-height: var(--control); padding: 0 var(--space-2); border: 0; background: transparent; font-weight: 600; cursor: text; }      /* a small minimum, then as wide as the text: the rest of the row is the click-to-play area */
.vc-clip .vc-clip-name:focus { background: var(--panel); }
.vc-clip .vc-clip-del { border-color: transparent; background: transparent; }
.vc-range { min-height: var(--tap); padding: 0 var(--space-2); border: 0; background: transparent; color: var(--brand); font: inherit; font-size: var(--text-sm); font-variant-numeric: tabular-nums; cursor: pointer; }
.vc-range:hover { text-decoration: underline; }
.vc-clip .vc-clip-range { flex: 1; text-align: right; }
.vc-clip .vc-clip-name:focus, .vc-clip .vc-clip-name:focus-visible { outline: 0; box-shadow: none; background: transparent; }      /* no ring: it would overlap the row's own border */
.vc-clips-empty { margin: 0; }
.vc-cards { display: grid; gap: var(--space-3); }
.vc-card { display: grid; gap: var(--space-2); }      /* no box: the deck inside is exactly as wide as the player was */
.vc-card + .vc-card { padding-top: var(--space-4); border-top: 1px solid var(--line); }
.vc-deck-wrap { display: grid; gap: var(--space-2); }
.vc-deck { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; cursor: grab; border-radius: var(--radius); background: var(--media-bg); overscroll-behavior-x: contain; }      /* player-sized slides: swipe, or drag with the mouse */
.vc-deck.dragging { scroll-snap-type: none; cursor: grabbing; user-select: none; }
.vc-slide { position: relative; flex: 0 0 100%; scroll-snap-align: start; overflow: hidden; }
.vc-slide-pic { display: block; width: 100%; height: 100%; object-fit: contain; background: var(--media-bg); }
.vc-slide-pic.wait { background: color-mix(in srgb, var(--media-fg) 10%, transparent); }
.vc-slide-draw { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
/* a picture note's slide takes its picture's own shape (user, 2026-11-03): the frame holds the picture and its drawing exactly; a tall picture is capped at 70% of the window */
.vc-slide.fitted { display: flex; align-items: center; justify-content: center; }
.vc-slide-frame { position: relative; width: min(100%, calc(70vh * var(--r))); }
.vc-slide-frame .vc-slide-pic { object-fit: fill; }
/* the order of the pictures: thumbnails to drag (a finger holds first), a drop line where it lands */
.pic-strip { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.pic-thumb { position: relative; width: 56px; height: 56px; padding: 0; border: 2px solid transparent; border-radius: var(--radius); background: var(--media-bg); overflow: hidden; cursor: grab; touch-action: none; }
.pic-thumb img { width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.pic-thumb.on { border-color: var(--brand); }
.pic-thumb.lifted { box-shadow: var(--shadow-pop); opacity: .7; cursor: grabbing; }
.pic-thumb.drop-before { box-shadow: -4px 0 0 var(--brand); }
.pic-thumb.drop-after { box-shadow: 4px 0 0 var(--brand); }
.pic-grip { position: absolute; right: 2px; bottom: 2px; width: 16px; height: 16px; color: var(--media-fg); background: var(--shade-4); border-radius: var(--radius-pill); }
/* cropping: the picture with a box to move and resize; outside the box is dimmed */
.pic-crop { display: grid; gap: var(--space-3); }
.pic-crop-frame { position: relative; width: min(100%, calc(70vh * var(--r))); margin: 0 auto; overflow: hidden; background: var(--media-bg); user-select: none; }
.pic-crop-frame img { display: block; width: 100%; height: 100%; }
.pic-crop-box { position: absolute; box-shadow: 0 0 0 100vmax var(--shade-4); outline: 2px solid var(--media-fg); }
.pic-crop-body { position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; border: 0; background: transparent; cursor: move; touch-action: none; }
.pic-crop-handle { position: absolute; width: 24px; height: 24px; padding: 0; border: 2px solid var(--media-bg); border-radius: var(--radius-pill); background: var(--media-fg); touch-action: none; }
.pic-crop-handle.tl { left: 0; top: 0; cursor: nwse-resize; }
.pic-crop-handle.tr { right: 0; top: 0; cursor: nesw-resize; }
.pic-crop-handle.bl { left: 0; bottom: 0; cursor: nesw-resize; }
.pic-crop-handle.br { right: 0; bottom: 0; cursor: nwse-resize; }
.pic-crop-actions { align-items: center; }
.vc-slide-tag { position: absolute; left: var(--space-2); bottom: var(--space-2); padding: var(--space-1) var(--space-2); border-radius: var(--radius-pill); background: var(--shade-4); color: var(--media-fg); font-size: var(--text-sm); font-variant-numeric: tabular-nums; pointer-events: none; }
.vc-status { display: flex; align-items: center; gap: var(--space-3); }
.vc-status .meter { flex: 1; }
.vc-saved { display: grid; place-items: center; width: var(--tap); height: var(--tap); color: var(--brand); }
.vc-card.failed .vc-status { color: var(--bad); }
.vc-card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.vc-card-title { display: grid; gap: var(--space-1); min-width: 0; }
.vc-step { margin: 0; font-size: var(--text-sm); }
.vc-factsrow { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.vc-factsrow .vc-facts { flex: 1; min-width: 0; }
.vc-facts { margin: 0; overflow-wrap: anywhere; }
.vc-end { justify-content: flex-end; }
.vc-stepbar { align-items: center; min-height: var(--tap); }
.vc-drop-hint { color: var(--muted); font-size: var(--text-md); }
.vc-convert { display: grid; gap: var(--stack); }
.vc-convert p, .vc-converted { margin: 0; }
.vc-frames { display: flex; gap: var(--space-2); margin: 0; padding: 0 0 var(--space-2); list-style: none; overflow-x: auto; scroll-snap-type: x proximity; scrollbar-width: thin; }
.vc-frame { flex: none; scroll-snap-align: start; display: grid; gap: var(--space-1); justify-items: center; }
.vc-frame.over { opacity: .4; }
.vc-frame-pick { display: grid; gap: var(--space-1); justify-items: center; padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; }
.vc-frame-pic { display: block; height: 80px; width: auto; border-radius: var(--radius-xs); background: color-mix(in srgb, currentColor 10%, transparent); object-fit: cover; }
.vc-frame-pick:focus-visible .vc-frame-pic, .vc-frame-pick:hover .vc-frame-pic { outline: 2px solid var(--brand); }
.vc-frame-time { font-size: var(--text-sm); color: var(--muted); font-variant-numeric: tabular-nums; }
.vc-frames-note { margin: 0; }
.vc-controls input[type=range] { padding: 0; min-height: 28px; }
.vc-tray { border: 1px dashed var(--line); border-radius: var(--radius); padding: var(--space-3) var(--space-4); } .vc-tray ul { margin: var(--space-2) 0 0; padding-left: var(--space-4); }
.vn { display: flex; flex-direction: column; gap: var(--space-3); margin: var(--space-3) 0; }
.vn-stage { position: relative; background: var(--media-bg); border-radius: var(--radius); overflow: hidden; }
.vn-video { display: block; width: 100%; max-height: 52vh; }
.vn-canvas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.vn-frames { display: flex; gap: var(--space-2); overflow-x: auto; align-items: stretch; padding-bottom: var(--space-1); }
.vn-frame { flex: none; width: 92px; padding: var(--space-1); border: 2px solid var(--line); border-radius: var(--radius); background: var(--panel); cursor: pointer; display: flex; flex-direction: column; gap: var(--space-1); align-items: center; }
.vn-frame img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: var(--radius-xs); background: var(--media-bg); }
.vn-frame.on { border-color: var(--brand); } .vn-frame.has-drawing small::after { content: ' ✎'; color: var(--brand); }
.vn-tools, .vn-story { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.vn-palette { display: flex; gap: var(--space-2); } .vn-swatch { width: 28px; height: 28px; border-radius: 50%; border: 2px solid var(--line); cursor: pointer; padding: 0; } .vn-swatch.on { border-color: var(--fg); box-shadow: 0 0 0 2px var(--brand); }
.vn-widths { display: flex; gap: var(--space-1); } .vn-width { min-width: 36px; padding: 0 var(--space-2); }
.vn-rec { color: var(--bad); font-weight: 600; }

/* the kind-of-note chooser under the list header */
.kind-picker { display: grid; gap: var(--space-2); padding: var(--space-3) var(--space-3); border-bottom: 1px solid var(--line); }
.kind-picker .kind { display: grid; gap: var(--space-1); text-align: left; padding: var(--space-3) var(--space-4); border-radius: var(--radius); border: 1px solid var(--line); background: var(--panel); color: inherit; font: inherit; cursor: pointer; min-height: 44px; }
.kind-picker .kind:hover, .kind-picker .kind:focus-visible { border-color: var(--brand); }
.kind-picker .kind small { opacity: .7; }
.kind-picker .kind-cancel { justify-self: start; }

/* reading a note */
.note-view { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3); padding: var(--space-1) var(--space-1); } .note-view > *, .vn, .vn-frames { min-width: 0; }
.note-view-title { margin: 0; overflow-wrap: anywhere; }
.note-view-meta { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.note-view-body { white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.5; }
.pane-head .spacer { flex: 1; }

/* how full a note is: a bar and a percentage */
.meter { display: flex; align-items: center; gap: var(--space-2); min-width: 110px; }
.meter-track { flex: 1; height: 8px; border-radius: var(--radius-pill); background: color-mix(in srgb, currentColor 14%, transparent); overflow: hidden; min-width: 60px; }
.meter-fill { height: 100%; border-radius: var(--radius-pill); background: var(--brand); transition: width .2s; }
.meter.busy .meter-fill { background: var(--warn); }
.meter.warn .meter-fill { background: var(--bad); }
.meter-text { font-size: var(--text-sm); font-variant-numeric: tabular-nums; min-width: 3ch; text-align: right; }
.pane-head .note-dup { white-space: nowrap; }

/* note templates: readers */
.rich-view h3 { margin: .6em 0 .2em; font-size: var(--text-md); }
.rich-view p { margin: 0 0 .5em; white-space: pre-wrap; }
.rich-view ul, .item-view { margin: .2em 0 .6em; padding-left: 1.4em; }
.rich-view .b { font-weight: 700; }
.rich-view .i { font-style: italic; }
.rich-view .u { text-decoration: underline; }
.item-view li { margin: .2em 0; overflow-wrap: anywhere; }
.checklist-view { list-style: none; padding-left: 0; }
.checklist-view li { display: flex; gap: var(--space-2); align-items: baseline; }
.checklist-view li.done span { text-decoration: line-through; opacity: .65; }
.json-view { margin: 0; padding: var(--space-3) var(--space-3); border-radius: var(--radius); background: color-mix(in srgb, currentColor 7%, transparent); font: var(--text-sm)/1.45 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; }

/* note templates: editors */
.template-select { min-height: 40px; }
.rich-editor-wrap, .json-editor { display: grid; gap: var(--space-2); }
.rich-toolbar { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.rich-tool { min-height: var(--tap); min-width: var(--tap); }
.rich-editor { min-height: 12em; padding: var(--space-3) var(--space-3); border: 1px solid var(--line); border-radius: var(--radius); line-height: 1.5; overflow-wrap: anywhere; outline-offset: 2px; }
.rich-editor h3 { margin: .4em 0 .2em; font-size: var(--text-md); }
.rich-editor ul { margin: .2em 0; padding-left: 1.4em; }
.items-editor { display: grid; gap: var(--space-2); }
.items-editor .items { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.items-editor ol.items { counter-reset: item; }
.item-row { display: flex; align-items: center; gap: var(--space-2); }
.items-editor ol.items .item-row { counter-increment: item; }
.items-editor ol.items .item-row::before { content: counter(item) "."; min-width: 2ch; text-align: right; opacity: .7; }
.items-editor.bullets .item-row::before { content: "\2022"; opacity: .6; }
.item-row .li-input { flex: 1; min-width: 0; min-height: 40px; }
.item-row.done .li-input { text-decoration: line-through; opacity: .7; }
.item-row .li-check { width: 20px; height: 20px; }
.li-add { justify-self: start; }
.json-input { font: var(--text-sm)/1.45 var(--mono); min-height: 12em; }
.json-bar { display: flex; justify-content: space-between; align-items: center; gap: var(--space-2); }
.json-status.ok { color: var(--good); }
.json-status.bad { color: var(--bad); }
/* YOUR DATA AS A FILE (the template's dataviews.js, 2026-11-04): the import window says in red what a restore deletes */
.data-mode.bad { color: var(--bad); }

/* ONE button language: actions are icon-only (tooltip + accessible name), the same size and shape everywhere */
.btn.icon-only { width: var(--tap); min-width: var(--tap); padding: 0; gap: 0; flex: none; }
.btn.icon-only .icon { width: 22px; height: 22px; }
.btn.icon-only.primary { background: var(--brand); border-color: var(--brand); color: var(--brand-fg); }
.btn.icon-only.danger { color: var(--bad); }
.btn.icon-only.danger:hover:not(:disabled) { background: color-mix(in srgb, var(--bad) 10%, transparent); }
.btn.icon-only.primary.danger { background: var(--bad); border-color: var(--bad); color: var(--media-fg); }
.btn.icon-only:disabled { opacity: .45; cursor: default; }
.btn.icon-only.wide { width: 100%; }
.btn.icon-only:focus-visible, .kind:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.vc-pick { position: relative; cursor: pointer; }
.vc-pick .file { position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%; }
.wdot { display: block; border-radius: 50%; background: currentColor; }
.vn-width.primary .wdot { background: var(--brand-fg); }
.gate-others { display: grid; gap: var(--space-2); }
/* a collapsible section (ui.js disclosure): the chevron turns when it opens */
.disclosure-head { display: flex; align-items: center; gap: var(--space-2); width: 100%; min-height: var(--tap); background: none; border: 0; padding: var(--space-1) var(--space-1); color: var(--muted); font: inherit; text-align: left; cursor: pointer; border-radius: var(--radius); }
.disclosure-head:hover { color: var(--fg); }
.disclosure-head .icon { transition: transform var(--dur-1) var(--ease); }
.disclosure.open > .disclosure-head .icon { transform: rotate(90deg); }
.disclosure-body { display: grid; gap: var(--space-2); }
/* an info tip (ui.js infoTip): the field and its info icon on one row, what it does in a soft panel under it while open */
.info-tip-row { display: flex; align-items: center; gap: var(--space-2); }
.info-tip-row > .field { flex: 1; }
.info-tip-btn { color: var(--muted); }
.info-tip-btn.on { color: var(--brand); }
.info-tip-body { display: grid; gap: var(--space-2); margin-top: var(--space-1); padding: var(--pad-inset); border-radius: var(--radius); background: var(--brand-soft); color: var(--fg); font-size: var(--text-sm); }
.info-tip-body p { margin: 0; }
/* a row that is one button (optionRow): the text and its icon, hover and press feedback over the whole row */
.option-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); width: 100%; min-height: calc(var(--tap) + 2 * var(--space-1)); padding: var(--space-1) var(--space-1) var(--space-1) var(--space-3); border: 0; border-radius: var(--radius); background: transparent; color: var(--muted); font: inherit; text-align: left; cursor: pointer; transition: background-color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease); }
.option-row:hover { background: color-mix(in srgb, var(--brand-soft) 55%, transparent); color: var(--fg); }
.option-row:active { background: var(--brand-soft); color: var(--fg); transform: scale(.98); }
.option-row-icon { display: inline-flex; align-items: center; justify-content: center; flex: none; width: var(--tap); height: var(--tap); border-radius: var(--radius-xs); color: var(--fg); }
.option-row:hover .option-row-icon, .option-row:active .option-row-icon { color: var(--brand); }
.option-row-icon .icon { width: 22px; height: 22px; }
.option-row.danger .option-row-icon { color: var(--bad); }
.kind-picker { display: flex; gap: var(--space-3); align-items: center; }
.kind-picker .kind { width: 64px; height: 64px; min-height: 64px; padding: 0; display: grid; place-items: center; }
.kind-picker .kind .icon { width: 30px; height: 30px; }
.kind-picker .kind-cancel { margin-left: auto; }
.section-head .btn.icon-only { min-height: 36px; width: 36px; min-width: 36px; }

/* the "are you sure" dialog */
.confirm-backdrop { position: fixed; inset: 0; z-index: var(--z-confirm); display: grid; place-items: center; padding: var(--space-4); background: var(--scrim); animation: fade var(--dur-2) var(--ease); }
.confirm { width: min(360px, 100%); display: grid; gap: var(--space-3); padding: var(--space-5); border-radius: var(--radius-lg); background: var(--panel); color: inherit; border: 1px solid var(--line); box-shadow: var(--shadow-pop); animation: pop var(--dur-3) var(--ease-spring); }
.confirm-message { margin: 0; font-weight: 600; }
.confirm-detail { margin: 0; }
.confirm-actions { display: flex; justify-content: flex-end; gap: var(--space-3); } .confirm-actions .btn { min-width: 96px; } .btn.primary.danger { background: var(--bad); border-color: var(--bad); color: var(--bg); }

/* profiles: the account bar in the rail and the settings card */
.nav-account { padding: var(--space-2) 0 0; border-top: 1px solid var(--line); }      /* no bottom padding: the profile row's own padding matches the title row's, so the gap below it equals the gap above the title */
.profile-card { display: grid; gap: var(--space-3); }
.gate-card .profiles { margin: var(--space-1) 0; }
@media (max-width: 859px) { .nav-account { display: none; } }
@media (min-width: 860px) { .nav .nav-account { margin-top: auto; } .nav .nav-account + .nav-foot { margin-top: 0; } .nav-account .account-bar { flex-wrap: wrap; } }

/* the scrubber: the whole video as a LINE (a timeline), the selection as a lit stretch of it with a handle at each end, the clips already cut as shadows on it */
.sc { display: grid; gap: var(--space-1); user-select: none; -webkit-user-select: none; }
.sc-track { position: relative; height: var(--tap); margin: 0 var(--space-6); touch-action: none; cursor: pointer; }      /* the margins are where the handles hang at the ends of the video */
.sc.readonly .sc-track { cursor: default; }
.sc-line { position: absolute; left: 0; right: 0; top: var(--space-4); bottom: var(--space-4); border-radius: var(--radius-pill); background: color-mix(in srgb, currentColor 18%, transparent); pointer-events: none; }
.sc-shadow { position: absolute; top: 0; bottom: 0; min-width: var(--space-2); padding: 0; border: 0; background: none; pointer-events: none; }
.sc-shadow::before { content: ""; position: absolute; inset: var(--space-4) 0; border-radius: var(--radius-pill); background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--fg) 60%, transparent) 0 5px, color-mix(in srgb, var(--fg) 30%, transparent) 5px 10px); border: 2px solid color-mix(in srgb, var(--fg) 75%, transparent); box-sizing: border-box; }
.sc-shadow.tap { pointer-events: auto; cursor: pointer; }
.sc-shadow.tap:hover::before, .sc-shadow.tap:focus-visible::before { background: repeating-linear-gradient(135deg, var(--fg) 0 5px, color-mix(in srgb, var(--fg) 55%, transparent) 5px 10px); }
.sc-shadow.tap:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.sc-sel { position: absolute; top: 0; bottom: 0; min-width: var(--space-4); box-sizing: border-box; cursor: grab; touch-action: none; }
.sc-sel::before { content: ""; position: absolute; inset: var(--space-4) 0; border-radius: var(--radius-pill); background: var(--brand); }
.sc-sel:active { cursor: grabbing; }
.sc-handle { position: absolute; top: 0; bottom: 0; width: var(--space-6); display: grid; place-items: center; cursor: ew-resize; touch-action: none; }
.sc-handle::after { content: ""; width: var(--space-3); height: var(--space-6); border-radius: var(--radius-xs); background: var(--brand); border: 2px solid var(--brand-fg); box-sizing: border-box; box-shadow: 0 0 0 1px var(--brand); }
.sc-handle.start { right: 100%; place-items: center end; }
.sc-handle.end { left: 100%; place-items: center start; }
.sc-handle:focus-visible::after { outline: 3px solid var(--fg); outline-offset: 1px; }
.sc-play { position: absolute; top: var(--space-2); bottom: var(--space-2); width: 2px; margin-left: -1px; /* ui-lint-ignore: centres a 2px line on its position */ background: var(--fg); box-shadow: 0 0 0 1px var(--bg); pointer-events: none; }
.sc.fixed .sc-track, .sc.flush .sc-track, .sc.flush .sc-scale { margin: 0; }      /* no handles hang outside: the bar is exactly as wide as the player above it */
.sc-scale { margin: 0 var(--space-6); display: flex; justify-content: space-between; font-size: var(--text-sm); opacity: .7; font-variant-numeric: tabular-nums; }

.sc-dim { position: absolute; top: var(--space-4); bottom: var(--space-4); background: var(--bg); opacity: .6; pointer-events: none; }
.sc-mark { position: absolute; top: var(--space-3); bottom: var(--space-3); width: 2px; margin-left: -1px; /* ui-lint-ignore: centres a 2px line on its position */ background: var(--brand); opacity: .8; pointer-events: none; }

/* keeping a video: none / the original / a smaller copy, and the quality choices behind Advanced */
.vc-keep { display: grid; gap: var(--space-2); margin: var(--space-3) 0; padding: var(--space-3); border: 1px solid var(--line); border-radius: var(--radius); }
.vc-keep legend { padding: 0 var(--space-2); font-weight: 600; }
.vc-keep-opt { display: flex; gap: var(--space-3); align-items: flex-start; }
.vc-keep-opt.disabled { opacity: .6; }
.vc-keep-opt input { margin-top: var(--space-1); }
.vc-keep-note { display: block; }
.vc-advanced { margin: var(--space-1) 0 0 var(--space-5); }
.vc-advanced summary { cursor: pointer; font-weight: 600; min-height: 32px; }
.vc-adv-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-3); margin: var(--space-2) 0; }
.vc-adv-grid .field select, .vc-adv-grid .field input { min-height: 40px; width: 100%; }
.vc-adv-record, .vc-adv-limit { margin: var(--space-2) 0; }
.vc-from-copy { margin: var(--space-1) 0; }

/* the background job: a thin bar under the top of the app while a smaller copy is being made */
.proxy-job { position: sticky; top: 0; z-index: 6; display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); background: var(--panel); border-bottom: 1px solid var(--line); }
.proxy-job .meter { flex: 1; }
.vc-offstage { position: fixed; right: 0; bottom: 0; width: 2px; height: 2px; overflow: hidden; opacity: .01; pointer-events: none; }          /* the video a closed cutter still records clips from: on the page (so it is painted), not seen */
.vc-offstage video { width: 2px; height: 2px; }
.proxy-job .proxy-text { flex: 2; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.proxy-job.error { border-bottom-color: var(--bad); }
.vs-copy { display: grid; gap: var(--space-1); }
.vs-resume-row { display: flex; align-items: center; gap: var(--space-3); margin-top: var(--space-2); }
.btn.disabled { opacity: .45; pointer-events: none; }

/* ---- the palettes: ACCENT ONLY (a light and a dark value each). 'ink' is the default above; theme.js sets data-palette and data-mode (none = follow the device). ---- */
:root[data-palette=leaf] { --p-brand: #0a7650; --p-brand-fg: #ffffff; --p-soft: #dcf3ea; --p-brand-d: #2dd4a0; --p-brand-fg-d: #06251a; --p-soft-d: #123329; }
:root[data-palette=ember] { --p-brand: #b03a08; --p-brand-fg: #ffffff; --p-soft: #ffe8d9; --p-brand-d: #ff9150; --p-brand-fg-d: #2a1000; --p-soft-d: #3d2112; }
:root[data-palette=plum] { --p-brand: #6d28d9; --p-brand-fg: #ffffff; --p-soft: #ece3fb; --p-brand-d: #b794f6; --p-brand-fg-d: #1a0b36; --p-soft-d: #2a1d48; }
:root[data-palette=graphite] { --p-brand: #27272a; --p-brand-fg: #ffffff; --p-soft: #e7e7ea; --p-brand-d: #e4e4e7; --p-brand-fg-d: #18181b; --p-soft-d: #2a2a2f; }

.theme-panel { margin-bottom: var(--gap); }
.palettes { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.palette { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap); padding: 0 var(--space-4) 0 var(--space-3); border-radius: var(--radius-pill); border: 1px solid var(--line); background: var(--panel); cursor: pointer; }
.palette.on { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand); } .palette .swatch { width: 22px; height: 22px; border-radius: 50%; border: 1px solid var(--muted); }

/* ---- the sign-in card: brand on one line, the password and its button side by side ---- */
.gate-card { position: relative; }
.gate-brand { display: flex; align-items: center; gap: var(--space-4); padding-right: calc(var(--tap) + var(--space-2)); }
.gate-brand .mode-toggle { position: absolute; top: 14px; right: 14px; }
.gate-row { display: flex; align-items: flex-end; gap: var(--space-3); } .gate-row .field { flex: 1; }

/* ---- TEAMS ------------------------------------------------------------------------------------------------------------------------------------------------------------ */
.teams-view .row-head .row { display: flex; gap: var(--space-2); }
.team-card .team-alert { color: var(--brand); font-weight: 600; }
.subtabs { display: flex; gap: var(--space-1); overflow-x: auto; border-bottom: 1px solid var(--line); margin-bottom: var(--space-4); }
.subtab { background: none; border: 0; border-bottom: 2px solid transparent; padding: var(--space-3) var(--space-3); color: var(--muted); cursor: pointer; font: inherit; white-space: nowrap; }
.subtab.current { color: var(--brand); border-bottom-color: var(--brand); font-weight: 600; }
.subtab .badge { margin-left: var(--space-2); background: var(--brand); color: var(--brand-fg); border-radius: var(--radius-pill); padding: 0 var(--space-2); font-size: var(--text-sm); }
.team-panel { display: flex; flex-direction: column; gap: var(--space-4); }
.team-panel .list .request, .team-panel .list .member-row, .team-panel .list .roster-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); }
.team-panel .list .request .row, .team-panel .list .member-row .row { margin-left: auto; display: flex; gap: var(--space-2); }
.chat { display: flex; flex-direction: column; gap: var(--space-2); max-height: 55dvh; overflow-y: auto; padding: var(--space-1); }
.msg { max-width: 82%; align-self: flex-start; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: var(--space-2) var(--space-3); }
.msg.mine { align-self: flex-end; background: var(--brand-soft); }
.msg-head { display: flex; align-items: center; gap: var(--space-2); }
.msg-head .msg-del { margin-left: auto; padding: var(--space-1); min-width: 0; min-height: 0; opacity: .6; }
.msg-text { margin: var(--space-1) 0 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.chat-form { margin-top: var(--space-2); }
/* ---- THREADS (threadviews.js): a timeline like a messenger, the first note on top, the composer at the bottom (sticky above the tab bar on phones) ---- */
.thread-timeline { display: flex; flex-direction: column; gap: var(--space-3); }
.thread-note { align-self: stretch; }
.thread-note.card { padding: var(--space-3); }
.thread-comment { max-width: 82%; }
.thread-answers { font-style: italic; }
.thread-entry-actions { display: flex; gap: var(--space-2); justify-content: flex-end; }
.thread-composer { position: sticky; bottom: 0; align-items: center; padding: var(--space-2) 0; background: var(--bg); }
.thread-closed { text-align: center; }
/* a thread announced in a team chat: one line that opens it (user, 2026-11-03) */
.msg-thread { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); border-radius: var(--radius-xs); background: var(--bg); border: 1px solid var(--line); }
.msg-thread > span { flex: 1; min-width: 0; overflow-wrap: anywhere; }
/* what was sent to the coaches as notes before threads: listed under the threads */
.thread-watch.on { color: var(--brand); }
.presented-note { padding: var(--space-3) var(--space-3); }
.presented-note .link { text-align: left; }
.print-sheet { text-align: center; }
.print-sheet .qr { width: min(320px, 80%); height: auto; margin: var(--space-3) auto; display: block; }
.print-sheet .offer-text { width: 100%; font-size: var(--text-sm); }
.join-card .field { margin-bottom: var(--space-2); }
@media print {
  body * { visibility: hidden; }
  .print-sheet, .print-sheet * { visibility: visible; }
  .print-sheet { position: fixed; inset: 0; background: Canvas; color: CanvasText; border: 0; padding: 24mm 18mm; /* ui-lint-ignore: print sheet in millimetres */ }
  .print-sheet .qr { width: 120mm; }
  .print-sheet .offer-text, .no-print { display: none; }
  .print-sheet h2 { font-size: 28pt; } /* ui-lint-ignore: print */
  .print-sheet .print-line { font-size: 16pt; } /* ui-lint-ignore: print */
}


/* ============================================================================================================================================================================
   THE UI LAYER (ui.ea3282d160.js): shell, modal, toast, states, fields, rows, motion. Everything uses the tokens; animate transform and opacity only.
   ============================================================================================================================================================================ */
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes pop { from { opacity: 0; transform: translateY(12px) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes sheet { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes flash { 0%, 40% { background-color: var(--brand-soft); } 100% { background-color: transparent; } }
@keyframes toast-in { from { opacity: 0; transform: translateY(16px) scale(.96); } to { opacity: 1; transform: none; } }
@keyframes row-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes shimmer { from { opacity: .45; } to { opacity: .9; } }
@keyframes page-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--dur-2); animation-timing-function: var(--ease); }
@media (prefers-reduced-motion: reduce) { ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; } }
.spin { animation: spin 1s linear infinite; }
.btn { transition: background-color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease); }
.btn:active:not(:disabled) { transform: scale(.95); }
.view { animation: page-in var(--dur-3) var(--ease) both; }

/* ---- the shell: a header (title, search, sync status, settings) above the page; the content leaves room for it and for the bottom bar ---- */
.content { --pad-x: var(--gap); --pad-y: var(--gap); padding: var(--pad-y) var(--pad-x) calc(var(--nav-h) + var(--gap) + env(safe-area-inset-bottom)); }
@media (min-width: 860px) { .content { --pad-x: var(--space-6); --pad-y: 28px; padding: var(--pad-y) var(--pad-x) var(--space-6); } }
.topbar { position: sticky; top: 0; z-index: var(--z-top); display: flex; align-items: center; gap: var(--space-1); min-height: var(--top-h); padding: var(--space-1) var(--pad-x); margin: calc(-1 * var(--pad-y)) calc(-1 * var(--pad-x)) var(--pad-y); background: color-mix(in srgb, var(--bg) 90%, transparent); backdrop-filter: blur(10px); border-bottom: 1px solid var(--line); }
.topbar .spacer, .pane-head .spacer, .modal-foot .spacer { flex: 1; }
.topbar-title { font-size: var(--text-md); }
.topbar-logo { margin-right: var(--space-2); }
@media (min-width: 860px) { .topbar-logo { display: none; } }
.topbar .btn.icon-only { border-color: transparent; background: transparent; }
.status-chip.synced { color: var(--good); } .status-chip.attention { color: var(--warn); } .status-chip.maintenance { color: var(--warn); } .status-chip.offline, .status-chip.local { color: var(--muted); }
.tab { transition: color var(--dur-1) var(--ease); }
.tab .icon { transition: transform var(--dur-2) var(--ease-spring); } .tab.current .icon { transform: translateY(-1px) scale(1.08); }

/* ---- the modal: three sizes, a full-screen sheet on phones, a sticky footer ---- */
html.modal-open { overflow: hidden; }
.modal-backdrop { position: fixed; inset: 0; z-index: var(--z-modal); display: grid; place-items: center; padding: var(--space-4); background: var(--scrim); animation: fade var(--dur-2) var(--ease); }
.modal { width: min(520px, 100%); max-height: min(92dvh, 100%); display: flex; flex-direction: column; border-radius: var(--radius-lg); background: var(--panel); color: inherit; border: 1px solid var(--line); box-shadow: var(--shadow-pop); overflow: hidden; animation: pop var(--dur-3) var(--ease-spring); }
.modal.wide { width: min(980px, 100%); }
.modal.screen { width: 100%; height: 100%; max-height: none; border-radius: 0; border: 0; }
.modal-backdrop:has(.modal.screen) { padding: 0; }
.modal-form { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.modal-head { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4); border-bottom: 1px solid var(--line); min-height: 56px; }
.modal-head h2 { flex: 1; margin: 0; font-size: var(--text-md); }
.modal-head .btn.icon-only { border-color: transparent; background: transparent; }
.modal-body { display: flex; flex-direction: column; gap: var(--stack); padding: var(--space-4); overflow-y: auto; flex: 1; min-height: 0; }
.modal.screen .modal-body > * { width: min(860px, 100%); margin-inline: auto; }
.modal.screen .modal-head, .modal.screen .modal-foot { padding-inline: max(var(--space-4), calc((100% - var(--measure)) / 2)); }
.modal.screen .rich-editor-wrap { display: flex; flex-direction: column; flex: 1; } .modal.screen .rich-toolbar { order: 2; position: sticky; bottom: 0; background: var(--panel); padding: var(--space-2) 0; border-top: 1px solid var(--line); }
.modal-foot { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4) calc(var(--space-3) + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); background: var(--panel); }
@media (max-width: 640px) {
  .modal-backdrop { padding: 0; place-items: stretch; }
  .modal, .modal.wide, .modal.screen { width: 100%; height: 100%; max-height: none; border-radius: 0; border: 0; animation: sheet var(--dur-3) var(--ease); }
}

/* ---- the toast and the row highlight ---- */
.toast-region { position: fixed; left: 0; right: 0; bottom: calc(var(--nav-h) + var(--space-4) + env(safe-area-inset-bottom)); z-index: var(--z-toast); display: flex; justify-content: center; padding: 0 var(--space-4); pointer-events: none; }
@media (min-width: 860px) { .toast-region { bottom: var(--space-5); } }
.toast { display: flex; align-items: center; gap: var(--space-2); max-width: 480px; padding: var(--space-3) var(--space-4); border-radius: var(--radius); background: var(--fg); color: var(--bg); box-shadow: var(--shadow-pop); animation: toast-in var(--dur-3) var(--ease-spring); }
.toast .icon { color: var(--good); }
.flash { animation: flash 1.8s var(--ease); }

/* ---- the three states ---- */
.empty { align-items: center; text-align: center; padding: var(--space-5); gap: var(--space-3); } .empty .icon { width: 32px; height: 32px; opacity: .7; }
.skeleton { display: flex; flex-direction: column; gap: var(--space-2); }
.skeleton-row { height: 56px; border-radius: var(--radius); background: var(--line); animation: shimmer .9s ease-in-out infinite alternate; }
.error-notice { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-radius: var(--radius); background: var(--warn-bg); color: var(--warn); } .error-notice p { flex: 1; }

/* ---- form fields: the label above, helper text below, errors in red under the field ---- */
.field-label { font-size: var(--text-sm); color: var(--muted); }
.field-hint { font-size: var(--text-sm); } .field-error { font-size: var(--text-sm); color: var(--bad); }
.field.has-error input, .field.has-error select, .field.has-error textarea { border-color: var(--bad); }
.field.toggle { flex-direction: row; align-items: center; gap: var(--space-3); min-height: var(--tap); color: var(--fg); font-size: var(--text-md); }
input[type=checkbox][role=switch] { appearance: none; width: 46px; min-width: 46px; height: 28px; min-height: 28px; padding: 0; border-radius: var(--radius-pill); border: 1px solid var(--line); background: var(--line); position: relative; cursor: pointer; transition: background-color var(--dur-2) var(--ease); }
input[type=checkbox][role=switch]::after { content: ""; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: var(--panel); box-shadow: var(--shadow); transition: transform var(--dur-2) var(--ease-spring); }
input[type=checkbox][role=switch]:checked { background: var(--brand); border-color: var(--brand); }
input[type=checkbox][role=switch]:checked::after { transform: translateX(18px); }
.chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.chip-choice { min-height: var(--tap); padding: 0 var(--space-4); border-radius: var(--radius-pill); border: 1px solid var(--line); background: var(--panel); cursor: pointer; transition: background-color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease); }
.chip-choice.on { background: var(--brand-soft); border-color: var(--brand); color: var(--brand); font-weight: 600; }

/* ---- the one list row: leading part, title + one subline + chips, trailing part ---- */
.list-row { animation: row-in var(--dur-2) var(--ease) both; transition: background-color var(--dur-1) var(--ease); }
.list-row:hover { background: color-mix(in srgb, var(--brand-soft) 55%, transparent); }
.row-lead { display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: var(--radius); background: var(--brand-soft); color: var(--brand); flex: none; overflow: hidden; }
.row-lead img { width: 100%; height: 100%; object-fit: cover; }
.row-main { display: flex; flex-direction: column; gap: var(--space-1); flex: 1; min-width: 0; }
.row-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-sub { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-trail { display: flex; align-items: center; color: var(--muted); flex: none; }
.row-trail .spark { width: 84px; height: 28px; }
/* THE WEEK on Home (user, 2026-11-03): a bar per day with its number, today marked, the streak beside it */
.week-card { display: grid; gap: var(--space-2); }
.week-head { display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap; }
.week-streak { display: inline-flex; align-items: center; gap: var(--space-1); color: var(--brand); font-weight: 600; }
.bars { width: 100%; max-width: 420px; height: auto; display: block; }
.bars-bar { fill: color-mix(in srgb, var(--brand) 55%, transparent); } .bars-bar.on { fill: var(--brand); } .bars-bar.none { fill: var(--line); }
.bars-value { fill: var(--fg); font-size: 11px; /* ui-lint-ignore: SVG user units */ } .bars-label { fill: var(--muted); font-size: 11px; /* ui-lint-ignore: SVG user units */ } .bars-label.on { fill: var(--fg); font-weight: 600; }
.list-row.flash { animation: flash 1.8s var(--ease); }

/* ---- search, settings, the gate's steps ---- */
.search-bar { display: flex; gap: var(--space-2); align-items: center; } .search-bar input { flex: 1; }
.search-groups { display: flex; flex-direction: column; gap: var(--space-4); }
.search-scope { display: flex; flex-direction: column; gap: var(--space-2); } .search-scope p { margin: 0; } .search-status { margin: 0; min-height: 1.5em; }
.search-group h2 { font-size: var(--text-sm); color: var(--muted); margin-bottom: var(--space-2); }
.settings-group { display: flex; flex-direction: column; gap: var(--space-2); }
.settings-group > h2 { font-size: var(--text-sm); color: var(--muted); padding: 0 var(--space-1); }
.settings-group.danger > h2 { color: var(--bad); }
.gate-steps { display: flex; justify-content: center; gap: var(--space-2); }
.gate-step { width: 8px; height: 8px; border-radius: 50%; background: var(--line); transition: background-color var(--dur-2) var(--ease), transform var(--dur-2) var(--ease-spring); }
.gate-step.on { background: var(--brand); transform: scale(1.3); }
.gate-head { display: flex; align-items: center; gap: var(--space-2); }

/* ---- the shared player controls (player.b0d3087171.js): a bar over the bottom of the stage, hidden while it plays, back on a tap ---- */
.vc-stage, .vn-stage { position: relative; }      /* the stage the controls sit on (the controls are the last child of it) */
.pl-controls { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); background: linear-gradient(transparent, var(--shade-4)); color: var(--media-fg); transition: opacity var(--dur-2) var(--ease); }
.pl-controls.pl-hidden { opacity: 0; pointer-events: none; }
.pl-controls .btn.icon-only { background: transparent; border-color: transparent; color: var(--media-fg); }
.pl-range { flex: 1; min-width: 0; padding: 0; min-height: 28px; accent-color: var(--brand); background: transparent; border: 0; }
.pl-volume { display: none; align-items: center; gap: var(--space-1); }
@media (hover: hover) and (pointer: fine) { .pl-volume { display: flex; } }      /* a computer with a mouse; phones have their own volume keys */
.pl-vol { width: calc(var(--tap) * 1.5); padding: 0; min-height: 28px; accent-color: var(--brand); background: transparent; border: 0; }
@media (max-width: 640px) { .pl-vol { width: var(--tap); } }      /* a narrow window keeps room for the position bar */
.pl-controls.pl-volume-only { display: none; justify-content: flex-end; }
@media (hover: hover) and (pointer: fine) { .pl-controls.pl-volume-only { display: flex; } }      /* the cutter's player: volume only, and only where there is a mouse */
.pl-time { font-size: var(--text-sm); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---- THIN SCROLLBARS everywhere (standard properties first, WebKit for older browsers) ---- */
* { scrollbar-width: thin; scrollbar-color: var(--scroll-thumb) transparent; }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: var(--radius-pill); border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); background-clip: content-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* ---- WIDE SCREENS: the side menu stays put and only the main view scrolls; the menu collapses to icons ---- */
@media (min-width: 860px) {
  .app { display: grid; grid-template-columns: max-content minmax(0, 1fr); grid-template-rows: auto auto minmax(0, 1fr); height: 100dvh; overflow: hidden; }      /* the menu is as wide as its widest item (the app's title): nothing fixed, so any app's title fits */
  .app > .update, .app > .proxy-job { grid-column: 1 / -1; position: static; }
  .app > .nav { grid-row: 3; position: static; height: auto; width: auto; overflow-x: hidden; overflow-y: auto; }
  .app > .content { grid-row: 3; grid-column: 2; min-height: 0; overflow-y: auto; }
  .nav.collapsed { padding-inline: var(--space-2); align-items: center; }
  .nav.collapsed .app-brand-text, .nav.collapsed .tab-label, .nav.collapsed .nav-foot small { display: none; }
  .nav.collapsed .brand { justify-content: center; } .nav.collapsed .brand-toggle { padding: var(--space-3) 0; width: var(--tap); }
  .nav.collapsed .tab { justify-content: center; padding: 0; width: var(--tap); }
  .nav.collapsed .nav-account { width: 100%; }
  .nav.collapsed .profile-row { justify-content: center; padding: var(--space-3) 0; } .nav.collapsed .profile-row-name { display: none; }
}
@media (min-width: 860px) {
  .app > .content { max-width: none; margin: 0; }
  .app > .content > :not(.topbar) { max-width: 1080px; margin-inline: auto; }
}
@media (min-width: 860px) { .topbar { top: calc(-1 * var(--pad-y)); } }      /* the main view is its own scroller: its padding is above the header's stuck position */

/* the brand toggles the menu (wide screens); the profile row opens the Profile window, where switching and logging out live */
.brand-toggle { background: none; border: 0; color: inherit; font: inherit; text-align: left; cursor: default; width: 100%; padding: var(--space-3); }
@media (min-width: 860px) { .brand-toggle { cursor: pointer; border-radius: var(--radius); } .brand-toggle:hover { background: color-mix(in srgb, var(--brand-soft) 55%, transparent); } }
.profile-row { display: flex; align-items: center; justify-content: flex-start; gap: var(--space-2); width: 100%; min-height: var(--tap); padding: var(--space-3); background: none; border: 0; border-radius: var(--radius); color: inherit; font: inherit; cursor: pointer; text-align: left; }
.profile-row:hover { background: color-mix(in srgb, var(--brand-soft) 55%, transparent); }
.profile-row-name { flex: 1; min-width: 0; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* wide menu: the icon column stays where it is; the text column takes the rest of the row and centres its text */
@media (min-width: 860px) { .nav:not(.collapsed) .tab .tab-label { flex: 1; text-align: center; } }

/* the sign-in screen's profiles: the choices and the add button in one wrapping row */
.gate-card .profiles { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.gate-card .profile-list, .gate-card .profile-actions { display: contents; }
.gate-card .profile-list { list-style: none; margin: 0; padding: 0; }

/* every window has an icon before its title; the profile window's name is edited in place */
.modal-head .modal-icon { color: var(--brand); flex: none; }
.profile-head { display: flex; align-items: center; gap: 0; } .profile-head .spacer { flex: 1; }      /* the name's own padding supplies the 8 px after the avatar */
.inline-text { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap); padding: 0 var(--space-2); background: none; border: 0; border-radius: var(--radius); color: inherit; font: inherit; font-weight: 600; cursor: text; min-width: 0; }
.inline-text:hover { background: color-mix(in srgb, var(--brand-soft) 55%, transparent); }
.inline-text .icon { width: 16px; height: 16px; opacity: .55; flex: none; }
.inline-text-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inline-text-input { flex: 1; min-width: 0; font-weight: 600; }

.topbar-icon { color: var(--brand); flex: none; margin-right: var(--space-2); }

/* ---- the label rule: floating labels for text fields (the label sits inside and moves up on focus or when filled); plain = placeholder only ---- */
.field.float { position: relative; gap: 0; color: var(--fg); font-size: var(--text-md); }
.field.float input, .field.float textarea { padding-top: var(--space-5); padding-bottom: var(--space-1); min-height: var(--control); }
.field.float textarea { min-height: 96px; }
.field.float .field-label { position: absolute; left: 13px; top: 26px; transform: translateY(-50%); transform-origin: left top; font-size: var(--text-md); color: var(--muted); pointer-events: none; transition: transform var(--dur-2) var(--ease), top var(--dur-2) var(--ease), color var(--dur-2) var(--ease); max-width: calc(100% - 26px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.field.float.area .field-label { top: 24px; }
.field.float input:focus + .field-label, .field.float input:not(:placeholder-shown) + .field-label, .field.float input:-webkit-autofill + .field-label,
.field.float textarea:focus + .field-label, .field.float textarea:not(:placeholder-shown) + .field-label { top: 7px; transform: translateY(0) scale(.78); color: var(--brand); }
.field.float input:not(:focus):not(:placeholder-shown) + .field-label, .field.float textarea:not(:focus):not(:placeholder-shown) + .field-label { color: var(--muted); }
.field.float input::placeholder, .field.float textarea::placeholder { color: transparent; }
.field.float input:focus::placeholder, .field.float textarea:focus::placeholder { color: var(--muted); opacity: .8; }
.field.float.has-error .field-label { color: var(--bad); }
.field.float .field-hint, .field.float .field-error { margin-top: var(--space-1); }
.field.plain { gap: var(--space-1); }

/* the action inside the input (see ui.js field({ action })): the label of a floating field stops before it; the quick note and chat boxes are one field */
.field.float.has-action .field-label { max-width: calc(100% - 26px - 52px); }
.gate-card .profile-form { flex: 1 1 100%; margin-top: var(--space-4); }      /* the same air between the chips and what follows as in every other mode */
.quick > .field { flex: 1; min-width: 0; }
.gate-card .field.has-action { width: 100%; }

/* the app card (ui.js appBrand): icon, title and subtitle as one unit; the subtitle sits under the title, beside the icon */
.app-brand { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.app-brand-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; }
.app-brand-title { margin: 0; font-size: var(--text-md); font-weight: 700; white-space: nowrap; }
.app-brand-subtitle { margin-top: var(--space-1); font-size: var(--text-sm); color: var(--muted); line-height: 1.3; }
.app-brand.large .logo { width: 56px; height: 56px; flex: none; font-size: var(--text-lg); }
.app-brand.large .app-brand-title { font-size: var(--text-lg); letter-spacing: -.01em; }
.app-brand.compact .logo { width: 34px; height: 34px; flex: none; border-radius: var(--radius); font-size: var(--text-sm); }

/* the sign-in card's pacing: air around the profile chips, and a quiet line at the bottom that anchors the card */
.gate-card { gap: var(--space-4); }
.gate-card .profiles { margin-block: var(--space-2); }
.gate-foot { margin: var(--space-2) 0 0; padding-top: var(--space-4); border-top: 1px solid var(--line); text-align: center; font-size: var(--text-sm); color: var(--muted); }

/* PROFILE IDENTITY (UI guide, section 7b): the same everywhere a profile is shown - the sign-in chip, the Profile window and the menu row: a 32 px avatar, the name in body size (md) at weight 600, 8 px between them */
.avatar { width: var(--avatar); height: var(--avatar); font-size: var(--text-md); font-weight: 700; }
.profile .profile-name, .profile-row-name, .inline-text, .inline-text-input { font-size: var(--text-md); font-weight: 600; }
.profile, .profile-row { gap: var(--space-2); }

/* THE WAY BACK: a plain chevron and the parent's name (never a boxed button). In the header it replaces the section title on that page; in a card it sits at the top. */
.topbar-back, .back-link { display: inline-flex; align-items: center; gap: var(--space-1); min-height: var(--tap); padding: 0 var(--space-2) 0 0; background: none; border: 0; color: var(--brand); font: inherit; font-weight: 600; cursor: pointer; min-width: 0; }
.topbar-back span, .back-link span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar-back:hover, .back-link:hover { text-decoration: underline; }
.topbar-title-wrap { display: inline-flex; align-items: center; min-width: 0; }
.topbar.has-back .topbar-title-wrap { display: none; }
@media (max-width: 859px) { .topbar.has-back-phone .topbar-title-wrap { display: none; } }
@media (min-width: 860px) { .topbar-back.phone-only { display: none; } }
.gate-head { display: flex; flex-direction: column; align-items: flex-start; gap: var(--stack-snug); }
.gate-step-title { font-size: var(--text-lg); }

/* ---- NARROW WINDOWS AND PHONES: the same structure as wide screens - the main view is its own scroller and the bottom bar is a row of its own, so the scroll bar ends above the bar instead of running behind it ---- */
@media (max-width: 859px) {
  .app { display: grid; grid-template-rows: auto auto minmax(0, 1fr) auto; height: 100dvh; overflow: hidden; }
  .app > .update, .app > .proxy-job { position: static; }
  .app > .nav { position: static; grid-row: 4; }
  .app > .content { grid-row: 3; min-height: 0; overflow-y: auto; padding-bottom: var(--pad-y); }
  .topbar { top: calc(-1 * var(--pad-y)); }
}

/* sync problems (the Sync window): enough to debug - the document, the error code, the detail, the node's raw answer */
.sync-problems { display: flex; flex-direction: column; gap: var(--stack-tight); }
.problem { display: flex; flex-direction: column; gap: var(--stack-snug); padding: var(--space-3); border-radius: var(--radius); background: var(--warn-bg); min-width: 0; }
.problem-name { overflow-wrap: anywhere; } .problem-code { color: var(--warn); font-weight: 600; } .problem-detail { color: var(--fg); overflow-wrap: anywhere; }
.problem-raw summary { cursor: pointer; font-size: var(--text-sm); color: var(--muted); }
.problem-raw pre { margin: var(--space-2) 0 0; font: var(--text-sm)/1.4 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; }

.sync-notes { display: flex; flex-direction: column; gap: var(--stack-snug); overflow-wrap: anywhere; }

.problem-hint { overflow-wrap: anywhere; }

/* the node's health in the Sync window: version, the administrator's message, an update notice that matters, the download link */
.node-info { display: flex; flex-direction: column; gap: var(--stack-snug); }
.node-message { overflow-wrap: anywhere; }
.update-notice { display: flex; align-items: flex-start; gap: var(--space-2); padding: var(--space-3); border-radius: var(--radius); background: var(--warn-bg); color: var(--warn); font-size: var(--text-sm); } .update-notice.critical { color: var(--bad); }
.download-link { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap); color: var(--brand); font-weight: 600; text-decoration: none; } .download-link:hover { text-decoration: underline; }
.download-sum { overflow-wrap: anywhere; }

.vs-stage { margin-bottom: var(--space-3); }
.vs-loading { position: absolute; inset: 0; display: grid; place-items: center; margin: 0; color: var(--media-fg); }
.vs-nocopy { margin: 0 0 var(--space-3); }
.vs-desc { margin-top: var(--space-3); border-top: 1px solid var(--line); padding-top: var(--space-2); }
.vs-desc-head { display: flex; align-items: center; gap: var(--space-2); background: none; border: 0; padding: var(--space-2) 0; color: inherit; font: inherit; cursor: pointer; }
.vs-desc-head .icon { transition: transform 0.15s; }
.vs-desc-head.open .icon { transform: rotate(90deg); }
.progress-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.progress-step { display: flex; align-items: center; gap: var(--space-2); color: var(--muted); }
.progress-step.done { color: var(--fg); }
.progress-step.now { color: var(--brand); font-weight: 600; }
.progress-step .icon { color: var(--brand); flex: none; }
.progress-dot { flex: none; width: var(--space-4); height: var(--space-4); display: grid; place-items: center; }
.progress-dot::before { content: ""; width: var(--space-2); height: var(--space-2); border-radius: var(--radius-pill); background: currentColor; opacity: .5; }
.progress-step.now .progress-dot::before { opacity: 1; animation: progress-pulse 1s ease-in-out infinite; }
@keyframes progress-pulse { 50% { transform: scale(1.5); } }
@media (prefers-reduced-motion: reduce) { .progress-step.now .progress-dot::before { animation: none; } }
.feed { display: flex; flex-direction: column; gap: var(--space-3); }
.post { gap: var(--space-3); }
.post-head { display: flex; align-items: center; gap: var(--space-2); }
.post-head .icon-only { margin-left: auto; }
.post-text { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.post-note, .post-progress { display: flex; flex-direction: column; gap: var(--space-2); }
.post-value { font-size: var(--text-lg); font-weight: 700; }
.post-up { color: var(--good); }
.post-down { color: var(--muted); }
.post-reactions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.reaction { display: inline-flex; align-items: center; gap: var(--space-1); min-height: var(--tap); padding: 0 var(--space-3); border-radius: var(--radius-pill); border: 1px solid var(--line); background: var(--panel); cursor: pointer; font-size: var(--text-md); }
.reaction.on { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 18%, transparent); }
.post-comments { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.comment { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.comment .icon-only { margin-left: auto; }

/* "Powered by APPI-AI": the quiet badge under the sign-in card, and its window */
.powered-by { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap); padding: 0 var(--space-4); border: 0; background: none; color: var(--muted); font-size: var(--text-sm); cursor: pointer; border-radius: var(--radius); }
.powered-by strong { color: var(--text); font-weight: 700; letter-spacing: .02em; }
.powered-by:hover strong { text-decoration: underline; }
.powered-by-mark { width: 20px; height: 20px; }
.get-app { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-2); }
.get-app-link { border: 0; background: none; cursor: pointer; display: inline-grid; place-items: center; width: var(--tap); height: var(--tap); border-radius: var(--radius); color: var(--muted); }
.get-app-link:hover { color: var(--text); }
.get-app-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.about-tagline { margin: 0; font-size: var(--text-lg); font-weight: 700; }

.link-device { display: flex; flex-direction: column; align-items: flex-start; gap: var(--stack-tight); }
.ws-compat { display: flex; gap: var(--space-2); align-items: flex-start; font-size: var(--text-sm); } .ws-compat .icon { width: 18px; height: 18px; margin-top: var(--space-1); }
.ws-summary { display: flex; flex-direction: column; gap: var(--stack-snug); margin-bottom: var(--stack); } .ws-summary p { margin: 0; }
.ws-actions { display: flex; gap: var(--space-2); margin-top: var(--stack); }
.ws-row.ws-expired, .ws-row.ws-revoked { opacity: .7; } .ws-expired .chip, .ws-revoked .chip { color: var(--muted); }

/* ---- PEOPLE: the Teams | Friends chips and the Friends page (friendviews.js, @appi/friends-ui) ---- */
.people { display: flex; flex-direction: column; gap: var(--stack); }
.people-chips .badge { margin-left: var(--space-2); background: var(--brand); color: var(--brand-fg); border-radius: var(--radius-pill); padding: 0 var(--space-2); font-size: var(--text-sm); }
.people-chips .chip-choice.on .badge { background: var(--brand); }
.friends-view { display: flex; flex-direction: column; gap: var(--stack-section); }
.friend-section { display: flex; flex-direction: column; gap: var(--stack-tight); }
.friend-section > h2, .friend-people > .friend-section > h2 { font-size: var(--text-md); font-weight: 700; }
.friend-people { display: flex; flex-direction: column; gap: var(--stack-section); }
.friend-code { display: flex; flex-direction: column; gap: var(--stack); align-items: flex-start; }
.friend-code .link-field { align-self: stretch; }          /* the code's text fills the row, its copy button inside it (user, 2026-11-03) */
.friend-add { display: flex; flex-direction: column; gap: var(--stack); }
.row-split { display: flex; align-items: center; gap: var(--space-2); }
.row-split .row-open { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--space-3); background: none; border: 0; padding: 0; text-align: left; color: inherit; cursor: pointer; min-height: var(--tap); }
.row-actions { display: flex; gap: var(--space-2); }
.friend-request .row-trail, .friend-blocked-row .row-trail { color: inherit; }

/* ---- PROGRESS ON A NOTE: the band under a note's text (one card per measure) and the Track progress window ---- */
.progress-band { display: flex; flex-direction: column; gap: var(--stack-section); margin-top: var(--stack-section); border-top: 1px solid var(--line); padding-top: var(--stack-section); }
.measure-card { display: flex; flex-direction: column; gap: var(--stack); }
.measure-card .section-head h2 { font-size: var(--text-md); font-weight: 700; }
.track-measure { display: flex; flex-direction: column; gap: var(--stack-tight); padding-bottom: var(--stack); border-bottom: 1px solid var(--line); }
.track-measure:last-of-type { border-bottom: 0; }

/* ---- HOME FEED: day headings over the latest activity ---- */
.feed-day { font-size: var(--text-sm); font-weight: 600; color: var(--muted); padding: var(--space-3) var(--space-1) var(--space-1); }
.feed-day:first-child { padding-top: 0; }
.feed-filters { margin: var(--stack) 0; }
/* INVITATIONS (the template's UI_VERSION 42, inviteviews.js; backported 2026-11-04): the code shown as a QR over its text, the person's invitations under it, the way in from the Sync window */
.invite-shown { display: flex; flex-direction: column; gap: var(--stack); }
.invite-mine { display: flex; flex-direction: column; gap: var(--stack-tight); margin-top: var(--stack-section); }
.invite-mine > h2, .invite-mine > p { margin: 0; }
.invite-row.revoked, .invite-row.over { opacity: .7; } .invite-revoked { color: var(--muted); }
.invite-enter { display: grid; gap: var(--space-2); } .invite-enter p { margin: 0; }

/* A MONTH CALENDAR (ui.js monthCalendar, UI guide section 20b, 2026-11-04): seven columns, Monday first; today ringed, the chosen day filled; a dot per kind of thing a day holds */
.cal { display: grid; gap: var(--space-2); }
.cal-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.cal-title { text-transform: capitalize; }
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--space-1); }
.cal-weekday { text-align: center; color: var(--muted); font-size: var(--text-sm); }
.cal-day { min-height: var(--tap); display: grid; justify-items: center; align-content: center; gap: var(--space-1); border: 1px solid transparent; border-radius: var(--radius-xs); background: none; color: var(--fg); font: inherit; cursor: pointer; padding: var(--space-1) 0; }
.cal-day:hover { background: var(--brand-soft); }
.cal-day.today { border-color: var(--brand); }
.cal-day[aria-pressed="true"] { background: var(--brand); color: var(--brand-fg); }
.cal-dots { display: flex; gap: var(--space-1); min-height: var(--space-2); }
.cal-dot { width: var(--space-2); height: var(--space-2); border-radius: var(--radius-pill); background: var(--brand); }
.cal-day[aria-pressed="true"] .cal-dot { background: var(--brand-fg); }
.cal-dot.kind-session { background: var(--good); } .cal-dot.kind-reading { background: var(--warn); } .cal-day[aria-pressed="true"] .cal-dot.kind-session, .cal-day[aria-pressed="true"] .cal-dot.kind-reading { background: var(--brand-fg); }
/* THE PRACTICE CALENDAR on Home (2026-11-04): the month card, then the chosen day's sessions, notes and readings */
.calendar-card { display: grid; gap: var(--stack); }
.cal-chosen { display: grid; gap: var(--stack-tight); }
.cal-chosen-day { margin: 0; font-size: var(--text-md); }
.cal-nothing { margin: 0; }

/* the backup reminder (the template's dataviews.js reminderCard, UI guide section 15b) */
.data-reminder { display: grid; gap: var(--stack-tight); } .data-reminder-text { display: flex; gap: var(--space-2); align-items: flex-start; } .data-reminder-actions { justify-content: flex-end; }

/* a toast's one action (ui.js toast({ action }): Undo after a drop, UI guide section 21) - the region lets nothing else take the pointer */
.toast .toast-action { pointer-events: auto; color: inherit; background: transparent; border-color: transparent; } .toast .toast-action:hover { background: color-mix(in srgb, currentColor 14%, transparent); }
/* MOVING A NOTE BY DRAGGING (2026-11-04, UI guide section 21): the grip in a row, the lifted row, the Move to bar of library chips that shows while a note is lifted */
.note-lead { display: inline-flex; align-items: center; gap: var(--space-1); } .note-grip { display: inline-flex; color: var(--muted); cursor: grab; touch-action: none; padding: var(--space-1); }
.list-row.lifted { opacity: .55; box-shadow: var(--shadow-pop); }
.move-bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); padding: var(--space-2) 0; }
.move-chip { cursor: copy; } .move-chip.over { background: var(--brand); color: var(--brand-fg); } .move-chip.here { opacity: .5; cursor: not-allowed; }
/* a library's badge (its colour, and its icon or first letter) and the colour choices in its window */
.lib-badge { display: inline-grid; place-items: center; width: var(--space-6); height: var(--space-6); border-radius: var(--radius-xs); background: var(--muted); color: var(--lib-fg); font-weight: 700; font-size: var(--text-sm); flex: none; } .lib-badge .icon { width: 70%; height: 70%; }
.lib-badge.lib-none { background: var(--brand-soft); color: var(--brand); }
.lib-blue { background: var(--lib-blue); }
.lib-green { background: var(--lib-green); }
.lib-orange { background: var(--lib-orange); }
.lib-purple { background: var(--lib-purple); }
.lib-red { background: var(--lib-red); }
.lib-grey { background: var(--lib-grey); }
.chip-choice .lib-swatch { display: inline-block; width: var(--space-3); height: var(--space-3); border-radius: var(--radius-pill); margin-inline-end: var(--space-1); vertical-align: middle; } .move-chip .lib-badge { width: var(--space-4); height: var(--space-4); margin-inline-end: var(--space-1); vertical-align: middle; font-size: var(--text-sm); }
/* a practice session's measurements (a library with a date; 2026-11-04) */
.session-card { display: grid; gap: var(--stack-tight); } .session-card h2 { margin: 0; font-size: var(--text-md); } .session-value { margin-inline-end: var(--space-1); }

/* CALLS IN A THREAD (template UI_VERSION 53 = NotePerfect 50, callviews.js): the call is a full-screen view over the app (windows and the confirm dialog still open above it); a tile per person, my own picture small and
   mirrored; the controls are icon-only at the bottom. The banner in the thread is a list row. */
.call-banner { margin-bottom: var(--space-3); border: 1px solid var(--brand); background: var(--brand-soft); }
.call-banner.in { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3); border-radius: var(--radius); color: var(--fg); }
.call-banner.full { border-color: var(--line); background: var(--panel); }
.call-join { color: var(--brand); font-weight: 600; }
.call-screen { position: fixed; inset: 0; z-index: var(--z-call); display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-3); background: var(--media-bg); color: var(--media-fg); }
.call-head { display: flex; align-items: center; gap: var(--space-2); min-height: 44px; }
.call-head .call-count { margin-left: auto; color: color-mix(in srgb, var(--media-fg) 70%, transparent); }
.call-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.call-tiles { flex: 1; min-height: 0; display: grid; gap: var(--space-2); grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); grid-auto-rows: minmax(0, 1fr); }
.call-tile { position: relative; margin: 0; min-height: 120px; overflow: hidden; border-radius: var(--radius); background: color-mix(in srgb, var(--media-fg) 10%, var(--media-bg)); }
.call-tile video { width: 100%; height: 100%; object-fit: cover; display: block; }
.call-tile video.mirror { transform: scaleX(-1); }
.call-tile.off video { visibility: hidden; }
.call-tiles { position: relative; }
.call-tiles.with-others .call-tile.mine { position: absolute; right: var(--space-2); bottom: var(--space-2); z-index: 1; width: 160px; height: 90px; min-height: 0; box-shadow: var(--shadow-pop); }
.call-tiles.with-others .call-tile.mine .call-avatar { width: 40px; height: 40px; font-size: var(--text-md); }
.call-avatar { position: absolute; inset: 0; margin: auto; width: 72px; height: 72px; display: grid; place-items: center; border-radius: 50%; background: var(--brand); color: var(--brand-fg); font-size: var(--text-lg); font-weight: 700; }
.call-name { position: absolute; left: var(--space-2); bottom: var(--space-2); display: flex; align-items: center; gap: var(--space-1); padding: var(--space-1) var(--space-2); border-radius: var(--radius-pill); background: color-mix(in srgb, var(--media-bg) 60%, transparent); font-size: var(--text-sm); }
.call-name .icon { width: 16px; height: 16px; }
.call-state { color: color-mix(in srgb, var(--media-fg) 70%, transparent); }
.call-sound { align-self: center; display: inline-flex; align-items: center; gap: var(--space-2); min-height: 44px; padding: var(--space-2) var(--space-4); border: 0; border-radius: var(--radius-pill); background: var(--media-fg); color: var(--media-bg); font: inherit; font-weight: 600; cursor: pointer; }
.call-controls { display: flex; justify-content: center; gap: var(--space-3); padding-bottom: env(safe-area-inset-bottom); }
.call-controls .btn { width: 56px; height: 56px; border-radius: 50%; }
.call-controls .btn.on { background: var(--media-fg); color: var(--media-bg); }
@media (max-width: 640px) {
  .call-tiles { grid-template-columns: 1fr; }
  .call-tiles.n2 { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
  .call-tiles:is(.n3, .n4, .n5, .n6) { grid-template-columns: 1fr 1fr; }
  .call-tiles.with-others .call-tile.mine { width: 96px; height: 128px; }
}

/* THE STARTUP SCREEN (index.html's .boot, UI guide 10 "Starting"; user, 2026-11-06: "a loading animation or spinner, something cool, in the colors of the app with the app name"):
   what shows from the first paint until the app mounts (the app replaces it). Plain HTML and CSS - it runs before any script (the CSP allows no inline script) - in the app's own
   tokens, so it takes the app's colours, light or dark. The app's icon breathes inside a ring that turns in the brand colour; under it the app's name and "Starting…"; a slow start
   (the first visit downloads the app) says why after a while. Reduced motion: still, with the explanation shown at once. */
.boot { position: fixed; inset: 0; display: grid; place-content: center; justify-items: center; gap: var(--space-2); padding: var(--space-5); background: var(--bg); color: var(--fg); text-align: center; }
.boot-mark { position: relative; display: grid; place-items: center; width: 112px; height: 112px; margin-bottom: var(--space-3); }
.boot-mark::before { content: ''; position: absolute; inset: 16px; border-radius: 50%; background: var(--brand-soft); animation: boot-breathe var(--dur-breathe) var(--ease) infinite; }
.boot-ring { position: absolute; inset: 0; border-radius: 50%; background: conic-gradient(from 0deg, transparent 0 30%, color-mix(in srgb, var(--brand) 25%, transparent) 55%, var(--brand) 100%);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 6px), black calc(100% - 5px)); mask: radial-gradient(farthest-side, transparent calc(100% - 6px), black calc(100% - 5px));
  animation: boot-spin var(--dur-loop) linear infinite; }
.boot-icon { position: relative; width: 64px; height: 64px; border-radius: var(--radius-lg); box-shadow: var(--shadow); animation: boot-breathe var(--dur-breathe) var(--ease) infinite; }
.boot-name { margin: 0; font-size: var(--text-lg); font-weight: 700; letter-spacing: .02em; animation: boot-in var(--dur-3) var(--ease) both; }
.boot-note { margin: 0; color: var(--muted); font-size: var(--text-sm); animation: boot-in var(--dur-3) var(--ease) var(--dur-2) both; }
.boot-slow { max-width: 34ch; margin: var(--space-3) 0 0; color: var(--muted); font-size: var(--text-sm); opacity: 0; animation: boot-in var(--dur-3) var(--ease) var(--boot-slow-after) both; }
@keyframes boot-spin { to { transform: rotate(1turn); } }
@keyframes boot-breathe { 0%, 100% { transform: scale(.94); opacity: .8; } 50% { transform: scale(1); opacity: 1; } }
@keyframes boot-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .boot-slow { opacity: 1; } }
/* the first visit's DOWNLOAD PROGRESS (user, 2026-11-07): boot.js (written by build_pwa.mjs) adds a bar and "x of y MB" under "Starting…" while the worker saves the app; none when it is saved already */
.boot-progress { appearance: none; width: min(240px, 70vw); height: 6px; margin-top: var(--space-2); border: 0; border-radius: var(--radius-pill); background: var(--brand-soft); color: var(--brand); overflow: hidden; animation: boot-in var(--dur-3) var(--ease) both; }
.boot-progress::-webkit-progress-bar { background: var(--brand-soft); border-radius: var(--radius-pill); }
.boot-progress::-webkit-progress-value { background: var(--brand); border-radius: var(--radius-pill); transition: width var(--dur-2) var(--ease); }
.boot-progress::-moz-progress-bar { background: var(--brand); border-radius: var(--radius-pill); }
.boot-amount { margin: 0; color: var(--muted); font-size: var(--text-sm); font-variant-numeric: tabular-nums; }

/* the node refusing this profile (nodeproblem.js; UI guide section 11): an attention card on Home, never a dialog */
.node-problem { display: flex; flex-direction: column; gap: var(--stack-snug); background: var(--warn-bg); border-left: 3px solid var(--warn); }
.node-problem strong { color: var(--warn); }
