/* ASOT live overlay — operator control panel
   Dark, high-contrast, built to be readable in a dim gallery. */

:root {
  --bg:        #0b0c10;
  --panel:     #14161d;
  --panel-2:   #1b1e27;
  --line:      #272b36;
  --ink:       #e9ecf2;
  --ink-dim:   #8b93a4;
  --accent:    #29e0ff;   /* ASOT cyan */
  --live:      #ff2d55;
  --take:      #1ec86a;
  --radius:    10px;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 14px/1.45 -apple-system, BlinkMacSystemFont, "Helvetica Neue", Inter, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* ── top bar ─────────────────────────────────────────── */
.bar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 12px 20px;
  background: rgba(11,12,16,.92);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: center; gap: 14px; font-weight: 600; letter-spacing: .02em; }
.brand img { height: 26px; width: auto; display: block; }
.brand span { color: var(--ink-dim); font-size: 13px; }
.bar-right { display: flex; align-items: center; gap: 12px; }
.account-identity { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; color: var(--ink-dim); font-size: 12px; min-width: 0; }
#settings-identity { overflow-wrap: anywhere; }
.account-role { padding: 4px 7px; border: 1px solid var(--line); border-radius: 5px; font: 10px/1.2 var(--mono); text-transform: uppercase; letter-spacing: .06em; }

.conn {
  font: 600 11px/1.4 var(--mono); letter-spacing: .08em; text-transform: uppercase;
  padding: 6px 10px; border-radius: 999px; border: 1px solid var(--line); color: var(--ink-dim);
}
.conn[data-state="open"]   { color: var(--take); border-color: color-mix(in srgb, var(--take) 45%, transparent); }
.conn[data-state="closed"] { color: var(--live); border-color: color-mix(in srgb, var(--live) 45%, transparent); }

/* ── layout ──────────────────────────────────────────── */
/* The panels flow into as many columns as fit; the preview spans the full
   row beneath them. On a wide display that wastes the width and pushes the
   preview off the bottom of the screen, so it moves alongside further down. */
/* Two stacked regions by default — the widgets, then the preview beneath.
   On a wide display they sit side by side (see the media query below). */
main {
  display: grid;
  gap: 16px;
  padding: 16px 20px 28px;
  grid-template-columns: 1fr;
  align-items: start;
  max-width: 1600px;
  margin: 0 auto;
}

/* The control widgets flow into as many columns as fit. */
.widgets {
  margin: 0; padding: 0; border: 0; min-width: 0;
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
  align-items: start;
}
.panel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px;
}
.panel.wide { grid-column: 1 / -1; }

/* Wide displays: three control columns and the preview beside them, all on
   one row, so the operator sees the controls and what is on air together
   without scrolling. The preview column takes the surplus width — a bigger
   preview is the most useful thing to spend it on — but is capped by the
   grid's own max-width so it cannot grow taller than the panels beside it. */
/* Wide displays: two columns of widgets on the left, the live preview taking
   the whole right half.

   The widgets fill column-first rather than row-first, so the three of them
   land as bugs + rundown in one column and the lower third in the other. Row-
   first would stack the two tall panels together and leave the rundown alone
   beside them with a column of empty space under it. */
@media (min-width: 1440px) {
  main {
    max-width: 2280px;
    grid-template-columns: 1fr 1fr;
  }
  .widgets {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto;
    grid-auto-flow: column;
  }
  .panel.wide { grid-column: auto; }
}
.panel-head {
  display: flex; align-items: center; justify-content: space-between;
  margin: 0 0 14px;
}
.panel-head h2 { margin: 0; font-size: 13px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-dim); }
.count { font: 11px/1 var(--mono); color: var(--ink-dim); }

/* tally */
.tally {
  font: 700 11px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  padding: 5px 9px; border-radius: 5px;
  background: var(--panel-2); color: var(--ink-dim); border: 1px solid var(--line);
}
.tally.on { background: var(--live); color: #fff; border-color: var(--live); box-shadow: 0 0 0 3px color-mix(in srgb, var(--live) 22%, transparent); }

/* ── fields ──────────────────────────────────────────── */
.fields { display: grid; gap: 11px; }
label { display: grid; gap: 5px; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-dim); }
label em { text-transform: none; letter-spacing: 0; font-style: normal; opacity: .65; }
input[type="text"], input[type="number"], .rundown-add input {
  font: 15px/1.2 "Helvetica Neue", Helvetica, Arial, sans-serif;
  color: var(--ink); background: var(--panel-2);
  border: 1px solid var(--line); border-radius: 7px; padding: 10px 11px;
  width: 100%; transition: border-color .12s, box-shadow .12s;
}
input:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
/* a live lower third's text is locked — the change would otherwise happen
   on air with no transition. Say why, rather than leaving dead inputs. */
input:disabled {
  color: var(--ink-dim);
  background: color-mix(in srgb, var(--panel-2) 60%, transparent);
  cursor: not-allowed;
}
.fields[data-locked="true"] { position: relative; }
.fields[data-locked="true"]::after {
  content: "on air — take out to edit";
  position: absolute; top: -1px; right: 0;
  font: 600 10px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase;
  color: var(--live);
}

.row { margin-top: 12px; }
label.inline { display: flex; align-items: center; gap: 8px; }
label.inline input { width: 74px; }

/* ── buttons ─────────────────────────────────────────── */
.actions { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
.actions.secondary { margin-top: 10px; }
button, .filebtn {
  position: relative; cursor: pointer; user-select: none;
  font: 600 13px/1 -apple-system, system-ui, sans-serif; letter-spacing: .02em;
  /* .filebtn is a <label> wrapping a hidden file input, so it would otherwise
     inherit the uppercase field-label styling and shout next to its siblings */
  text-transform: none;
  padding: 11px 14px; border-radius: 8px; border: 1px solid var(--line);
  background: var(--panel-2); color: var(--ink);
  display: inline-flex; align-items: center; gap: 8px;
  transition: transform .06s, filter .12s, background .12s;
}
button:hover, .filebtn:hover { filter: brightness(1.18); }
button:active { transform: translateY(1px); }
button.take { background: var(--take); border-color: var(--take); color: #04160c; }
button.out  { background: var(--live); border-color: var(--live); color: #fff; }

/* one button per graphic — it is coloured and labelled for the action it
   will perform, so green always means "this puts something up".
   Its colour changes instantly: the label flips the moment state arrives, and
   a colour that eases in behind it leaves a window where the button reads
   "IN" while still red. Hover keeps its transition. */
/* Two registers, applied here rather than baked into the strings:
   CAPS for anything that puts a graphic to air or reports that it is there
   (these toggles, the tally chips, the rundown's Take), sentence case for
   every other control. Keeps the copy readable in the markup. */
button.toggle {
  flex: 1;
  justify-content: center;
  text-transform: uppercase;
  letter-spacing: .06em;
  transition: transform .06s, filter .12s;
}
.rundown button.take { text-transform: uppercase; letter-spacing: .06em; }
/* :not(:disabled) so an unavailable graphic never wears the "ready" colour */
button.toggle[data-live="false"]:not(:disabled) { background: var(--take); border-color: var(--take); color: #04160c; }
button.toggle[data-live="true"]:not(:disabled)  { background: var(--live); border-color: var(--live); color: #fff; }
button:disabled,
button.toggle:disabled {
  background: var(--panel-2); border-color: var(--line); color: var(--ink-dim);
  cursor: not-allowed; filter: none; opacity: .55;
}
button:disabled:hover { filter: none; }
button.ghost { background: transparent; }
button.danger { color: var(--live); border-color: color-mix(in srgb, var(--live) 40%, transparent); }
kbd {
  font: 600 10px/1 var(--mono); opacity: .6;
  border: 1px solid currentColor; border-radius: 4px; padding: 2px 4px;
}
a.ghost { color: var(--ink-dim); text-decoration: none; font-size: 12px; }
a.ghost:hover { color: var(--accent); }

.hint { margin: 10px 0 0; font-size: 12px; color: var(--ink-dim); }
.hint code, footer code { font: 11px/1 var(--mono); background: var(--panel-2); padding: 2px 5px; border-radius: 4px; }

/* ── rundown ─────────────────────────────────────────── */
.rundown-add { display: grid; grid-template-columns: 1fr 1fr 1fr auto; gap: 6px; }
.rundown {
  list-style: none; margin: 12px 0 0; padding: 0;
  max-height: 260px; overflow-y: auto;
  border: 1px solid var(--line); border-radius: 8px;
}
.rundown:empty { display: none; }
.rundown li {
  display: grid; grid-template-columns: 26px 1fr auto; gap: 10px; align-items: center;
  padding: 9px 11px; border-bottom: 1px solid var(--line);
}
.rundown li:last-child { border-bottom: 0; }
.rundown li.cued { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.rundown .idx { font: 11px/1 var(--mono); color: var(--ink-dim); }
.rundown .meta { min-width: 0; }
.rundown .a { font-weight: 600; }
.rundown .t { color: var(--ink-dim); font-size: 12px; }
.rundown .a, .rundown .t { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rundown .ops { display: flex; gap: 5px; }
.rundown button { padding: 6px 9px; font-size: 11px; }

/* ── bugs ────────────────────────────────────────────── */
.bug { padding: 12px 0; border-top: 1px solid var(--line); }
.bug:first-of-type { border-top: 0; padding-top: 0; }
.bug-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 9px; }
.bug h3 { margin: 0; font-size: 13px; font-weight: 600; }
.bug .actions button { flex: 1; justify-content: center; }

/* ── preview ─────────────────────────────────────────── */
.preview-wrap {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  border-radius: 8px; overflow: hidden; border: 1px solid var(--line);
  /* checkerboard reads as "this is transparent on air" */
  background-color: #101218;
  background-image:
    linear-gradient(45deg, #171a22 25%, transparent 25%, transparent 75%, #171a22 75%),
    linear-gradient(45deg, #171a22 25%, transparent 25%, transparent 75%, #171a22 75%);
  background-size: 28px 28px;
  background-position: 0 0, 14px 14px;
}
#preview { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* ── footer ──────────────────────────────────────────── */
.foot {
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  padding: 14px 20px 26px; color: var(--ink-dim); font-size: 12px;
  border-top: 1px solid var(--line); max-width: 1600px; margin: 0 auto;
}
.keys { font: 11px/1.6 var(--mono); }

/* ── hashtag auto-cycle ──────────────────────────────────────── */
.auto {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed var(--line);
  display: grid;
  gap: 10px;
}
.switch { display: flex; align-items: center; gap: 9px; cursor: pointer; }
.switch input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.switch span { text-transform: none; letter-spacing: 0; font-size: 13px; color: var(--ink); }

.auto-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.auto-fields label { gap: 4px; }
.auto-fields .unit { position: relative; display: block; }
.auto-fields input { width: 100%; padding-right: 38px; }
.auto-fields em {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  font-style: normal; font-size: 11px; color: var(--ink-dim); pointer-events: none;
}
/* dim the schedule until it is switched on */
.auto[data-on="false"] .auto-fields { opacity: .45; }

/* the countdown sits on the toggle's own row — it reports on that switch, and
   giving it a row of its own pushed everything below it down */
.auto-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
#auto-next { font: 11px/1 var(--mono); color: var(--ink-dim); white-space: nowrap; }
#auto-next.armed { color: var(--accent); }

[hidden] { display: none !important; }
.error-message { grid-column: 1 / -1; margin: 0; color: #ff9bac; padding: 12px 16px; border: 1px solid var(--live); border-radius: 8px; }
.panel-review { grid-column: 1 / -1; }
#assist-form { display: flex; align-items: end; gap: 14px; flex-wrap: wrap; }
#assist-form > label:first-child { flex: 1; min-width: 260px; }
#assist-form .switch { padding-bottom: 10px; }
.review-fields { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; margin-top: 18px; }
.release-match { display: flex; gap: 12px; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--line); }
.release-match span { flex: 1; }
a { color: var(--accent); }
.review-history { margin-top: 18px; color: var(--ink-dim); font-size: 12px; }
summary { cursor: pointer; }
#approval-history { max-height: 200px; overflow: auto; line-height: 1.8; }
.settings-main { max-width: 960px; display: block; }
.settings-main .panel { margin-bottom: 18px; }
.settings-main form { display: grid; gap: 14px; }
.settings-main #ndi-form { grid-template-columns: 100px minmax(140px,1fr) 110px 110px auto; align-items: end; }
.settings-main #pair-form { grid-template-columns: 1fr 1fr auto; align-items: end; }
.settings-main #output-form { grid-template-columns: 1fr auto; align-items: end; }
.settings-main #user-form { grid-template-columns: 1fr 150px auto; align-items: end; }
.settings-main .panel-head > a, .review-availability { font-size: 12px; }
.review-availability { display: flex; gap: 12px; align-items: center; }
#settings-status:empty, #assist-note:empty, #review-source:empty, #login-status:empty { display: none; }
.settings-details > summary { display: flex; align-items: center; justify-content: space-between; gap: 12px; color: var(--ink-dim); }
.settings-details > summary > span:first-child { font-size: 13px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; }
.settings-details > summary > span:first-child::before { content: '›'; display: inline-block; margin-right: 10px; transition: transform .15s; }
.settings-details[open] > summary > span:first-child::before { transform: rotate(90deg); }
.settings-details > summary::-webkit-details-marker { display: none; }
.settings-fold { border-top: 1px solid var(--line); margin-top: 14px; padding-top: 14px; color: var(--ink-dim); font-size: 12px; }
.usage-table { width: 100%; border-collapse: collapse; margin: 14px 0; font-size: 12px; }
.usage-table th, .usage-table td { padding: 9px 0; border-bottom: 1px solid var(--line); text-align: right; }
.usage-table th { font-weight: 400; color: var(--ink-dim); }
.usage-table th:first-child { text-align: left; }
.usage-table td { font-family: var(--mono); }
input[type="email"], input[type="password"], input[type="url"], select, textarea {
  font: inherit; color: var(--ink); background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px; padding: 10px 11px; width: 100%;
}
.secret-result { overflow-wrap: anywhere; white-space: pre-wrap; padding: 12px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; }
.admin-list { list-style: none; padding: 0; }
.admin-list li { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.admin-list:empty { display: none; }
.admin-list li > span:first-child { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.admin-list li > button { flex-shrink: 0; }
.admin-meta { display: block; color: var(--ink-dim); font-size: 12px; margin-top: 3px; }
.login-wrap { display: block; max-width: 460px; margin: 12vh auto; padding: 24px; }
.login-wrap img { display: block; width: 110px; margin-bottom: 28px; }
.login-wrap h1 { font-size: 27px; margin: 0; }
.login-wrap form { display: grid; gap: 16px; margin-top: 24px; }
.login-wrap p { color: var(--ink-dim); }
.login-wrap button { width: 100%; justify-content: center; }
@media (max-width: 700px) {
  .bar { flex-wrap: wrap; }
  .bar-right { flex-wrap: wrap; }
  .widgets { grid-template-columns: minmax(0, 1fr); }
  .review-fields { grid-template-columns: 1fr; }
  .release-match { flex-wrap: wrap; }
  .settings-main #pair-form, .settings-main #user-form, .settings-main #output-form, .settings-main #ndi-form { grid-template-columns: 1fr; }
  .admin-list li { flex-wrap: wrap; }
  .panel-review .panel-head { flex-wrap: wrap; gap: 10px; }
  #assist-form > label:first-child { min-width: 0; flex-basis: 100%; }
  .rundown-add { grid-template-columns: 1fr 1fr; }
  .rundown li { grid-template-columns: 20px minmax(0, 1fr); }
  .rundown .ops { grid-column: 2; }
}

#local-control .actions { margin: 0 0 14px; align-items: center; }
#local-control-status { margin: 0 auto 0 0; }

#decklink-form { display:grid; grid-template-columns:100px minmax(180px,1fr) 140px 140px auto; align-items:end; gap:14px; }
#decklink-refresh { grid-column:2; justify-self:start; }
@media (max-width:800px) { #decklink-form { grid-template-columns:1fr; } #decklink-refresh { grid-column:auto; } }
