﻿/* SaySo — talkback console.

   Push-to-talk is radio, so the interface is broadcast equipment rather than a
   chat window: a warm dark chassis the colour of old studio gear, cream
   lettering, an amber backlight and a red peak lamp. Indicator colours mean
   one thing each — jade is fine, amber is loud, ember is live or broken.

   Every typeface here ships with the OS. SaySo has to work with the network
   off, so a font CDN is not an option — and condensed Bahnschrift happens to be
   exactly the face equipment labels are set in. */

:root {
  --chassis:   #14100c;
  --panel:     #1d1811;
  --panel-hi:  #251e16;
  --rail:      #382c20;
  --cream:     #f2e8d5;
  --sand:      #ab9578;
  --dim:       #6d5f4d;
  --amber:     #f0a830;
  --ember:     #e04a25;
  --jade:      #86a86b;

  /* Panel labels: condensed, the way equipment is silkscreened. */
  --face: "Bahnschrift", "Arial Narrow", "Segoe UI", system-ui, sans-serif;
  /* The wordmark gets its own face so the brand is not just a big label.
     Franklin Gothic is wide and warm where Bahnschrift is narrow and technical,
     which matches the rounded logo — and it ships with Windows, so the offline
     promise survives. */
  --mark: "Franklin Gothic Medium", "Segoe UI Semibold", "Trebuchet MS", sans-serif;
  --body: "Segoe UI", system-ui, -apple-system, sans-serif;
  --data: Consolas, "Cascadia Mono", ui-monospace, monospace;

  --gap: 10px;
  --pad: 12px;
  --row: 6px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--chassis);
  color: var(--cream);
  font-family: var(--body);
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

kbd {
  font-family: var(--data);
  font-size: 0.84em;
  background: var(--panel-hi);
  border: 1px solid var(--rail);
  border-bottom-width: 2px;
  border-radius: 3px;
  padding: 0 5px;
  color: var(--cream);
  white-space: nowrap;
}

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

/* Silkscreened panel label — the one structural device, used wherever a piece
   of equipment would have engraved text. */
.panel-label {
  margin: 0;
  font-family: var(--face);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sand);
}

/* ------------------------------------------------------------ status rail */

.rail {
  display: flex;
  align-items: center;
  gap: 34px;
  flex-wrap: wrap;
  padding: 14px 22px;
  background: var(--panel);
  border-bottom: 1px solid var(--rail);
}

.rail-brand { display: flex; align-items: center; gap: 12px; }

.rail-mark { display: block; width: 52px; height: 52px; flex: none; }

.rail-name {
  font-family: var(--mark);
  font-size: 32px;
  font-weight: 600;
  letter-spacing: 0.005em;
  /* Sized and centred against the logo box rather than against its own line
     box, so the wordmark sits level with the mark instead of riding low on
     the font's descender space. */
  line-height: 52px;
  display: block;
}

/* The readouts are an instrument cluster: each one gets its own column with
   room around it, rather than four labels crowded into a corner. */
.rail-readouts {
  display: flex;
  gap: 0;
  margin: 0;
  flex: 1;
  flex-wrap: wrap;
}

.readout {
  padding: 0 26px;
  border-left: 1px solid var(--rail);
  min-width: 116px;
}
.readout:first-child { border-left: none; padding-left: 0; }

.readout dt {
  font-family: var(--face);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--dim);
  line-height: 1.5;
}

.readout dd {
  margin: 0;
  font-family: var(--data);
  font-size: 14px;
  color: var(--cream);
  line-height: 1.35;
}

.rail-ptt { margin: 0 0 0 auto; font-size: 13px; color: var(--sand); }

/* -------------------------------------------------------------- the desk */

.desk {
  display: flex;
  align-items: stretch;
  gap: 18px;
  padding: 14px 16px;
  background: linear-gradient(180deg, var(--panel) 0%, var(--chassis) 100%);
  border-bottom: 1px solid var(--rail);
}

/* Tally lamp: dark glass until the key goes down. */
.tally-bay { display: flex; flex-direction: column; align-items: center; gap: 7px; }

/* Also the button: click to talk, click again to send. */
.tally {
  width: 58px;
  height: 58px;
  padding: 0;
  border-radius: 50%;
  background: #241009;
  border: 3px solid var(--rail);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
}
.tally:hover { border-color: var(--sand); }

.tally-cancel {
  background: none;
  border: 1px solid rgba(224, 74, 37, 0.45);
  border-radius: 2px;
  color: var(--ember);
  font-family: var(--face);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 2px 7px;
  cursor: pointer;
}
.tally-cancel:hover { background: rgba(224, 74, 37, 0.15); }

.tally-glass {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: radial-gradient(circle at 38% 32%, rgba(255,255,255,0.14), transparent 60%), #35170f;
  transition: background 160ms ease;
}

.tally[data-state="listening"] {
  background: #5a1c0d;
  border-color: var(--ember);
  box-shadow: 0 0 22px rgba(224, 74, 37, 0.6);
}
.tally[data-state="listening"] .tally-glass {
  background: radial-gradient(circle at 38% 32%, #ff9d76, var(--ember) 70%);
  animation: lamp 1.1s ease-in-out infinite;
}

.tally[data-state="transcribing"],
.tally[data-state="executing"] {
  background: #4c3510;
  border-color: var(--amber);
  box-shadow: 0 0 18px rgba(240, 168, 48, 0.45);
}
.tally[data-state="transcribing"] .tally-glass,
.tally[data-state="executing"] .tally-glass {
  background: radial-gradient(circle at 38% 32%, #ffdc9b, var(--amber) 70%);
}

.tally[data-state="idle"] .tally-glass {
  background: radial-gradient(circle at 38% 32%, rgba(134, 168, 107, 0.55), #23301c 70%);
}

.tally[data-state="error"] { background: #5a1c0d; border-color: var(--ember); }

@keyframes lamp { 50% { filter: brightness(1.3); } }

.tally-state {
  margin: 0;
  font-family: var(--face);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--sand);
  text-align: center;
}

/* The meter. Discrete segments, because a smooth bar reads as a progress
   indicator and this is an instrument. */
.meter-bay { display: flex; flex-direction: column; align-items: center; gap: 7px; }

.meter {
  display: flex;
  flex-direction: column-reverse;
  gap: 2px;
  padding: 5px;
  background: #0d0a07;
  border: 1px solid var(--rail);
  border-radius: 2px;
  height: 100%;
  min-height: 76px;
  justify-content: flex-start;
}

.segment {
  width: 13px;
  flex: 1;
  min-height: 2px;
  border-radius: 1px;
  background: #2b2118;
  transition: background 70ms linear;
}

.segment.lit { background: var(--jade); }
.segment.lit.hot { background: var(--amber); }
.segment.lit.peak { background: var(--ember); }

.meter-label {
  margin: 0;
  font-family: var(--face);
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
}

.transmission { flex: 1; min-width: 240px; display: flex; flex-direction: column; gap: 5px; justify-content: center; }

.said {
  margin: 0;
  font-size: 23px;
  line-height: 1.22;
  letter-spacing: -0.01em;
  color: var(--cream);
}

.said.waiting { font-size: 14.5px; color: var(--dim); line-height: 1.5; }

.did {
  margin: 0;
  min-height: 17px;
  font-family: var(--data);
  font-size: 12.5px;
  color: var(--amber);
}

.did.bad { color: var(--ember); }

/* ----------------------------------------------------------------- bays */

.bays {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--gap);
  padding: var(--gap) 16px;
  align-items: start;
}

.panel-log     { grid-column: span 4; }
.panel-patch   { grid-column: span 2; }
.panel-notes   { grid-column: span 2; }
.panel-timers  { grid-column: span 2; }
.panel-aliases { grid-column: span 2; }
.panel-phrases { grid-column: span 6; }

.panel {
  background: var(--panel);
  border: 1px solid var(--rail);
  border-radius: 3px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 7px var(--pad);
  background: var(--panel-hi);
  border-bottom: 1px solid var(--rail);
}

.count {
  font-family: var(--data);
  font-size: 10.5px;
  color: var(--cream);
  background: var(--chassis);
  border-radius: 2px;
  padding: 0 5px;
  letter-spacing: 0;
}

.hint { font-size: 11px; color: var(--dim); }

.head-actions { display: flex; gap: 4px; }

.needs-ext {
  font-family: var(--body);
  font-size: 9.5px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--amber);
  margin-left: 5px;
}

.ghost {
  background: none;
  border: 1px solid transparent;
  color: var(--dim);
  font-family: var(--face);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: 2px;
  cursor: pointer;
}
.ghost:hover { color: var(--cream); border-color: var(--rail); }

/* Shown only while a reminder is ringing. It sits in the timers panel, where
   you would look for it, instead of taking over the top of the page. */
.ghost-alert {
  color: var(--ember);
  border-color: rgba(224, 74, 37, 0.45);
  animation: lamp 0.9s ease-in-out infinite;
}
.ghost-alert:hover { color: var(--cream); border-color: var(--ember); }

.empty {
  padding: 14px var(--pad);
  color: var(--dim);
  font-size: 12.5px;
  text-align: center;
}

/* ------------------------------------------------------------------ log */

.log, .notes, .timers, .aliases, .jacks {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  flex: 1;
}

.log { max-height: 248px; }
.notes, .timers, .aliases, .jacks { max-height: 200px; }

.entry {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 8px;
  align-items: baseline;
  padding: var(--row) var(--pad);
  border-bottom: 1px solid rgba(56, 44, 32, 0.55);
  font-size: 13.5px;
}

.entry-time { font-family: var(--data); font-size: 10.5px; color: var(--dim); }
.entry-said { color: var(--cream); }
.entry-said::before { content: attr(data-source); margin-right: 5px; opacity: 0.5; }

.entry-did {
  font-family: var(--data);
  font-size: 11.5px;
  color: var(--sand);
  word-break: break-word;
}

.entry-intent {
  font-family: var(--data);
  font-size: 10px;
  color: var(--dim);
  white-space: nowrap;
}

.entry.failed .entry-did { color: var(--ember); }

/* ---------------------------------------------------------------- notes */

.note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: var(--row) var(--pad);
  border-bottom: 1px solid rgba(56, 44, 32, 0.55);
}

.note-index {
  font-family: var(--data);
  font-size: 10.5px;
  color: var(--dim);
  padding-top: 2px;
  min-width: 13px;
}

.note-check {
  appearance: none;
  width: 14px;
  height: 14px;
  margin: 2px 0 0;
  flex: none;
  border: 1.5px solid var(--dim);
  border-radius: 2px;
  cursor: pointer;
}
.note-check:checked {
  background: var(--jade);
  border-color: var(--jade);
  box-shadow: inset 0 0 0 2px var(--panel);
}

.note-text { flex: 1; font-size: 13.5px; word-break: break-word; }
.note.done .note-text { color: var(--dim); text-decoration: line-through; }

.row-remove {
  background: none;
  border: none;
  color: var(--dim);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  padding: 0 3px;
  border-radius: 2px;
}
.row-remove:hover { color: var(--ember); }

/* --------------------------------------------------------------- timers */

.timer {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: var(--row) var(--pad);
  border-bottom: 1px solid rgba(56, 44, 32, 0.55);
}

.timer-remaining {
  font-family: var(--data);
  font-size: 15px;
  color: var(--amber);
  font-variant-numeric: tabular-nums;
  min-width: 54px;
}

.timer-label { flex: 1; font-size: 13.5px; }

.timer.missed .timer-remaining { color: var(--dim); font-size: 11px; }
.timer.missed .timer-label { color: var(--sand); }

/* ------------------------------------------------------------ shortcuts */

.alias {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: var(--row) var(--pad);
  border-bottom: 1px solid rgba(56, 44, 32, 0.55);
  font-size: 13px;
}

.alias-phrase { color: var(--cream); }
.alias-arrow { color: var(--dim); }
.alias-target {
  flex: 1;
  font-family: var(--data);
  font-size: 11.5px;
  color: var(--sand);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* -------------------------------------------------------------- patch bay */

.jack { border-bottom: 1px solid rgba(56, 44, 32, 0.55); }

.jack-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: var(--row) var(--pad);
  background: none;
  border: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.jack-head:hover { background: var(--panel-hi); }

/* The ring is a patch socket: hollow when nothing is plugged in. */
.jack-ring {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 2px solid var(--dim);
  flex: none;
}
.jack-ring[data-state="connected"] {
  border-color: var(--jade);
  background: var(--jade);
  box-shadow: 0 0 8px rgba(134, 168, 107, 0.65);
}
.jack-ring[data-state="needs setup"] { border-color: var(--amber); }
.jack-ring[data-state="error"] { border-color: var(--ember); background: var(--ember); }

.jack-name { font-size: 13.5px; }

/* Says out loud which connectors cost you the offline guarantee. */
.jack-net {
  font-family: var(--face);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 1px 5px;
  border-radius: 2px;
  border: 1px solid var(--rail);
  color: var(--dim);
}
.jack-net[data-network="true"] { color: var(--amber); border-color: rgba(240, 168, 48, 0.35); }

.jack-state {
  margin-left: auto;
  font-family: var(--face);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
  text-align: right;
}
.jack-state[data-state="connected"] { color: var(--jade); }
.jack-state[data-state="needs setup"] { color: var(--amber); }
.jack-state[data-state="error"] { color: var(--ember); }

.jack-body {
  padding: 2px var(--pad) 10px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.jack-docs { margin: 0; font-size: 11.5px; color: var(--dim); line-height: 1.4; }
.jack-docs a { color: var(--sand); }

.field { display: flex; flex-direction: column; gap: 3px; }

.field span {
  font-family: var(--face);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
}

.field input {
  background: var(--chassis);
  border: 1px solid var(--rail);
  border-radius: 2px;
  padding: 5px 8px;
  color: var(--cream);
  font-family: var(--data);
  font-size: 12px;
}
.field input:focus { border-color: var(--amber); outline: none; }

.jack-actions { display: flex; gap: 6px; flex-wrap: wrap; }

.jack-actions button {
  background: var(--panel-hi);
  border: 1px solid var(--rail);
  color: var(--cream);
  font-family: var(--face);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 2px;
  cursor: pointer;
}
.jack-actions button:hover { border-color: var(--amber); }
.jack-actions .primary { background: var(--amber); border-color: var(--amber); color: #1d1409; }

.jack-tools {
  margin: 0;
  font-family: var(--data);
  font-size: 11px;
  color: var(--sand);
  max-height: 92px;
  overflow-y: auto;
  line-height: 1.6;
  white-space: pre-wrap;
}

/* ------------------------------------------------------------- composer */

.composer {
  display: flex;
  gap: 6px;
  padding: 8px var(--pad);
  border-top: 1px solid var(--rail);
  background: var(--panel-hi);
}

.composer input {
  flex: 1;
  min-width: 0;
  background: var(--chassis);
  border: 1px solid var(--rail);
  border-radius: 2px;
  padding: 6px 9px;
  color: var(--cream);
  font-family: var(--body);
  font-size: 13px;
}
.composer input::placeholder { color: var(--dim); }
.composer input:focus { border-color: var(--amber); outline: none; }

.composer button {
  background: var(--amber);
  color: #1d1409;
  border: none;
  border-radius: 2px;
  padding: 6px 14px;
  font-family: var(--face);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
}
.composer button:hover { filter: brightness(1.08); }

.composer-split input { flex: 1 1 40%; }

/* -------------------------------------------------------------- phrases */

.phrase-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 14px;
  padding: 12px;
}

.phrase-group h3 {
  margin: 0 0 6px;
  font-family: var(--face);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
}

.phrase {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--chassis);
  border: 1px solid var(--rail);
  border-left: 2px solid var(--rail);
  border-radius: 2px;
  color: var(--sand);
  font-family: var(--data);
  font-size: 11.5px;
  padding: 5px 8px;
  margin-bottom: 4px;
  cursor: pointer;
  transition: border-color 140ms ease, color 140ms ease;
}
.phrase:hover { color: var(--cream); border-left-color: var(--amber); }

/* ----------------------------------------------------------------- foot */

.foot {
  max-width: 640px;
  margin: 0 auto;
  padding: 10px 16px 22px;
  color: var(--dim);
  font-size: 11.5px;
  text-align: center;
  line-height: 1.5;
}

/* --------------------------------------------------------------- scroll */

::-webkit-scrollbar { width: 7px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--rail); border-radius: 4px; }

/* ----------------------------------------------------------- responsive */

@media (max-width: 1100px) {
  .bays { grid-template-columns: repeat(4, 1fr); }
  .panel-log     { grid-column: span 4; }
  .panel-patch   { grid-column: span 4; }
  .panel-notes   { grid-column: span 2; }
  .panel-timers  { grid-column: span 2; }
  .panel-aliases { grid-column: span 4; }
  .panel-phrases { grid-column: span 4; }
}

@media (max-width: 720px) {
  .bays { grid-template-columns: 1fr; padding: 8px; }
  .panel-log, .panel-patch, .panel-notes,
  .panel-timers, .panel-aliases, .panel-phrases { grid-column: span 1; }
  .desk { flex-wrap: wrap; padding: 12px; gap: 14px; }
  .rail { padding: 8px 12px; gap: 12px; }
  .rail-ptt { margin-left: 0; }
  .said { font-size: 19px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
