/* LN24 News Finder — the board.

   Same visual language as the LN Lower Thirds panel: dark neon, drifting aura,
   red/blue accents, the LN24 mark. Tokens are lifted from that project's
   panel.css so the two tools read as one suite.

   Motion budget: transform / opacity / box-shadow only, and everything yields
   to prefers-reduced-motion. */

:root {
  /* surfaces */
  --bg:        #0a0c12;
  --bg-2:      rgba(255,255,255,.035);
  --bg-3:      rgba(255,255,255,.07);
  --line:      rgba(255,255,255,.10);
  --line-lit:  rgba(255,255,255,.20);

  /* type */
  --text:      #eaf0ff;
  --dim:       #9aa6c4;
  --faint:     #6b7699;

  /* neon */
  --cyan:      #22e0ff;
  --blue:      #4b74ff;
  --violet:    #a855f7;
  --magenta:   #ff2d78;
  --red:       #ff3b5c;
  --green:     #00e58a;
  --amber:     #ffb32e;

  --glow-blue:    rgba(75,116,255,.55);
  --glow-cyan:    rgba(34,224,255,.50);
  --glow-magenta: rgba(255,45,120,.45);
  --glow-green:   rgba(0,229,138,.55);

  --radius: 10px;
  --tap:    36px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  background: var(--bg);
  color: var(--text);
  font: 13.5px/1.5 -apple-system, "Segoe UI", "Helvetica Neue", sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* ── living background ────────────────────────────────────────────────── */

.aura { position: fixed; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
.aura i {
  position: absolute;
  display: block;
  border-radius: 50%;
  filter: blur(80px);
  opacity: .42;
  will-change: transform;
}
.aura i:nth-child(1) {
  width: 520px; height: 520px; top: -190px; left: -140px;
  background: radial-gradient(circle, var(--blue), transparent 68%);
  animation: drift-a 19s ease-in-out infinite;
}
.aura i:nth-child(2) {
  width: 440px; height: 440px; top: 28%; right: -190px;
  background: radial-gradient(circle, var(--magenta), transparent 68%);
  animation: drift-b 23s ease-in-out infinite;
}
.aura i:nth-child(3) {
  width: 560px; height: 560px; bottom: -240px; left: 22%;
  background: radial-gradient(circle, var(--violet), transparent 70%);
  animation: drift-c 27s ease-in-out infinite;
}

@keyframes drift-a {
  0%,100% { transform: translate3d(0,0,0)       scale(1); }
  50%     { transform: translate3d(60px,80px,0) scale(1.16); }
}
@keyframes drift-b {
  0%,100% { transform: translate3d(0,0,0)         scale(1.08); }
  50%     { transform: translate3d(-70px,-60px,0) scale(.92); }
}
@keyframes drift-c {
  0%,100% { transform: translate3d(0,0,0)        scale(1); }
  50%     { transform: translate3d(48px,-70px,0) scale(1.2); }
}

/* ── masthead ─────────────────────────────────────────────────────────── */

.masthead {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 22px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(10,12,18,.95), rgba(10,12,18,.78));
  backdrop-filter: blur(16px);
}

/* The LN24 mark: blue LN, red 24. No gradient, no animation — it reads as a
   logo rather than as another effect. */
.mark {
  font-weight: 800;
  font-size: 19px;
  letter-spacing: -.5px;
  line-height: 1;
  padding: 6px 9px;
  border-radius: 6px;
  color: var(--blue);
  background: var(--bg-3);
}
.mark span { color: var(--red); }

.titles h1 { margin: 0; font-size: 15px; font-weight: 650; letter-spacing: .2px; }
.titles p  { margin: 1px 0 0; font-size: 11px; color: var(--faint); }

.masthead .spacer { flex: 1; }

/* ── health line ──────────────────────────────────────────────────────── */

.health {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 11px;
  border-radius: 999px;
  font-size: 11px;
  color: var(--dim);
  background: var(--bg-2);
  border: 1px solid var(--line);
}
.health .dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 9px var(--glow-green);
}
.health.warn         { color: var(--amber); border-color: rgba(255,179,46,.4); }
.health.warn .dot    { background: var(--amber); box-shadow: 0 0 9px rgba(255,179,46,.7); }
.health.bad          { color: var(--red);   border-color: rgba(255,59,92,.45); }
.health.bad .dot     { background: var(--red);   box-shadow: 0 0 9px var(--glow-magenta); }

/* ── scan button ──────────────────────────────────────────────────────── */

.scan {
  position: relative;
  height: var(--tap);
  padding: 0 18px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  color: #fff;
  font-family: inherit;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .14em;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(180deg, #f2394a 0%, #e01e2e 55%, #c8121f 100%);
  box-shadow:
    0 0 22px rgba(232,32,47,.5),
    inset 0 1px 0 rgba(255,255,255,.28),
    inset 0 -1px 0 rgba(0,0,0,.28);
  transition: transform .16s cubic-bezier(.34,1.56,.64,1), box-shadow .28s, background .28s;
}
.scan:not(:disabled):hover {
  filter: brightness(1.08);
  box-shadow: 0 0 32px rgba(232,32,47,.7), inset 0 1px 0 rgba(255,255,255,.36);
}
.scan:not(:disabled):active { transform: scale(.975); }
.scan:disabled { cursor: progress; background: linear-gradient(180deg,#571420,#3c0c14); box-shadow: none; }

.scan .sheen {
  position: absolute; top: 0; bottom: 0; left: 0;
  width: 34%;
  pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.36), transparent);
  transform: translateX(-140%);
}
.scan:not(:disabled) .sheen { animation: sheen 4.2s cubic-bezier(.4,0,.5,1) infinite; }
@keyframes sheen {
  0%, 58% { transform: translateX(-140%); }
  100%    { transform: translateX(330%); }
}
.scan .label { position: relative; z-index: 1; }

/* The 24-hour scan is the cheap one. Same shape as SCAN NOW so they read as a
   pair, but none of the pull — two equally loud red buttons side by side would
   leave a producer deciding which one they meant. */
.scan.quiet {
  margin-right: 8px;
  padding: 0 13px;
  background: var(--bg-3);
  border-color: var(--line-lit);
  color: var(--dim);
  box-shadow: none;
}
.scan.quiet:not(:disabled):hover {
  filter: none;
  color: var(--text);
  border-color: var(--cyan);
  box-shadow: 0 0 16px rgba(34,224,255,.20);
}
.scan.quiet:disabled { background: var(--bg-2); color: var(--faint); box-shadow: none; }

/* ── desk tabs ────────────────────────────────────────────────────────── */

.decks {
  position: relative;
  z-index: 10;
  display: flex;
  gap: 9px;
  padding: 16px 22px 0;
}
.deck {
  position: relative;
  padding: 10px 17px;
  border-radius: var(--radius) var(--radius) 0 0;
  border: 1px solid var(--line);
  border-bottom: 0;
  background: var(--bg-2);
  color: var(--dim);
  font: inherit;
  font-size: 12.5px;
  font-weight: 650;
  cursor: pointer;
  transition: color .18s, background .18s, box-shadow .25s;
}
.deck:hover { color: var(--text); background: var(--bg-3); }
.deck .n {
  margin-left: 8px;
  padding: 1px 7px;
  border-radius: 8px;
  font-size: 10.5px;
  font-weight: 700;
  color: var(--faint);
  background: rgba(255,255,255,.07);
}
.deck.on { color: #fff; background: rgba(255,59,92,.10); border-color: rgba(255,59,92,.34); }
.deck.on .n { color: #fff; background: rgba(255,59,92,.28); }
/* the red live-bar, as on the lower-thirds dropdown */
.deck.on::after {
  content: "";
  position: absolute;
  left: 14px; right: 14px; top: 0;
  height: 2px;
  border-radius: 2px;
  background: #ff3b3b;
  box-shadow: 0 0 9px rgba(255,59,59,.75);
}

/* ── toolbar ──────────────────────────────────────────────────────────── */

main { position: relative; z-index: 1; padding: 0 22px 40px; }

.toolbar {
  /* backdrop-filter creates a stacking context, which trapped the open
     dropdown's z-index inside the toolbar — and the cards, which come later in
     the DOM and carry a transform of their own, painted straight over the top
     of it. Positioning the toolbar and lifting the whole context above the
     grid is the fix; raising z-index on .dd-menu alone could never work. */
  position: relative;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 13px 14px;
  border: 1px solid var(--line);
  border-radius: 0 var(--radius) var(--radius) var(--radius);
  background: rgba(10,12,18,.55);
  backdrop-filter: blur(10px);
}

.search {
  flex: 1;
  min-width: 220px;
  height: var(--tap);
  padding: 0 13px;
  color: var(--text);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  transition: border-color .18s, box-shadow .25s;
}
.search::placeholder { color: var(--faint); }
.search:focus {
  outline: none;
  border-color: rgba(34,224,255,.5);
  box-shadow: 0 0 0 3px rgba(34,224,255,.10), 0 0 20px rgba(34,224,255,.14);
}

/* Styled dropdown. The real <select> stays in the DOM but hidden — macOS draws
   a native select's menu itself and ignores CSS, so the open list has to be our
   own markup. Mirrors js/dropdown.js from the lower-thirds panel. */
.dd { position: relative; min-width: 150px; }
.dd select { display: none; }

.dd-trigger {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  height: var(--tap);
  padding: 0 12px;
  color: var(--text);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  font-size: 12.5px;
  text-align: left;
  cursor: pointer;
  transition: border-color .18s, box-shadow .25s, background .18s;
}
.dd-trigger:hover { border-color: var(--line-lit); background: var(--bg-3); }
.dd-open .dd-trigger,
.dd-trigger:focus-visible {
  outline: none;
  border-color: rgba(255,59,59,.55);
  box-shadow: 0 0 0 3px rgba(255,59,59,.10), 0 0 22px rgba(255,59,59,.18);
}

.dd-bar {
  flex: none;
  width: 3px; height: 15px;
  border-radius: 2px;
  background: #ff3b3b;
  box-shadow: 0 0 9px rgba(255,59,59,.7);
}
.dd-value { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dd-caret {
  flex: none;
  width: 7px; height: 7px;
  margin-right: 2px;
  border-right: 1.7px solid var(--dim);
  border-bottom: 1.7px solid var(--dim);
  transform: translateY(-2px) rotate(45deg);
  transition: transform .22s cubic-bezier(.34,1.56,.64,1);
}
.dd-open .dd-caret { transform: translateY(1px) rotate(225deg); }

.dd-menu {
  position: absolute;
  left: 0; right: 0;
  top: calc(100% + 6px);
  z-index: 40;
  max-height: 320px;
  overflow-y: auto;
  padding: 5px;
  border-radius: var(--radius);
  background: #12141d;
  border: 1px solid rgba(255,255,255,.14);
  box-shadow: 0 14px 40px rgba(0,0,0,.6), 0 0 26px rgba(61,109,255,.14);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px) scale(.98);
  transform-origin: top center;
  transition: opacity .16s, transform .22s cubic-bezier(.34,1.56,.64,1), visibility .16s;
}
.dd-open .dd-menu { opacity: 1; visibility: visible; transform: none; }

.dd-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 9px;
  border-radius: 6px;
  font-size: 12px;
  color: var(--dim);
  cursor: pointer;
  transition: background .14s, color .14s;
}
.dd-item .dd-bar { background: transparent; box-shadow: none; transition: background .14s, box-shadow .14s; }
.dd-item:hover { background: rgba(255,255,255,.06); color: var(--text); }
.dd-item:hover .dd-bar { background: rgba(255,59,59,.45); }
.dd-item.is-on { color: #fff; background: rgba(255,59,59,.10); }
.dd-item.is-on .dd-bar { background: #ff3b3b; box-shadow: 0 0 9px rgba(255,59,59,.7); }

.toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: var(--tap);
  padding: 0 13px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--bg-2);
  color: var(--dim);
  font-size: 12.5px;
  cursor: pointer;
  user-select: none;
  transition: color .18s, border-color .18s, box-shadow .25s, background .18s;
}
.toggle:hover { color: var(--text); border-color: var(--line-lit); }
.toggle.on {
  color: #fff;
  background: rgba(34,224,255,.10);
  border-color: rgba(34,224,255,.4);
  box-shadow: 0 0 18px rgba(34,224,255,.16);
}
.toggle input { display: none; }

.datepick {
  height: var(--tap);
  padding: 0 11px;
  color: var(--text);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
  color-scheme: dark;
}
.datepick:focus { outline: none; border-color: rgba(75,116,255,.55); box-shadow: 0 0 0 3px rgba(75,116,255,.12); }

/* ── card grid ────────────────────────────────────────────────────────── */

.grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
  gap: 15px;
  margin-top: 17px;
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(255,255,255,.028);
  overflow: hidden;
  cursor: pointer;
  transition: border-color .2s, box-shadow .3s, transform .18s;
  animation: card-in .32s cubic-bezier(.2,.8,.3,1) both;
}
@keyframes card-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.card:hover {
  transform: translateY(-2px);
  border-color: rgba(75,116,255,.4);
  box-shadow: 0 10px 34px rgba(0,0,0,.45), 0 0 26px rgba(75,116,255,.16);
}

.thumb { position: relative; aspect-ratio: 16/9; background: #0d1018; overflow: hidden; }
.thumb img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .4s; }
.card:hover .thumb img { transform: scale(1.035); }

.dur {
  position: absolute;
  right: 7px; bottom: 7px;
  padding: 2px 6px;
  border-radius: 5px;
  font-size: 11px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  color: #fff;
  background: rgba(0,0,0,.78);
}

.newflag {
  position: absolute;
  left: 7px; top: 7px;
  padding: 2px 8px;
  border-radius: 8px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .1em;
  color: #fff;
  background: linear-gradient(180deg,#f2394a,#c8121f);
  box-shadow: 0 0 16px rgba(232,32,47,.6);
}

.body { display: flex; flex-direction: column; gap: 7px; padding: 12px 13px 13px; }

.meta { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font-size: 10.5px; }
.src  { font-weight: 700; color: var(--text); }
.lean {
  padding: 1px 7px;
  border-radius: 7px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  font-size: 9.5px;
}
.lean-institutional { color:#7ce7ff; background:rgba(34,224,255,.12); border:1px solid rgba(34,224,255,.32); }
.lean-right,
.lean-centre-right  { color:#ff8fa3; background:rgba(255,59,92,.12); border:1px solid rgba(255,59,92,.32); }
.lean-wire          { color:#c9b4ff; background:rgba(168,85,247,.13); border:1px solid rgba(168,85,247,.32); }
.lean-centre        { color:#9aa6c4; background:rgba(255,255,255,.06); border:1px solid var(--line); }
.lean-state         { color:#ffcf7a; background:rgba(255,179,46,.11); border:1px solid rgba(255,179,46,.3); }
.lean-centre-left,
.lean-left          { color:#93b0ff; background:rgba(75,116,255,.12); border:1px solid rgba(75,116,255,.32); }

.when { margin-left: auto; color: var(--faint); }

.headline {
  margin: 0;
  font-size: 13.5px;
  font-weight: 650;
  line-height: 1.36;
  letter-spacing: .1px;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.summary {
  margin: 0;
  font-size: 12px;
  line-height: 1.55;
  color: var(--dim);
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.summary.none { color: var(--faint); font-style: italic; }

.tags { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
.tag {
  padding: 1px 7px;
  border-radius: 7px;
  font-size: 10px;
  color: var(--faint);
  background: rgba(255,255,255,.05);
  border: 1px solid var(--line);
}
.tag.cc { color: var(--cyan); border-color: rgba(34,224,255,.28); background: rgba(34,224,255,.08); }

/* ── empty / loading ──────────────────────────────────────────────────── */

.empty {
  grid-column: 1 / -1;
  padding: 70px 20px;
  text-align: center;
  color: var(--faint);
}
.empty strong { display: block; margin-bottom: 6px; font-size: 15px; color: var(--dim); }

.skeleton { position: relative; overflow: hidden; background: rgba(255,255,255,.035); border-radius: var(--radius); height: 270px; }
.skeleton::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.055), transparent);
  transform: translateX(-100%);
  animation: shimmer 1.4s infinite;
}
@keyframes shimmer { to { transform: translateX(100%); } }

/* ── scrollbars ───────────────────────────────────────────────────────── */

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  border: 3px solid transparent;
  border-radius: 6px;
  background: rgba(255,255,255,.13);
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.26); background-clip: content-box; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ── detail sheet ─────────────────────────────────────────────────────── */

.scrim {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: start center;
  padding: 34px 20px;
  overflow-y: auto;
  background: rgba(4,6,11,.74);
  backdrop-filter: blur(9px);
  animation: fade-in .18s ease both;
}
/* `display: grid` above beats the UA's [hidden] { display: none }, so the
   sheet would sit open over the board on first paint. Restate it. */
.scrim[hidden] { display: none; }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

.sheet {
  position: relative;
  width: min(940px, 100%);
  border: 1px solid var(--line-lit);
  border-radius: 14px;
  background: #0d1017;
  box-shadow: 0 30px 80px rgba(0,0,0,.7), 0 0 40px rgba(75,116,255,.12);
  overflow: hidden;
  animation: sheet-in .28s cubic-bezier(.2,.8,.3,1) both;
}
@keyframes sheet-in {
  from { opacity: 0; transform: translateY(14px) scale(.985); }
  to   { opacity: 1; transform: none; }
}

.sheet-close {
  position: absolute;
  right: 10px; top: 8px;
  z-index: 5;
  width: 32px; height: 32px;
  border: 0;
  border-radius: 50%;
  background: rgba(0,0,0,.55);
  color: #fff;
  font-size: 21px;
  line-height: 1;
  cursor: pointer;
  transition: background .16s, color .16s;
}
.sheet-close:hover { background: rgba(255,59,92,.85); }

.sheet-player { aspect-ratio: 16/9; background: #000; position: relative; }
.sheet-player iframe { width: 100%; height: 100%; border: 0; display: block; }
.sheet-player video { width: 100%; height: 100%; display: block; background: #000; }
.sheet-player video[hidden] { display: none; }

/* Live captions.
   Sat above the picture rather than below it so the producer reads them
   without their eye leaving the frame — and kept clear of the bottom
   quarter, where a broadcaster's own lower third and burned-in subtitles
   live. Text-shadow rather than a solid bar: a box would hide exactly the
   part of the shot you are judging. */
.caption-layer {
  position: absolute;
  left: 6%;
  right: 6%;
  bottom: 15%;
  text-align: center;
  pointer-events: none;
  z-index: 3;
}
.caption-layer[hidden] { display: none; }

.caption-layer span {
  display: inline-block;
  padding: 6px 12px;
  border-radius: 6px;
  background: rgba(5, 7, 12, 0.72);
  color: #fff;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.01em;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
  box-shadow: 0 0 24px rgba(34, 224, 255, 0.14);
}
.caption-layer span:empty { display: none; }

/* Embed refused — the fallback panel that replaces the dead frame. */
.embed-fallback {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 24px 34px;
  text-align: center;
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(75, 116, 255, 0.16), transparent 70%),
    #05070c;
}
.embed-fallback[hidden] { display: none; }
.ef-title { font-size: 15px; font-weight: 700; color: var(--fg); }
.ef-body { margin: 0; max-width: 46ch; font-size: 12.5px; line-height: 1.6; color: var(--dim); }
.ef-actions { display: flex; gap: 10px; margin-top: 4px; }
.as-btn { text-decoration: none; display: inline-flex; align-items: center; }
.embed-fallback .hint { font-size: 11.5px; color: var(--faint); min-height: 14px; }

.sheet-body { padding: 17px 20px 22px; }
.sheet-title { margin: 5px 0 8px; font-size: 19px; font-weight: 700; line-height: 1.3; }
.sheet-summary { margin: 0 0 14px; font-size: 13px; line-height: 1.6; color: var(--dim); }

/* transcript */
.transcript-block {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 12px 0 14px;
  border-top: 1px solid var(--line);
}
.transcript-block .hint { font-size: 11.5px; color: var(--faint); }
.transcript {
  flex-basis: 100%;
  max-height: 240px;
  overflow-y: auto;
  margin-top: 4px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--cyan);
  border-radius: 8px;
  background: rgba(34,224,255,.04);
  font-size: 12.5px;
  line-height: 1.65;
  color: var(--dim);
  white-space: pre-wrap;
}

button.secondary {
  height: var(--tap);
  padding: 0 15px;
  color: var(--text);
  background: var(--bg-3);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color .18s, box-shadow .25s, transform .12s, color .18s;
}
button.secondary:hover {
  color: #fff;
  border-color: rgba(61,109,255,.5);
  box-shadow: 0 0 18px rgba(61,109,255,.2);
}
button.secondary:active { transform: scale(.97); }
button.secondary.sm { height: 30px; padding: 0 11px; font-size: 11.5px; }
button.secondary:disabled { opacity: .5; cursor: default; box-shadow: none; }

/* export panel */
.export { border-top: 1px solid var(--line); padding-top: 15px; }
.export h3 {
  margin: 0 0 12px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
}

.marks { display: flex; flex-wrap: wrap; align-items: end; gap: 12px; margin-bottom: 13px; }
.mark-field { display: flex; align-items: center; gap: 8px; }
.mark-field label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--faint);
}
.mark-field input {
  width: 106px;
  height: var(--tap);
  padding: 0 11px;
  color: var(--text);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  font-variant-numeric: tabular-nums;
  transition: border-color .18s, box-shadow .25s;
}
.mark-field input:focus {
  outline: none;
  border-color: rgba(34,224,255,.5);
  box-shadow: 0 0 0 3px rgba(34,224,255,.1);
}
.mark-len {
  margin-left: auto;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--cyan);
  text-shadow: 0 0 12px var(--glow-cyan);
}
.mark-len.bad { color: var(--red); text-shadow: 0 0 12px var(--glow-magenta); }

.export-row { display: flex; flex-wrap: wrap; gap: 11px; align-items: center; margin-bottom: 15px; }
.export-row .dd { min-width: 190px; }

/* GET CLIP — the "Solid Live" treatment from the lower-thirds panel */
.generate {
  position: relative;
  display: block;
  width: 100%;
  height: 52px;
  border: 1px solid transparent;
  border-radius: 10px;
  color: #fff;
  font-family: inherit;
  font-size: 14px;
  font-weight: 900;
  line-height: 1;
  letter-spacing: .22em;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(180deg, #f2394a 0%, #e01e2e 55%, #c8121f 100%);
  box-shadow:
    0 0 24px rgba(232,32,47,.55),
    0 0 62px rgba(232,32,47,.28),
    inset 0 1px 0 rgba(255,255,255,.3),
    inset 0 -1px 0 rgba(0,0,0,.28);
  transition: transform .16s cubic-bezier(.34,1.56,.64,1), box-shadow .28s, background .28s, color .28s;
}
.generate:not(:disabled):not(.running):not(.done):hover {
  filter: brightness(1.08);
  box-shadow: 0 0 34px rgba(232,32,47,.72), 0 0 84px rgba(232,32,47,.42), inset 0 1px 0 rgba(255,255,255,.38);
}
.generate:not(:disabled):not(.running):not(.done):active { transform: scale(.982); }
.generate:disabled {
  cursor: default;
  color: #6a6a74;
  background: linear-gradient(180deg, #1e1e25, #16161c);
  border-color: rgba(255,255,255,.06);
  box-shadow: none;
}
.generate .sheen {
  position: absolute; top: 0; bottom: 0; left: 0;
  width: 34%;
  pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.38), transparent);
  transform: translateX(-140%);
}
.generate:not(:disabled):not(.running):not(.done) .sheen {
  animation: sheen 4.2s cubic-bezier(.4,0,.5,1) infinite;
}
.generate .label { position: relative; z-index: 1; }
.generate.running { cursor: progress; background: linear-gradient(180deg,#571420,#3c0c14); box-shadow: 0 0 20px rgba(232,32,47,.34); }
.generate.done {
  cursor: default;
  color: #3ee6a0;
  background: linear-gradient(180deg,#123528,#0c2620);
  border-color: rgba(62,230,160,.55);
  box-shadow: 0 0 26px rgba(47,191,136,.42), 0 0 64px rgba(47,191,136,.2);
}

.status { margin: 11px 2px 0; min-height: 15px; font-size: 11.5px; color: var(--dim); text-align: center; }
.status a { color: var(--text); text-decoration: underline; }
.status a:hover { color: var(--cyan); }
.status.bad  { color: var(--red);  text-shadow: 0 0 14px var(--glow-magenta); }
.status.good { color: #3ee6a0;     text-shadow: 0 0 14px rgba(62,230,160,.45); }

/* ── location badges ──────────────────────────────────────────────────── */
/* Where the story is about, not where the broadcaster sits. Pinned above the
   headline because on a scan it's the fastest way to orient. */

.places { display: flex; flex-wrap: wrap; gap: 5px; }
.place {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px 2px 7px;
  border-radius: 7px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .02em;
  color: #ffd9a1;
  background: rgba(255,179,46,.12);
  border: 1px solid rgba(255,179,46,.34);
}
.place::before {
  content: "";
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--amber);
  box-shadow: 0 0 7px rgba(255,179,46,.9);
}

.tag.tr { color: var(--violet); border-color: rgba(168,85,247,.34); background: rgba(168,85,247,.10); }

.sheet-places { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 0; }

/* ── press briefings ──────────────────────────────────────────────────── */
/* Briefings are the priority material — usually official releases or pool
   feeds, so they routinely come cleared. They get their own mark. */

/* Amber, so it never reads as the cyan BRIEFING badge at a glance. Sits top-
   left because .brief-badge is bottom-left and .newflag is top-right — a
   briefing about the day's biggest story carries both, and that is the single
   most valuable card on the board, so the two must stack rather than collide. */
.story-badge {
  position: absolute;
  left: 7px; top: 7px;
  padding: 2px 8px;
  border-radius: 8px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .08em;
  color: #0a0c12;
  background: linear-gradient(180deg, #ffd27a, #ffb32e);
  box-shadow: 0 0 16px rgba(255, 179, 46, .55);
}
.card.is-big { border-color: rgba(255, 179, 46, .34); }
.card.is-big:hover {
  border-color: rgba(255, 179, 46, .62);
  box-shadow: 0 10px 34px rgba(0,0,0,.45), 0 0 30px rgba(255, 179, 46, .2);
}

.brief-badge {
  position: absolute;
  left: 7px; bottom: 7px;
  padding: 2px 8px;
  border-radius: 8px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .08em;
  color: #0a0c12;
  background: linear-gradient(180deg, #7ce7ff, #22e0ff);
  box-shadow: 0 0 16px var(--glow-cyan);
}
.card.is-brief { border-color: rgba(34,224,255,.34); }
.card.is-brief:hover { border-color: rgba(34,224,255,.62); box-shadow: 0 10px 34px rgba(0,0,0,.45), 0 0 30px rgba(34,224,255,.2); }

.toggle.brief.on {
  color: #0a0c12;
  background: linear-gradient(180deg,#7ce7ff,#22e0ff);
  border-color: rgba(34,224,255,.6);
  box-shadow: 0 0 20px var(--glow-cyan);
}

/* ── X paste bar ──────────────────────────────────────────────────────── */

.xbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 11px;
  padding: 12px 14px;
  border: 1px solid rgba(34,224,255,.22);
  border-radius: var(--radius);
  background: rgba(34,224,255,.045);
}
/* `display: flex` above beats the UA's [hidden] { display: none }, so the bar
   would show on every tab. Same trap as .scrim — restate it. */
.xbar[hidden] { display: none; }
.xbar .hint { flex-basis: 100%; font-size: 11px; color: var(--faint); }
.xbar .search { min-width: 300px; }

/* ── multiple in/out segments ─────────────────────────────────────────── */

.segments { display: flex; flex-direction: column; gap: 8px; margin-bottom: 11px; }

.seg-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--cyan);
  border-radius: 8px;
  background: var(--bg-2);
  animation: card-in .2s cubic-bezier(.2,.8,.3,1) both;
}
.seg-row .n {
  width: 18px;
  font-size: 11px;
  font-weight: 800;
  color: var(--cyan);
  text-align: center;
}
.seg-row label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--faint);
}
.seg-row input {
  width: 92px;
  height: 30px;
  padding: 0 9px;
  color: var(--text);
  background: rgba(255,255,255,.04);
  border: 1px solid var(--line);
  border-radius: 7px;
  font: inherit;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.seg-row input:focus { outline: none; border-color: rgba(34,224,255,.55); box-shadow: 0 0 0 3px rgba(34,224,255,.1); }
.seg-row .dur { margin-left: auto; font-size: 11px; font-variant-numeric: tabular-nums; color: var(--dim); }
.seg-row .drop-seg {
  padding: 0 4px;
  background: none;
  border: 0;
  color: var(--faint);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: color .15s, text-shadow .15s;
}
.seg-row .drop-seg:hover { color: var(--red); text-shadow: 0 0 10px var(--glow-magenta); }
.seg-row.only .drop-seg { visibility: hidden; }

.seg-actions { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; margin-bottom: 14px; }
.seg-actions .hint { font-size: 11px; color: var(--faint); flex: 1; min-width: 180px; }

/* article cards have no player, so the whole card is the link */
.card.is-article .thumb { background: linear-gradient(150deg, rgba(75,116,255,.16), rgba(255,45,120,.10)); }
.card.is-article .thumb .noimg {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-size: 11px; font-weight: 700; letter-spacing: .16em;
  color: var(--faint);
}

/* Captions segmented control.
   Red when captions are off, green when they are running — the state is
   readable from across the room without reading the words. Text stays white
   in both halves so the colour is doing the signalling, not the type. */
.capseg {
  display: inline-flex;
  padding: 3px;
  gap: 3px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-2);
}
.capbtn {
  position: relative;
  padding: 7px 15px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: #fff;
  font: inherit;
  font-size: 12.5px;
  font-weight: 650;
  cursor: pointer;
  transition: background .2s, box-shadow .28s, font-weight .2s, opacity .2s;
}
.capbtn:not(.is-on) { opacity: .62; }
.capbtn:hover:not(.is-on) { opacity: 1; background: var(--bg-3); }
.capbtn:disabled { opacity: .4; cursor: progress; }

.capbtn.is-on { font-weight: 800; opacity: 1; }

#captionsOnBtn.is-on {
  background: rgba(0, 229, 138, .16);
  box-shadow: 0 0 20px rgba(0, 229, 138, .45), inset 0 0 0 1px rgba(0, 229, 138, .55);
}
#captionsOffBtn.is-on {
  background: rgba(255, 59, 92, .16);
  box-shadow: 0 0 20px rgba(255, 59, 92, .45), inset 0 0 0 1px rgba(255, 59, 92, .55);
}

/* Transcribing. Sits to the right of the control rather than replacing a
   label, so the buttons never shift while the job runs. */
.capspin {
  width: 17px;
  height: 17px;
  flex: none;
  border-radius: 50%;
  border: 2px solid rgba(0, 229, 138, .22);
  border-top-color: var(--green);
  animation: capspin .7s linear infinite;
}
.capspin[hidden] { display: none; }
@keyframes capspin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .capspin { animation-duration: 2.4s; }
}

/* ── sort direction + result count ────────────────────────────────────── */

.dirbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap);
  height: var(--tap);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-2);
  color: var(--dim);
  font-size: 15px;
  cursor: pointer;
  transition: color .18s, background .18s, border-color .18s;
}
.dirbtn:hover { color: var(--text); background: var(--bg-3); border-color: var(--line-lit); }
.dirbtn .arrow { transition: transform .22s cubic-bezier(.34,1.56,.64,1); }
.dirbtn.asc .arrow { transform: rotate(180deg); }
.dirbtn.asc {
  color: #d8fbff;
  border-color: rgba(34,224,255,.45);
  box-shadow: 0 0 16px rgba(34,224,255,.18) inset;
}

/* Pushed to the end of the toolbar row so it reads as an answer to the
   filters rather than another control to set. */
.resultcount {
  margin-left: auto;
  padding: 0 4px;
  font-size: 12px;
  font-weight: 650;
  color: var(--dim);
  white-space: nowrap;
}
.resultcount b { color: var(--text); font-weight: 800; }
.resultcount .capped { color: var(--faint); font-weight: 500; }
.resultcount.none b { color: var(--red); }

/* ── Sources tab ──────────────────────────────────────────────────────── */

.sources { position: relative; z-index: 1; margin-top: 17px; }
.sources[hidden] { display: none; }

.addbox {
  padding: 16px 18px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    radial-gradient(110% 140% at 0% 0%, rgba(75,116,255,.10), transparent 62%),
    rgba(255,255,255,.028);
}
.addbox h3 { margin: 0 0 4px; font-size: 14px; font-weight: 700; }
.addbox .hint { display: block; margin-bottom: 12px; font-size: 12px; color: var(--faint); line-height: 1.55; }
.addrow { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.addrow + .addrow { margin-top: 10px; }
.addrow.opts .hint { font-size: 11.5px; color: var(--faint); }
.addrow .search { flex: 1; min-width: 300px; }

.srcpreview {
  margin-top: 12px;
  padding: 13px 15px;
  border-radius: var(--radius);
  border: 1px solid rgba(0,229,138,.35);
  background: rgba(0,229,138,.06);
  font-size: 12.5px;
  line-height: 1.6;
}
.srcpreview[hidden] { display: none; }
.srcpreview.bad { border-color: rgba(255,59,92,.42); background: rgba(255,59,92,.07); }
.srcpreview .found { font-weight: 700; color: var(--text); }
.srcpreview .via { color: var(--faint); font-size: 11.5px; }
.srcpreview ul { margin: 8px 0 10px; padding-left: 17px; color: var(--dim); }
.srcpreview li { margin: 2px 0; }

.srcfilters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 18px 0 12px;
  position: relative;
  z-index: 20;
}
.srcfilters .search { flex: 1; min-width: 220px; }

.srclist { display: flex; flex-direction: column; gap: 7px; }

/* ── Upload tab ───────────────────────────────────────────────────────── */

.uploadpane { position: relative; z-index: 1; margin-top: 17px; }
.uploadpane[hidden] { display: none; }

/* Reads as a field rather than a button: it sits on the row under the link
   box and does the same job, so it should carry the same weight as one. */
.filepick {
  flex: 1;
  min-width: 300px;
  display: flex;
  align-items: center;
  height: var(--tap);
  padding: 0 14px;
  border: 1px dashed var(--line-lit);
  border-radius: var(--radius);
  background: var(--bg-2);
  color: var(--dim);
  font-size: 12.5px;
  cursor: pointer;
  transition: border-color .18s, color .18s, background .18s;
}
.filepick:hover { border-color: var(--cyan); color: var(--text); }
.filepick.dragging {
  border-color: var(--cyan);
  border-style: solid;
  color: var(--text);
  background: rgba(34,224,255,.07);
}
.filepick.has-file { border-style: solid; border-color: rgba(0,229,138,.45); color: var(--text); }

.upbar {
  height: 4px;
  margin-top: 12px;
  border-radius: 3px;
  background: var(--bg-3);
  overflow: hidden;
}
.upfill {
  height: 100%;
  width: 0;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--blue), var(--cyan));
  transition: width .2s linear;
}

.srcrow {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(255,255,255,.026);
  transition: border-color .18s, background .18s;
}
.srcrow:hover { border-color: var(--line-lit); background: rgba(255,255,255,.05); }
.srcrow.off { opacity: .48; }

.srcrow .kindtag {
  flex: none;
  width: 62px;
  text-align: center;
  padding: 3px 0;
  border-radius: 6px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  background: rgba(255,255,255,.07);
  color: var(--dim);
}
.srcrow .kindtag.youtube { color: #ffd9df; background: rgba(255,59,92,.18); }
.srcrow .kindtag.article { color: #d6e2ff; background: rgba(75,116,255,.20); }

.srcrow .nm { flex: 1; min-width: 0; }
.srcrow .nm b { display: block; font-size: 13px; font-weight: 650; }
.srcrow .nm a { color: var(--faint); font-size: 11px; text-decoration: none; word-break: break-all; }
.srcrow .nm a:hover { color: var(--cyan); }

.srcrow .facts { display: flex; gap: 6px; flex: none; }
.srcrow .facts span {
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 650;
  background: rgba(255,255,255,.06);
  color: var(--dim);
}
.srcrow .origin { font-size: 10.5px; color: var(--faint); flex: none; width: 54px; text-align: right; }

.srcrow .act {
  flex: none;
  padding: 6px 12px;
  border-radius: 7px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--dim);
  font: inherit;
  font-size: 11.5px;
  font-weight: 650;
  cursor: pointer;
  transition: color .16s, border-color .16s, background .16s;
}
.srcrow .act.remove:hover { color: #fff; border-color: rgba(255,59,92,.6); background: rgba(255,59,92,.16); }
.srcrow .act.restore:hover { color: #fff; border-color: rgba(0,229,138,.6); background: rgba(0,229,138,.16); }

/* `hidden` is only a default style, and any `display` rule beats it. .grid is
   display:grid and .toolbar is display:flex, so both ignored the attribute and
   the Sources tab rendered underneath a live board. Third time this trap has
   come up in this stylesheet — .scrim and .xbar were the first two. */
.grid[hidden],
.toolbar[hidden] { display: none; }

/* ── Media Batch tab ──────────────────────────────────────────────────── */

.batch { position: relative; z-index: 1; margin-top: 17px; }
.batch[hidden] { display: none; }

.batchhead {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 16px;
}
.batchhead h3 { margin: 0 0 4px; font-size: 14px; font-weight: 700; }
.batchhead .hint { margin: 0; font-size: 12px; color: var(--faint); line-height: 1.55; max-width: 62ch; }

/* Clear batch. Red, and idly breathing so it reads as a live control rather
   than a static label — the press animation below is a bigger, sharper
   version of the same glow, not a different effect. */
.clearbatch {
  flex: none;
  padding: 9px 18px;
  border-radius: var(--radius);
  border: 1px solid rgba(255,59,92,.4);
  background: rgba(255,59,92,.09);
  color: #fff;
  font: inherit;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .04em;
  cursor: pointer;
  box-shadow: 0 0 10px rgba(255,59,92,.24);
  animation: clearbatch-idle 2.6s ease-in-out infinite;
  transition: background .2s, border-color .2s;
}
.clearbatch:hover:not(:disabled) { background: rgba(255,59,92,.18); border-color: rgba(255,59,92,.65); }
.clearbatch:disabled { opacity: .32; cursor: default; animation: none; box-shadow: none; }

@keyframes clearbatch-idle {
  0%, 100% { box-shadow: 0 0 8px rgba(255,59,92,.22); }
  50%      { box-shadow: 0 0 17px rgba(255,59,92,.52); }
}

/* Pressed: bigger, brighter, then settles straight back to the idle breathe —
   no separate "lit" resting state, since the click is a one-shot action, not
   a mode the button stays in. */
.clearbatch.pressed { animation: clearbatch-press .4s cubic-bezier(.34,1.56,.64,1); }
@keyframes clearbatch-press {
  0%   { transform: scale(1);    box-shadow: 0 0 10px rgba(255,59,92,.3); }
  40%  { transform: scale(1.16); box-shadow: 0 0 32px rgba(255,59,92,.9), 0 0 54px rgba(255,59,92,.4); }
  100% { transform: scale(1);    box-shadow: 0 0 8px rgba(255,59,92,.22); }
}

@media (prefers-reduced-motion: reduce) {
  .clearbatch, .clearbatch.pressed { animation: none; }
}

/* Active-job count on the tab itself — the whole point is being able to walk
   away, so the number has to be visible from the tab strip, not just inside
   the pane. Glows the same green as a running caption button: this app's
   established "something is happening" colour. */
.deck .n.batch-badge {
  color: #052018;
  background: rgba(255,255,255,.07);
}
.deck .n.batch-badge.batch-active {
  color: #052018;
  background: var(--green);
  box-shadow: 0 0 10px rgba(0,229,138,.65);
  animation: batch-badge-pulse 1.6s ease-in-out infinite;
}
@keyframes batch-badge-pulse {
  0%, 100% { box-shadow: 0 0 10px rgba(0,229,138,.55); }
  50%      { box-shadow: 0 0 16px rgba(0,229,138,.9); }
}

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

.batch-row {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(255,255,255,.026);
  transition: border-color .18s, background .18s;
}
.batch-row:hover { border-color: var(--line-lit); background: rgba(255,255,255,.05); }
.batch-row.running { border-color: rgba(0,229,138,.3); }
.batch-row.done     { border-color: rgba(0,229,138,.18); }
.batch-row.failed   { border-color: rgba(255,59,92,.35); }

.thumb.sm {
  flex: none;
  width: 76px;
  height: 43px;
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg-2);
}
.thumb.sm img { width: 100%; height: 100%; object-fit: cover; display: block; }

.batch-info { flex: 1; min-width: 0; }
.batch-title {
  font-size: 13px;
  font-weight: 650;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.batch-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 3px;
  font-size: 11px;
  color: var(--faint);
}
.batch-meta .src { color: var(--dim); font-weight: 600; }

.batch-status {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  min-width: 190px;
  text-align: right;
}

.batch-progress {
  display: flex;
  align-items: center;
  gap: 8px;
}

.batch-bar {
  width: 100px;
  height: 5px;
  border-radius: 3px;
  background: rgba(255,255,255,.08);
  overflow: hidden;
}
.batch-fill {
  height: 100%;
  border-radius: 3px;
  background: linear-gradient(90deg, #17c98a, var(--green));
  box-shadow: 0 0 8px rgba(0,229,138,.6);
  transition: width .5s ease;
}

/* The percentage itself is the thing the user asked to glow — a small pulse
   on the text, distinct from (and in addition to) the spinner beside it. */
.batch-pct {
  min-width: 44px;
  font-size: 12.5px;
  font-weight: 800;
  color: #baffe3;
  text-shadow: 0 0 8px rgba(0,229,138,.55);
  animation: batch-pct-glow 1.8s ease-in-out infinite;
  font-variant-numeric: tabular-nums;
}
@keyframes batch-pct-glow {
  0%, 100% { text-shadow: 0 0 6px rgba(0,229,138,.4); }
  50%      { text-shadow: 0 0 12px rgba(0,229,138,.85); }
}
.batch-pct.good { color: var(--green); text-shadow: 0 0 8px rgba(0,229,138,.6); animation: none; }
.batch-pct.bad  { color: var(--red);   text-shadow: 0 0 8px rgba(255,59,92,.55); animation: none; }

.capspin.sm { width: 13px; height: 13px; border-width: 2px; }

.batch-stage {
  font-size: 11px;
  color: var(--faint);
  max-width: 220px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.batch-stage.bad { color: #ffb3c0; }

.batch-status .act.sm {
  padding: 4px 10px;
  font-size: 10.5px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--dim);
  cursor: pointer;
  transition: color .16s, border-color .16s, background .16s;
}
.batch-status .act.sm:hover { color: #fff; border-color: var(--line-lit); background: var(--bg-3); }

/* ── Caption placement ──────────────────────────────────────────────────────
   Say where the burned-in subtitles go by drawing a rectangle on the picture,
   rather than by typing numbers nobody can picture. The overlay only exists
   while placing — the rest of the time the player is the player. */
.place-layer {
  position: absolute;
  inset: 0;
  z-index: 6;
  cursor: crosshair;
  background: rgba(5, 7, 12, 0.35);
  touch-action: none;
}
.place-layer[hidden] { display: none; }

/* The strip the AI SUBTITLES mark owns. Shown rather than silently enforced:
   a producer who drags into it can see why the box stops. */
.place-reserved {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 9%;
  background: repeating-linear-gradient(
    -45deg,
    rgba(255, 179, 46, 0.16) 0 6px,
    rgba(255, 179, 46, 0.04) 6px 12px);
  border-top: 1px dashed rgba(255, 179, 46, 0.5);
  pointer-events: none;
}

.place-box {
  position: absolute;
  border: 1.5px solid var(--cyan);
  background: rgba(34, 224, 255, 0.10);
  box-shadow: 0 0 20px var(--glow-cyan), inset 0 0 0 1px rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  cursor: move;
}
.place-box[hidden] { display: none; }

/* Sample text sits at the bottom of the box because that is where real
   captions sit — lines stack upward from the baseline. */
.place-sample {
  max-width: 100%;
  margin-bottom: 2px;
  padding: 2px 7px;
  background: #000;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.3;
  text-align: center;
  pointer-events: none;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* One grip per corner. Grabbing any of them pins the opposite corner and
   drags this one, which is what every crop rectangle in every editor does —
   and it means a box can be reshaped from whichever side has room, rather
   than only from the bottom right. */
.place-grip {
  position: absolute;
  width: 13px; height: 13px;
  border-radius: 3px;
  background: var(--cyan);
  box-shadow: 0 0 10px var(--glow-cyan);
}
.place-grip[data-corner="nw"] { left: -6px;  top: -6px;    cursor: nwse-resize; }
.place-grip[data-corner="ne"] { right: -6px; top: -6px;    cursor: nesw-resize; }
.place-grip[data-corner="sw"] { left: -6px;  bottom: -6px; cursor: nesw-resize; }
.place-grip[data-corner="se"] { right: -6px; bottom: -6px; cursor: nwse-resize; }

.place-hint {
  position: absolute;
  top: 10px; left: 50%;
  transform: translateX(-50%);
  padding: 5px 11px;
  border-radius: 999px;
  background: rgba(5, 7, 12, 0.85);
  border: 1px solid var(--line-lit);
  color: var(--text);
  font-size: 12px;
  white-space: nowrap;
  pointer-events: none;
}
.place-hint[hidden] { display: none; }

/* The row under the subtitles toggle. */
.subs-place,
.subs-place-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 8px;
}
.subs-place[hidden],
.subs-place-actions[hidden] { display: none; }

.sp-label {
  color: var(--faint);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.sp-value {
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
}
.sp-value.is-custom { color: var(--cyan); }

/* Keep GET CLIP clear of whatever sits above it. .export-row already carried
   this gap; the placement rows now come between the two, so the space belongs
   on the button. Adjacent vertical margins collapse, so with the placement
   rows hidden the spacing is exactly what it was before they existed. */
.export .generate { margin-top: 15px; }
