/* Soundgun web — token layer and shared vocabulary.
 *
 * Every value here is lifted from the app's own stylesheet (ui/app.css, shipped to the
 * design project as _ds_bundle.css) rather than re-derived, so a visual diff against the
 * design is meaningful. The app stylesheet is a desktop window frame — html/body are
 * height:100% with overflow:hidden and user-select:none — and a landing page is a
 * document that scrolls, so the reset below is the document-shaped counterpart of it.
 */

/* --------------------------------------------------------------------------
   Tokens
   -------------------------------------------------------------------------- */

:root {
  --bg-page: #0f0e0d;
  --bg-app: #141311;
  --bg-chrome: #191714;
  --bg-panel: #171512;
  --bg-canvas: #111010;
  --bg-card: #1b1a17;
  --bg-step: #1f1c19;

  --bd: #2d2a26;
  --bd-raised: #34302b;
  --bd-row: #1e1c19;
  --bd-hover: #4a4540;

  --tx: #f2efe9;
  --tx-2: #d8d2ca;
  --tx-3: #c9c2ba;
  --tx-4: #9c948a;
  --tx-5: #8a837a;
  --tx-6: #7d766e;
  --tx-7: #6b645d;
  --tx-8: #6f6862;
  --tx-body: #a8a099;
  --tx-faint: #5a544e;

  --accent: #ff3d81;
  --accent-hi: #ff5e97;
  --accent-wash: rgba(255, 61, 129, 0.1);

  --ok: #4fd18b;
  --warn: #ff8a1f;
  --warn-prose: #c9a97e;
  --warn-bd: rgba(255, 138, 31, 0.35);
  --warn-bg: rgba(255, 138, 31, 0.07);

  --ui: 'Chakra Petch', system-ui, 'Segoe UI', sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, Consolas, 'Cascadia Mono', monospace;

  /* The gutter every full-width section shares. */
  --gut: clamp(16px, 3vw, 40px);
  --head-h: 60px;
}

/* --------------------------------------------------------------------------
   Reset and base
   -------------------------------------------------------------------------- */

* { box-sizing: border-box; }

/* `clip`, not `hidden`. An axis set to `hidden` forces the other axis to compute to `auto`,
   which makes the element a scroll container — and a scroll container here would silently
   kill every position:sticky in the page, because sticky positions against its nearest
   scrollport and that scrollport would never move. `clip` is exempt from that rule, so the
   viewport stays the scroller and the scenes still pin. Set on the root only: the root's
   overflow propagates to the viewport, and body must be left alone so it does not
   propagate instead. */
html {
  height: auto;
  margin: 0;
  overflow-x: clip;
  scroll-behavior: smooth;
  /* Fixed header height plus a breath, so an in-page jump does not land under it. */
  scroll-padding-top: calc(var(--head-h) + 12px);
  color-scheme: dark;
  -webkit-text-size-adjust: 100%;
}

body {
  height: auto;
  min-height: 100%;
  margin: 0;
  background: var(--bg-page);
  color: var(--tx);
  font-family: var(--ui);
  font-size: 12px;
  /* The app disables selection because it is a window, not a document. This is a document. */
  user-select: text;
  -webkit-user-select: text;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: rgba(255, 61, 129, 0.3); }

img, svg, canvas { display: block; max-width: 100%; }

a { color: var(--accent); text-decoration: none; }
a:hover:not([class*='btn']) { color: var(--accent-hi); }

button, input, select, textarea { font-family: inherit; color: inherit; }
button { cursor: pointer; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
:focus:not(:focus-visible) { outline: none; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Scrollbar. The app paints its track on --bg-canvas; the page paints it on --bg-page. */
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: var(--bg-page); }
::-webkit-scrollbar-thumb { background: #2a2724; border: 2px solid var(--bg-page); }
::-webkit-scrollbar-thumb:hover { background: var(--bd-hover); }

/* --------------------------------------------------------------------------
   Shared vocabulary — the classes the design pulls out of the app stylesheet
   -------------------------------------------------------------------------- */

.grow { flex: 1; min-width: 0; }
.ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.h2 { font: 600 12px/1 var(--ui); letter-spacing: 0.06em; }
.sec-label {
  font: 600 10px/1 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--tx-8);
}
.mono-note { font: 400 10px/1.6 var(--mono); color: var(--tx-6); }
.mono-dim { font: 400 10px/1 var(--mono); color: var(--tx-5); }

.dot { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--tx-7); }
.dot.ok { background: var(--ok); }
.dot.warn { background: var(--warn); animation: sg-blink 1.8s ease-in-out infinite; }

.tag {
  font: 600 9px/1 var(--mono);
  letter-spacing: 0.1em;
  padding: 4px 6px;
  color: var(--tx-5);
  border: 1px solid var(--bd-raised);
  white-space: nowrap;
}

.chip {
  font: 500 9px/1 var(--mono);
  letter-spacing: 0.1em;
  color: var(--tx-7);
  border: 1px solid var(--bd-raised);
  padding: 3px 4px;
}

.keycap {
  border: 1px solid var(--bd-hover);
  background: var(--bg-step);
  color: var(--tx);
  font: 500 11px/1 var(--mono);
  padding: 5px 8px;
}
.keycap.quiet { border-color: var(--bd-raised); background: var(--bg-app); }

.card { border: 1px solid var(--bd); background: var(--bg-panel); }
.card-head {
  padding: 14px 16px;
  border-bottom: 1px solid var(--bd);
  display: flex;
  align-items: center;
  gap: 10px;
}
.card-body { padding: 14px 16px; display: flex; flex-direction: column; gap: 10px; }

/* Coloured status banner. The kind colour arrives inline as --c / --c-bd / --c-bg, so one
   rule covers ok / warn / bad / idle without four near-identical blocks. */
.banner {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 11px 12px;
  border: 1px solid var(--c-bd);
  background: var(--c-bg);
  color: var(--c);
}
.banner .banner-title { font: 600 11px/1.2 var(--ui); }
.banner .banner-body { font: 400 10.5px/1.6 var(--ui); opacity: 0.85; }

.warn-note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  border: 1px solid var(--warn-bd);
  background: var(--warn-bg);
  padding: 10px 12px;
}
.warn-note .bang { font: 700 11px/1.2 var(--ui); color: var(--warn); flex: none; }
.warn-note .text { font: 400 10.5px/1.55 var(--ui); color: var(--warn-prose); }

.info-note {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  border: 1px solid var(--bd);
  background: var(--bg-app);
  padding: 12px 14px;
}
.info-note .bang { font: 700 11px/1.2 var(--ui); color: var(--accent); flex: none; }
.info-note .text { font: 400 11px/1.7 var(--ui); color: var(--tx-body); }

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

.btn {
  background: none;
  border: 1px solid var(--bd);
  color: var(--tx-4);
  font: 500 11px/1 var(--ui);
  padding: 8px 11px;
}
.btn:hover { border-color: var(--bd-hover); color: var(--tx); }

.btn-primary {
  background: var(--accent);
  border: none;
  color: var(--bg-app);
  font: 600 11px/1 var(--ui);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 8px 12px;
  transition: background 160ms ease;
}
.btn-primary:hover { background: var(--accent-hi); }

.btn-accent {
  background: none;
  border: 1px solid var(--accent);
  color: var(--accent);
  font: 600 10.5px/1 var(--mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 9px 12px;
  transition: background 160ms ease;
}
.btn-accent:hover { background: rgba(255, 61, 129, 0.12); }

.btn-ghost {
  background: none;
  border: 1px solid var(--bd);
  color: var(--tx-4);
  font: 500 10.5px/1 var(--mono);
  letter-spacing: 0.06em;
  padding: 8px 11px;
  transition: border-color 160ms ease, color 160ms ease;
}
.btn-ghost:hover { border-color: var(--bd-hover); color: var(--tx); }

/* Anchors wearing a button class must not inherit the link colour rules above. */
a.btn-primary, a.btn-primary:hover { color: var(--bg-app); }
a.btn-accent, a.btn-accent:hover { color: var(--accent); }
a.btn-ghost, a.btn, a.btn-ghost:hover, a.btn:hover { color: var(--tx-4); }
a.btn-ghost:hover, a.btn:hover { color: var(--tx); }

/* --------------------------------------------------------------------------
   The overlay ring — geometry the design shares with the app's Overlay screen
   -------------------------------------------------------------------------- */

.ring { position: relative; width: var(--stage); height: var(--stage); flex: none; }
.ring .guide {
  position: absolute;
  border: 1px dashed var(--bd-raised);
  border-radius: 50%;
}
.ring .centre {
  position: absolute;
  left: 50%; top: 50%;
  width: calc(0.2143 * var(--stage)); height: calc(0.2143 * var(--stage));
  transform: translate(-50%, -50%);
  border: 1px solid var(--bd);
  background: var(--bg-panel);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 5px;
}
.ring .centre .cap {
  font: 600 9.5px/1 var(--mono);
  letter-spacing: 0.12em;
  color: var(--tx-5);
}
.ring .centre .sub { font: 500 11px/1.4 var(--ui); color: var(--tx-4); text-align: center; }

/* Width and height arrive inline: how big a card is falls out of how many are on the page. */
.slot-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 5px;
  padding: 8px;
  border: 1px solid var(--bd-raised);
  background: var(--bg-card);
  color: var(--tx-3);
  text-align: left;
  position: absolute;
  left: 50%; top: 50%;
  overflow: hidden;
}
.slot-card .slot { font: 600 9px/1 var(--mono); color: var(--accent); }
.slot-card .name { font: 500 11.5px/1.25 var(--ui); color: var(--tx-3); }
.slot-card .len { font: 400 9px/1 var(--mono); color: var(--tx-5); }
.slot-card .empty { font: 400 10.5px/1.25 var(--mono); color: var(--tx-8); }

/* Says which page of which playlist the canvas is showing, in the playlist's own colour. */
.canvas-tag {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 9px;
}
.canvas-tag .bar { width: 3px; height: 15px; background: var(--pl, var(--accent)); }
.canvas-tag .who { font: 600 11px/1 var(--ui); letter-spacing: 0.04em; color: var(--tx-2); }
.canvas-tag .dim { font: 400 10px/1 var(--mono); color: var(--tx-7); }

/* --------------------------------------------------------------------------
   Keyframes
   -------------------------------------------------------------------------- */

@keyframes sg-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@keyframes sg-spin-slow { to { transform: rotate(360deg); } }
@keyframes sg-spin-back { to { transform: rotate(-360deg); } }
@keyframes sg-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes sg-bars { 0%, 100% { transform: scaleY(0.22); } 50% { transform: scaleY(1); } }
@keyframes sg-cue { 0%, 100% { transform: translateY(0); opacity: 0.3; } 50% { transform: translateY(7px); opacity: 0.9; } }
