:root {
  --ink: #101010;
  --paper: #f4f1ea;
  --panel: #ffffff;
  --line: #d7d0c4;
  --muted: #6d675f;
  --red: #c5162e;
  --blue: #194f90;
  --green: #186a4d;
  --amber: #a05b00;
  --shadow: 0 18px 50px rgba(18, 16, 13, 0.12);
}

* {
  box-sizing: border-box;
}

/* Every panel that hides itself does so with the hidden attribute, and several of
   those elements also carry a display rule from a class. A class beats the
   browser's own [hidden] rule, so hiding silently did nothing: the signed-out
   panel still drew a Sign out button, and the operator-token box still sat in
   front of a reporter - the one field they must never be invited to type their
   own password into. */
[hidden] {
  display: none !important;
}

body {
  margin: 0;
  color: var(--ink);
  background:
    linear-gradient(90deg, rgba(16, 16, 16, 0.035) 1px, transparent 1px),
    linear-gradient(0deg, rgba(16, 16, 16, 0.03) 1px, transparent 1px),
    var(--paper);
  background-size: 34px 34px;
  font-family: "Aptos", "Segoe UI", sans-serif;
}

button {
  font: inherit;
}

.shell {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 260px 1fr;
}

.rail {
  border-right: 1px solid var(--line);
  background: #161616;
  color: #f8f5ed;
  padding: 20px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 56px;
  margin-bottom: 26px;
}

.brand-mark {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 4px;
  background: var(--red);
  color: #fff;
  font-weight: 900;
  font-size: 22px;
}

.brand strong,
.brand span {
  display: block;
}

.brand span {
  color: #bbb5a9;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

nav {
  display: grid;
  gap: 8px;
}

.nav-item {
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 4px;
  background: transparent;
  color: #f8f5ed;
  min-height: 42px;
  padding: 0 12px;
  text-align: left;
  cursor: pointer;
}

.nav-item:hover,
.nav-item:focus-visible,
.nav-item.is-active {
  outline: none;
  background: #f8f5ed;
  color: #111;
}

main {
  min-width: 0;
  padding: 26px;
}

.topbar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  border-bottom: 3px solid var(--ink);
  padding-bottom: 18px;
}

.eyebrow {
  margin: 0 0 4px;
  color: var(--red);
  font-weight: 800;
  text-transform: uppercase;
  font-size: 12px;
  letter-spacing: 0.12em;
}

h1 {
  margin: 0;
  font-family: Georgia, "Times New Roman", serif;
  font-size: clamp(38px, 6vw, 84px);
  line-height: 0.92;
  letter-spacing: 0;
}

.write-lock {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--line);
  background: var(--panel);
  min-height: 36px;
  padding: 0 12px;
  border-radius: 4px;
  color: var(--muted);
  text-transform: uppercase;
  font-size: 12px;
  font-weight: 800;
}

.operator-bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  min-width: 220px;
}

.operator-bar label {
  display: grid;
  gap: 4px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
}

input {
  min-height: 36px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #fff;
  color: var(--ink);
  padding: 0 10px;
  font: inherit;
}

.write-lock span {
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: var(--amber);
}

.write-lock.armed span {
  background: var(--green);
}

.view {
  padding-top: 22px;
}

.grid {
  display: grid;
  gap: 14px;
}

.kpi-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.card,
.table-wrap,
.hero-panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: var(--shadow);
}

.card {
  min-height: 132px;
  padding: 16px;
}

.card h2,
.panel-title {
  margin: 0 0 8px;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.metric {
  margin: 0;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 42px;
  line-height: 1;
}

.metric.small {
  font-size: 34px;
}

.subtle {
  color: var(--muted);
  margin: 8px 0 0;
  font-size: 13px;
}

.pinned-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.live-card {
  display: grid;
  gap: 8px;
}

.hero-panel {
  margin-top: 14px;
  padding: 18px;
  display: grid;
  gap: 16px;
}

.status-line {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.pill {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  border-radius: 999px;
  padding: 0 10px;
  color: #fff;
  background: var(--blue);
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
}

.pill.warn {
  background: var(--amber);
}

.pill.ok {
  background: var(--green);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.table-wrap {
  overflow: auto;
}

.table-wrap.inline {
  box-shadow: none;
  border-radius: 4px;
}

th,
td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  text-align: left;
  white-space: nowrap;
}

td.wide,
th.wide {
  min-width: 260px;
  white-space: normal;
}

th {
  color: var(--muted);
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.08em;
}

.action-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.inline-form {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
}

.button {
  min-height: 38px;
  border: 1px solid var(--ink);
  border-radius: 4px;
  background: var(--ink);
  color: #fff;
  padding: 0 12px;
  cursor: pointer;
}

.button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.button.secondary {
  background: #fff;
  color: var(--ink);
}

.button.danger,
.icon-button.danger {
  border-color: var(--red);
  background: var(--red);
  color: #fff;
}

.icon-button {
  min-height: 32px;
  border: 1px solid var(--ink);
  border-radius: 4px;
  background: #fff;
  color: var(--ink);
  padding: 0 10px;
  cursor: pointer;
  white-space: nowrap;
}

.icon-button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.detail-row {
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
  margin: 8px 0;
}

.detail-row summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 12px;
  align-items: center;
  padding: 12px;
  cursor: pointer;
}

.detail-row summary strong {
  min-width: 0;
  overflow-wrap: anywhere;
}

.updates {
  border-top: 1px solid var(--line);
  padding: 12px;
}

.updates p {
  margin: 0 0 8px;
}

.result-box {
  margin: 0;
  max-height: 260px;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #111;
  color: #f8f5ed;
  padding: 12px;
  white-space: pre-wrap;
}

.toast {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 10;
  max-width: min(420px, calc(100vw - 36px));
  transform: translateY(150%);
  transition: transform 180ms ease;
  border-radius: 4px;
  background: var(--green);
  color: #fff;
  padding: 12px 14px;
  box-shadow: var(--shadow);
  font-weight: 800;
}

.toast.ok,
.toast.error {
  transform: translateY(0);
}

.toast.error {
  background: var(--red);
}

@media (max-width: 900px) {
  .shell {
    grid-template-columns: 1fr;
  }

  /* NOT sticky. Stacked, this rail is the brand plus a two-column nav - about
     360px tall - and a sticky block that tall pins itself over the top 40% of the
     viewport for good. Measured at 887px wide: a queue row's transition buttons
     landed under it and the clicks were swallowed, so a control looked dead while
     being perfectly wired. It scrolls away with the document instead; a static
     element cannot overlay anything. */
  .rail {
    position: static;
    border-right: 0;
    border-bottom: 1px solid #383838;
  }

  nav {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .kpi-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .pinned-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 560px) {
  main,
  .rail {
    padding: 16px;
  }

  .topbar {
    display: grid;
  }

  .operator-bar {
    justify-content: stretch;
  }

  .operator-bar input {
    width: 100%;
  }

  .kpi-grid {
    grid-template-columns: 1fr;
  }

  .detail-row summary {
    grid-template-columns: 1fr;
  }
}


/* Channel panel: the picture that is on air comes first. */
.channel-live {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
  align-items: flex-start;
}

.channel-screen {
  position: relative;
  flex: 0 0 auto;
  width: 420px;
  max-width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 12px;
  overflow: hidden;
  background: #0b0d10;
  display: flex;
  align-items: center;
  justify-content: center;
}

.channel-screen__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.channel-screen__note {
  position: absolute;
  margin: 0;
  padding: 0 16px;
  text-align: center;
  font-size: 13px;
  color: #9aa4b2;
}

.channel-screen.needs-click::after {
  content: 'Click to start the picture';
  position: absolute;
  inset: auto 0 0 0;
  padding: 8px;
  text-align: center;
  font-size: 12px;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
}

.channel-live__side {
  flex: 1 1 260px;
  min-width: 240px;
}

.screen-state {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.screen-state.is-live {
  color: #d92d20;
}

.screen-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #d92d20;
  flex: 0 0 auto;
}

.screen-dot.is-loop {
  background: #12b76a;
}

.tech-details {
  margin-top: 18px;
  padding: 14px 18px;
  border: 1px solid rgba(140, 150, 165, 0.28);
  border-radius: 12px;
}

.tech-details summary {
  cursor: pointer;
  font-size: 13px;
  color: #6b7280;
}

.tech-details[open] summary {
  margin-bottom: 10px;
}

/* Channel write side: the video order, the drop target and the reporter cards. */

.clip-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
  counter-reset: clip;
}

/* The panel has lost touch with the channel. The marker is dimmed rather than
   left looking authoritative, and the health line above says why in words. */
.clip-list.is-stale {
  opacity: 0.62;
}

.channel-screen.is-stale {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
}

.screen-lag {
  margin-top: 6px;
  font-size: 12px;
}

/* ON AIR. A labelled block, not a paragraph: a fixed label column so the eye can
   never join a grey label to the bold value on the line above. The countdown and
   the clip name used to be separate paragraphs, which read as one run-on phrase. */
.onair-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.onair-row {
  display: flex;
  gap: 24px;
  flex-wrap: wrap;
  align-items: flex-start;
}

.onair {
  flex: 1 1 320px;
  min-width: 280px;
}

.onair-row__side {
  flex: 0 1 260px;
  min-width: 200px;
}

.onair__row {
  display: grid;
  grid-template-columns: 62px 1fr;
  gap: 12px;
  align-items: baseline;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}

/* The two controls that act on what is on air. Placed in the value column so they
   line up under the clip name rather than under the label gutter, and allowed to
   wrap so a narrow panel stacks them instead of clipping one off. */
.onair__row.is-actions {
  grid-template-columns: 62px 1fr;
  align-items: center;
}

/* ON AIR is the card title, so the clip going out needs no NOW label under it -
   the title already says what it is. Only NEXT is labelled. */
.onair__row.is-now {
  grid-template-columns: 1fr;
  border-top: 0;
  padding-top: 0;
}

.onair__label {
  color: var(--muted);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.onair__value {
  min-width: 0;
}

.onair__clip {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-clamp: 2;
  overflow: hidden;
  font-size: 19px;
  font-weight: 700;
  line-height: 1.25;
}

.onair__clip.is-next {
  font-size: 17px;
}

.onair__timeline {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 2px;
}

.onair__clock {
  font-size: 52px;
  line-height: 1.05;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.onair__clock.is-ending {
  color: #d92d20;
}

.onair__unit {
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

@media (max-width: 720px) {
  .onair__clock {
    font-size: 40px;
  }
}

.clip {
  position: relative;
  display: grid;
  grid-template-columns: 18px 128px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 8px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
}

.clip[draggable="true"] {
  cursor: grab;
}

.clip.is-dragging {
  opacity: 0.45;
  border-style: dashed;
}

/* Where the row will land. Drawn during the drag; the list itself is not touched
   until the row is released, which is what makes the same gesture repeatable. */
.clip.is-drop-before::before,
.clip.is-drop-after::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  height: 3px;
  border-radius: 999px;
  background: var(--blue);
}

.clip.is-drop-before::before {
  top: -6px;
}

.clip.is-drop-after::after {
  bottom: -6px;
}

.clip.is-playing {
  border-color: var(--green);
  box-shadow: inset 3px 0 0 var(--green);
}

.clip.is-next {
  box-shadow: inset 3px 0 0 var(--line);
}

.clip.is-pending {
  border-style: dashed;
  background: rgba(16, 16, 16, 0.02);
}

.clip.is-failed {
  border-color: var(--red);
}

.clip__grip {
  color: var(--muted);
  font-size: 14px;
  letter-spacing: -2px;
  text-align: center;
  user-select: none;
}

.clip__thumb {
  width: 128px;
  height: 72px;
  object-fit: cover;
  border-radius: 4px;
  background: #dedbd3;
  display: block;
}

.clip__thumb.is-empty {
  background:
    repeating-linear-gradient(45deg, #e5e2da 0 6px, #dbd8cf 6px 12px);
}

.clip__body {
  min-width: 0;
}

.clip__name {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  /* A de-slugified filename can be very long. Two lines with an ellipsis reads;
     one clipped line hides which clip a row is, and the full name is on hover.
     This is a stopgap - editorial names for queue entries are a separate job. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-clamp: 2;
  overflow: hidden;
  text-overflow: ellipsis;
}

.clip__meta {
  margin: 2px 0 0;
  color: var(--muted);
  font-size: 12px;
}

.clip.is-playing .clip__meta {
  color: var(--green);
  font-weight: 700;
}

.clip__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
}

.dropzone {
  display: grid;
  justify-items: start;
  gap: 6px;
  padding: 18px;
  border: 2px dashed var(--line);
  border-radius: 6px;
  background: rgba(16, 16, 16, 0.015);
}

.dropzone.is-over {
  border-color: var(--blue);
  background: rgba(25, 79, 144, 0.06);
}

.dropzone__title {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
}

/* One live card, then a quiet roster. The old grid of identical cards gave a
   one-at-a-time fact six equal-weight boxes. */
.reporter {
  display: grid;
  gap: 10px;
  padding: 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
}

.reporter.is-live {
  border-color: var(--amber);
  box-shadow: inset 3px 0 0 var(--amber);
}

.reporter__since {
  margin: 0;
  font-size: 13px;
  color: var(--muted);
}

.reporter-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
}

.reporter-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 12px;
  background: var(--panel);
}

.reporter-row__name {
  font-size: 14px;
}

.reporter-row__state {
  font-size: 12px;
  color: var(--muted);
}

.reporter-empty {
  margin: 0;
  padding: 14px;
  border: 1px dashed var(--line);
  border-radius: 6px;
  color: var(--muted);
  font-size: 14px;
}

/* A reporter who cannot connect right now needs to see why before they try. */
.hero-panel.is-blocked {
  border-color: var(--amber);
  box-shadow: inset 3px 0 0 var(--amber);
}

.warn-note {
  margin: 0;
  padding: 8px 10px;
  border-radius: 4px;
  background: rgba(196, 120, 20, 0.1);
  color: var(--ink);
  font-size: 13px;
  line-height: 1.45;
}

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

.who__name {
  font-size: 13px;
  font-weight: 700;
}

.login-panel {
  max-width: 420px;
}

.login-form {
  display: grid;
  gap: 12px;
  margin: 4px 0 12px;
}

.login-form label {
  display: grid;
  gap: 4px;
}

.login-form label span {
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

.login-form input {
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--panel);
  color: var(--ink);
  font: inherit;
}

.reporter__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.reporter__name {
  margin: 0;
  font-size: 16px;
}

.reporter__conn {
  margin: 0;
  display: grid;
  grid-template-columns: 68px 1fr;
  align-items: center;
  gap: 6px 10px;
  font-size: 12px;
}

.reporter__conn dt {
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 800;
}

.reporter__conn dd {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.reporter__conn code {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 4px 6px;
  background: rgba(16, 16, 16, 0.05);
  border-radius: 4px;
  font-size: 12px;
}

@media (max-width: 720px) {
  .clip {
    grid-template-columns: 18px 96px 1fr;
    grid-template-areas:
      "grip thumb body"
      "actions actions actions";
  }

  .clip__grip { grid-area: grip; }
  .clip__thumb { grid-area: thumb; width: 96px; height: 54px; }
  .clip__body { grid-area: body; }
  .clip__actions { grid-area: actions; }
}
