/* ============================================================================
   Cake IdP demo-web — layout & components. SEMANTIC TOKENS ONLY.
   No raw hex here: every color/spacing pulls from tokens.css var(--*).
   Left device = theme-aware. Right console = always-dark (--console-*).
============================================================================ */

*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font: var(--body-s);
  color: var(--fg-primary);
  background: var(--bg-surface-secondary);
  -webkit-font-smoothing: antialiased;
}
button { font-family: var(--font-sans); cursor: pointer; }
:focus-visible { outline: 2px solid var(--fg-brand); outline-offset: 2px; border-radius: 6px; }

.app-shell {
  height: 100%;
  display: grid;
  grid-template-rows: auto auto 1fr;
  min-height: 100vh;
}

/* ============================ TOP BAR ============================ */
.topbar {
  display: flex; align-items: center; gap: 16px;
  padding: 10px 18px;
  background: var(--bg-surface-primary);
  border-bottom: 1px solid var(--border-secondary);
}
.brand { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.brand-mark { font-size: 22px; }
.brand-sub { font: var(--caption-m-subtle); color: var(--fg-secondary); white-space: nowrap; }

.role-tabs {
  display: flex; gap: 4px; margin: 0 auto;
  background: var(--bg-surface-secondary);
  padding: 4px; border-radius: var(--radius-tab);
}
.role-tab {
  border: 0; background: transparent; color: var(--fg-secondary);
  font: var(--title-xs); padding: 7px 16px; border-radius: 9px;
  transition: color var(--dur) var(--ease-out), background var(--dur) var(--ease-out);
}
.role-tab:hover { color: var(--fg-primary); }
.role-tab.is-active {
  background: var(--bg-surface-primary);
  color: var(--fg-brand);
  box-shadow: var(--shadow-card);
}

.topbar-right { display: flex; align-items: center; gap: 8px; }
.theme-toggle {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--border-primary); background: var(--bg-surface-secondary);
  color: var(--fg-primary); border-radius: var(--radius-pill);
  padding: 6px 12px 6px 8px; font: var(--caption-m);
}
.theme-dot {
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--gradient-primary);
  box-shadow: inset 0 0 0 2px var(--bg-surface-primary);
}

/* buttons (shared) */
.btn-primary, .btn-secondary, .btn-ghost {
  border-radius: var(--radius-pill); font: var(--title-xs); padding: 8px 16px; border: 1px solid transparent;
  transition: transform var(--dur) var(--ease-out), background var(--dur) var(--ease-out);
}
.btn-primary { background: var(--bg-brand); color: var(--fg-inverse); }
.btn-primary:hover { background: var(--bg-brand-pressed); }
.btn-primary:active { transform: translateY(1px); }
.btn-primary:disabled { background: var(--disabled-bg); color: var(--disabled-fg); cursor: not-allowed; }
.btn-secondary { background: var(--bg-surface-secondary); color: var(--fg-primary); border-color: var(--border-primary); }
.btn-secondary:hover { border-color: var(--border-brand); color: var(--fg-brand); }
.btn-ghost { background: transparent; color: var(--fg-secondary); }
.btn-ghost:hover { color: var(--fg-brand); background: var(--bg-brand-subtle); }
.btn-ghost.sm { padding: 4px 10px; font: var(--caption-m); }

/* ============================ SCENARIO BAR ============================ */
.scenario-bar {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  padding: 10px 18px;
  background: var(--bg-surface-primary);
  border-bottom: 1px solid var(--border-secondary);
}
.scenario-picker { display: flex; gap: 6px; }
.scn-pill {
  border: 1px solid var(--border-primary); background: transparent;
  color: var(--fg-secondary); border-radius: var(--radius-pill);
  padding: 5px 12px; font: var(--caption-m);
}
.scn-pill.is-active { background: var(--bg-brand-subtle); color: var(--fg-brand); border-color: var(--border-brand); }

.stepper { display: flex; align-items: center; gap: 0; margin: 0; padding: 0; list-style: none; flex: 1 1 320px; min-width: 0; overflow-x: auto; }
.step {
  display: flex; align-items: center; gap: 8px; padding: 4px 6px; white-space: nowrap;
  color: var(--fg-tertiary);
}
.step .step-num {
  width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center;
  background: var(--bg-surface-secondary); color: var(--fg-secondary);
  font: var(--caption-m); border: 1px solid var(--border-secondary);
}
.step .step-label { font: var(--caption-m-subtle); }
.step.done .step-num { background: var(--bg-success-subtle); color: var(--fg-success); border-color: transparent; }
.step.active { color: var(--fg-brand); }
.step.active .step-num { background: var(--bg-brand); color: var(--fg-inverse); border-color: transparent; }
.step.active .step-label { font: var(--caption-m); color: var(--fg-brand); }
.step-sep { width: 18px; height: 1px; background: var(--border-primary); flex: none; }

.scenario-controls { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.mock-badge {
  font: var(--caption-s); letter-spacing: .08em; color: var(--fg-warning);
  background: var(--bg-warning-subtle); border: 1px solid var(--bg-warning);
  padding: 3px 8px; border-radius: var(--radius-pill);
}
.conn-badge {
  font: var(--caption-m); font-family: var(--font-mono);
  padding: 4px 10px; border-radius: var(--radius-pill);
  border: 1px solid var(--border-primary); color: var(--fg-secondary);
}
.conn-badge[data-state="on"]  { color: var(--fg-success); border-color: var(--bg-success); }
.conn-badge[data-state="mock"]{ color: var(--fg-warning); border-color: var(--bg-warning); }
.conn-badge[data-state="err"] { color: var(--fg-danger); border-color: var(--bg-danger); }

/* ============================ SPLIT ============================ */
.split {
  /* M5.1 diagram-first: LEFT = interactive device (compact); RIGHT = the STAGE
     (live architecture diagram as focal + storytelling + collapsible console). */
  display: grid; grid-template-columns: minmax(300px, 340px) minmax(0, 1fr);
  gap: 20px; padding: 20px; min-height: 0;
}
.stage-left { display: flex; flex-direction: column; align-items: center; gap: 14px; min-width: 0; }
.scenario-caption {
  align-self: stretch; background: var(--bg-surface-primary);
  border: 1px solid var(--border-secondary); border-radius: var(--radius-16);
  padding: 12px 14px; font: var(--body-s); color: var(--fg-primary);
  box-shadow: var(--shadow-card);
}
.scenario-caption .cap-map {
  display: inline-block; margin-top: 6px; font: var(--caption-m); font-family: var(--font-mono);
  color: var(--fg-info); background: var(--bg-info-subtle); padding: 2px 8px; border-radius: 8px;
}

/* device frame — theme-aware (follows [data-theme]) */
.device {
  position: relative; width: min(393px, 100%);
  aspect-ratio: 393 / 760; max-height: calc(100vh - 220px);
  background: var(--app-bg);
  border: 10px solid var(--grey-1000);
  border-radius: 46px;
  box-shadow: var(--shadow-island);
  overflow: hidden; flex: none;
}
[data-theme="dark"] .device { border-color: var(--grey-1000); }
.device-notch {
  position: absolute; top: 8px; left: 50%; transform: translateX(-50%);
  width: 120px; height: 22px; background: var(--grey-1000); border-radius: 0 0 14px 14px; z-index: 5;
}
.device-home {
  position: absolute; bottom: 7px; left: 50%; transform: translateX(-50%);
  width: 120px; height: 4px; border-radius: 100px; background: var(--fg-tertiary); opacity: .5; z-index: 5;
}
.device-screen {
  position: absolute; inset: 0;
  overflow-y: auto; padding: 40px 16px 26px;
  background: var(--app-bg); color: var(--fg-primary);
}

/* ---- device UI primitives (VN-first) ---- */
.d-statusbar { display: flex; justify-content: space-between; font: var(--caption-m); color: var(--fg-secondary); margin-bottom: 12px; }
.d-appbar { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.d-appicon { width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center; font-size: 20px; background: var(--bg-brand-subtle); }
.d-title { font: var(--title-l); letter-spacing: -.25px; }
.d-sub { font: var(--body-xs); color: var(--fg-secondary); }
.d-card {
  background: var(--bg-surface-primary); border: 1px solid var(--border-secondary);
  border-radius: var(--radius-card); padding: 16px; margin-bottom: 12px; box-shadow: var(--shadow-card);
}
.d-card.flat { box-shadow: none; }
.d-label { font: var(--caption-m); color: var(--fg-secondary); display: block; margin-bottom: 6px; }
.d-field {
  width: 100%; border: 1px solid var(--border-primary); background: var(--bg-surface-secondary);
  color: var(--fg-primary); border-radius: var(--radius-16); padding: 11px 12px; font: var(--body-s); margin-bottom: 12px;
}
.d-cta { width: 100%; border: 0; background: var(--bg-brand); color: var(--fg-inverse); font: var(--title-s); padding: 13px; border-radius: var(--radius-pill); }
.d-cta:disabled { background: var(--disabled-bg); color: var(--disabled-fg); }
.d-cta.secondary { background: var(--bg-surface-secondary); color: var(--fg-primary); border: 1px solid var(--border-primary); }
.d-pill { display: inline-flex; align-items: center; gap: 6px; font: var(--caption-m); padding: 4px 10px; border-radius: var(--radius-pill); }
.d-pill.info { background: var(--bg-info-subtle); color: var(--fg-info); }
.d-pill.warn { background: var(--bg-warning-subtle); color: var(--fg-warning); }
.d-pill.ok   { background: var(--bg-success-subtle); color: var(--fg-success); }
.d-pill.danger { background: var(--bg-danger-subtle); color: var(--fg-danger); }
.d-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border-tertiary); }
.d-row:last-child { border-bottom: 0; }
.d-amount { font: var(--display-x); letter-spacing: -1px; }
.d-amount .cur { color: var(--amount-currency); font-weight: 600; }
.d-secret { font-family: var(--font-mono); font-size: 13px; word-break: break-all; background: var(--bg-surface-secondary); padding: 10px; border-radius: 10px; border: 1px dashed var(--border-primary); }
.d-note { font: var(--body-xs); color: var(--fg-secondary); margin: 8px 0 0; }
.d-scope { display: flex; align-items: flex-start; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border-tertiary); }
.d-scope:last-child { border-bottom: 0; }
.d-check { width: 22px; height: 22px; border-radius: var(--radius-check); border: 2px solid var(--border-primary); flex: none; display: grid; place-items: center; margin-top: 1px; }
.d-check.on { background: var(--bg-brand); border-color: var(--bg-brand); color: var(--fg-inverse); }
.d-banner { border-radius: var(--radius-16); padding: 11px 12px; font: var(--body-s); margin-bottom: 12px; display: flex; gap: 8px; }
.d-banner.danger { background: var(--bg-danger-subtle); color: var(--fg-danger); }
.d-banner.info { background: var(--bg-info-subtle); color: var(--fg-info); }
.d-sheet {
  position: absolute; left: 0; right: 0; bottom: 0; background: var(--bg-surface-primary);
  border-radius: var(--radius-card) var(--radius-card) 0 0; box-shadow: var(--shadow-sheet);
  padding: 8px 16px 20px; z-index: 4;
}
.d-sheet .grabber { width: 40px; height: 4px; background: var(--fg-tertiary); opacity: .5; border-radius: 100px; margin: 6px auto 12px; }
.d-empty { text-align: center; color: var(--fg-tertiary); font: var(--body-s); padding: 30px 0; }
.d-seg { display: flex; gap: 4px; background: var(--bg-surface-secondary); padding: 4px; border-radius: var(--radius-tab); margin-bottom: 14px; }
.d-seg button { flex: 1; border: 0; background: transparent; color: var(--fg-secondary); font: var(--title-xs); padding: 7px; border-radius: 9px; }
.d-seg button.on { background: var(--bg-surface-primary); color: var(--fg-brand); box-shadow: var(--shadow-card); }
.step-glow { animation: glow 1.2s var(--ease-out); }
@keyframes glow { 0% { box-shadow: 0 0 0 0 var(--bg-brand-subtle); } 40% { box-shadow: 0 0 0 4px var(--bg-brand-subtle); } 100% { box-shadow: var(--shadow-card); } }

/* ============================ CONSOLE (ALWAYS DARK) ============================ */
.stage-right { min-width: 0; display: flex; }
.console {
  flex: 1; display: flex; flex-direction: column; min-width: 0;
  background: var(--console-bg); color: var(--console-fg);
  border: 1px solid var(--console-border); border-radius: 16px; overflow: hidden;
  font-family: var(--font-mono);
}
.console-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 14px; background: var(--console-surface); border-bottom: 1px solid var(--console-border);
}
.console-title { display: flex; align-items: center; gap: 7px; min-width: 0; }
.console-title .dot { width: 11px; height: 11px; border-radius: 50%; background: var(--console-fg-faint); }
.console-title .dot.amber { background: var(--badge-5xx-fg); }
.console-title .dot.green { background: var(--badge-2xx-fg); }
.console-name { margin-left: 8px; color: var(--console-fg-dim); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.console-tools { display: flex; align-items: center; gap: 12px; color: var(--console-fg-dim); font-size: 12px; }
.autoscroll { display: inline-flex; align-items: center; gap: 5px; }
.console-tools .btn-ghost { color: var(--console-fg-dim); }
.console-tools .btn-ghost:hover { color: var(--console-accent); background: transparent; }

.introspect-sticky {
  display: inline-flex; align-items: center; gap: 6px; font-size: 11px;
  background: var(--console-surface-2); border: 1px solid var(--console-border);
  padding: 3px 8px; border-radius: var(--radius-pill);
}
.isp-label { color: var(--console-fg-dim); }
.isp-badge { color: var(--badge-2xx-fg); font-weight: 600; }
.isp-badge[data-state="inactive"] { color: var(--badge-4xx-fg); }
.isp-count { color: var(--console-fg); font-variant-numeric: tabular-nums; }

.log-list { flex: 1; overflow-y: auto; padding: 8px; }
/* empty-state: shown only while the console has 0 events (:empty), auto-hides on first appended row */
.log-list:empty { display: flex; align-items: center; justify-content: center; }
.log-list:empty::after { content: "Thao tác ở màn bên trái — mỗi hành động sinh 1 sự kiện tại đây"; color: var(--console-fg-dim); font-size: 12px; font-family: var(--font-mono); text-align: center; padding: 24px; max-width: 260px; }

.evt {
  border: 1px solid var(--console-border); border-radius: 10px; margin-bottom: 6px;
  background: var(--console-surface); overflow: hidden;
  transition: background var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}
/* system note (session-restore line) — muted, non-interactive, no status accent */
.evt.sys { background: var(--console-surface-2); border-style: dashed; }
.evt.sys .evt-head { cursor: default; }
.evt.sys .evt-head:hover { background: transparent; }
.evt.sys .evt-call { color: var(--console-fg-dim); font-style: italic; }
.evt-head { display: flex; align-items: center; gap: 10px; padding: 9px 11px; cursor: pointer; }
.evt-head:hover { background: var(--console-surface-2); }
.evt-seq { color: var(--console-fg-faint); font-size: 11px; width: 26px; flex: none; text-align: right; }
.role-chip {
  font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: var(--radius-pill); flex: none;
  color: var(--role-color, var(--console-fg)); background: color-mix(in srgb, var(--role-color, var(--console-fg-dim)) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--role-color, var(--console-fg-dim)) 40%, transparent);
}
.evt-service { color: var(--console-fg-dim); font-size: 11px; flex: none; }
.evt-call { color: var(--console-fg); font-size: 12px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.evt-call .method { color: var(--console-accent); font-weight: 600; margin-right: 6px; }
.badge {
  font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: var(--radius-pill); flex: none; font-variant-numeric: tabular-nums;
}
.badge.s2xx { color: var(--badge-2xx-fg); background: var(--badge-2xx-bg); }
.badge.s4xx { color: var(--badge-4xx-fg); background: var(--badge-4xx-bg); }
.badge.s5xx { color: var(--badge-5xx-fg); background: var(--badge-5xx-bg); }
.evt-dur { color: var(--console-fg-faint); font-size: 11px; flex: none; font-variant-numeric: tabular-nums; width: 52px; text-align: right; }
.evt-caret { color: var(--console-fg-faint); flex: none; transition: transform var(--dur); }
.evt.open .evt-caret { transform: rotate(90deg); }

.evt-body { display: none; padding: 0 11px 11px 11px; border-top: 1px solid var(--console-border); }
.evt.open .evt-body { display: block; }
.evt-note { color: var(--console-fg-dim); font-size: 11px; margin: 9px 0; }
.kv-title { color: var(--console-fg-faint); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; margin: 10px 0 4px; }
pre.json { margin: 0; font-family: var(--font-mono); font-size: 12px; line-height: 1.55; color: var(--console-fg); background: var(--console-bg); border: 1px solid var(--console-border); border-radius: 8px; padding: 9px 11px; overflow-x: auto; white-space: pre; }
.json .k { color: var(--role-cake-auth); }
.json .s { color: var(--badge-2xx-fg); }
.json .n { color: var(--role-portal-admin); }
.json .b { color: var(--role-cn-portal); }
.json .nul { color: var(--console-fg-faint); }
.redacted { color: var(--badge-5xx-fg); }
.jwt { display: grid; gap: 8px; }
.jwt-part { border: 1px solid var(--console-border); border-radius: 8px; padding: 8px 10px; background: var(--console-bg); }
.jwt-part h5 { margin: 0 0 5px; font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--console-fg-faint); }
.jwt-sig { color: var(--badge-5xx-fg); font-size: 11px; }
.evt.flash { animation: flash 1.4s var(--ease-out); }
@keyframes flash { 0%,20% { border-color: var(--console-accent); background: color-mix(in srgb, var(--console-accent) 12%, var(--console-surface)); } 100% { border-color: var(--console-border); background: var(--console-surface); } }

.result-dock { border-top: 1px solid var(--console-border); background: var(--console-surface); padding: 12px 14px; }
.result-dock h4 { margin: 0 0 8px; font-size: 12px; color: var(--console-accent); letter-spacing: .04em; text-transform: uppercase; }
.result-ac { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--console-fg); padding: 3px 0; }
.result-ac .tick { color: var(--badge-2xx-fg); }
.result-ac .cross { color: var(--badge-4xx-fg); }

/* ============================ MAPPING OVERLAY ============================ */
.overlay { position: fixed; inset: 0; background: var(--bg-overlay); display: grid; place-items: center; padding: 24px; z-index: 50; }
/* hidden guard: attr-selector (0,1,1) beats .overlay (0,1,0) so [hidden] wins over display:grid — no !important. Overlay is OFF on load. */
.overlay[hidden] { display: none; }
.overlay-card { width: min(880px, 100%); max-height: 88vh; overflow-y: auto; background: var(--bg-surface-primary); border-radius: var(--radius-card); padding: 22px; box-shadow: var(--shadow-card); }
.overlay-head { display: flex; align-items: center; justify-content: space-between; }
.overlay-sub { color: var(--fg-secondary); font: var(--body-s); margin: 6px 0 16px; }
.map-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.map-item { border: 1px solid var(--border-secondary); border-radius: var(--radius-16); padding: 14px; }
.map-item .m-top { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.map-item .m-local { font: var(--title-xs); color: var(--fg-primary); }
.map-item .m-arrow { color: var(--fg-tertiary); }
.map-item .m-prod { font: var(--title-xs); color: var(--fg-brand); }
.map-item .m-ep { font-family: var(--font-mono); font-size: 11px; color: var(--fg-secondary); background: var(--bg-surface-secondary); padding: 2px 6px; border-radius: 6px; display: inline-block; margin-bottom: 8px; }
.map-item .m-note { font: var(--body-xs); color: var(--fg-secondary); margin: 0; }
.map-item .m-contract { list-style: none; margin: 8px 0 0; padding: 0; }
.map-item .m-contract li { font-family: var(--font-mono); font-size: 10px; color: var(--fg-tertiary); padding: 1px 0; }

/* ============================ RESPONSIVE ============================ */
/* Tablet portrait (820) + phones (430/393): stack device over console */
@media (max-width: 1024px) {
  .split { grid-template-columns: 1fr; grid-auto-rows: min-content; }
  .device { max-height: none; }
  .stage-right { min-height: 60vh; }
  .map-grid { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .topbar { flex-wrap: wrap; gap: 10px; padding: 10px 12px; }
  .role-tabs { order: 3; width: 100%; margin: 0; justify-content: space-between; }
  .role-tab { flex: 1; padding: 7px 4px; text-align: center; }
  .brand-sub { display: none; }
  .scenario-bar { padding: 10px 12px; gap: 12px; }
  .scenario-controls { width: 100%; }
  .split { padding: 12px; gap: 14px; }
  .stepper { order: 3; width: 100%; }
}

/* ============================ SESSION BAR (free-interaction) ============================ */
.sess-info { display: flex; align-items: center; gap: 10px; min-width: 0; flex: 1; }
.sess-tag { font: var(--caption-s); text-transform: uppercase; letter-spacing: .1em; color: var(--fg-tertiary); }
.sess-id { font-family: var(--font-mono); font-size: 12px; color: var(--fg-brand); background: var(--bg-brand-subtle); padding: 3px 8px; border-radius: 8px; }
.sess-note { font: var(--caption-m-subtle); color: var(--fg-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ============================ CONSOLE — 6-SECTION EVENT FRAME (always dark) ============================ */
.sec { border-top: 1px solid var(--console-border); margin-top: 8px; padding-top: 8px; }
.sec:first-of-type { border-top: 0; margin-top: 4px; }
.sec-h { font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--console-accent); margin-bottom: 6px; font-weight: 600; }
.sec-na .sec-h { color: var(--console-fg-faint); }
.sec-b { color: var(--console-fg); }
.sec-b.na, .na.inline { color: var(--console-fg-faint); font-style: italic; font-size: 11px; }
.na.inline { display: block; padding: 2px 0 4px; }

.kvlist { display: grid; gap: 2px; margin-bottom: 4px; }
.kvrow { display: flex; gap: 10px; font-size: 12px; }
.kk { color: var(--console-fg-dim); min-width: 84px; flex: none; }
.vv { color: var(--console-fg); word-break: break-all; }
.vv .dim, .dim { color: var(--console-fg-faint); }
.mono { font-family: var(--font-mono); }

/* DB-EVIDENCE table: expected | actual + match badge */
.dbtab { width: 100%; border-collapse: collapse; font-size: 11px; }
.dbtab th { text-align: left; color: var(--console-fg-faint); font-weight: 600; padding: 3px 6px; border-bottom: 1px solid var(--console-border); }
.dbtab td { padding: 4px 6px; border-bottom: 1px solid var(--console-border); vertical-align: top; color: var(--console-fg); }
.dbtab td.mono { font-family: var(--font-mono); }
.dbtab .mtick { color: var(--badge-2xx-fg); font-weight: 700; text-align: center; }
.dbtab .mcross { color: var(--badge-4xx-fg); font-weight: 700; text-align: center; }
.dbtab .dim.mono { font-size: 10px; }

/* SERVICE-LOGS: mono lines */
.loglines { display: grid; gap: 2px; }
.logline { font-family: var(--font-mono); font-size: 11px; color: var(--console-fg); white-space: pre-wrap; word-break: break-word; }
.logline .svc { color: var(--role-cake-auth); }

/* ============================ F7/F9 device additions ============================ */
.d-seg.sm3 button { font: var(--caption-m); padding: 6px 4px; }
.d-linkbtn { background: none; border: 0; color: var(--fg-info); font: var(--caption-m); padding: 4px 0; text-decoration: underline; cursor: pointer; }
.d-linkbtn:hover { color: var(--fg-brand); }
.d-audit { background: var(--bg-surface-secondary); border-radius: var(--radius-16); padding: 8px 10px; margin: 4px 0 8px; }
.d-auditrow { padding: 4px 0; border-bottom: 1px solid var(--border-tertiary); font: var(--caption-m); }
.d-auditrow:last-child { border-bottom: 0; }
.d-auditrow .a-ok { color: var(--fg-success); font-weight: 600; }
.d-auditrow .a-rej { color: var(--fg-danger); font-weight: 600; }

/* ============================ console: service tag + step subtitle ============================ */
.svc-tag {
  font-size: 11px; padding: 2px 7px; border-radius: var(--radius-pill); flex: none;
  color: var(--svc-color, var(--console-fg-dim));
  background: color-mix(in srgb, var(--svc-color, var(--console-fg-dim)) 14%, transparent);
}
.evt-step { padding: 2px 11px 6px 11px; color: var(--console-fg-dim); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.evt.open .evt-step { white-space: normal; }

/* ============================ F10 architecture diagram (overlay) ============================ */
.overlay-card.wide { width: min(960px, 100%); }
.diag { display: flex; flex-direction: column; align-items: stretch; gap: 6px; }
.diag-note { color: var(--fg-warning); background: var(--bg-warning-subtle); border-radius: var(--radius-16); padding: 8px 12px; font: var(--caption-m); margin-bottom: 8px; }
.lane { background: var(--bg-surface-secondary); border: 1px solid var(--border-secondary); border-radius: var(--radius-16); padding: 12px; display: flex; gap: 10px; flex-wrap: wrap; }
.lane.cols { justify-content: space-between; }
.lane-h { flex-basis: 100%; font: var(--caption-m); text-transform: uppercase; letter-spacing: .08em; color: var(--fg-tertiary); margin-bottom: 2px; }
.flow { text-align: center; color: var(--fg-tertiary); font-size: 16px; line-height: 1; }
.anode {
  position: relative; flex: 1 1 180px; min-width: 150px;
  background: var(--bg-surface-primary); border: 1px solid var(--border-primary); border-radius: var(--radius-16);
  padding: 12px 12px 10px; transition: box-shadow var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.anode.live { border-color: var(--border-brand); box-shadow: 0 0 0 3px var(--bg-brand-subtle); transform: translateY(-2px); }
/* M1/M2 — EVENT-driven highlight. is-active = persistent trail for the current run
   (accent border + subtle pink ring, never a bg wash). pulse = one-shot per-step
   motion (@keyframes, ≥150ms) driven by requestAnimation of the class, removed by a
   setTimeout — no setInterval-animate. */
.anode.is-active { border-color: var(--border-brand); box-shadow: 0 0 0 2px var(--bg-brand-subtle); }
.anode.pulse { animation: nodepulse 700ms var(--ease-out); }
@keyframes nodepulse {
  0%   { box-shadow: 0 0 0 0 var(--bg-brand-subtle); transform: translateY(0); }
  35%  { box-shadow: 0 0 0 8px color-mix(in srgb, var(--pink-500) 22%, transparent); transform: translateY(-3px); }
  100% { box-shadow: 0 0 0 2px var(--bg-brand-subtle); transform: translateY(0); }
}
.anode .n-ic { font-size: 20px; }
.anode .n-title { font: var(--title-xs); color: var(--fg-primary); margin-top: 2px; }
.anode .n-sub { font: var(--caption-m-subtle); color: var(--fg-secondary); }
.anode .n-prod { font: var(--caption-s); color: var(--fg-brand); margin-top: 4px; }
.anode .n-boundary { display: inline-block; margin-top: 6px; font: var(--caption-s); color: var(--fg-warning); background: var(--bg-warning-subtle); padding: 1px 6px; border-radius: 6px; }
.n-dot { position: absolute; top: 12px; right: 12px; width: 9px; height: 9px; border-radius: 50%; }
.n-dot.up { background: var(--bg-success); box-shadow: 0 0 0 3px var(--bg-success-subtle); }
.n-dot.down { background: var(--disabled-fg); }
.diag-legend { margin-top: 12px; font: var(--caption-m); color: var(--fg-secondary); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.diag-legend .n-dot { position: static; }
.diag-legend .n-boundary { display: inline-block; font: var(--caption-s); color: var(--fg-warning); background: var(--bg-warning-subtle); padding: 1px 6px; border-radius: 6px; }
.diag-legend .lg-active { color: var(--fg-brand); border-bottom: 2px solid var(--border-brand); }

/* ---- M3 demo-visualizer overlay: tabs + in-overlay scenario runner ---- */
.ov-run { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-left: auto; }
.ovr-tag { font: var(--caption-s); text-transform: uppercase; letter-spacing: .08em; color: var(--fg-tertiary); }
.ovr-btn { border: 1px solid var(--border-primary); background: var(--bg-surface-secondary); color: var(--fg-secondary); border-radius: var(--radius-pill); padding: 4px 10px; font: var(--caption-s); cursor: pointer; transition: color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out), background var(--dur) var(--ease-out); }
.ovr-btn:hover { color: var(--fg-brand); border-color: var(--border-brand); }
.ovr-btn.on { color: var(--fg-brand); border-color: var(--border-brand); background: var(--bg-brand-subtle); }
.ovr-btn.reset { color: var(--fg-tertiary); }
.ov-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border-tertiary); margin: 4px 0 14px; }
.ov-tab { border: 0; background: transparent; color: var(--fg-secondary); padding: 8px 14px; font: var(--title-xs); cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; transition: color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out); }
.ov-tab:hover { color: var(--fg-primary); }
.ov-tab.is-active { color: var(--fg-brand); border-bottom-color: var(--border-brand); }
.ov-panel[hidden] { display: none; }
.ov-todo { color: var(--fg-tertiary); font: var(--caption-m); padding: 24px; text-align: center; }

/* ---- M3 DB-view (3 real tables) ---- */
.dbview { display: flex; flex-direction: column; gap: 16px; }
.dbt { border: 1px solid var(--border-secondary); border-radius: var(--radius-16); overflow: hidden; background: var(--bg-surface-primary); }
.dbt-h { display: flex; align-items: baseline; gap: 8px; padding: 10px 12px; background: var(--bg-surface-secondary); border-bottom: 1px solid var(--border-secondary); }
.dbt-h .dbt-name { font: var(--title-xs); color: var(--fg-primary); }
.dbt-h .dbt-src { font: var(--caption-s); color: var(--fg-tertiary); margin-left: auto; }
.dbt table { width: 100%; border-collapse: collapse; font: var(--caption-m); }
.dbt th { text-align: left; padding: 7px 12px; color: var(--fg-tertiary); font: var(--caption-s); text-transform: uppercase; letter-spacing: .05em; border-bottom: 1px solid var(--border-tertiary); }
.dbt td { padding: 7px 12px; border-bottom: 1px solid var(--border-tertiary); color: var(--fg-secondary); font-variant-numeric: tabular-nums; }
.dbt td.mono { font-family: var(--font-mono, ui-monospace, monospace); color: var(--fg-primary); }
.dbt tr:last-child td { border-bottom: 0; }
.dbt .db-empty { padding: 14px 12px; color: var(--fg-tertiary); font: var(--caption-m); }
.dbt .revoked { color: var(--badge-4xx-fg); }
.dbt .active-yes { color: var(--badge-2xx-fg); }
/* changed-field highlight — one-shot pink flash driven by db_evidence (accent-only) */
.dbt td.changed { animation: dbflash 1.2s var(--ease-out); }
@keyframes dbflash {
  0%,25% { background: color-mix(in srgb, var(--pink-500) 22%, transparent); }
  100%   { background: transparent; }
}

/* ---- M4 mapping cards (demo ↔ prod) ---- */
.mapcards { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px; }
.mapcard { border: 1px solid var(--border-secondary); border-radius: var(--radius-16); background: var(--bg-surface-primary); padding: 14px; position: relative; }
.mapcard .mc-h { display: flex; align-items: center; gap: 8px; }
.mapcard .mc-name { font: var(--title-xs); color: var(--fg-primary); }
.mapcard .mc-dot { width: 9px; height: 9px; border-radius: 50%; margin-left: auto; }
.mapcard .mc-dot.up { background: var(--bg-success); box-shadow: 0 0 0 3px var(--bg-success-subtle); }
.mapcard .mc-dot.down { background: var(--badge-4xx-fg); }
.mapcard .mc-map { display: flex; align-items: center; gap: 8px; margin: 10px 0 6px; font: var(--caption-m); }
.mapcard .mc-local { color: var(--fg-secondary); }
.mapcard .mc-arrow { color: var(--fg-brand); font-weight: 700; }
.mapcard .mc-prod { color: var(--fg-primary); font-weight: 600; }
.mapcard .mc-assert { font: var(--caption-s); color: var(--fg-brand); background: var(--bg-brand-subtle); border-radius: 8px; padding: 3px 8px; display: inline-block; margin: 4px 0 8px; }
.mapcard .mc-note { font: var(--caption-m); color: var(--fg-secondary); margin-bottom: 8px; }
.mapcard .mc-contract { font: var(--caption-s); color: var(--fg-tertiary); }
.mapcard .mc-contract code { font-family: var(--font-mono, ui-monospace, monospace); color: var(--fg-secondary); }

/* ============================================================================
   P1 — prerequisite gating + guided coach. Semantic tokens only.
============================================================================ */
/* guided coach launcher (in the session bar) */
.guided { flex-basis: 100%; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border-tertiary); }
.guided-tag { font: var(--caption-s); text-transform: uppercase; letter-spacing: 0.08em; color: var(--fg-tertiary); }
.guided-btn { border: 1px solid var(--border-primary); background: var(--bg-surface-secondary); color: var(--fg-secondary); border-radius: var(--radius-pill); padding: 5px 12px; font: var(--caption-m); transition: color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out); }
.guided-btn:hover { color: var(--fg-brand); border-color: var(--border-brand); }
.guided-btn.on { background: var(--bg-brand-subtle); color: var(--fg-brand); border-color: var(--border-brand); }

/* coach panel (rendered in the left hint strip) */
.g-head { font: var(--title-xs); color: var(--fg-primary); }
.g-dots { display: flex; gap: 6px; margin: 8px 0; flex-wrap: wrap; }
.g-dot { width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; font: var(--caption-s); background: var(--bg-surface-secondary); color: var(--fg-tertiary); border: 1px solid var(--border-secondary); }
.g-dot.done { background: var(--bg-success-subtle); color: var(--fg-success); border-color: transparent; }
.g-dot.cur { background: var(--bg-brand); color: var(--fg-inverse); border-color: transparent; }
.g-body { font: var(--body-s); color: var(--fg-primary); margin: 6px 0 10px; }
.g-body .g-sub { font: var(--caption-m); color: var(--fg-secondary); margin-top: 4px; }
.g-err { font: var(--caption-m); color: var(--fg-danger); background: var(--bg-danger-subtle); padding: 6px 10px; border-radius: 10px; margin-bottom: 8px; }
.g-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.g-actions .d-cta { width: auto; flex: 1; padding: 10px; }

/* C1 — security-reject scenario row + reject-success card (reuse warning/danger tokens) */
.guided-reject { margin-top: 6px; }
.reject-tag { color: var(--fg-warning); }
.reject-btn:hover { color: var(--fg-warning); border-color: var(--fg-warning); }
.reject-btn.on { background: var(--bg-warning-subtle); color: var(--fg-warning); border-color: var(--fg-warning); }
.g-expect { color: var(--fg-warning); font: var(--caption-m); }
.g-hole { font: var(--caption-m); color: var(--fg-danger); background: var(--bg-danger-subtle); padding: 6px 10px; border-radius: 10px; margin-bottom: 8px; font-weight: 600; }
.g-reject { background: var(--bg-warning-subtle); border: 1px solid var(--fg-warning); border-radius: 12px; padding: 10px 12px; margin: 4px 0 10px; }
.g-reject-h { font: var(--title-xs); color: var(--fg-warning); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.g-reject-badge { font: var(--caption-s); text-transform: uppercase; letter-spacing: 0.06em; background: var(--bg-warning); color: var(--fg-inverse); border-radius: var(--radius-pill); padding: 1px 8px; }
.g-reject-proves { font: var(--caption-m); color: var(--fg-secondary); margin-top: 6px; }
.g-reject-detail { font: var(--caption-s); color: var(--fg-tertiary); font-family: var(--font-mono, monospace); margin-top: 4px; word-break: break-word; }

/* coach: highlight the exact next button (static ring — no infinite animation) */
.coach-target { box-shadow: 0 0 0 3px var(--bg-brand-subtle), 0 0 0 1px var(--border-brand) !important; border-radius: var(--radius-pill); position: relative; }

/* gated (disabled) buttons + inline gate note */
.d-cta:disabled, .d-pill[disabled], button[disabled] { opacity: 0.5; cursor: not-allowed; }
.d-pill[disabled] { filter: grayscale(0.3); }
.d-gate { color: var(--fg-warning); background: var(--bg-warning-subtle); border-radius: 10px; padding: 6px 10px; margin: 4px 0 8px; font: var(--caption-m); }

/* ============================================================================
   F8 — VISUAL POLISH (style-only, per canonical cake-design-system).
   Semantic tokens ONLY. Pink = accent (CTA / active tab / focus / status),
   never a background wash. One-shot micro-transitions, no infinite motion.
============================================================================ */
/* chrome hierarchy */
.topbar { box-shadow: 0 1px 0 var(--border-tertiary); }
.brand-mark { letter-spacing: -0.02em; }
.role-tab { transition: color var(--dur) var(--ease-out), background var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out); }
.role-tab.is-active { box-shadow: var(--shadow-card), inset 0 -2px 0 var(--border-brand); }
.sess-id { letter-spacing: -0.01em; }

/* sharpen type hierarchy */
.d-label { font: var(--caption-s); text-transform: uppercase; letter-spacing: 0.08em; color: var(--fg-tertiary); margin-bottom: 7px; }
.d-title { letter-spacing: -0.3px; }

/* device: real Cake-app depth (accent-only pink) */
.device { box-shadow: var(--shadow-island), var(--shadow-card); }
.d-appbar { padding-bottom: 12px; border-bottom: 1px solid var(--border-tertiary); }
.d-appicon { box-shadow: inset 0 0 0 1px var(--border-brand); }
.d-card { border-radius: var(--radius-card); padding: 18px; }
.scenario-caption { border-left: 3px solid var(--border-brand); }

/* CTAs */
.d-cta { transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out), background var(--dur) var(--ease-out); }
.d-cta:not(.secondary):not(:disabled) { box-shadow: 0 8px 20px -10px var(--bg-brand); }
.d-cta:not(.secondary):not(:disabled):hover { background: var(--bg-brand-pressed); }
.d-cta:active { transform: translateY(1px); box-shadow: none; }
.d-field { transition: border-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out); }
.d-field:focus { outline: none; border-color: var(--border-brand); box-shadow: 0 0 0 3px var(--bg-brand-subtle); }
.d-seg button { transition: color var(--dur) var(--ease-out), background var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out); }
.d-seg button.on { box-shadow: var(--shadow-card); }

/* semantic status badges (draft=amber · active=green · revoked/suspended=red) */
.d-pill { font: var(--caption-m); font-weight: 600; padding: 3px 10px; border: 1px solid transparent; letter-spacing: -0.1px; }
.d-pill.ok     { background: var(--bg-success-subtle); color: var(--fg-success); border-color: color-mix(in srgb, var(--fg-success) 30%, transparent); }
.d-pill.warn   { background: var(--bg-warning-subtle); color: var(--fg-warning); border-color: color-mix(in srgb, var(--fg-warning) 30%, transparent); }
.d-pill.danger { background: var(--bg-danger-subtle);  color: var(--fg-danger);  border-color: color-mix(in srgb, var(--fg-danger) 30%, transparent); }
.d-pill.info   { background: var(--bg-info-subtle);    color: var(--fg-info);    border-color: color-mix(in srgb, var(--fg-info) 30%, transparent); }

/* console: severity accent by status code + refined tags */
.evt { transition: border-color var(--dur) var(--ease-out); }
.evt.s2xx { box-shadow: inset 3px 0 0 var(--badge-2xx-fg); }
.evt.s4xx { box-shadow: inset 3px 0 0 var(--badge-4xx-fg); }
.evt.s5xx { box-shadow: inset 3px 0 0 var(--badge-5xx-fg); }
.evt.open { border-color: color-mix(in srgb, var(--console-accent) 40%, var(--console-border)); }
.evt-head { transition: background var(--dur) var(--ease-out); }
.badge { font-weight: 700; letter-spacing: 0.02em; }
.role-chip { font-weight: 600; letter-spacing: -0.1px; }
.svc-tag { font-weight: 600; }
.evt-caret { transition: transform var(--dur) var(--ease-out), color var(--dur) var(--ease-out); }
.evt.open .evt-caret { color: var(--console-accent); }
.evt.open .evt-body { animation: evtExpand 0.18s var(--ease-out); }
@keyframes evtExpand { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.sec-h { letter-spacing: 0.14em; }

/* scenario/stepper polish */
.guided-btn { transition: color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out), background var(--dur) var(--ease-out); }
.g-dot { transition: background var(--dur) var(--ease-out); }

/* diagram: one-shot pulse on live highlight */
.anode { transition: box-shadow var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out); }
.anode.live { animation: nodePulse 0.6s var(--ease-out); }
@keyframes nodePulse { 0% { box-shadow: 0 0 0 0 var(--bg-brand-subtle); } 60% { box-shadow: 0 0 0 6px var(--bg-brand-subtle); } 100% { box-shadow: 0 0 0 3px var(--bg-brand-subtle); } }

/* ============================================================================
   C2 — visualization layer (token-type badges · step annotation · inspector ·
   pairwise · lifecycle · strength callouts · prominent viz entry). Reuses the
   existing Cake tokens; console elements use --console-*, panels use semantic.
============================================================================ */

/* prominent "Trực quan" entry (brand-outlined variant of the ghost button) */
.btn-viz { border: 1px solid var(--border-brand); background: var(--bg-brand-subtle); color: var(--fg-brand); border-radius: var(--radius-pill); padding: 7px 16px; font: var(--title-xs); cursor: pointer; transition: background var(--dur) var(--ease-out), transform var(--dur) var(--ease-out); }
.btn-viz:hover { background: var(--bg-brand); color: var(--fg-inverse); }
.btn-viz.viz-live { animation: vizLive 1.4s var(--ease-out) infinite; }
@keyframes vizLive { 0%,100% { box-shadow: 0 0 0 0 var(--bg-brand-subtle); } 50% { box-shadow: 0 0 0 5px var(--bg-brand-subtle); } }

/* console: per-step security-property annotation */
.evt-proof { display: flex; gap: 6px; align-items: baseline; padding: 0 11px 7px 11px; font-size: 11px; color: var(--role-hydra); }
.evt-proof span { color: var(--console-fg-dim); }

/* console: token-type badges + opaque→revoke callout (inside RESPONSE) */
.tok-badges { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 4px; }
.tok-badge { font-size: 10px; font-family: var(--font-mono); padding: 2px 8px; border-radius: var(--radius-pill); border: 1px solid transparent; }
.tok-badge.opaque { color: #7fc7ff; border-color: rgba(96,165,250,0.5); background: rgba(96,165,250,0.12); }
.tok-badge.jwt { color: var(--role-miniapp); border-color: rgba(255,92,184,0.5); background: rgba(255,92,184,0.12); }
.tok-badge.refresh { color: var(--role-hydra); border-color: rgba(52,211,153,0.5); background: rgba(52,211,153,0.12); }
.tok-badge.single { color: var(--badge-4xx-fg); border-color: rgba(255,107,107,0.4); background: rgba(255,107,107,0.10); }
.tok-callout { font-size: 11px; color: var(--console-fg-dim); background: var(--console-surface-2); border-left: 2px solid var(--role-hydra); border-radius: 6px; padding: 6px 9px; margin-top: 6px; }
.tok-callout code, .tok-callout b { color: var(--console-fg); }

/* left device: Token Inspector card */
.tok-inspect .ti-row { display: flex; align-items: center; justify-content: space-between; margin-top: 10px; }
.ti-ttl { font: var(--caption-m); color: var(--fg-secondary); }
.ti-val { font-size: 12px; color: var(--fg-tertiary); margin-top: 3px; word-break: break-all; }
.ti-note { font: var(--body-xs); color: var(--fg-secondary); margin-top: 6px; }
.ti-claims { margin-top: 8px; display: grid; gap: 6px; }
.ti-claim { display: flex; justify-content: space-between; gap: 10px; background: var(--bg-surface-secondary); border-radius: 10px; padding: 6px 10px; }
.ti-claim.pairwise { border: 1px solid var(--border-brand); background: var(--bg-brand-subtle); }
.ti-k { font: var(--caption-m); color: var(--fg-secondary); }
.ti-v { font-size: 12px; color: var(--fg-primary); word-break: break-all; text-align: right; }
.ti-tag { font: var(--caption-s); text-transform: uppercase; letter-spacing: 0.06em; color: var(--fg-brand); background: var(--bg-surface-primary); border: 1px solid var(--border-brand); border-radius: var(--radius-pill); padding: 0 6px; margin-left: 6px; }
.tok-badge.opaque, .tok-badge.jwt { } /* (badges reused inside inspector rows) */

/* stepper: pairwise comparison card */
.g-pairwise { background: var(--bg-brand-subtle); border: 1px solid var(--border-brand); border-radius: 12px; padding: 10px 12px; margin: 4px 0 10px; }
.g-pw-h { font: var(--title-xs); color: var(--fg-brand); }
.g-pw-h code, .g-pw-note code, .g-pw-verdict code { font-family: var(--font-mono); }
.g-pw-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 8px 0; }
.g-pw-col { background: var(--bg-surface-primary); border: 1px solid var(--border-secondary); border-radius: 10px; padding: 8px; }
.g-pw-app { font: var(--caption-m); color: var(--fg-secondary); }
.g-pw-sub { font-size: 11px; color: var(--fg-primary); word-break: break-all; margin-top: 3px; }
.g-pw-verdict { font: var(--caption-m); border-radius: 8px; padding: 6px 9px; }
.g-pw-verdict.ok { color: var(--fg-success); background: var(--bg-success-subtle); }
.g-pw-verdict.warn { color: var(--fg-warning); background: var(--bg-warning-subtle); }
.g-pw-note { font: var(--body-xs); color: var(--fg-secondary); margin-top: 6px; }

/* overlay run strip: reject variant */
.ovr-btn.reject:hover { color: var(--fg-warning); border-color: var(--fg-warning); }
.ovr-btn.reject.on { color: var(--fg-warning); border-color: var(--fg-warning); background: var(--bg-warning-subtle); }

/* overlay: token lifecycle (3 flows) */
.lc-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.lc-col { background: var(--bg-surface-secondary); border: 1px solid var(--border-secondary); border-radius: var(--radius-16); padding: 12px; border-top: 3px solid var(--border-primary); }
.lc-col.info { border-top-color: var(--fg-info); }
.lc-col.brand { border-top-color: var(--fg-brand); }
.lc-col.role { border-top-color: var(--role-partner); }
.lc-flow { font: var(--title-xs); color: var(--fg-primary); margin-bottom: 8px; }
.lc-arrow { text-align: center; color: var(--fg-tertiary); font-size: 12px; margin: 2px 0; }
.lc-step { background: var(--bg-surface-primary); border: 1px solid var(--border-secondary); border-radius: 10px; padding: 7px 9px; }
.lc-step-h { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font: var(--caption-m); color: var(--fg-primary); }
.lc-ttl { margin-left: auto; font-family: var(--font-mono); font-size: 11px; color: var(--fg-secondary); }
.lc-note { font: var(--body-xs); color: var(--fg-secondary); margin-top: 3px; }
.lc-chip { font-size: 10px; font-family: var(--font-mono); padding: 1px 7px; border-radius: var(--radius-pill); border: 1px solid transparent; }
.lc-chip.opaque { color: var(--fg-info); border-color: var(--fg-info); background: var(--bg-info-subtle); }
.lc-chip.jwt { color: var(--fg-brand); border-color: var(--border-brand); background: var(--bg-brand-subtle); }
.lc-chip.single { color: var(--fg-danger); border-color: var(--fg-danger); background: var(--bg-danger-subtle); }
.lc-refresh { margin-top: 14px; font: var(--body-s); color: var(--fg-secondary); background: var(--bg-warning-subtle); border-left: 3px solid var(--fg-warning); border-radius: 10px; padding: 10px 12px; }
.lc-refresh code, .lc-refresh b { color: var(--fg-primary); }
.lc-legend { margin-top: 10px; display: flex; gap: 12px; flex-wrap: wrap; font: var(--caption-m); color: var(--fg-tertiary); align-items: center; }

/* overlay: strength callouts */
.strength { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.st-card { background: var(--bg-surface-secondary); border: 1px solid var(--border-secondary); border-radius: var(--radius-16); padding: 12px; }
.st-h { display: flex; align-items: center; gap: 8px; }
.st-ic { font-size: 18px; }
.st-title { font: var(--title-xs); color: var(--fg-primary); }
.st-body { font: var(--body-s); color: var(--fg-secondary); margin: 6px 0 8px; }
.st-src { font: var(--caption-s); text-transform: uppercase; letter-spacing: 0.05em; color: var(--fg-tertiary); }

@media (max-width: 720px) {
  .lc-cols { grid-template-columns: 1fr; }
  .g-pw-grid { grid-template-columns: 1fr; }
}

/* ============================================================================
   C3 — polish: docked auto-open visualizer · console list-poll dedup badge ·
   welcome empty-state. Reuses existing tokens (console + semantic); no new colors.
============================================================================ */

/* docked visualizer: transparent backdrop (pointer-events pass through so the left
   device/stepper stays usable), card pinned full-height to the right over the console. */
.overlay.docked { background: transparent; place-items: stretch end; padding: 0; pointer-events: none; }
.overlay.docked .overlay-card { pointer-events: auto; width: min(780px, 56vw); max-width: 56vw; height: 100vh; max-height: 100vh; border-radius: 0; box-shadow: -10px 0 40px rgba(0,0,0,0.30); }
@media (max-width: 720px) { .overlay.docked .overlay-card { width: 100vw; max-width: 100vw; } }

/* console: ×N dedup badge on a collapsed run of read-only list polls */
.evt-dup { color: var(--console-fg-dim); background: var(--console-surface-2); border: 1px solid var(--console-border); }
.evt-dup[hidden] { display: none; }

/* console: welcome empty-state (retired by first EVENT) */
.console-welcome { margin: auto; max-width: 560px; padding: 22px; }
.cw-badge { display: inline-block; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--console-accent); border: 1px solid var(--console-border); border-radius: var(--radius-pill); padding: 3px 10px; }
.cw-title { font: var(--title-m); color: var(--console-fg); margin: 14px 0 6px; }
.cw-title b { color: var(--console-accent); }
.cw-sub { font: var(--body-s); color: var(--console-fg-dim); margin-bottom: 16px; }
.cw-grid { display: grid; gap: 10px; }
.cw-col { border: 1px solid var(--console-border); border-radius: 12px; padding: 10px 12px; background: var(--console-surface); }
.cw-h { font: var(--caption-m); margin-bottom: 4px; }
.cw-h.ok { color: var(--badge-2xx-fg); }
.cw-h.warn { color: var(--fg-warning); }
.cw-h.viz { color: var(--console-accent); }
.cw-list { font-family: var(--font-mono); font-size: 11px; color: var(--console-fg-dim); line-height: 1.7; }

/* ============================================================================
   M5.1 — DIAGRAM-FIRST STAGE. The architecture diagram is the focal panel; the
   storytelling + inline data-verify read the run/EVENT; the JSON console is a
   collapsed drawer. Reuses Cake tokens (pink accent-only, soft elevation). No em-dash.
============================================================================ */
.stage-main {
  min-width: 0; display: grid;
  grid-template-rows: minmax(0, 1fr) auto auto;   /* diagram (focal) · story · console-drawer */
  gap: 14px; min-height: 0;
}

/* focal diagram panel — light card, generous room, scrolls internally if tall */
.stage-diagram {
  background: var(--bg-surface-primary); border: 1px solid var(--border-secondary);
  border-radius: var(--radius-card); box-shadow: var(--shadow-card);
  padding: 16px; overflow: auto; min-height: 0;
}

/* storytelling + inline data-verify (the read-first surface) */
.stage-story {
  background: var(--bg-surface-primary); border: 1px solid var(--border-secondary);
  border-radius: var(--radius-16); box-shadow: var(--shadow-card); padding: 14px 16px;
}
.story-step { margin: 6px 0 10px; }
.story-no { font: var(--caption-m); text-transform: uppercase; letter-spacing: .08em; color: var(--fg-brand); }
.story-title { font: var(--title-m); color: var(--fg-primary); margin-top: 2px; }
.story-explain { font: var(--body-s); color: var(--fg-secondary); margin-top: 4px; max-width: 68ch; }
.story-proof { font: var(--caption-m); color: var(--fg-success); background: var(--bg-success-subtle); border-radius: 10px; padding: 6px 10px; margin-top: 8px; }
.g-live { font: var(--caption-m); color: var(--fg-brand); }

/* inline data-verify (AC-D5) — request → status → real DB rows with ✓/✗ from db_evidence */
.stage-verify { border-top: 1px solid var(--border-tertiary); margin-top: 10px; padding-top: 10px; }
.sv-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-family: var(--font-mono); font-size: 12px; }
.sv-m { color: var(--fg-info); font-weight: 700; }
.sv-ep { color: var(--fg-secondary); }
.sv-st { margin-left: auto; padding: 1px 8px; border-radius: var(--radius-pill); font-weight: 700; }
.sv-st.ok { color: var(--fg-success); background: var(--bg-success-subtle); }
.sv-st.bad { color: var(--fg-danger); background: var(--bg-danger-subtle); }
.sv-db { margin-top: 8px; display: grid; gap: 5px; }
.sv-row { display: flex; align-items: baseline; gap: 8px; font: var(--caption-m); padding: 5px 8px; border-radius: 8px; background: var(--bg-surface-secondary); }
.sv-row.ok { border-left: 3px solid var(--fg-success); }
.sv-row.bad { border-left: 3px solid var(--fg-danger); background: var(--bg-danger-subtle); }
.sv-row.na { border-left: 3px solid var(--border-primary); }
.sv-row.blocked { border-left: 3px solid var(--fg-tertiary); background: var(--bg-surface-secondary); }   /* B4: step rejected → write skipped (neutral, NOT red) */
.sv-badge { flex: none; width: 16px; text-align: center; font-weight: 700; }
.sv-row.ok .sv-badge { color: var(--fg-success); }
.sv-row.bad .sv-badge { color: var(--fg-danger); }
.sv-row.na .sv-badge { color: var(--fg-tertiary); }
.sv-row.blocked .sv-badge { color: var(--fg-tertiary); }
.sv-note { margin-left: 8px; font: var(--caption-s); color: var(--fg-tertiary); }
.sv-lab { color: var(--fg-secondary); }
.sv-val { margin-left: auto; color: var(--fg-primary); word-break: break-all; }

/* stage welcome empty-state (before any run) */
.stage-welcome { padding: 6px 2px; }
.sw-title { font: var(--title-m); color: var(--fg-primary); }
.sw-title b { color: var(--fg-brand); }
.sw-sub { font: var(--body-s); color: var(--fg-secondary); margin: 6px 0 12px; max-width: 70ch; }
.sw-tags { display: flex; gap: 8px; flex-wrap: wrap; }
.sw-tag { font: var(--caption-m); border-radius: var(--radius-pill); padding: 4px 12px; border: 1px solid var(--border-secondary); background: var(--bg-surface-secondary); color: var(--fg-secondary); }
.sw-tag.ok { color: var(--fg-success); border-color: color-mix(in srgb, var(--fg-success) 40%, transparent); }
.sw-tag.warn { color: var(--fg-warning); border-color: color-mix(in srgb, var(--fg-warning) 40%, transparent); }
.sw-tag.viz { color: var(--fg-brand); border-color: var(--border-brand); }

/* collapsible JSON console drawer (details/summary) — no longer the focal point */
.stage-console { border: 1px solid var(--border-secondary); border-radius: var(--radius-16); overflow: hidden; background: var(--console-bg); }
.sc-summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px; background: var(--console-surface); color: var(--console-fg); }
.sc-summary::-webkit-details-marker { display: none; }
.sc-title { font: var(--title-xs); color: var(--console-fg); }
.sc-sub { font: var(--caption-m); color: var(--console-fg-dim); margin-left: 8px; font-weight: 400; }
.sc-tools { display: flex; align-items: center; gap: 10px; }
.sc-caret { color: var(--console-fg-dim); transition: transform var(--dur) var(--ease-out); }
.stage-console[open] .sc-caret { transform: rotate(90deg); }
.stage-console .console { border: 0; border-radius: 0; height: min(38vh, 420px); }
.stage-console .console-head { border-top: 1px solid var(--console-border); }
/* RED-1: the console sets display:flex, which leaks past the native <details> collapse.
   Force it hidden when the drawer is closed (id+class beats the .console rule). */
#consoleDrawer:not([open]) .console { display: none; }

/* flow connector: smooth "request travels between lanes" pulse, synced to real EVENTs */
.flow { transition: color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out); }
@media (prefers-reduced-motion: no-preference) {
  .flow.flowing { animation: flowBeam 780ms var(--ease-out); color: var(--fg-brand); }
}
@keyframes flowBeam { 0% { transform: translateY(-4px); opacity: .3; } 40% { opacity: 1; } 100% { transform: translateY(2px); opacity: .6; } }
.anode.is-active { position: relative; }

/* mobile: single column, diagram first, device below */
@media (max-width: 900px) {
  .split { grid-template-columns: 1fr; }
  .stage-left { order: 2; }
  .stage-main { order: 1; }
  .stage-diagram { max-height: 60vh; }
}

/* overlay: note above the deep-dive tabs (diagram moved to main stage) */
.ov-panel-note { font: var(--caption-m); color: var(--fg-secondary); background: var(--bg-surface-secondary); border-radius: 10px; padding: 8px 12px; margin: 4px 0 10px; }

/* ============================================================================
   M5.2 — decluttered scenario launcher: 5 happy CARDS (▶ auto / từng bước) +
   an "advanced" disclosure hiding the 7 security-reject scenarios + free-play.
   Cake tokens, pink accent-only on the primary ▶, mostly neutral, whitespace.
============================================================================ */
.scenario-launcher { padding: 4px 20px 0; }
.scn-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(216px, 1fr)); gap: 12px; }
.scn-card {
  display: flex; flex-direction: column; gap: 8px; cursor: pointer;
  background: var(--bg-surface-primary); border: 1px solid var(--border-secondary);
  border-radius: var(--radius-16); padding: 14px; box-shadow: var(--shadow-card);
  transition: border-color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.scn-card:hover { border-color: var(--border-brand); transform: translateY(-2px); }
.scn-card.on { border-color: var(--border-brand); box-shadow: 0 0 0 2px var(--bg-brand-subtle), var(--shadow-card); }
.scn-ic { font-size: 22px; line-height: 1; }
.scn-name { font: var(--title-xs); color: var(--fg-primary); }
.scn-desc { font: var(--caption-m-subtle); color: var(--fg-secondary); }
.scn-actions { display: flex; gap: 8px; margin-top: auto; padding-top: 4px; }
.scn-play { flex: 1; border: 0; background: var(--bg-brand); color: var(--fg-inverse); font: var(--caption-m); padding: 8px 10px; border-radius: var(--radius-pill); cursor: pointer; transition: background var(--dur) var(--ease-out); }
.scn-play:hover { background: var(--bg-brand-pressed); }
.scn-step { border: 1px solid var(--border-primary); background: var(--bg-surface-secondary); color: var(--fg-secondary); font: var(--caption-m); padding: 8px 10px; border-radius: var(--radius-pill); cursor: pointer; }
.scn-step:hover { color: var(--fg-brand); border-color: var(--border-brand); }

/* advanced disclosure — clearly labeled, collapsed by default, discoverable (R-b) */
.scn-advanced { margin: 12px 0 4px; border: 1px solid var(--border-secondary); border-radius: var(--radius-16); background: var(--bg-surface-secondary); overflow: hidden; }
.scn-adv-sum { list-style: none; cursor: pointer; display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; padding: 12px 16px; }
.scn-adv-sum::-webkit-details-marker { display: none; }
.scn-adv-title { font: var(--title-xs); color: var(--fg-warning); }
.scn-adv-hint { font: var(--caption-m); color: var(--fg-secondary); }
.scn-advanced[open] .scn-adv-sum { border-bottom: 1px solid var(--border-secondary); }
.scn-adv-body { padding: 12px 16px; }
.scn-reject-row { display: flex; flex-wrap: wrap; gap: 8px; }
.scn-freeplay { margin-top: 12px; font: var(--body-xs); color: var(--fg-secondary); }
.scn-freeplay b { color: var(--fg-primary); }

@media (max-width: 640px) { .scenario-launcher { padding: 4px 12px 0; } .scn-cards { grid-template-columns: 1fr 1fr; } }
