/* ============================================================
   Keepsake design system — securekeepsake.com (MASTER_PLAN §6.5)
   One file, both themes. Dark default; light via OS preference or the header
   toggle, which wins (WEB_FEATURES_PLAN §3). Tokens match the PWA.
   Budget: ~18 KB raw / ~5 KB gzip, measured. Was 14.0/3.9 before the A1 restructure;
   the alias blocks and the toggle cost ~1 KB gzip and buy a theme that can be chosen.
   (light-dark() would collapse the alias blocks, but it fails *closed* — an older
   browser gets an unstyled page — so the explicit form stays.)
   The gate that matters is <100 KB first load; the home page measures ~66 KB.
   No webfonts, no third-party requests.
   ============================================================ */

/* Precedence: explicit choice (data-theme) → OS preference → dark.
   Every colour is written ONCE below; the three blocks after only alias, because
   two hand-kept copies of a palette drift and it is always the untested one.
   --accent-btn: white on --d-accent is 3.95:1 — fine as a link on the dark page
   (4.92:1), too light as a fill, so fills get their own darker token (5.42:1).
   --l-ok / --l-warn darkened in A5; the old pair failed on .hl and .badge.warn. */
:root {
  --d-bg: #0b0d11; --d-surface: #14161d; --d-surface2: #1b1e27; --d-border: #262a35;
  --d-text: #edeae3; --d-muted: #9a96a8; --d-accent: #9460fa; --d-accent-hover: #7d48e0;
  --d-accent-soft: rgba(148, 96, 250, .12);
  --d-accent-btn: #7d48e0; --d-accent-btn-hover: #7340d6;
  --d-danger: #ff7a7a; --d-ok: #7ee08a; --d-warn: #ffd75e;

  --l-bg: #faf9f7; --l-surface: #ffffff; --l-surface2: #f1eff4; --l-border: #ddd9e4;
  --l-text: #1c1a24; --l-muted: #5f5a6e; --l-accent: #6d34e0; --l-accent-hover: #5825c0;
  --l-accent-soft: rgba(109, 52, 224, .09);
  --l-accent-btn: #6d34e0; --l-accent-btn-hover: #5825c0;
  --l-danger: #c0392b; --l-ok: #12662a; --l-warn: #7a5400;

  --bg: var(--d-bg); --surface: var(--d-surface); --surface2: var(--d-surface2);
  --border: var(--d-border); --text: var(--d-text); --muted: var(--d-muted);
  --accent: var(--d-accent); --accent-hover: var(--d-accent-hover);
  --accent-soft: var(--d-accent-soft);
  --accent-btn: var(--d-accent-btn); --accent-btn-hover: var(--d-accent-btn-hover);
  --danger: var(--d-danger); --ok: var(--d-ok); --warn: var(--d-warn);
  color-scheme: dark;

  --radius: 10px; --wrap: 1080px;
  --font: ui-sans-serif, system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "Cascadia Code", Consolas, Menlo, monospace;
}

:root[data-theme="light"] {
  --bg: var(--l-bg); --surface: var(--l-surface); --surface2: var(--l-surface2);
  --border: var(--l-border); --text: var(--l-text); --muted: var(--l-muted);
  --accent: var(--l-accent); --accent-hover: var(--l-accent-hover);
  --accent-soft: var(--l-accent-soft);
  --accent-btn: var(--l-accent-btn); --accent-btn-hover: var(--l-accent-btn-hover);
  --danger: var(--l-danger); --ok: var(--l-ok); --warn: var(--l-warn);
  color-scheme: light;
}

/* The :not([data-theme="dark"]) guard is the trick: without it a light-OS visitor
   who explicitly chose dark gets the media query handed back to them. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg: var(--l-bg); --surface: var(--l-surface); --surface2: var(--l-surface2);
    --border: var(--l-border); --text: var(--l-text); --muted: var(--l-muted);
    --accent: var(--l-accent); --accent-hover: var(--l-accent-hover);
    --accent-soft: var(--l-accent-soft);
    --accent-btn: var(--l-accent-btn); --accent-btn-hover: var(--l-accent-btn-hover);
    --danger: var(--l-danger); --ok: var(--l-ok); --warn: var(--l-warn);
    color-scheme: light;
  }
}

/* ── Reset-lite ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
body {
  background: var(--bg); color: var(--text);
  font: 16px/1.65 var(--font);
  -webkit-text-size-adjust: 100%;
}
img, svg, video { max-width: 100%; height: auto; display: block; }
a { color: var(--accent); }
a:hover { color: var(--accent-hover); }

/* ── Layout ── */
.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 22px; }
main { display: block; min-height: 60vh; }
section { padding: 64px 0; }
section.alt { background: var(--surface); border-block: 1px solid var(--border); }
.center { text-align: center; }
.muted { color: var(--muted); }

/* ── Type ── */
h1, h2, h3, h4 { line-height: 1.2; font-weight: 750; letter-spacing: -.015em; text-wrap: balance; }
h1 { font-size: clamp(2rem, 5vw, 3.1rem); margin-bottom: .5em; }
h2 { font-size: clamp(1.5rem, 3.4vw, 2.1rem); margin-bottom: .6em; }
h3 { font-size: 1.15rem; margin-bottom: .4em; }
p { margin-bottom: 1em; }
.lead { font-size: 1.18rem; color: var(--muted); max-width: 46em; }
.center .lead { margin-inline: auto; }
.eyebrow {
  display: inline-block; color: var(--accent); font-size: .78rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; margin-bottom: 10px;
}
code, kbd { font-family: var(--mono); font-size: .9em; background: var(--surface2); border: 1px solid var(--border); border-radius: 5px; padding: .1em .35em; }
pre { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; overflow-x: auto; margin-bottom: 1em; }
pre code { background: none; border: 0; padding: 0; }
hr { border: 0; border-top: 1px solid var(--border); margin: 32px 0; }

/* ── Buttons ── */
.btn {
  display: inline-block; background: var(--accent-btn); color: #fff; border: 1px solid transparent;
  border-radius: 8px; padding: 12px 26px; font: 600 .97rem var(--font);
  text-decoration: none; cursor: pointer; transition: background .15s;
}
.btn:hover { background: var(--accent-btn-hover); color: #fff; }
.btn.ghost { background: transparent; color: var(--text); border-color: var(--border); }
.btn.ghost:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.btn.sm { padding: 8px 16px; font-size: .88rem; }
.cta-row { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.center .cta-row { justify-content: center; }

/* ── Header / nav (CSS-only burger) ── */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}
.site-header .bar { display: flex; align-items: center; gap: 28px; min-height: 62px; }
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--text); font-weight: 800; font-size: 1.12rem; margin-right: auto; }
.brand img { width: 30px; height: 30px; }
.site-nav { display: flex; align-items: center; gap: 24px; }
.site-nav a { color: var(--muted); text-decoration: none; font-size: .92rem; font-weight: 600; }
.site-nav a:hover, .site-nav a[aria-current="page"] { color: var(--text); }
.site-nav a[aria-current="page"] { color: var(--accent); }
.site-nav .btn { color: #fff; }
/* ── Theme toggle (A4). Hidden until <html class="js"> proves the handler can arrive —
   a dead control is worse than an absent one. Icon = destination. ── */
.theme-toggle { display: none; }
.js .theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; flex: none;
  background: transparent; color: var(--muted);
  border: 1px solid var(--border); border-radius: 9px;
  cursor: pointer; transition: color .15s, border-color .15s, background .15s;
}
.theme-toggle:hover { color: var(--text); border-color: var(--accent); background: var(--accent-soft); }
.theme-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.theme-toggle svg { display: block; }
.theme-toggle .i-moon { display: none; }
:root[data-theme="light"] .theme-toggle .i-sun { display: none; }
:root[data-theme="light"] .theme-toggle .i-moon { display: block; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .theme-toggle .i-sun { display: none; }
  :root:not([data-theme="dark"]) .theme-toggle .i-moon { display: block; }
}

/* ── Site search (B3). Launcher mirrors the toggle: hidden until `js`. ── */
.search-open { display: none; }
.js .search-open {
  display: inline-flex; align-items: center; gap: 8px; flex: none;
  background: var(--surface2); color: var(--muted);
  border: 1px solid var(--border); border-radius: 9px;
  padding: 7px 10px; font: 600 .85rem var(--font); cursor: pointer;
  transition: color .15s, border-color .15s;
}
.search-open:hover { color: var(--text); border-color: var(--accent); }
.search-open:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.search-open-kbd { border: 1px solid var(--border); border-radius: 5px; padding: 1px 5px;
  font: 600 .72rem var(--mono); background: var(--bg); color: var(--muted); }
@media (max-width: 900px) { .search-open-label, .search-open-kbd { display: none; } }

.ks-search { width: min(620px, calc(100vw - 32px)); max-height: 78vh; padding: 0;
  border: 1px solid var(--border); border-radius: 14px; background: var(--surface);
  color: var(--text); box-shadow: 0 24px 60px rgba(0,0,0,.45); overflow: hidden; }
dialog.ks-search { margin: 12vh auto auto; }
dialog.ks-search::backdrop { background: rgba(0,0,0,.55); }
/* Fallback when <dialog> is missing: position it ourselves, same look. */
div.ks-search { position: fixed; inset: 12vh 0 auto 0; margin: 0 auto; z-index: 200; }
div.ks-search[hidden] { display: none; }
.ks-search-bar { display: flex; align-items: center; gap: 8px; padding: 12px 14px;
  border-bottom: 1px solid var(--border); }
.ks-search-input { flex: 1; background: transparent; border: 0; color: var(--text);
  font: 500 1.05rem var(--font); padding: 6px 2px; }
.ks-search-input:focus { outline: none; }
.ks-search-close { background: transparent; border: 0; color: var(--muted); cursor: pointer;
  font-size: 1rem; padding: 4px 8px; border-radius: 6px; }
.ks-search-close:hover { color: var(--text); }
.ks-search-results { overflow-y: auto; max-height: 58vh; }
.ks-result { display: block; padding: 11px 16px; text-decoration: none; color: var(--text);
  border-bottom: 1px solid var(--border); }
.ks-result:last-child { border-bottom: 0; }
.ks-result.sel, .ks-result:hover { background: var(--accent-soft); }
.ks-result-t { display: block; font-weight: 700; font-size: .97rem; }
.ks-result-h { display: inline-block; color: var(--accent); font-size: .84rem; margin-top: 2px; }
.ks-result-x { display: block; color: var(--muted); font-size: .86rem; margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ks-search-empty { padding: 18px 16px; color: var(--muted); font-size: .92rem; }
.ks-search-hint { padding: 9px 16px; border-top: 1px solid var(--border); color: var(--muted);
  font-size: .78rem; background: var(--surface2); }
.ks-result.ks-community { color: var(--accent); font-weight: 600; }

#nav-toggle, .burger { display: none; }
.burger { cursor: pointer; padding: 8px; margin-left: 8px; }
.burger span { display: block; width: 22px; height: 2px; background: var(--text); border-radius: 2px; margin: 5px 0; transition: transform .2s, opacity .2s; }
/* Collapse to the burger at 1000px, not 760px. Between those two widths the desktop row did
   not fit: measured at 860px the brand text overlapped the first nav link by 14px, and at
   780px the bar overflowed its container by 65px. That predates this work — the header gained
   a search launcher and a theme toggle after the breakpoint was chosen, and nobody
   re-measured. iPad landscape is 1024px, so this range is real traffic. */
@media (max-width: 1000px) {
  .burger { display: block; order: 2; }
  .js .theme-toggle { order: 1; }   /* toggle, then burger — the menu button stays outermost */
  .site-nav {
    display: none; position: absolute; inset: 100% 0 auto 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--bg); border-bottom: 1px solid var(--border); padding: 8px 22px 18px;
  }
  .site-nav a { padding: 13px 0; border-bottom: 1px solid var(--border); font-size: 1.05rem; }
  .site-nav a:last-child { border-bottom: 0; }
  .site-nav .btn { text-align: center; margin-top: 12px; border-bottom: 0; }
  #nav-toggle:checked ~ .site-nav { display: flex; }
  #nav-toggle:checked ~ .burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  #nav-toggle:checked ~ .burger span:nth-child(2) { opacity: 0; }
  #nav-toggle:checked ~ .burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
}

/* ── Hero ── */
.hero { padding: 84px 0 70px; position: relative; overflow: hidden; }
.hero::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 65% 55% at 50% -10%, var(--accent-soft) 0%, transparent 70%);
}
.hero > .wrap { position: relative; }

/* ── Cards & grids ── */
.grid { display: grid; gap: 18px; }
.grid.c2 { grid-template-columns: repeat(2, 1fr); }
.grid.c3 { grid-template-columns: repeat(3, 1fr); }
.grid.c4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) { .grid.c3, .grid.c4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .grid.c2, .grid.c3, .grid.c4 { grid-template-columns: 1fr; } }
.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 22px;
}
.card h3 { display: flex; align-items: center; gap: 8px; }
.card .ico { color: var(--accent); font-size: 1.25rem; line-height: 1; }
.card p:last-child { margin-bottom: 0; }
a.card { display: block; color: inherit; text-decoration: none; transition: border-color .15s; }
a.card:hover { border-color: var(--accent); }

/* ── Steps (how it works) ── */
.steps { counter-reset: step; }
.steps .card { position: relative; padding-top: 30px; }
.steps .card::before {
  counter-increment: step; content: counter(step);
  position: absolute; top: -16px; left: 20px;
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--accent); color: #fff; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
}

/* ── Tables ── */
.table-scroll { overflow-x: auto; }
table.table { width: 100%; border-collapse: collapse; font-size: .95rem; }
.table th, .table td { padding: 11px 14px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
.table tbody th { font-weight: 600; }
.table thead th { font-size: .8rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); border-bottom-width: 2px; }
.table .yes { color: var(--ok); font-weight: 700; }
.table .no { color: var(--muted); }
.table .hl { background: var(--accent-soft); }

/* ── Permissions matrix (/features/family, rendered from shared/roles.json) ──
   The "enforced by" column carries the meaning of the whole table — it says whether a "No"
   is cryptography or our own interface — so it is styled to be read, not skipped, and the
   two badges are deliberately different colours rather than two shades of the same one. */
table.perm-matrix { width: 100%; border-collapse: collapse; font-size: .95rem; min-width: 720px; }
.perm-matrix caption { text-align: left; font-weight: 650; padding-bottom: 10px; color: var(--muted); }
.perm-matrix th, .perm-matrix td { padding: 12px 14px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
.perm-matrix thead th { font-size: .8rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); border-bottom-width: 2px; white-space: nowrap; }
.perm-matrix tbody th { font-weight: 650; max-width: 22em; }
.perm-matrix .cap-how { display: block; font-weight: 400; font-size: .85rem; color: var(--muted); margin-top: 5px; }
.perm-matrix .cell { white-space: nowrap; }
.perm-matrix .cell-yes, .perm-matrix .cell-all { color: var(--ok); font-weight: 700; }
.perm-matrix .cell-no, .perm-matrix .cell-none { color: var(--muted); }
.perm-matrix .cell-granted, .perm-matrix .cell-except-owner { color: var(--text); font-weight: 600; }
.enf { display: inline-block; font-size: .78rem; font-weight: 700; letter-spacing: .03em; padding: 3px 9px; border-radius: 999px; white-space: nowrap; cursor: help; }
.enf-keys { background: var(--accent-soft); color: var(--accent); }
.enf-app { background: var(--surface2); color: var(--muted); border: 1px solid var(--border); }

/* ── FAQ (details/summary) ── */
details.faq { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: 0 18px; margin-bottom: 10px; }
details.faq summary { cursor: pointer; font-weight: 650; padding: 15px 0; list-style: none; position: relative; padding-right: 28px; }
details.faq summary::-webkit-details-marker { display: none; }
details.faq summary::after { content: "+"; position: absolute; right: 2px; top: 12px; color: var(--accent); font-size: 1.25rem; }
details.faq[open] summary::after { content: "–"; }
details.faq .a { padding: 0 0 16px; color: var(--muted); }
details.faq .a p:last-child { margin-bottom: 0; }

/* ── Forms ── */
input, select, textarea {
  font: inherit; color: var(--text); background: var(--surface2);
  border: 1px solid var(--border); border-radius: 8px; padding: 11px 13px; width: 100%;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); }
label { font-size: .9rem; font-weight: 600; display: block; margin-bottom: 6px; }
.field { margin-bottom: 16px; }

/* ── Badges & notes ── */
.badge { display: inline-block; background: var(--accent-soft); color: var(--accent); border-radius: 999px; padding: 3px 12px; font-size: .8rem; font-weight: 700; }
.note { border-left: 3px solid var(--accent); background: var(--surface); border-radius: 0 var(--radius) var(--radius) 0; padding: 14px 18px; margin: 18px 0; }
.note.warn { border-left-color: var(--warn); }

/* ── Under-the-hood technical box (feature pages) ── */
.hood { background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px 22px; margin: 24px 0; font-size: .95rem; }
.hood h3 { font-family: var(--mono); font-size: .85rem; text-transform: uppercase; letter-spacing: .1em; color: var(--accent); }

/* ── Prose (markdown-rendered docs/blog) ── */
.prose { max-width: 46em; }
.prose h2 { margin-top: 1.6em; }
.prose h3 { margin-top: 1.3em; }
.prose ul, .prose ol { margin: 0 0 1em 1.4em; }
.prose li { margin-bottom: .35em; }
.prose img { border: 1px solid var(--border); border-radius: var(--radius); }
.prose blockquote { border-left: 3px solid var(--accent); padding-left: 16px; color: var(--muted); margin-bottom: 1em; }

/* ── Footer ── */
.site-footer { background: var(--surface); border-top: 1px solid var(--border); padding: 48px 0 34px; margin-top: 64px; font-size: .92rem; }
.site-footer .cols { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 28px; }
@media (max-width: 760px) { .site-footer .cols { grid-template-columns: 1fr 1fr; } }
.site-footer .foot-h { font-size: .8rem; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); margin-bottom: 12px; }
.site-footer ul { list-style: none; }
.site-footer li { margin-bottom: 8px; }
.site-footer a { color: var(--muted); text-decoration: none; }
.site-footer a:hover { color: var(--text); }
.site-footer .fine { margin-top: 34px; padding-top: 18px; border-top: 1px solid var(--border); color: var(--muted); font-size: .84rem; display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }

/* ── Utilities ── */
.mt0 { margin-top: 0; } .mb0 { margin-bottom: 0; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ── Accounts (Phase 6.4): auth forms + dashboard ── */
.section.narrow .wrap, .wrap.narrow { max-width: 620px; }
.note.ok { border-left-color: var(--ok); }
.badge.warn { background: rgba(255,215,94,.14); color: var(--warn); }
.form { display: flex; flex-direction: column; gap: 4px; margin-top: 16px; }
.form label { font-weight: 600; margin-top: 10px; font-size: .95rem; }
.form input { background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius);
  color: var(--text); padding: 11px 13px; font: inherit; }
.form input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.form .btn { align-self: flex-start; margin-top: 14px; }

/* ── Licence-key box in the dashboard (Phase 6.5) ── */
.keybox { border: 1px solid var(--border); background: var(--surface2); border-radius: var(--radius); padding: 14px 16px; margin-top: 14px; }
.keybox-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 8px; flex-wrap: wrap; }
.keybox-head .muted { font-size: .82rem; }
.keytext { display: block; font-family: var(--mono, ui-monospace, Consolas, monospace); font-size: .82rem; word-break: break-all;
  background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; margin-bottom: 10px; color: var(--text); }
.btn.sm { padding: 7px 14px; font-size: .85rem; }

/* ── Comments + forum (Phase 6.7–6.9) ── */
.form textarea, .form select { background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius);
  color: var(--text); padding: 11px 13px; font: inherit; resize: vertical; }
.form textarea:focus, .form select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.comments { margin-top: 44px; border-top: 1px solid var(--border); padding-top: 26px; }
.comment { border: 1px solid var(--border); background: var(--surface); border-radius: var(--radius);
  padding: 14px 16px; margin-top: 12px; }
/* Was opacity:.68, which put the moderation notice at 3.2:1 — the least readable
   thing on the page. Dashed border + recessed surface says it without dimming text. */
.comment.pending { border-style: dashed; background: var(--surface2); }
.comment.solved { border-color: var(--ok); }
.comment-meta { margin: 0 0 6px; font-size: .9rem; }
.comment-body p { margin: 0 0 10px; } .comment-body p:last-child { margin-bottom: 0; }
.comment-body blockquote { border-left: 3px solid var(--border); margin: 8px 0; padding: 2px 12px; color: var(--muted); }
.comment-body pre { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px;
  overflow-x: auto; font-size: .85rem; }
.comment-body code { font-family: var(--mono, ui-monospace, Consolas, monospace); font-size: .88em; }
.comment-body ul { margin: 8px 0 8px 20px; }

/* "Was this page helpful?" prompt above the comments (WEB_FEATURES_PLAN C3). */
.helpful { border: 1px solid var(--border); border-radius: 12px; background: var(--surface2);
  padding: 16px 18px; margin: 34px 0 8px; }
.helpful-q { font-weight: 700; margin: 0 0 4px; }
.helpful-b { margin: 0 0 12px; font-size: .9rem; }
.helpful .cta-row { display: flex; flex-wrap: wrap; gap: 10px; margin: 0; }

/* ── Keepsake Assist (WEB_FEATURES_PLAN D6) ─────────────────────────────────── */
/* Hidden until <html class="js"> — the panel is built by script, so a launcher
   without script is a button that does nothing. */
.ka-launch { display: none; }
.js .ka-launch { display: inline-flex; align-items: center; gap: 8px; position: fixed;
  right: 18px; bottom: 18px; z-index: 190; padding: 11px 16px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--accent-btn); color: #fff;
  font: 600 .92rem var(--font); cursor: pointer; box-shadow: 0 10px 30px rgba(0,0,0,.35); }
.js .ka-launch:hover { background: var(--accent-btn-hover); }
.ka-launch:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.ka-panel { position: fixed; right: 18px; bottom: 76px; z-index: 195;
  width: min(390px, calc(100vw - 28px)); max-height: min(620px, calc(100vh - 110px));
  display: flex; flex-direction: column; background: var(--surface);
  border: 1px solid var(--border); border-radius: 14px; overflow: hidden;
  box-shadow: 0 24px 60px rgba(0,0,0,.45); }
.ka-panel[hidden] { display: none; }
.ka-head { display: flex; justify-content: space-between; align-items: center;
  padding: 12px 14px; border-bottom: 1px solid var(--border); background: var(--surface2); }
.ka-close { background: transparent; border: 0; color: var(--muted); cursor: pointer;
  font-size: 1rem; padding: 4px 8px; border-radius: 6px; }
.ka-close:hover { color: var(--text); }
.ka-log { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.ka-msg p { margin: 0 0 6px; font-size: .92rem; line-height: 1.55; }
.ka-msg p:last-child { margin-bottom: 0; }
.ka-bot { align-self: flex-start; max-width: 96%; }
.ka-you { align-self: flex-end; max-width: 88%; background: var(--accent-soft);
  border: 1px solid var(--border); border-radius: 12px; padding: 8px 11px; }
.ka-note { color: var(--muted); font-size: .82rem; }
.ka-links { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 8px; }
.ka-chip { display: inline-block; padding: 6px 11px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface2); color: var(--text);
  font: 500 .84rem var(--font); text-decoration: none; cursor: pointer; }
.ka-chip:hover { border-color: var(--accent); color: var(--text); }
.ka-chip:disabled { opacity: .5; cursor: default; }
.ka-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ka-ask { display: flex; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--border); }
.ka-input { flex: 1; background: var(--bg); border: 1px solid var(--border); border-radius: 9px;
  color: var(--text); font: 400 .92rem var(--font); padding: 9px 11px; }
.ka-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.ka-send { border: 0; border-radius: 9px; background: var(--accent-btn); color: #fff;
  padding: 0 14px; font-size: 1rem; cursor: pointer; }
.ka-foot { margin: 0; padding: 0 12px 11px; color: var(--muted); font-size: .76rem; }
.ka-form { display: flex; flex-direction: column; gap: 8px; width: 100%; }
.ka-form input, .ka-form textarea { background: var(--bg); border: 1px solid var(--border);
  border-radius: 9px; color: var(--text); font: 400 .9rem var(--font); padding: 8px 10px; width: 100%; }
.ka-incl-row { display: flex; align-items: center; gap: 8px; margin: 0; }
.ka-incl-row input { width: auto; }
.ka-incl { font-size: .84rem; color: var(--muted); }
.ka-tx summary { cursor: pointer; font-size: .82rem; color: var(--muted); }
.ka-tx pre { white-space: pre-wrap; font-size: .78rem; color: var(--muted);
  max-height: 150px; overflow: auto; margin-top: 6px; }
@media (max-width: 480px) {
  .js .ka-launch { right: 12px; bottom: 12px; padding: 10px 14px; }
  .ka-launch-label { display: none; }
  .ka-panel { right: 8px; left: 8px; bottom: 70px; width: auto; }
}
@media (prefers-reduced-motion: no-preference) {
  .ka-panel.open { animation: ka-in .16s ease-out; }
  @keyframes ka-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
}

/* Help videos (WEB_FEATURES_PLAN E5). */
.vid h2 { margin-top: 0; }
.chapters { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.chapters button { display: flex; gap: 12px; align-items: baseline; width: 100%; text-align: left;
  background: transparent; border: 1px solid transparent; border-radius: 8px; padding: 7px 10px;
  color: var(--text); font: 400 .92rem var(--font); cursor: pointer; }
.chapters button:hover { background: var(--surface2); border-color: var(--border); }
.chapters button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.chapters .t { color: var(--accent); font-variant-numeric: tabular-nums; font-size: .86rem; min-width: 3.2em; }
.transcript h4 { margin: 14px 0 4px; font-size: .95rem; }
.transcript p { color: var(--muted); font-size: .92rem; margin: 0; }

/* Initials avatars (F8) — deterministic hue from the account id, no third-party request. */
.avatar { display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%; margin-right: 8px; flex: 0 0 auto;
  font-size: .72rem; font-weight: 700; letter-spacing: .3px; vertical-align: -7px;
  color: hsl(var(--h) 70% 88%); background: hsl(var(--h) 46% 26%);
  border: 1px solid hsl(var(--h) 46% 38%); }
/* Light needs a darker ink on a paler disc. Written as two blocks, mirroring how every
   other token in this file is applied — a media query is not valid inside a selector list,
   and CSS fails that silently by dropping the whole rule. */
:root[data-theme="light"] .avatar {
  color: hsl(var(--h) 62% 22%); background: hsl(var(--h) 62% 90%); border-color: hsl(var(--h) 45% 74%); }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .avatar {
    color: hsl(var(--h) 62% 22%); background: hsl(var(--h) 62% 90%); border-color: hsl(var(--h) 45% 74%); }
}
.comment-meta a { text-decoration: none; }
.comment-meta a:hover strong { text-decoration: underline; }

/* One upvote per post (F10). */
.votebar { margin: 10px 0 0; }
.votebtn { display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  background: var(--surface2); border: 1px solid var(--border); border-radius: 999px;
  color: var(--text); font: 500 .84rem var(--font); padding: 4px 12px; }
.votebtn:hover { border-color: var(--accent); }
.votebtn.on { background: var(--accent-soft); border-color: var(--accent); }
.votebtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.threadlist { list-style: none; padding: 0; margin: 10px 0 0; display: flex; flex-direction: column; gap: 8px; }
.vidgroup { margin: 40px 0 4px; font-size: 1.05rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); font-weight: 700; }
.vidgroup:first-of-type { margin-top: 26px; }

/* ── Answer-first block (docs/SEO_AEO_GEO_PLAN.md, A1) ───────────────────────
   Sits directly under the H1 and holds 40–70 words that answer the page's question
   standing alone. Styled as a quote rather than a callout on purpose: it IS a pull
   quote — the sentence an answer engine will lift, shown to the reader in the same
   shape it will be lifted in. `.answer-text` is the selector named by the page's
   `speakable` markup, so the two can never point at different words. */
.answer-box { border-left: 3px solid var(--accent); background: var(--accent-soft);
  border-radius: 0 var(--radius) var(--radius) 0; padding: 16px 20px; margin: 22px auto 30px;
  max-width: 46em; text-align: left; }
.answer-box .answer-q { color: var(--accent); font-weight: 700; font-size: .82rem;
  letter-spacing: .06em; text-transform: uppercase; margin: 0 0 8px; }
.answer-box .answer-text { margin: 0; font-size: 1.04rem; line-height: 1.62; }
.answer-box .answer-more { margin: 10px 0 0; font-size: .9rem; }

/* ── /faq and /search ───────────────────────────────────────────────────────── */
.faq-group { margin-top: 34px; }
.faq-group > h2 { font-size: 1.15rem; }
.faq-group > p.muted { margin-top: -4px; }
.searchbar { display: flex; gap: 10px; max-width: 560px; margin: 0 auto; }
.searchbar input[type=search] { flex: 1; }
.search-hit { padding: 14px 0; border-bottom: 1px solid var(--border); }
.search-hit:last-child { border-bottom: 0; }
.search-hit h3 { font-size: 1rem; margin: 0 0 4px; }
.search-hit p { margin: 0; font-size: .9rem; color: var(--muted); }
.search-hit .u { font-size: .8rem; color: var(--accent); }

/* Jump index on /faq. The first group needs no top margin — it already sits under the
   hero's own padding, and the two together read as a layout mistake. */
.faq-jump { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center;
  max-width: 780px; margin: 24px auto 0; }
.faq-jump a { font-size: .84rem; text-decoration: none; color: var(--muted);
  border: 1px solid var(--border); border-radius: 999px; padding: 5px 12px;
  background: var(--surface); }
.faq-jump a:hover { border-color: var(--accent); color: var(--accent); }
.faq-group:first-of-type { margin-top: 0; }
/* On a 390px screen the 14 chips filled the entire first viewport before any question was
   visible. Smaller and tighter, so the index is still the first thing you see and the
   content starts within the same screen. */
@media (max-width: 560px) {
  .faq-jump { gap: 6px; margin-top: 18px; }
  .faq-jump a { font-size: .76rem; padding: 4px 9px; }
}

/* The header row. "Open Web App" wrapped onto two lines from about 1300px down, because the
   bar gained a search launcher and a theme toggle after it was laid out. nowrap alone just
   moved the squeeze onto the brand: its text then overflowed its own box by exactly the 28px
   flex gap, so "Keepsake" and "Features" touched with no space between them. A logo and a
   call-to-action must never be the things that compress — both get flex-shrink:0, the gaps
   give back the width, and below 1000px the nav is the burger (see above).
   Measured at 1440/1280/1180/1000, not eyeballed. */
.site-header .brand { flex-shrink: 0; }
.site-nav .btn { white-space: nowrap; flex-shrink: 0; }
@media (min-width: 1001px) {
  .site-header .bar { gap: 20px; }
  .site-nav { gap: 18px; }
}
