/* ══════════════════════════════════════════════════════════════════════════
   app.css — shell, chat, composer, and the live run log.
   ══════════════════════════════════════════════════════════════════════════ */

.app {
  display: grid;
  grid-template-rows: auto 1fr;
  block-size: 100dvh;
}

/* ── title bar ───────────────────────────────────────────────────────────
   Two locales, one lockup: Arabic occupies the inline start (right in RTL),
   English the inline end (left). Both are optically centred on the same
   baseline grid so the bar reads as one object, not two headers. */
.topbar {
  background: var(--surface);
  border-block-end: 1px solid var(--line);
  z-index: var(--z-sticky);
}

.titlebar {
  display: flex;
  align-items: center;
  justify-content: space-between;   /* Arabic pinned right, English pinned left */
  gap: var(--space-5);
  padding-block: var(--space-4);
  padding-inline: var(--space-5);
}

.title-ar { min-inline-size: 0; }

/* No auto margin here: this box declares `direction: ltr`, so logical margins
   resolve against its own axis, not the page's — `margin-inline-start: auto`
   pushed it the wrong way. The parent's space-between does the job instead. */
.title-en {
  min-inline-size: 0;
  direction: ltr;
  unicode-bidi: isolate;
  text-align: start;           /* ltr box → text hugs the left edge */
}

.title-main {
  font-size: var(--fs-title);
  font-weight: var(--fw-bold);
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--ink);
}

.title-sub {
  font-size: var(--fs-subtitle);
  font-weight: var(--fw-medium);
  line-height: 1.45;
  color: var(--ink-2);
  margin-block-start: 3px;
}

/* The English lockup is the quieter of the two — same sizes, lighter ink. */
.title-en .title-main { font-weight: var(--fw-semi); color: var(--ink-2); }
.title-en .title-sub { color: var(--ink-3); font-weight: var(--fw-normal); }

/* ── control strip ───────────────────────────────────────────────────────── */
.controlbar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  padding-block: var(--space-2);
  padding-inline: var(--space-5);
  border-block-start: 1px solid var(--line);
  background: var(--surface-2);
}

.controlbar-spacer { flex: 1; }

/* Health indicator — a green light before presenting is worth a lot of calm. */
.health {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-xs);
  color: var(--ink-2);
  padding-block: var(--space-1);
  padding-inline: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  background: var(--surface);
}

.health-dot {
  inline-size: 8px;
  block-size: 8px;
  border-radius: var(--r-full);
  background: var(--ink-4);
  flex: none;
}

.health[data-state="ok"] .health-dot { background: var(--ok); }
.health[data-state="down"] .health-dot { background: var(--crit); }
.health[data-state="checking"] .health-dot { animation: pulse 1.4s ease-in-out infinite; }

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

.case-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-xs);
  color: var(--ink-2);
  padding-block: var(--space-1);
  padding-inline: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  background: var(--surface);
}

.mode-badge {
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  padding-block: 2px;
  padding-inline: var(--space-2);
  border-radius: var(--r-full);
  background: var(--role-human-soft);
  color: var(--role-human);
  border: 1px solid color-mix(in srgb, var(--role-human) 25%, transparent);
}

/* ── view switch ─────────────────────────────────────────────────────────── */
.viewnav {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}

.viewnav button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-block-size: 34px;
  padding-inline: var(--space-3);
  border-radius: var(--r-sm);
  font-size: var(--fs-sm);
  color: var(--ink-2);
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}

.viewnav button:hover:not(:disabled):not([aria-current="page"]) {
  background: color-mix(in srgb, var(--ink) 5%, transparent);
  color: var(--ink);
}

.viewnav button[aria-current="page"] {
  background: var(--surface);
  color: var(--ink);
  font-weight: var(--fw-medium);
  box-shadow: var(--sh-1);
}

.viewnav button:disabled { opacity: 0.4; }

/* ── shell ───────────────────────────────────────────────────────────────
   In RTL the first grid column falls on the right, so the workspace takes
   column 1 and the rail column 2 — putting the rail on the left as asked. */
.shell {
  display: grid;
  grid-template-columns: 1fr var(--rail-w);
  min-block-size: 0;
}

.workspace {
  grid-column: 1;
  grid-row: 1;
  min-block-size: 0;
  min-inline-size: 0;
  position: relative;
}

.sidebar {
  grid-column: 2;
  grid-row: 1;
  min-block-size: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-3);
  background: var(--surface-2);
  border-inline-end: 1px solid var(--line);
  overflow-y: auto;
}

.new-chat {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  inline-size: 100%;
  min-block-size: 40px;
  padding-inline: var(--space-3);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  text-align: start;
  box-shadow: var(--sh-1);
  transition: background var(--dur-fast) var(--ease-out);
}

.new-chat:hover { background: var(--surface-3); }
.new-chat .icon { font-size: 16px; color: var(--ink-2); }

.rail-section { display: flex; flex-direction: column; gap: 2px; }

.rail-label {
  font-size: var(--fs-2xs);
  color: var(--ink-3);
  padding-inline: var(--space-2);
  padding-block: var(--space-2) var(--space-1);
  letter-spacing: 0.02em;
}

.rail-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-block: var(--space-2);
  padding-inline: var(--space-2);
  border-radius: var(--r-sm);
  font-size: var(--fs-sm);
  color: var(--ink-2);
  line-height: 1.4;
}

.rail-item[aria-current="true"] {
  background: var(--surface);
  color: var(--ink);
  font-weight: var(--fw-medium);
  box-shadow: var(--sh-1);
}

.rail-item.is-muted { color: var(--ink-3); }

.rail-dot {
  inline-size: 6px;
  block-size: 6px;
  border-radius: var(--r-full);
  background: var(--role-agent);
  flex: none;
}

.rail-item.is-muted .rail-dot { background: var(--ink-4); }

/* The project name identifies the case — let it wrap rather than truncate. */
.rail-item-text { min-inline-size: 0; }

.rail-item {
  align-items: flex-start;
}

.rail-item .rail-dot { margin-block-start: 7px; }

.rail-spacer { flex: 1; min-block-size: var(--space-4); }

/* ── admin panel — lower-left corner ─────────────────────────────────────── */
.adminbox {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  padding: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.adminbox-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-inline-size: 0;
}

.adminbox-avatar {
  inline-size: 28px;
  block-size: 28px;
  flex: none;
  border-radius: var(--r-full);
  background: var(--surface-3);
  display: grid;
  place-items: center;
  font-size: 15px;
  line-height: 1;
}

.adminbox-text { display: flex; flex-direction: column; min-inline-size: 0; }

.adminbox-name {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  direction: ltr;
  unicode-bidi: isolate;
  text-align: start;
}

.adminbox-role { font-size: var(--fs-2xs); color: var(--ink-3); }

.adminbox-out {
  inline-size: 100%;
  min-block-size: 34px;
  border: 1px solid var(--line);
  font-size: var(--fs-xs);
}


.view {
  block-size: 100%;
  display: none;
  min-block-size: 0;
}

.view[data-active="true"] { display: grid; }

.view-chat { grid-template-rows: 1fr auto; }

/* ── transcript ──────────────────────────────────────────────────────────── */
.transcript {
  padding-block: var(--space-5) var(--space-4);
  padding-inline: var(--space-5);
  min-block-size: 0;
  font-size: var(--fs-chat);
}

.thread {
  max-inline-size: var(--thread-max);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding-block-end: var(--space-5);
}

/* ── messages ────────────────────────────────────────────────────────────── */
.msg { display: flex; gap: var(--space-2); }

.msg-user { justify-content: flex-start; }

.msg-user { flex-direction: row-reverse; }

.msg-user .msg-body {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  border-start-end-radius: var(--r-xs);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  max-inline-size: 40rem;
  margin-inline-start: auto;
}

.msg-bot { align-items: flex-start; }

/* Emoji avatars: a robot for the system, a person for the human. Emoji are
   colour glyphs, so they need a neutral plate rather than a brand gradient. */
.msg-avatar {
  inline-size: 26px;
  block-size: 26px;
  border-radius: var(--r-full);
  flex: none;
  display: grid;
  place-items: center;
  background: var(--surface-2);
  border: 1px solid var(--line);
  font-size: 14px;
  line-height: 1;
  margin-block-start: 1px;
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
}

.msg-user .msg-avatar { background: var(--surface-3); }

.msg-bot .msg-body {
  min-inline-size: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.msg-text { white-space: pre-wrap; }

.msg-files {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-block-start: var(--space-2);
}

.file-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-xs);
  color: var(--ink-2);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding-block: var(--space-1);
  padding-inline: var(--space-2);
}

.file-pill .name { direction: ltr; unicode-bidi: isolate; }

/* ── run log ─────────────────────────────────────────────────────────────── */
.runlog {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.runlog-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  border-block-end: 1px solid var(--line);
  background: var(--surface-2);
}

.runlog-title {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.runlog-timer {
  margin-inline-start: auto;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--fs-2xs);
  color: var(--ink-2);
}

.runlog-timer .num { font-family: var(--font-mono); }

.runlog-steps {
  display: flex;
  flex-direction: column;
}

/* Each step: a role rail, then the content. */
.step {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-2);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  border-block-end: 1px solid color-mix(in srgb, var(--line) 60%, transparent);
  animation: rise var(--dur-slow) var(--ease-out) both;
}

.step:last-child { border-block-end: none; }

.step-rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding-block-start: 3px;
}

.step-badge {
  inline-size: 20px;
  block-size: 20px;
  border-radius: var(--r-xs);
  display: grid;
  place-items: center;
  flex: none;
  font-size: 11px;
  background: var(--role-soft, var(--surface-2));
  color: var(--role-color, var(--ink-2));
  border: 1px solid color-mix(in srgb, var(--role-color, var(--ink-3)) 26%, transparent);
}

.step-thread {
  inline-size: 1px;
  flex: 1;
  background: var(--line);
  min-block-size: 6px;
}

.step-main { min-inline-size: 0; }

.step-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.step-name {
  font-size: var(--fs-step);
  font-weight: var(--fw-medium);
  line-height: 1.45;
}

/* Role label is text, so role identity never depends on colour alone. */
.role-tag {
  font-size: var(--fs-2xs);
  color: var(--ink-3);
  padding-inline: var(--space-2);
  border-inline-start: 1px solid var(--line-2);
}

.step-msg {
  font-size: var(--fs-step-msg);
  color: var(--ink-2);
  line-height: 1.5;
  margin-block-start: 1px;
}

.step-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  margin-block-start: var(--space-1);
  align-items: center;
}

.step-tools-label {
  font-size: var(--fs-3xs);
  color: var(--ink-3);
}

.step-note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin-block-start: var(--space-1);
  padding-block: var(--space-1);
  padding-inline: var(--space-2);
  background: var(--surface-2);
  border-radius: var(--r-xs);
  font-size: var(--fs-3xs);
  color: var(--ink-2);
  border-inline-start: 2px solid var(--line-2);
}

.step-picks {
  margin-block-start: var(--space-1);
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: var(--fs-step-msg);
  color: var(--ink-2);
}

.step-pick {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.step-pick .dot {
  inline-size: 5px;
  block-size: 5px;
  border-radius: var(--r-full);
  background: var(--role-color, var(--ink-4));
  flex: none;
}

.step-status {
  margin-inline-start: auto;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: var(--fs-3xs);
  color: var(--ink-3);
}

/* A running step breathes so the ~2-minute wait feels alive. */
.step[data-status="running"] .step-badge {
  animation: breathe 2s var(--ease-in-out) infinite;
}

@keyframes breathe {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--role-color, var(--accent)) 30%, transparent); }
  50%      { box-shadow: 0 0 0 5px color-mix(in srgb, var(--role-color, var(--accent)) 0%, transparent); }
}

.spinner {
  inline-size: 12px;
  block-size: 12px;
  border-radius: var(--r-full);
  border: 1.75px solid var(--line-2);
  border-block-start-color: var(--role-color, var(--accent));
  animation: spin 0.8s linear infinite;
  flex: none;
}

@keyframes spin { to { transform: rotate(360deg); } }

/* ── waiting state — never an error on an empty poll ────────────────────── */
.waiting {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  color: var(--ink-2);
  font-size: var(--fs-xs);
  background: var(--surface-2);
  border-block-start: 1px solid var(--line);
}

.waiting .num { font-family: var(--font-mono); color: var(--ink-3); }

/* ── notices ─────────────────────────────────────────────────────────────── */
.notice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding-block: var(--space-3);
  padding-inline: var(--space-4);
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
  border: 1px solid transparent;
}

.notice .icon { font-size: 17px; margin-block-start: 2px; flex: none; }
.notice-ok   { background: var(--ok-soft);   color: var(--ok);   border-color: color-mix(in srgb, var(--ok) 22%, transparent); }
.notice-warn { background: var(--warn-soft); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 28%, transparent); }
.notice-crit { background: var(--crit-soft); color: var(--crit); border-color: color-mix(in srgb, var(--crit) 28%, transparent); }
.notice-info { background: var(--surface-2); color: var(--ink-2); border-color: var(--line); }

.notice strong { color: inherit; font-weight: var(--fw-semi); }

/* ── composer ────────────────────────────────────────────────────────────── */
.composer-wrap {
  padding-block: 0 var(--space-5);
  padding-inline: var(--space-5);
  background: linear-gradient(to top, var(--bg) 62%, transparent);
}

.composer {
  max-inline-size: var(--thread-max);
  margin-inline: auto;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-2);
  transition: border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}

.composer:focus-within {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line-2));
  box-shadow: var(--sh-2), 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
}

.composer.dragover {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.composer-files {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding-block: var(--space-3) 0;
  padding-inline: var(--space-4);
}

.composer-files:empty { display: none; }

.attach {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding-block: var(--space-1);
  padding-inline: var(--space-2);
  font-size: var(--fs-xs);
  color: var(--ink-2);
}

.attach .name {
  direction: ltr;
  unicode-bidi: isolate;
  max-inline-size: 16rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.attach .size { color: var(--ink-3); font-size: var(--fs-2xs); }

.attach button {
  display: grid;
  place-items: center;
  inline-size: 20px;
  block-size: 20px;
  border-radius: var(--r-xs);
  color: var(--ink-3);
  font-size: 11px;
}

.attach button:hover { background: var(--line); color: var(--ink); }

.composer-row {
  display: flex;
  align-items: flex-end;
  gap: var(--space-2);
  padding: var(--space-3);
}

.composer textarea {
  flex: 1;
  min-block-size: 26px;
  max-block-size: 11rem;
  padding-block: var(--space-2);
  padding-inline: var(--space-2);
  font-size: var(--fs-base);
  line-height: var(--lh-snug);
  overflow-y: auto;
}

.composer textarea::placeholder { color: var(--ink-3); }

.composer-actions {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.send-btn {
  inline-size: 40px;
  block-size: 40px;
  min-block-size: 40px;
  padding: 0;
  border-radius: var(--r-md);
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

.send-btn:hover:not(:disabled) { background: var(--accent-ink); border-color: var(--accent-ink); }
.send-btn:disabled { background: var(--surface-3); border-color: var(--line); color: var(--ink-4); }
.send-btn .icon { font-size: 18px; }

.composer-hint {
  padding-block: 0 var(--space-3);
  padding-inline: var(--space-4);
  font-size: var(--fs-2xs);
  color: var(--ink-3);
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}

/* ── decision gate ───────────────────────────────────────────────────────── */
.gate {
  border: 1px solid color-mix(in srgb, var(--role-human) 30%, var(--line));
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
}

.gate-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-block: var(--space-3);
  padding-inline: var(--space-4);
  background: var(--role-human-soft);
  color: var(--role-human);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  border-block-end: 1px solid color-mix(in srgb, var(--role-human) 22%, transparent);
}

.gate-body { padding: var(--space-4); }

.gate-lead {
  font-size: var(--fs-sm);
  color: var(--ink-2);
  margin-block-end: var(--space-3);
}

.gate-options {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--space-2);
}

.gate-option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-block-size: 48px;
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  text-align: start;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--surface);
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}

.gate-option:hover:not(:disabled) {
  background: var(--surface-2);
  border-color: var(--ink-4);
}

.gate-option .code {
  margin-inline-start: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--ink-3);
  direction: ltr;
  unicode-bidi: isolate;
}

.gate-option[data-tone="primary"] { border-color: color-mix(in srgb, var(--accent) 40%, var(--line-2)); }
.gate-option[data-tone="primary"]:hover:not(:disabled) { background: var(--accent-soft); border-color: var(--accent); }
.gate-option[data-tone="danger"] { border-color: color-mix(in srgb, var(--crit) 32%, var(--line-2)); color: var(--crit); }
.gate-option[data-tone="danger"]:hover:not(:disabled) { background: var(--crit-soft); border-color: var(--crit); }

.gate[data-resolved="true"] .gate-options { opacity: 0.55; pointer-events: none; }

.gate-chosen {
  margin-block-start: var(--space-3);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-sm);
  color: var(--ok);
}

/* ── replay bar ──────────────────────────────────────────────────────────── */
.replay-bar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  max-inline-size: var(--thread-max);
  margin-inline: auto;
  margin-block-end: var(--space-3);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  background: var(--role-human-soft);
  border: 1px solid color-mix(in srgb, var(--role-human) 25%, transparent);
  border-radius: var(--r-md);
  font-size: var(--fs-xs);
  color: var(--role-human);
}

.replay-bar .grow { flex: 1; }

/* ══════════════════════════════════════════════════════════════════════════
   sign-in gate

   Redesigned as a bright, luminous agentic surface: a light aurora field, a
   straight-line neural network drawn behind the card, and a glass card on top.

   Two rules govern this block:
   1. It is scoped entirely to `.login`. Nothing here leaks into the app —
      `.login` is removed from view (hidden) the moment sign-in succeeds.
   2. `.login` re-declares the semantic tokens locally, so the gate stays
      luminous even when the app is in dark mode. `boot()` calls
      `applyTheme(currentTheme())`, which follows localStorage or the OS, so
      without this a dark-mode visitor would land on a dark sign-in screen.
      The app itself still honours the user's theme — only the gate is pinned.
   ══════════════════════════════════════════════════════════════════════════ */
.login {
  position: fixed;
  inset: 0;
  z-index: var(--z-toast);
  display: grid;
  place-items: center;
  padding: var(--space-5);
  overflow-y: auto;
  isolation: isolate;

  /* ── local light palette — pinned, theme-independent ──────────────────── */
  color-scheme: light;

  --surface:   #ffffff;
  --surface-2: #f4f7fc;
  --surface-3: #e9eff8;
  --line:      #e2e8f2;
  --line-2:    #cbd5e6;

  --ink:   #101827;  /* 17.3:1 on white */
  --ink-2: #46536b;  /*  7.9:1 on white */
  --ink-3: #64708a;  /*  4.9:1 on white — floor for text */
  --ink-4: #9aa5bb;  /* decorative only, never text */

  --accent:      #1f6fd0;
  --accent-ink:  #17539c;
  --accent-soft: #e9f1fc;
  --on-accent:   #ffffff;

  --crit:      #b02525;
  --crit-soft: #fbeaea;

  /* Luminous accents — background washes and the mesh only, never text. */
  --lum-cyan:   #22b8cf;
  --lum-violet: #7a3596;
  --lum-blue:   #1f6fd0;

  color: var(--ink);

  /* Aurora field: three soft washes over a white-to-pale-blue base. */
  background:
    radial-gradient(920px 540px at 82% -10%,
      color-mix(in srgb, var(--lum-cyan) 17%, transparent), transparent 60%),
    radial-gradient(780px 540px at 10% 110%,
      color-mix(in srgb, var(--lum-violet) 14%, transparent), transparent 60%),
    radial-gradient(1200px 760px at 50% 42%,
      color-mix(in srgb, var(--lum-blue) 8%, transparent), transparent 70%),
    linear-gradient(180deg, #ffffff 0%, #f7faff 46%, #eef4fd 100%);
}

/* Fine straight-line grid — the technical underlayer beneath the network.
   Fades out toward the centre so it never sits behind the reading area. */
.login::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(0deg,
      color-mix(in srgb, var(--lum-blue) 6%, transparent) 0 1px,
      transparent 1px 46px),
    repeating-linear-gradient(90deg,
      color-mix(in srgb, var(--lum-blue) 6%, transparent) 0 1px,
      transparent 1px 46px);
  -webkit-mask-image: radial-gradient(60% 55% at 50% 50%, transparent 12%, #000 78%);
  mask-image: radial-gradient(60% 55% at 50% 50%, transparent 12%, #000 78%);
}

/* ── the neural network field — straight lines only ──────────────────────── */
.login-net {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* Clear the mesh from behind the card, and soften it at the trim edges, so
     the lines read as depth rather than as texture printed over the form. */
  -webkit-mask-image:
    radial-gradient(40rem 30rem at 50% 50%, transparent 6%, #000 62%),
    linear-gradient(#000, #000);
  mask-image:
    radial-gradient(40rem 30rem at 50% 50%, transparent 6%, #000 62%),
    linear-gradient(#000, #000);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

.login-net > svg {
  inline-size: 100%;
  block-size: 100%;
  display: block;
}

.login-net line { stroke-linecap: square; }

.login-net .nn-far  line { stroke: color-mix(in srgb, var(--lum-blue) 24%, transparent); stroke-width: 1; }
.login-net .nn-mid  line { stroke: color-mix(in srgb, var(--lum-blue) 36%, transparent); stroke-width: 1.25; }
.login-net .nn-near line { stroke: color-mix(in srgb, var(--lum-violet) 40%, transparent); stroke-width: 1.6; }

.login-net .nn-dot-far  { fill: color-mix(in srgb, var(--lum-blue) 30%, transparent); }
.login-net .nn-dot-mid  { fill: color-mix(in srgb, var(--lum-blue) 48%, transparent); }
.login-net .nn-dot-near { fill: color-mix(in srgb, var(--lum-violet) 52%, transparent); }

/* A pulse travelling along an existing edge — the only motion on the page,
   and slow enough to be ignorable. Uses the same subtle tier as the app. */
.login-net .nn-signal {
  fill: none;
  stroke: color-mix(in srgb, var(--lum-cyan) 85%, transparent);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-dasharray: 52 1600;
  stroke-dashoffset: 1652;
  opacity: 0;
  animation: nn-travel 10s var(--ease-in-out) infinite;
}

.login-net .nn-signal.s2 { animation-duration: 12.5s; animation-delay: 2.2s; }
.login-net .nn-signal.s3 { animation-duration: 9s;    animation-delay: 4.6s; }

@keyframes nn-travel {
  0%        { stroke-dashoffset: 1652; opacity: 0; }
  10%       { opacity: 0.9; }
  72%       { opacity: 0.9; }
  88%, 100% { stroke-dashoffset: 0; opacity: 0; }
}

/* base.css collapses animation duration under reduced-motion, which would
   freeze the pulse mid-edge. Remove it outright instead. */
@media (prefers-reduced-motion: reduce) {
  .login-net .nn-signal { display: none; }
}

/* ── the card ────────────────────────────────────────────────────────────── */
.login-card {
  position: relative;
  z-index: 1;
  inline-size: min(30rem, 100%);
  background: color-mix(in srgb, #ffffff 82%, transparent);
  -webkit-backdrop-filter: blur(18px) saturate(1.08);
  backdrop-filter: blur(18px) saturate(1.08);
  border: 1px solid color-mix(in srgb, #ffffff 92%, transparent);
  border-radius: var(--r-xl);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.92),
    0 26px 64px -22px rgba(16, 24, 39, 0.24),
    0 4px 16px rgba(16, 24, 39, 0.06);
  padding: var(--space-6) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  overflow: hidden;
  animation: rise var(--dur-slow) var(--ease-out) both;
}

/* Brand seam across the top edge. `linear-gradient()` has no logical
   direction keyword — `to inline-end` is invalid and kills the declaration —
   so this is physical, with an RTL flip below. */
.login-card::before {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 3px;
  background: linear-gradient(to right,
    var(--lum-blue), var(--lum-cyan) 45%, var(--lum-violet));
}

:root[dir="rtl"] .login-card::before {
  background: linear-gradient(to left,
    var(--lum-blue), var(--lum-cyan) 45%, var(--lum-violet));
}

/* ── the mark ────────────────────────────────────────────────────────────── */
.login-mark {
  inline-size: 72px;
  block-size: 72px;
  border-radius: 20px;
  display: grid;
  place-items: center;
  margin-inline: auto;
  background: linear-gradient(150deg, #ffffff, #eef4fd);
  border: 1px solid color-mix(in srgb, var(--lum-blue) 18%, transparent);
  box-shadow:
    inset 0 1px 0 #ffffff,
    0 12px 26px -12px color-mix(in srgb, var(--lum-blue) 55%, transparent);
}

.login-mark svg {
  inline-size: 44px;
  block-size: 44px;
  display: block;
  overflow: visible;
}

.login-mark .ag-strokes line {
  stroke: url(#agGrad);
  stroke-width: 3.2;
  stroke-linecap: round;
}

.login-mark .ag-lattice line {
  stroke: var(--lum-blue);
  stroke-width: 1;
  opacity: 0.3;
}

.login-mark .ag-nodes circle { fill: url(#agGrad); }
.login-mark .ag-nodes .ag-hub { fill: #ffffff; stroke: url(#agGrad); stroke-width: 2; }
.login-mark .ag-nodes .ag-faint { fill: var(--lum-blue); opacity: 0.32; }

/* Wordmark under the mark. Latin inside an RTL document must be isolated or
   the line reorders (base.css §.latin). */
.login-brand {
  margin-block-start: calc(var(--space-2) * -1);
  text-align: center;
  direction: ltr;
  unicode-bidi: isolate;
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: 0.22em;
  color: var(--ink-2);
}

.login-brand .ai {
  background: linear-gradient(120deg, var(--lum-blue), var(--lum-violet));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Never render a blank word where background-clip:text is unsupported. */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .login-brand .ai { color: var(--accent); background: none; }
}

/* ── titles — text unchanged, presentation refreshed ─────────────────────── */
.login-titles { text-align: center; }

.login-title-ar {
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.login-sub-ar {
  font-size: var(--fs-sm);
  color: var(--ink-2);
  margin-block-start: var(--space-1);
}

.login-title-en {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  color: var(--ink-2);
  margin-block-start: var(--space-3);
  padding-block-start: var(--space-3);
  border-block-start: 1px solid var(--line);
  line-height: var(--lh-snug);
}

.login-sub-en {
  font-size: var(--fs-xs);
  color: var(--ink-3);
  margin-block-start: var(--space-1);
}

/* ── fields ──────────────────────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: var(--space-1); }

.field label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--ink-2);
}

.field input {
  min-block-size: 44px;
  padding-inline: var(--space-3);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--fs-base);
  transition: border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}

.field input:hover {
  border-color: color-mix(in srgb, var(--accent) 42%, var(--line-2));
}

/* One ring, not two: base.css draws a global :focus-visible outline, and the
   original block already replaced it here with a softer inset ring. Adding an
   outline back on top produced a doubled ring on the auto-focused username
   field, so the outline stays suppressed and the 3px ring carries focus. */
.field input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}

.login-error {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-sm);
  color: var(--crit);
  background: var(--crit-soft);
  border: 1px solid color-mix(in srgb, var(--crit) 28%, transparent);
  border-radius: var(--r-sm);
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
}

/* ── submit ──────────────────────────────────────────────────────────────── */
.login-submit {
  inline-size: 100%;
  border-color: transparent;
  background: linear-gradient(120deg, var(--lum-blue), var(--lum-violet));
  color: #ffffff;
  box-shadow: 0 10px 24px -12px color-mix(in srgb, var(--lum-blue) 70%, transparent);
}

.login-submit:hover:not(:disabled) {
  background: linear-gradient(120deg, var(--accent-ink), var(--lum-violet));
  border-color: transparent;
  color: #ffffff;
}

/* ── responsive ──────────────────────────────────────────────────────────── */

/* On a presentation display the content should use the screen rather than sit
   in a narrow column with empty margins. The measure still stays inside a
   comfortable reading width — it grows, it does not go full-bleed. */
@media (min-width: 1500px) {
  :root { --thread-max: 68rem; --dash-max: 92rem; }
}

@media (min-width: 1900px) {
  :root { --thread-max: 76rem; --dash-max: 104rem; --rail-w: 18rem; }
}

@media (max-width: 1100px) {
  :root { --rail-w: 13rem; }
  .title-main { font-size: 1.25rem; }
  .title-sub { font-size: var(--fs-sm); }
}

@media (max-width: 900px) {
  .titlebar { padding-inline: var(--space-4); gap: var(--space-3); }
  .controlbar { padding-inline: var(--space-4); }
  .transcript { padding-inline: var(--space-4); }
  .composer-wrap { padding-inline: var(--space-4); }

  /* The rail is navigation for a single-project demo — below this width the
     transcript needs the room more than the rail does. */
  .shell { grid-template-columns: 1fr; }
  .sidebar { display: none; }
}

@media (max-width: 620px) {
  .titlebar { flex-direction: column; align-items: flex-start; gap: var(--space-2); }
  .title-en { margin-inline-start: 0; text-align: start; }
  .title-main { font-size: 1.0625rem; }
  .title-sub { font-size: var(--fs-xs); }
  .login-card { padding: var(--space-5) var(--space-4); }
  .login-mark { inline-size: 60px; block-size: 60px; border-radius: 17px; }
  .login-mark svg { inline-size: 36px; block-size: 36px; }
  .login-net { opacity: 0.6; }

  /* The status text collapses visually but stays in the accessibility tree —
     `display: none` would remove the only name this indicator has. */
  .health span:not(.health-dot) {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .health { padding-inline: var(--space-2); }

  /* Never hide these labels: the buttons carry no icon, so hiding the text
     leaves two empty pills. Shrink instead. */
  .viewnav button { padding-inline: var(--space-2); font-size: var(--fs-xs); }

  .composer textarea { min-block-size: 44px; }
  .hint-keys { display: none; }        /* no hardware keyboard to hint at */

  .step { grid-template-columns: 1fr; }
  .step-rail { flex-direction: row; }
  .step-thread { display: none; }
  .gate-options { grid-template-columns: 1fr; }
}

/* ══════════════════════════════════════════════════════════════════════════
   INTERNAL UI — luminous redesign
   ══════════════════════════════════════════════════════════════════════════

   Everything below is scoped to `.app`, the post-login root. `.login` is a
   sibling of `.app`, never a descendant, so no rule in this block can reach
   the sign-in page — the same containment the login block uses in reverse.

   Additive by construction: this block is appended after every existing rule
   and overrides by scope, so no earlier declaration was edited or deleted.

   Nothing here changes markup semantics, Arabic text, node ids, numbers, or
   any JS hook. Digits stay Latin: no font-feature or locale switch is applied
   anywhere in this file, and every numeric run keeps `lining-nums`.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 1. the luminous palette ──────────────────────────────────────────────
   Same family as the sign-in page — white, soft blue, cyan, violet — retuned
   a half-step calmer, because this surface is read for a whole session while
   the gate is read for five seconds. */
.app {
  --bg:        #f7fafd;
  --surface:   #ffffff;
  --surface-2: #f4f7fc;
  --surface-3: #e9eff8;
  --line:      #e3e9f3;
  --line-2:    #cdd7e7;

  --ink:   #101827;  /* 17.3:1 on white */
  --ink-2: #46536b;  /*  7.9:1 on white */
  --ink-3: #64708a;  /*  4.9:1 on white — floor for text */
  --ink-4: #9aa5bb;  /* dividers and decoration only, never text */

  --accent:      #1f6fd0;
  --accent-ink:  #17539c;
  --accent-soft: #e9f1fc;
  --on-accent:   #ffffff;

  /* Brand triad, shared with the sign-in page. */
  --lum-blue:   #1f6fd0;
  --lum-cyan:   #22b8cf;
  --lum-violet: #7a3596;

  /* Role hues are identity, not decoration — an agent keeps its colour so the
     run log stays readable to anyone who already knows the system. Only the
     soft fills move, from warm parchment to a cool tint that sits on white. */
  --role-leader-soft:   #f4ecfa;
  --role-employee-soft: #e4f5ef;
  --role-agent-soft:    #e9f1fc;
  --role-engine-soft:   #fdefe4;
  --role-gate-soft:     #fcecf4;
  --role-system-soft:   #eef1f6;
  --role-human-soft:    #fbf3e2;

  --ok:        #0f7a4d;
  --ok-soft:   #e3f5ec;
  --warn:      #92600a;
  --warn-soft: #fdf2df;
  --crit:      #b02525;
  --crit-soft: #fceaea;

  --seq-1: #dbe9fb;
  --seq-2: #a9c9f1;
  --seq-3: #6ea3e2;
  --seq-4: #3b81d6;
  --seq-5: #1f6fd0;
  --grid:  #e3e9f3;

  /* Cool shadows. Warm-grey shadows over a blue-white surface read muddy. */
  --sh-1: 0 1px 2px rgba(16, 24, 39, 0.05);
  --sh-2: 0 2px 8px rgba(16, 24, 39, 0.07);
  --sh-3: 0 12px 32px -12px rgba(16, 24, 39, 0.18);

  background: var(--bg);
  color: var(--ink);
}

/* The theme toggle stays a working control (#theme-btn is a JS hook), so the
   dark side is retuned to the same cool family rather than left warm-beige.
   The default and intended direction is the light one above. */
:root[data-theme="dark"] .app {
  --bg:        #0f141c;
  --surface:   #161d27;
  --surface-2: #1c2531;
  --surface-3: #24303f;
  --line:      #2a3543;
  --line-2:    #3a4757;

  --ink:   #eef2f8;
  --ink-2: #b3bdcc;
  --ink-3: #94a0b2;
  --ink-4: #64708a;

  --accent:      #6ea8f0;
  --accent-ink:  #a6c9f7;
  --accent-soft: #16263c;
  --on-accent:   #0b1420;

  --role-leader-soft:   #241a30;
  --role-employee-soft: #0e2620;
  --role-agent-soft:    #12243c;
  --role-engine-soft:   #2b1f13;
  --role-gate-soft:     #301823;
  --role-system-soft:   #1e2733;
  --role-human-soft:    #2b2313;

  --ok:        #45c088;
  --ok-soft:   #10261e;
  --warn:      #d9a648;
  --warn-soft: #2a2213;
  --crit:      #e8736d;
  --crit-soft: #31191a;

  --seq-1: #1b2c44;
  --seq-2: #274465;
  --seq-3: #33608f;
  --seq-4: #3d8fe6;
  --seq-5: #6ea8f0;
  --grid:  #2a3543;
}

/* ── 2. top header — logo centred between the two existing titles ─────────
   The bar becomes a three-column grid so the mark is optically centred on the
   page, not merely placed between two flex items of unequal width. Both title
   blocks keep their exact text, order and side. */
.app .titlebar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding-block: var(--space-3);
}

.app .title-ar { grid-column: 1; }
.app .topbar-mark { grid-column: 2; }
.app .title-en   { grid-column: 3; justify-self: end; }

.app .topbar-mark {
  display: grid;
  place-items: center;
  inline-size: 46px;
  block-size: 46px;
  border-radius: 14px;
  background: linear-gradient(150deg, #ffffff, var(--accent-soft));
  border: 1px solid color-mix(in srgb, var(--lum-blue) 20%, transparent);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    0 8px 18px -10px color-mix(in srgb, var(--lum-blue) 60%, transparent);
}

.app .topbar-mark svg {
  inline-size: 28px;
  block-size: 28px;
  display: block;
  overflow: visible;
}

/* Same geometry as the sign-in mark. The gradient carries its own id
   (`agGradTop`) because the sign-in mark's `agGrad` still exists in the
   document — two nodes sharing one id would make every `url(#…)` in the page
   resolve to whichever came first. */
.app .topbar-mark .ag-strokes line {
  stroke: url(#agGradTop);
  stroke-width: 3.2;
  stroke-linecap: round;
}

.app .topbar-mark .ag-lattice line {
  stroke: var(--lum-blue);
  stroke-width: 1;
  opacity: 0.3;
}

.app .topbar-mark .ag-nodes circle { fill: url(#agGradTop); }
.app .topbar-mark .ag-nodes .ag-hub { fill: var(--surface); stroke: url(#agGradTop); stroke-width: 2; }
.app .topbar-mark .ag-nodes .ag-faint { fill: var(--lum-blue); opacity: 0.32; }

.app .topbar {
  background: var(--surface);
  border-block-end: 1px solid var(--line);
}

/* Brand hairline under the whole header. */
.app .topbar::after {
  content: '';
  display: block;
  block-size: 2px;
  background: linear-gradient(to right,
    var(--lum-blue), var(--lum-cyan) 45%, var(--lum-violet));
  opacity: 0.5;
}

:root[dir="rtl"] .app .topbar::after {
  background: linear-gradient(to left,
    var(--lum-blue), var(--lum-cyan) 45%, var(--lum-violet));
}

.app .controlbar {
  background: color-mix(in srgb, var(--surface-2) 70%, var(--surface));
  border-block-start: 1px solid var(--line);
}

/* ── 3. chat background — thin straight neural lines ──────────────────────
   Decorative and inert: aria-hidden, pointer-events none, and masked away
   from the centre column so it never sits behind a line of text. */
.app .view-chat { position: relative; }

.app .chat-net {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.85;
  -webkit-mask-image:
    linear-gradient(to right, #000 0%, transparent 26%, transparent 74%, #000 100%),
    linear-gradient(to bottom, #000 0%, #000 70%, transparent 100%);
  mask-image:
    linear-gradient(to right, #000 0%, transparent 26%, transparent 74%, #000 100%),
    linear-gradient(to bottom, #000 0%, #000 70%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

.app .chat-net > svg {
  inline-size: 100%;
  block-size: 100%;
  display: block;
}

.app .chat-net line { stroke-linecap: square; }
.app .chat-net .nn-far  line { stroke: color-mix(in srgb, var(--lum-blue) 14%, transparent); stroke-width: 1; }
.app .chat-net .nn-mid  line { stroke: color-mix(in srgb, var(--lum-blue) 20%, transparent); stroke-width: 1; }
.app .chat-net .nn-near line { stroke: color-mix(in srgb, var(--lum-violet) 22%, transparent); stroke-width: 1.2; }
.app .chat-net .nn-dot-far  { fill: color-mix(in srgb, var(--lum-blue) 18%, transparent); }
.app .chat-net .nn-dot-mid  { fill: color-mix(in srgb, var(--lum-blue) 26%, transparent); }
.app .chat-net .nn-dot-near { fill: color-mix(in srgb, var(--lum-violet) 30%, transparent); }

/* Content sits above the field. */
.app .transcript,
.app .composer-wrap { position: relative; z-index: 1; }

.app .composer-wrap {
  background: linear-gradient(to top,
    var(--bg) 58%, color-mix(in srgb, var(--bg) 60%, transparent) 85%, transparent);
}

/* ── 4. rail and shell ───────────────────────────────────────────────────── */
.app .sidebar {
  background: color-mix(in srgb, var(--surface-2) 82%, var(--surface));
  border-inline-end: 1px solid var(--line);
}

.app .rail-item[aria-current="true"] {
  background: var(--surface);
  box-shadow: var(--sh-1);
  border-inline-start: 2px solid var(--lum-blue);
}

.app .rail-dot { background: var(--lum-blue); }

.app .new-chat { border-color: var(--line-2); }
.app .new-chat:hover { background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 35%, var(--line-2)); }

.app .viewnav button[aria-current="page"] {
  background: var(--surface);
  color: var(--lum-blue);
  box-shadow: var(--sh-1);
}

/* ══════════════════════════════════════════════════════════════════════════
   5. EXECUTION LOG — compact process view
   ══════════════════════════════════════════════════════════════════════════
   The old row was three stacked blocks (name / message / tools) separated by a
   full-width rule, which made 20 steps read as a 20-row table. The new row is
   a single spine with a tight two-line body: identity on line 1, what happened
   on line 2, tools inline and quiet. Rules are gone; the spine carries the
   sequence. Every field that was on screen before is still on screen.
   ══════════════════════════════════════════════════════════════════════════ */
.app .runlog {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  overflow: hidden;
}

.app .runlog-head {
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--accent-soft) 55%, var(--surface)), var(--surface));
  border-block-end: 1px solid var(--line);
  position: relative;
}

.app .runlog-title {
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semi);
  color: var(--ink-2);
  letter-spacing: 0.01em;
}

.app .runlog-title .icon { color: var(--lum-blue); font-size: 13px; }

.app .runlog-timer {
  font-size: var(--fs-3xs);
  color: var(--ink-3);
  font-variant-numeric: lining-nums tabular-nums;
}

/* Progress: an indeterminate hairline that runs only while a step is running,
   and disappears on its own when the last step completes. Pure CSS — the log
   already carries the state in `data-status`, so no JS hook is touched. */
.app .runlog:has(.step[data-status="running"]) .runlog-head::after {
  content: '';
  position: absolute;
  inset-block-end: -1px;
  inset-inline: 0;
  block-size: 2px;
  background: linear-gradient(90deg,
    transparent, var(--lum-cyan), var(--lum-blue), transparent);
  background-size: 45% 100%;
  background-repeat: no-repeat;
  animation: runlog-scan 1.8s var(--ease-in-out) infinite;
}

@keyframes runlog-scan {
  0%   { background-position: -50% 0; }
  100% { background-position: 150% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .app .runlog:has(.step[data-status="running"]) .runlog-head::after { animation: none; opacity: 0.6; }
}

/* One continuous spine down the badge column, drawn once on the container.
   Per-row threads left visible gaps at every row's padding, which broke the
   sequence into fragments; the badges have their own background and paint
   over this line, so it reads as a connected process tree.
   20px = the step's 12px inline padding + half the 18px badge. */
.app .runlog-steps {
  padding-block: var(--space-1);
  position: relative;
}

.app .runlog-steps::before {
  content: '';
  position: absolute;
  inset-block: 16px;
  inset-inline-start: 20px;
  inline-size: 1px;
  background: linear-gradient(to bottom,
    transparent, var(--line) 3%, var(--line) 97%, transparent);
  pointer-events: none;
}

.app .step-thread { display: none; }

/* One compact row, no divider — the spine is the sequence. */
.app .step {
  grid-template-columns: 18px 1fr;
  gap: var(--space-2);
  padding-block: 5px;
  padding-inline: var(--space-3);
  border-block-end: none;
  transition: background var(--dur-fast) var(--ease-out);
}

.app .step:hover { background: color-mix(in srgb, var(--accent) 4%, transparent); }

.app .step-rail { gap: 3px; padding-block-start: 2px; }

.app .step-badge {
  inline-size: 18px;
  block-size: 18px;
  border-radius: 5px;
  font-size: 10px;
  background: var(--role-soft, var(--surface-2));
  color: var(--role-color, var(--ink-2));
  border: 1px solid color-mix(in srgb, var(--role-color, var(--ink-3)) 22%, transparent);
}

.app .step-thread {
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--role-color, var(--line-2)) 30%, transparent),
    var(--line));
  min-block-size: 4px;
}

.app .step-head { gap: var(--space-2); row-gap: 1px; }

.app .step-name {
  font-size: var(--fs-step-msg);   /* 12px */
  font-weight: var(--fw-semi);
  line-height: 1.4;
  color: var(--ink-2);
}

/* Only the live step gets full-strength ink — that is the hierarchy. */
.app .step[data-status="running"] .step-name,
.app .step[data-status="awaiting_human_decision"] .step-name { color: var(--ink); }

/* Node id: monospace, unboxed. It is a reference, not a chip. */
.app .step .node-id {
  background: none;
  border: none;
  padding: 0;
  color: var(--ink-3);
  font-size: var(--fs-3xs);
  letter-spacing: 0.01em;
  font-variant-numeric: lining-nums tabular-nums;
}

.app .role-tag {
  font-size: var(--fs-3xs);
  color: var(--ink-4);
  padding-inline: var(--space-2) 0;
  border-inline-start: 1px solid var(--line);
}

.app .step-msg {
  font-size: var(--fs-3xs);
  color: var(--ink-3);
  line-height: 1.5;
  margin-block-start: 0;
}

/* Tools: the loudest thing on the old row, now the quietest. */
.app .step-tools { gap: 3px; margin-block-start: 3px; }

.app .step-tools-label {
  font-size: var(--fs-3xs);
  color: var(--ink-4);
}

.app .step-tools .tool-chip {
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  border: none;
  color: var(--ink-3);
  font-size: var(--fs-3xs);
  border-radius: var(--r-xs);
  padding-block: 1px;
  padding-inline: 5px;
  line-height: 1.5;
}

.app .step-picks {
  margin-block-start: 3px;
  gap: 1px;
  font-size: var(--fs-3xs);
  color: var(--ink-3);
}

.app .step-pick .dot { inline-size: 4px; block-size: 4px; }

.app .step-note {
  margin-block-start: 3px;
  padding-block: 3px;
  padding-inline: var(--space-2);
  background: color-mix(in srgb, var(--accent) 5%, transparent);
  border-inline-start: 2px solid color-mix(in srgb, var(--lum-blue) 35%, transparent);
  border-radius: var(--r-xs);
  font-size: var(--fs-3xs);
  color: var(--ink-3);
}

/* Status: a glyph and a word, sized down. Completed recedes; running and
   awaiting-decision hold their colour, so the eye lands on the live row. */
.app .step-status {
  font-size: var(--fs-3xs);
  color: var(--ink-4);
  gap: 3px;
  flex: none;
}

.app .step-status .icon { font-size: 11px; }
.app .step[data-status="running"] .step-status { color: var(--lum-blue); font-weight: var(--fw-medium); }
.app .step[data-status="awaiting_human_decision"] .step-status { color: var(--role-human); font-weight: var(--fw-medium); }

.app .step[data-status="awaiting_human_decision"] {
  background: color-mix(in srgb, var(--role-human) 6%, transparent);
}

/* An advisory opinion is a result, not a step — give it a quiet inset panel. */
.app .step-opinion .step-extra {
  margin-block-start: var(--space-2);
  padding-inline-start: var(--space-2);
  border-inline-start: 2px solid color-mix(in srgb, var(--lum-violet) 25%, transparent);
}

.app .spinner {
  inline-size: 11px;
  block-size: 11px;
  border-width: 1.5px;
  border-block-start-color: var(--role-color, var(--lum-blue));
}

.app .waiting {
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  font-size: var(--fs-3xs);
  color: var(--ink-3);
  background: color-mix(in srgb, var(--surface-2) 60%, var(--surface));
  border-block-start: 1px solid var(--line);
}

/* ── 6. messages, notices ────────────────────────────────────────────────── */
.app .msg-user .msg-body {
  background: var(--accent-soft);
  border-color: color-mix(in srgb, var(--accent) 18%, transparent);
}

.app .msg-avatar {
  background: var(--surface);
  border-color: var(--line-2);
  box-shadow: var(--sh-1);
}

.app .notice { border-radius: var(--r-md); }
.app .notice-info { background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--ink-2); }

.app .composer {
  border-radius: var(--r-lg);
  border-color: var(--line-2);
  box-shadow: var(--sh-2);
}

.app .composer:focus-within {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--line-2));
  box-shadow: var(--sh-2), 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent);
}

/* ══════════════════════════════════════════════════════════════════════════
   7. DASHBOARD — smaller cards, tighter hierarchy
   ══════════════════════════════════════════════════════════════════════════ */
.app .dash { gap: var(--space-5); }
.app .dash-scroll { padding-block: var(--space-5) var(--space-7); }

.app .dash-title { font-size: var(--fs-xl); }
.app .dash-sub { font-size: var(--fs-xs); }

.app .tiles { gap: var(--space-2); }

.app .tile {
  padding: var(--space-3);
  border-radius: var(--r-sm);
  border-color: var(--line);
  background: var(--surface);
  gap: 2px;
  box-shadow: var(--sh-1);
  transition: box-shadow var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}

.app .tile:hover {
  border-color: color-mix(in srgb, var(--accent) 28%, var(--line));
  box-shadow: var(--sh-2);
}

.app .tile-key { font-size: var(--fs-3xs); color: var(--ink-3); gap: var(--space-1); }
.app .tile-key .icon { color: var(--ink-4); font-size: 12px; }

/* The hero number stays the loudest thing in the tile, one step smaller. */
.app .tile-val {
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  letter-spacing: -0.02em;
  font-variant-numeric: lining-nums tabular-nums;
}

.app .tile-val.small { font-size: var(--fs-sm); font-weight: var(--fw-semi); }
.app .tile-note { font-size: var(--fs-3xs); color: var(--ink-4); line-height: 1.45; }

.app .section-title { font-size: var(--fs-sm); }
.app .section-title .icon { color: var(--lum-blue); }

.app .rolegrid { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: var(--space-3); }

.app .rolecard {
  border-radius: var(--r-sm);
  border-block-start-width: 2px;
  box-shadow: var(--sh-1);
}

.app .rolecard-head {
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  background: color-mix(in srgb, var(--surface-2) 70%, var(--surface));
}

.app .rolecard-icon { inline-size: 20px; block-size: 20px; font-size: 11px; }
.app .rolecard-name { font-size: var(--fs-xs); }
.app .rolecard-count { font-size: var(--fs-3xs); background: var(--surface-3); }
.app .rolecard-list { padding-block: var(--space-1); }

.app .rolecard-item {
  padding-block: 5px;
  padding-inline: var(--space-3);
  font-size: var(--fs-xs);
}

.app .rolecard-item-tools { font-size: var(--fs-3xs); color: var(--ink-4); }

.app .gatecard {
  padding: var(--space-3);
  border-radius: var(--r-sm);
  border-inline-start-width: 2px;
  box-shadow: var(--sh-1);
}

.app .gatecard-key { font-size: var(--fs-3xs); }
.app .gatecard-val { font-size: var(--fs-base); }
.app .gatecard-code { font-size: var(--fs-3xs); }

.app .toolgrid { gap: var(--space-1); }

.app .toolrow {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--r-xs);
  gap: var(--space-2);
}

.app .toolrow-name { font-size: var(--fs-3xs); min-inline-size: 10rem; color: var(--ink-2); }
.app .toolrow-users { font-size: var(--fs-3xs); color: var(--ink-4); }

.app .identity { gap: var(--space-2); }
.app .identity-item { padding: var(--space-2) var(--space-3); border-radius: var(--r-xs); }
.app .identity-key { font-size: var(--fs-3xs); }
.app .identity-val { font-size: var(--fs-xs); }

/* Distribution bars pick up the brand ramp. */
.app .dist-fill { border-radius: var(--r-xs); }
.app .dist-label { font-size: var(--fs-xs); }
.app .dist-val { font-size: var(--fs-xs); font-variant-numeric: lining-nums tabular-nums; }

/* ══════════════════════════════════════════════════════════════════════════
   8. REPORTS AND TABLES
   ══════════════════════════════════════════════════════════════════════════ */
.app .report {
  border-radius: var(--r-md);
  border-color: var(--line);
  box-shadow: var(--sh-1);
}

.app .report-head {
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--accent-soft) 50%, var(--surface)), var(--surface));
  border-block-end: 1px solid var(--line);
}

.app .report-eyebrow { font-size: var(--fs-3xs); color: var(--ink-3); letter-spacing: 0.06em; }
.app .report-title { font-size: var(--fs-lg); }
.app .report-sub { font-size: var(--fs-xs); }

.app .verdict-number {
  font-size: var(--fs-2xl);
  font-variant-numeric: lining-nums tabular-nums;
  background: linear-gradient(120deg, var(--lum-blue), var(--lum-violet));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .app .verdict-number { color: var(--ink); background: none; }
}

.app .verdict-number .of {
  font-size: var(--fs-base);
  -webkit-text-fill-color: var(--ink-3);
  color: var(--ink-3);
}

/* ── tables ──────────────────────────────────────────────────────────────── */
.app .table-wrap {
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
}

.app table { font-size: var(--fs-xs); }

/* Header: quieter fill, letterspaced label, and a solid bottom edge so the
   head reads as a rule rather than a filled band. */
.app thead th {
  background: color-mix(in srgb, var(--accent-soft) 60%, var(--surface));
  color: var(--ink-2);
  font-size: var(--fs-3xs);
  font-weight: var(--fw-semi);
  letter-spacing: 0.04em;
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  border-block-end: 1px solid var(--line-2);
  text-align: start;          /* RTL-correct: start, never left */
}

.app th,
.app td {
  padding-block: var(--space-2);
  padding-inline: var(--space-3);
  border-block-end: 1px solid color-mix(in srgb, var(--line) 80%, transparent);
  text-align: start;
}

.app tbody tr { transition: background var(--dur-fast) var(--ease-out); }
.app tbody tr:hover { background: color-mix(in srgb, var(--accent) 5%, transparent); }

/* The winning cell: a tint plus an inline-start edge, so the win survives a
   greyscale print and does not depend on colour alone. */
.app td.win {
  background: color-mix(in srgb, var(--ok) 9%, transparent);
  box-shadow: inset 2px 0 0 0 var(--ok);
}

:root[dir="rtl"] .app td.win { box-shadow: inset -2px 0 0 0 var(--ok); }

.app .cell-strong { font-weight: var(--fw-semi); color: var(--ink); }

/* Every numeric run in a table: Latin lining digits, tabular so columns line
   up. This never switches the numbering system — it only picks the lining,
   fixed-width forms of the same Latin digits. */
.app td,
.app .num,
.app .scorebar-value,
.app .tile-val,
.app .dist-val {
  font-variant-numeric: lining-nums tabular-nums;
}

/* ── score bars ──────────────────────────────────────────────────────────── */
.app .scorebar { gap: var(--space-2); }
.app .scorebar-label { font-size: var(--fs-xs); }

.app .scorebar-track {
  block-size: 7px;
  background: var(--surface-3);
  border-radius: var(--r-full);
}

.app .scorebar-fill {
  background: linear-gradient(90deg, var(--lum-blue), var(--lum-cyan));
  border-radius: var(--r-full);
}

:root[dir="rtl"] .app .scorebar-fill {
  background: linear-gradient(270deg, var(--lum-blue), var(--lum-cyan));
}

.app .scorebar-value {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  color: var(--ink);
}

/* ── PASS / FAIL and status pills ───────────────────────────────────────── */
.app .pill {
  font-size: var(--fs-3xs);
  font-weight: var(--fw-semi);
  padding-block: 2px;
  padding-inline: var(--space-2);
  letter-spacing: 0.01em;
}

.app .pill .icon { font-size: 11px; }

.app .pill-ok {
  background: var(--ok-soft);
  color: var(--ok);
  border-color: color-mix(in srgb, var(--ok) 28%, transparent);
}

.app .pill-crit {
  background: var(--crit-soft);
  color: var(--crit);
  border-color: color-mix(in srgb, var(--crit) 30%, transparent);
}

.app .pill-warn {
  background: var(--warn-soft);
  color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 30%, transparent);
}

.app .pill-mute { background: var(--surface-2); color: var(--ink-3); border-color: var(--line); }

.app .evidence-file,
.app .tool-chip {
  font-variant-numeric: lining-nums tabular-nums;
}

.app .trace-row-quote { font-size: var(--fs-3xs); }

.app tr.unverified td { background: var(--crit-soft); }

.app .finding-callout { border-radius: var(--r-sm); }

/* ── gate options ────────────────────────────────────────────────────────── */
.app .gate-option {
  border-radius: var(--r-sm);
  transition: border-color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}

.app .gate-option:hover {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line-2));
  background: var(--accent-soft);
  box-shadow: var(--sh-1);
}

/* ── 9. responsive — the internal block's own overrides ──────────────────── */
@media (max-width: 900px) {
  /* Three columns collapse to two: the mark would otherwise squeeze the
     English lockup off its own baseline on a narrow header. */
  .app .titlebar { grid-template-columns: 1fr auto; row-gap: var(--space-2); }
  .app .title-ar { grid-column: 1; }
  .app .topbar-mark { grid-column: 2; }
  .app .title-en { grid-column: 1 / -1; justify-self: start; }
}

@media (max-width: 620px) {
  .app .topbar-mark { inline-size: 38px; block-size: 38px; border-radius: 11px; }
  .app .topbar-mark svg { inline-size: 23px; block-size: 23px; }
  .app .chat-net { opacity: 0.5; }

  /* Step padding drops to 8px here, so the spine follows: 8 + 9 = 17. */
  .app .step { padding-inline: var(--space-2); }
  .app .runlog-steps::before { inset-inline-start: 16px; }
  .app .tile { padding: var(--space-2) var(--space-3); }
}

/* ── 10. print ───────────────────────────────────────────────────────────── */
@media print {
  .app .chat-net,
  .app .topbar::after { display: none !important; }
  .app .runlog-head::after { display: none !important; }
}
