/*
  Music control console.

  Two signal colours, because the product has exactly two audio channels: red belongs to live
  and nothing else, teal belongs to cue and nothing else. Live is raised and lit; cue is
  recessed and cool, so at a glance the operator can never confuse the two.
*/

:root {
  --night: #111a22;
  --deck: #18242e;
  --deck-2: #1f2e39;
  --deck-3: #273844;
  --edge: #2d4150;
  --chalk: #ece8dd;
  --chalk-dim: #8da0ae;
  --chalk-faint: #5f7383;
  --live: #f0503c;
  --live-deep: #7c2419;
  --cue: #4fbfc0;
  --cue-deep: #1b4a4b;
  --grass: #7bb661;
  --warn: #e8b33d;

  --display: 'Archivo Narrow', 'Arial Narrow', system-ui, sans-serif;
  --text: 'IBM Plex Sans', system-ui, -apple-system, sans-serif;

  --radius: 3px;
  --rail-height: 52px;
}

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

/*
  The views, the gate and several panels are shown and hidden through the `hidden` attribute,
  but every one of them also carries a class that sets `display`, which would otherwise win
  over the user-agent rule for `[hidden]`. This keeps `hidden` authoritative.
*/
[hidden] {
  display: none !important;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  background: var(--night);
  color: var(--chalk);
  font-family: var(--text);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  font-family: var(--display);
  font-weight: 600;
  margin: 0;
  letter-spacing: 0.005em;
}

button,
input,
select {
  font: inherit;
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--cue);
  outline-offset: 2px;
}

/* ---------- Top rail ---------------------------------------------------- */

.rail {
  position: sticky;
  top: 0;
  z-index: 20;
  height: var(--rail-height);
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 0 20px;
  background: var(--deck);
  border-bottom: 1px solid var(--edge);
}

.rail__brand {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
}

.rail__name {
  font-family: var(--display);
  font-size: 19px;
  font-weight: 600;
}

/* The tally light: the one piece of ambient motion, and only while live audio runs. */
.tally {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--chalk-faint);
  box-shadow: none;
}

.tally[data-state='playing'] {
  background: var(--live);
  box-shadow: 0 0 0 4px rgba(240, 80, 60, 0.18);
  animation: tally 1.8s ease-in-out infinite;
}

.tally[data-state='paused'] {
  background: var(--warn);
}

@keyframes tally {
  50% {
    box-shadow: 0 0 0 9px rgba(240, 80, 60, 0.05);
  }
}

@media (prefers-reduced-motion: reduce) {
  .tally[data-state='playing'] {
    animation: none;
  }
}

.rail__nav {
  display: flex;
  gap: 2px;
  flex: 1 1 auto;
}

.rail__nav a {
  padding: 6px 12px;
  border-radius: var(--radius);
  color: var(--chalk-dim);
  text-decoration: none;
  font-size: 14px;
}

.rail__nav a:hover {
  color: var(--chalk);
  background: var(--deck-2);
}

.rail__nav a[aria-current='page'] {
  color: var(--chalk);
  background: var(--deck-3);
}

.rail__status {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  flex: 0 1 auto;
}

.rail__revision {
  font-size: 12px;
  color: var(--chalk-faint);
  font-variant-numeric: tabular-nums;
}

.badge {
  font-size: 12px;
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid var(--edge);
  color: var(--chalk-dim);
  white-space: nowrap;
}

.badge--operator {
  border-color: var(--live);
  color: var(--live);
}

.badge--online {
  border-color: var(--grass);
  color: var(--grass);
}

.badge--trouble {
  border-color: var(--warn);
  color: var(--warn);
}

.badge--quiet {
  color: var(--chalk-faint);
}

/* ---------- Buttons ----------------------------------------------------- */

.button {
  padding: 9px 16px;
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  background: var(--deck-2);
  color: var(--chalk);
  cursor: pointer;
  white-space: nowrap;
}

.button:hover:not(:disabled) {
  background: var(--deck-3);
}

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

.button--small {
  padding: 5px 10px;
  font-size: 13px;
}

.button--quiet {
  background: transparent;
  color: var(--chalk-dim);
}

.button--primary {
  background: var(--chalk);
  border-color: var(--chalk);
  color: var(--night);
  font-weight: 500;
}

.button--primary:hover:not(:disabled) {
  background: #fff;
}

.button--live {
  background: var(--live);
  border-color: var(--live);
  color: #fff;
  font-weight: 500;
}

.button--live:hover:not(:disabled) {
  background: #f4624f;
}

.button--cue {
  background: transparent;
  border-color: var(--cue);
  color: var(--cue);
}

.button--cue:hover:not(:disabled) {
  background: var(--cue-deep);
}

/* ---------- Layout ------------------------------------------------------ */

.view {
  padding: 18px;
  gap: 18px;
}

/*
  Two columns: the game on the left, the two audio channels and the queue on the right.
  The batting order spans the remaining height so its list is the only thing that scrolls.
*/
.console {
  display: grid;
  grid-template-columns: minmax(360px, 1fr) minmax(400px, 1fr);
  grid-template-rows: auto auto auto minmax(0, 1fr);
  grid-template-areas:
    'batter     live'
    'order      cue'
    'order      queued'
    'situations situations';
  align-items: start;
  min-height: calc(100vh - var(--rail-height));
}

.batter {
  grid-area: batter;
}

.order {
  grid-area: order;
  align-self: stretch;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.channel--live {
  grid-area: live;
}

.channel--cue {
  grid-area: cue;
}

.queued {
  grid-area: queued;
}

.situations {
  grid-area: situations;
}

/* Situation buttons are hit under time pressure, so they are large and evenly sized. */
.situations__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 10px;
}

.situation {
  display: flex;
  flex-direction: column;
  gap: 3px;
  align-items: flex-start;
  padding: 12px 14px;
  min-height: 62px;
  border: 1px solid var(--edge);
  border-left: 3px solid var(--live);
  border-radius: var(--radius);
  background: var(--deck-2);
  color: var(--chalk);
  cursor: pointer;
  text-align: left;
}

.situation:hover:not(:disabled) {
  background: var(--deck-3);
}

.situation:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  border-left-color: var(--edge);
}

.situation__name {
  font-family: var(--display);
  font-size: 18px;
  font-weight: 600;
}

.situation__track {
  font-size: 12.5px;
  color: var(--chalk-faint);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.situation__track--missing {
  color: var(--warn);
}

.editor,
.library,
.log {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  align-items: start;
}

/* ---------- Panels ------------------------------------------------------ */

.panel,
.batter,
.order,
.channel,
.queued,
.situations {
  background: var(--deck);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  padding: 16px 18px;
}

.panel__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.panel__head--spaced {
  margin-top: 26px;
}

.panel__title {
  font-size: 17px;
  color: var(--chalk);
}

.panel__meta {
  font-size: 13px;
  color: var(--chalk-faint);
  font-variant-numeric: tabular-nums;
}

.panel__lede,
.panel__empty {
  font-size: 14px;
  color: var(--chalk-dim);
  margin: 0 0 12px;
  max-width: 62ch;
}

.panel__empty {
  color: var(--chalk-faint);
}

.panel__foot {
  margin-top: 14px;
}

/* ---------- Now batting: the one loud element --------------------------- */

.batter__body {
  display: flex;
  align-items: center;
  gap: 20px;
  min-height: 108px;
}

.batter__slot {
  font-family: var(--display);
  font-size: 76px;
  font-weight: 700;
  line-height: 0.82;
  color: var(--live);
  font-variant-numeric: tabular-nums;
  padding-right: 20px;
  border-right: 1px solid var(--edge);
}

.batter__who {
  min-width: 0;
}

.batter__name {
  font-family: var(--display);
  font-size: 42px;
  font-weight: 600;
  line-height: 1.04;
  overflow-wrap: break-word;
}

.batter__number {
  color: var(--chalk-dim);
  font-size: 15px;
  margin-top: 2px;
}

.batter__walkup {
  margin-top: 6px;
  font-size: 14px;
  color: var(--chalk-dim);
}

.batter__walkup b {
  color: var(--chalk);
  font-weight: 500;
}

.batter__empty {
  color: var(--chalk-faint);
  margin: 0;
  max-width: 44ch;
}

.batter__actions {
  display: flex;
  gap: 10px;
  margin-top: 16px;
  flex-wrap: wrap;
}

/* ---------- Batting order list ------------------------------------------ */

.order__list {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  min-height: 0;
  flex: 1 1 auto;
}

.order__row {
  display: grid;
  grid-template-columns: 30px 1fr auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 9px 10px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: none;
  text-align: left;
  cursor: pointer;
}

.order__row:hover:not(:disabled) {
  background: var(--deck-2);
}

.order__row:disabled {
  cursor: default;
}

.order__row[aria-current='true'] {
  background: var(--deck-2);
  border-color: var(--live);
}

.order__slot {
  font-family: var(--display);
  font-size: 19px;
  font-weight: 600;
  color: var(--chalk-faint);
  font-variant-numeric: tabular-nums;
}

.order__row[aria-current='true'] .order__slot {
  color: var(--live);
}

.order__who {
  min-width: 0;
}

.order__name {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.order__walkup {
  display: block;
  font-size: 12.5px;
  color: var(--chalk-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.order__walkup--missing {
  color: var(--warn);
}

.order__walkup--none {
  color: var(--chalk-faint);
  font-style: italic;
}

/* ---------- Channels ---------------------------------------------------- */

.channel--live {
  border-left: 3px solid var(--live);
  background: linear-gradient(180deg, rgba(240, 80, 60, 0.07), transparent 180px), var(--deck);
}

/* Cue sits lower and cooler than live: recessed, never lit. */
.channel--cue {
  border-left: 3px solid var(--cue-deep);
  background: var(--deck);
  box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.35);
}

.channel__note {
  margin: -4px 0 12px;
  font-size: 13px;
  color: var(--chalk-faint);
}

.channel__track {
  min-height: 62px;
  margin-bottom: 14px;
}

.channel__title {
  font-family: var(--display);
  font-size: 25px;
  font-weight: 600;
  line-height: 1.15;
}

.channel--cue .channel__title {
  font-size: 20px;
}

.channel__sub {
  font-size: 13.5px;
  color: var(--chalk-dim);
  font-variant-numeric: tabular-nums;
}

.channel__empty {
  color: var(--chalk-faint);
  margin: 0;
}

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

.channel__fault {
  margin: 12px 0 0;
  padding: 9px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--live);
  background: rgba(240, 80, 60, 0.1);
  font-size: 13.5px;
}

.state {
  font-size: 13px;
  color: var(--chalk-dim);
  font-variant-numeric: tabular-nums;
}

.state[data-state='playing'] {
  color: var(--grass);
}

.state[data-state='paused'] {
  color: var(--warn);
}

.volume {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  font-size: 13px;
  color: var(--chalk-dim);
}

.volume input {
  width: 110px;
  accent-color: var(--chalk-dim);
}

/* ---------- Forms and lists -------------------------------------------- */

.stack {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.row {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 12px;
}

.row--wrap {
  flex-wrap: wrap;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin-bottom: 12px;
  font-size: 13.5px;
  color: var(--chalk-dim);
}

input[type='text'],
input[type='password'],
input[type='search'],
select {
  padding: 9px 11px;
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  background: var(--deck-2);
  color: var(--chalk);
  min-width: 0;
  flex: 1 1 auto;
}

.input--narrow {
  flex: 0 0 76px;
}

/* Start times are short and read as numbers, so they get a fixed, tabular field. */
.input--time {
  flex: 0 0 84px;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.field--inline {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  margin-bottom: 0;
}

.field--inline > span {
  white-space: nowrap;
}

.track__start {
  font-variant-numeric: tabular-nums;
  color: var(--cue);
  font-size: 12.5px;
  white-space: nowrap;
}

.switch {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  color: var(--chalk-dim);
}

.switch input {
  accent-color: var(--cue);
}

.roster,
.tracks,
.log__list,
.lineup-editor {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 46vh;
  overflow-y: auto;
}

.roster li,
.tracks li,
.lineup-editor li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--deck-2);
}

.roster li:last-child,
.tracks li:last-child,
.lineup-editor li:last-child {
  border-bottom: none;
}

.roster__name,
.track__name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.track__sub,
.roster__sub {
  display: block;
  font-size: 12.5px;
  color: var(--chalk-faint);
}

.track--missing .track__sub {
  color: var(--warn);
}

.lineup-editor__slot {
  font-family: var(--display);
  font-size: 18px;
  font-weight: 600;
  color: var(--chalk-faint);
  width: 26px;
  font-variant-numeric: tabular-nums;
}

.log__list li {
  display: grid;
  grid-template-columns: 150px 190px 1fr;
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid var(--deck-2);
  font-size: 13px;
}

.log__when {
  color: var(--chalk-faint);
  font-variant-numeric: tabular-nums;
}

.log__kind {
  color: var(--chalk);
}

.log__detail {
  color: var(--chalk-dim);
  overflow-wrap: anywhere;
}

.diagnostics {
  margin: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 6px 16px;
  font-size: 13.5px;
}

.diagnostics dt {
  color: var(--chalk-faint);
}

.diagnostics dd {
  margin: 0;
  overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums;
}

/* ---------- Scan progress ---------------------------------------------- */

.scan {
  margin-top: 14px;
}

.scan__bar {
  height: 4px;
  background: var(--deck-2);
  border-radius: 999px;
  overflow: hidden;
  margin-bottom: 7px;
}

.scan__fill {
  height: 100%;
  width: 0;
  background: var(--cue);
  transition: width 160ms linear;
}

/* ---------- Gate and notice -------------------------------------------- */

.gate {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(10, 16, 21, 0.94);
}

.gate__card {
  width: min(420px, 100%);
  background: var(--deck);
  border: 1px solid var(--edge);
  border-top: 3px solid var(--live);
  border-radius: var(--radius);
  padding: 26px;
}

.gate__title {
  font-size: 28px;
  margin-bottom: 14px;
}

.gate__lede {
  color: var(--chalk-dim);
  font-size: 14px;
  margin: 0;
}

.gate__error {
  margin: 14px 0 0;
  color: var(--live);
  font-size: 13.5px;
}

.notice {
  position: fixed;
  z-index: 40;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: min(620px, calc(100vw - 32px));
  padding: 11px 14px;
  border-radius: var(--radius);
  background: var(--deck-3);
  border: 1px solid var(--edge);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  font-size: 14px;
}

.notice[data-kind='error'] {
  border-color: var(--live);
}

.notice__close {
  border: none;
  background: none;
  color: var(--chalk-dim);
  font-size: 19px;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
}

/* ---------- Narrow screens --------------------------------------------- */

@media (max-width: 920px) {
  .console {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    grid-template-areas:
      'batter'
      'live'
      'cue'
      'queued'
      'situations'
      'order';
    min-height: calc(100vh - var(--rail-height));
  }

  .order__list {
    max-height: 50vh;
  }

  .batter__slot {
    font-size: 58px;
  }

  .batter__name {
    font-size: 32px;
  }

  /* The rail becomes three stacked rows rather than one that overflows sideways. */
  .rail {
    height: auto;
    flex-wrap: wrap;
    gap: 10px;
    padding: 10px 16px;
  }

  .rail__nav,
  .rail__status {
    flex: 1 1 100%;
  }

  .rail__nav {
    overflow-x: auto;
    scrollbar-width: none;
  }

  .rail__nav::-webkit-scrollbar {
    display: none;
  }

  .log__list li {
    grid-template-columns: 1fr;
    gap: 2px;
  }
}
