/* ===================================================================
   wired UX redesign -- component styles (Wired_UX_Redesign_Handoff).

   Its own file, loaded after limestone-v2.css, and every selector is
   prefixed `rd-`. Two reasons. style.css's header warns its cascade is
   load-bearing and forbids appending after its final block; and keeping
   the redesign's rules in one place means the whole thing can be reviewed
   -- or backed out -- as a unit while it lives on a branch.

   Built on the --ltg-* tokens directly. They are theme-aware through the
   bridge, so nothing here has a dark-mode override: Midnight is the same
   rules resolving to different values.

   Accessibility rules this file holds to (brief: WCAG 2.2 AA):
   - Every interactive target is at least --ltg-target (44px) tall on
     touch, 24px minimum (SC 2.5.8) anywhere.
   - State is never colour alone. Every .rd-state carries its word; the
     dot is decoration and aria-hidden in the markup.
   - Nothing depends on hover. Hover only ever restates what's already
     visible.
   - Reflows to 320px with no horizontal scroll (SC 1.4.10).
   =================================================================== */

/* ---------------- App-wide: controls never break mid-word ----------------
   style.css sets `overflow-wrap: anywhere` on <body> on purpose: a long
   pasted URL, email or name must not force a panel wider than the screen.
   Everything inherits it -- including buttons, chips and tabs, where it does
   real damage: `anywhere` shrinks an element's min-content width to ONE
   CHARACTER, so a flex or grid row is free to squeeze a button narrower
   than its own label and split the word. Confirmed on Peyton's iPhone
   (393px): "Resu|me", "mom|ent" in the live capture bar. Content keeps the
   protection; controls opt out, so they wrap between words if they must and
   their minimum width is always the longest word.

   break-word, not normal: both keep the min-content width at the longest
   word (so nothing can squeeze a control into splitting one), but
   break-word still breaks a word that is genuinely wider than the whole
   screen instead of pushing the page sideways. Labels are included --
   the whole-app sweep caught a radio label on Scheduled captures splitting
   "Recurr|ing" the same way.

   This section and the next hold the rules in this file that aren't rd-
   scoped -- fixes for pages the redesign hasn't reached yet. The few
   others sit in the media blocks at the end, beside the breakpoint they
   share. */
button, .button, .badge, [role="tab"], .nav-link, .link-button,
.rd-state, .rd-link, summary, .sidebar-footer-row, label {
  overflow-wrap: break-word;
}

/* ---------------- App-wide mobile fixes (found by the phone sweep) ---------------- */

/* A native <select> is as wide as its LONGEST option, whatever is selected.
   The session page's export scope has "Summary report — needs a
   re-analysis" (for sessions with no short summary), 355px on its own, which
   forced the whole page to 371px on a 320px phone -- title, word count and
   the Email button all ran off the right edge. max-width:100% caps it, and
   because a select is a "compressible" form control, a percentage max-width
   also drops its min-content contribution, so it can no longer hold the
   page open. Applied to every select: none of them should be able to do
   this, and none was relying on overflowing. */
select { max-width: 100%; }

/* Breadcrumb: only the LAST crumb was allowed to truncate; the parent
   ("Peyton's bucket") wrapped onto two lines in the phone top bar. Parents
   now stay on one line and truncate too, and the current crumb takes what
   space is left. The <nav> itself has to take the top bar's free width:
   left to shrink-wrap its content, the cap below resolved against that
   shrink-wrapped width and cut "Peyton's bucket" short on a 1280px screen. */
.breadcrumb { flex: 1 1 auto; }
.breadcrumb li { white-space: nowrap; min-width: 0; }
.breadcrumb li:not(:last-child) { flex: 0 1 auto; max-width: 50%; } /* "Peyton's bucket" fits whole at 320 */
.breadcrumb li:not(:last-child) > a {
  display: block; overflow: hidden; text-overflow: ellipsis; line-height: 24px;
}
.breadcrumb li:last-child { flex: 1 1 0; }

/* The Meeting Coach flag toggle is a 13x13 icon button (suggestions.html) --
   under WCAG 2.2's 24px floor (SC 2.5.8), and not inline text, so no
   exception applies. It appears on the live page AND the pop-out; the sweep
   measured it 13x13 on both. The hit area grows; the icon doesn't. */
.suggestion-flag {
  min-width: 24px; min-height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
}
@media (pointer: coarse) {
  .suggestion-flag { min-width: var(--ltg-target); min-height: var(--ltg-target); }
}

/* Transcript mark icon (marks.js): 22px, under the 24px floor. And it only
   appears on hover/focus, which a phone never has -- so on touch screens it
   stays visible, just quieter than on hover. */
.mark-icon { width: 24px; height: 24px; }
@media (hover: none) { .mark-icon { opacity: .7; } }

/* iPhone zooms the whole page in when you focus a field whose text is under
   16px, and leaves it zoomed. Fields here use `font: inherit`, so any field
   in a small-text panel came out 13-14px -- measured on the review page's
   edit forms, Meetings, Scheduled captures, Admin, Reminders and the PIN
   login. 16px is a floor on touch screens only; no field anywhere is
   larger (measured), so nothing gets smaller. !important because the point
   is that no panel's own size can take a field back under it. */
@media (pointer: coarse) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select, textarea { font-size: 16px !important; }
}

/* Keeps a short run (a date, "· 20 words") on one line so a narrow screen
   breaks between runs, not inside one. */
.rd-nowrap { white-space: nowrap; }

/* Short runs separated by dots ("Sep 22 · Bravo · 39 words"). Each dot is
   drawn in the gap before its run and the list clips at its left edge, so a
   run that starts a wrapped line never starts with a stray dot. A run moves
   to the next line whole, and only wraps inside itself when it's wider than
   the whole line. The "/ ''" alt text keeps the dots out of screen readers. */
.rd-sep-list { display: flex; flex-wrap: wrap; column-gap: .75em; overflow: hidden; overflow: clip; }
.rd-sep-list > * { position: relative; }
.rd-sep-list > * + *::before {
  content: "\00B7"; content: "\00B7" / "";
  position: absolute; right: 100%; width: .75em; text-align: center;
}


@media (max-width: 480px) {
  /* The request-a-recording page (public_share.html) nests a dropzone in a
     card in a navy frame: 63px of padding a side left 194px at 320, and
     "Paste screenshot" folded onto two lines. What the dropzone gives up is
     inner padding the dashed border already separates. */
  .share-card { padding-left: var(--space-5); padding-right: var(--space-5); }
  .share-card .dropzone { padding-left: var(--space-3); padding-right: var(--space-3); }

  /* Note / link box under the full-size dropzone. Beside its Add button it
     got ~150px at 320, and the placeholder ("Or type a note, or paste a link
     (https://...)") ran to a third line the two-row box cut off. On a phone
     it takes the full width, tall enough for all three lines, with Add
     under it on the right. Not the compact contributor row
     (public_share_view.html): its one-line box and two icon buttons fit. */
  .dropzone:not(.dropzone-compact) .capture-note-row { flex-wrap: wrap; }
  .dropzone:not(.dropzone-compact) .capture-note-row textarea { flex: 1 1 100%; min-height: 6em; }
  .dropzone:not(.dropzone-compact) .capture-note-row .button { margin-left: auto; }
}

/* Meeting Coach header (suggestions.html): at 320 the caption squeezed the
   heading onto two lines. The heading stays whole; the caption drops under
   it when there isn't room. */
.suggestions-panel .panel-header { flex-wrap: wrap; row-gap: 2px; }
.suggestions-panel .panel-header h2 { white-space: nowrap; }

/* Live / Contributor / Read-only chips after a shared page's title
   (public_share_view.html, the pop-out). The markup already puts a space
   before each; style.css's extra margin-left doubled it, and when a chip
   wrapped under a long title the margin stayed while the space collapsed,
   indenting the chip 8px off the title's left edge. */
.kiosk-feed-header h1 .badge { margin-left: 0; }

/* ---------------- Page scaffold ---------------- */
.rd-page {
  max-width: var(--ltg-content-max);
  margin: 0 auto;
  display: flex; flex-direction: column; gap: var(--ltg-space-16);
  min-width: 0;
}
.rd-page--narrow { max-width: 880px; }

.rd-page-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--ltg-space-16); flex-wrap: wrap;
}
.rd-page-heading { min-width: 0; flex: 1 1 20rem; }
/* Guide v2 page title: 28/36 at every width. The guide gives H1 no smaller
   phone size, and anything under ~24px here would sit level with the 20px
   card headings below it. */
.rd-page-heading h1 {
  margin: 0; font-size: var(--text-title);
  line-height: var(--text-title-lh); letter-spacing: -0.01em; color: var(--ltg-text);
}
.rd-eyebrow {
  margin: 0 0 var(--ltg-space-4);
  font-size: .75rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ltg-text-secondary);
}
.rd-lede { margin: var(--ltg-space-8) 0 0; color: var(--ltg-text-secondary); font-size: 1rem; }
.rd-page-actions { display: flex; align-items: center; gap: var(--ltg-space-8); flex-wrap: wrap; }
.rd-new-session { display: inline-flex; align-items: center; gap: var(--ltg-space-8); }
.rd-status:empty { display: none; }
.rd-status { margin: 0; color: var(--ltg-text-secondary); font-size: .9rem; }

.rd-stack { display: flex; flex-direction: column; gap: var(--ltg-space-16); }

/* ---------------- Cards ---------------- */
.rd-card {
  background: var(--ltg-surface);
  border: 1px solid var(--ltg-divider);
  border-radius: var(--ltg-radius-card);
  padding: var(--ltg-space-24);
  min-width: 0;
}
.rd-card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--ltg-space-12); flex-wrap: wrap; margin-bottom: var(--ltg-space-12);
}
.rd-card-head h2, .rd-card > h2 { margin: 0; font-size: var(--text-section); line-height: var(--text-section-lh); color: var(--ltg-text); }
.rd-card-title { margin: 0; font-weight: 600; color: var(--ltg-text); }
.rd-card-meta { margin: var(--ltg-space-4) 0 0; color: var(--ltg-text-secondary); font-size: .92rem; }
.rd-card-body { margin: 0; color: var(--ltg-text-secondary); }
.rd-card-foot {
  display: flex; align-items: center; gap: var(--ltg-space-8); flex-wrap: wrap;
  margin: var(--ltg-space-12) 0 0;
}

.rd-link {
  color: var(--ltg-link); font-weight: 600; text-decoration: none;
  text-underline-offset: 3px;
}
.rd-link:hover { text-decoration: underline; }
.rd-hint { margin: var(--ltg-space-4) 0 0; color: var(--ltg-text-secondary); font-size: .85rem; }
.rd-optional { color: var(--ltg-text-secondary); font-weight: 400; font-size: .85em; }

/* ---------------- State chip ----------------
   Word first, dot second. The dot is aria-hidden in the markup, so the
   word is the whole accessible name -- colour only ever decorates it. */
.rd-state {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 999px;
  font-size: .78rem; font-weight: 700; line-height: 1.4; white-space: nowrap;
  border: 1px solid transparent;
}
.rd-state-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.rd-state--live    { color: var(--ltg-live); background: var(--ltg-live-surface); }
.rd-state--pending { color: var(--ltg-warning); background: var(--ltg-warning-surface); }
.rd-state--neutral { color: var(--ltg-text-secondary); background: var(--ltg-subtle); }
.rd-state--planned { color: var(--ltg-link); background: var(--ltg-subtle); border-color: var(--ltg-divider); }
/* Recording pulses -- but only when motion is welcome, and the word
   "Recording" says it either way. */
.rd-state--live .rd-state-dot { animation: rd-pulse 1.6s ease-in-out infinite; }
@keyframes rd-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .rd-state--live .rd-state-dot { animation: none; } }

/* ---------------- Sessions home: banners + prompts ---------------- */
.rd-live-banner {
  display: flex; align-items: center; gap: var(--ltg-space-12); flex-wrap: wrap;
  padding: var(--ltg-space-12) var(--ltg-space-16);
  border-radius: var(--ltg-radius-card);
  background: var(--ltg-live-surface);
  border: 1px solid color-mix(in srgb, var(--ltg-live) 35%, transparent);
}
.rd-live-banner-head { display: flex; align-items: center; gap: var(--ltg-space-12); flex: 1 1 14rem; }
.rd-live-title { margin: 0; font-size: 1rem; color: var(--ltg-text); }
.rd-live-list { display: flex; align-items: center; gap: var(--ltg-space-8); flex-wrap: wrap; }

/* Record now (sessions_home.html header) -- red like every other
   "recording" signal in the app, distinct from New session's navy so
   the two don't read as equally-weighted alternatives. */
.rd-record-now {
  background: var(--ltg-live-solid); color: #fff; border-color: var(--ltg-live-solid);
}
.rd-record-now:hover { background: color-mix(in srgb, var(--ltg-live-solid) 85%, black); border-color: color-mix(in srgb, var(--ltg-live-solid) 85%, black); }

.rd-prompts {
  display: grid; gap: var(--ltg-space-16);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}

/* ---------------- Sessions list ---------------- */
.rd-sessions { padding: var(--ltg-space-24) var(--ltg-space-24) var(--ltg-space-8); }
.rd-sessions-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--ltg-space-16); flex-wrap: wrap; margin-bottom: var(--ltg-space-8);
}
.rd-sessions-head h2 { margin: 0; font-size: var(--text-section); line-height: var(--text-section-lh); color: var(--ltg-text); }

.rd-search { flex: 0 1 20rem; min-width: 0; }
.rd-search-label, .rd-field-label { display: block; font-size: .8rem; color: var(--ltg-text-secondary); margin-bottom: var(--ltg-space-4); }
.rd-search-field { display: flex; align-items: center; gap: var(--ltg-space-8); }
.rd-search-field input {
  flex: 1; min-width: 0; min-height: var(--ltg-target);
  padding: 0 var(--ltg-space-12);
  border: 1px solid var(--ltg-control-border); border-radius: var(--ltg-radius-control);
  background: var(--ltg-surface); color: var(--ltg-text); font: inherit;
}
.rd-search-clear { font-size: .85rem; color: var(--ltg-link); white-space: nowrap; }
.rd-filter-note { margin: 0 0 var(--ltg-space-8); color: var(--ltg-text-secondary); font-size: .9rem; }

.rd-session-list { list-style: none; margin: 0; padding: 0; }
.rd-session-row {
  display: grid; align-items: center; gap: var(--ltg-space-8) var(--ltg-space-16);
  grid-template-columns: minmax(0, 1fr) auto auto;
  padding: var(--ltg-space-16) 0;
  border-top: 1px solid var(--ltg-divider);
}
.rd-session-row:first-child { border-top: 0; }
.rd-session-main { min-width: 0; }
.rd-session-title {
  display: block; color: var(--ltg-text); font-weight: 600; text-decoration: none;
  overflow-wrap: anywhere;
}
.rd-session-title:hover { color: var(--ltg-link); text-decoration: underline; }
.rd-session-meta { margin: var(--ltg-space-4) 0 0; color: var(--ltg-text-secondary); font-size: .86rem; }
.rd-session-status { display: flex; gap: var(--ltg-space-4); flex-wrap: wrap; justify-content: flex-end; }
.rd-session-actions { display: flex; align-items: center; gap: var(--ltg-space-4); }
.rd-row-delete { margin: 0; }
/* `button.rd-icon-btn`, not `.rd-icon-btn`: style.css paints every
   `button[type="submit"]` as a filled primary button at specificity
   (0,1,1), which beats a bare class (0,1,0). That turned the row's trash
   control into a solid navy block -- louder than the row's own Open
   action, for the one action a person should reach for least. Element +
   class is (0,1,1) too, and later-loading wins the tie. */
button.rd-icon-btn,
.rd-icon-btn {
  display: inline-grid; place-items: center;
  width: 36px; height: 36px; padding: 0;
  border: 1px solid transparent; border-radius: var(--ltg-radius-control);
  background: transparent; color: var(--ltg-text-secondary); cursor: pointer;
}
button.rd-icon-btn:hover,
.rd-icon-btn:hover { color: var(--ltg-danger); border-color: var(--ltg-divider); background: var(--ltg-danger-surface); }

.rd-empty { text-align: center; padding: var(--ltg-space-48) var(--ltg-space-16); }
.rd-empty h3 { margin: 0 0 var(--ltg-space-8); font-size: 1.1rem; color: var(--ltg-text); }
.rd-empty p { margin: 0 auto var(--ltg-space-16); max-width: 32rem; color: var(--ltg-text-secondary); }

/* "More ways to capture" -- a <details> menu, so it works with no JS and
   is keyboard-operable by construction. */
.rd-more { position: relative; }
/* The ⋯ beside New session is an icon button (35px, 44 on touch) next to a
   52px primary -- visibly shorter. Stretched to the row and squared, so the
   two read as one set. */
.rd-page-actions > .rd-more { align-self: stretch; }
.rd-page-actions > .rd-more > summary { height: 100%; width: 52px; box-sizing: border-box; }
.rd-more > summary { list-style: none; cursor: pointer; }
.rd-more > summary::-webkit-details-marker { display: none; }
.rd-more-menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 30;
  min-width: 17rem; padding: var(--ltg-space-4);
  background: var(--ltg-surface); border: 1px solid var(--ltg-divider);
  border-radius: var(--ltg-radius-card); box-shadow: var(--shadow-overlay);
}
.rd-more-item {
  display: flex; flex-direction: column; gap: 2px; width: 100%;
  padding: var(--ltg-space-12); text-align: left; text-decoration: none;
  background: none; border: 0; border-radius: var(--ltg-radius-control);
  color: var(--ltg-text); font: inherit; cursor: pointer;
}
.rd-more-item:hover { background: var(--ltg-subtle); }
.rd-more-title { font-weight: 600; }
.rd-more-help { font-size: .82rem; color: var(--ltg-text-secondary); }

/* ---------------- New session: stepper ---------------- */
.rd-stepper {
  list-style: none; margin: 0; padding: 0 0 var(--ltg-space-12);
  display: flex; gap: var(--ltg-space-16); flex-wrap: wrap;
  border-bottom: 3px solid var(--ltg-divider); position: relative;
  font-size: .88rem; color: var(--ltg-text-secondary);
}
.rd-step { display: inline-flex; align-items: center; gap: var(--ltg-space-8); }
.rd-step-num {
  display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%;
  border: 1px solid var(--ltg-control-border); font-size: .75rem; font-weight: 700;
}
.rd-step.is-current { color: var(--ltg-text); font-weight: 700; }
.rd-step.is-current .rd-step-num { background: var(--ltg-action); color: var(--ltg-on-action); border-color: var(--ltg-action); }
/* The one orange on this screen: the progress marker. Orange is signal in
   this system (~5% of a composition), and "you are here" is exactly a
   signal. It never carries text. */
.rd-stepper::after {
  content: ""; position: absolute; left: 0; bottom: -3px; height: 3px; width: 33.333%;
  background: var(--ltg-orange); border-radius: 3px;
}

/* ---------------- New session: choice cards ---------------- */
.rd-choice-group { border: 1px solid var(--ltg-divider); margin: 0; }
.rd-card-legend { padding: 0; margin-bottom: var(--ltg-space-16); float: left; width: 100%; }
.rd-card-legend + * { clear: both; }
.rd-card-legend-title { display: block; font-size: 1.2rem; font-weight: 700; color: var(--ltg-text); }
.rd-card-legend-help { display: block; margin-top: var(--ltg-space-4); color: var(--ltg-text-secondary); font-size: .92rem; font-weight: 400; }

.rd-choice-grid { display: grid; gap: var(--ltg-space-12); }
.rd-choice-grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 12.5rem), 1fr)); }

.rd-choice {
  position: relative; display: flex; align-items: flex-start; gap: var(--ltg-space-12);
  min-height: var(--ltg-target);
  padding: var(--ltg-space-12) var(--ltg-space-16);
  border: 1px solid var(--ltg-control-border); border-radius: var(--ltg-radius-control);
  background: var(--ltg-surface); cursor: pointer;
  transition: border-color var(--ltg-motion-fast), background var(--ltg-motion-fast);
}
.rd-choice input { margin: 3px 0 0; width: 18px; height: 18px; flex: none; accent-color: var(--ltg-action); }
.rd-choice-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rd-choice-title { display: inline-flex; align-items: center; gap: .4rem; font-weight: 600; color: var(--ltg-text); }
.rd-choice-icon { flex: none; color: var(--ltg-text-secondary); }
.rd-choice-brand-icons { display: inline-flex; align-items: center; gap: 3px; flex: none; }
.rd-choice-brand-icons svg { display: block; border-radius: 5px; }
.rd-choice-help { font-size: .84rem; color: var(--ltg-text-secondary); }
.rd-choice:hover { border-color: var(--ltg-action); }
/* Selected: a heavier border AND a tint, plus the native checked radio --
   three signals, none of them colour alone. */
.rd-choice:has(input:checked) {
  border-color: var(--ltg-action); background: var(--ltg-subtle);
  box-shadow: inset 0 0 0 1px var(--ltg-action);
}
/* Focus lands on the radio; show it on the whole card too so it's visible
   at a glance, without replacing the radio's own ring. */
.rd-choice:has(input:focus-visible) { outline: 3px solid var(--ltg-focus); outline-offset: 2px; }
.rd-choice.is-unavailable { cursor: not-allowed; opacity: .6; }
.rd-choice.is-unavailable:hover { border-color: var(--ltg-control-border); }

/* ---------------- New session: fields ---------------- */
.rd-source-panel {
  margin-top: var(--ltg-space-16); padding-top: var(--ltg-space-16);
  border-top: 1px solid var(--ltg-divider);
  display: flex; flex-direction: column; gap: var(--ltg-space-12);
}
.rd-source-note { margin: 0; color: var(--ltg-text-secondary); }
.rd-source-note.is-error {
  color: var(--ltg-danger); background: var(--ltg-danger-surface);
  padding: var(--ltg-space-12) var(--ltg-space-16); border-radius: var(--ltg-radius-control);
}

.rd-field-row {
  display: grid; gap: var(--ltg-space-16);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  align-items: start;
}
.rd-field { display: flex; flex-direction: column; gap: var(--ltg-space-4); min-width: 0; margin: 0; }
.rd-field > label, .rd-fieldset > legend { font-weight: 600; color: var(--ltg-text); font-size: .95rem; padding: 0; }
/* style.css makes every <label> a grid (for its label-wraps-input forms),
   which stacks a label's "(optional)" under its own text and knocks a row
   of fields out of line. These labels are text only. */
.rd-field > label { display: block; }
.rd-field input[type="text"], .rd-field input[type="url"], .rd-field input[type="datetime-local"],
.rd-field select, .rd-field textarea {
  width: 100%; min-height: var(--ltg-target); box-sizing: border-box;
  padding: var(--ltg-space-8) var(--ltg-space-12);
  border: 1px solid var(--ltg-control-border); border-radius: var(--ltg-radius-control);
  background: var(--ltg-surface); color: var(--ltg-text); font: inherit;
}
.rd-field textarea { resize: vertical; line-height: 1.5; }
.rd-field input[type="file"] { font: inherit; color: var(--ltg-text-secondary); max-width: 100%; }
.rd-field [aria-invalid="true"] { border-color: var(--ltg-danger); box-shadow: inset 0 0 0 1px var(--ltg-danger); }
.rd-field-error { margin: 0; color: var(--ltg-danger); font-size: .86rem; font-weight: 600; }
.rd-field-inline { display: flex; align-items: center; gap: var(--ltg-space-12); flex-wrap: wrap; }
.rd-field-inline input { flex: 1 1 14rem; }
.rd-fieldset { border: 0; padding: 0; }
.rd-fieldset > legend { margin-bottom: var(--ltg-space-8); }
.rd-choice-inline {
  display: inline-flex; align-items: center; gap: var(--ltg-space-8);
  min-height: 32px; margin-right: var(--ltg-space-16); cursor: pointer; color: var(--ltg-text);
}
/* Checkbox and radio only: a label can also hold a text field ("After
   [7] days"), which this would otherwise crush to 18px. */
.rd-choice-inline input[type="checkbox"],
.rd-choice-inline input[type="radio"] { width: 18px; height: 18px; accent-color: var(--ltg-action); }

.rd-disclosure {
  margin-top: var(--ltg-space-16);
  background: var(--ltg-subtle); border-radius: var(--ltg-radius-control);
}
.rd-disclosure > summary {
  cursor: pointer; padding: var(--ltg-space-12) var(--ltg-space-16);
  min-height: var(--ltg-target); box-sizing: border-box;
  display: flex; align-items: center; gap: var(--ltg-space-8);
  font-weight: 600; color: var(--ltg-link);
}
.rd-disclosure-body {
  padding: 0 var(--ltg-space-16) var(--ltg-space-16);
  display: flex; flex-direction: column; gap: var(--ltg-space-16);
}

.rd-confirm {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--ltg-space-16); flex-wrap: wrap;
  margin-top: var(--ltg-space-24); padding-top: var(--ltg-space-16);
  border-top: 1px solid var(--ltg-divider);
}
.rd-confirm-summary { margin: 0; flex: 1 1 18rem; color: var(--ltg-text-secondary); }
.rd-confirm .button { display: inline-flex; align-items: center; gap: var(--ltg-space-8); min-height: var(--ltg-target); }
.rd-cancel { padding: var(--ltg-space-8) var(--ltg-space-12); }

/* ---------------- Request-a-recording page ---------------- */
.rd-form { display: flex; flex-direction: column; gap: var(--ltg-space-16); }
.rd-permission-preview {
  padding: var(--ltg-space-16); border-radius: var(--ltg-radius-control);
  background: var(--ltg-subtle); border: 1px solid var(--ltg-divider);
}
.rd-permission-preview ul { margin: var(--ltg-space-4) 0 var(--ltg-space-12); padding-left: 1.25rem; color: var(--ltg-text); }
.rd-preview-title { margin: 0; font-weight: 700; color: var(--ltg-text); }
.rd-form-actions { display: flex; justify-content: flex-end; gap: var(--ltg-space-8); flex-wrap: wrap; }

/* ===================================================================
   Live session workspace (session_live.html)
   =================================================================== */

/* The capture bar. Persistent -- it sticks under the top bar while the
   transcript and brief scroll beneath it, because the brief is explicit
   that recording state must be "unmistakable", and a control that scrolls
   out of view is a state you can lose track of. Navy in both themes: the
   same "the chassis doesn't change colour" rule the sidebar follows, and
   the one surface on this page that is about the machine rather than the
   meeting. */
.rd-capture-bar {
  position: sticky; top: 60px; z-index: 12;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--ltg-space-12) var(--ltg-space-16);
  padding: var(--ltg-space-16) var(--ltg-space-24);
  border-radius: var(--ltg-radius-card);
  background: var(--ltg-navy); color: #F4F7FA;
  box-shadow: var(--shadow-raised);
}
.rd-capture-bar[hidden] { display: none; }
.rd-capture-status { display: flex; align-items: center; gap: var(--ltg-space-12); flex-wrap: wrap; min-width: 0; }
.rd-capture-clock {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: 1.15rem; font-weight: 700; letter-spacing: .02em; color: #fff;
}
.rd-capture-source { color: var(--ltg-blue); font-size: .92rem; font-weight: 600; }
.rd-capture-actions { display: flex; align-items: center; gap: var(--ltg-space-8); flex-wrap: wrap; }
/* A control label never wraps at any width -- the row rearranges instead
   (see the narrow-screen rules). */
.rd-capture-actions > .button { white-space: nowrap; }
/* Paused: Resume is the action to take, so it looks like Record does --
   not style.css's amber is-paused treatment, which on the navy bar read as
   a brown box with orange text and competed with the Paused chip beside it. */
.rd-capture-bar #pause-btn.is-paused {
  background: var(--ltg-blue); color: var(--ltg-navy); border-color: var(--ltg-blue);
}

/* State chip ON the navy bar. The page-level tones are tuned for a light or
   midnight surface; on navy they need their own values to hold contrast. */
.rd-capture-bar .rd-state { border: 1px solid rgba(255,255,255,.18); }
.rd-capture-bar .rd-state--neutral { color: #F4F7FA; background: rgba(255,255,255,.10); }
.rd-capture-bar .rd-state--live    { color: #0B1725; background: #FFADB8; }
.rd-capture-bar .rd-state--pending { color: #0B1725; background: #FFC781; }
.rd-capture-bar .rd-state--planned { color: #F4F7FA; background: rgba(143,185,216,.25); }

/* Buttons on the bar: light fills, so they read as controls against navy
   rather than disappearing into it. */
.rd-capture-bar .button.secondary,
.rd-capture-bar button.button.secondary {
  background: #fff; color: var(--ltg-navy); border-color: #fff;
}
.rd-capture-bar .button.secondary:hover { background: #EDF3F7; }
.rd-capture-bar .button.primary,
.rd-capture-bar button.rd-record-btn {
  background: var(--ltg-blue); color: var(--ltg-navy); border-color: var(--ltg-blue);
  display: inline-flex; align-items: center; gap: var(--ltg-space-8);
}
/* End is the one destructive control, and it looks it -- but it is a
   solid, labelled button, never red text alone. */
.button.rd-end-btn,
button.rd-end-btn {
  background: var(--ltg-danger); color: #fff; border-color: var(--ltg-danger);
}
[data-theme="dark"] .button.rd-end-btn, [data-theme="dark"] button.rd-end-btn {
  background: #C8334A; border-color: #C8334A; color: #fff;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .button.rd-end-btn,
  :root:not([data-theme="light"]) button.rd-end-btn { background: #C8334A; border-color: #C8334A; color: #fff; }
}
.rd-capture-bar #mark-btn { display: inline-flex; align-items: center; gap: var(--ltg-space-8); }
/* Off the record / redacted: the button itself changes, in words ("Off the
   record — tap to resume") and colour, so nobody forgets they're in one. */
.rd-capture-bar #mark-btn.mark-open-otr { background: #FFC781; border-color: #FFC781; color: #0B1725; }
.rd-capture-bar #mark-btn.mark-open-redacted { background: #FFB7C2; border-color: #FFB7C2; color: #0B1725; }

.rd-capture-choice {
  flex-basis: 100%;
  display: flex; align-items: center; gap: var(--ltg-space-8); flex-wrap: wrap;
  padding-top: var(--ltg-space-12); border-top: 1px solid rgba(255,255,255,.15);
}
.rd-capture-choice[hidden] { display: none; }
.rd-capture-choice-label { font-weight: 700; margin-right: var(--ltg-space-4); }
.rd-capture-bar .rd-link { color: var(--ltg-blue); background: none; border: 0; cursor: pointer; font: inherit; }
.rd-capture-msg { flex-basis: 100%; margin: 0; font-size: .9rem; color: #D7E4EE; }
.rd-capture-msg:empty, .rd-capture-msg[hidden] { display: none; }
.rd-meter { flex-basis: 100%; }
.rd-capture-bar .mic-meter-label { color: #D7E4EE; }
.rd-mic-picker { flex-basis: 100%; }
.rd-capture-bar .rd-mic-picker label { color: #D7E4EE; }
.rd-extend { flex-basis: 100%; }

/* ---------------- Two columns ----------------
   Transcript on the left, brief on the right, at desktop widths; stacked
   below 1024px. The transcript scrolls inside its own card so the brief
   next to it stays in view -- a two-hour meeting is a very long page. */
.rd-live-grid {
  display: grid; gap: var(--ltg-space-16);
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  align-items: start;
}
/* Quick start (templates/quick_start.html) -- one button, centered,
   nothing else competing for a thumb reaching for it one-handed. Fills
   the actual viewport rather than a fixed top margin, so it lands in
   the middle of the screen instead of the middle of a mostly-empty page. */
.rd-quick-start-center {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: var(--ltg-space-8); max-width: 22rem; margin: 0 auto; padding: var(--ltg-space-16);
  min-height: calc(100dvh - 180px); justify-content: center;
}
.rd-quick-start-center h1 { margin: 0; }
.rd-quick-start-center .rd-lede { margin-bottom: var(--ltg-space-8); }
/* A big circular shutter, not a form button -- the whole point of this
   page is that there is exactly one thing to press. Filled with
   --ltg-live-solid (the same red the app now uses everywhere for
   "recording") so the color itself says what tapping it does. */
.rd-quick-record-btn {
  width: 132px; height: 132px; border-radius: 50%; border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  background: var(--ltg-live-solid); color: #fff; margin: var(--ltg-space-8) 0;
  transition: transform .12s ease;
  animation: rd-record-ring 2.2s ease-out infinite;
}
.rd-quick-record-btn:active { transform: scale(0.96); }
.rd-quick-record-btn:disabled { opacity: .55; animation: none; cursor: default; }
.rd-quick-record-label { margin: 0; font-weight: 600; color: var(--ltg-text-secondary); }
.rd-quick-start-back { margin-top: var(--ltg-space-8); }
@keyframes rd-record-ring {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ltg-live-solid) 45%, transparent); }
  70%  { box-shadow: 0 0 0 22px color-mix(in srgb, var(--ltg-live-solid) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) { .rd-quick-record-btn { animation: none; } }
.rd-live-col { min-width: 0; }
.rd-brief-col { display: flex; flex-direction: column; gap: var(--ltg-space-16); }

/* Workflow diagram (React/ReactFlow island -- see static/vendor/reactflow/).
   The canvas itself is styled by the vendored bundle's own CSS; this is
   just the wrapper card/toolbar, kept consistent with every other card. */
.rd-workflow-card { min-width: 0; }
.rd-workflow-toolbar {
  display: flex; align-items: center; gap: var(--ltg-space-12); flex-wrap: wrap;
  margin-bottom: var(--ltg-space-8);
}
.rd-workflow-root { min-height: 3rem; }
.rd-workflow-empty { display: flex; flex-direction: column; align-items: flex-start; gap: var(--ltg-space-8); }

.rd-transcript-card { position: sticky; top: 180px; }
.rd-transcript-scroll {
  overflow-y: auto;
  margin: 0 calc(-1 * var(--ltg-space-8)); padding: 0 var(--ltg-space-8);
  overscroll-behavior: contain;
}
/* Closed captions (default, not .is-expanded): no different formatting from
   the full transcript below -- same type, same speaker labels -- just a
   short, scrollable box instead of a tall one. Newest-first ordering (see
   transcript.html) already puts the words just said at the top, so a short
   box shows exactly those without any JS scroll-position management. */
.rd-transcript-scroll:not(.is-expanded) {
  max-height: 9rem; min-height: 0;
}
.rd-transcript-scroll.is-expanded {
  max-height: calc(100vh - 300px); min-height: 12rem;
}
.rd-transcript-scroll:focus-visible { outline-offset: 0; }
/* The embedded transcript panel brings its own .panel chrome; inside a card
   that's a box in a box. */
.rd-transcript-scroll > .panel { border: 0; padding: 0; margin: 0; background: transparent; box-shadow: none; }
.rd-transcript-foot { margin-top: var(--ltg-space-12); }
/* No speaker label, no timestamp, no per-line mark control -- just the
   words, the way they were said, the way an actual caption reads. See
   .rd-live .mark-icon just below for why the mark control is already
   hidden on this page regardless; .meta/.u-speaker/.u-at are this view's
   own equivalent trim, restored in full under .is-expanded. */
.rd-transcript-scroll:not(.is-expanded) .meta,
.rd-transcript-scroll:not(.is-expanded) .u-speaker,
.rd-transcript-scroll:not(.is-expanded) .u-at {
  display: none;
}
/* marks.js isn't loaded here (it reloads the page after a mark, which would
   kill the recording), so the per-line mark controls would be dead -- hide
   them rather than show a button that does nothing. Existing bookmarks'
   pins stay: they're display, not controls. The capture bar's Mark button
   is how a moment is marked while recording. */
.rd-live .mark-icon, .rd-live #mark-popover { display: none !important; }
/* No player on this page, so a line isn't click-to-seek; don't imply it. */
.rd-live .live-transcript-line .utterance[data-at] { cursor: default; }
.rd-live .live-transcript-line .utterance[data-at]:hover { background: none; }

.rd-brief-card .current-topic { margin-bottom: var(--ltg-space-16); }
.rd-brief-card #live-summary-panel { border: 0; padding: 0; margin: 0; background: transparent; box-shadow: none; }

/* ---------------- Add to this meeting ---------------- */
.rd-add-card h2 { margin: 0 0 var(--ltg-space-12); font-size: var(--text-section); line-height: var(--text-section-lh); color: var(--ltg-text); }
.rd-add-tabs { display: flex; gap: var(--ltg-space-8); flex-wrap: wrap; }
.rd-add-tabs .button[aria-expanded="true"] {
  background: var(--ltg-subtle); border-color: var(--ltg-action);
  box-shadow: inset 0 0 0 1px var(--ltg-action);
}
.rd-add-panel { margin-top: var(--ltg-space-16); padding-top: var(--ltg-space-16); border-top: 1px solid var(--ltg-divider); }
.rd-add-panel[hidden] { display: none; }
.rd-add-section + .rd-add-section { margin-top: var(--ltg-space-24); }
.rd-add-section h3 { margin: 0 0 var(--ltg-space-4); font-size: 1rem; color: var(--ltg-text); }
.rd-inline-form { display: flex; gap: var(--ltg-space-8); margin-top: var(--ltg-space-8); }
.rd-inline-form input {
  flex: 1; min-width: 0; min-height: var(--ltg-target); padding: 0 var(--ltg-space-12);
  border: 1px solid var(--ltg-control-border); border-radius: var(--ltg-radius-control);
  background: var(--ltg-surface); color: var(--ltg-text); font: inherit;
}

/* ---------------- Share panel ---------------- */
.rd-share-panel[hidden] { display: none; }
.rd-share-now { margin: 0 0 var(--ltg-space-16); color: var(--ltg-text); }
.rd-share-options { display: grid; gap: var(--ltg-space-16); grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); margin-bottom: var(--ltg-space-12); }
.rd-share-option .button { width: 100%; justify-content: center; }
.rd-share-close { background: none; border: 0; cursor: pointer; font: inherit; }
.rd-full-link { padding: var(--ltg-space-8) var(--ltg-space-4); }

/* ---------------- End dialog ---------------- */
.rd-dialog {
  max-width: min(28rem, calc(100vw - 32px)); padding: var(--ltg-space-24);
  border: 1px solid var(--ltg-divider); border-radius: var(--ltg-radius-dialog);
  background: var(--ltg-surface); color: var(--ltg-text);
  box-shadow: var(--shadow-overlay);
}
.rd-dialog::backdrop { background: rgb(11 23 37 / .55); }
.rd-dialog h2 { margin: 0 0 var(--ltg-space-8); font-size: 1.25rem; }
.rd-dialog p { margin: 0 0 var(--ltg-space-24); color: var(--ltg-text-secondary); }
.rd-dialog-actions { display: flex; justify-content: flex-end; gap: var(--ltg-space-8); flex-wrap: wrap; }

@media (max-width: 1023px) {
  .rd-live-grid { grid-template-columns: minmax(0, 1fr); }
  .rd-transcript-card { position: static; }
  .rd-transcript-scroll.is-expanded { max-height: 55vh; }
}

/* ================= Review workspace (session_detail.html) ================= */

/* Review status: says "AI draft" or "Reviewed" in words; the chip and tint
   only restate it. */
.rd-review-notice {
  display: flex; align-items: center; gap: var(--ltg-space-8) var(--ltg-space-16); flex-wrap: wrap;
  padding: var(--ltg-space-12) var(--ltg-space-16);
  background: var(--ltg-warning-surface); border: 1px solid var(--ltg-divider);
  border-radius: var(--ltg-radius-card);
}
.rd-review-notice.is-reviewed { background: var(--ltg-surface); }
.rd-review-notice p { margin: 0; flex: 1 1 18rem; color: var(--ltg-text); font-size: .92rem; }
.rd-review-notice form { margin: 0; }

/* Tabs. The selected one is marked by weight, an underline AND
   aria-selected -- never by colour alone. */
.rd-tabs {
  display: flex; gap: var(--ltg-space-4);
  border-bottom: 1px solid var(--ltg-divider);
}
.rd-tab {
  display: inline-flex; align-items: center; gap: var(--ltg-space-8);
  min-height: var(--ltg-target); padding: 0 var(--ltg-space-16);
  margin-bottom: -1px; border: 0; border-bottom: 3px solid transparent;
  background: none; color: var(--ltg-text-secondary);
  font: inherit; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.rd-tab:hover { color: var(--ltg-text); }
.rd-tab[aria-selected="true"] { color: var(--ltg-text); border-bottom-color: var(--ltg-action); }
.rd-tab:focus-visible { outline: 3px solid var(--ltg-focus); outline-offset: -3px; border-radius: 6px 6px 0 0; }
.rd-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 22px; padding: 0 6px; box-sizing: border-box;
  border-radius: 999px; background: var(--ltg-warning-surface); color: var(--ltg-warning);
  font-size: .78rem; font-weight: 700; line-height: 1;
}
.rd-tabpanel { display: flex; flex-direction: column; gap: var(--ltg-space-16); min-width: 0; }
.rd-tabpanel[hidden] { display: none; }
.rd-tabpanel:focus-visible { outline: 3px solid var(--ltg-focus); outline-offset: 4px; border-radius: 4px; }
/* Inside a tab the transcript isn't a collapsible section any more, so it
   needs a height cap or a long meeting becomes an endless page. */
.rd-review .live-transcript { max-height: 70vh; }

/* Brief: the notes, with what to do next and who was there beside them. */
.rd-review-grid {
  display: grid; gap: var(--ltg-space-16);
  grid-template-columns: minmax(0, 1fr) minmax(0, 22rem); align-items: start;
}
.rd-review-main, .rd-review-side { display: flex; flex-direction: column; gap: var(--ltg-space-16); min-width: 0; }
.rd-review-main > .panel, .rd-review-side > .panel { margin-bottom: 0; }
.rd-brief-edit { margin-top: 0; }
@media (max-width: 1023px) {
  .rd-review-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Next steps: each state written out ("Done", "To do", "2 waiting"). */
.rd-checklist { list-style: none; margin: var(--ltg-space-12) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--ltg-space-12); }
.rd-checklist li { display: grid; grid-template-columns: 5.5rem minmax(0, 1fr); gap: var(--ltg-space-8); align-items: baseline; color: var(--ltg-text); }
.rd-check-state {
  font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ltg-warning);
}
.rd-checklist li.is-done .rd-check-state { color: var(--ltg-success); }
.rd-checklist li.is-done > span:last-child { color: var(--ltg-text-secondary); }

/* People: the speaker labels exactly as the transcript has them. */
.rd-people { list-style: none; margin: var(--ltg-space-8) 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--ltg-space-8); }
.rd-people li {
  padding: 4px 12px; border-radius: 999px; background: var(--ltg-subtle);
  color: var(--ltg-text); font-weight: 600; font-size: .9rem;
}
.rd-people-fix { margin-top: var(--ltg-space-16); }
/* The side column is ~22rem: the field needs ~13rem before its button sits
   beside it, or the button drops under it -- rather than the field being
   squeezed until its placeholder is cut off. Above 650px only: below it
   style.css makes .ai-ask-form a column, where a 13rem flex-basis would
   set the field's HEIGHT. */
@media (min-width: 651px) {
  .rd-review-side .ai-ask-form { flex-wrap: wrap; }
  .rd-review-side .ai-ask-form > input { flex: 1 1 13rem; min-width: 0; }
}

/* Actions: suggestions to confirm, then this meeting's follow-ups. */
.rd-card-count { color: var(--ltg-text-secondary); font-weight: 400; font-size: .95rem; }
.rd-suggestions { list-style: none; margin: var(--ltg-space-16) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--ltg-space-12); }
.rd-suggestion {
  display: flex; flex-direction: column; gap: var(--ltg-space-12);
  padding: var(--ltg-space-16); border: 1px solid var(--ltg-divider);
  border-left: 4px solid var(--ltg-warning); border-radius: var(--ltg-radius-control);
  background: var(--ltg-surface);
}
.rd-suggestion-form { display: flex; flex-direction: column; gap: var(--ltg-space-12); margin: 0; }
.rd-suggestion-form input[type="date"] {
  width: 100%; min-height: var(--ltg-target); box-sizing: border-box;
  padding: var(--ltg-space-8) var(--ltg-space-12);
  border: 1px solid var(--ltg-control-border); border-radius: var(--ltg-radius-control);
  background: var(--ltg-surface); color: var(--ltg-text); font: inherit;
}
.rd-field-row .rd-field .rd-hint { margin: 0; }
.rd-evidence { display: flex; flex-direction: column; align-items: flex-start; gap: var(--ltg-space-4); }
.rd-evidence .quote { margin: 0; }
.rd-suggestion-actions { display: flex; gap: var(--ltg-space-8); flex-wrap: wrap; }
.rd-suggestion-actions form { margin: 0; }
.rd-add-action .rd-disclosure-body { padding-top: var(--ltg-space-4); }
.rd-card .record-list { margin-top: var(--ltg-space-8); }

/* More menu: the export group sits above the one-off actions. */
.rd-review-more .rd-more-menu { min-width: 18rem; }
.rd-more-group {
  margin: 0; font-size: .75rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ltg-text-secondary);
}
.rd-export { display: flex; flex-direction: column; gap: var(--ltg-space-8); padding: var(--ltg-space-12); margin: 0; }
.rd-export select { width: 100%; min-height: var(--ltg-target); }
.rd-export .rd-hint { margin: 0; }
.rd-export-buttons { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--ltg-space-8); }
.rd-export-buttons .button { justify-content: center; padding-left: 8px; padding-right: 8px; }
.rd-review-more .session-email {
  display: flex; flex-direction: column; gap: var(--ltg-space-8);
  padding: 0 var(--ltg-space-12) var(--ltg-space-12);
}
.rd-review-more .session-email[hidden] { display: none; }
.rd-review-more .session-email input { width: 100%; box-sizing: border-box; }
.rd-more-rule { height: 1px; margin: var(--ltg-space-4) 0; background: var(--ltg-divider); }
.rd-more-item.is-danger .rd-more-title { color: var(--ltg-danger); }
.rd-more-menu form { margin: 0; }

/* Session-wide tools under the tabs. style.css's own spacing for these
   disclosures was keyed to the old page's header, so it's restated here:
   one even 16px rhythm, and none of the dashboard's 32px share margin. */
/* Set apart from the tabs with a rule: these are about the whole session,
   not whichever tab is open above them. */
.rd-review-tools {
  display: flex; flex-direction: column;
  border-top: 1px solid var(--ltg-divider); padding-top: var(--ltg-space-4);
}
.rd-review .rd-card > h2 { margin-bottom: var(--ltg-space-8); }
/* Inside a tab the panel's flex gap is the only spacing, so the partials'
   own margins don't stack on top of it into uneven gaps. */
.rd-tabpanel > .panel, .rd-tabpanel > div > .panel, .rd-review-main > div > .panel { margin-bottom: 0; }
.rd-review .rd-tabpanel > .chunks-section-toggle { margin-top: 0; }
.rd-tabpanel > .transcript-download { margin: 0; }
.rd-suggestion-form input[type="text"], .rd-suggestion-form input[type="date"] { height: var(--ltg-target); }
/* Sized to its text where the browser can (Chrome, Edge); two rows where it
   can't. Either way a long action wraps instead of being cut off. */
.rd-suggestion-form textarea { field-sizing: content; min-height: var(--ltg-target); }
/* A follow-up stays one row on a phone -- tick, text, delete. style.css
   stacks every .record below 650px, which left the delete button alone on
   a line under the item it deletes. */
.rd-review .record.action-item { flex-direction: row; align-items: flex-start; }
/* The tick box: 24px to see (it was 22, under the SC 2.5.8 floor), and on a
   touch screen a 44px hit area around it that doesn't make the box itself
   any bigger. */
.rd-review .action-item-check { width: 24px; height: 24px; position: relative; }
/* It's a submit button, and style.css's button[type="submit"] outranks its
   own .action-item-check -- so an UNticked box was painted solid navy (light
   blue in Midnight), reading as already done. Empty until it's done. */
.rd-review .action-item-check {
  background: var(--ltg-surface); color: var(--ltg-success);
  border: 1.5px solid var(--ltg-control-border);
}
.rd-review .action-item.is-done .action-item-check {
  background: var(--ltg-success-surface); border-color: var(--ltg-success);
}
@media (pointer: coarse) {
  .rd-review .action-item-check::after { content: ""; position: absolute; inset: -10px; }
}

/* Five tabs don't fit one line on a phone. They stay ONE row and scroll
   sideways rather than wrapping -- the 2x2 grid this replaces was sized for
   four tabs and left Workflow alone on a third row, and the style guide
   asks for an overflow pattern, never a tab strip wrapped into ambiguous
   rows. The cut-off last tab is the cue that there's more; arrow keys and
   focus scroll the active tab into view (see session_detail's reveal()). */
@media (max-width: 560px) {
  .rd-tabs { overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; }
  .rd-tabs::-webkit-scrollbar { display: none; }
  .rd-tab { flex: none; padding: 0 var(--ltg-space-12); }
}
.rd-review .chunks-section-toggle { margin-top: var(--ltg-space-16); }
.rd-review .rd-page-heading h1 .badge { vertical-align: middle; font-size: .8rem; }
.rd-subhead { margin: var(--ltg-space-16) 0 var(--ltg-space-8); font-size: 1rem; }

/* Worker capture detail on the live page's capture bar. */
.rd-worker-detail { flex: 1 1 100%; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.rd-worker-what { margin: 0; color: inherit; font-size: .95rem; } /* the bar is navy in both themes */
.rd-worker-what:empty { display: none; }
.rd-worker-facts { margin: 0; color: var(--ltg-blue, #8FB9D8); font-size: .85rem; }
.rd-worker-facts:empty { display: none; }
.rd-worker-level { display: flex; align-items: center; gap: var(--ltg-space-8); font-size: .8rem; color: var(--ltg-blue, #8FB9D8); }
.rd-worker-level[hidden] { display: none; }
.rd-worker-level-track { flex: 0 1 10rem; height: 6px; border-radius: 3px; background: rgb(255 255 255 / .18); overflow: hidden; }
.rd-worker-level-fill { display: block; height: 100%; width: 0; background: var(--ltg-blue, #8FB9D8); transition: width .4s ease; }
.rd-worker-level-word { font-weight: 700; }

/* Review page: a capture still under way, or stopped short. */
.rd-capture-note {
  display: flex; align-items: center; gap: var(--ltg-space-8) var(--ltg-space-16); flex-wrap: wrap;
  padding: var(--ltg-space-12) var(--ltg-space-16); border-radius: var(--ltg-radius-card);
  border: 1px solid var(--ltg-divider); background: var(--ltg-surface);
}
.rd-capture-note--pending { background: var(--ltg-warning-surface); }
.rd-capture-note p { margin: 0; flex: 1 1 18rem; color: var(--ltg-text); font-size: .92rem; }
.rd-capture-note-facts { color: var(--ltg-text-secondary); }

/* The recording, above the review tabs. */
.rd-recording {
  display: flex; flex-direction: column; gap: var(--ltg-space-8);
  padding: var(--ltg-space-12) var(--ltg-space-16);
  background: var(--ltg-surface); border: 1px solid var(--ltg-divider); border-radius: var(--ltg-radius-card);
}
.rd-recording-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--ltg-space-12); flex-wrap: wrap; }
.rd-recording-head h2 { margin: 0; font-size: 1rem; }
.rd-recording .recording-panel,
.rd-recap .recording-panel { margin: 0; padding: 0; border: 0; background: none; box-shadow: none; }
.rd-recording .session-chunk-audio { width: 100%; }
.rd-recording .recording-panel .section-hint,
.rd-recap .recording-panel .section-hint { margin: 4px 0 0; }
.rd-recording .rd-hint { margin: 0; }
.rd-recording-watch { margin-top: 0; }
.rd-recording .session-youtube-panel { margin: 0; padding: 0; border: 0; background: none; }
.rd-no-audio { margin: 0; }

/* Anything the page scrolls to by id (#shared-links, a speaker panel) lands
   below the sticky top bar instead of under it. */
.rd-review [id] { scroll-margin-top: 72px; }

/* ================= Share dialog (_partials/share_dialog.html) ================= */
.rd-share-dialog {
  width: min(34rem, calc(100vw - 32px)); max-width: none;
  max-height: calc(100dvh - 32px); overflow-y: auto; box-sizing: border-box;
}
.rd-share-step { display: flex; flex-direction: column; gap: var(--ltg-space-16); }
.rd-share-step[hidden] { display: none; }
.rd-share-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--ltg-space-12); }
.rd-share-dialog h2 { margin: 0; }
.rd-share-dialog h2:focus { outline: none; }
.rd-share-x { flex: none; margin: -6px -6px 0 0; }
.rd-share-x:hover { color: var(--ltg-text); background: var(--ltg-subtle); border-color: var(--ltg-divider); }
.rd-share-form { display: flex; flex-direction: column; gap: var(--ltg-space-16); margin: 0; }
.rd-share-intents { display: flex; flex-direction: column; gap: var(--ltg-space-8); }
/* The intent cards and option rows are <label>s, which style.css sets at
   13px for its own label-over-field forms. These are the choices, at
   reading size. */
.rd-share-dialog .rd-choice, .rd-share-dialog .rd-choice-inline { font-size: 1rem; font-weight: 400; }
.rd-share-dialog .rd-choice-help { font-size: .88rem; }
.rd-share-dialog .rd-preview-title { font-size: 1rem; }
.rd-recap-blocked {
  display: flex; align-items: center; gap: var(--ltg-space-8) var(--ltg-space-12); flex-wrap: wrap;
  margin-top: calc(-1 * var(--ltg-space-8)); padding: var(--ltg-space-12);
  background: var(--ltg-warning-surface); border-radius: var(--ltg-radius-control);
}
.rd-recap-blocked p { margin: 0; flex: 1 1 14rem; font-size: .9rem; color: var(--ltg-text); }
.rd-share-expiry { display: flex; gap: var(--ltg-space-8); flex-wrap: wrap; align-items: center; }
.rd-share-expiry select { flex: 1 1 12rem; }
.rd-share-days { display: inline-flex; align-items: center; gap: var(--ltg-space-8); color: var(--ltg-text-secondary); }
.rd-share-days[hidden] { display: none; }
.rd-share-days input { width: 5.5rem; min-height: var(--ltg-target); box-sizing: border-box; padding: var(--ltg-space-8); }
.rd-share-more { margin-top: 0; }
.rd-share-more .rd-choice-inline { margin-right: 0; align-items: flex-start; }
.rd-share-more .rd-choice-inline[hidden] { display: none; }
.rd-share-more .rd-choice-inline input[type="checkbox"] { margin-top: 3px; flex: none; }
.rd-share-dialog .rd-dialog-actions { margin: 0; }

/* Permission lines: a word for every line ("Can:" / "Cannot:", read by a
   screen reader), a mark for sighted readers -- never colour alone. */
.rd-perm-list { list-style: none; margin: var(--ltg-space-8) 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.rd-permission-preview .rd-perm-list { padding-left: 0; margin-bottom: var(--ltg-space-8); }
.rd-perm-list li { display: grid; grid-template-columns: 1.25rem minmax(0, 1fr); gap: var(--ltg-space-4); color: var(--ltg-text); font-size: .92rem; }
.rd-perm-list li.is-no { color: var(--ltg-text-secondary); }
.rd-perm-mark { font-weight: 700; }
.rd-perm-list li.is-yes .rd-perm-mark { color: var(--ltg-success); }
.rd-perm-list li.is-no .rd-perm-mark { color: var(--ltg-text-secondary); }
.rd-perm-list li .visually-hidden + * { grid-column: 2; }

.rd-share-url-row { display: flex; gap: var(--ltg-space-8); }
.rd-share-url-row input {
  flex: 1 1 auto; min-width: 0; min-height: var(--ltg-target); box-sizing: border-box;
  padding: var(--ltg-space-8) var(--ltg-space-12); font: inherit;
  border: 1px solid var(--ltg-control-border); border-radius: var(--ltg-radius-control);
  background: var(--ltg-surface); color: var(--ltg-text);
}
.rd-share-url-row .button { flex: none; }
.rd-share-pin-note { padding: var(--ltg-space-12); background: var(--ltg-warning-surface); border-radius: var(--ltg-radius-control); color: var(--ltg-text); }
@media (max-width: 480px) {
  .rd-share-dialog { padding: var(--ltg-space-16); }
  .rd-share-url-row { flex-wrap: wrap; }
  .rd-share-url-row .button { flex: 1 1 100%; justify-content: center; }
  .rd-share-dialog .rd-dialog-actions > * { flex: 1 1 auto; justify-content: center; }
}

/* Shared links: each with its state, who made it, and what it grants. */
.rd-links-head { display: flex; align-items: center; justify-content: space-between; gap: var(--ltg-space-8) var(--ltg-space-16); flex-wrap: wrap; }
.rd-links-head .section-hint { margin: 0; flex: 1 1 16rem; }
.rd-link-list { list-style: none; margin: var(--ltg-space-12) 0 0; padding: 0; display: flex; flex-direction: column; }
.rd-link-row {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--ltg-space-12);
  padding: var(--ltg-space-12) 0; border-top: 1px solid var(--ltg-divider);
}
.rd-link-row:first-child { border-top: 0; }
.rd-link-main { min-width: 0; flex: 1 1 auto; }
.rd-link-title { margin: 0; color: var(--ltg-text); }
.rd-link-row .rd-card-meta { margin: 2px 0 0; }
.rd-link-row.is-revoked .rd-link-title { color: var(--ltg-text-secondary); }
.rd-link-perms { margin-top: var(--ltg-space-4); }
.rd-link-perms > summary { cursor: pointer; color: var(--ltg-link); font-weight: 600; font-size: .88rem; min-height: 24px; display: inline-flex; align-items: center; }

/* The recap page (public_share_recap.html). */
.rd-recap { display: flex; flex-direction: column; gap: var(--ltg-space-16); }
.rd-recap .kiosk-feed-header { margin-bottom: 0; }
.rd-recap-meta { margin: calc(-1 * var(--ltg-space-8)) 0 0; color: var(--ltg-text-secondary); }
.rd-recap-reviewed { display: flex; align-items: center; gap: var(--ltg-space-8); flex-wrap: wrap; margin: 0; color: var(--ltg-text-secondary); font-size: .92rem; }
.rd-recap-actions { display: flex; gap: var(--ltg-space-8); flex-wrap: wrap; }
.rd-recap .panel { margin-bottom: 0; }
.rd-recap-list, .rd-recap-files { list-style: none; margin: var(--ltg-space-8) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--ltg-space-12); }
.rd-recap-list li { display: flex; flex-direction: column; gap: 2px; }
.rd-recap-what { margin: 0; font-weight: 600; color: var(--ltg-text); }
.rd-recap-detail { display: flex; gap: var(--ltg-space-12); flex-wrap: wrap; color: var(--ltg-text-secondary); font-size: .9rem; }
.rd-recap-list li.is-done .rd-recap-what { text-decoration: line-through; color: var(--ltg-text-secondary); }
.rd-recap-files img { display: block; max-width: 100%; max-height: 24rem; border-radius: var(--ltg-radius-control); border: 1px solid var(--ltg-divider); margin-bottom: var(--ltg-space-4); }
.rd-recap-foot { margin: 0; color: var(--ltg-text-secondary); font-size: .85rem; }

/* Admin page: YouTube access (admin.html). Not a rebuilt page -- just
   enough structure for the three steps and the check's result. */
.admin-subhead { margin: var(--ltg-space-16) 0 var(--ltg-space-8); font-size: 1rem; }
.admin-steps { margin: var(--ltg-space-8) 0 var(--ltg-space-12); padding-left: 1.25rem; display: flex; flex-direction: column; gap: 4px; }
.yt-check-result:empty { display: none; }
.yt-check-result { margin-top: var(--ltg-space-12); padding: var(--ltg-space-12) var(--ltg-space-16); border-radius: var(--ltg-radius-control); background: var(--ltg-subtle); }
.yt-check-steps { list-style: none; margin: 0 0 var(--ltg-space-8); padding: 0; display: flex; flex-direction: column; gap: 6px; }
.yt-check-steps li { overflow-wrap: anywhere; }
.yt-check-steps li.is-ok strong { color: var(--ltg-success); }
.yt-check-steps li.is-fail strong { color: var(--ltg-danger); }
.yt-check-hint { margin: 0 0 var(--ltg-space-8); font-weight: 600; color: var(--ltg-text); }

/* Sessions home: the review prompt names what's waiting. */
.rd-review-links { list-style: none; margin: var(--ltg-space-8) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--ltg-space-4); }
.rd-review-links a { display: inline-block; padding: 2px 0; }

/* ---------------- Narrow screens ----------------
   A session row stops being a three-column grid: the title gets the whole
   width, and the state chip and actions share the line under it. Beside
   the title, Open + delete took ~110px and pushed a three-word title onto
   three lines at 320. A wrapping flex row rather than a grid, because at
   320 "Nothing captured" (151px) and the actions (117px) don't both fit --
   a grid column let the chip run under the Open button; flex drops the
   actions to their own line, still right-aligned. */
@media (max-width: 640px) {
  .rd-card, .rd-sessions { padding: var(--ltg-space-16); }
  .rd-session-row { display: flex; flex-wrap: wrap; }
  .rd-session-main { flex: 1 1 100%; }
  .rd-session-status { justify-content: flex-start; }
  .rd-session-actions { margin-left: auto; }
  .rd-page-actions .rd-new-session, .rd-page-actions .rd-record-now { flex: 1; justify-content: center; }
  .rd-live-banner .button { width: 100%; justify-content: center; }
  .rd-confirm .button { width: 100%; justify-content: center; }
  .rd-search { flex-basis: 100%; }
  /* Capture bar on a phone: state + clock on one line, then the controls
     as a row of equal, thumb-sized buttons. The bar stays sticky -- on a
     phone it's the only way to see you're still recording once you scroll. */
  .rd-capture-bar { padding: var(--ltg-space-12); top: 56px; }
  .rd-capture-actions { width: 100%; }
  /* Equal-width buttons that still never shrink below their label:
     flex-basis 0 shares each row equally, and min-width:max-content is what
     line-breaking is decided on -- so when a row can't hold every label, the
     last button drops to its own full-width row instead of squeezing the
     others. Measured: at 393px "Pause | Mark moment" then "End session"; the
     old flex:1 1 0 without a minimum gave each ~107px and "Resume" (needs
     122) split in half. */
  .rd-capture-actions > .button {
    flex: 1 1 0; min-width: max-content; justify-content: center;
    min-height: var(--ltg-target); padding-left: 12px; padding-right: 12px;
  }
  /* Off the record / redacted is the state that matters most while it's on:
     it leads, on its own row. */
  .rd-capture-actions > #mark-btn.mark-open-otr,
  .rd-capture-actions > #mark-btn.mark-open-redacted { order: -1; }
  .rd-page-actions { width: 100%; justify-content: space-between; }
  /* Add to this meeting: Context / Quick note / Capture left "Capture"
     alone on a second row at 393. Same equal-width pattern as the bar. */
  .rd-add-tabs > .button {
    flex: 1 1 0; min-width: max-content; justify-content: center;
    padding-left: 12px; padding-right: 12px;
  }
  .rd-page-heading h1 { text-wrap: balance; }

  /* Review header: Share and the ⋯ menu on the first row, the recording
     link under them. Three buttons don't fit one row at 320 ("Continue
     recording" alone is 180px), and a wrap would orphan whichever lost. A
     grid, not flex, because the ⋯ is a <details>, which Chrome won't size
     by flex-basis. */
  .rd-review .rd-page-actions { display: grid; grid-template-columns: minmax(0, 1fr) 52px; }
  .rd-review .rd-page-actions > [data-share-open] { grid-column: 1; grid-row: 1; justify-content: center; }
  .rd-review .rd-page-actions > .rd-more { grid-column: 2; grid-row: 1; }
  .rd-review .rd-page-actions > a.button { grid-column: 1 / -1; grid-row: 2; justify-content: center; }
}
/* Words a label can lose below 360px and still make sense. "Mark moment"
   can't share a row with Pause there (it needs 161px; half the bar is 128),
   so it shows "Mark"; "Share link as contributor" needs 248px of a 244px
   card, so it shows "Share as contributor". The hidden words stay in the
   accessible name -- clipped visually, not removed. */
@media (max-width: 359px) {
  .rd-hide-narrow {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  /* The contributor page's one-line note box (public_share_view.html) is
     ~130px wide here beside its two 44px buttons, and "Add a note or
     file..." wraps -- a textarea always wraps -- into a second line the
     box cut in half. Two lines tall at this width only. */
  .dropzone-compact textarea { min-height: 4em; }
}
/* Touch: every control reaches the full target size, wherever it sits. */
@media (pointer: coarse) {
  .rd-icon-btn { width: var(--ltg-target); height: var(--ltg-target); }
  .rd-choice-inline { min-height: var(--ltg-target); }
  /* The phone top bar's menu button is 36px (style.css) with a -8px margin
     that lines its icon up with the page gutter. 44px, and 4px more pulled
     left, keeps the icon exactly where it was. */
  .topbar-menu-button {
    width: var(--ltg-target); height: var(--ltg-target);
    margin-left: calc(-1 * var(--space-2) - 4px);
  }
}
