/* ==========================================================================
   Phantom Radio — control panel.

   The Phantom family look. Tokens, radii, control heights and the on-air pulse
   are deliberately the same values as phantomstream.io (OpenStudio/web/styles.css)
   so Radio reads as a sibling product rather than a separate purchase.

   ⚠ Keep these in step with Phantom Stream. If a token changes there, change it
     here. The one intentional divergence is --acc-ink (see below).

   Committed to dark. Broadcast automation is operated in dim rooms and at 3am,
   and the family has no light theme to match anyway.
   ========================================================================== */

:root {
  /* ---- surfaces, darkest to lightest */
  --bg:    #0B0C0E;
  --card:  #15171C;
  --c2:    #1B1E25;
  --c3:    #23272F;
  --ln:    rgba(255,255,255,.07);
  --ln2:   rgba(255,255,255,.13);

  /* ---- text */
  --tx:    #F4F5F7;
  --dim:   #A1A7B2;
  --mute:  #697079;

  /* ---- accent. Near-white, so anything filled with it needs dark ink. */
  --acc:     #dff1f6;
  --acc-rgb: 223,241,246;
  /* Phantom Stream's --limd (#141a04) is an olive left over from its old lime
     accent; under a near-white fill it reads muddy. Radio uses the ground
     colour as ink instead. Worth pushing back into Phantom Stream. */
  --acc-ink: #0B0C0E;

  /* ---- semantic. Separate from the accent on purpose: these encode state,
     they are not decoration, and they must never be used for emphasis. */
  --live:   #FF4D5E;   /* ON AIR, and critical only */
  --good:   #63D3C4;
  --warn:   #E5B769;
  --teal:   #63D3C4;   /* commercials / measured values */
  --violet: #A78BFA;   /* teaching + spoken word */
  --gold:   #E5B769;   /* station IDs + sweepers */

  /* ---- radii. The family clusters at 9-16; nothing else is allowed. */
  --r-sm: 7px;
  --r:    9px;
  --r-md: 10px;
  --r-lg: 12px;
  --r-xl: 16px;

  --shadow: 0 18px 46px rgba(0,0,0,.5);
  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--tx);
  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: 'Space Grotesk', 'Inter', system-ui, sans-serif;
  margin: 0;
  font-weight: 600;
  letter-spacing: -.015em;
  text-wrap: balance;
}

a { color: inherit; }

/* Numbers that sit in columns must line up. Applied wherever digits are read
   rather than skimmed: timecodes, LUFS, listener counts, impressions. */
.num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

.eyebrow {
  font-size: 10.5px;
  letter-spacing: .3px;
  color: var(--mute);
}

.dimmed { color: var(--dim); }
.muted  { color: var(--mute); }

:where(button, a, input, select, textarea):focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

@keyframes pulse { 0%,100% { opacity: 1 } 50% { opacity: .3 } }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ==========================================================================
   APP SHELL
   ========================================================================== */

.app {
  display: grid;
  grid-template-columns: 210px minmax(0, 1fr);
  min-height: 100dvh;
}

/* ---- left rail ---------------------------------------------------------- */

.rail {
  background: var(--card);
  border-right: 1px solid var(--ln);
  padding: 16px 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.brand {
  display: flex; align-items: center; gap: 9px;
  padding: 0 4px 4px;
  margin-bottom: 14px;
  text-decoration: none;
}
.brand-mark {
  width: 28px; height: 28px; border-radius: var(--r);
  background: var(--acc); flex: none;
  display: grid; place-items: center;
}
.brand-mark svg { width: 15px; height: 15px; display: block; }
.brand-name { font-family: 'Space Grotesk', sans-serif; font-weight: 700; font-size: 14px; letter-spacing: -.01em; }

/* Station switcher. Multi-station is the point, so this is never hidden even
   when an account only owns one. */
.station-pick {
  width: 100%; text-align: left;
  background: var(--c2); border: 1px solid var(--ln);
  border-radius: var(--r-md); padding: 8px 11px;
  color: inherit; font: inherit; cursor: pointer;
  margin-bottom: 12px;
}
.station-pick:hover { background: var(--c3); }
.station-pick .eyebrow { display: block; font-size: 9.5px; }
.station-pick-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 2px; }
.station-pick b { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.station-pick svg { width: 11px; height: 11px; flex: none; color: var(--mute); }

.rail-group + .rail-group { margin-top: 14px; }
.rail-group > .eyebrow { display: block; padding: 0 11px 6px; }

.nav {
  display: flex; align-items: center; gap: 9px;
  height: 36px; padding: 0 11px;
  border-radius: var(--r-md);
  color: var(--dim); font-size: 13px; font-weight: 500;
  text-decoration: none; cursor: pointer;
  border: 0; background: transparent; width: 100%;
  font-family: inherit;
}
.nav svg { width: 16px; height: 16px; flex: none; }
.nav:hover { background: var(--c2); color: var(--tx); }
.nav[aria-current="page"] { background: rgba(var(--acc-rgb), .12); color: var(--acc); font-weight: 600; }
.nav .n {
  margin-left: auto;
  display: inline-flex; align-items: center; height: 20px; padding: 0 8px;
  border-radius: 7px; background: rgba(255,77,94,.14); color: var(--live);
  font-size: 10px; font-weight: 600; letter-spacing: .04em;
}

.rail-foot { margin-top: auto; padding-top: 12px; border-top: 1px solid var(--ln); }

/* ---- main column -------------------------------------------------------- */

.main { min-width: 0; display: flex; flex-direction: column; }
.content { padding: 18px 20px 28px; }

.page-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 16px;
}
.page-head h1 { font-size: 21px; }
.page-head p { margin: 3px 0 0; color: var(--dim); font-size: 13px; }
.page-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* ==========================================================================
   TRANSPORT BAR
   Present on every screen and never scrolled away. An operator must never have
   to navigate somewhere to find out what is going out over the air.
   ========================================================================== */

.transport {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 11px 20px;
  background: var(--card);
  border-bottom: 1px solid var(--ln);
}
.transport .spacer { flex: 1 1 auto; }

.onair {
  display: inline-flex; align-items: center; gap: 7px;
  height: 30px; padding: 0 13px; border-radius: var(--r);
  font-size: 12px; font-weight: 600;
  background: rgba(255,77,94,.14); color: var(--live);
  white-space: nowrap;
}
.onair .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--live); animation: pulse 1.2s infinite; }
.onair.off { background: var(--c2); color: var(--dim); }
.onair.off .dot { background: var(--mute); animation: none; }

.pill {
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 11px; border-radius: var(--r);
  background: var(--c2); font-size: 12px; color: var(--dim);
  white-space: nowrap;
}
.pill b { color: var(--tx); font-weight: 600; }
.pill.ghost { background: transparent; border: 1px solid var(--ln2); }

/* ==========================================================================
   CONTROLS
   ========================================================================== */

.ctl {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 44px; padding: 0 16px; border-radius: var(--r-lg);
  background: var(--c2); color: var(--tx);
  font-family: inherit; font-size: 13px; font-weight: 500;
  border: 0; cursor: pointer;
  transition: background .18s ease, color .18s ease;
  white-space: nowrap;
}
.ctl:hover:not(:disabled) { background: var(--c3); }
.ctl:disabled { opacity: .45; cursor: not-allowed; }
.ctl svg { width: 17px; height: 17px; }
.ctl.primary { background: var(--acc); color: var(--acc-ink); font-weight: 600; }
.ctl.primary:hover:not(:disabled) { filter: brightness(1.06); background: var(--acc); }
.ctl.danger { color: var(--live); background: rgba(255,77,94,.1); }
.ctl.danger:hover:not(:disabled) { background: rgba(255,77,94,.18); }
.ctl.ghost { background: transparent; border: 1px solid var(--ln2); }
.ctl.sm { height: 32px; padding: 0 11px; font-size: 12px; border-radius: var(--r); }
.ctl.icon { width: 30px; height: 30px; padding: 0; border-radius: var(--r); }

/* ==========================================================================
   SURFACES
   Border, fill and radius each say "separate object" — spent by role rather
   than stamped on every block.
   ========================================================================== */

.card {
  background: var(--card);
  border: 1px solid var(--ln);
  border-radius: var(--r-xl);
  padding: 17px;
}
.card-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 14px;
}
.card-head h2, .card-head h3 { font-size: 14px; }

.grid { display: grid; gap: 14px; }
.g-2      { grid-template-columns: repeat(2, minmax(0,1fr)); }
.g-4      { grid-template-columns: repeat(4, minmax(0,1fr)); }
.g-main   { grid-template-columns: minmax(0,1.2fr) minmax(0,1fr); }

/* Stat tiles. Only used where the figures ARE the point of the screen. */
.tile {
  background: var(--card); border: 1px solid var(--ln);
  border-radius: var(--r-lg); padding: 15px 16px;
}
.tile .k { display: block; font-size: 10.5px; letter-spacing: .3px; color: var(--mute); margin-bottom: 6px; }
.tile .v { font-family: 'Space Grotesk', sans-serif; font-size: 25px; font-weight: 600; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.tile .u { font-size: 13px; color: var(--mute); font-weight: 400; }
.tile .d { display: block; font-size: 11.5px; color: var(--mute); margin-top: 3px; }
.tile .d.up   { color: var(--good); }
.tile .d.down { color: var(--live); }

/* ==========================================================================
   NOW PLAYING
   ========================================================================== */

.player {
  background: var(--card); border: 1px solid var(--ln2);
  border-radius: var(--r-xl); padding: 18px;
  display: grid; grid-template-columns: 72px minmax(0,1fr) auto;
  gap: 18px; align-items: center;
}
.player .art {
  width: 72px; height: 72px; border-radius: var(--r-lg);
  background: var(--c3); border: 1px solid var(--ln); flex: none;
  object-fit: cover;
  display: grid; place-items: center;
  color: var(--mute); font-size: 9px; letter-spacing: .1em;
}
.player .pt { font-family: 'Space Grotesk', sans-serif; font-size: 17px; font-weight: 600; letter-spacing: -.015em; }
.player .ps { font-size: 13px; color: var(--dim); margin-top: 2px; }
.player .prog { height: 4px; background: var(--c2); border-radius: 3px; margin-top: 11px; overflow: hidden; }
.player .prog i { display: block; height: 100%; background: var(--acc); border-radius: 3px; transition: width 1s linear; }
.player .ptime { display: flex; justify-content: space-between; margin-top: 6px; font-size: 11.5px; color: var(--mute); font-variant-numeric: tabular-nums; }

/* ==========================================================================
   QUEUE / LIST ROWS
   ========================================================================== */

.rows { display: grid; gap: 6px; }

.row {
  position: relative;
  display: grid; grid-template-columns: 44px minmax(0,1fr) auto;
  gap: 11px; align-items: center;
  min-height: 52px; padding: 7px 11px 7px 18px;
  border-radius: var(--r-lg);
  background: var(--c2);
}
/* State marker: a real bar, vertically centred, held clear of the corner.
   Deliberately NOT `box-shadow: inset 2px 0 0` — an inset shadow is clipped by
   the border radius, so it bends around both corners and tapers away instead
   of reading as a straight rail. */
.row[data-state]::before {
  content: ""; position: absolute; left: 6px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 20px; border-radius: 2px; background: var(--mute);
}
.row[data-state="next"]::before   { background: var(--acc); }
.row[data-state="ad"]::before     { background: var(--teal); }
.row[data-state="id"]::before     { background: var(--gold); }
.row[data-state="sermon"]::before { background: var(--violet); }
.row[data-state="live"]::before   { background: var(--live); }

.row .when  { font-size: 11.5px; color: var(--mute); font-variant-numeric: tabular-nums; }
.row .title { font-size: 13px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row .sub   { font-size: 11.5px; color: var(--mute); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ==========================================================================
   CHIPS — kind and state labels
   ========================================================================== */

.chip {
  display: inline-flex; align-items: center; gap: 5px;
  height: 22px; padding: 0 9px; border-radius: 7px;
  background: var(--c3); color: var(--dim);
  font-size: 10px; font-weight: 600; letter-spacing: .04em;
  white-space: nowrap;
}
.chip.next   { background: var(--acc); color: var(--acc-ink); }
.chip.ad     { background: rgba(99,211,196,.18);  color: var(--teal); }
.chip.id     { background: rgba(229,183,105,.18); color: var(--gold); }
.chip.sermon { background: rgba(167,139,250,.18); color: var(--violet); }
.chip.live   { background: rgba(255,77,94,.14);   color: var(--live); }
.chip.good   { background: rgba(99,211,196,.16);  color: var(--good); }
.chip.warn   { background: rgba(229,183,105,.16); color: var(--warn); }

/* ==========================================================================
   TABLES
   ========================================================================== */

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--ln);
  border-radius: var(--r-xl);
  background: var(--card);
}
table { width: 100%; border-collapse: collapse; font-size: 13px; min-width: 700px; }
thead th {
  position: sticky; top: 0; z-index: 1;
  text-align: left; padding: 10px 14px;
  background: var(--c2); border-bottom: 1px solid var(--ln);
  font-size: 10.5px; font-weight: 600; letter-spacing: .3px; color: var(--mute);
  white-space: nowrap;
}
tbody td { padding: 10px 14px; border-bottom: 1px solid var(--ln); vertical-align: middle; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--c2); }
.t-r { text-align: right; }
.t-title { font-weight: 500; }
.t-sub { color: var(--mute); font-size: 11.5px; }

/* Measured loudness plus the correction applied. This pairing is the whole
   reason a -9 LUFS commercial and a -24 LUFS sermon leave the speaker level. */
.lufs { display: inline-flex; align-items: baseline; gap: 6px; font-variant-numeric: tabular-nums; }
.lufs .gain { font-size: 11px; color: var(--teal); }

/* ==========================================================================
   FORMS
   ========================================================================== */

label.field { display: block; margin-bottom: 13px; }
label.field > span { display: block; font-size: 10.5px; letter-spacing: .3px; color: var(--mute); margin-bottom: 6px; }

input[type=text], input[type=email], input[type=password], input[type=number],
input[type=time], input[type=date], input[type=search], select, textarea {
  width: 100%; height: 40px; padding: 0 12px;
  background: var(--c2); border: 1px solid var(--ln);
  border-radius: var(--r-md);
  color: var(--tx); font-family: inherit; font-size: 13px;
}
textarea { height: auto; min-height: 90px; padding: 10px 12px; resize: vertical; }
input::placeholder, textarea::placeholder { color: var(--mute); }
input:focus, select:focus, textarea:focus { border-color: var(--ln2); outline-offset: 0; }

.search {
  display: flex; align-items: center; gap: 8px;
  padding: 0 12px; height: 38px;
  background: var(--c2); border: 1px solid var(--ln);
  border-radius: var(--r-md); flex: 1; min-width: 190px;
}
.search svg { width: 15px; height: 15px; color: var(--mute); flex: none; }
.search input { border: 0; background: transparent; height: auto; padding: 0; }
.search input:focus { outline: none; }

.toolbar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; }

.seg { display: inline-flex; border: 1px solid var(--ln); border-radius: var(--r-md); overflow: hidden; }
.seg button {
  border: 0; background: var(--card); color: var(--dim);
  font: inherit; font-size: 12px; padding: 7px 12px; cursor: pointer;
}
.seg button + button { border-left: 1px solid var(--ln); }
.seg button[aria-pressed="true"] { background: var(--c3); color: var(--tx); font-weight: 600; }

/* ==========================================================================
   FEEDBACK — empty, loading, errors, toasts
   ========================================================================== */

.empty {
  padding: 40px 20px; text-align: center; color: var(--dim);
  border: 1px dashed var(--ln2); border-radius: var(--r-xl);
}
.empty h3 { font-size: 15px; margin-bottom: 6px; color: var(--tx); }
.empty p { margin: 0 auto 14px; max-width: 44ch; font-size: 13px; }

.skeleton {
  background: linear-gradient(90deg, var(--c2) 25%, var(--c3) 37%, var(--c2) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
  border-radius: var(--r-sm);
}
@keyframes shimmer { 0% { background-position: 100% 0 } 100% { background-position: 0 0 } }

.banner {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 14px; border-radius: var(--r-lg);
  font-size: 13px; margin-bottom: 14px;
}
.banner.err  { background: rgba(255,77,94,.10);  color: #FFB3BA; border: 1px solid rgba(255,77,94,.3); }
.banner.warn { background: rgba(229,183,105,.10); color: #F0D6A6; border: 1px solid rgba(229,183,105,.3); }
.banner.ok   { background: rgba(99,211,196,.10); color: #A8EDE4; border: 1px solid rgba(99,211,196,.3); }

#toasts {
  position: fixed; right: 18px; bottom: 18px; z-index: 200;
  display: flex; flex-direction: column; gap: 8px; align-items: flex-end;
}
.toast {
  background: var(--c3); border: 1px solid var(--ln2);
  border-radius: var(--r-lg); padding: 11px 15px;
  font-size: 13px; box-shadow: var(--shadow);
  max-width: 380px;
}
.toast.err { border-color: rgba(255,77,94,.45); color: #FFB3BA; }
.toast.ok  { border-color: rgba(99,211,196,.4); }

/* ==========================================================================
   MODAL
   ========================================================================== */

.modal {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  background: rgba(6,7,9,.6); backdrop-filter: blur(3px);
  padding: 20px;
}
.modal .box {
  width: 460px; max-width: 100%; max-height: calc(100dvh - 40px); overflow-y: auto;
  background: var(--card); border: 1px solid var(--ln2);
  border-radius: var(--r-xl); box-shadow: 0 24px 60px rgba(0,0,0,.55);
  padding: 20px;
}
.modal h3 { font-size: 15px; margin-bottom: 16px; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.modal .x {
  width: 28px; height: 28px; border-radius: 8px; border: 0;
  background: var(--c2); color: var(--dim);
  display: grid; place-items: center; font-size: 15px; cursor: pointer;
}
.modal .actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 18px; }

/* ==========================================================================
   ROTATION CLOCK — the hour wheel
   ========================================================================== */

.clock-wrap { display: flex; gap: 18px; align-items: center; flex-wrap: wrap; }
.clock { width: 156px; height: 156px; flex: none; }
.clock circle { fill: none; stroke-width: 15; }
.clock .track { stroke: var(--c2); }

.legend { display: grid; gap: 7px; flex: 1; min-width: 180px; }
.legend-row { display: flex; align-items: center; gap: 9px; font-size: 12px; color: var(--dim); }
.legend-row .sw { width: 9px; height: 9px; border-radius: 3px; flex: none; }
.legend-row .t { margin-left: auto; font-size: 11px; color: var(--mute); font-variant-numeric: tabular-nums; }

/* ==========================================================================
   RESPONSIVE
   The panel is a desktop tool, but a phone has to be able to answer "what is
   on air and is it healthy" — so the rail collapses and the transport stays.
   ========================================================================== */

@media (max-width: 900px) {
  .app { grid-template-columns: 1fr; }
  .rail {
    position: fixed; inset: 0 auto 0 0; z-index: 90; width: 232px;
    transform: translateX(-100%); transition: transform .2s ease;
    box-shadow: var(--shadow);
  }
  .rail[data-open] { transform: none; }
  .rail-scrim { position: fixed; inset: 0; z-index: 89; background: rgba(6,7,9,.6); }
  .g-main, .g-2 { grid-template-columns: minmax(0,1fr); }
  .g-4 { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .content { padding: 16px 14px 26px; }
  .transport { padding: 10px 14px; }
  .player { grid-template-columns: 56px minmax(0,1fr); }
  .player > :last-child { grid-column: 1 / -1; }
}
@media (min-width: 901px) { .menu-btn, .rail-scrim { display: none; } }
