/* Rookery — editorial UI. Newsreader (serif headlines) + Inter (UI) + IBM Plex Mono.
   ~All colours flow through these vars; [data-theme="dark"] re-skins the whole app. */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  color-scheme: light;
  --bg: #f7f5f0;
  --surface: #ffffff;
  --surface-2: #f2efe8;
  --border: #e3e0d8;
  --text: #17191e;
  --muted: #6a6f78;
  --accent: #244b7a;
  --accent-light: #e9eef5;

  --serif: 'Newsreader', Georgia, 'Times New Roman', serif;
  --sans: 'Inter', system-ui, -apple-system, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', monospace;

  --ok: #1f7a4d;   --ok-light: #e6f3ec;
  --warn: #a15c07; --warn-light: #fbf0dc;
  --err: #c0392b;  --err-light: #fbeae7;  --err-border: #eecac3;
  --danger: #c0392b;

  --state-capturing: #244b7a;
  --state-syncing: #1d4ed8;
  --state-done: #6b7280;
  --state-failed: #c0392b;
  --state-pending: #a15c07;
  --state-offline: #cfccc4;

  --shadow: 0 1px 2px rgba(20,22,28,0.05), 0 1px 3px rgba(20,22,28,0.04);
  --nav-h: 62px;
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #14161b;
  --surface: #1d2027;
  --surface-2: #242832;
  --border: #2d323c;
  --text: #e9e7e1;
  --muted: #969ca6;
  --accent: #6ba3e0;
  --accent-light: #1e3450;

  --ok: #57b487;   --ok-light: #16281f;
  --warn: #d59433; --warn-light: #2c2214;
  --err: #e5776a;  --err-light: #2c1a18;  --err-border: #4a2a26;
  --danger: #e5776a;

  --state-syncing: #6ba3e0;
  --state-offline: #3a3f49;

  --shadow: 0 1px 2px rgba(0,0,0,0.4), 0 1px 3px rgba(0,0,0,0.3);
}

body {
  font-family: var(--sans);
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--serif); font-weight: 600; letter-spacing: -0.01em; line-height: 1.2; }

/* ── Top navigation ─────────────────────────────────────────────────────────── */

.topnav {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in srgb, var(--surface) 72%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
}
/* Solid fallback where backdrop-filter isn't supported (keeps text legible) */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .topnav { background: var(--surface); }
}
.topnav-inner { max-width: 1180px; margin: 0 auto; height: var(--nav-h); display: flex; align-items: center; gap: 1.25rem; padding: 0 1.25rem; }

.brand { display: flex; flex-direction: column; align-items: center; gap: 0; text-decoration: none; white-space: nowrap; line-height: 1;
  border: 1px solid var(--border); border-radius: 10px; padding: 0.38rem 1rem 0;
  background: var(--bg); }
.brand-name { font-family: var(--serif); font-size: 2.15rem; font-weight: 700; color: var(--text); letter-spacing: -0.02em; }
.brand-name .ac { color: var(--accent); }
/* Subtitle straddles the bottom border: translateY(50%) drops its centre onto the line;
   the surface-coloured mask breaks the line at the text so it doesn't strike the glyphs.
   Negative margin-top pulls it snug under PressNest. */
.brand-sub { font-family: var(--mono); font-size: 0.62rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.14em; color: var(--muted);
  margin-top: -5px; transform: translateY(50%); padding: 0 0.45rem; background: var(--bg); }

/* Auth pages (login/signup): same boxed wordmark, but larger and sitting on the page
   background — no surface fill (the box is just the bordered rect), so the mask that
   breaks the border under the subtitle must match --bg too. */
.auth-wrap .brand { background: var(--bg); padding: 0.5rem 1.4rem 0; }
.auth-wrap .brand-name { font-size: 2.9rem; }
.auth-wrap .brand-sub { background: var(--bg); font-size: 0.74rem; margin-top: -7px; }

.nav-links { display: flex; align-items: center; gap: 0.15rem; }
.nav-links a { font-size: 0.86rem; color: var(--muted); text-decoration: none; padding: 0.4rem 0.7rem; border-radius: 6px; transition: color 0.12s, background 0.12s; white-space: nowrap; }
.nav-links a:hover { color: var(--text); background: var(--accent-light); }
.nav-links a.active { color: var(--accent); font-weight: 600; }

/* Hover dropdown: Dashboard → content types */
.nav-drop { position: relative; }
.nav-drop > a::after { content: none; }
.nav-submenu {
  display: none; position: absolute; top: 100%; left: 0; min-width: 250px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: var(--shadow); padding: 0.3rem; z-index: 120;
}
.nav-drop:hover .nav-submenu, .nav-drop:focus-within .nav-submenu { display: block; }
.nav-submenu a { display: block; padding: 0.45rem 0.6rem; border-radius: 5px; font-size: 0.85rem; color: var(--text); white-space: nowrap; }
.nav-submenu a:hover { background: var(--accent-light); color: var(--accent); }
.nav-add { padding: 0.36rem 0.7rem; font-size: 0.82rem; }

/* Admin "view as member" preview toggle */
.view-toggle { display: inline-flex; align-items: center; justify-content: center; height: 34px; min-width: 34px; box-sizing: border-box; font-family: var(--mono); font-size: 0.82rem; font-weight: 700; color: #fff; background: var(--ok); border: 1px solid var(--ok); border-radius: 6px; text-decoration: none; }
.view-toggle:hover { color: #fff; opacity: 0.9; }
.nav-back { display: inline-flex; align-items: center; justify-content: center; height: 34px; min-width: 34px; box-sizing: border-box; font-size: 1.05rem; color: var(--muted); border: 1px solid var(--border); border-radius: 6px; text-decoration: none; }
.nav-back:hover { color: var(--accent); border-color: var(--accent); }
.view-toggle.previewing { color: #fff; background: var(--warn); border-color: var(--warn); }
.view-toggle.previewing:hover { color: #fff; opacity: 0.9; }

.nav-right { margin-left: auto; display: flex; align-items: center; gap: 0.5rem; }

.theme-toggle { background: none; border: 1px solid var(--border); border-radius: 6px; width: 34px; height: 34px; cursor: pointer; color: var(--muted); font-size: 0.95rem; line-height: 1; display: inline-flex; align-items: center; justify-content: center; }
.theme-toggle:hover { color: var(--accent); border-color: var(--accent); }

.user-menu { position: relative; }
.user-menu > summary { list-style: none; cursor: pointer; font-size: 0.8rem; color: var(--muted); height: 34px; padding: 0 0.6rem; border: 1px solid var(--border); border-radius: 6px; max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-flex; align-items: center; }
.user-menu > summary::-webkit-details-marker { display: none; }
.user-menu[open] > summary { color: var(--text); border-color: var(--accent); }
.user-menu-pop { position: absolute; right: 0; top: calc(100% + 6px); background: var(--surface); border: 1px solid var(--border); border-radius: 8px; box-shadow: var(--shadow); min-width: 160px; padding: 0.3rem; display: flex; flex-direction: column; z-index: 110; }
.user-menu-pop a { font-size: 0.85rem; color: var(--text); text-decoration: none; padding: 0.45rem 0.6rem; border-radius: 5px; }
.user-menu-pop a:hover { background: var(--accent-light); color: var(--accent); }

.hamburger { display: none; background: none; border: 1px solid var(--border); border-radius: 6px; width: 34px; height: 34px; color: var(--text); cursor: pointer; align-items: center; justify-content: center; padding: 0; -webkit-tap-highlight-color: transparent; }
.hamburger.open { border-color: var(--accent); color: var(--accent); }   /* matches the open drawer's accent edge */
/* Three bars that morph to an X. Each bar animates independently so the change reads clearly. */
.ham-box { position: relative; display: block; width: 18px; height: 14px; }
.ham-box span { position: absolute; left: 0; width: 100%; height: 2px; border-radius: 2px; background: currentColor;
  transition: transform 0.28s cubic-bezier(0.4,0,0.2,1), opacity 0.18s ease, top 0.28s cubic-bezier(0.4,0,0.2,1); }
.ham-box span:nth-child(1) { top: 0; }
.ham-box span:nth-child(2) { top: 6px; }
.ham-box span:nth-child(3) { top: 12px; }
.hamburger.open .ham-box span:nth-child(1) { top: 6px; transform: rotate(45deg); }
.hamburger.open .ham-box span:nth-child(2) { opacity: 0; transform: scaleX(0.2); }
.hamburger.open .ham-box span:nth-child(3) { top: 6px; transform: rotate(-45deg); }

.nav-drawer { display: none; flex-direction: column; padding: 0.5rem 1.25rem 1rem; background: var(--surface); border-bottom: 1px solid var(--border); }
.nav-drawer a { font-size: 0.95rem; color: var(--text); text-decoration: none; padding: 0.6rem 0.4rem; border-radius: 6px; }
.nav-drawer a:hover { background: var(--accent-light); color: var(--accent); }
.nav-drawer .drawer-sep { height: 1px; background: var(--border); margin: 0.4rem 0; }

/* ── Page container + footer ────────────────────────────────────────────────── */

.page { max-width: 1040px; margin: 0 auto; padding: 1.75rem 1.25rem 3rem; }
.site-footer { max-width: 1040px; margin: 0 auto; padding: 1.75rem 1.25rem 2.5rem; font-family: var(--mono); font-size: 0.82rem; color: var(--muted); border-top: 1px solid var(--border); display: flex; gap: 0.6rem; align-items: baseline; flex-wrap: wrap; }
.site-footer a { color: var(--muted); text-decoration: none; }
.site-footer a:hover { color: var(--accent); }

.auth-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 2rem 1rem; flex-direction: column; }

/* Nav search box */
.nav-search input {
  font-family: var(--sans);
  font-size: 0.82rem;
  height: 34px;
  padding: 0 0.65rem;
  width: 150px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--surface);
  color: var(--text);
  transition: width 0.15s ease, border-color 0.12s;
}
.nav-search input:focus { outline: none; border-color: var(--accent); width: 200px; }
.drawer-search { margin-bottom: 0.5rem; }
.drawer-search input {
  width: 100%;
  font-family: var(--sans);
  font-size: 0.95rem;
  padding: 0.55rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--surface);
  color: var(--text);
}

/* Dashboard header row (title + accuracy chip) */
.dash-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.dash-head h1 { font-size: 2.1rem; }
.accuracy-chip {
  font-family: var(--mono); font-size: 0.75rem; color: var(--muted);
  display: inline-flex; align-items: center; gap: 0.45rem;
  border: 1px solid var(--border); border-radius: 999px; padding: 0.32rem 0.8rem; background: var(--surface);
}
.accuracy-chip b { font-weight: 700; color: var(--text); }

@media (max-width: 640px) { .hide-narrow { display: none !important; } }

@media (max-width: 820px) {
  /* Collapse to the hamburger drawer; +Add and the brand tagline are in there too, so drop
     them from the bar to keep it narrow (it was overflowing on large phones). */
  .nav-links, .user-menu, .nav-search, .nav-add, .brand-sub { display: none; }
  .hamburger { display: inline-flex; }
  /* The drawer is a panel anchored just under the top bar (so it reads as the hamburger's menu),
     sliding down + fading in. It's always in the DOM now — hidden via transform/opacity so it can
     animate — and scrolls internally if the list is long. */
  .nav-drawer {
    display: flex;
    position: absolute; top: 100%; left: 0; right: 0;
    max-height: calc(100dvh - var(--nav-h)); overflow-y: auto;
    transform: translateY(-10px); opacity: 0; visibility: hidden; pointer-events: none;
    box-shadow: 0 12px 24px rgba(0,0,0,0.18);
    transition: transform 0.26s cubic-bezier(0.4,0,0.2,1), opacity 0.26s ease, visibility 0s linear 0.26s;
    z-index: 90;   /* below the sticky bar (100) so it appears to drop from underneath it */
  }
  .nav-drawer.open {
    transform: translateY(0); opacity: 1; visibility: visible; pointer-events: auto;
    transition: transform 0.26s cubic-bezier(0.4,0,0.2,1), opacity 0.26s ease;
  }
}

/* ── Card ─────────────────────────────────────────────────────────────────── */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  width: 100%;
  padding: 1.5rem 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  box-shadow: var(--shadow);
}

.card + .card { margin-top: 1.25rem; }

/* Readable body copy — one spaced paragraph per source line (articles, releases, …) */
.body-read { font-size: 1rem; line-height: 1.65; margin-top: 0.75rem; }
.body-read p { margin: 0 0 0.9em; }
.body-read p:last-child { margin-bottom: 0; }

.card-narrow { max-width: 580px; margin-left: auto; margin-right: auto; }
.card-wide { max-width: 900px; margin-left: auto; margin-right: auto; }

/* Radio pill group (e.g. VOD | Live) */
.radio-row { display: inline-flex; border: 1px solid var(--border); border-radius: 7px; overflow: hidden; }
.radio-pill { display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.45rem 1.1rem; cursor: pointer; font-size: 0.9rem; font-weight: 500; color: var(--muted); background: var(--surface); }
.radio-pill + .radio-pill { border-left: 1px solid var(--border); }
.radio-pill input { accent-color: var(--accent); }
.radio-pill:has(input:checked) { background: var(--accent-light); color: var(--accent); }

/* Collapsible capture-node picker on the new-job form */
.node-details > summary { cursor: pointer; font-family: var(--mono); font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); padding: 0.2rem 0; list-style: none; }
.node-details > summary::-webkit-details-marker { display: none; }
.node-details > summary::before { content: "▸ "; }
.node-details[open] > summary::before { content: "▾ "; }
.node-details > summary:hover { color: var(--accent); }
.node-details .node-grid { margin-top: 0.75rem; }

/* ── Section labels ───────────────────────────────────────────────────────── */

.section-label {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Section label as its own pill, straddling the card's top border (its vertical centre
   sits on the top edge). position:relative keeps the header's flow space; top offsets by
   the card's top padding (1.5rem) and translateY(-50%) by half the pill's own height. */
.section-pill {
  display: inline-flex;
  align-items: center;
  position: relative;
  top: -1.5rem;
  transform: translateY(-50%);
  font-family: var(--mono);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-light);
  border: 1px solid var(--accent);
  padding: 0.35rem 0.85rem;
  border-radius: 999px;
  line-height: 1;
}

.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
/* A straddling pill header's box is visually empty (the pill renders above it), so the
   card's default gap reads as dead space — pull the first item up snug beneath it. Covers
   pill-only headers, pill+action headers, and the pill-nested-in-a-div variants. */
.section-header:has(> .section-pill),
.section-header:has(> div > .section-pill) { margin-bottom: -1.4rem; }

/* Collapsible cards (e.g. /add): click the header to toggle; hash-target opens on load.
   Animation is the grid-template-rows 0fr→1fr trick — browser-optimized and smooth, and
   it slides to the exact content height with no JS measuring or pixel-stepping. */
.collapsible > .section-header { cursor: pointer; }
.collapse-chevron { font-size: 0.8rem; color: var(--muted); transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1); margin-left: auto; }
.collapsible.open .collapse-chevron { transform: rotate(90deg); }
.collapse-body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 1s cubic-bezier(0.4, 0, 0.2, 1); }
.collapsible.open .collapse-body { grid-template-rows: 1fr; }
.collapse-inner { overflow: hidden; min-height: 0; }

/* Topic / tag pills — solid accent fill, white text, with an inline remove × */
.topic-pill { display: inline-flex; align-items: center; gap: 0.3rem; background: var(--accent); color: #fff; font-family: var(--mono); font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; padding: 0.2rem 0.6rem; border-radius: 999px; text-decoration: none; line-height: 1.35; }
/* Dark mode: --accent is a light blue, so white text on it is too low-contrast at this size.
   Use a deeper blue fill so the white text stays crisp. */
:root[data-theme="dark"] .topic-pill { background: #2f5c8f; }
.topic-pill:hover { opacity: 0.9; }
.topic-pill .x { cursor: pointer; opacity: 0.7; font-weight: 700; }

/* Interview headline — larger, and scales down gracefully on phones. */
.job-title { font-size: clamp(1.65rem, 5.5vw, 2.1rem); font-weight: 600; line-height: 1.25; margin-top: 0.35rem; }
/* Person pills: on phones drop the role word (Reporter/Interviewee/PIO/Outlet) so the pills stay
   compact and readable — just the name shows. */
@media (max-width: 640px) {
  .people-pills .role-tag { display: none; }
  .people-pills .topic-pill { font-size: 0.7rem; padding: 0.18rem 0.55rem; }
}
.topic-pill .x:hover { opacity: 1; }

/* Floating "add selection as tag" button — appears above a text selection in the body */
.sel-tag-btn { position: absolute; z-index: 500; background: var(--accent); color: #fff; border: none; border-radius: 7px; font-family: var(--sans); font-size: 0.78rem; font-weight: 600; padding: 0.32rem 0.65rem; cursor: pointer; box-shadow: var(--shadow); white-space: nowrap; display: inline-flex; align-items: center; gap: 0.3rem; }
.sel-tag-btn:hover { opacity: 0.92; }

/* ── Buttons ──────────────────────────────────────────────────────────────── */

.btn {
  font-family: var(--mono);
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 6px;
  padding: 0.75rem 1.5rem;
  cursor: pointer;
  transition: opacity 0.15s, transform 0.1s;
  text-decoration: none;
  display: inline-block;
}

.btn:hover { opacity: 0.88; }
.btn:active { transform: scale(0.99); }
.btn:disabled { opacity: 0.4; cursor: default; }

.btn-sm {
  font-family: var(--mono);
  font-size: 0.72rem;
  padding: 0.3rem 0.75rem;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
  text-decoration: none;
}

.btn-sm:hover { background: var(--accent-light); border-color: var(--accent); color: var(--accent); }
.btn-sm:disabled { opacity: 0.4; cursor: default; pointer-events: none; }

/* Prominent primary action (e.g. "＋ Add content") */
.btn-add {
  font-family: var(--sans);
  font-size: 0.85rem;
  font-weight: 600;
  padding: 0.4rem 0.9rem;
  border-radius: 7px;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: #fff;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: opacity 0.12s;
}
.btn-add:hover { opacity: 0.88; }

/* Modal (in-page, replaces browser popups) */
.modal-overlay { position: fixed; inset: 0; z-index: 1000; background: rgba(0,0,0,0.45); display: flex; align-items: center; justify-content: center; padding: 1.5rem; }
.modal-overlay[hidden] { display: none; }
.modal-card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow); padding: 1.5rem 1.6rem; width: 100%; max-width: 500px; }
.modal-title { font-family: var(--serif); font-size: 1.25rem; font-weight: 700; margin-bottom: 0.4rem; }
.modal-desc { font-size: 0.85rem; color: var(--muted); line-height: 1.5; margin-bottom: 0.85rem; }
.modal-card textarea { width: 100%; font-family: var(--sans); font-size: 0.9rem; line-height: 1.5; padding: 0.6rem 0.75rem; border: 1px solid var(--border); border-radius: 7px; background: var(--surface); color: var(--text); resize: vertical; }
.modal-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 1rem; }
.modal-msg { margin-top: 0.75rem; font-family: var(--mono); font-size: 0.75rem; padding: 0.5rem 0.7rem; border-radius: 6px; }

/* Dashboard roundup rows — one compact clickable line per content item */
.roundup-list { display: flex; flex-direction: column; }
.roundup-row {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.6rem 0.25rem;
  border-top: 1px solid var(--border);
  text-decoration: none; color: inherit;
}
.roundup-row:first-child { border-top: none; padding-top: 0.1rem; }
.roundup-row:hover { background: var(--accent-light); }
.roundup-main { flex: 1; min-width: 0; }
.roundup-title { font-size: 0.95rem; font-weight: 600; line-height: 1.35; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.roundup-sub { font-family: var(--mono); font-size: 0.7rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 0.1rem; }
.roundup-date { font-family: var(--mono); font-size: 0.7rem; color: var(--muted); white-space: nowrap; }
.roundup-empty { font-family: var(--mono); font-size: 0.8rem; color: var(--muted); }

.btn-danger {
  background: none;
  border: 1px solid var(--err-border);
  color: var(--err);
}
.btn-danger:hover { background: var(--err-light); border-color: var(--err); color: var(--err); opacity: 1; }

.btn-full { width: 100%; text-align: center; }

/* ── Inputs ───────────────────────────────────────────────────────────────── */

.field { display: flex; flex-direction: column; gap: 0.35rem; }

.field label {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.input-wrap {
  display: flex;
  align-items: center;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg);
  transition: border-color 0.15s;
}

.input-wrap:focus-within { border-color: var(--accent); }

.input-wrap input,
.input-wrap select {
  font-family: var(--mono);
  font-size: 0.82rem;
  flex: 1;
  padding: 0.65rem 0.9rem;
  border: none;
  background: transparent;
  color: var(--text);
  outline: none;
  width: 100%;
}

input, select, textarea {
  font-family: var(--mono);
  font-size: 0.82rem;
  padding: 0.65rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  color: var(--text);
  outline: none;
  transition: border-color 0.15s;
  width: 100%;
}

input:focus, select:focus, textarea:focus { border-color: var(--accent); }

select { cursor: pointer; }

.input-hint {
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--muted);
  opacity: 0.8;
}

/* ── Checkboxes ───────────────────────────────────────────────────────────── */

.checkbox-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  cursor: pointer;
  font-family: var(--mono);
  font-size: 0.78rem;
}

.checkbox-row input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  accent-color: var(--accent);
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
}

/* ── Node picker ──────────────────────────────────────────────────────────── */

.node-grid {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.node-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  transition: border-color 0.12s, background 0.12s;
  cursor: pointer;
}

.node-item:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-light);
}

.node-item input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  accent-color: var(--accent);
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
}


/* ── Node status card (dashboard) ─────────────────────────────────────────── */

.node-card {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
}

.node-row-top {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.node-row-top .node-name { flex: 1; }

.node-badges {
  display: flex;
  gap: 0.35rem;
  align-items: center;
  flex-wrap: wrap;
}

.badge-method {
  background: #f1f0ed;
  color: var(--muted);
  font-size: 0.58rem;
  letter-spacing: 0.04em;
}

.node-row-disk {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-left: 1.1rem; /* indent under dot */
}

.node-row-disk .disk-bar-wrap { flex: 1; }

.spool-badge {
  font-family: var(--mono);
  font-size: 0.62rem;
  color: var(--warn);
  background: var(--warn-light);
  padding: 0.1rem 0.4rem;
  border-radius: 3px;
  white-space: nowrap;
  flex-shrink: 0;
}

.node-name {
  font-family: var(--mono);
  font-size: 0.82rem;
  flex: 1;
}

.node-meta {
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--muted);
  display: flex;
  gap: 0.75rem;
  align-items: center;
}

.node-status-dot {
  position: relative;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
}

.dot-ready    { background: var(--ok); }
.dot-online   { background: var(--warn); }
.dot-offline  { background: var(--state-offline); }

@keyframes dot-ping {
  0%   { transform: scale(1);   opacity: 0.7; }
  100% { transform: scale(4);   opacity: 0; }
}

.node-status-dot::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: inherit;
  opacity: 0;
  pointer-events: none;
}

.node-status-dot.dot-ping::after {
  animation: dot-ping 0.9s ease-out forwards;
}

/* ── Status badges ────────────────────────────────────────────────────────── */

.badge {
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.15rem 0.5rem;
  border-radius: 3px;
}

/* Compact hardware/type tag (CPU class, docker) — icon-led, lighter than .badge */
.hw-tag {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1;
  padding: 0.1rem 0.36rem;
  border-radius: 3px;
  background: #f1f5f9;
  color: #475569;
  border: 1px solid #e2e8f0;
  vertical-align: middle;
}
.hw-tag-docker { background: #e0e7ff; color: #3730a3; border-color: #c7d2fe; }
.hw-ico {
  display: inline-block;
  width: 11px;
  height: 11px;
  flex: none;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}
.hw-ico-cpu    { background-image: url(/static/icons/chip.svg); }
.hw-ico-docker { background-image: url(/static/icons/docker.svg); }
.hw-ico-pi     { background-image: url(/static/icons/raspberrypi.svg); }

.badge-capturing    { background: var(--ok-light);   color: var(--ok);   }
.badge-syncing      { background: #eff6ff;            color: #1d4ed8;     }
.badge-done         { background: #f3f4f6;            color: #6b7280;     }
.badge-failed       { background: var(--err-light);   color: var(--err);  }
.badge-pending      { background: var(--warn-light);  color: var(--warn); }
.badge-pending_sync { background: #eff6ff;            color: #1d4ed8;     }
.badge-finalizing   { background: #f0fdf4;            color: #166534;     }
.badge-stopped      { background: #f3f4f6;            color: #6b7280;     }
.badge-offline      { background: #f3f4f6;            color: #9ca3af;     }
.badge-reencoded { background: var(--warn-light);  color: var(--warn); font-size: 0.58rem; }

/* Dark-mode overrides for the hardcoded badge / tag tints (they bypass the vars). */
:root[data-theme="dark"] .badge-syncing,
:root[data-theme="dark"] .badge-pending_sync { background: #17263f; color: #7ab0f0; }
:root[data-theme="dark"] .badge-done,
:root[data-theme="dark"] .badge-stopped,
:root[data-theme="dark"] .badge-offline { background: #262b34; color: #9aa0aa; }
:root[data-theme="dark"] .badge-finalizing { background: #16281f; color: #57b487; }
:root[data-theme="dark"] .hw-tag { background: #242832; color: #9aa0aa; border-color: #2d323c; }
:root[data-theme="dark"] .hw-tag-docker { background: #1e2440; color: #8ea2e8; border-color: #2f3a63; }
:root[data-theme="dark"] .tw-active { color: #0d1a2a; }
:root[data-theme="dark"] .date-edit.date-ok { box-shadow: 0 0 0 2px #3f7a5c; }

/* ── Progress bar ─────────────────────────────────────────────────────────── */

.progress-wrap { display: flex; flex-direction: column; gap: 0.45rem; }
.progress-label { font-family: var(--mono); font-size: 0.75rem; color: var(--muted); }
.progress-detail { font-family: var(--mono); font-size: 0.72rem; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-height: 0.9rem; }
.progress-track { height: 4px; background: var(--border); border-radius: 2px; overflow: hidden; }
.progress-bar { height: 100%; background: var(--accent); border-radius: 2px; width: 0%; transition: width 0.4s ease; }
.progress-bar.pulse { animation: pulse-bar 1.5s ease-in-out infinite; width: 35%; }

@keyframes pulse-bar {
  0%   { transform: translateX(-120%); }
  100% { transform: translateX(400%); }
}

/* ── Tables ───────────────────────────────────────────────────────────────── */

.tbl { width: 100%; border-collapse: collapse; }

.tbl th {
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: left;
  padding: 0 0.5rem 0.6rem;
  border-bottom: 1px solid var(--border);
  font-weight: 400;
}

.tbl td {
  font-family: var(--mono);
  font-size: 0.78rem;
  padding: 0.6rem 0.5rem;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

.tbl tr:last-child td { border-bottom: none; }
.tbl tr:hover td { background: var(--bg); }

.tbl-url {
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted);
}

/* ── Capture log (collapsible error/stderr) ───────────────────────────────── */

.cap-log {
  border: 1px solid var(--err-border);
  border-radius: 6px;
  background: var(--err-light);
  overflow: hidden;
}

.cap-log-summary {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--err);
  padding: 0.45rem 0.75rem;
  cursor: pointer;
  user-select: none;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.cap-log-summary::-webkit-details-marker { display: none; }

.cap-log-summary::before {
  content: '▶';
  font-size: 0.55rem;
  transition: transform 0.15s;
  flex-shrink: 0;
}

.cap-log[open] .cap-log-summary::before { transform: rotate(90deg); }

.cap-log-pre {
  margin: 0;
  padding: 0.6rem 0.75rem;
  border-top: 1px solid var(--err-border);
  font-family: var(--mono);
  font-size: 0.68rem;
  line-height: 1.5;
  color: var(--err);
  white-space: pre-wrap;
  word-break: break-all;
  overflow-x: auto;
}

/* ── Alert / error / success banners ─────────────────────────────────────── */

.alert {
  font-family: var(--mono);
  font-size: 0.75rem;
  border-radius: 6px;
  padding: 0.65rem 0.9rem;
  position: relative;
}

.alert-err {
  color: var(--err);
  background: var(--err-light);
  border: 1px solid var(--err-border);
}

.alert-warn {
  color: var(--warn);
  background: var(--warn-light);
  border: 1px solid #fde68a;
}

.alert-ok {
  color: var(--ok);
  background: var(--ok-light);
  border: 1px solid var(--accent);
}

.alert-badge {
  position: absolute;
  top: -0.7rem;
  left: 0.75rem;
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.15rem 0.5rem;
  border-radius: 3px;
}

.alert-ok   .alert-badge { background: var(--accent); color: #fff; }
.alert-err  .alert-badge { background: var(--err);    color: #fff; }
.alert-warn .alert-badge { background: var(--warn);   color: #fff; }

/* ── Disk usage bar ───────────────────────────────────────────────────────── */

.disk-bar-wrap { display: flex; align-items: center; gap: 0.5rem; }
.disk-bar-track { flex: 1; height: 4px; background: var(--border); border-radius: 2px; overflow: hidden; }
.disk-bar-fill { height: 100%; background: var(--accent); border-radius: 2px; transition: width 0.4s; }
.disk-bar-fill.warn { background: var(--warn); }
.disk-bar-fill.floor { background: var(--err); }
.disk-bar-label { font-family: var(--mono); font-size: 0.68rem; color: var(--muted); white-space: nowrap; }

/* ── Stale indicator ──────────────────────────────────────────────────────── */

.stale { opacity: 0.45; font-style: italic; }
.stale-label {
  font-family: var(--mono);
  font-size: 0.65rem;
  color: var(--muted);
  font-style: italic;
}

/* ── Animations ───────────────────────────────────────────────────────────── */

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

.fade-up { animation: fadeUp 0.2s ease; }

/* ── Footer ───────────────────────────────────────────────────────────────── */

footer {
  margin-top: 2rem;
  font-size: 0.7rem;
  color: var(--muted);
  font-family: var(--mono);
  text-align: center;
}

footer a { color: var(--muted); text-decoration: none; }
footer a:hover { color: var(--text); }
.footer-sep { margin: 0 0.4rem; }
.footer-colon { margin-right: 0.4rem; }

/* ── Video player ─────────────────────────────────────────────────────────── */

.video-wrap {
  border-radius: 6px;
  overflow: hidden;
  background: #111;
  line-height: 0;
}

/* ── Timeline scrubber ────────────────────────────────────────────────────── */

.timeline {
  position: relative;
  height: 52px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  overflow: hidden;
  user-select: none;
}

/* ── Playback controls ────────────────────────────────────────────────────── */

.playback-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.time-display {
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--muted);
  margin-left: auto;
  white-space: nowrap;
}

.btn-transport {
  font-family: var(--mono);
  font-size: 0.72rem;
  padding: 0.35rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
  white-space: nowrap;
}

.btn-transport:hover  { background: var(--bg); border-color: var(--muted); }
.btn-transport:active { transform: scale(0.97); }

.btn-transport.btn-play {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
  min-width: 2.5rem;
  text-align: center;
}

.btn-transport.btn-play:hover { opacity: 0.85; }

/* ── Keyboard hint ────────────────────────────────────────────────────────── */

.kbd-hint {
  font-family: var(--mono);
  font-size: 0.65rem;
  color: var(--muted);
  text-align: center;
  opacity: 0.7;
}

/* ── In / out point row ───────────────────────────────────────────────────── */

.inout-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.inout-times {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}

.inout-time {
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--text);
  min-width: 4.5rem;
  text-align: center;
}

.inout-arrow {
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--muted);
}

.btn-mark {
  font-family: var(--mono);
  font-size: 0.72rem;
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
  white-space: nowrap;
}

.btn-mark:hover { background: var(--accent-light); border-color: var(--accent); color: var(--accent); }

/* ── Inline click-to-edit fields (title, summary) ─────────────────────────────
   Editable in place with realtime autosave — no Save/Cancel buttons. */

.editable {
  cursor: text;
  border-radius: 5px;
  outline: none;
  padding: 0.1rem 0.35rem;
  margin-left: -0.35rem;                 /* keep text visually aligned despite the padding */
  transition: background 0.15s ease, box-shadow 0.15s ease;
}

.editable:hover {
  background: var(--accent-light);
  box-shadow: 0 0 0 1px var(--border);
}

.editable:focus {
  background: var(--surface);
  box-shadow: 0 0 0 2px var(--accent);
}

/* Placeholder for an empty editable field. */
.editable:empty::before {
  content: attr(data-placeholder);
  color: var(--muted);
  opacity: 0.6;
}

/* Interview-date input — reads like the title (large, transparent) but stays a strict
   mm/dd/yyyy field. Hover/focus mirror the .editable click-to-edit affordance. */
.date-edit {
  display: block;
  margin-top: 0.35rem;
  margin-left: -0.35rem;
  padding: 0.1rem 0.35rem;
  width: 12ch;
  font-family: var(--mono);
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--accent);
  background: transparent;
  border: none;
  border-radius: 5px;
  outline: none;
  transition: background 0.15s ease, box-shadow 0.15s ease;
}
.date-edit::placeholder { color: var(--muted); opacity: 0.55; font-weight: 400; }
.date-edit:hover  { background: var(--accent-light); box-shadow: 0 0 0 1px var(--border); }
.date-edit:focus  { background: var(--surface); box-shadow: 0 0 0 2px var(--accent); }
.date-edit.date-ok  { box-shadow: 0 0 0 2px #7bbf9e; }
.date-edit.date-err { box-shadow: 0 0 0 2px var(--err); background: var(--err-light); }

/* Small variant for the inline provenance "Updated" date. */
.date-edit-sm {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text);
  /* 10 chars (mm/dd/yyyy) + the inherited horizontal padding, so the year isn't clipped. */
  width: calc(10ch + 0.8rem);
  margin-top: 0;
  margin-left: 0;
}

/* Pencil affordance on hover so it reads as editable. */
.editable:hover::after {
  content: '✎';
  font-size: 0.7em;
  color: var(--muted);
  margin-left: 0.4em;
  vertical-align: middle;
}
.editable:focus::after { content: none; }

@keyframes save-ok-flash {
  0%   { background: #cdeddd; }
  100% { background: transparent; }
}
@keyframes save-err-flash {
  0%   { background: var(--err-light); }
  100% { background: transparent; }
}
.editable.save-ok  { animation: save-ok-flash 0.9s ease; }
.editable.save-err { animation: save-err-flash 0.9s ease; }

/* ── Find-in-transcript highlights ────────────────────────────────────────────
   <mark> wrappers around matches; the current match gets a stronger tint. */

mark.tx-find {
  background: #ffe08a;
  color: #1a1916;
  border-radius: 2px;
  padding: 0 1px;
}
mark.tx-find.tx-find-cur {
  background: #f59e0b;
  box-shadow: 0 0 0 1px #d97706;
}

/* ── Speaker picker modal ─────────────────────────────────────────────────── */

.spk-modal-ov {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.4);
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  opacity: 0;
  /* Dim AND blur, so the page behind reads as out of reach rather than merely darker.
     Blurring the backdrop also stops busy transcript text competing with the dialog. */
  -webkit-backdrop-filter: blur(7px);
  backdrop-filter: blur(7px);
  transition: opacity 0.5s ease;
}

.spk-modal-ov.show { opacity: 1; }

/* The page behind a modal is frozen where it stands. `position: fixed` rather than
   `overflow: hidden` because iOS Safari happily scrolls the body regardless of the latter;
   the JS stores the scroll offset in `top` and restores it on close, so nothing jumps. */
body.modal-open {
  position: fixed;
  width: 100%;
  overflow: hidden;
}

.spk-modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1rem;
  width: 100%;
  max-width: 400px;
  max-height: 88vh;
  overflow-y: auto;
  box-shadow: 0 8px 32px rgba(0,0,0,0.22);
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  transform: scale(0.96);
  transition: transform 0.5s ease;
}

.spk-modal-ov.show .spk-modal { transform: scale(1); }

.spk-modal-title {
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 0.35rem;
}

.spk-modal-row {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  text-align: left;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--surface);
  color: var(--text);
  font-size: 0.92rem;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}

.spk-modal-row:hover { background: var(--accent-light); border-color: var(--accent); }

.spk-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex: 0 0 auto;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.12) inset;
}

.spk-modal-new {
  display: flex;
  gap: 0.4rem;
  align-items: center;
  margin-top: 0.15rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
}

.spk-modal-new input {
  flex: 1;
  min-width: 0;
  font-size: 0.85rem;
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface);
  color: var(--text);
}

.spk-modal-input {
  width: 100%;
  font-size: 0.95rem;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--surface);
  color: var(--text);
}

.spk-modal-input:focus { outline: none; box-shadow: 0 0 0 2px var(--accent); }

/* ── Modal field + its suggestion popdown ──────────────────────────────────────
   The popdown sits IN FLOW, not floating over the dialog. Absolute positioning would
   drop it across the Save/Cancel buttons; in flow it pushes them down instead, so the
   controls are never covered and the box simply grows.

   Open, the input and the list share one accent border and glow with the seam between
   them squared off, so the pair reads as a single control rather than a menu that
   happens to be nearby. Same affordance as the record form's reporter/outlet fields. */
.spk-field { margin-bottom: 0.5rem; }

/* `input`, not `.spk-modal-input`: the new-speaker field in the assign-to dialog uses the
   compact `.spk-modal-new input` styling and needs the same welded look. */
.spk-field.linked input {
  border-color: var(--accent);
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}

/* The new-speaker field is a column (input above its popdown) sharing a flex row with the
   speaker dot and the Add button. Top-align the row so those two stay level with the input
   instead of drifting to the middle of a tall open list. */
.spk-modal-new { align-items: flex-start; }
.spk-new-field { flex: 1; min-width: 0; margin-bottom: 0; }
.spk-modal-new > .spk-dot { margin-top: 0.65rem; }

/* Both of the animated boxes below are opened to a height JavaScript measures, not to a
   guessed maximum. A max-height guess large enough to fit the content stops animating the
   moment the real height is reached, which reads as a snap rather than a slide. */
.spk-suggest {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--accent);
  border-top: none;
  border-radius: 0 0 7px 7px;
  transition: max-height 0.24s ease, opacity 0.18s ease;
}

.spk-suggest.open {
  opacity: 1;
  overflow-y: auto;
  box-shadow: 0 8px 22px rgba(0,0,0,0.18),
              0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}

.spk-suggest .suggest-item:hover,
.spk-suggest .suggest-item.active {
  background: var(--accent-light);
  color: var(--accent);
  font-weight: 600;
}

/* Reserved runway under the last field so an opening popdown has somewhere to go before
   it starts pushing the buttons around. */
.spk-modal-runway { height: 0.35rem; flex: none; }

/* A field that appears only for certain roles. JS animates max-height to the measured
   content height, then releases the cap once open so the popdown inside can grow past it. */
.spk-collapse {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  margin-bottom: 0;
  transition: max-height 0.3s ease, opacity 0.24s ease, margin-bottom 0.3s ease;
}

.spk-collapse.open {
  opacity: 1;
  margin-bottom: 0.5rem;
}

/* ── Video player container ───────────────────────────────────────────────── */

.vid-container {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: 10px;
  overflow: hidden;
  /* Match the page's card treatment — light border + soft shadow, not a heavy dark frame. */
  border: 1px solid var(--border);
  box-shadow: 0 1px 3px rgba(0,0,0,0.06);
  margin-top: 0.5rem;
}

/* ── Review pane: transcript + player + actions, contained to the viewport ──────
   When the transcript is open the three stack into one pane no taller than the
   screen — the transcript scrolls internally while the player and action buttons
   stay visible beneath it. */

.review-pane {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 0.5rem;
  min-width: 0;
}

/* Inside the pane the gap owns the spacing — drop the element's own top margin. */
.review-pane .vid-container { margin-top: 0; }

.review-pane.review-open {
  max-height: calc(100vh - 1.5rem);
}

/* Order the open review pane: video pinned on top, then transport, then the transcript panel,
   then the download/action row. The pane is viewport-tall, so the video (the top item) stays
   put while only the transcript scrolls. */
.review-pane.review-open .vid-container { order: 1; }
.review-pane.review-open .tx-transport  { order: 2; }
.review-pane.review-open .tx-panel      { order: 3; flex: 1 1 auto; min-height: 0; }
.review-pane.review-open .tx-actions-row { order: 4; }

/* The transcript text is the scroll surface that absorbs the leftover height. */
.tx-scroll {
  max-height: 360px;
  overflow-y: auto;
}

/* Only the transcript box carries the ~90%-of-screen cap; it scrolls internally, and its scroll
   is "contained" so it won't spill into scrolling the page until you deliberately break out. */
.review-pane.review-open .tx-scroll {
  flex: 1 1 auto;
  max-height: 90vh;
  min-height: 160px;
  overscroll-behavior: contain;
}

/* Video: a 360px floor + user resize (the Video −/+ controls set --vid-h), instead of the old
   48vh squeeze. object-fit:contain letterboxes non-16:9 sources cleanly. */
.review-pane.review-open .vid-container {
  flex: 0 0 auto;
  aspect-ratio: auto;
  height: var(--vid-h, 42vh);
  min-height: 360px;
  max-height: 72vh;
}

.vid-container video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* ── Video placeholder overlay ───────────────────────────────────────────── */

.vid-ph {
  position: absolute;
  inset: 0;
  background: rgba(8, 10, 12, 0.32);   /* neutral scrim over the real /thumb poster — no branded image */
  transition: opacity 0.9s ease, transform 0.9s ease, filter 0.9s ease;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

/* Dissolve: shrink + blur + fade. */
.vid-ph.vid-ph-fading {
  opacity: 0;
  transform: scale(0.93);
  filter: blur(8px);
}

/* Glow play button on hover — overlay stays put until clicked. */
.vid-ph:hover .vid-play-btn {
  transform: scale(1.1);
  background: rgba(255,255,255,0.12);
  border-color: #fff;
  box-shadow: 0 0 0 6px rgba(255,255,255,0.12), 0 0 32px rgba(255,255,255,0.35), 0 2px 20px rgba(0,0,0,0.5);
}

.vid-play-btn {
  position: relative;
  z-index: 1;
  width: 68px;
  height: 68px;
  border-radius: 50%;
  background: rgba(0,0,0,0.48);
  border: 2px solid rgba(255,255,255,0.82);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.2s ease, background 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
  box-shadow: 0 2px 20px rgba(0,0,0,0.5);
  pointer-events: none;
}

/* ── Video in-player overlays ────────────────────────────────────────────── */

.vid-mode-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 6;
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  padding: 0.2rem 0.5rem;
  border-radius: 4px;
  background: rgba(0,0,0,0.72);
  color: #fff;
  border: 1px solid rgba(255,255,255,0.15);
  opacity: 0;
  transition: opacity 0.25s;
  pointer-events: none;
}

.vid-buffer-bar {
  position: absolute;
  top: 0;
  left: 0;
  height: 3px;
  width: 0%;
  background: rgba(255,255,255,0.55);
  box-shadow: 0 0 4px rgba(255,255,255,0.3);
  z-index: 6;
  pointer-events: none;
  transition: width 0.8s linear;
}

.vid-buf-label {
  position: absolute;
  top: 8px;
  left: 63px;
  z-index: 6;
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  padding: 0.2rem 0.5rem;
  border-radius: 4px;
  background: rgba(0,0,0,0.72);
  color: #fff;
  border: 1px solid rgba(255,255,255,0.15);
  opacity: 0;
  transition: opacity 0.4s;
  pointer-events: none;
}

@keyframes vid-spinner {
  to { transform: translate(-50%, -50%) rotate(360deg); }
}

.vid-buffering-ring {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 38px;
  height: 38px;
  border: 3px solid rgba(255,255,255,0.15);
  border-top-color: rgba(255,255,255,0.75);
  border-radius: 50%;
  z-index: 6;
  animation: vid-spinner 0.75s linear infinite;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s;
}

.vid-buffering-ring.visible { opacity: 1; }

/* ── Responsive ───────────────────────────────────────────────────────────── */

@media (max-width: 640px) {
  .page { padding: 1.25rem 0.9rem 3rem; }   /* nav stays flush to the top edge */
  .card { padding: 1.25rem; gap: 1rem; }

  /* Section headers: let the label and button group stack to two lines */
  .section-header { flex-wrap: wrap; gap: 0.5rem; }

  /* Tables: horizontal scroll instead of crushing columns */
  .tbl { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }

  /* Prevent flex children from blowing out their container width */
  .progress-wrap,
  .node-row-top,
  .node-row-disk { min-width: 0; }

  /* Tighten mark in/out buttons so they stay on one row longer */
  .btn-mark { font-size: 0.67rem; padding: 0.3rem 0.5rem; }

  /* Allow playback transport row to wrap on narrow screens */
  .playback-row { flex-wrap: wrap; }
  .time-display  { margin-left: 0; }

  /* Keyboard shortcut hint is irrelevant on touch devices */
  .kbd-hint { display: none; }

  /* Modal code blocks must not overflow the modal width */
  code { white-space: pre-wrap; word-break: break-all; }
}

@media (max-width: 420px) {
  /* Stack in/out row vertically on very small phones */
  .inout-row    { flex-direction: column; gap: 0.4rem; }
  .inout-times  { justify-content: center; }

  /* Move time counter below the transport buttons */
  .time-display { width: 100%; text-align: right; order: 4; }

  /* Node name + badges: allow name to shrink so badges stay readable */
  .node-name { font-size: 0.78rem; }
}

/* Transcript — paragraph spacing + word-synced highlighting */
.tx-para { margin: 0 0 1.25rem; line-height: 1.7; }
.tx-para:last-child { margin-bottom: 0; }
.tw { cursor: pointer; border-radius: 3px; transition: background 0.1s ease, color 0.1s ease; }
.tw:hover { background: var(--surface); }
.tw-active { background: var(--accent); color: #fff; }

/* Transcript EDIT mode — make it an obviously distinct, active surface (vs. reviewing) */
.tx-scroll.tx-editing { border: 2px solid var(--accent) !important; background: var(--warn-light) !important; box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 12%, transparent); }
.btn-sm.btn-save { background: var(--ok) !important; color: #fff !important; border-color: var(--ok) !important; font-weight: 600; }
.btn-sm.btn-save:hover { filter: brightness(1.08); }
.btn-sm.btn-cancel { background: var(--warn-light) !important; color: var(--warn) !important; border-color: var(--warn) !important; font-weight: 600; }

/* Playback-speed segmented control (replaces the dropdown) */
.speed-seg { display: inline-flex; align-items: center; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; margin-left: 0.35rem; }
.speed-seg .speed-lbl { font-family: var(--mono); font-size: 0.66rem; color: var(--muted); padding: 0 0.45rem 0 0.5rem; letter-spacing: 0.02em; user-select: none; }
.speed-seg .speed-opt { border: none; border-left: 1px solid var(--border); background: var(--surface); color: var(--muted); font-family: var(--mono); font-size: 0.72rem; padding: 0.3rem 0.5rem; cursor: pointer; transition: background 0.12s ease, color 0.12s ease; }
.speed-seg .speed-opt:hover { background: var(--surface-2); color: var(--text); }
.speed-seg .speed-opt.active { background: var(--accent); color: #fff; }

/* On-button keyboard-shortcut hints */
.kbd { font-family: var(--mono); font-size: 0.64rem; opacity: 0.6; border: 1px solid var(--border);
       border-radius: 3px; padding: 0 3px; margin-left: 3px; white-space: nowrap; }

/* ── Search results + live suggestions ──────────────────────────────────────── */
.search-hit {
  display: block; text-decoration: none; color: inherit;
  border: 1px solid var(--border); border-radius: 6px;
  padding: 0.75rem 1rem; margin: 0.5rem 0; background: var(--surface);
}
.search-hit:hover { border-color: var(--accent); }
.hit-title { font-weight: 600; font-size: 1rem; line-height: 1.3; color: var(--text); }
.hit-meta { font-family: var(--mono); font-size: 0.72rem; color: var(--muted); margin-top: 0.25rem; }
.hit-blurb { font-size: 0.85rem; line-height: 1.55; margin-top: 0.45rem; color: var(--text); }
.hit-blurb mark { background: var(--accent-light); color: var(--accent); font-weight: 600; border-radius: 2px; padding: 0 2px; }
.hit-topics { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.5rem; }

[data-suggest] { position: relative; }
.suggest-dropdown {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 120;
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.20); overflow: hidden auto; max-height: 340px; display: none;
}
.suggest-dropdown.open { display: block; }
.suggest-item {
  display: flex; align-items: center; gap: 0.6rem; padding: 0.45rem 0.7rem; cursor: pointer;
  font-size: 0.85rem; color: var(--text); border-bottom: 1px solid var(--border);
}
.suggest-item:last-child { border-bottom: none; }
.suggest-item:hover, .suggest-item.active { background: var(--accent-light); }
.suggest-item .s-text { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.suggest-item .s-kind { font-family: var(--mono); font-size: 0.58rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }

/* Corpus tallies, flush-right on the footer row. */
.footer-stats { margin-left: auto; text-align: right; color: var(--muted); }
@media (max-width: 720px) {
  .footer-stats { margin-left: 0; text-align: left; flex-basis: 100%; }
}

/* ── Recorded-session ground rules + participant roster (interview page) ───────── */
.ground-badge { display: inline-flex; align-items: center; gap: 0.45rem; font-family: var(--mono);
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em; padding: 0.4rem 0.7rem;
  border-radius: 7px; border: 1px solid transparent; }
.ground-badge .mdi { font-size: 0.95rem; }
.ground-badge .ground-note { font-weight: 400; letter-spacing: 0; text-transform: none;
  font-family: var(--sans, inherit); font-size: 0.75rem; opacity: 0.85; }
.gr-bg { background: var(--warn-light); color: var(--warn); border-color: var(--warn); }
.gr-off { background: var(--err-light); color: var(--err); border-color: var(--err-border); }
.session-roster { display: flex; flex-direction: column; gap: 0.35rem; margin-top: 0.55rem; }
.roster-line { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; }
.roster-label { font-family: var(--mono); font-size: 0.64rem; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--muted); margin-right: 0.15rem; }
.roster-chip { display: inline-flex; align-items: baseline; gap: 0.25rem; font-size: 0.82rem;
  padding: 0.2rem 0.55rem; border: 1px solid var(--border); border-radius: 20px; background: var(--surface); }
.roster-outlet { font-family: var(--mono); font-size: 0.68rem; color: var(--muted); }

/* Per-transcript accuracy chip (interview page, shown after review). */
.tx-accuracy { display: inline-flex; align-items: center; gap: 0.4rem; font-family: var(--mono);
  font-size: 0.72rem; color: var(--accent); background: var(--accent-light); border: 1px solid var(--accent);
  border-radius: 7px; padding: 0.3rem 0.6rem; margin-top: 0.1rem; }
.tx-accuracy .mdi { font-size: 0.95rem; }
.tx-accuracy b { font-weight: 700; }
.tx-accuracy .tx-accuracy-note { font-weight: 400; color: var(--muted); border-left: 1px solid var(--border); padding-left: 0.45rem; }

/* Merge-up affordance on transcript paragraphs (review mode, hover-revealed). */
.tx-para { position: relative; }
.tx-merge { position: absolute; top: -0.55rem; right: 0; z-index: 2; display: inline-flex;
  align-items: center; gap: 0.15rem; font-family: var(--mono); font-size: 0.6rem;
  text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); background: var(--surface);
  border: 1px solid var(--border); border-radius: 5px; padding: 0.1rem 0.4rem; cursor: pointer;
  opacity: 0; transition: opacity 0.12s, color 0.12s, border-color 0.12s; user-select: none; }
.tx-merge .mdi { font-size: 0.8rem; }
.tx-para:hover .tx-merge { opacity: 0.75; }
.tx-merge:hover { opacity: 1; color: var(--accent); border-color: var(--accent); background: var(--accent-light); }
.tx-editing .tx-merge { display: none; }   /* structural edits are disabled while editing text */

/* The counts behind the accuracy rates. Sits directly under .tx-accuracy and reads as its
   detail line, so it is quieter: no icon, no border, separators between the figures. */
.tx-edits {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.15rem 0;                  /* the ::before separators carry the horizontal spacing */
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--muted);
  margin: 0.2rem 0 0 1.55rem;      /* indented to clear the icon on the line above */
}
.tx-edits b { color: var(--text); font-weight: 700; }
.tx-edits-label { text-transform: uppercase; letter-spacing: 0.05em; opacity: 0.75; }
/* Separators between the figures, but not before the trailing "of N words" — that is a
   qualifier on the whole line, not another figure in the list. */
.tx-edits > span + span:not(.tx-accuracy-note)::before {
  content: "·";
  margin: 0 0.5rem;
  opacity: 0.5;
}
.tx-edits > .tx-accuracy-note { margin-left: 0.9rem; }

/* Certify-that-you-reviewed-it. Reads as a deliberate act rather than another toolbar
   button: it puts the reviewer's name on the record. Green once ticked, matching the
   dashboard badge it produces. --ok carries its own dark-theme value. */
.tx-certify {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--muted);
  cursor: pointer;
  padding: 0.15rem 0.45rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.tx-certify:hover { border-color: var(--ok); color: var(--text); }
.tx-certify input { accent-color: var(--ok); margin: 0; cursor: pointer; }
.tx-certify:has(input:checked) {
  color: var(--ok);
  border-color: var(--ok);
  background: var(--ok-light);
}

/* "reviewed by X" on a dashboard row. */
.cert-by {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-family: var(--mono);
  font-size: 0.66rem;
  color: var(--ok);
  white-space: nowrap;
}
.cert-by .mdi { font-size: 0.85rem; }

/* Segment seams, shown only while editing. A paragraph is several separately-timed segments
   rendered as one flow, so the joins inside a sentence are invisible — "…in particular though
   is" running straight into "keeping in mind…". Backspace there behaves differently (it joins
   the two segments first), so the seam is worth being able to see before you land on it.
   A border, deliberately, not a ::before: Chrome counts generated content in innerText, and
   the save reads innerText, so a marker made that way would be written into the transcript. */
.tx-editing .tx-seg + .tx-seg {
  border-left: 1px dotted color-mix(in srgb, var(--muted) 45%, transparent);
  padding-left: 3px;
}
