/* 45-spots.css — SPOTS manager (#sec-spots).
   Control deck (master rocker, timing knobs, eligibility counter) over
   grouped compact rows built to scale past 100 spots. Base panel / badge /
   chip / switch / form styling comes from 20-console.css + 30-panels.css;
   only the manager dress lives here. Red never appears — ON AIR only;
   "off" states speak amber/warn + dimming. Tablet-first: every control in
   the deck, toolbar, group heads and rows keeps a >=40px touch target. */

/* ---- search well (tokens file styles the other input types) ---- */
#sec-spots input[type=search]{
  background:var(--input-bg);
  border:1px solid var(--line);
  color:var(--text);
  border-radius:var(--radius);
  padding:8px 12px;
  font-family:var(--font-body);
  font-size:14px;
  max-width:100%;
  box-shadow:var(--well-inset);
  transition:border-color var(--t-fast), box-shadow var(--t-fast);
}
#sec-spots input[type=search]:focus-visible{
  outline:none;
  border-color:var(--accent);
  box-shadow:var(--well-inset), 0 0 0 3px var(--accent-glow);
}

/* enlarged touch targets: checkboxes get a padded hit label, switches get an
   expanded invisible input, buttons in the list get taller keys */
#sec-spots .sr-ck input,
#sec-spots .sg-ck input{ width:20px; height:20px; }
#sec-spots .switch input{ inset:-8px -4px; width:auto; height:auto; }
#sec-spots .sr-btns .btn.small,
#sec-spots .sg-head .btn.small,
#sec-spots .bulk-bar .btn.small,
#sec-spots .spot-edit .form-row .btn,
#sec-spots .knob-save .btn{ min-height:40px; padding:4px 12px; }
/* creation panels (Add spot / Upload): default .btn computes ~38px — lift to
   the 40px floor while keeping the house key's own padding */
#sec-spots .two-col .form-row .btn{ min-height:40px; }

/* ---- control deck ---- */
.spot-deck{ display:flex; flex-direction:column; gap:14px; }

.deck-master{ display:flex; align-items:center; gap:16px; flex-wrap:wrap; }
.deck-master .spacer{ flex:1; }
.master-switch{
  transform:scale(1.4);
  transform-origin:left center;
  margin:4px 12px 4px 4px;
}
.dm-text{ display:flex; flex-direction:column; gap:3px; min-width:0; }
.dm-title{
  font-family:var(--font-display);
  font-weight:800;
  font-size:19px;
  letter-spacing:.14em;
  text-transform:uppercase;
  line-height:1;
}
.dm-state{
  font-family:var(--font-mono);
  font-size:11px;
  letter-spacing:.09em;
  text-transform:uppercase;
}
.dm-state.on{ color:var(--ok); }
.dm-state.off{ color:var(--warn); }

/* live eligibility counter — recessed mono readout */
.deck-count{
  font-size:12.5px;
  color:var(--text);
  background:var(--input-bg);
  border:1px solid var(--line);
  border-radius:var(--radius);
  box-shadow:var(--well-inset);
  padding:8px 12px;
  white-space:nowrap;
}

/* unmissable master-off banner — warn amber hazard stripes, never red */
.deck-offbanner{
  font-family:var(--font-display);
  font-weight:800;
  font-size:15.5px;
  letter-spacing:.12em;
  text-transform:uppercase;
  text-align:center;
  color:var(--warn);
  background:
    repeating-linear-gradient(-45deg, rgba(224,169,63,.10) 0 12px, rgba(224,169,63,.03) 12px 24px),
    var(--input-bg);
  border:1px solid var(--warn);
  border-radius:var(--radius);
  box-shadow:var(--well-inset);
  padding:11px 14px;
}

/* timing knobs */
.deck-knobs{
  display:flex; gap:22px; flex-wrap:wrap; align-items:flex-end;
  border-top:1px solid var(--hairline);
  padding-top:14px;
}
.knob-block{ flex:1 1 280px; min-width:240px; }
.knob-line{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  margin-top:7px;
  font-size:13.5px;
}
.knob-line input[type=number]{ width:78px; min-height:40px; text-align:center; }
.knob-block .help{ margin-top:5px; }
.knob-block .help b{ color:var(--text); font-weight:600; }
.knob-save{ flex:none; padding-bottom:22px; }

/* READ-ONLY deck block (Timer spots). It sits between two real knobs that each
   have a number field and share one Save key, so if it looks the same it reads
   as a control that dead-ends — and a timer is per-spot, there is nothing to
   type here. Give it the recessed .deck-count well treatment so it plainly
   reads as a readout, and let it point at where the control actually lives. */
.knob-read{
  background:var(--input-bg);
  border:1px solid var(--line);
  border-radius:var(--radius);
  box-shadow:var(--well-inset);
  padding:9px 12px 11px;
}
.knob-read .knob-line{ margin-top:5px; }
#sec-spots .knob-goto{ margin-top:9px; min-height:40px; }

/* the one sentence that answers "which spots talk over a song" — mode vs
   source. Full width under the knobs, so it is readable from the list and not
   only from inside the New-spot panel. */
.deck-help{
  border-top:1px solid var(--hairline);
  padding-top:11px;
}

/* master off dims the whole list — the rows stay interactive */
#sp-groups.spots-dimmed{ opacity:.5; }

/* ---- toolbar ---- */
.spot-toolbar{
  display:flex; gap:10px; align-items:center; flex-wrap:wrap;
  margin-top:16px;
}
.spot-toolbar .spacer{ flex:1; }
#sp-q{ flex:1 1 220px; min-width:170px; min-height:40px; }
.spot-toolbar select{ min-height:40px; }

/* ---- bulk action bar — armed amber keyline, sticks under the strip ---- */
.bulk-bar{
  display:flex; gap:8px; align-items:center; flex-wrap:wrap;
  margin-top:12px;
  padding:9px 12px;
  background:linear-gradient(180deg,var(--panel-hi),var(--panel-lo));
  border:1px solid var(--accent-dim);
  border-radius:var(--radius-lg);
  box-shadow:var(--bezel), 0 0 0 1px rgba(245,165,36,.16), var(--shadow-2);
  position:sticky;
  top:calc(var(--chrome-bar) + var(--strip-h, 0px) + 8px);
  z-index:15;
}
.bulk-bar .spacer{ flex:1; }
.bb-count{ color:var(--accent); font-size:12.5px; padding:0 4px; white-space:nowrap; }
.bb-move{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
#sp-bulk-group{ width:168px; min-height:40px; }

/* ---- group sections ---- */
.spot-group{
  margin-top:14px;
  background:var(--panel-face);
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  box-shadow:var(--bezel), var(--shadow-1);
  overflow:hidden;
}
.sg-head{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  padding:8px 12px;
  border-bottom:1px solid var(--hairline);
  background:rgba(255,255,255,.015);
  min-height:52px;
}
.sg-head .spacer{ flex:1; }
.sg-caret{
  background:transparent; border:none; cursor:pointer;
  color:var(--muted);
  width:40px; height:40px; flex:none;
  display:flex; align-items:center; justify-content:center;
  margin-left:-8px;
  border-radius:var(--radius-sm);
}
.sg-caret:hover{ color:var(--text); background:rgba(255,255,255,.04); }
.sg-caret svg{ width:14px; height:14px; transform:rotate(90deg); transition:transform .15s; }
.sg-caret.is-collapsed svg{ transform:rotate(0deg); }
.sg-ck, .sr-ck{
  display:flex; align-items:center; justify-content:center;
  width:40px; height:40px; flex:none;
  cursor:pointer;
  margin:0 -6px;
}
.sg-name{
  font-family:var(--font-display);
  font-weight:700;
  font-size:15.5px;
  letter-spacing:.12em;
  text-transform:uppercase;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  max-width:40vw;
}
.sg-count{ font-size:11.5px; color:var(--muted); white-space:nowrap; }
#sec-spots .chip.off{ color:var(--warn); border-color:var(--warn-line); }
.sg-none{ padding:12px 16px; color:var(--muted); font-size:12.5px; }

/* disabled group: members dim as a block */
.spot-group.grp-off .sg-rows{ opacity:.55; }

/* ---- compact rows ---- */
.spot-row{ border-top:1px solid var(--hairline); }
.sg-rows .spot-row:first-child{ border-top:none; }
.sr-line{
  display:flex; align-items:center; gap:9px;
  padding:4px 12px;
  min-height:50px;
}
.sg-rows .spot-row:nth-child(even) .sr-line{ background:rgba(255,255,255,.015); }
.sr-sw{ flex:none; }
.sr-name{
  font-weight:600; font-size:13.5px;
  flex:1 1 140px; min-width:70px; max-width:300px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.sr-mode{
  display:inline-flex; align-items:center; gap:5px; flex:none;
  color:var(--muted); font-size:11.5px;
}
.sr-mode .btn-ico{ width:13px; height:13px; color:var(--accent-dim); }
.sr-prev{
  flex:2 1 160px; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  color:var(--muted); font-size:12.5px;
}
.sr-prev.mono{ font-size:11.5px; }
.sr-hint{
  flex:none;
  font-family:var(--font-mono);
  font-size:10px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--warn);
  border:1px solid var(--warn-line);
  border-radius:999px;
  padding:2px 8px;
  white-space:nowrap;
}
.sr-btns{ display:flex; gap:6px; flex:none; margin-left:auto; }

/* source marker — the real discriminator for "does this talk over the song".
   Sibling of .sr-mode for the same reason .sr-every is: the 1000px rule hides
   .sr-mode-w, and this must survive that. Quiet: it is context, not a fault. */
.sr-src{
  flex:none;
  font-family:var(--font-mono);
  font-size:10px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--muted);
  white-space:nowrap;
}
.spot-row.ineligible .sr-src{ opacity:.6; }

/* interval cadence — deliberately a SIBLING of .sr-mode, not inside
   .sr-mode-w, which the 1000px rule below hides: on a tablet that would make
   the four Promo timers indistinguishable again */
.sr-every{
  flex:none;
  font-family:var(--font-mono);
  font-size:11px;
  color:var(--accent-dim);
  white-space:nowrap;
}
.spot-row.ineligible .sr-every{ opacity:.5; }
/* everyMins 0 is not a cadence, it is a fault: enabled, eligible, silent */
.sr-notimer{
  flex:none;
  font-family:var(--font-mono);
  font-size:10px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--warn);
  border:1px solid var(--warn-line);
  border-radius:999px;
  padding:2px 8px;
  white-space:nowrap;
}
.mins-warn{ color:var(--warn); font-weight:600; }
/* conditional minutes field (create form + inline editor) */
.sp-mins-line{ display:inline-flex; align-items:center; gap:8px; font-size:13.5px; flex-wrap:wrap; }
.sp-mins-line input[type=number]{ width:78px; min-height:40px; text-align:center; }
/* the plays-per-hour figure inside the read-only deck block (.knob-read above) */
.knob-rate{ color:var(--text); font-weight:600; }
.knob-rate.busy{ color:var(--warn); }

/* an ineligible spot reads muted, its controls stay crisp; the script preview
   keeps a higher floor so it stays readable inside dimmed groups/master-off */
.spot-row.ineligible .sr-name,
.spot-row.ineligible .sr-mode,
.spot-row.ineligible .badge{ opacity:.5; }
.spot-row.ineligible .sr-prev{ opacity:.72; }

/* ---- giveaway-campaign cross-reference (codes that speak on air) ---- */
.camp-panel{ margin-top:14px; }
.camp-panel .panel-title{ display:flex; align-items:center; gap:10px; }
.camp-row{
  display:flex; align-items:center; gap:12px;
  min-height:48px;
  padding:6px 4px;
  border-top:1px solid var(--line);
}
.camp-row:first-of-type{ margin-top:8px; }
.camp-row .camp-script{
  flex:1; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.camp-row.is-off .camp-script{ opacity:.55; }
.camp-mins{ display:flex; align-items:center; gap:6px; flex:none; white-space:nowrap; }
.camp-mins input{ width:64px; min-height:40px; text-align:center; }
.camp-trig{ flex:none; font-size:12px; color:var(--muted); }
.camp-mins .btn.small{ min-height:40px; }
@media (max-width:640px){
  .camp-row{ flex-wrap:wrap; }
  .camp-row .camp-script{ flex-basis:100%; white-space:normal; }
}

/* inline editor under the row (base .spot-edit rule in 30-panels.css) */
.spot-row .spot-edit{
  padding:12px 14px 14px;
  background:rgba(0,0,0,.16);
  margin-top:0;
}
.spot-row.is-editing .sr-line{ background:var(--accent-ghost); }

/* ---- responsive: keep rows one line, no horizontal page scroll ---- */
@media (max-width:1000px){
  .sr-mode-w{ display:none; }
}
@media (max-width:640px){
  .sr-prev{ display:none; }
  .sr-src{ display:none; }
  .sr-name{ max-width:none; }
  #sec-spots .sr-btns .btn.small{ padding:4px 9px; }
  .sr-line{ gap:7px; }
  .deck-count{ white-space:normal; }
}
@media (max-width:900px){
  /* the rail is itself sticky here — let the bar flow instead of stacking */
  .bulk-bar{ position:static; }
}
