/* styles.css -- one calm, dark-friendly sheet for every page: the product
   (index.html), the health check, and the trust page. Colors come from
   prefers-color-scheme so all of them read well in both themes without any
   script involvement. The product page's state machine lives at the bottom:
   panels show or hide purely from body[data-state], so main.js has exactly
   one visibility write point and this sheet documents what is visible when. */

:root {
  color-scheme: light dark;
  --bg: #f7f7f5;
  --fg: #1c1c1a;
  --muted: #6b6b66;
  --card: #ffffff;
  --ok: #1a7f37;
  --fail: #b42318;
  --warn: #9a6700;
  --border: #e2e2de;
  --accent: #1f5eff;
  --accent-fg: #ffffff;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #141416;
    --fg: #e8e8e4;
    --muted: #9a9a94;
    --card: #1e1e21;
    --ok: #4ade80;
    --fail: #f87171;
    --warn: #fbbf24;
    --border: #2c2c30;
    --accent: #6491ff;
    --accent-fg: #10131c;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 16px/1.55 system-ui, -apple-system, "Segoe UI", sans-serif;
  min-height: 100vh;
  /* dvh tracks the real visible height as mobile URL bars collapse; older
     browsers ignore this line and keep the vh fallback above. */
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

main {
  max-width: 44rem;
  width: 100%;
  margin: 0 auto;
  padding: 3rem 1.25rem 2rem;
  flex: 1;
}

h1 { margin: 0 0 0.25rem; font-size: 1.6rem; }
h2 { font-size: 1.1rem; margin: 2rem 0 0.75rem; }
.tagline { margin: 0; color: var(--muted); }
.muted { color: var(--muted); }
.small { font-size: 0.85rem; }
.trust-line { margin: 0; color: var(--muted); }
.trust-line a { color: inherit; }
a { color: var(--accent); }

/* ------------------------------------------------------------- health page */

#status {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  overflow: hidden;
}

#status li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 0.9rem;
  border-bottom: 1px solid var(--border);
}

#status li:last-child { border-bottom: none; }
#status .verdict { font-variant-numeric: tabular-nums; white-space: nowrap; }
#status .ok .verdict { color: var(--ok); }
#status .fail .verdict { color: var(--fail); }
#status .pending { color: var(--muted); }

/* -------------------------------------------------------------- trust page */

.prose h2 { margin-top: 1.75rem; }
.prose p, .prose li { max-width: 40rem; }
.backlink { margin-top: 2.5rem; }
.backlink a { color: var(--muted); }

/* ----------------------------------------------------------------- buttons */

button {
  font: inherit;
  color: var(--fg);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.45rem 1rem;
  cursor: pointer;
}

button:hover:not(:disabled) { border-color: var(--muted); }
button:disabled { opacity: 0.5; cursor: default; }

button.primary {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: transparent;
}

button.big { font-size: 1.15rem; padding: 0.7rem 2.2rem; }

button.danger { border-color: var(--fail); color: var(--fail); background: transparent; }

button.quiet { background: transparent; border-color: transparent; color: var(--muted); }
button.quiet:hover:not(:disabled) { color: var(--fg); }

/* ----------------------------------------------------------------- banners */

.banner {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  padding: 0.7rem 0.9rem;
  margin: 1.25rem 0 0;
}

.banner-error { border-color: var(--fail); }
.banner-warning { border-color: var(--warn); }
.banner-notice { border-color: var(--border); }
.banner-actions { display: inline-flex; gap: 0.5rem; margin-left: 0.75rem; }
[hidden] { display: none !important; }

/* ------------------------------------------------------------------ panels */

.panel { margin-top: 1.75rem; }

/* idle */
#record-button { display: block; margin: 0.5rem 0 1.25rem; }
.steps { margin: 0; padding-left: 1.25rem; color: var(--muted); }
.steps li { margin: 0.25rem 0; }

/* mode picker */
#mode-picker {
  border: none;
  margin: 0 0 1.25rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
#mode-picker legend {
  padding: 0;
  margin-bottom: 0.35rem;
  font-weight: 600;
}
.mode-card {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  padding: 0.6rem 0.8rem;
  cursor: pointer;
}
/* Selection is a class ui.js toggles (not :has) so the harness can assert it
   and the styling stays inspectable. */
.mode-card.selected { border-color: var(--accent); }
.mode-card.disabled { opacity: 0.55; cursor: default; }
.mode-card input[type='radio'] { margin-top: 0.2rem; flex: none; }
.mode-text { display: flex; flex-direction: column; gap: 0.15rem; }
.mode-label { font-weight: 600; }
.mode-desc { color: var(--muted); font-size: 0.9rem; }
#mic-extras { padding: 0.1rem 0.2rem 0; }

/* quality tiers (consent dialog) -- shares the mode-card anatomy */
#tier-list { display: flex; flex-direction: column; gap: 0.5rem; margin: 0.75rem 0; }
.tier-card {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  padding: 0.55rem 0.75rem;
  cursor: pointer;
}
.tier-card.selected { border-color: var(--accent); }
.tier-card input[type='radio'] { margin-top: 0.2rem; flex: none; }
.tier-badge {
  border: 1px solid var(--accent);
  border-radius: 999px;
  color: var(--accent);
  font-size: 0.75rem;
  font-weight: 400;
  padding: 0.05rem 0.5rem;
  white-space: nowrap;
}
.tier-size { font-size: 0.85rem; }
#quality-line { margin: -0.75rem 0 1rem; }
#quality-line .quiet { padding: 0.1rem 0.4rem; }
.ns-row { display: flex; align-items: flex-start; gap: 0.5rem; color: var(--muted); }
.ns-row input { margin-top: 0.2rem; flex: none; }
#mic-phone-note { margin: 0.5rem 0 0; }

/* my calls */
#calls-section { margin-top: 2rem; }
#calls-section h2 { margin: 0 0 0.5rem; }
.calls-list { list-style: none; margin: 0 0 0.5rem; padding: 0; }
.call-item {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  padding: 0.6rem 0.8rem;
  margin: 0 0 0.5rem;
}
.call-main { display: flex; align-items: baseline; gap: 0.5rem; flex-wrap: wrap; }
.call-label { font-weight: 600; }
.call-badge {
  border: 1px solid var(--warn);
  border-radius: 999px;
  color: var(--warn);
  font-size: 0.75rem;
  padding: 0.05rem 0.5rem;
  white-space: nowrap;
}
.call-badge-past { border-color: var(--muted); color: var(--muted); }
.call-moment { flex-basis: 100%; }
.call-actions { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-top: 0.45rem; }
.call-actions button { padding: 0.25rem 0.7rem; font-size: 0.9rem; }
.call-actions .call-arm { border-color: var(--accent); color: var(--accent); background: transparent; }

/* server recorder */
#recorder-section { margin-top: 2rem; }
#recorder-section h2 { margin: 0 0 0.5rem; }
#recorder-token-row { display: flex; gap: 0.6rem; align-items: flex-end; flex-wrap: wrap; }
#recorder-token-row .field { flex: 1 1 14rem; margin-top: 0; }
#recorder-token-row p { flex-basis: 100%; }
#recorder-start { margin-top: 0.6rem; }
#recorder-jobs { margin-top: 0.75rem; }
.recorder-job-note { margin: 0.2rem 0 0; }

/* per-call prep expander */
.call-prep {
  border-left: 2px solid var(--border);
  margin-top: 0.5rem;
  padding: 0.2rem 0 0.2rem 0.7rem;
}
.call-prep p { margin: 0.2rem 0; }
.call-prep-heading { font-size: 0.9rem; font-weight: 600; }
.call-prep .call-transcript-button { margin: 0.35rem 0; padding: 0.25rem 0.7rem; font-size: 0.9rem; }

/* official-transcript dialog */
#transcript-dialog { max-width: min(38rem, calc(100vw - 2rem)); }
#transcript-dialog-body {
  max-height: min(24rem, 55dvh);
  overflow-y: auto;
  margin-top: 0.6rem;
}
.transcript-turn-head { font-weight: 600; font-size: 0.9rem; margin: 0.7rem 0 0.15rem; }
.transcript-turn-body { margin: 0; white-space: pre-wrap; }

/* add/edit call dialog */
.field { display: flex; flex-direction: column; gap: 0.2rem; margin: 0.6rem 0 0; }
.field > span { font-size: 0.85rem; color: var(--muted); }
.field input, .field select, .field textarea {
  font: inherit;
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.35rem 0.5rem;
}
.field textarea { resize: vertical; }
.field-row { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.field-row .field { flex: 1 1 8rem; margin-top: 0.6rem; }
#call-dialog .ns-row { margin-top: 0.75rem; }
#call-extract { margin-top: 0.4rem; }
.form-error { color: var(--fail); }

/* armed-call countdown */
#armed-call-label { margin: 0; font-weight: 600; }
#armed-call-countdown {
  margin: 0.15rem 0 0.35rem;
  font-size: 1.5rem;
  font-variant-numeric: tabular-nums;
}
#armed-call { margin-bottom: 1rem; }

/* consent dialog */
dialog {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card);
  color: var(--fg);
  max-width: 26rem;
  /* 26rem is wider than a phone; never exceed the viewport minus margins. */
  max-width: min(26rem, calc(100vw - 2rem));
  padding: 1.25rem 1.5rem;
}
dialog::backdrop { background: rgba(0, 0, 0, 0.45); }
dialog h2 { margin-top: 0; }
.dialog-actions { display: flex; justify-content: flex-end; gap: 0.6rem; margin-top: 1.25rem; }

/* downloading */
#download-progress { width: 100%; height: 0.8rem; accent-color: var(--accent); }

/* capturing header strip */
.cap-header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  padding: 0.55rem 0.9rem;
}

#rec-dot {
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  background: var(--fail);
  flex: none;
  animation: rec-pulse 1.6s ease-in-out infinite;
}

@keyframes rec-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

@media (prefers-reduced-motion: reduce) {
  #rec-dot { animation: none; }
}

#cap-elapsed { font-variant-numeric: tabular-nums; }
#cap-source { color: var(--muted); flex: 1; min-width: 10rem; }
/* CSS owns the meter's ELEMENT size so ui.js can scale the canvas backing
   store by devicePixelRatio without growing the element (crisp on 3x). */
#cap-meter { flex: none; width: 120px; height: 14px; }
#wake-note { margin: 0.5rem 0 0; }

/* transcript: black committed paragraphs, grey growing partial line */
#transcript {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  padding: 0.9rem 1.1rem;
  max-height: 24rem;
  /* On a phone screen the Stop button and the transcript must coexist;
     55dvh caps the pane to the visible viewport. Older browsers keep 24rem. */
  max-height: min(24rem, 55dvh);
  overflow-y: auto;
  overflow-wrap: anywhere;
}
.gap-note { color: var(--muted); font-style: italic; }

#transcript p { margin: 0 0 0.7rem; }
#transcript p:last-child { margin-bottom: 0; }
#transcript .stamp {
  color: var(--muted);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}
#transcript .partial { color: var(--muted); }

/* review */
#review-summary { font-size: 1.1rem; }
.review-note { color: var(--muted); font-size: 0.9rem; }
.review-actions { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-top: 1rem; }

/* review insights: the machine-made extras under the save buttons */
#cleanup-row { margin-top: 1.25rem; }
#review-insights h3 { font-size: 1rem; margin: 1.5rem 0 0.15rem; }
#review-insights .muted.small { margin: 0 0 0.35rem; }
.insight-list { margin: 0.35rem 0 0; padding-left: 1.25rem; }
.insight-list li { margin: 0.3rem 0; }
.insight-list .stamp {
  color: var(--muted);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}
.cited-group { margin-top: 0.75rem; }
.cited-label { margin: 0; font-weight: 600; }

/* ------------------------------------------------------------------ footer */

footer {
  max-width: 44rem;
  width: 100%;
  margin: 0 auto;
  padding: 1rem 1.25rem 1.5rem;
  display: flex;
  gap: 1.25rem;
}

footer a { color: var(--muted); font-size: 0.85rem; text-decoration: none; }
footer a:hover { text-decoration: underline; }

/* ------------------------------------------------------------------- mobile */

/* Touch targets: pointer-based (the correct trigger -- a small window on a
   desktop is not a touch device), lifting every button to the 44px floor. */
@media (pointer: coarse) {
  button { min-height: 2.75rem; touch-action: manipulation; }
}

@media (max-width: 480px) {
  main { padding: 1.5rem 1rem; }
  h1 { font-size: 1.35rem; }
  .review-actions button { flex: 1 1 12rem; }
}

/* Home-indicator clearance when installed standalone on iOS; degrades to the
   plain padding wherever env() is unsupported or the inset is zero. */
footer { padding-bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px)); }

/* ----------------------------------------------- product page state machine
   idle -> consent -> downloading -> armed -> capturing -> review.
   The consent state keeps the idle panel visible beneath the modal dialog so
   the page does not blank out behind it. The transcript panel spans
   capturing AND review: the transcript is the product, so it stays on screen
   after Stop while the summary appears above it. */

.panel { display: none; }

body[data-state="idle"] #panel-idle,
body[data-state="consent"] #panel-idle,
body[data-state="downloading"] #panel-downloading,
body[data-state="armed"] #panel-armed,
body[data-state="capturing"] #panel-capturing,
body[data-state="capturing"] #panel-transcript,
body[data-state="review"] #panel-review,
body[data-state="review"] #panel-transcript {
  display: block;
}

/* ------------------------------------------------- the mechanical deck (P16)
   Shared classes with the standalone export document (deck-render.js writes
   both); here they ride the app's own theme variables. */

#deck-live { margin-top: 12px; }
#deck-live summary { cursor: pointer; color: var(--muted); }

.deck-pane .deck-slide {
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--card);
  padding: 16px 20px;
  margin: 12px 0;
}
.deck-pane .deck-slide h2 { margin: 0 0 4px; font-size: 1.15em; }
.deck-pane .deck-slide h3 { margin: 0 0 10px; font-size: 1em; }
.deck-muted { color: var(--muted); font-size: 0.85em; }
.deck-tiles { display: flex; flex-wrap: wrap; gap: 10px; }
.deck-tile {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
  min-width: 110px;
  flex: 1 1 130px;
}
.deck-tile-value { font-size: 1.2em; font-weight: 600; }
.deck-tile-label { color: var(--muted); font-size: 0.78em; margin-top: 2px; }
.deck-chart { width: 100%; height: auto; display: block; }
.deck-bar { fill: var(--accent); }
.deck-bar-range { opacity: 0.55; }
.deck-bar-tick, .deck-axis { stroke: var(--fg); stroke-width: 1; }
.deck-axis { opacity: 0.4; }
.deck-bar-label { fill: var(--fg); font-size: 12px; font-weight: 600; }
.deck-captions { margin: 8px 0 0; padding-left: 22px; color: var(--muted); font-size: 0.82em; }
.deck-captions strong { color: var(--fg); }
.deck-quote { margin: 0; border-left: 3px solid var(--accent); padding-left: 12px; }
.deck-list { margin: 0; padding-left: 20px; }

/* ----------------------------------------------- timestamped notes (P16)
   The third ink: the user's own words, visually unmistakable next to the
   committed (plain) and refined (polished) inks. */

.note-row { margin: 0 0 8px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
#note-bar { display: inline-flex; gap: 6px; flex: 1; align-items: center; }
#note-bar[hidden] { display: none; }
#note-input { flex: 1; min-width: 160px; }
.user-note { border-left: 3px solid var(--warn); padding-left: 10px; font-style: italic; }
.user-note .user-note-label { color: var(--warn); font-style: normal; font-weight: 600; }

/* -------------------------------------------------- the fact check (P18)
   Three verdicts and nothing else: differing statements read loud, support
   reads calm, unverifiable reads muted -- no scores anywhere. */

.factcheck-row { margin-bottom: 8px; }
.factcheck-verdict { font-weight: 700; text-transform: uppercase; font-size: 0.78em; letter-spacing: 0.04em; }
.factcheck-supports .factcheck-verdict { color: var(--ok); }
.factcheck-differs .factcheck-verdict { color: var(--fail); }
.factcheck-unverifiable .factcheck-verdict { color: var(--muted); }
.factcheck-quote { margin-left: 12px; }
