/* ═══════════════════════════════════════════════════════════════════════════════════════════
   The call pages — the lab page and every tenant page — on the Majlis design language.
   ═══════════════════════════════════════════════════════════════════════════════════════════

   `moawen.css` holds the system: tokens, surfaces, and the components shared with the console
   and the embedded panel. This file holds ONLY what a call page adds, and the legacy class names
   the browser modules already write.

   THAT SECOND PART IS A CONTRACT, NOT AN OVERSIGHT. view.js builds `.message`, monitor.js builds
   `.monitor-node`, call-page.js toggles `.active` and `.talking`. Renaming them would be a
   rewrite of four modules to change how a page looks, so the names stay and the system is mapped
   onto them. A comment beside each says which module writes it, so the next person can see the
   coupling instead of discovering it.

   Night surface. See rule 1 in moawen.css: a call is a lit face in a dark room. */

/* ── Shell ─────────────────────────────────────────────────────────────────────────────── */
body{min-height:100dvh}

header{
  position:sticky;top:0;z-index:20;display:flex;align-items:center;gap:var(--s3);
  min-height:62px;padding-inline:max(var(--s5),calc((100% - 1160px) / 2));
  background:color-mix(in srgb,var(--bg) 86%,transparent);
  backdrop-filter:saturate(1.6) blur(14px);border-block-end:1px solid var(--edge);
}
header a{
  display:flex;align-items:center;gap:var(--s3);font-size:var(--t-sub);font-weight:700;
  color:var(--fg);text-decoration:none;
}
header a::before{
  content:'';width:30px;height:28px;flex:none;
  background:url('/brand/mark.png') center/contain no-repeat;
}
header span{font-size:var(--t-micro);color:var(--dim);margin-inline-start:auto;text-align:end}

main{width:100%;max-width:1160px;margin-inline:auto;padding:0 var(--s5) var(--s8)}

/* ── The stage ─────────────────────────────────────────────────────────────────────────────
   One subject. Everything the caller does not need while talking is below it or behind a
   summary. `.intro` still exists because tenant.js writes into it. */
.intro{padding-block:var(--s6) 0;text-align:center;display:grid;gap:var(--s2);justify-items:center}
.eyebrow{font-size:var(--t-micro);font-weight:600;color:var(--accent)}
h1{font-size:var(--t-title);font-weight:700;line-height:var(--lh-tight);letter-spacing:-.015em;margin:0}
h2{font-size:var(--t-head);margin:0}
.subtle{color:var(--dim);font-size:var(--t-cap);line-height:var(--lh-cap)}

.stage{padding-block:var(--s5) var(--s6);display:grid;gap:var(--s4);justify-items:center;text-align:center}
/* #state and #hint: written by view.js stage() and by call-page.js. */
#state{font-size:var(--t-title);font-weight:700;min-height:1.25em;margin:0}
#hint{max-width:44ch;color:var(--dim);font-size:var(--t-cap);margin:0}
#timer{font-variant-numeric:tabular-nums;direction:ltr;unicode-bidi:isolate}
.who-line{display:flex;align-items:center;gap:var(--s2);font-size:var(--t-cap);color:var(--dim);flex-wrap:wrap;justify-content:center}
.who-line b{color:var(--fg);font-weight:600}
.who-line a{color:var(--accent)}

/* ── Controls ──────────────────────────────────────────────────────────────────────────────
   The 2×2 grid of four equal buttons is gone. `#start` is the only control that begins a
   conversation, so it is the only one that gets the gradient and the pill (rules 2 and 3).
   The rest are peers of each other, not of it. */
.controls{display:flex;gap:var(--s3);flex-wrap:wrap;justify-content:center}
button{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--s2);
  font:inherit;font-size:var(--t-body);font-weight:500;cursor:pointer;
  padding:11px var(--s5);border-radius:var(--r-pill);
  border:1px solid var(--edge-2);background:var(--bg-2);color:var(--fg);
  transition:background var(--fast) var(--ease),border-color var(--fast) var(--ease),transform var(--fast) var(--ease),filter var(--fast) var(--ease);
}
button:hover{background:var(--bg-3);border-color:var(--dim)}
button:active{transform:translateY(1px)}
button:disabled{opacity:.38;cursor:not-allowed;transform:none}
#start{
  border:0;color:#fff;font-weight:700;font-size:var(--t-sub);padding:15px var(--s7);
  background:var(--grad-live);
  box-shadow:0 10px 30px -10px #1b47d685,0 2px 0 0 #ffffff26 inset;
}
#start:hover{filter:brightness(1.08);background:var(--grad-live)}
#start:disabled{box-shadow:none}
.danger{background:#4a1a15;border-color:#7a2b23;color:#ffc9c1}
.danger:hover{background:#5a201a;border-color:#94352b}
#resume{display:block;margin:var(--s3) auto 0}
#resume[hidden]{display:none}
/* role=alert, written by view.js showError. Empty until it matters, so it must not hold space. */
#error{color:#ff9d93;font-size:var(--t-cap);margin:0;text-align:center}
#error:empty{display:none}

/* ── Journey ───────────────────────────────────────────────────────────────────────────────
   view.js stage() toggles `.active` on #step-connect / #step-ivr / #step-agent. The three
   labels no longer name LiveKit and Gemini to a caller; they are three dots with a caption, and
   the technical route lives in the diagnostics strip where an operator looks for it. */
.journey{display:flex;align-items:center;gap:var(--s2);list-style:none;padding:0;margin:0}
.journey li{
  width:7px;height:7px;border-radius:50%;background:var(--edge-2);
  /* font-size:0 collapses the label without moving it. `text-indent:-999px` was the first
     attempt and is wrong here twice over: in an RTL document it pushes text the other way, and
     it leaves the glyphs laid out at 15px inside a 7px box for the browser to clip. The words
     stay in the DOM for a screen reader either way — and each <li> carries a `title`, so a
     sighted reader can find out what a dot means too, which the hidden label alone never told
     them. */
  font-size:0;line-height:0;color:transparent;
  transition:background var(--base) var(--ease),width var(--base) var(--ease);
}
.journey li.active{width:22px;border-radius:var(--r-pill);background:var(--grad-live)}

/* ── Cards & rails ─────────────────────────────────────────────────────────────────────── */
.grid{display:grid;grid-template-columns:1.25fr .95fr;gap:var(--s4);align-items:start}
@media(max-width:900px){.grid{grid-template-columns:1fr}}
.card{background:var(--bg-2);border:1px solid var(--edge);border-radius:var(--r-lg);padding:var(--s5);min-width:0}
.cardhead{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);margin-block-end:var(--s3)}
.cardhead h2{margin:0}
.badge{
  display:inline-flex;align-items:center;gap:6px;padding:4px 11px;border-radius:var(--r-pill);
  font-size:var(--t-micro);font-weight:600;background:var(--bg-3);color:var(--dim);border:1px solid var(--edge);
}
.center{text-align:center}

/* ── Transcript ────────────────────────────────────────────────────────────────────────────
   view.js add() builds: <div class="message user|assistant"><small>who</small><div>text</div>.
   `.empty` is the placeholder it removes on the first line of speech. */
#transcript{display:flex;flex-direction:column;gap:var(--s4);height:min(44vh,360px);overflow:auto;overscroll-behavior:contain;padding-inline-end:var(--s2)}
.message{display:grid;gap:5px;max-width:84%;margin-inline-start:auto;animation:msg-in var(--base) var(--ease) both}
.message small{font-size:var(--t-micro);font-weight:600;color:var(--accent)}
.message > div{padding:var(--s3) var(--s4);border-radius:var(--r-md);border-start-start-radius:var(--r-xs);background:var(--bg-3);border:1px solid var(--edge);line-height:var(--lh-body)}
/* The caller sits on the reading edge; the assistant answers from the other side. */
.message.user{margin-inline-start:0;margin-inline-end:auto}
.message.user small{color:var(--dim)}
.message.user > div{background:#122b55;border-color:#1d3f75;border-radius:var(--r-md);border-start-end-radius:var(--r-xs)}
#transcript .empty,#transcript .subtle{max-width:none;margin:0;text-align:center;padding-block:var(--s6)}

/* ── Search line ───────────────────────────────────────────────────────────────────────────
   #search is one sentence, replaced wholesale by call-page.js on every search event. */
.search{
  display:flex;align-items:center;gap:var(--s2);margin-block-start:var(--s4);
  padding:var(--s3) var(--s4);border-radius:var(--r-md);
  background:var(--bg-3);border:1px solid var(--edge);
  font-size:var(--t-cap);color:var(--fg-2);
}

/* ── Evidence ──────────────────────────────────────────────────────────────────────────────
   The retrieved answer, verbatim, before the assistant paraphrased it. This is the product's
   integrity feature; it used to be the last thing on the second card. It is a rail of its own
   now, and `.faq-result` is built by view.js showFaqResult(). */
.faq-evidence h3{font-size:var(--t-head);margin:0}
.faq-evidence > p{font-size:var(--t-micro);color:var(--dim);margin:var(--s2) 0 var(--s3);line-height:var(--lh-cap)}
.faq-source{display:inline-flex;align-items:center;min-height:26px;font-size:var(--t-micro);color:var(--accent);text-decoration:none}
.faq-source:hover{text-decoration:underline}
#faq-results{max-height:min(46vh,380px);overflow:auto;display:grid;gap:var(--s2);overscroll-behavior:contain}
.faq-result{background:var(--bg-3);border:1px solid var(--edge);border-radius:var(--r-md);padding:var(--s4);min-width:0}
.faq-result strong{display:block;font-size:var(--t-micro);font-weight:600;color:var(--dim);margin-block-end:var(--s2);white-space:pre-wrap;overflow-wrap:anywhere}
.faq-answer{font-size:var(--t-body);line-height:var(--lh-body);white-space:pre-wrap;overflow-wrap:anywhere}
.faq-result details{margin-block-start:var(--s3);font-size:var(--t-micro);color:var(--dim)}
.faq-result details[hidden]{display:none}
.faq-result summary{cursor:pointer}
.faq-result pre{
  direction:ltr;text-align:start;white-space:pre-wrap;overflow-wrap:anywhere;margin:var(--s2) 0 0;
  background:var(--bg-sunk);border-radius:var(--r-xs);padding:var(--s3);font:11px/1.7 var(--mono);
}

/* ── Pickers ───────────────────────────────────────────────────────────────────────────────
   `.mode` wraps a label and a <select>; call-page.js and tenant.js fill the options. */
.mode{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);font-size:var(--t-cap);color:var(--fg-2)}
select{
  font:inherit;font-size:var(--t-cap);color:var(--fg);background:var(--bg-2);
  padding:8px var(--s3);border:1px solid var(--edge-2);border-radius:var(--r-sm);max-width:100%;
}
select:focus-visible{outline:2px solid var(--teal);outline-offset:2px}

.voice-settings{margin-block-start:var(--s3);border-block-start:1px solid var(--edge);padding-block-start:var(--s3)}
.voice-settings summary{font-size:var(--t-cap);cursor:pointer;color:var(--fg-2);list-style:none;display:flex;align-items:center;min-height:30px;gap:var(--s2)}
.voice-settings summary::-webkit-details-marker{display:none}
.voice-settings summary::after{content:'⌄';margin-inline-start:auto;color:var(--dim)}
.voice-settings[open] summary::after{rotate:180deg}
.voice-settings summary span{background:var(--bg-3);border:1px solid var(--edge);border-radius:var(--r-pill);padding:2px 9px;font-size:var(--t-micro);direction:ltr;unicode-bidi:isolate}
.voice-settings .mode{margin-block-start:var(--s3);flex-wrap:wrap}
.voice-settings .subtle{font-size:var(--t-micro);margin:var(--s2) 0 0}
.voice-preview-button{font-size:var(--t-cap);padding:8px var(--s4);margin-block-start:var(--s3)}
#voice-preview{display:block;width:100%;height:36px;margin-block-start:var(--s3)}
#voice-preview[hidden]{display:none}

/* ── Presence ring hosting ─────────────────────────────────────────────────────────────────
   <saudi-avatar bare> inside .nafas-core. The component keeps its own rig and portrait; `bare`
   turns off the card chrome it draws for the standalone preview page, because the page around
   it already says the name and the state. */
saudi-avatar{display:block;width:100%;height:100%}
.nafas-core saudi-avatar{border-radius:inherit;overflow:hidden}
/* The «٧» orb is gone: choosing 7 belongs to a phone keypad, not a web page. Kept as a no-op
   because call-page.js still addresses #orb with optional chaining. */
.orb{display:none}

/* The experiment's own controls, on the lab page only. */
.lab-settings{margin-block-start:var(--s4)}

/* ── Diagnostics ───────────────────────────────────────────────────────────────────────────
   Everything below is written by monitor.js. It was a permanent card under the call; it is a
   hairline strip now — an operator opens it, a caller never has to look at it. */
.monitor{
  border:1px solid var(--edge);border-radius:var(--r-md);background:var(--bg-2);
  padding:0;margin-block:var(--s5) 0;overflow:hidden;
}
.monitor .cardhead{padding:var(--s3) var(--s4);margin:0;gap:var(--s3)}
.monitor .cardhead h2{font-size:var(--t-cap);font-weight:600;color:var(--dim)}
.monitor .badge{font-size:var(--t-micro)}
#monitor-route{font-size:var(--t-micro);color:var(--dim);margin:0;padding:0 var(--s4) var(--s3);line-height:var(--lh-cap)}
.monitor-nodes{direction:ltr;padding:0 var(--s4) var(--s3)}
.monitor-transport,.monitor-processing{display:flex;align-items:stretch;gap:var(--s2);flex-wrap:wrap}
.monitor-processing{max-width:760px;margin-inline:auto}
.monitor-node{
  direction:rtl;flex:1;min-width:104px;border:1px solid var(--edge);border-radius:var(--r-sm);
  padding:9px var(--s3);background:var(--bg-3);position:relative;
  transition:background var(--base) var(--ease),border-color var(--base) var(--ease);
}
.monitor-node b{display:flex;align-items:center;justify-content:center;gap:6px;font-size:var(--t-micro);font-weight:600;white-space:nowrap}
.monitor-node b::before{content:'';width:6px;height:6px;border-radius:50%;background:var(--edge-2);flex:none}
.monitor-node small{display:block;margin-block-start:3px;text-align:center;color:var(--dim);font-size:var(--t-micro);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.monitor-node[data-status=ok]{border-color:#16c6b23d;background:#0c3b3626}
.monitor-node[data-status=ok] b::before{background:var(--teal);box-shadow:0 0 0 3px #16c6b224}
.monitor-node[data-status=busy]{border-color:#c8a04d40;background:#3a2e1226}
.monitor-node[data-status=busy] b::before{background:#d6a33f}
.monitor-node[data-status=error]{border-color:#c4554b4d;background:#3b171326}
.monitor-node[data-status=error] b::before{background:#e0736a}
.monitor-node[data-status=bypass]{opacity:.42;border-style:dashed}
.monitor-node[data-status=ended]{opacity:.6}
.monitor-arrow{align-self:center;color:var(--dim);font-size:15px}
.monitor-bridge{text-align:center;color:var(--dim);font-size:var(--t-micro);direction:rtl;margin:var(--s2) 0}
.monitor-node.pulse{animation:observed-pulse .65s ease-in-out infinite alternate}
.monitor-node.pending b::before{animation:observed-pulse .8s infinite alternate}
@keyframes observed-pulse{from{box-shadow:0 0 0 0 #16c6b200}to{box-shadow:0 0 0 4px #16c6b233}}

.monitor-details{border-block-start:1px solid var(--edge);padding:var(--s3) var(--s4)}
.monitor summary{display:inline-flex;align-items:center;min-height:28px;cursor:pointer;font-size:var(--t-micro);color:var(--dim);width:fit-content;user-select:none}
.monitor summary:hover{color:var(--fg-2)}
.monitor summary span{background:var(--bg-3);border-radius:var(--r-pill);padding:1px 8px;margin-inline-start:6px;font-variant-numeric:tabular-nums}
.monitor-metrics{direction:rtl;font-family:var(--mono);font-size:var(--t-micro);line-height:1.9;background:var(--bg-sunk);padding:var(--s3);border-radius:var(--r-xs);margin-block-start:var(--s3)}
.monitor-note{font-size:var(--t-micro);color:var(--dim);line-height:var(--lh-cap);margin:var(--s3) 0}
#monitor-log{max-height:220px;overflow:auto;list-style:none;padding:0;margin:var(--s3) 0 0}
#monitor-log li{display:grid;grid-template-columns:70px 1fr 56px;gap:var(--s3);direction:ltr;border-block-end:1px solid var(--edge);padding:7px 2px;font-size:var(--t-micro)}
#monitor-log li span{direction:rtl;text-align:end}
#monitor-log time{font-family:var(--mono);color:var(--dim)}
#monitor-log small{direction:rtl;color:var(--dim);text-align:end}

/* ── Status bar ────────────────────────────────────────────────────────────────────────── */
.statusbar{
  display:flex;justify-content:space-between;align-items:center;gap:var(--s4);flex-wrap:wrap;
  margin-block-start:var(--s5);padding-block-start:var(--s4);border-block-start:1px solid var(--edge);
  font-size:var(--t-micro);color:var(--dim);
}
code{font-family:var(--mono);font-size:10.5px;direction:ltr;unicode-bidi:isolate}

@media(max-width:760px){
  header{padding-inline:var(--s4)}
  main{padding-inline:var(--s4)}
  #transcript{height:min(38vh,300px)}
  .monitor-node{min-width:84px;padding:8px 4px}
  #monitor-log li{grid-template-columns:58px 1fr 44px;gap:var(--s2)}
}

@media (prefers-reduced-motion:reduce){
  .monitor-node.pulse,.monitor-node.pending b::before{animation:none;outline:1px solid var(--teal)}
}
