/* Shared design system for /ui/admin and /ui/console.
   Tokens switch on <html data-theme>; RTL rules key off [dir="rtl"]. */

:root, :root[data-theme="dark"]{
  color-scheme: dark;
  --bg:#0d1014; --panel:#14181f; --panel-2:#1a1f28; --raise:#202733;
  --line:#28303b; --line-2:#323c49;
  --text:#d8dee7; --mut:#8a96a4; --dim:#5d6775;
  --green:#3ddc84; --green-d:#173a26; --amber:#e3b341; --amber-d:#3a3014;
  --red:#f4584d; --red-d:#3a1716; --blue:#5fa8ff; --blue-d:#13283f;
  --shadow:0 30px 80px -20px rgba(0,0,0,.6); --tex:rgba(255,255,255,.012); --hover:rgba(255,255,255,.02);
  --bub-in:#1a222c; --bub-out:#14432e; --bub-out-text:#dcf5e6;
  --focus-ring:0 0 0 3px rgba(61,220,132,.25);
  --ui:'Hanken Grotesk', system-ui, -apple-system, Segoe UI, sans-serif;
  --mono:'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --r:12px; --r-s:8px;
}
:root[data-theme="light"]{
  color-scheme: light;
  --bg:#f4f5f7; --panel:#ffffff; --panel-2:#f1f3f6; --raise:#ffffff;
  --line:#e3e7ec; --line-2:#d3d9e0;
  --text:#1b242f; --mut:#5b6571; --dim:#9aa4b0;
  --green:#129e54; --green-d:#dcf3e6; --amber:#9c6b15; --amber-d:#f7eed4; --red:#cf3a31; --red-d:#fbe3e1; --blue:#2563eb; --blue-d:#e4ecfd;
  --shadow:0 18px 44px -20px rgba(20,30,45,.18); --tex:rgba(20,30,45,.022); --hover:rgba(20,30,45,.025);
  --bub-in:#ffffff; --bub-out:#d9fdd3; --bub-out-text:#123a1e;
  --focus-ring:0 0 0 3px rgba(18,158,84,.22);
}
/* Arabic font swap — same Latin substack for non-Arabic glyphs. */
:root[lang="ar"]{ --ui:'Cairo','Hanken Grotesk', system-ui, -apple-system, Segoe UI, sans-serif; }
/* Code / URLs / JSON / tabular numerics stay LTR even when the page is RTL. */
code, pre, kbd, samp, .mono, td.num{ direction:ltr; unicode-bidi:isolate; }
[dir="rtl"] .nav-i.active::before{ left:auto; right:0; }
[dir="rtl"] .arrow{ display:inline-block; transform:scaleX(-1); }

*{box-sizing:border-box;margin:0;padding:0}
[hidden]{display:none!important}
html,body{height:100%}
body{font:15px/1.5 var(--ui); background:var(--bg); color:var(--text); -webkit-font-smoothing:antialiased}
a{color:var(--blue); text-decoration:none} a:hover{text-decoration:underline}
button,input,select,textarea{font:inherit; color:inherit}
::selection{background:var(--green); color:#04130a}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-thumb{background:var(--line-2); border-radius:6px; border:2px solid var(--bg)}
:focus-visible{outline:none; box-shadow:var(--focus-ring); border-radius:4px}

/* ---------- controls ---------- */
input[type=text],input[type=password],input[type=number],input[type=url],input[type=datetime-local],select,textarea{
  background:var(--bg); border:1px solid var(--line); border-radius:var(--r-s); padding:.45rem .6rem; outline:none;
}
input:focus,select:focus,textarea:focus{border-color:var(--green); box-shadow:var(--focus-ring)}
textarea{font-family:var(--mono); font-size:13px; width:100%; resize:vertical}
textarea.autogrow{overflow:hidden; min-height:6.5rem}
select{appearance:none; background-image:linear-gradient(45deg,transparent 50%,var(--mut) 50%),linear-gradient(135deg,var(--mut) 50%,transparent 50%); background-position:calc(100% - 14px) 53%,calc(100% - 9px) 53%; background-size:5px 5px,5px 5px; background-repeat:no-repeat; padding-right:1.8rem}
label.f{display:flex; flex-direction:column; gap:.25rem; font-size:.78rem; color:var(--mut); letter-spacing:.02em}
label.f > span.req::after{content:" *"; color:var(--amber)}
.btn{display:inline-flex; align-items:center; gap:.4rem; background:var(--panel-2); border:1px solid var(--line-2); border-radius:var(--r-s); padding:.45rem .75rem; cursor:pointer; font-weight:500; font-size:.9rem; transition:.12s border-color,.12s background,.12s transform}
.btn:hover{border-color:var(--mut)} .btn:active{transform:translateY(1px)}
.btn:disabled{opacity:.45; cursor:not-allowed}
.btn.pri{background:var(--green); color:#04130a; border-color:var(--green); font-weight:700}
.btn.pri:hover{filter:brightness(1.08)}
.btn.danger{border-color:var(--red-d); color:var(--red)}
.btn.danger:hover{background:var(--red); color:#fff; border-color:var(--red)}
.btn.s{padding:.25rem .5rem; font-size:.8rem}
.btn.ghost{background:transparent; border-color:transparent} .btn.ghost:hover{background:var(--panel-2); border-color:var(--line)}

/* ---------- login ---------- */
#login{min-height:100%; display:flex; flex-direction:column; padding:0;
  background:radial-gradient(900px 500px at 50% -10%, rgba(61,220,132,.07), transparent 70%), var(--bg)}
.login-top{display:flex; align-items:center; justify-content:space-between; padding:1.1rem 1.6rem; gap:.6rem}
.login-top .brand{display:flex; align-items:center; gap:.65rem}
.login-top .brand .dot{width:11px;height:11px;border-radius:50%;background:var(--green); box-shadow:0 0 14px var(--green)}
.login-top .brand b{letter-spacing:.04em; font-size:1rem}
.login-top .brand small{display:block; color:var(--dim); font-size:.68rem; letter-spacing:.16em; text-transform:uppercase}
.login-top .top-acts{display:flex; align-items:center; gap:.45rem}
.login-main{flex:1; display:grid; place-items:center; padding:1rem 1.6rem 2rem}
.login-card{width:min(480px,100%); background:var(--panel); border:1px solid var(--line); border-radius:var(--r); padding:2rem 2rem 1.6rem; box-shadow:var(--shadow)}
.mark{display:flex; align-items:center; gap:.6rem; margin-bottom:1.4rem}
.mark .dot{width:11px;height:11px;border-radius:50%;background:var(--green); box-shadow:0 0 14px var(--green)}
.mark b{font-size:1.05rem; letter-spacing:.04em} .mark span{color:var(--mut); font-size:.8rem}
.login-card h1{font-size:1.3rem; font-weight:700; margin-bottom:.3rem}
.login-card p.sub{color:var(--mut); font-size:.86rem; margin-bottom:1.3rem}
.login-card label.f{margin-bottom:.9rem} .login-card input{width:100%; padding:.6rem .7rem}
/* Advanced base-URL toggle: hidden by default (nearly everyone uses this same
   server). Opened programmatically when a saved base URL exists. */
.login-adv{margin-bottom:.9rem}
.login-adv > summary{list-style:none; cursor:pointer; color:var(--mut); font-size:.8rem; user-select:none; padding:.15rem 0; display:inline-flex; align-items:center; gap:.35rem}
.login-adv > summary::-webkit-details-marker{display:none}
.login-adv > summary::before{content:"▸"; font-size:.7rem; transition:transform .15s}
.login-adv[open] > summary::before{transform:rotate(90deg)}
.login-adv > summary:hover{color:var(--text)}
.login-adv label.f{margin-top:.6rem; margin-bottom:0}
/* .f is display:flex, which defeats the native closed-<details> collapse in
   Chromium — hide the field explicitly when the panel isn't open. */
.login-adv:not([open]) label.f{display:none}
#loginMsg{font-size:.84rem; margin-top:.7rem; min-height:1.2em}
#signInBtn{width:100%; justify-content:center; margin-top:.4rem; padding:.6rem}
.rememberme{display:flex;align-items:center;gap:.5rem;margin:.4rem 0 .2rem;font-size:.84rem;color:var(--mut);cursor:pointer}
.rememberme input{flex:0 0 auto;width:14px;height:14px;margin:0;accent-color:var(--green)}
.rememberme .sub2{color:var(--dim);font-size:.78rem}

/* ---------- shell ---------- */
#shell{display:grid; grid-template-columns:248px 1fr; height:100%}
#sidebar{background:var(--panel); border-inline-end:1px solid var(--line); display:flex; flex-direction:column;
  background-image:repeating-linear-gradient(0deg, transparent, transparent 27px, var(--tex) 28px)}
.side-brand{padding:1.05rem 1.1rem; border-bottom:1px solid var(--line); display:flex; align-items:center; gap:.6rem}
.side-brand .dot{width:10px;height:10px;border-radius:50%;background:var(--green); box-shadow:0 0 12px var(--green)}
.side-brand b{letter-spacing:.05em; font-size:.98rem} .side-brand small{color:var(--dim); font-size:.7rem; display:block; letter-spacing:.12em; text-transform:uppercase}
#nav{flex:1; padding:.7rem .6rem; display:flex; flex-direction:column; gap:.15rem; overflow:auto}
.nav-i{display:flex; align-items:center; gap:.7rem; padding:.55rem .7rem; border-radius:var(--r-s); cursor:pointer; color:var(--mut); font-weight:500; font-size:.92rem; border:1px solid transparent; position:relative}
.nav-i:hover{background:var(--panel-2); color:var(--text)}
.nav-i.active{background:linear-gradient(90deg, rgba(61,220,132,.12), transparent); color:var(--text)}
.nav-i.active::before{content:""; position:absolute; left:0; top:6px; bottom:6px; width:3px; border-radius:2px; background:var(--green); box-shadow:0 0 10px var(--green)}
.nav-i .ic{width:1.15rem; text-align:center; font-size:1rem; opacity:.9}
.nav-sec{font-size:.66rem; letter-spacing:.16em; text-transform:uppercase; color:var(--dim); padding:.9rem .8rem .3rem}
.side-foot{border-top:1px solid var(--line); padding:.85rem 1rem; display:flex; flex-direction:column; gap:.55rem}
.who{display:flex; align-items:center; gap:.55rem; font-size:.84rem}
.who .av{width:26px;height:26px;border-radius:50%; display:grid; place-items:center; font-weight:700; font-size:.75rem; flex:none}
.who .av.adm{background:var(--green-d); color:var(--green)} .who .av.usr{background:var(--blue-d); color:var(--blue)}
.who .meta{overflow:hidden} .who .meta b{display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis} .who .meta span{color:var(--dim); font-size:.72rem}

#main{display:flex; flex-direction:column; overflow:hidden}
#topbar{display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:1rem 1.4rem; border-bottom:1px solid var(--line); background:linear-gradient(180deg, var(--panel), transparent)}
#topbar h1{font-size:1.18rem; font-weight:700; letter-spacing:.01em}
#topbar .crumb{color:var(--dim); font-size:.78rem; letter-spacing:.08em; text-transform:uppercase; margin-bottom:.1rem}
#topbar .acts{display:flex; gap:.5rem; align-items:center}
#content{flex:1; overflow:auto; padding:1.4rem}
/* Use the screen. The cap only stops absurd line lengths on ultrawides;
   readability is handled per-component (.bubble, form cards) instead. */
#content > .inner{max-width:min(100%, 2400px); width:100%; margin:0 auto; display:flex; flex-direction:column; gap:1.25rem}
/* Chat is the one view that fills the frame instead of growing the page, so
   the composer stays on screen and only the two panes scroll. Scoped via a
   class set in navTo — making #content a flex column unconditionally would
   let tall pages (Queue) shrink and clip instead of scrolling. */
#content.fill{display:flex; flex-direction:column; overflow:hidden; padding-bottom:1.1rem}
/* Chat is a two-pane app view, not a document — it uses the whole width.
   Bubbles stay capped (see .bubble) so text never stretches. */
#content.fill > .inner{flex:1 1 auto; min-height:0; max-width:none}

/* ---------- pages / cards ---------- */
.page{display:none; flex-direction:column; gap:1.25rem; animation:fade .25s ease both}
.page.show{display:flex}
.page[data-page="chats"].show{flex:1 1 auto; min-height:0}
.page[data-page="chats"] > #chatHost{flex:1 1 auto; min-height:0; display:flex; flex-direction:column}
@keyframes fade{from{opacity:0; transform:translateY(6px)} to{opacity:1; transform:none}}
.card{background:var(--panel); border:1px solid var(--line); border-radius:var(--r); overflow:hidden; animation:fade .3s ease both}
.card > .hd{display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:.9rem 1.25rem; border-bottom:1px solid var(--line); background:var(--panel-2)}
.card > .hd h2{font-size:.98rem; font-weight:600; display:flex; align-items:center; gap:.5rem}
.card > .hd .sub{color:var(--mut); font-size:.78rem; font-weight:400}
.card > .hd .acts{display:flex; gap:.6rem; align-items:flex-end; margin-inline-start:auto}
.card > .bd{padding:1.25rem}
.card > .bd.pad0{padding:0}
.toolbar{display:flex; flex-wrap:wrap; gap:.7rem; align-items:flex-end}
.pager{display:flex; align-items:center; gap:.4rem}
.pager .pglbl{font:500 .8rem/1 var(--mono); color:var(--mut); min-width:4.6rem; text-align:center}
.toolbar .btn{margin-bottom:1px}
.hint{color:var(--dim); font-size:.78rem; margin-top:.5rem}
hr.sep{border:0; border-top:1px solid var(--line); margin:1.1rem 0}
.banner{border:1px solid var(--amber); background:var(--amber-d); color:var(--amber); border-radius:var(--r-s); padding:.7rem .9rem; font-size:.86rem}
.banner.red{border-color:var(--red); background:var(--red-d); color:var(--red)}
.banner.green{border-color:var(--green); background:var(--green-d); color:var(--green)}

/* stat cards */
.stats{display:grid; grid-template-columns:repeat(auto-fit,minmax(160px,1fr)); gap:1rem}
.stat{background:var(--panel); border:1px solid var(--line); border-radius:var(--r); padding:1rem 1.1rem; position:relative; overflow:hidden}
.stat::after{content:""; position:absolute; inset-inline-end:-20px; top:-20px; width:70px; height:70px; border-radius:50%; background:var(--accent,var(--green)); opacity:.08}
.stat .k{font-size:.74rem; letter-spacing:.1em; text-transform:uppercase; color:var(--mut)}
.stat .v{font:700 1.9rem/1 var(--mono); margin-top:.4rem}
.stat .v small{font-size:.95rem; color:var(--mut); font-weight:500}
.stat.clickable{cursor:pointer; transition:.12s border-color} .stat.clickable:hover{border-color:var(--mut)}

/* progress bar (daily budget etc.) */
.meter{height:8px; background:var(--panel-2); border:1px solid var(--line); border-radius:999px; overflow:hidden}
.meter > i{display:block; height:100%; background:var(--green); border-radius:999px; transition:width .3s ease}
.meter.warn > i{background:var(--amber)} .meter.hot > i{background:var(--red)}

/* tables */
.tw{overflow:auto; max-height:60vh}
table{width:100%; border-collapse:collapse; font-size:.875rem}
thead th{position:sticky; top:0; background:var(--panel-2); text-align:start; font-weight:600; color:var(--mut); font-size:.74rem; letter-spacing:.06em; text-transform:uppercase; padding:.6rem .8rem; border-bottom:1px solid var(--line-2); white-space:nowrap; z-index:1}
tbody td{padding:.55rem .8rem; border-bottom:1px solid var(--line); vertical-align:top}
tbody tr:hover{background:var(--hover)}
tbody tr:last-child td{border-bottom:0}
td.num,th.num{font-family:var(--mono)}
td.act{white-space:nowrap; text-align:end}
td.prev{max-width:24rem} td.prev > div{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
td.act .btn{margin-inline-start:.3rem}
.empty{padding:2.2rem 1rem; text-align:center; color:var(--dim); display:flex; flex-direction:column; gap:.4rem; align-items:center}
.empty .big{font-size:1.6rem; opacity:.5}
code.mono{font-family:var(--mono); font-size:.8rem; background:var(--bg); border:1px solid var(--line); border-radius:5px; padding:.08rem .35rem}

/* skeleton loaders */
.skel{padding:.9rem 1.1rem; display:flex; flex-direction:column; gap:.6rem}
.skel i{display:block; height:.95rem; border-radius:5px; background:linear-gradient(90deg, var(--panel-2) 25%, var(--raise) 45%, var(--panel-2) 65%); background-size:200% 100%; animation:shimmer 1.1s linear infinite}
.skel i:nth-child(2n){width:82%} .skel i:nth-child(3n){width:64%}
@keyframes shimmer{from{background-position:200% 0} to{background-position:-200% 0}}

/* badges */
.bdg{display:inline-flex; align-items:center; gap:.32rem; font-size:.72rem; font-weight:600; padding:.12rem .5rem; border-radius:999px; border:1px solid currentColor; letter-spacing:.02em}
.bdg::before{content:""; width:6px;height:6px;border-radius:50%; background:currentColor}
.bdg.g{color:var(--green); background:var(--green-d)} .bdg.a{color:var(--amber); background:var(--amber-d)}
.bdg.r{color:var(--red); background:var(--red-d)} .bdg.b{color:var(--blue); background:var(--blue-d)}
.bdg.m{color:var(--dim); background:transparent} .bdg.m::before{background:var(--dim)}
.chip{display:inline-block; font:600 .68rem/1.5 var(--mono); color:var(--blue); background:var(--blue-d); border-radius:5px; padding:.1rem .4rem; margin-inline-end:.25rem}
.toggle{display:inline-flex; align-items:center; gap:.5rem; cursor:pointer; font-size:.82rem}
.toggle input{appearance:none; width:34px; height:19px; background:var(--line-2); border-radius:999px; position:relative; cursor:pointer; transition:.15s}
.toggle input::after{content:""; position:absolute; top:2px; inset-inline-start:2px; width:15px; height:15px; border-radius:50%; background:#cfd6df; transition:.15s}
.toggle input:checked{background:var(--green)} .toggle input:checked::after{inset-inline-start:17px; background:#04130a}

/* info grid */
.kv{display:grid; grid-template-columns:max-content minmax(0,1fr); gap:.55rem 1.4rem; font-size:.9rem}
/* minmax(0,...) + min-width:0 stop an unbreakable value (a wamid, a URL) from
   forcing the grid wider than its container and clipping the right edge. */
.kv > div{min-width:0; overflow-wrap:anywhere}
pre.payload{margin:0; white-space:pre-wrap; word-break:break-word; font:12px/1.5 var(--mono); max-height:18rem; overflow:auto; background:var(--bg); border:1px solid var(--line); border-radius:6px; padding:.5rem .65rem}
.kv .k{color:var(--mut); font-size:.8rem; letter-spacing:.03em}

/* legend modal list */
.legend{display:flex; flex-direction:column; gap:.65rem; max-height:55vh; overflow:auto}
.legend .li{display:grid; grid-template-columns:9.5rem 1fr; gap:.9rem; align-items:start; font-size:.88rem}
.legend .li p{color:var(--mut); font-size:.82rem}

/* activity log */
#log{font-family:var(--mono); font-size:12.5px; line-height:1.7; white-space:pre-wrap; word-break:break-word; padding:1rem 1.1rem; max-height:65vh; overflow:auto}
#log .e{color:var(--red)} #log:empty::after{content:"—"; color:var(--dim); font-family:var(--ui)}

/* toasts */
#toasts{position:fixed; inset-inline-end:1.1rem; bottom:1.1rem; display:flex; flex-direction:column; gap:.55rem; z-index:50; max-width:380px}
.toast{background:var(--raise); border:1px solid var(--line-2); border-inline-start:3px solid var(--mut); border-radius:var(--r-s); padding:.65rem .85rem; font-size:.86rem; box-shadow:var(--shadow); animation:slideIn .22s ease both; display:flex; gap:.5rem; align-items:flex-start}
.toast.ok{border-inline-start-color:var(--green)} .toast.err{border-inline-start-color:var(--red)} .toast.info{border-inline-start-color:var(--blue)}
.toast .x{margin-inline-start:auto; cursor:pointer; color:var(--dim); flex:none} .toast .x:hover{color:var(--text)}
@keyframes slideIn{from{opacity:0; transform:translateX(20px)} to{opacity:1; transform:none}}
.toast.out{animation:slideOut .2s ease forwards} @keyframes slideOut{to{opacity:0; transform:translateX(20px)}}

/* modal */
#modal{position:fixed; inset:0; background:rgba(4,6,9,.55); backdrop-filter:blur(3px); display:grid; place-items:center; z-index:60; padding:1.5rem; animation:fade .15s ease both}
.modal-box{width:min(600px,100%); max-height:calc(100vh - 3rem); display:flex; flex-direction:column; background:var(--panel); border:1px solid var(--line-2); border-radius:var(--r); box-shadow:var(--shadow); overflow:hidden}
.modal-box .hd{padding:.9rem 1.2rem; border-bottom:1px solid var(--line); background:var(--panel-2); font-weight:600; display:flex; justify-content:space-between; align-items:center}
.modal-box .bd{padding:1.2rem; overflow:auto}
/* Detail dumps (payloads, ids) need room; plain confirms stay narrow. */
.modal-box.wide{width:min(920px,100%)}
.modal-box .ft{padding:0 1.2rem 1.2rem; display:flex; gap:.6rem; justify-content:flex-end}
.copyrow{display:flex; gap:.5rem; margin-top:.7rem}
.copyrow input{flex:1; font-family:var(--mono); font-size:.82rem}

@media(max-width:820px){
  #shell{grid-template-columns:1fr; grid-template-rows:auto 1fr}
  #sidebar{flex-direction:row; border-inline-end:0; border-bottom:1px solid var(--line); overflow:auto}
  .side-brand{border-bottom:0; border-inline-end:1px solid var(--line); white-space:nowrap}
  #nav{flex-direction:row; padding:.4rem; gap:.3rem; align-items:center}
  .nav-sec{display:none} .nav-i.active::before{display:none} .nav-i.active{outline:1px solid var(--green)}
  .side-foot{border-top:0; border-inline-start:1px solid var(--line); flex-direction:row; align-items:center; white-space:nowrap}
  .who .meta{display:none}
}
