/* =========================================================================
   Dissect — consolidated UI styles
   -------------------------------------------------------------------------
   Sourced from Claude Design's six design HTMLs (01-welcome..06-complete).
   - Tokens + resets at the top.
   - Design-system atoms next (.btn, .eyebrow, .input-wrap, etc.).
   - Screen-specific styles below, scoped by `#screen-*` parent.
   ========================================================================= */

/* One palette for the whole app, in two themes. The --gd-* names are kept
   so the rest of this file did not have to change, but their values are now
   roles, not colours: --gd-cream is the page ground, --gd-white a raised
   surface, --gd-navy the primary ink (and the primary button, which is why
   it flips to near-white in dark mode, with --gd-white text on it flipping
   to near-black). The theme is picked in app.html's <head> before first
   paint: light, unless dark was picked with the toggle. */
:root {
  color-scheme: light;

  --gd-cream:    #F5F6F8;   /* page */
  --gd-cream-2:  #F9FAFB;   /* soft fill */
  --gd-white:    #FFFFFF;   /* cards, panels, inputs */
  --gd-navy:     #0E1A33;   /* ink, primary button */
  --gd-navy-2:   #1A2747;
  --gd-gold:     #F4C430;
  --gd-gold-2:   #E5B520;
  --gd-ink:      #344054;   /* body text */
  --gd-warmgray: #667085;   /* secondary text */
  --gd-taupe:    #E4E7EC;   /* lines */
  --gd-overdue:  #D92D20;
  /* The armed state of a two-click destructive button: solid red, white
     text, and a deeper red on hover so the second click still has feedback. */
  --danger-solid: #D92D20; --danger-solid-hover: #B42318; --on-danger: #FFFFFF;

  --on-accent:   #FFFFFF;
  --on-gold:     #0E1A33;   /* ink on gold, dark in both themes */
  --line-soft:   #EEF0F3;
  --line-strong: #D0D5DD;
  --faint:       #98A2B3;
  --chip:        #F2F4F7;
  --hover:       rgba(16, 24, 40, 0.05);
  --go:          #C0C5CE;

  --ok-bg:   #ECFDF3; --ok-fg:   #067647;
  --done-bg: #067647; --on-done: #FFFFFF;   /* the complete screen's Done pill */
  --err-bg:  #FEF3F2; --err-fg:  #B42318; --err-line: #FECDCA;
  --warn-bg: #FFFAEB; --warn-fg: #B54708;
  --info-bg: #EFF4FF; --info-fg: #1D5BD8;
  --gold-bg: #FEF6DA; --gold-fg: #7A5800;

  --sk-a: #EEF0F3; --sk-b: #F7F8FA;
  --overlay: rgba(16, 24, 40, 0.40);
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.05);
  --shadow-lg: 0 24px 48px -12px rgba(16, 24, 40, 0.25);
  --focus-line: #9DB1D6; --focus-ring: rgba(29, 91, 216, 0.10);

  /* The run log stays dark in both themes, like a terminal. */
  --console-bg: #0E1A33; --console-fg: #EEF0F5; --console-line: transparent;
  --console-warn: #FACC15; --console-error: #F87171; --console-stage: var(--gd-gold);
  --console-thumb: rgba(255, 255, 255, 0.22); --console-thumb-hover: rgba(255, 255, 255, 0.38);

  --font-display: 'Fraunces', 'Times New Roman', Georgia, serif;
  --font-ui: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --gold-bar-w: 9px;
}

/* Midnight: a navy-tinted dark built from the brand navy rather than a
   neutral grey, so the gold keeps its pop. Layering follows the usual rule
   for dark UIs: the page is darkest, surfaces step up in lightness instead
   of casting shadows, lines are low-contrast, text is off-white. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --gd-cream:    #0A0F1C;
  --gd-cream-2:  #141B2D;
  --gd-white:    #10172A;
  --gd-navy:     #E9EDF5;
  --gd-navy-2:   #C9D1E0;
  --gd-gold:     #F5C542;
  --gd-gold-2:   #E8B82E;
  --gd-ink:      #B9C2D3;
  --gd-warmgray: #8591A8;
  --gd-taupe:    #222C42;
  --gd-overdue:  #F97066;
  /* Not --gd-overdue: white on that light coral is too faint to read. */
  --danger-solid: #D92D20; --danger-solid-hover: #F04438; --on-danger: #FFFFFF;

  --on-accent:   #0A0F1C;
  --on-gold:     #0A0F1C;
  --line-soft:   #1A2235;
  --line-strong: #33405C;
  --faint:       #5F6B84;
  --chip:        #1A2337;
  --hover:       rgba(233, 237, 245, 0.06);
  --go:          #4A5670;

  --ok-bg:   rgba(23, 178, 106, 0.14); --ok-fg:   #47CD89;
  --done-bg: #17B26A; --on-done: #0A0F1C;
  --err-bg:  rgba(240, 68, 56, 0.14);  --err-fg:  #FDA29B; --err-line: rgba(240, 68, 56, 0.35);
  --warn-bg: rgba(247, 144, 9, 0.14);  --warn-fg: #FDB022;
  --info-bg: rgba(83, 138, 255, 0.16); --info-fg: #84ADFF;
  --gold-bg: rgba(245, 197, 66, 0.14); --gold-fg: #F5C542;

  --sk-a: #161E31; --sk-b: #1E2740;
  --overlay: rgba(3, 6, 14, 0.65);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.40);
  --shadow-lg: 0 24px 48px -12px rgba(0, 0, 0, 0.60);
  --focus-line: #3E5A94; --focus-ring: rgba(132, 173, 255, 0.18);

  /* Raised above the page, not sunk below it: a darker-than-page console
     read as a hole in the page and lost its edge (#070B16 on #0A0F1C). */
  --console-bg: #121B30; --console-fg: #E9EDF5; --console-line: #2A3652;
  --console-warn: #FACC15; --console-error: #F87171; --console-stage: #84ADFF;
  --console-thumb: rgba(255, 255, 255, 0.22); --console-thumb-hover: rgba(255, 255, 255, 0.38);
}

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

/* The scrollbar's space is always reserved, so switching between a short
   screen and a long one never changes the page width. */
html { scrollbar-gutter: stable; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--gd-cream);
  color: var(--gd-navy);
  font-family: var(--font-ui);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Persistent gold left bar — every screen sees it. */
body::before {
  display: none;
  content: "";
  position: fixed;
  left: 0; top: 0; bottom: 0;
  width: var(--gold-bar-w);
  background: var(--gd-gold);
  pointer-events: none;
  z-index: 100;
}

/* ───────────── Screen toggling ───────────── */

.screen {
  position: relative;
  min-height: 100vh;
  min-width: 960px;
  display: flex;
  flex-direction: column;
}
[hidden] { display: none !important; }

/* ───────────── Shared chrome: top bars ───────────── */

/* Setup screens (01, 02, 03): a thin topbar with back button + corner tag. */
.topbar {
  position: relative;
  z-index: 6;
  padding: 24px 40px 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.back {
  background: transparent;
  border: 0;
  padding: 6px 8px 6px 0;
  margin-left: -8px;
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--gd-ink);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: color 120ms ease-out;
}
.back:hover { color: var(--gd-navy); }
.back:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 2px; }
.back .chev { font-size: 15px; line-height: 1; transform: translateY(-1px); }

.corner {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 11px;
  color: var(--gd-warmgray);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.corner::before {
  content: "";
  width: 6px;
  height: 6px;
  background: var(--gd-gold);
  display: inline-block;
}

/* App screens (04, 05, 06): wordmark on the left, settings cog on the right. */
.app-topbar {
  position: relative;
  z-index: 6;
  /* One bar for every screen, down to the pixel. Fixed height and padding,
     so switching screens never makes it jump; per-screen overrides of it
     are how it used to look broken between the dashboard and the rest. */
  height: 60px;
  padding: 0 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--gd-white);
  border-bottom: 1px solid var(--gd-taupe);
}
.app-topbar .wordmark-small {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  line-height: 1;
  color: var(--gd-navy);
  letter-spacing: -0.01em;
  display: inline-flex;
  align-items: center;
  gap: 12px;
}
.app-topbar .wordmark-small::before {
  content: "";
  width: 10px;
  height: 10px;
  background: var(--gd-gold);
  display: inline-block;
}

.icon-btn {
  width: 36px; height: 36px;
  padding: 0;
  border-radius: 8px;
  flex: none;
  background: transparent;
  border: 0;
  color: var(--gd-ink);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 120ms ease-out, color 120ms ease-out;
}
.icon-btn:hover { background: var(--hover); color: var(--gd-navy); }
.icon-btn:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 2px; }
/* The screen you are on: its icon stays in place, just filled in. */
.icon-btn.is-current { background: var(--chip); color: var(--gd-navy); cursor: default; }
/* New dissection while one is already queued or running: greyed out. It is
   still clickable on purpose; the click goes to the run in progress (app.js,
   openNewDissection), which is more use than a button that does nothing. */
.icon-btn.is-disabled { opacity: 0.4; cursor: not-allowed; }
.icon-btn.is-disabled:hover { background: transparent; color: var(--gd-ink); }

/* ───────────── Shared stage + stack ───────────── */

.stage {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 96px 64px 144px;
}
.stage-narrow { padding: 48px 64px 144px; }    /* setup screens 02, 03 */
.stage-narrow-3 { padding: 32px 64px 144px; }  /* setup screen 03 */
.app-stage {
  flex: 1;
  padding: 40px 64px 56px;
  display: flex;
  justify-content: center;
}
.stack { width: 100%; max-width: 520px; }
.stack-560 { width: 100%; max-width: 560px; }
.stack-640 { width: 100%; max-width: 640px; }
.stack-720 { width: 100%; max-width: 720px; }
.stack-760 { width: 100%; max-width: 760px; }

/* ───────────── Design-system atoms ───────────── */

.eyebrow {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 12px;
  color: var(--gd-navy);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 24px;
}
.eyebrow::before {
  content: "";
  width: 7px;
  height: 7px;
  background: var(--gd-gold);
  display: inline-block;
}

.title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 44px;
  line-height: 1.08;
  letter-spacing: -0.02em;
  color: var(--gd-navy);
  margin: 0 0 20px;
}
.title-lg { font-size: 48px; line-height: 1.05; }

.explainer {
  font-family: var(--font-ui);
  font-size: 16px;
  line-height: 1.55;
  color: var(--gd-ink);
  margin: 0 0 40px;
  max-width: 58ch;
}

.btn {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0.01em;
  color: var(--gd-white);
  background: var(--gd-navy);
  border: 0;
  border-radius: 0;
  padding: 15px 28px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  transition: background 120ms ease-out, transform 120ms ease-out;
}
.btn:hover:not(:disabled) { background: var(--gd-navy-2); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 2px; }
.btn:disabled {
  background: var(--gd-taupe);
  color: var(--gd-warmgray);
  cursor: not-allowed;
}
.btn .arrow {
  font-family: var(--font-ui);
  font-weight: 400;
  font-size: 17px;
  line-height: 1;
  transform: translateY(-0.5px);
}
.btn-lg { padding: 16px 32px; gap: 14px; }

.btn-secondary {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 14px;
  color: var(--gd-navy);
  background: transparent;
  border: 1px solid var(--gd-taupe);
  border-radius: 0;
  padding: 12px 18px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  transition: border-color 120ms ease-out, background 120ms ease-out, color 120ms ease-out;
}
.btn-secondary:hover { border-color: var(--gd-navy); background: var(--gd-white); }
.btn-secondary:active { transform: translateY(1px); }
.btn-secondary:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 2px; }
.btn-secondary svg { display: block; color: var(--gd-ink); }

.link {
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 14px;
  color: var(--gd-ink);
  text-decoration: none;
  background: transparent;
  border: 0;
  padding: 8px 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  letter-spacing: 0.01em;
  border-bottom: 1px solid transparent;
  transition: color 120ms ease-out, border-color 120ms ease-out;
}
.link:hover { color: var(--gd-navy); border-bottom-color: var(--gd-gold); }
.link:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 3px; }
.link .arrow { font-size: 15px; line-height: 1; transform: translateY(-1px); }

.field { margin: 0 0 28px; }
.field-label {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 12px;
  color: var(--gd-navy);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  display: block;
  margin: 0 0 10px;
}

.input-wrap {
  position: relative;
  display: flex;
  align-items: stretch;
  background: var(--gd-white);
  border: 1px solid var(--gd-taupe);
  transition: border-color 120ms ease-out, box-shadow 120ms ease-out;
}
.input-wrap:focus-within {
  border-color: var(--gd-navy);
  box-shadow: 0 0 0 3px rgba(244, 196, 48, 0.25);
}
.input-wrap.is-invalid {
  border-color: var(--gd-overdue);
  box-shadow: 0 0 0 3px rgba(192, 57, 43, 0.12);
}
.input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  padding: 14px 16px;
  font-family: var(--font-ui);
  font-variant-numeric: tabular-nums;
  font-size: 15px;
  letter-spacing: 0.01em;
  color: var(--gd-navy);
  line-height: 1.4;
}
.input::placeholder { color: var(--gd-warmgray); opacity: 0.7; }

.helper {
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.45;
  color: var(--gd-warmgray);
  margin: 10px 0 0;
}
.error {
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.45;
  color: var(--gd-overdue);
  margin: 10px 0 0;
  display: none;
  align-items: flex-start;
  gap: 10px;
}
.error::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  background: var(--gd-overdue);
  margin-top: 6px;
}
.error.is-shown { display: inline-flex; }

.actions {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-top: 40px;
}

/* Setup screen bottom step indicator (welcome / apikey / folder) */
.setup-step {
  position: absolute;
  left: 50%;
  bottom: 40px;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 16px;
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 11px;
  color: var(--gd-warmgray);
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.setup-step .dots { display: inline-flex; gap: 6px; }
.setup-step .dot { width: 6px; height: 6px; background: var(--gd-taupe); }
.setup-step .dot.is-active { background: var(--gd-gold); }
.setup-step .count { color: var(--gd-ink); }

/* ===========================================================================
   #screen-welcome (01)
   ========================================================================= */

#screen-welcome .corner {
  position: absolute;
  left: 40px;
  top: 32px;
}
#screen-welcome .brand {
  display: flex;
  flex-direction: column;
  gap: 24px;
  margin-bottom: 40px;
}
#screen-welcome .mark {
  width: 28px;
  height: 28px;
  background: var(--gd-gold);
  display: block;
}
#screen-welcome .wordmark {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 64px;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--gd-navy);
  margin: 0;
}
/* Running-build badge stamped next to every wordmark (see app.js
   stampVersionBadges). Tells the user at a glance which build this is. */
.version-badge {
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--gd-warmgray);
  align-self: center;
}
#screen-welcome .wordmark .version-badge {
  margin-left: 14px;
  vertical-align: middle;
  font-size: 14px;
}

/* Active-backend indicator on the setup screen (shown when opened via the
   gear by an already-onboarded user). */
.backend-current {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  color: var(--gd-ink);
  background: var(--gd-cream-2);
  border: 1px solid var(--gd-taupe);
  border-radius: 6px;
  padding: 8px 12px;
  margin: 14px 0 0;
  display: inline-block;
}

/* Equal-weight access cards on the setup screen: Anthropic API key vs
   Claude Code subscription. Selecting a card swaps the panel below. */
.backend-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin: 26px 0 30px;
}
.backend-card {
  font-family: var(--font-ui);
  text-align: left;
  background: var(--gd-white);
  border: 1.5px solid var(--gd-taupe);
  border-radius: 8px;
  padding: 18px 18px 16px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.backend-card:hover { border-color: var(--gd-navy-2); }
.backend-card.is-selected {
  border-color: var(--gd-navy);
  box-shadow: 0 0 0 1.5px var(--gd-navy);
}
.backend-card-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--gd-navy);
  display: flex;
  align-items: center;
  gap: 8px;
}
.backend-card.is-selected .backend-card-title::before {
  content: "";
  width: 9px;
  height: 9px;
  background: var(--gd-gold);
  flex: 0 0 auto;
}
.backend-card-desc {
  font-size: 13px;
  line-height: 1.5;
  color: var(--gd-warmgray);
}

#screen-welcome .lede {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: 24px;
  line-height: 1.35;
  letter-spacing: -0.005em;
  color: var(--gd-ink);
  margin: 0 0 56px;
  max-width: 460px;
}
#screen-welcome .features {
  list-style: none;
  padding: 0;
  margin: 0 0 56px;
  border-top: 1px solid var(--gd-taupe);
}
#screen-welcome .features li {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 18px 0;
  border-bottom: 1px solid var(--gd-taupe);
  font-family: var(--font-ui);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.45;
  color: var(--gd-ink);
}
#screen-welcome .features li::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  background: var(--gd-gold);
  margin-top: 9px;
}
#screen-welcome .hint {
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--gd-warmgray);
}
#screen-welcome .hint kbd {
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 11px;
  color: var(--gd-ink);
  background: transparent;
  border: 1px solid var(--gd-taupe);
  border-radius: 3px;
  padding: 2px 6px;
  letter-spacing: 0.04em;
}

/* ===========================================================================
   #screen-apikey (02)
   ========================================================================= */

#screen-apikey .reveal {
  flex: none;
  width: 48px;
  background: transparent;
  border: 0;
  border-left: 1px solid var(--gd-taupe);
  color: var(--gd-ink);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 120ms ease-out, background 120ms ease-out;
}
#screen-apikey .reveal:hover { color: var(--gd-navy); background: var(--hover); }
#screen-apikey .reveal:focus-visible {
  outline: 2px solid var(--gd-gold);
  outline-offset: -2px;
}
#screen-apikey .reveal svg { display: block; }
#screen-apikey .reveal .eye-off { display: none; }
#screen-apikey .reveal.is-revealed .eye { display: none; }
#screen-apikey .reveal.is-revealed .eye-off { display: block; }

#screen-apikey .actions {
  justify-content: space-between;
  gap: 24px;
}

/* ===========================================================================
   #screen-folder (03)
   ========================================================================= */

#screen-folder .options {
  border: 0;
  padding: 0;
  margin: 0 0 32px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
#screen-folder .options legend { display: none; }

#screen-folder .card {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  column-gap: 18px;
  padding: 20px 22px 20px 24px;
  background: var(--gd-white);
  border: 1px solid var(--gd-taupe);
  cursor: pointer;
  transition: border-color 120ms ease-out, box-shadow 120ms ease-out;
}
#screen-folder .card:hover { border-color: var(--gd-ink); }
#screen-folder .card input[type="radio"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
#screen-folder .card-radio {
  width: 16px;
  height: 16px;
  border: 1.5px solid var(--gd-taupe);
  background: var(--gd-cream);
  flex: none;
  position: relative;
  transition: border-color 120ms ease-out, background 120ms ease-out;
}
#screen-folder .card-radio::after {
  content: "";
  position: absolute;
  inset: 3px;
  background: transparent;
  transition: background 120ms ease-out;
}
#screen-folder .card:has(input:checked) {
  border-color: var(--gd-navy);
  box-shadow: inset 4px 0 0 var(--gd-gold);
  padding-left: 28px;
}
#screen-folder .card:has(input:checked) .card-radio {
  border-color: var(--gd-navy);
  background: var(--gd-white);
}
#screen-folder .card:has(input:checked) .card-radio::after { background: var(--gd-gold); }
#screen-folder .card:focus-within { outline: 2px solid var(--gd-gold); outline-offset: 2px; }

#screen-folder .card-icon {
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--gd-navy);
  flex: none;
}
#screen-folder .card-icon svg { display: block; }
#screen-folder .card-body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
#screen-folder .card-path {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 15px;
  color: var(--gd-navy);
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#screen-folder .card-path .home { color: var(--gd-warmgray); font-weight: 500; }
#screen-folder .card-title {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 15px;
  color: var(--gd-navy);
}
#screen-folder .card-meta {
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--gd-warmgray);
  line-height: 1.4;
}
#screen-folder .card-right {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 14px;
}
#screen-folder .browse {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 13px;
  color: var(--gd-navy);
  background: transparent;
  border: 1px solid var(--gd-navy);
  border-radius: 0;
  padding: 8px 14px;
  cursor: pointer;
  transition: background 120ms ease-out, color 120ms ease-out;
}
#screen-folder .browse:hover { background: var(--gd-navy); color: var(--gd-white); }
#screen-folder .browse:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 2px; }

#screen-folder .actions {
  justify-content: flex-end;
  gap: 24px;
}

/* ===========================================================================
   #screen-main (04)
   ========================================================================= */

/* The drop area has to read as a control before anyone hovers it: a raised
   white panel with a real dashed edge, a gold badge that breathes, and a
   button-shaped call to action. Hover and drag-over build on that rather
   than being the first sign it does anything. */
#screen-main .dropzone {
  width: 100%;
  position: relative;
  background: var(--gd-white);
  border: 2px dashed var(--line-strong);
  border-radius: 16px;
  padding: 44px 32px 40px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  cursor: pointer;
  font: inherit;
  color: inherit;
  text-align: center;
  box-shadow: var(--shadow-sm);
  transition: border-color 200ms ease, background 200ms ease, box-shadow 260ms cubic-bezier(0.16, 1, 0.3, 1), transform 260ms cubic-bezier(0.16, 1, 0.3, 1);
}
#screen-main .dropzone:hover {
  border-color: var(--gd-gold);
  box-shadow: 0 12px 28px -14px rgba(16, 24, 40, 0.28);
  transform: translateY(-2px);
}
#screen-main .dropzone:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 3px; }
#screen-main .dropzone.is-dragover,
#screen-main .dropzone.is-over {
  border-color: var(--gd-gold);
  border-style: solid;
  background: var(--gold-bg);
  transform: scale(1.01);
}

#screen-main .dz-badge {
  position: relative;
  display: grid;
  place-items: center;
  width: 60px;
  height: 60px;
  margin-bottom: 10px;
  border-radius: 50%;
  background: var(--gold-bg);
  color: var(--gold-fg);
}
/* A soft ring pulsing out of the badge: the one bit of motion that says
   "this is where it goes" without anyone having to hover. */
#screen-main .dz-badge::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid var(--gd-gold);
  opacity: 0;
  animation: dz-ring 2.4s cubic-bezier(0.16, 1, 0.3, 1) infinite;
}
#screen-main .dz-icon { display: block; color: currentColor; }
#screen-main .dz-arrow { transition: transform 260ms cubic-bezier(0.16, 1, 0.3, 1); }
#screen-main .dropzone:hover .dz-arrow,
#screen-main .dropzone.is-dragover .dz-arrow,
#screen-main .dropzone.is-over .dz-arrow { transform: translateY(-2px); }

#screen-main .dz-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 24px;
  color: var(--gd-navy);
  letter-spacing: -0.01em;
  line-height: 1.2;
}
#screen-main .dz-sub {
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--gd-warmgray);
}
#screen-main .dz-sub .dot { margin: 0 6px; color: var(--faint); }

#screen-main .dz-cta {
  margin-top: 14px;
  display: inline-flex;
  align-items: center;
  height: 40px;
  padding: 0 18px;
  border-radius: 8px;
  background: var(--gd-navy);
  color: var(--gd-white);
  font: 600 14px var(--font-ui);
  transition: background 150ms ease;
}
#screen-main .dropzone:hover .dz-cta { background: var(--gd-navy-2); }

@keyframes dz-ring {
  0%   { transform: scale(1);    opacity: 0.55; }
  70%  { transform: scale(1.45); opacity: 0; }
  100% { transform: scale(1.45); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  #screen-main .dz-badge::after { animation: none; }
  #screen-main .dropzone, #screen-main .dropzone:hover { transform: none; }
}

#screen-main .selected {
  display: none;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  column-gap: 18px;
  padding: 18px 18px 18px 24px;
  background: var(--gd-white);
  border: 1px solid var(--gd-taupe);
  box-shadow: inset 4px 0 0 var(--gd-gold);
}
#screen-main .selected.is-shown { display: grid; }
/* The preview spans the card under the file row. Black letterbox, because
   recordings are portrait and landscape and neither should be cropped; the
   height cap keeps a portrait clip from pushing the form off the screen. */
#screen-main .file-preview {
  grid-column: 1 / -1;
  margin-top: 16px;
  display: flex;
  flex-direction: column;
}
#screen-main .file-preview[hidden] { display: none; }
#screen-main .preview-frame {
  display: flex;
  justify-content: center;
  background: #000000;
}
#screen-main .preview-frame video {
  display: block;
  max-width: 100%;
  max-height: 360px;
  cursor: pointer;
}

/* The control bar: play, time, a full-width scrubber, length, sound. */
#screen-main .preview-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  background: var(--chip);
  border-top: 1px solid var(--gd-taupe);
}
#screen-main .pv-btn {
  width: 32px; height: 32px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--gd-navy);
  cursor: pointer;
  transition: background 120ms ease-out;
}
#screen-main .pv-btn:hover { background: var(--hover); }
#screen-main .pv-btn:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 2px; }
#screen-main .pv-btn svg { display: block; }
#screen-main #main-preview-play .pv-pause,
#screen-main #main-preview-play.is-playing .pv-play,
#screen-main #main-preview-mute .pv-muted,
#screen-main #main-preview-mute.is-muted .pv-sound { display: none; }
#screen-main #main-preview-play.is-playing .pv-pause,
#screen-main #main-preview-mute.is-muted .pv-muted { display: block; }
#screen-main .pv-time {
  flex: none;
  min-width: 4ch;
  font-size: 12.5px;
  color: var(--gd-ink);
  font-variant-numeric: tabular-nums;
  text-align: center;
}

/* The scrubber: gold up to the playhead (--pct, set from app.js), the line
   colour after it, and a round thumb that grows while held. */
#screen-main .pv-seek {
  --pct: 0%;
  flex: 1;
  min-width: 0;
  height: 20px;
  margin: 0;
  background: transparent;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
#screen-main .pv-seek:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 4px; border-radius: 4px; }
#screen-main .pv-seek::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(to right, var(--gd-gold) var(--pct), var(--line-strong) var(--pct));
}
/* Trimmed: the kept section is solid yellow from its start to its end (the
   video's end until one is set), and what is cut off either side is grey.
   The playhead is the thumb, so it turns white with a dark ring to stay
   visible on the yellow. */
#screen-main .file-preview.is-trimmed .pv-seek::-webkit-slider-runnable-track {
  height: 8px;
  background: linear-gradient(to right,
    var(--trim-cut) var(--a), var(--gd-gold) var(--a),
    var(--gd-gold) var(--b), var(--trim-cut) var(--b));
}
#screen-main .file-preview.is-trimmed .pv-seek::-webkit-slider-thumb {
  margin-top: -3px;
  background: #FFFFFF;
  border-color: #0E1A33;   /* fixed, not the theme ink: it sits on yellow in both */
}
#screen-main .pv-seek::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px; height: 14px;
  margin-top: -5px;
  border-radius: 50%;
  background: var(--gd-gold);
  border: 2px solid var(--gd-white);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  transition: transform 120ms ease-out;
}
#screen-main .pv-seek:active::-webkit-slider-thumb { transform: scale(1.2); }
#screen-main .pv-seek::-moz-range-track {
  height: 4px;
  border-radius: 999px;
  background: var(--line-strong);
}
#screen-main .pv-seek::-moz-range-progress {
  height: 4px;
  border-radius: 999px;
  background: var(--gd-gold);
}
#screen-main .file-preview.is-trimmed .pv-seek::-moz-range-track {
  height: 8px;
  background: linear-gradient(to right,
    var(--trim-cut) var(--a), var(--gd-gold) var(--a),
    var(--gd-gold) var(--b), var(--trim-cut) var(--b));
}
#screen-main .file-preview.is-trimmed .pv-seek::-moz-range-progress { background: transparent; }
#screen-main .file-preview.is-trimmed .pv-seek::-moz-range-thumb {
  background: #FFFFFF;
  border-color: #0E1A33;   /* fixed, not the theme ink: it sits on yellow in both */
}
#screen-main .pv-seek::-moz-range-thumb {
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--gd-gold);
  border: 2px solid var(--gd-white);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
#screen-main .dropzone.is-hidden { display: none; }

#screen-main .file-thumb {
  width: 44px;
  height: 44px;
  flex: none;
  background: var(--gd-cream);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--gd-navy);
}
#screen-main .file-meta {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
#screen-main .filename {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 14px;
  color: var(--gd-navy);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#screen-main .filemeta {
  font-family: var(--font-ui);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  color: var(--gd-warmgray);
}
#screen-main .filemeta .dot { margin: 0 6px; color: var(--gd-taupe); }
#screen-main .remove {
  width: 32px; height: 32px;
  background: transparent;
  border: 0;
  color: var(--gd-warmgray);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 120ms ease-out, color 120ms ease-out;
}
#screen-main .remove:hover { background: var(--hover); color: var(--gd-navy); }
#screen-main .remove:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 2px; }

/* The part of the video a trim cuts off. */
#screen-main .pv-seek { --a: 0%; --b: 100%; --trim-cut: var(--line-strong); }

/* The trim row, under the control bar. */
#screen-main .preview-trim {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
  padding: 10px 12px 12px;
  background: var(--chip);
}
#screen-main .trim-btn {
  height: 30px;
  padding: 0 12px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--gd-white);
  color: var(--gd-navy);
  font: 500 12.5px var(--font-ui);
  cursor: pointer;
  transition: border-color 120ms ease-out;
}
#screen-main .trim-btn:hover { border-color: var(--gd-navy); }
#screen-main .trim-btn:focus-visible,
#screen-main .trim-reset:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 2px; }
#screen-main .trim-readout {
  flex: 1;
  min-width: 14ch;
  font-size: 12.5px;
  color: var(--gd-ink);
  font-variant-numeric: tabular-nums;
}
#screen-main .file-preview.is-trimmed .trim-readout { color: var(--gd-navy); font-weight: 600; }
#screen-main .trim-reset {
  border: 0;
  background: transparent;
  padding: 4px 6px;
  font: 500 12.5px var(--font-ui);
  color: var(--gd-warmgray);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
#screen-main .trim-reset:hover { color: var(--gd-navy); }
#screen-main .trim-reset[hidden] { display: none; }

#screen-main .form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  margin-top: 36px;
}
#screen-main .field { display: flex; flex-direction: column; margin: 0; }
#screen-main .input-wrap.select-wrap { position: relative; }
#screen-main .select {
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  padding-right: 40px;
  font-family: var(--font-ui);
  font-size: 15px;
  color: var(--gd-navy);
  background-color: var(--gd-white);
}
/* The open list is drawn by the OS. Chrome on Windows paints it from the
   options' own colours, white by default, so without these the dark theme's
   near-white text lands on a white list and the genres disappear. */
#screen-main .select option,
.pager-size select option {
  background-color: var(--gd-white);
  color: var(--gd-navy);
}
#screen-main .select option:checked,
.pager-size select option:checked {
  background-color: var(--chip);
}
#screen-main .select-wrap::after {
  content: "";
  position: absolute;
  right: 16px;
  top: 50%;
  width: 10px;
  height: 10px;
  border-right: 1.5px solid var(--gd-navy);
  border-bottom: 1.5px solid var(--gd-navy);
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none;
}

#screen-main .dest-help {
  margin: 12px 0 0;
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--gd-warmgray);
  line-height: 1.5;
}
#screen-main .dest-help .mono {
  font-variant-numeric: tabular-nums;
  color: var(--gd-ink);
  font-weight: 500;
}

#screen-main .action-row {
  margin-top: 44px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
}
#screen-main .cost {
  font-family: var(--font-ui);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  color: var(--gd-ink);
}
#screen-main .cost strong {
  font-weight: 600;
  color: var(--gd-navy);
  margin-left: 4px;
}

/* ===========================================================================
   #screen-progress (05)
   ========================================================================= */

#screen-progress .header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 18px;
}
#screen-progress .eyebrow { margin-bottom: 0; }
#screen-progress .cost-counter {
  font-family: var(--font-ui);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  color: var(--gd-ink);
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
#screen-progress .cost-counter .live-dot {
  width: 7px;
  height: 7px;
  background: var(--gd-gold);
  display: inline-block;
  animation: live-pulse 1.6s ease-in-out infinite;
}
#screen-progress .cost-counter strong { font-weight: 600; color: var(--gd-navy); }
#screen-progress .cost-counter .label { color: var(--gd-warmgray); }

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

#screen-progress .title { font-size: 48px; line-height: 1.05; margin: 0 0 12px; }
#screen-progress .stage-desc {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: 22px;
  line-height: 1.35;
  color: var(--gd-ink);
  letter-spacing: -0.005em;
  margin: 0 0 56px;
}
#screen-progress .stage-desc .ellipsis {
  display: inline-block;
  animation: ellipsis-fade 1.4s ease-in-out infinite;
}
@keyframes ellipsis-fade {
  0%, 100% { opacity: 0.4; }
  50% { opacity: 1; }
}

#screen-progress .stepper {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  align-items: flex-start;
  margin-bottom: 48px;
  position: relative;
  padding: 0;
  list-style: none;
}
#screen-progress .step {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 0 4px;
  z-index: 1;
}
#screen-progress .marker {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--gd-cream);
  border: 1.5px solid var(--gd-taupe);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
  color: var(--gd-warmgray);
  line-height: 1;
  position: relative;
  transition: background 200ms ease-out, color 200ms ease-out, border-color 200ms ease-out;
}
#screen-progress .step.is-done .marker {
  background: var(--gd-gold);
  border-color: var(--gd-gold);
  color: var(--on-gold);
}
#screen-progress .step.is-done .marker .num { display: none; }
#screen-progress .step.is-done .marker .check { display: block; }
#screen-progress .step.is-current .marker {
  background: var(--gd-navy);
  border-color: var(--gd-navy);
  color: var(--gd-white);
  animation: marker-pulse 2.4s ease-in-out infinite;
}
#screen-progress .step.is-current .marker::after {
  content: "";
  position: absolute;
  inset: -6px;
  border: 1.5px solid var(--gd-gold);
  animation: ring-pulse 2.4s ease-out infinite;
  pointer-events: none;
}
#screen-progress .marker .check { display: none; }

@keyframes marker-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.04); }
}
@keyframes ring-pulse {
  0% { opacity: 0.55; transform: scale(0.92); }
  80%, 100% { opacity: 0; transform: scale(1.25); }
}

#screen-progress .step-label {
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 12px;
  color: var(--gd-warmgray);
  text-align: center;
  letter-spacing: 0.01em;
  line-height: 1.3;
  max-width: 12ch;
}
#screen-progress .step.is-done .step-label,
#screen-progress .step.is-current .step-label {
  color: var(--gd-navy);
  font-weight: 600;
}

#screen-progress .progress-block {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-bottom: 36px;
}
#screen-progress .progress {
  flex: 1;
  height: 4px;
  background: var(--gd-taupe);
  position: relative;
  overflow: hidden;
}
#screen-progress .progress-fill {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  background: var(--gd-gold);
  width: 0%;
  transition: width 600ms ease-out;
}
/* The bar is per step: when a step finishes it snaps back to empty for the
   next one instead of sliding backwards. */
#screen-progress .progress-fill.is-snap { transition: none; }
/* The upload phase (app.js, setUploadPhase). The five steps have not started
   yet, so they are dimmed rather than shown as if waiting on step 1. */
#screen-progress.is-uploading .stepper { opacity: 0.4; transition: opacity 200ms ease; }
/* No run exists yet, so there is no log to show. */
#screen-progress.is-uploading #progress-details { display: none; }
/* "Checking the video": the bytes are all there and the server is saving and
   probing the file, for seconds on a big upload. The bar runs on its own so
   it never sits frozen at 100%. */
#screen-progress .progress.is-indeterminate .progress-fill {
  width: 30% !important;
  transition: none;
  animation: upload-check 1.1s ease-in-out infinite;
}
@keyframes upload-check {
  from { left: -30%; }
  to   { left: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  #screen-progress .progress.is-indeterminate .progress-fill { animation: none; left: 0; width: 100% !important; opacity: 0.5; }
}
/* A sheen travelling along the track while the run is alive, so a stage
   that reports no progress of its own (the colour profile is one API call)
   still reads as working rather than stuck. */
#screen-progress .progress::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  width: 25%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.55), transparent);
  animation: sweep 1.6s ease-in-out infinite;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  #screen-progress .progress::after { animation: none; display: none; }
}
#screen-progress .progress-meta {
  flex: none;
  font-family: var(--font-ui);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  color: var(--gd-ink);
  display: inline-flex;
  align-items: baseline;
  gap: 12px;
  min-width: 14ch;
  justify-content: flex-end;
}
#screen-progress .progress-meta .pct {
  font-weight: 600;
  color: var(--gd-navy);
  font-size: 14px;
}
#screen-progress .progress-meta .eta { color: var(--gd-warmgray); }

#screen-progress .details { margin-bottom: 56px; }
#screen-progress .details summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 13px;
  color: var(--gd-ink);
  padding: 6px 0;
  letter-spacing: 0.01em;
  border-bottom: 1px solid transparent;
  transition: color 120ms ease-out, border-color 120ms ease-out;
}
#screen-progress .details summary::-webkit-details-marker { display: none; }
#screen-progress .details summary:hover { color: var(--gd-navy); border-bottom-color: var(--gd-gold); }
#screen-progress .details summary:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 3px; }
#screen-progress .details summary .chev {
  transition: transform 180ms ease-out;
  display: inline-block;
}
#screen-progress .details[open] summary .chev { transform: rotate(90deg); }

/* "Waiting for Claude…": the one log line a non-technical person needs,
   shown just above "Show details". Blue while normal, amber once slow. */
#screen-progress .claude-note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 0 0 14px;              /* sits right above "Show details" */
  padding: 10px 14px;
  border-radius: 10px;
  background: var(--info-bg);
  color: var(--info-fg);
  font-size: 14px;
  line-height: 1.45;
  animation: rise 300ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
#screen-progress .claude-note::before {
  content: "";
  flex: none;
  width: 14px;
  height: 14px;
  margin-top: 3px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 900ms linear infinite;
}
#screen-progress .claude-note.is-slow { background: var(--warn-bg); color: var(--warn-fg); }
@media (prefers-reduced-motion: reduce) {
  #screen-progress .claude-note, #screen-progress .claude-note::before { animation: none; }
}

/* ── the details console: one stream, printed the way docker prints logs */
#screen-progress .console-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 14px;
}
#screen-progress .console-copy {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 11px;
  border: 1px solid var(--gd-taupe);
  border-radius: 999px;
  background: var(--gd-white);
  color: var(--gd-ink);
  font: 500 12.5px var(--font-ui);
  cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease, color 150ms ease;
}
#screen-progress .console-copy { border-radius: 8px; }
#screen-progress .console-tools { display: flex; align-items: center; gap: 12px; }
#screen-progress .console-quiet {
  font-size: 12.5px;
  color: var(--gd-warmgray);
  font-variant-numeric: tabular-nums;
  transition: color 200ms ease;
}
/* Quiet for 30s or more: worth a look. The watchdog's ⏱ lines in the log
   say where it is waiting. */
#screen-progress .console-quiet.is-quiet { color: var(--warn-fg); font-weight: 600; }
#screen-progress .console-quiet.is-quiet::before { content: "⏱ "; }
#screen-progress .console-copy:hover { border-color: var(--line-strong); }
#screen-progress .console-copy:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 2px; }
/* The wrap carries the console's shape and clips it: a scrolling box does
   not round its own scrollbar, which squared off the two right corners. */
#screen-progress .console-wrap {
  position: relative;
  margin-top: 10px;
  background: var(--console-bg);
  border: 1px solid var(--console-line);
  border-radius: 10px;
  overflow: hidden;
}
#screen-progress .console {
  color: var(--console-fg);
  padding: 10px 0;
  height: 340px;
  overflow: auto;
  overscroll-behavior: contain;
  font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, 'Liberation Mono', monospace;
  font-size: 12.5px;
  line-height: 1.35;
  font-variant-numeric: tabular-nums;
}
/* A floating pill: a transparent border insets the thumb from the edge, and
   the track's margin keeps it clear of the rounded corners. */
#screen-progress .console::-webkit-scrollbar { width: 14px; height: 14px; }
#screen-progress .console::-webkit-scrollbar-track { background: transparent; margin: 8px 0; }
#screen-progress .console::-webkit-scrollbar-thumb {
  background: var(--console-thumb);
  background-clip: padding-box;
  border: 4px solid transparent;
  border-radius: 999px;
  min-height: 40px;
}
#screen-progress .console::-webkit-scrollbar-thumb:hover { background-color: var(--console-thumb-hover); }
#screen-progress .console::-webkit-scrollbar-corner { background: transparent; }
/* Firefox has no pseudo-elements for this. Kept out of Chrome on purpose:
   there, setting scrollbar-width or scrollbar-color switches the
   ::-webkit-scrollbar styles above off. */
@supports not selector(::-webkit-scrollbar) {
  #screen-progress .console { scrollbar-width: thin; scrollbar-color: var(--console-thumb) transparent; }
}

#screen-progress .log-line {
  padding: 0 16px;
  white-space: pre-wrap;
  word-break: break-word;
}
/* Stage changes are blue and bold, so yellow only ever means a warning. */
#screen-progress .log-line.is-stage { color: var(--console-stage); font-weight: 600; }
#screen-progress .log-line.is-warn  { color: var(--console-warn); }
#screen-progress .log-line.is-error { color: var(--console-error); }

#screen-progress .console-jump {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  height: 28px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: var(--gd-gold);
  color: var(--on-gold);
  font: 600 12px var(--font-ui);
  cursor: pointer;
  box-shadow: 0 6px 16px -6px rgba(0, 0, 0, 0.5);
}

/* Dark mode: the progress screen's hairlines (the stepper boxes, the
   bar's track, the cancel outline) use --gd-taupe, which is right for
   dividers but vanishes as the only edge of a control on the dark page.
   Lift them one step, and dim the bar's white sheen to a glow. */
:root[data-theme="dark"] #screen-progress .progress { background: var(--line-strong); }
:root[data-theme="dark"] #screen-progress .marker,
:root[data-theme="dark"] #screen-progress .cancel { border-color: var(--line-strong); }
:root[data-theme="dark"] #screen-progress .step:not(.is-done):not(.is-current) .marker { color: var(--gd-ink); }
:root[data-theme="dark"] #screen-progress .step.is-done .marker { border-color: var(--gd-gold); }
:root[data-theme="dark"] #screen-progress .step.is-current .marker { border-color: var(--gd-navy); }
:root[data-theme="dark"] #screen-progress .cancel:hover { border-color: var(--gd-navy); }
:root[data-theme="dark"] #screen-progress .progress::after {
  background: linear-gradient(90deg, transparent, rgba(245, 197, 66, 0.28), transparent);
}

#screen-progress .footer-actions {
  display: flex;
  justify-content: flex-end;
}
#screen-progress .cancel {
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 13px;
  color: var(--gd-ink);
  background: transparent;
  border: 1px solid var(--gd-taupe);
  border-radius: 0;
  padding: 9px 18px;
  cursor: pointer;
  transition: border-color 120ms ease-out, background 120ms ease-out, color 120ms ease-out;
}
#screen-progress .cancel:hover { border-color: var(--gd-navy); background: var(--gd-white); color: var(--gd-navy); }
#screen-progress .cancel:active { transform: translateY(1px); }
#screen-progress .cancel { display: inline-flex; align-items: center; gap: 8px; }

/* Armed: the first click of a cancel or delete. Red, so the second click is
   a choice. The :hover rule has to be spelled out: without it the plain
   .is-danger:hover further down (same specificity, later in the file) turned
   the background white under the armed state's white text. */
#screen-progress .cancel.is-armed,
.btn-secondary.is-danger.is-armed {
  background: var(--danger-solid);
  border-color: var(--danger-solid);
  color: var(--on-danger);
}
#screen-progress .cancel.is-armed:hover,
.btn-secondary.is-danger.is-armed:hover {
  background: var(--danger-solid-hover);
  border-color: var(--danger-solid-hover);
  color: var(--on-danger);
}
.btn-secondary.is-danger.is-armed svg { color: currentColor; }
#screen-progress .cancel.is-loading,
.btn-secondary.is-loading { opacity: 0.8; cursor: default; }
.live-right { display: flex; align-items: center; gap: 10px; justify-content: flex-end; }
#screen-progress .cancel:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 2px; }

/* Error state on progress screen */
#screen-progress .error-banner {
  display: none;
  background: var(--gd-overdue);
  color: var(--gd-white);
  padding: 16px 22px;
  margin-top: 24px;
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.5;
}
#screen-progress .error-banner.is-shown { display: block; }
#screen-progress .error-banner strong { font-weight: 600; }
#screen-progress .error-banner .actions { margin-top: 12px; gap: 12px; }
#screen-progress .error-banner .btn-on-error {
  background: var(--gd-white);
  color: var(--gd-navy);
  padding: 8px 18px;
}

/* ===========================================================================
   #screen-complete (06)
   ========================================================================= */

#screen-complete .status-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 22px;
}
#screen-complete .pill-done {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px 5px 10px;
  background: var(--done-bg);
  color: var(--on-done);
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-radius: 999px;
  line-height: 1.3;
}
#screen-complete .pill-done svg { display: block; }
#screen-complete .title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 48px;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--gd-navy);
  margin: 0 0 40px;
}

#screen-complete .stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--gd-taupe);
  border-bottom: 1px solid var(--gd-taupe);
  margin-bottom: 40px;
}
#screen-complete .stat {
  padding: 24px 28px 22px;
  border-right: 1px solid var(--gd-taupe);
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
#screen-complete .stat:last-child { border-right: 0; }
#screen-complete .stat-num {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 48px;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--gd-navy);
  font-variant-numeric: tabular-nums;
}
#screen-complete .stat-num.is-gold { color: var(--gd-gold); }
#screen-complete .stat-label {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gd-warmgray);
  line-height: 1.3;
}

#screen-complete .actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 0;
  margin-bottom: 18px;
}
#screen-complete .actions-left { display: inline-flex; gap: 12px; }
#screen-complete .info {
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--gd-warmgray);
  line-height: 1.5;
  display: inline-flex;
  align-items: flex-start;
  gap: 10px;
}
#screen-complete .info::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  background: var(--gd-gold);
  margin-top: 7px;
}
#screen-complete .info strong { color: var(--gd-ink); font-weight: 600; }

/* ======================================================================
   Web app additions
   ====================================================================== */

/* The topbar used to hold a single settings gear. It now holds a small
   cluster, so it needs to be a row. */
.topbar-right { display: flex; align-items: center; gap: 4px; }
.logout-form { display: inline-flex; margin: 0; }

/* The dropzone is a <label> now, not a <button>, so it needs the pointer
   and the drag-over state it used to get from :active. */
label.dropzone { cursor: pointer; }

/* ── Run history ─────────────────────────────────────────────────────── */

.history-filter { display: flex; gap: 18px; margin: 4px 0 18px; font-size: 14px; }
.history-filter label { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }

.history-list { display: flex; flex-direction: column; gap: 8px; }

.history-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 18px; margin: 4px 0 18px; font-size: 14px; color: var(--gd-warmgray); }
.history-filters label, .history-per-page { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; color: var(--gd-warmgray); }
.history-filters input, .history-filters select, .history-per-page select {
  padding: 6px 8px; border: 1px solid var(--gd-taupe); border-radius: 8px;
  background: var(--gd-white); color: var(--gd-ink); font: 14px var(--font-ui);
  color-scheme: light dark;
}
.history-filters select { max-width: 220px; }
.history-filters :is(input, select):focus-visible, .history-per-page select:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 1px; }

.history-pager { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 16px; margin-top: 18px; }
.history-pager-steps { display: inline-flex; align-items: center; gap: 16px; }
.history-page { font-size: 14px; color: var(--gd-warmgray); }
.history-pager button:disabled { opacity: 0.4; cursor: not-allowed; }
/* Its own line above the eyebrow. Inline, it sat beside "Run history" on
   a different baseline. The -6px pulls the chevron's ink, not its padding,
   onto the column's left edge. */
.history-back {
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 6px;
  margin: 0 0 18px -6px;
  padding: 6px 10px 6px 6px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  font: 500 13.5px var(--font-ui);
  color: var(--gd-warmgray);
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease;
}
.history-back:hover { background: var(--hover); color: var(--gd-navy); }
.history-back:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 2px; }
.history-whose { margin: -8px 0 20px; font-size: 14px; color: var(--gd-warmgray); }
.history-empty { color: var(--gd-warmgray); font-size: 14px; padding: 18px 0; }

.history-row {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 16px; border: 1px solid var(--gd-taupe); border-radius: 10px; background: var(--gd-white);
}
.history-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.history-title { font-weight: 600; letter-spacing: -0.01em; }
.history-meta { font-size: 13px; color: var(--gd-warmgray); }
/* Why a run did not finish (views.runs.failure_reason). Red only for a real
   failure; a cancel or a time limit is information, not an error. */
.history-reason { margin: 4px 0 0; font-size: 13px; line-height: 1.45; color: var(--gd-ink); overflow-wrap: anywhere; }
.history-reason.is-failed { color: var(--err-fg); }
.history-reason[title] { cursor: help; }
/* A deleted row fades and folds away rather than vanishing. */
.history-row { transition: opacity 240ms ease, transform 240ms ease; }
.history-row.is-leaving { opacity: 0; transform: translateX(12px); }
.history-actions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }

.history-status {
  font-size: 12px; text-transform: capitalize; padding: 3px 9px; border-radius: 999px;
  background: var(--chip); color: var(--gd-warmgray); white-space: nowrap;
}
/* Solid, the same green as the complete screen's Done pill: a finished run
   is the one status worth spotting at a glance down the list. */
.history-status.is-succeeded { background: var(--done-bg); color: var(--on-done); font-weight: 600; }
.history-status.is-failed,
.history-status.is-timed_out { background: var(--err-bg); color: var(--err-fg); }
.history-status.is-running,
.history-status.is-queued { background: var(--info-bg); color: var(--info-fg); }

.btn-sm { padding: 6px 12px; font-size: 13px; }

/* ── Access requests ─────────────────────────────────────────────────────
   The bell only exists for admins, so nothing here is ever rendered for
   anyone else. The badge is the whole notification as far as the app is
   concerned: a refused sign-in has to be visible the next time an admin
   loads a page, without them going looking for it. */

.icon-btn.bell { position: relative; overflow: visible; }

.bell-badge {
  position: absolute; top: 3px; right: 3px;
  min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 999px;
  background: var(--gd-overdue); color: #FFFFFF;
  font: 600 10px/16px var(--font-ui);
  text-align: center;
  pointer-events: none;
}

.access-lede { margin: 0 0 18px; color: var(--gd-warmgray); font-size: 14px; max-width: 60ch; }

.access-row .history-actions { gap: 8px; }

/* ── Settings ────────────────────────────────────────────────────────────
   One block per setting, a raised panel like the history rows. For now the
   only block is the Anthropic key. */
.settings-block {
  margin-top: 28px;
  padding: 24px 28px;
  border: 1px solid var(--gd-taupe);
  border-radius: 12px;
  background: var(--gd-white);
}
.settings-heading {
  margin: 0 0 6px;
  font-family: var(--font-ui);
  font-size: 17px;
  font-weight: 600;
  color: var(--gd-navy);
}
.settings-note { margin: 0 0 20px; color: var(--gd-warmgray); font-size: 14px; line-height: 1.55; max-width: 60ch; }
.settings-current {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  padding: 14px 16px;
  border-radius: 10px;
  background: var(--gd-cream-2);
}
.settings-summary { margin: 0; color: var(--gd-ink); font-size: 14px; font-variant-numeric: tabular-nums; }
.settings-actions { display: flex; align-items: center; gap: 10px; }
.settings-help { margin: 10px 0 18px; color: var(--gd-warmgray); font-size: 13px; line-height: 1.55; }
.settings-help a { color: inherit; }
.settings-current[hidden], .settings-form[hidden], .settings-steps[hidden] { display: none; }

/* Dissect Helper's two setup steps, shown after "Set up". */
.settings-steps {
  margin: 20px 0 0;
  padding-left: 22px;
  display: flex; flex-direction: column; gap: 12px;
  color: var(--gd-ink); font-size: 14px; line-height: 1.55;
}
.settings-command { display: flex; gap: 8px; align-items: stretch; margin-top: 8px; }
.settings-command .input-wrap { flex: 1; min-width: 0; }
.settings-command .input { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 13px; padding: 10px 12px; }
@media (max-width: 640px) {
  .settings-block { padding: 20px; }
}

.history-status.is-approved { background: var(--ok-bg); color: var(--ok-fg); }
.history-status.is-rejected { background: var(--err-bg); color: var(--err-fg); }
.history-status.is-pending  { background: var(--warn-bg); color: var(--warn-fg); }

/* ── Responsive ──────────────────────────────────────────────────────────
   The desktop build had min-width: 960px and no media queries at all: it
   only ever ran in a fixed 960x720 window. In a browser people will check
   "is it done yet" from a phone, and with runs of 10 to 50 minutes that is
   the most frequent visit the app gets. */

@media (max-width: 1000px) {
  .screen { min-width: 320px; }
  .stack-720 { width: 100%; padding-left: 20px; padding-right: 20px; box-sizing: border-box; }
  .form-grid { grid-template-columns: 1fr; }
  .action-row { flex-wrap: wrap; }
}

@media (max-width: 600px) {
  .app-topbar { padding: 0 16px; }
  .title, .title-lg { font-size: 26px; }
  .stepper { gap: 6px; font-size: 12px; }
  .stepper .step span { display: none; }
  .history-row { flex-direction: column; align-items: flex-start; gap: 10px; }
  .history-actions { width: 100%; justify-content: space-between; }
  .stat-row { flex-wrap: wrap; gap: 16px; }
  .actions, .action-row { flex-direction: column; align-items: stretch; }
  .btn, .btn-secondary { width: 100%; justify-content: center; }
}

/* ── Dashboard ───────────────────────────────────────────────────────────
   Two audiences, one screen. An artist sees the four tiles at the top and
   nothing else; an admin sees the studio's totals, who is running something
   right now, and the people list. The split is decided on the server, so
   there is no "admin only" styling here — the markup simply is not there. */

.stack-960 { width: 100%; max-width: 960px; }

/* The dashboard steps out of the cream editorial theme on purpose: it is a
   working screen that people scan, so it gets a neutral grey ground, white
   panels and the full width of the window. Navy and gold survive as accents
   only. Every token is scoped here, so no other screen changes. */
#screen-dashboard,
.person-modal,
.toast {
  --d-bg: var(--gd-cream);
  --d-surface: var(--gd-white);
  --d-soft: var(--gd-cream-2);
  --d-line: var(--gd-taupe);
  --d-row: var(--line-soft);
  --d-text: var(--gd-navy);
  --d-body: var(--gd-ink);
  --d-muted: var(--gd-warmgray);
  --d-faint: var(--faint);
  --d-accent: var(--gd-navy);
  --d-radius: 12px;
  --d-shadow: var(--shadow-sm);
  --d-ease: cubic-bezier(0.16, 1, 0.3, 1);
}

body.on-dashboard::before { display: none; }
#screen-dashboard { background: var(--d-bg); color: var(--d-text); }

.dash-stage { padding: 28px 32px 48px; display: block; }
.dash-wrap { width: 100%; display: flex; flex-direction: column; gap: 20px; }

.dash-top { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.dash-title {
  margin: 0;
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 24px;
  letter-spacing: -0.02em;
  color: var(--d-text);
}
.dash-whoami { margin: 2px 0 0; font-size: 13.5px; color: var(--d-muted); }
.dash-top-right { display: flex; align-items: center; gap: 12px; }
.dash-updated { font-size: 12.5px; color: var(--d-faint); font-variant-numeric: tabular-nums; }

.btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 14px;
  border: 1px solid var(--d-line);
  border-radius: 8px;
  background: var(--d-surface);
  color: var(--d-body);
  font: 500 13.5px var(--font-ui);
  cursor: pointer;
  box-shadow: var(--d-shadow);
  transition: background 150ms ease, border-color 150ms ease, transform 150ms ease;
}
.btn-ghost:hover { background: var(--d-soft); border-color: var(--line-strong); }
.btn-ghost:active { transform: scale(0.98); }
.btn-ghost:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 2px; }
.btn-ghost:disabled { cursor: default; }
.btn-ghost svg { display: block; }
.btn-ghost.is-loading svg { animation: spin 800ms linear infinite; }

/* ── cards ── */
.kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.kpis.has-five { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.kpi {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 18px 20px;
  background: var(--d-surface);
  border: 1px solid var(--d-line);
  border-radius: var(--d-radius);
  box-shadow: var(--d-shadow);
  min-width: 0;
  animation: rise 420ms var(--d-ease) both;
}
.kpi:nth-child(2) { animation-delay: 40ms; }
.kpi:nth-child(3) { animation-delay: 80ms; }
.kpi:nth-child(4) { animation-delay: 120ms; }
.kpi:nth-child(5) { animation-delay: 160ms; }
.kpi-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.kpi-label { font-size: 13px; font-weight: 500; color: var(--d-muted); }
.kpi-icon {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--chip);
  color: var(--d-accent);
  flex-shrink: 0;
}
.kpi.is-accent .kpi-icon { background: var(--gold-bg); color: var(--gold-fg); }
.kpi.is-live .kpi-icon { background: var(--info-bg); color: var(--info-fg); }
.kpi-num {
  font-weight: 600;
  font-size: 28px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--d-text);
  font-variant-numeric: tabular-nums;
}
.kpi-sub { font-size: 12.5px; color: var(--d-faint); min-height: 1em; }
.kpi.is-live .kpi-sub { color: var(--info-fg); display: inline-flex; align-items: center; gap: 6px; }
.kpi.is-live .kpi-sub::before {
  content: "";
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
  animation: pulse 1.6s ease-in-out infinite;
}

/* ── panels ── */
.panel {
  position: relative;
  background: var(--d-surface);
  border: 1px solid var(--d-line);
  border-radius: var(--d-radius);
  box-shadow: var(--d-shadow);
  overflow: hidden;
  animation: rise 460ms var(--d-ease) both;
  animation-delay: 120ms;
}
.panel-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 16px;
  padding: 16px 20px;
}
.panel-head > div { min-width: 0; }
.panel-title {
  margin: 0;
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 16px;
  color: var(--d-text);
}
.live-panel .panel-head { justify-content: flex-start; gap: 10px; }
.panel-count {
  font-size: 12px; font-weight: 600;
  padding: 1px 8px; border-radius: 999px;
  background: var(--info-bg); color: var(--info-fg);
}
.panel-count:empty { display: none; }
.dash-note { font-size: 13px; color: var(--d-muted); margin: 2px 0 0; }
.panel-empty { margin: 0; padding: 20px; font-size: 14px; color: var(--d-muted); }

/* A thin sweeping bar under the panel head while a reload is in flight. */
.panel-busy { height: 2px; margin-top: -2px; position: relative; overflow: hidden; }
.panel.is-busy .panel-busy::after {
  content: "";
  position: absolute; top: 0; bottom: 0; width: 30%;
  background: linear-gradient(90deg, transparent, var(--gd-gold), transparent);
  animation: sweep 1s ease-in-out infinite;
}

.search {
  display: flex;
  align-items: center;
  gap: 8px;
  width: min(320px, 100%);
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--d-line);
  border-radius: 8px;
  background: var(--d-surface);
  color: var(--d-faint);
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
.search:focus-within { border-color: var(--focus-line); box-shadow: 0 0 0 4px var(--focus-ring); color: var(--d-body); }
.search input {
  flex: 1; min-width: 0;
  border: 0; outline: 0; background: transparent;
  font: 400 14px var(--font-ui); color: var(--d-text);
}
.search input::placeholder { color: var(--d-faint); }

/* ── running now ── */
.live-list { display: flex; flex-direction: column; }
.live-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(180px, 280px) auto;
  align-items: center;
  gap: 24px;
  padding: 14px 20px;
  border-top: 1px solid var(--d-row);
}
.live-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.live-title { font-weight: 600; font-size: 14px; color: var(--d-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.live-meta { font-size: 12.5px; color: var(--d-muted); }
.live-progress { display: flex; flex-direction: column; gap: 6px; }
.live-bar { display: block; height: 6px; border-radius: 999px; background: var(--d-row); overflow: hidden; }
.live-bar > span { display: block; height: 100%; border-radius: inherit; background: var(--gd-gold); transition: width 600ms var(--d-ease); }
.live-stage { font-size: 12px; color: var(--d-body); font-variant-numeric: tabular-nums; }

/* ── the table ── */
.dash-scroll { overflow-x: auto; }
.dash-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.dash-table th {
  text-align: left;
  font-weight: 500;
  font-size: 12px;
  color: var(--d-muted);
  padding: 10px 16px;
  background: var(--d-soft);
  border-top: 1px solid var(--d-line);
  border-bottom: 1px solid var(--d-line);
  white-space: nowrap;
}
.dash-table td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--d-row);
  vertical-align: middle;
  color: var(--d-body);
}
.dash-table tbody tr:last-child td { border-bottom: 0; }
.dash-table th:first-child, .dash-table td:first-child { padding-left: 20px; }
.dash-table th:last-child, .dash-table td:last-child { padding-right: 16px; }
.dash-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.dash-table th.num .th-sort { flex-direction: row-reverse; }
.dash-table .dash-when { white-space: nowrap; color: var(--d-muted); }
.dash-table tr.is-revoked td { opacity: 0.55; }
.dash-table tr.is-empty td { padding: 40px 20px; text-align: center; color: var(--d-muted); cursor: default; }

.th-sort {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
  transition: color 150ms ease;
}
.th-sort:hover { color: var(--d-text); }
.th-sort:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 2px; border-radius: 2px; }
.th-sort::after {
  content: "";
  width: 0; height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 5px solid currentColor;
  opacity: 0;
  transition: opacity 150ms ease, transform 200ms var(--d-ease);
}
.th-sort:hover::after { opacity: 0.35; }
.th-sort.is-sorted { color: var(--d-text); }
.th-sort.is-sorted::after { opacity: 1; }
.th-sort.is-desc::after { transform: rotate(180deg); }

.dash-who { display: flex; align-items: center; gap: 12px; min-width: 0; }
.avatar {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--d-accent, var(--gd-navy));
  color: var(--on-accent);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
.avatar-lg { width: 44px; height: 44px; font-size: 15px; }
.dash-person { display: block; font-weight: 600; color: var(--d-text); }
.dash-sub { display: block; margin-top: 1px; font-size: 12.5px; color: var(--d-muted); }
.dash-sub.is-error { color: var(--gd-overdue); }

.dash-roles { white-space: nowrap; }
.role-pill {
  display: inline-flex;
  align-items: center;
  margin-right: 6px;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  background: var(--chip);
  color: var(--d-body);
}
.role-pill.is-owner { background: var(--d-accent); color: var(--on-accent); }
.role-pill.is-admin { background: var(--gold-bg); color: var(--gold-fg); }
.role-pill.is-revoked { background: var(--err-bg); color: var(--err-fg); }
.role-pill.is-idle { background: transparent; color: var(--d-faint); padding-left: 0; }

.dash-go { width: 1%; white-space: nowrap; text-align: right; }
.row-btn {
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  margin-left: 4px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--d-muted);
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}
.row-btn svg { display: block; }
.row-btn:hover { background: var(--d-surface); border-color: var(--d-line); color: var(--d-text); }
.row-btn:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 1px; }
.row-btn.is-history { color: var(--d-body); }

/* Rows open a panel; they never act. Whole-row targets are easy to hit by
   accident, which is exactly why nothing behind one is destructive. */
.dash-table tbody tr:not(.is-skeleton):not(.is-empty) {
  cursor: pointer;
  transition: background 150ms ease;
  animation: row-in 360ms var(--d-ease) both;
  animation-delay: calc(var(--i, 0) * 22ms);
}
.dash-table tbody tr:not(.is-skeleton):not(.is-empty):hover { background: var(--d-soft); }
.dash-table tbody tr:hover .row-btn.is-manage { color: var(--d-text); }
.dash-table tbody tr:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: -2px; }

/* ── pager ── */
.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 20px;
  border-top: 1px solid var(--d-line);
  font-size: 13px;
  color: var(--d-muted);
}
.pager-info { font-variant-numeric: tabular-nums; }
.pager-right { display: flex; align-items: center; gap: 16px; }
.pager-size { display: inline-flex; align-items: center; gap: 8px; }
.pager-size select {
  height: 32px;
  padding: 0 8px;
  border: 1px solid var(--d-line);
  border-radius: 8px;
  background: var(--d-surface);
  font: 500 13px var(--font-ui);
  color: var(--d-body);
  cursor: pointer;
}
.pager-pages { display: flex; align-items: center; gap: 4px; }
.page-btn {
  min-width: 32px;
  height: 32px;
  padding: 0 8px;
  display: inline-grid;
  place-items: center;
  border: 1px solid transparent;
  border-radius: 8px;
  background: none;
  font: 500 13px var(--font-ui);
  color: var(--d-body);
  cursor: pointer;
  font-variant-numeric: tabular-nums;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}
.page-btn:hover:not(:disabled) { background: var(--chip); }
.page-btn:focus-visible { outline: 2px solid var(--gd-gold); outline-offset: 1px; }
.page-btn:disabled { color: var(--line-strong); cursor: default; }
.page-btn.is-current { background: var(--d-accent); color: var(--on-accent); border-color: var(--d-accent); }
.page-gap { padding: 0 4px; color: var(--d-faint); }

/* ── skeletons ── */
.sk {
  display: block;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--sk-a) 0%, var(--sk-b) 40%, var(--sk-a) 80%);
  background-size: 200% 100%;
  animation: shimmer 1.3s ease-in-out infinite;
}
.sk-line { height: 10px; width: 60%; margin: 4px 0; }
.sk-line.short { width: 35%; }
.sk-num { height: 26px; width: 45%; margin: 6px 0; }
.sk-avatar { width: 34px; height: 34px; border-radius: 50%; }
.sk-pill { height: 20px; width: 56px; border-radius: 999px; }
.sk-cell { height: 10px; width: 36px; margin-left: auto; }
.dash-table tr.is-skeleton td { cursor: default; }
.dash-table tr.is-skeleton .dash-who > div { flex: 1; }

/* ── the person panel ──────────────────────────────────────────────────── */

.person-modal {
  width: min(640px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  overflow: auto;
  overscroll-behavior: contain;      /* a scroll that reaches the end stops here */
  padding: 26px 28px 24px;
  border: 1px solid var(--d-line);
  border-radius: 16px;
  background: var(--d-surface);
  color: var(--d-body);
  font-family: var(--font-ui);
  box-shadow: var(--shadow-lg);
}
.person-modal::backdrop {
  background: var(--overlay);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

/* Opening grows the panel out of a slightly smaller, transparent state on a
   decelerating curve; closing reverses it faster. The backdrop fades with it. */
.person-modal[open] { animation: modal-in 320ms var(--d-ease) both; }
.person-modal[open]::backdrop { animation: fade-in 240ms ease both; }
.person-modal.is-closing { animation: modal-out 180ms cubic-bezier(0.4, 0, 1, 1) both; }
.person-modal.is-closing::backdrop { animation: fade-out 180ms ease both; }

.person-modal-head { display: flex; align-items: center; gap: 14px; margin: 0 0 20px; padding-right: 36px; }
.person-modal .dash-head {
  margin: 0;
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 18px;
  letter-spacing: -0.01em;
  color: var(--d-text);
}
.person-modal-email { margin: 1px 0 0; font-size: 13px; color: var(--d-muted); word-break: break-all; }

.person-modal-x { position: absolute; top: 16px; right: 16px; border-radius: 8px; }

.person-facts {
  display: grid;
  grid-template-columns: auto 1fr auto 1fr;
  column-gap: 16px;
  margin: 0 0 20px;
  padding: 6px 16px;
  background: var(--d-soft);
  border: 1px solid var(--d-row);
  border-radius: 10px;
  font-size: 13.5px;
}
.person-facts dt,
.person-facts dd { padding: 8px 0; }
.person-facts dt { color: var(--d-muted); white-space: nowrap; }
.person-facts dd {
  margin: 0;
  font-weight: 500;
  color: var(--d-text);
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 560px) {
  .person-facts { grid-template-columns: auto 1fr; }
}

.person-modal-error {
  margin: 0 0 16px;
  padding: 10px 14px;
  border: 1px solid var(--err-line);
  border-radius: 8px;
  background: var(--err-bg);
  color: var(--err-fg);
  font-size: 13.5px;
  line-height: 1.45;
  animation: rise 240ms var(--d-ease) both;
}

.person-modal-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.person-modal-actions .btn-secondary {
  border-radius: 8px;
  border-color: var(--d-line);
  color: var(--d-text);
  box-shadow: var(--d-shadow);
}
.person-modal-actions .btn-secondary:hover { background: var(--d-soft); border-color: var(--line-strong); }
.person-modal-actions .btn-secondary:disabled { opacity: 0.6; cursor: default; }
.person-modal-actions .btn-secondary.is-loading { opacity: 1; }
.person-modal-none { margin: 0; font-size: 13px; color: var(--d-muted); }

/* A spinner inside whichever action was clicked, until the server answers. */
.btn-spin {
  display: none;
  width: 14px; height: 14px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 700ms linear infinite;
}
.is-loading > .btn-spin { display: inline-block; }
.btn-secondary.btn-sm { gap: 8px; }

/* Revoking is reversible, so it is not a red button; it is the one button
   that has to look different from the one next to it. */
.btn-secondary.is-danger { color: var(--gd-overdue); }
.btn-secondary.is-danger:hover {
  border-color: var(--gd-overdue);
  background: var(--gd-white);
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 1000px) {
  .stack-960 { width: 100%; padding-left: 20px; padding-right: 20px; }
}


/* Programmatic focus target, not a control: no ring when the panel opens.
   :focus-visible still applies if somebody reaches it by keyboard. */
.person-modal .dash-head:focus { outline: none; }

@media (max-width: 1280px) {
  .kpis.has-five { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 760px) {
  .dash-stage { padding: 20px 16px 40px; }
  .kpis, .kpis.has-five { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .kpi-num { font-size: 22px; }
  .live-row { grid-template-columns: minmax(0, 1fr) auto; }
  .live-progress { grid-column: 1 / -1; grid-row: 2; }
  .search { width: 100%; }
}

/* ── motion ────────────────────────────────────────────────────────────────
   Nothing on screen should simply blink into place. Screens fade up when you
   switch to them, cards and rows settle in, the modal grows and shrinks. All
   of it on one decelerating curve, and all of it off for anyone who has
   asked their system for less motion. */

.screen:not([hidden]) > :not(.app-topbar) { animation: screen-in 320ms cubic-bezier(0.16, 1, 0.3, 1) both; }

/* Locks the page while a modal is open. The scrollbar gutter stays
   reserved (scrollbar-gutter on html), so nothing shifts sideways. */
html.is-locked, html.is-locked body { overflow: hidden; }

.toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  z-index: 200;
  max-width: min(440px, calc(100vw - 32px));
  padding: 11px 16px;
  border-radius: 10px;
  background: var(--gd-navy);
  color: var(--on-accent);
  font: 500 13.5px var(--font-ui);
  box-shadow: 0 12px 32px -8px rgba(16, 24, 40, 0.35);
  opacity: 0;
  transform: translate(-50%, 12px) scale(0.98);
  pointer-events: none;
  transition: opacity 220ms ease, transform 320ms var(--d-ease);
}
.toast.is-shown { opacity: 1; transform: translate(-50%, 0) scale(1); }
.toast.is-error { background: var(--gd-overdue); color: #FFFFFF; }

/* The theme switch cross-fades the whole page (a view transition, where
   supported) instead of snapping every colour at once. */
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 320ms; animation-timing-function: ease; }

@keyframes screen-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes rise      { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes row-in    { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@keyframes modal-in  { from { opacity: 0; transform: translateY(8px) scale(0.96); } to { opacity: 1; transform: none; } }
@keyframes modal-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(4px) scale(0.97); } }
@keyframes fade-in   { from { opacity: 0; } to { opacity: 1; } }
@keyframes fade-out  { from { opacity: 1; } to { opacity: 0; } }
@keyframes spin      { to { transform: rotate(360deg); } }
@keyframes shimmer   { from { background-position: 100% 0; } to { background-position: -100% 0; } }
@keyframes sweep     { from { left: -30%; } to { left: 100%; } }
@keyframes pulse     { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

@media (prefers-reduced-motion: reduce) {
  .screen:not([hidden]) > :not(.app-topbar),
  .kpi, .panel, .dash-table tbody tr,
  .person-modal[open], .person-modal[open]::backdrop,
  .person-modal.is-closing, .person-modal.is-closing::backdrop,
  .person-modal-error { animation: none; }
  .sk, .kpi.is-live .kpi-sub::before { animation: none; }
  .btn-spin, .btn-ghost.is-loading svg { animation-duration: 1.6s; }
  .toast { transition: opacity 150ms ease; transform: translate(-50%, 0); }
}

/* "· based on 9 past runs": the estimate's source, quieter than the figure. */
#screen-main .cost-basis { color: var(--gd-warmgray); font-weight: 400; }

/* Dissect Helper's status in Settings: a grey dot, green while it is running. */
.helper-dot {
  display: inline-block; width: 8px; height: 8px; margin-right: 8px; border-radius: 50%;
  background: var(--faint); vertical-align: 1px;
}
.helper-dot.is-online { background: var(--ok-fg); }
.helper-dot.is-warn { background: var(--warn-fg); }
.settings-help code { font-size: 12px; padding: 1px 5px; border-radius: 4px; background: var(--chip); }

/* Dissect Helper setup: which computer, then the button. */
.settings-setup { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-top: 16px; }
.settings-choice { display: flex; align-items: center; gap: 18px; margin: 0; padding: 0; border: 0; font-size: 14px; color: var(--gd-ink); }
.settings-choice legend { float: left; margin-right: 6px; padding: 0; font-weight: 600; color: var(--gd-navy); }
.settings-pick { margin: 8px 0 0; color: var(--err-fg); font-size: 13px; }
.settings-pick[hidden] { display: none; }
.settings-choice label { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
