/* ============================================================
   BackBeatBot design system — app.css
   Ships verbatim into the repo. Tokens first; components after.
   ============================================================ */

/* ============ tokens ============ */
:root{
  --bg:#0b101b;
  --surface:#121a29;
  --surface-2:#182338;
  --line:#24304b;
  --line-soft:#1b2539;

  --text:#e9eef8;
  --text-2:#9da9c4;
  --text-3:#63708d;

  --brand:#00d0e4;
  --brand-deep:#0a55cc;
  --brand-hi:#7eefe4;
  --brand-ink:#04121c;
  --grad:linear-gradient(160deg,var(--brand-hi) 0%,#00d0e0 42%,var(--brand-deep) 100%);

  --ok:#2ed08c;
  --warn:#f0b24a;
  --danger:#ff5c6b;
  --danger-ink:#1c0508;
  --unknown:#7e8ba6;

  --wash-brand:rgba(0,208,228,.05);
  --wash-warn:rgba(240,178,74,.08);
  --wash-danger:rgba(255,92,107,.07);
  --wash-ok:rgba(46,208,140,.1);

  --r-panel:10px;
  --r-ctl:8px;

  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px; --s7:48px;

  --font-ui:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --font-chat:ui-monospace,"Cascadia Code","SF Mono",Menlo,Consolas,monospace;

  --fs-0:13px; --fs-1:14px; --fs-2:15px; --fs-3:18px; --fs-4:24px;
}

/* ============ base ============ */
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{background:var(--bg);color:var(--text);font:var(--fs-2)/1.55 var(--font-ui)}
a{color:var(--brand);text-decoration:none}
a:hover{text-decoration:underline}
:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:4px}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* ============ app shell ============
   Two grid rows: rail | main above, identity band | footer below.
   The bottom cells share ONE row, so they are equal height by
   construction — a wrapping name grows both together and the two
   separators always align. */
.shell{display:grid;grid-template-columns:232px 1fr;grid-template-rows:1fr auto;min-height:100vh}

.rail{grid-area:1/1;background:var(--surface);border-right:1px solid var(--line-soft);display:flex;flex-direction:column;padding:var(--s5) var(--s4);gap:var(--s5)}
.brand{display:flex;align-items:center;gap:var(--s3);padding:0 var(--s2)}
.brand-mark{width:38px;height:38px;flex:none;border-radius:9px;background:var(--grad);display:grid;place-items:center;color:var(--brand-ink)}
.brand-mark svg{display:block}
.brand-name{font-weight:650;font-size:var(--fs-3);letter-spacing:-.01em}
.brand-sub{font-size:var(--fs-0);color:var(--text-3);margin-top:1px}

.nav{display:flex;flex-direction:column;gap:2px}
.nav a{display:flex;align-items:center;gap:var(--s3);padding:9px var(--s3);border-radius:var(--r-ctl);color:var(--text-2);font-weight:500}
.nav a:hover{background:var(--surface-2);color:var(--text);text-decoration:none}
.nav a.active{background:var(--surface-2);color:var(--text);box-shadow:inset 2.5px 0 0 var(--brand)}
.nav svg{color:var(--text-3);flex:none}
.nav a.active svg,.nav a:hover svg{color:var(--brand)}

/* identity band — bottom-left cell; logout lives on /me */
.rail-foot{grid-area:2/1;background:var(--surface);border-top:1px solid var(--line-soft);border-right:1px solid var(--line-soft);display:flex;align-items:center;padding:var(--s2) var(--s4)}
.me{flex:1;display:flex;align-items:center;padding:0 var(--s2)}
.me-id{flex:1;display:flex;align-items:center;gap:var(--s3);min-width:0;color:inherit;border-radius:var(--r-ctl);padding:6px var(--s2)}
.me-id:hover{background:var(--surface-2);text-decoration:none}
.me-id > div{min-width:0}
.avatar{width:32px;height:32px;border-radius:50%;flex:none;background:var(--surface-2);border:1px solid var(--line);display:grid;place-items:center;color:var(--text-2);font-size:var(--fs-0);font-weight:600;overflow:hidden}
.avatar img{width:100%;height:100%;object-fit:cover}
.me-name{font-size:var(--fs-1);font-weight:600;overflow-wrap:anywhere}
.me-role{font-size:var(--fs-0);color:var(--text-3)}

/* ============ content column ============ */
.main{grid-area:1/2;display:flex;flex-direction:column;min-width:0}
.content{width:100%;max-width:960px;padding:var(--s7) var(--s6);margin:0 auto;flex:1}
.page-head{display:flex;align-items:center;gap:var(--s4);margin-bottom:var(--s5)}
h1{font-size:var(--fs-4);font-weight:650;letter-spacing:-.015em;margin:0}
.page-head .when{color:var(--text-3);font-size:var(--fs-0);margin-left:auto}
.page-head .act{margin-left:auto}

/* ============ buttons ============ */
.btn{display:inline-flex;align-items:center;gap:8px;border:0;border-radius:var(--r-ctl);cursor:pointer;font:600 var(--fs-1)/1 var(--font-ui);padding:10px 16px}
.btn-primary{background:var(--grad);color:var(--brand-ink)}
.btn-primary:hover{filter:brightness(1.07)}
.btn-quiet{background:var(--surface-2);color:var(--text);border:1px solid var(--line)}
.btn-quiet:hover{border-color:var(--text-3)}
.btn-danger{background:var(--danger);color:var(--danger-ink)}
.btn-danger:hover{filter:brightness(1.08)}
.btn-ghost{background:none;color:var(--text-2)}
.btn-ghost:hover{color:var(--text)}

/* ============ banners (page-level intent) ============
   .banner-danger  action required (danger rule)
   .banner-warn    worth knowing   (warn rule)
   .banner-quiet   informational   (unknown rule, no action) */
.banner{display:flex;gap:var(--s4);align-items:flex-start;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-panel);padding:var(--s4) var(--s5);margin-bottom:var(--s5)}
.banner .icon{flex:none;margin-top:2px}
.banner h2{margin:0;font-size:var(--fs-2);font-weight:650}
.banner p{margin:4px 0 0;color:var(--text-2);font-size:var(--fs-1)}
.banner .act{margin-left:auto;align-self:center;flex:none}
.banner-danger{border-inline-start:3px solid var(--danger)}
.banner-danger .icon{color:var(--danger)}
.banner-warn{border-inline-start:3px solid var(--warn)}
.banner-warn .icon{color:var(--warn)}
.banner-quiet{border-inline-start:3px solid var(--unknown)}
.banner-quiet .icon{color:var(--unknown)}

/* copyable authorize link (bot flow: no JS — select and copy) */
.copyfield{display:flex;flex-direction:column;gap:6px;min-width:280px}
.copyfield input{background:var(--bg);color:var(--brand);border:1px solid var(--line);border-radius:var(--r-ctl);padding:9px 12px;font:12px var(--font-chat);width:100%}
.copyfield .hint{color:var(--text-3);font-size:var(--fs-0)}

/* ============ status cards ============ */
.stat-row{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s4);margin-bottom:var(--s5)}
.stat{background:var(--surface);border:1px solid var(--line-soft);border-radius:var(--r-panel);padding:var(--s4) var(--s5)}
.stat .label{color:var(--text-2);font-size:var(--fs-1)}
.state{display:flex;align-items:center;gap:8px;margin-top:6px;font-weight:650}
.dot{width:8px;height:8px;border-radius:50%;flex:none}
.state.ok{color:var(--ok)}          .state.ok .dot{background:var(--ok)}
.state.danger{color:var(--danger)}  .state.danger .dot{background:var(--danger)}
.state.warn{color:var(--warn)}      .state.warn .dot{background:var(--warn)}
.state.unknown{color:var(--unknown)}.state.unknown .dot{background:var(--unknown)}
.stat .detail{color:var(--text-3);font-size:var(--fs-0);margin-top:4px}

/* ============ panels ============ */
.panel{background:var(--surface);border:1px solid var(--line-soft);border-radius:var(--r-panel);overflow:hidden}
.panel-head{display:flex;align-items:center;gap:var(--s3);padding:var(--s4) var(--s5);border-bottom:1px solid var(--line-soft)}
.panel-head h2{margin:0;font-size:var(--fs-2);font-weight:650}
.panel-head .pulse{color:var(--brand);flex:none}
.panel-pad{padding:var(--s5)}
.conn{margin-left:auto;display:flex;align-items:center;gap:7px;font-size:var(--fs-0);color:var(--text-2)}
.conn .dot{background:var(--ok)}
.conn.off{color:var(--warn)}
.conn.off .dot{background:var(--warn)}

/* ============ chat feed ============ */
.chat{font:13px/1.7 var(--font-chat);padding:var(--s3) 0;max-height:420px;overflow-y:auto}
.msg{display:flex;gap:var(--s3);padding:3px var(--s5)}
.msg:hover{background:var(--surface-2)}
.msg time{color:var(--text-3);flex:none}
.msg .who{font-weight:700;flex:none}
.msg .txt{color:var(--text);overflow-wrap:anywhere}
.who.streamer{color:#ff7a90}
.who.mod{color:var(--ok)}
.who.vip{color:#d9a0ff}
.who.sub{color:#6db3ff}
.who.bot{color:var(--brand)}
.msg.from-bot{background:var(--wash-brand)}
.chat-note{padding:6px var(--s5);color:var(--text-3);font-size:12px;font-family:var(--font-ui);border-top:1px dashed var(--line-soft);border-bottom:1px dashed var(--line-soft)}

/* ============ empty states ============ */
.empty{display:flex;flex-direction:column;align-items:center;gap:var(--s3);padding:var(--s7) var(--s5);text-align:center}
.empty svg{color:var(--text-3)}
.empty h3{margin:0;font-size:var(--fs-2);font-weight:650}
.empty p{margin:0;color:var(--text-3);font-size:var(--fs-1);max-width:38ch}

/* ============ commands table ============ */
.tbl{width:100%;border-collapse:collapse;font-size:var(--fs-1)}
.tbl th{text-align:left;font-weight:600;color:var(--text-3);font-size:var(--fs-0);padding:10px var(--s5);border-bottom:1px solid var(--line-soft)}
.tbl td{padding:14px var(--s5);border-bottom:1px solid var(--line-soft);vertical-align:middle}
.tbl tr:last-child td{border-bottom:0}
.tbl tbody tr:hover{background:var(--surface-2)}
.cmd-name{font:600 13px/1 var(--font-chat);color:var(--text)}
.tbl .meta{color:var(--text-3);font-size:var(--fs-0)}
.tbl .num{font-variant-numeric:tabular-nums}
.row-off .cmd-name,.row-off td{color:var(--text-3)}
.tbl-group td{padding:8px var(--s5);background:var(--bg);color:var(--text-3);font-size:var(--fs-0);border-bottom:1px solid var(--line-soft)}
.rowact{text-align:right}
.rowact a{font-weight:600;font-size:var(--fs-1)}

.chip{display:inline-flex;align-items:center;gap:6px;border-radius:999px;padding:3px 10px;font-size:12px;font-weight:600}
.chip .dot{width:6px;height:6px;border-radius:50%}
.chip-on{background:var(--wash-ok);color:var(--ok)}
.chip-on .dot{background:var(--ok)}
.chip-off{background:rgba(126,139,166,.12);color:var(--unknown)}
.chip-off .dot{background:var(--unknown)}
.chip-builtin{background:var(--wash-brand);color:var(--brand)}

/* ============ forms ============ */
.form-grid{display:grid;grid-template-columns:minmax(0,1fr) 280px;gap:var(--s5);align-items:start}
.field{margin-bottom:var(--s5)}
.field label{display:block;font-weight:600;font-size:var(--fs-1);margin-bottom:6px}
.hint{color:var(--text-3);font-size:var(--fs-0);margin-top:6px}
.input,.select,.textarea{width:100%;background:var(--bg);color:var(--text);border:1px solid var(--line);border-radius:var(--r-ctl);padding:10px 12px;font:inherit}
.textarea{font:13px/1.6 var(--font-chat);min-height:110px;resize:vertical}
.input:focus,.select:focus,.textarea:focus{outline:2px solid var(--brand);outline-offset:0;border-color:transparent}
.affix{display:flex;align-items:stretch}
.affix .pre{display:grid;place-items:center;padding:0 12px;background:var(--surface-2);border:1px solid var(--line);border-right:0;border-radius:var(--r-ctl) 0 0 var(--r-ctl);color:var(--brand);font:700 14px var(--font-chat)}
.affix .input{border-radius:0 var(--r-ctl) var(--r-ctl) 0}

.seg{display:inline-flex;background:var(--bg);border:1px solid var(--line);border-radius:var(--r-ctl);padding:3px;gap:3px}
.seg label{display:block;margin:0}
.seg input{position:absolute;opacity:0;pointer-events:none}
.seg span{display:block;padding:7px 14px;border-radius:6px;color:var(--text-2);font-size:var(--fs-1);font-weight:600;cursor:pointer}
.seg input:checked+span{background:var(--surface-2);color:var(--brand)}
.seg input:focus-visible+span{outline:2px solid var(--brand)}

.switch{position:relative;display:inline-flex;align-items:center;gap:10px;cursor:pointer}
.field label.switch{display:inline-flex}
.switch input{position:absolute;opacity:0}
.switch .track{width:38px;height:22px;border-radius:999px;background:var(--surface-2);border:1px solid var(--line);position:relative;transition:background .15s}
.switch .track::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--text-3);transition:all .15s}
.switch input:checked+.track{background:var(--brand);border-color:transparent}
.switch input:checked+.track::after{left:18px;background:var(--brand-ink)}
.switch input:focus-visible+.track{outline:2px solid var(--brand);outline-offset:2px}
.switch .lbl{font-weight:600;font-size:var(--fs-1)}

.note{display:flex;gap:10px;align-items:flex-start;border-radius:var(--r-ctl);padding:10px 12px;font-size:var(--fs-0);margin-top:8px}
.note svg{flex:none;margin-top:1px}
.note-warn{background:var(--wash-warn);color:var(--warn)}

.field.err .input,.field.err .textarea,.field.err .affix .input{border-color:var(--danger)}
.field.err .affix .pre{border-color:var(--danger)}
.err-msg{color:var(--danger);font-size:var(--fs-0);margin-top:6px;display:flex;gap:6px;align-items:center}

.form-alert{display:flex;gap:var(--s3);align-items:flex-start;background:var(--wash-danger);border:1px solid var(--line);border-inline-start:3px solid var(--danger);border-radius:var(--r-panel);padding:var(--s4);margin-bottom:var(--s5)}
.form-alert svg{color:var(--danger);flex:none;margin-top:2px}
.form-alert h3{margin:0;font-size:var(--fs-1);font-weight:650}
.form-alert ul{margin:6px 0 0;padding-left:18px;color:var(--text-2);font-size:var(--fs-1)}

.help{background:var(--bg);border:1px solid var(--line-soft);border-radius:var(--r-panel);padding:var(--s4)}
.help h3{margin:0 0 var(--s3);font-size:var(--fs-1);font-weight:650;display:flex;gap:8px;align-items:center;color:var(--text-2)}
.help dl{margin:0;font-size:var(--fs-0)}
.help dt{font:600 12px var(--font-chat);color:var(--brand);margin-top:10px}
.help dd{margin:2px 0 0;color:var(--text-3)}

.form-foot{display:flex;gap:var(--s3);align-items:center;border-top:1px solid var(--line-soft);padding-top:var(--s5)}
.form-foot .spacer{flex:1}

/* ============ confirm page card ============ */
.confirm{max-width:520px;background:var(--surface);border:1px solid var(--line);border-inline-start:3px solid var(--danger);border-radius:var(--r-panel);padding:var(--s5)}
.confirm h2{margin:0 0 6px;font-size:var(--fs-3);font-weight:650}
.confirm p{margin:0 0 var(--s4);color:var(--text-2);font-size:var(--fs-1)}
.confirm .cmd-name{color:var(--text)}
.confirm .row{display:flex;gap:12px}

/* ============ centered pages (login / 403) ============
   Two grid rows: the card centers in the flexible row, the footer
   sits in the auto row — req 10: EVERY page shows the version. */
.page-center{min-height:100vh;display:grid;place-items:center;grid-template-rows:1fr auto;padding:var(--s5)}
.page-center > .foot{width:100%;align-self:end}
.card-center{width:100%;max-width:400px;background:var(--surface);border:1px solid var(--line-soft);border-radius:var(--r-panel);padding:var(--s6);text-align:center}
.card-center .brand-mark{width:56px;height:56px;border-radius:14px;margin:0 auto var(--s4)}
.card-center h1{font-size:var(--fs-3);margin:0 0 6px}
.card-center p{color:var(--text-2);font-size:var(--fs-1);margin:0 0 var(--s5)}
.card-center .fine{color:var(--text-3);font-size:var(--fs-0);margin-top:var(--s4);margin-bottom:0}

/* ============ footer ============ */
.foot{display:flex;align-items:center;justify-content:center;padding:var(--s5) var(--s6);color:var(--text-3);font-size:var(--fs-0);text-align:center;border-top:1px solid var(--line-soft)}
.foot .env{color:var(--warn);font-weight:600}
.shell > .foot{grid-area:2/2}

/* ============ mobile ============ */
@media (max-width:720px){
  .shell{grid-template-columns:1fr;grid-template-rows:auto 1fr auto}
  .rail{grid-area:1/1;flex-direction:row;align-items:center;border-right:0;border-bottom:1px solid var(--line-soft);padding:var(--s3) 56px var(--s3) var(--s4)}
  .nav{flex-direction:row}
  .nav a{padding:7px 10px}
  .nav a.active{box-shadow:inset 0 -2.5px 0 var(--brand)}
  .rail-foot{grid-area:1/1;justify-self:end;align-self:center;background:none;border:0;padding:0 var(--s4) 0 0}
  .main{grid-area:2/1}
  .shell > .foot{grid-area:3/1}
  .brand-sub,.me-name,.me-role{display:none}
  .content{padding:var(--s5) var(--s4)}
  .stat-row{grid-template-columns:1fr}
  .banner{flex-wrap:wrap}
  .banner .act{margin-left:0}
  .form-grid{grid-template-columns:1fr}
  .tbl .hide-sm{display:none}
}
