/* ============================================================================
 * Manager console stylesheet — loads after base.css.
 *
 * Currently: the login flow (two-step, split layout) and the interim index
 * placeholder. Console shell (sidebar / tables / drawers) joins this file as
 * those pages are built.
 * ========================================================================== */

/* ---- Login: split layout ------------------------------------------------- */

.login-shell {
    position: fixed;
    inset: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
}

.login-brand {
    background: #0C0C0C;
    border-right: 1px solid rgba(255, 255, 255, .06);
    padding: 48px 52px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}

.login-logo { display: flex; align-items: center; gap: 11px; }

.login-logo .mark {
    display: inline-flex;
    width: 24px;
    height: 24px;
    border-radius: 7px;
    background: #34D399;
    align-items: center;
    justify-content: center;
    flex: none;
}

.login-logo .name { font-size: 16px; letter-spacing: -0.02em; font-weight: 600; }
.login-logo .name span { color: #8A8A8A; font-weight: 400; }

.login-eyebrow {
    font-family: 'Geist Mono', monospace;
    font-size: 12px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: #34D399;
}

.login-brand h1 {
    font-size: 30px;
    font-weight: 600;
    letter-spacing: -0.03em;
    line-height: 1.15;
    margin: 16px 0 0;
    max-width: 380px;
}

.login-features { margin-top: 30px; display: flex; flex-direction: column; gap: 16px; max-width: 400px; }

.login-feature { display: flex; gap: 12px; }
.login-feature svg { color: #34D399; flex: none; margin-top: 2px; }
.login-feature .t { font-size: 14px; font-weight: 500; }
.login-feature .d { font-size: 13px; color: #8A8A8A; line-height: 1.5; }

.login-version { font-family: 'Geist Mono', monospace; font-size: 11px; color: #4A4A4A; }

.login-side { display: grid; place-items: center; padding: 32px; }

.login-card { width: 100%; max-width: 352px; }

.login-card h2 { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; margin: 0; }

.login-sub { font-size: 13.5px; color: #8A8A8A; margin: 8px 0 0; line-height: 1.5; }
.login-sub .who { color: #EDEDED; font-family: 'Geist Mono', monospace; }

.login-form { margin-top: 26px; display: flex; flex-direction: column; gap: 16px; }

/* ---- Form controls ------------------------------------------------------- */

.field label { display: block; font-size: 12.5px; color: #B4B4B4; margin-bottom: 7px; }

.field input {
    width: 100%;
    height: 38px;
    background: #0C0C0C;
    border: 1px solid rgba(255, 255, 255, .13);
    border-radius: 9px;
    padding: 0 12px;
    color: #EDEDED;
    font-size: 13.5px;
    font-family: inherit;
    outline: none;
    transition: border-color .12s, box-shadow .12s;
}

.field input:focus { border-color: #34D399; box-shadow: 0 0 0 3px rgba(52, 211, 153, .14); }

.remember { display: flex; align-items: center; gap: 9px; font-size: 13px; color: #B4B4B4; cursor: pointer; user-select: none; }

/* Custom checkbox: pure CSS check (no data: URI images — img-src is 'self') */
.remember input {
    appearance: none;
    width: 16px;
    height: 16px;
    border-radius: 5px;
    border: 1px solid rgba(255, 255, 255, .2);
    background: #0C0C0C;
    margin: 0;
    cursor: pointer;
    position: relative;
    transition: background .12s, border-color .12s;
}

.remember input:checked { background: #34D399; border-color: #34D399; }

.remember input:checked::after {
    content: "";
    position: absolute;
    left: 4.5px;
    top: 1.5px;
    width: 4px;
    height: 8px;
    border: solid #06231A;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.btn-light {
    width: 100%;
    height: 39px;
    background: #E5E5E6;
    color: #0A0A0A;
    border: none;
    border-radius: 9px;
    font-size: 14px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    margin-top: 2px;
    transition: background .12s, opacity .12s;
}

.btn-light:hover { background: #FFFFFF; }
.btn-light[disabled] { opacity: .55; cursor: default; }
.btn-light[disabled]:hover { background: #E5E5E6; }

/* ---- Alerts / notes ------------------------------------------------------ */

.login-alert {
    display: flex;
    gap: 9px;
    background: rgba(248, 113, 113, .09);
    border: 1px solid rgba(248, 113, 113, .3);
    border-radius: 9px;
    padding: 11px 12px;
    font-size: 12.5px;
    color: #F5A97F;
    line-height: 1.5;
}

.login-alert svg { flex: none; margin-top: 1px; }

.login-alert[hidden] { display: none; }

.login-note { display: flex; align-items: center; gap: 8px; margin-top: 22px; font-size: 12px; color: #5A5A5A; }

/* ---- Step 2 (TOTP) ------------------------------------------------------- */

.login-back {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: transparent;
    border: none;
    color: #8A8A8A;
    font-size: 13px;
    font-family: inherit;
    cursor: pointer;
    padding: 0;
    margin-bottom: 20px;
    transition: color .12s;
}

.login-back:hover { color: #EDEDED; }

.code-input {
    width: 100%;
    height: 52px;
    margin-top: 24px;
    background: #0C0C0C;
    border: 1px solid rgba(255, 255, 255, .13);
    border-radius: 10px;
    text-align: center;
    letter-spacing: .5em;
    font-family: 'Geist Mono', monospace;
    font-size: 22px;
    color: #FAFAFA;
    outline: none;
    transition: border-color .12s, box-shadow .12s;
}

.code-input:focus { border-color: #34D399; box-shadow: 0 0 0 3px rgba(52, 211, 153, .14); }

.login-alt { text-align: center; margin-top: 18px; }

.login-alt a { font-size: 12.5px; color: #8A8A8A; text-decoration: none; transition: color .12s; }
.login-alt a:hover { color: #34D399; }

/* ---- Interim index placeholder ------------------------------------------- */

.stub-shell { min-height: 100vh; display: grid; place-items: center; padding: 32px; }

.stub-card {
    width: 100%;
    max-width: 420px;
    border: 1px solid rgba(255, 255, 255, .08);
    border-radius: 14px;
    background: #0F0F0F;
    padding: 32px;
    text-align: center;
}

.stub-card .mark {
    display: inline-flex;
    width: 40px;
    height: 40px;
    border-radius: 11px;
    background: #34D399;
    align-items: center;
    justify-content: center;
}

.stub-card h1 { font-size: 19px; font-weight: 600; letter-spacing: -0.02em; margin: 18px 0 0; }

.stub-card p { font-size: 13.5px; color: #8A8A8A; line-height: 1.6; margin: 10px 0 0; }

.stub-card .who { color: #EDEDED; font-family: 'Geist Mono', monospace; font-size: 13px; }

.stub-card form { margin-top: 22px; }

.btn-ghost {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 36px;
    padding: 0 16px;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, .14);
    border-radius: 9px;
    color: #C4C4C4;
    font-size: 13px;
    font-family: inherit;
    cursor: pointer;
    transition: border-color .12s, color .12s;
}

.btn-ghost:hover { border-color: rgba(255, 255, 255, .3); color: #FAFAFA; }

/* ---- Responsive ----------------------------------------------------------- */

@media (max-width: 880px) {
    .login-shell { grid-template-columns: 1fr; }
    .login-brand { display: none; }
}

/* ============================================================================
 * Console shell + shared components (Wave A foundation).
 *
 * Design tokens (docs/html/design_handoff · README) live as CSS variables so
 * every surface reads one source; shell, tables, drawer, modal, dropdown and
 * toast are all driven off them. No inline styles anywhere — the CSP forbids
 * them — so state is toggled by class only.
 * ========================================================================== */

:root {
    /* Surfaces */
    --bg: #0A0A0A;
    --surface: #0F0F0F;
    --surface-raised: #141414;
    --surface-sunk: #0C0C0C;
    --hairline: rgba(255, 255, 255, .07);
    --hairline-strong: rgba(255, 255, 255, .13);
    --row-hover: rgba(255, 255, 255, .025);

    /* Text */
    --text: #FAFAFA;
    --text-high: #EDEDED;
    --text-body: #C4C4C4;
    --text-muted: #8A8A8A;
    --text-faint: #6A6A6A;

    /* Accent + status hues */
    --accent: #34D399;
    --accent-hover: #4ADEA9;
    --accent-deep: #06231A;
    --accent-soft: rgba(52, 211, 153, .12);
    --accent-ring: rgba(52, 211, 153, .14);
    --light: #E5E5E6;
    --blue: #7DD3FC;
    --indigo: #A5B4FC;
    --amber: #FBBF77;
    --orange: #F5A97F;
    --danger: #F87171;
    --danger-solid: #DC2626;
    --grey: #9A9A9A;

    /* Geometry */
    --sidebar-w: 236px;
    --topbar-h: 56px;
    --content-max: 1320px;
    --radius-card: 12px;
    --radius-control: 9px;
    --radius-modal: 14px;

    /* Shadow */
    --shadow-modal: 0 30px 80px rgba(0, 0, 0, .6);
    --shadow-drawer: -24px 0 70px rgba(0, 0, 0, .55);
    --shadow-toast: 0 16px 40px rgba(0, 0, 0, .5);

    --mono: 'Geist Mono', monospace;
}

/* ---- Shell layout -------------------------------------------------------- */

.console { display: grid; grid-template-columns: var(--sidebar-w) minmax(0, 1fr); height: 100vh; overflow: hidden; }

.sidebar {
    height: 100vh;
    background: var(--surface-sunk);
    border-right: 1px solid var(--hairline);
    display: flex;
    flex-direction: column;
    padding: 18px 14px 14px;
}

/* An <a> since the logo leads back to the public landing — reset the UA
   link paint so the wordmark keeps the sidebar ink */
.sidebar-logo { display: flex; align-items: center; gap: 10px; padding: 4px 8px 20px;
    color: inherit; text-decoration: none; }

.sidebar-logo .mark {
    display: inline-flex;
    width: 22px;
    height: 22px;
    border-radius: 7px;
    background: var(--accent);
    align-items: center;
    justify-content: center;
    flex: none;
}

.sidebar-logo .name { font-size: 15px; font-weight: 600; letter-spacing: -0.02em; }
.sidebar-logo .name span { color: var(--text-muted); font-weight: 400; }

.nav { display: flex; flex-direction: column; gap: 2px; overflow-y: auto; flex: 1; }

.nav-group { margin-top: 16px; }
.nav-group:first-child { margin-top: 4px; }

.nav-label {
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--text-faint);
    padding: 0 8px 6px;
}

.nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    height: 34px;
    padding: 0 10px;
    border-radius: 8px;
    color: var(--text-body);
    font-size: 13.5px;
    text-decoration: none;
    position: relative;
    transition: background .12s, color .12s;
}

.nav-item svg { flex: none; color: var(--text-faint); transition: color .12s; }
.nav-item:hover { background: rgba(255, 255, 255, .04); color: var(--text-high); }
.nav-item:hover svg { color: var(--text-muted); }

.nav-item.active { background: rgba(255, 255, 255, .06); color: var(--text); }
.nav-item.active svg { color: var(--accent); }

.nav-item.active::before {
    content: "";
    position: absolute;
    left: -14px;
    top: 7px;
    bottom: 7px;
    width: 2px;
    background: var(--accent);
    border-radius: 0 2px 2px 0;
}

.sidebar-account {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 12px;
    padding: 10px 8px;
    border-top: 1px solid var(--hairline);
    text-decoration: none;
    color: inherit;
    border-radius: 8px;
    transition: background .12s;
}

.sidebar-account:hover { background: rgba(255, 255, 255, .04); }

.sidebar-account .avatar {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: var(--surface-raised);
    border: 1px solid var(--hairline-strong);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-high);
    flex: none;
    text-transform: uppercase;
}

.sidebar-account .who { display: flex; flex-direction: column; min-width: 0; }
.sidebar-account .who .n { font-size: 13px; color: var(--text-high); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-account .who .e { font-size: 11.5px; color: var(--text-faint); font-family: var(--mono); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.main { min-width: 0; height: 100vh; display: flex; flex-direction: column; }

.topbar {
    flex: none;
    height: var(--topbar-h);
    border-bottom: 1px solid var(--hairline);
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 0 24px;
    background: rgba(10, 10, 10, .72);
    backdrop-filter: blur(10px);
}

.topbar h1 { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; margin: 0; }
.topbar-right { display: flex; align-items: center; gap: 14px; margin-left: auto; }

.env-pill {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    color: var(--text-body);
    background: var(--surface);
    border: 1px solid rgba(255, 255, 255, .09);
    border-radius: 20px;
    padding: 5px 11px;
}

.env-pill .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 7px var(--accent); }
.topbar-meta { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); }

.content { flex: 1; min-height: 0; overflow-y: auto; padding: 26px max(28px, calc((100% - var(--content-max)) / 2)) 60px; }
.content-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 20px; }
.content-head h1 { font-size: 21px; font-weight: 600; letter-spacing: -0.02em; margin: 0; }
.content-head p { font-size: 13.5px; color: var(--text-muted); margin: 6px 0 0; line-height: 1.5; max-width: 640px; }

/* ---- Summary cards ------------------------------------------------------- */

.summary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 18px; }
.stat-card { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-card); padding: 15px 16px; }
.stat-card .k { font-family: var(--mono); font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-faint); }
.stat-card .v { font-size: 24px; font-weight: 600; letter-spacing: -0.02em; margin-top: 10px; color: var(--text); }
.stat-card .d { font-size: 12px; margin-top: 5px; color: var(--text-muted); }

@media (max-width: 820px) { .summary { grid-template-columns: repeat(2, 1fr); } }

/* ---- Buttons ------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    height: 36px;
    padding: 0 15px;
    border-radius: var(--radius-control);
    font-size: 13px;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    border: 1px solid transparent;
    white-space: nowrap;
    /* An action that navigates is an <a class="btn">; without this it keeps the
       user agent's underline and reads as a link wearing a button */
    text-decoration: none;
    /* Both must be stated. A <button class="btn"> carrying no variant otherwise
       falls back to the UA's `buttonface`/`buttontext` — on a page that never
       declares color-scheme: dark, buttonface is WHITE. */
    background: transparent;
    color: var(--text-body);
    transition: background .12s, border-color .12s, color .12s, box-shadow .12s, opacity .12s;
}

.btn svg { flex: none; }
.btn[disabled] { opacity: .5; cursor: default; }

.btn-primary { background: var(--accent); color: var(--accent-deep); font-weight: 600; }
.btn-primary:not([disabled]):hover { background: var(--accent-hover); }

/* Light solid button for a page-level create action (Add rule / Add chain …).
   Named -lighted, not -light: .btn-light is the login page's full-width
   (width:100%) submit button, a different component. */
.btn-lighted { background: var(--light); color: #0A0A0A; font-weight: 600; }
.btn-lighted:not([disabled]):hover { background: #FFFFFF; box-shadow: 0 2px 12px rgba(0, 0, 0, .45); }

.btn-outline { background: transparent; border-color: var(--hairline-strong); color: var(--text-body); }
.btn-outline:not([disabled]):hover { border-color: rgba(255, 255, 255, .3); color: var(--text); }

.btn-danger { background: transparent; border-color: rgba(248, 113, 113, .4); color: var(--danger); }
.btn-danger:not([disabled]):hover { background: rgba(248, 113, 113, .1); border-color: rgba(248, 113, 113, .6); }

/* Outline info button — the non-destructive "check / re-verify" drawer action */
.btn-info { background: transparent; border-color: rgba(125, 211, 252, .4); color: var(--blue); }
.btn-info:not([disabled]):hover { background: rgba(125, 211, 252, .1); border-color: rgba(125, 211, 252, .6); }

.btn-sm { height: 30px; padding: 0 11px; font-size: 12px; }

/* ---- Status pills (README badge palette) --------------------------------- */

.pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 500;
    padding: 3px 8px;
    border-radius: 6px;
    text-transform: lowercase;
    white-space: nowrap;
    border: 1px solid transparent;
}

.pill::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; flex: none; }

.pill-green  { color: var(--accent); background: rgba(52, 211, 153, .12); border-color: rgba(52, 211, 153, .28); }
.pill-indigo { color: var(--indigo); background: rgba(165, 180, 252, .12); border-color: rgba(165, 180, 252, .28); }
.pill-blue   { color: var(--blue); background: rgba(125, 211, 252, .12); border-color: rgba(125, 211, 252, .28); }
.pill-amber  { color: var(--amber); background: rgba(251, 191, 119, .12); border-color: rgba(251, 191, 119, .28); }
.pill-orange { color: var(--orange); background: rgba(245, 169, 127, .12); border-color: rgba(245, 169, 127, .28); }
.pill-red    { color: var(--danger); background: rgba(248, 113, 113, .12); border-color: rgba(248, 113, 113, .3); }
.pill-grey   { color: var(--grey); background: rgba(255, 255, 255, .05); border-color: rgba(255, 255, 255, .15); }

/* ---- Filter toolbar ------------------------------------------------------ */

.toolbar { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid rgba(255, 255, 255, .06); flex-wrap: wrap; }

.search { position: relative; flex: 1; min-width: 200px; }
.search > svg { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--text-faint); pointer-events: none; }
.search input {
    width: 100%;
    height: 34px;
    background: var(--surface-sunk);
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 8px;
    padding: 0 11px 0 32px;
    color: var(--text-high);
    font-size: 12.5px;
    font-family: inherit;
    outline: none;
    transition: border-color .12s;
}
.search input::placeholder { color: var(--text-faint); }
.search input:focus { border-color: var(--accent); }

/* ---- Table --------------------------------------------------------------- */

.panel { background: var(--surface); border: 1px solid rgba(255, 255, 255, .08); border-radius: var(--radius-card); overflow: hidden; }

.table-scroll { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; }
/* Column-dense tables keep a floor width and scroll horizontally under it */
.table.wide { min-width: 820px; }

.table th {
    text-align: left;
    font-family: var(--mono);
    font-size: 10.5px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--text-faint);
    padding: 11px 14px;
    white-space: nowrap;
}

.table th.num, .table td.num { text-align: right; }

/* Content stays whole: a wide table scrolls sideways (.table-scroll), so a cell
   never truncates or wraps — two-line cells (.cell-two) use block children,
   which nowrap does not affect.
   ⚠️ Without this the long cells folded onto a second line instead: a project's
   payment-method list, a block reason, a bucket address. A wrapped cell does
   not save the reader anything — it makes its whole row twice as tall, and the
   width it was hiding is a scroll away. */
.table td {
    padding: 12px 14px;
    font-size: 12.5px;
    color: var(--text-body);
    border-top: 1px solid rgba(255, 255, 255, .05);
    vertical-align: middle;
    white-space: nowrap;
}
.table tbody tr.clickable { cursor: pointer; transition: background .1s; }
.table tbody tr.clickable:hover { background: var(--row-hover); }

.table .mono { font-family: var(--mono); }
.table .strong { color: var(--text-high); }
.table .accent { color: var(--accent); }
/* Muted cell — a placeholder value (e.g. a Wave C runtime metric not yet wired) */
.table .faint { color: var(--text-faint); }
/* Fixed-format cells (timestamps) must never wrap mid-value */
.table .nowrap { white-space: nowrap; }
.cell-two { display: flex; flex-direction: column; gap: 2px; }
.cell-two .sub { font-size: 11px; color: var(--text-faint); font-family: var(--mono); }
/* A pill is sized by its label. As a flex child it stretches to the column and
   reads as a bar — but only align-self, never align-items on the container:
   the numeric two-line cells rely on stretch to keep their text right-aligned */
.cell-two > .pill { align-self: flex-start; }
/* Inline cell: label + trailing pill, vertically centred */
.cell-inline { display: flex; align-items: center; gap: 8px; }
/* Request-id cell: truncated id + inline copy affordance */
.reqid { display: inline-flex; align-items: center; gap: 6px; }

/* ---- Empty state --------------------------------------------------------- */

.empty { padding: 56px 24px; text-align: center; }
.empty svg { color: var(--text-faint); opacity: .6; margin-bottom: 12px; }
.empty .t { font-size: 13.5px; color: var(--text-high); }
.empty .d { font-size: 12.5px; color: var(--text-muted); margin-top: 4px; }

/* ---- Load failure -------------------------------------------------------- */

/* Where a fetch failed, said in the space its data was going to fill, with the
   retry beside it. Persistent on purpose: a toast outlives nothing, and the
   void it leaves behind reads as "loaded, and empty". */
.load-fallback { padding: 34px 24px; text-align: center; }
.load-fallback .t { font-size: 13px; color: var(--text-high); }
.load-fallback .d { font-size: 12.5px; color: var(--text-muted); line-height: 1.45; margin-top: 4px; }
.load-fallback .btn-ghost { height: 30px; padding: 0 14px; margin-top: 14px; font-size: 12.5px; }
/* Centred in the attention panel, like the all-clear state beside it */
.attn-list .load-fallback { margin: auto 0; }
/* One message across the chain grid, not one squeezed into its first column */
.chain-grid .load-fallback { grid-column: 1 / -1; }
/* The row flavour brings its own padding */
.table .load-fallback-row td { padding: 0; }

/* ---- Pagination ---------------------------------------------------------- */

.pagination { display: flex; align-items: center; justify-content: space-between; padding: 11px 16px; border-top: 1px solid rgba(255, 255, 255, .06); flex-wrap: wrap; gap: 10px; }
.pagination .range { font-size: 12px; color: #7A7A7A; }
.pagination .pager { display: flex; align-items: center; gap: 6px; }
.pagination .page-ind { font-size: 12px; color: var(--text-body); font-variant-numeric: tabular-nums; padding: 0 6px; min-width: 48px; text-align: center; }

/* ---- Overlay-based surfaces: drawer, modal ------------------------------- */

.overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .5);
    z-index: 100;
    animation: overlay-in .2s ease;
}

@keyframes overlay-in { from { opacity: 0; } to { opacity: 1; } }

/* Detail drawer — 462px right slide-in */
.drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 462px;
    max-width: 92vw;
    background: var(--surface);
    border-left: 1px solid var(--hairline-strong);
    box-shadow: var(--shadow-drawer);
    z-index: 101;
    display: flex;
    flex-direction: column;
    animation: drawer-in .26s cubic-bezier(.4, 0, .2, 1);
}

@keyframes drawer-in { from { transform: translateX(100%); } to { transform: translateX(0); } }

.drawer-head { padding: 20px 22px 16px; border-bottom: 1px solid var(--hairline); }
.drawer-head .title-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.drawer-head h3 { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; margin: 0; }
.drawer-head .sub { font-size: 12.5px; color: var(--text-muted); margin: 5px 0 0; font-family: var(--mono); }
.drawer-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.drawer-tag { font-family: var(--mono); font-size: 11px; color: var(--text-muted); background: var(--surface-sunk); border: 1px solid var(--hairline); border-radius: 6px; padding: 3px 8px; }

.drawer-body { padding: 6px 22px 20px; overflow-y: auto; flex: 1; }

.drawer-section { padding: 16px 0; border-bottom: 1px solid var(--hairline); }
.drawer-section:last-child { border-bottom: none; }
.drawer-section.framed { background: var(--surface-sunk); border: 1px solid var(--hairline); border-radius: 10px; padding: 14px 16px; margin: 14px 0; }
.section-title { font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-faint); margin-bottom: 12px; }

/* The webhook payload the integrator received, indented by the page for
   reading. `pre`, never `pre-wrap`: the indentation is the structure, and
   rewrapping a long string value mid-line would read as a line break that is
   not in the data. A line too long for the box scrolls the box, not the drawer
   around it */
.payload { max-height: 280px; overflow: auto; margin: 0; padding: 12px 14px; white-space: pre;
    background: var(--surface-sunk); border: 1px solid var(--hairline); border-radius: 10px;
    font-family: var(--mono); font-size: 11.5px; line-height: 1.6; color: var(--text-body); }

.kv { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; padding: 6px 0; }
.kv .k { font-size: 12.5px; color: var(--text-muted); flex: none; }
.kv .v { font-size: 12.5px; color: var(--text-high); text-align: right; word-break: break-word; }
.kv .v.mono { font-family: var(--mono); }
/* Health tone on a metric value (WS health, lag, price-feed staleness) */
.kv .v.tone-green { color: var(--accent); }
.kv .v.tone-amber { color: var(--amber); }
.kv .v.tone-red { color: var(--danger); }

/* Two equal columns, so buttons align into rows instead of wrapping ragged at
   their label widths. .wide spans the row — for an action deliberately set
   apart from the pairs (the primary, the destructive one), and for a lone
   trailing button that would otherwise sit half-width. */
.drawer-actions { padding: 16px 22px; border-top: 1px solid var(--hairline); display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.drawer-actions .wide { grid-column: 1 / -1; }

/* Trailing drawer callout (e.g. append-only notice) */
.drawer-note { display: flex; gap: 9px; margin-top: 10px; padding: 11px 13px; font-size: 12px; line-height: 1.5; color: var(--text-muted); background: var(--surface-sunk); border: 1px solid var(--hairline); border-radius: 9px; }
.drawer-note svg { color: var(--text-faint); flex: none; margin-top: 1px; }

/* Centered modal — 412px (confirm / form / 2FA) */
.modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 412px;
    max-width: 94vw;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    background: var(--surface-raised);
    border: 1px solid var(--hairline-strong);
    border-radius: var(--radius-modal);
    box-shadow: var(--shadow-modal);
    z-index: 101;
    animation: modal-in .2s ease;
}

@keyframes modal-in { from { opacity: 0; transform: translate(-50%, -46%) scale(.98); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }

.modal-head { padding: 20px 22px 0; flex: none; }
.modal-head h3 { font-size: 16px; font-weight: 600; letter-spacing: -0.01em; margin: 0; }
.modal-body { padding: 12px 22px 4px; font-size: 13px; color: var(--text-body); line-height: 1.55; overflow-y: auto; min-height: 0; }
.modal-body .field { margin-top: 14px; }
.modal-actions { padding: 18px 22px 20px; display: flex; justify-content: flex-end; gap: 9px; flex: none; }

.modal-body label { display: block; font-size: 12.5px; color: var(--text-body); margin-bottom: 7px; }
.modal-body input, .modal-body textarea {
    width: 100%;
    background: var(--surface-sunk);
    border: 1px solid var(--hairline-strong);
    border-radius: var(--radius-control);
    padding: 9px 12px;
    color: var(--text-high);
    font-size: 13.5px;
    font-family: inherit;
    outline: none;
    transition: border-color .12s, box-shadow .12s;
}
.modal-body textarea { resize: vertical; min-height: 72px; }
.modal-body input:focus, .modal-body textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }

.warn-note {
    display: flex;
    gap: 9px;
    background: rgba(248, 113, 113, .09);
    border: 1px solid rgba(248, 113, 113, .3);
    border-radius: 9px;
    padding: 11px 12px;
    font-size: 12.5px;
    color: var(--orange);
    line-height: 1.5;
    margin-top: 14px;
}
.warn-note svg { flex: none; margin-top: 1px; }

/* Settings edit modal extras */
.modal-body .modal-sub { font-size: 12px; color: var(--text-muted); margin: 6px 0 14px; }
.modal-body input.mono { font-family: var(--mono); font-size: 13px; }
.modal-note { display: flex; align-items: center; gap: 8px; margin-top: 14px; font-size: 12px; color: var(--text-muted); }
.modal-note .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--amber); flex: none; }
.modal-error { margin-top: 12px; font-size: 12px; color: var(--danger); }

/* ---- Wide detail modal --------------------------------------------------- */
/* Wider than the compact 412px confirm/form base — the frame the trace and
   lifecycle views share. .modal-fixed pins the height too, for a body whose
   content streams in: the frame opens at its final size and never grows step by
   step. Views whose content is known up front (the lifecycle) omit it and let
   the modal size to what it holds. Both scroll inside on short viewports
   (max-height: 90vh is inherited from .modal). */
.modal-wide { width: 34rem; }
.modal-fixed { height: 64rem; }
.modal-fixed .modal-body { flex: 1; }

.modal-headrow { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; }
.modal-headsub { font-family: var(--mono); font-size: 11px; color: var(--text-faint); margin-top: 6px; line-height: 1.5; }
.modal-headsub.break { word-break: break-all; }

.modal-statepill { flex: none; display: inline-flex; align-items: center; font-size: 12px; font-weight: 600; border-radius: 20px; padding: 5px 12px; border: 1px solid transparent; white-space: nowrap; }
.modal-statepill.tone-grey { color: var(--grey); background: rgba(255, 255, 255, .05); border-color: var(--hairline-strong); }
.modal-statepill.tone-green { color: var(--accent); background: rgba(52, 211, 153, .12); border-color: rgba(52, 211, 153, .28); }
.modal-statepill.tone-red { color: var(--danger); background: rgba(248, 113, 113, .12); border-color: rgba(248, 113, 113, .3); }
.modal-statepill.tone-amber { color: var(--amber); background: rgba(251, 191, 119, .12); border-color: rgba(251, 191, 119, .28); }
.modal-statepill.tone-indigo { color: var(--indigo); background: rgba(165, 180, 252, .12); border-color: rgba(165, 180, 252, .28); }

.rv-note { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-muted); padding: 4px 0 2px; }
.rv-note svg { color: var(--text-faint); flex: none; }

.rv-section { padding: 16px 0 2px; border-top: 1px solid var(--hairline); margin-top: 14px; }
.rv-section:first-of-type { border-top: none; margin-top: 6px; }

/* ---- Timeline ------------------------------------------------------------ */
/* The shared vertical event rail: a dot on a hairline spine, a time + tag head,
   then title, detail and supporting lines. Two views render into it — the
   re-verify trace (steps arriving live, time = elapsed) and the order lifecycle
   (events reconstructed from the ledger, time = clock + offset) — so the shape
   is defined once here and once in components/timeline.js. */
.tl { margin: 14px 0 4px 5px; border-left: 1px solid var(--hairline-strong); padding-left: 22px; }
.tl-event { position: relative; padding-bottom: 18px; }
.tl-event:last-child { padding-bottom: 2px; }
.tl-dot { position: absolute; left: -28px; top: 2px; width: 9px; height: 9px; border-radius: 50%; background: var(--text-faint); box-shadow: 0 0 0 4px var(--surface-raised); }
.tl-dot.indigo { background: var(--indigo); }
.tl-dot.green { background: var(--accent); box-shadow: 0 0 0 4px var(--surface-raised), 0 0 8px rgba(52, 211, 153, .55); }
.tl-dot.red { background: var(--danger); box-shadow: 0 0 0 4px var(--surface-raised), 0 0 8px rgba(248, 113, 113, .5); }
.tl-dot.amber { background: var(--amber); box-shadow: 0 0 0 4px var(--surface-raised); }
.tl-head { display: flex; align-items: center; gap: 12px; }
.tl-time { font-family: var(--mono); font-size: 11px; color: var(--text-faint); min-width: 58px; display: inline-flex; align-items: baseline; gap: 7px; }
.tl-offset { color: var(--text-muted); }
.tl-tag { font-family: var(--mono); font-size: 10.5px; color: var(--text-muted); border: 1px solid var(--hairline-strong); border-radius: 7px; padding: 2px 8px; white-space: nowrap; }
.tl-tag.indigo { color: var(--indigo); border-color: rgba(165, 180, 252, .32); background: rgba(165, 180, 252, .08); }
.tl-tag.green { color: var(--accent); border-color: rgba(52, 211, 153, .32); background: rgba(52, 211, 153, .08); }
.tl-tag.red { color: var(--danger); border-color: rgba(248, 113, 113, .32); background: rgba(248, 113, 113, .08); }
.tl-tag.amber { color: var(--amber); border-color: rgba(251, 191, 119, .32); background: rgba(251, 191, 119, .08); }
.tl-title { font-size: 13.5px; font-weight: 500; color: var(--text-high); margin-top: 8px; }
.tl-detail { font-family: var(--mono); font-size: 11.5px; color: var(--text-muted); margin-top: 3px; line-height: 1.55; word-break: break-word; }
.tl-sub { font-family: var(--mono); font-size: 11px; color: var(--text-faint); margin-top: 4px; line-height: 1.5; word-break: break-word; }

/* A step the order has not reached: drawn hollow and dimmed, so an in-flight
   order shows what it is still waiting for without claiming it happened. */
.tl-event.upcoming .tl-dot { background: transparent; border: 1px solid var(--hairline-strong); }
.tl-event.upcoming .tl-title { color: var(--text-muted); font-weight: 400; }
.tl-event.upcoming .tl-detail, .tl-event.upcoming .tl-tag { color: var(--text-faint); }

/* A moment computed rather than recorded — a batch passing the stuck threshold
   is broadcast_at plus a config value, not an event anything wrote down. The
   dot keeps its tone but becomes a ring: a scanner reads dots, not the sub-line
   that explains it. The title stays full strength, because the moment is real
   even though the record is not. Only the amber tone is spelled out because
   only the stuck threshold is derived; another one would be one line. */
.tl-event.derived .tl-dot { background: transparent; border: 1px solid var(--hairline-strong); }
.tl-event.derived .tl-dot.amber { border-color: var(--amber); }

/* The webhook an event triggered, inline under it */
.tl-web { display: inline-flex; align-items: center; gap: 7px; margin-top: 7px; padding: 4px 9px; font-family: var(--mono); font-size: 10.5px; color: var(--text-muted); background: var(--surface-sunk); border: 1px solid var(--hairline); border-radius: 7px; }
.tl-web svg { color: var(--text-faint); flex: none; }
.tl-web .ok { color: var(--accent); }
.tl-web .bad { color: var(--danger); }

/* On-chain vs registry table */
.rv-cmp { width: 100%; border-collapse: collapse; margin-top: 6px; }
.rv-cmp th { text-align: left; font-family: var(--mono); font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-faint); font-weight: 400; padding: 0 12px 9px 0; }
.rv-cmp th:last-child { padding-right: 0; }
.rv-cmp td { padding: 9px 12px 9px 0; font-size: 12.5px; border-top: 1px solid var(--hairline); vertical-align: middle; }
.rv-cfield { color: var(--text-muted); }
.rv-con, .rv-creg { font-family: var(--mono); color: var(--text-high); }
.rv-con.faint, .rv-creg.faint { color: var(--text-faint); }
.rv-con.diff { color: var(--danger); }
.rv-cmark { text-align: right; padding-right: 0; width: 24px; }
.rv-cmark .rv-ok { color: var(--accent); }
.rv-cmark .rv-bad { color: var(--danger); }
.rv-none { color: var(--text-faint); }

/* Verdict banner */
.rv-verdict { display: flex; gap: 11px; align-items: flex-start; margin-top: 14px; padding: 12px 14px; border-radius: 11px; border: 1px solid transparent; }
.rv-vic { flex: none; width: 22px; height: 22px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-top: 1px; }
.rv-vt { font-size: 13.5px; font-weight: 600; }
.rv-vd { font-size: 12.5px; color: var(--text-body); margin-top: 3px; line-height: 1.55; }
.rv-v-ok { background: rgba(52, 211, 153, .08); border-color: rgba(52, 211, 153, .24); }
.rv-v-ok .rv-vic { background: rgba(52, 211, 153, .16); color: var(--accent); }
.rv-v-ok .rv-vt { color: var(--accent); }
.rv-v-bad { background: rgba(248, 113, 113, .08); border-color: rgba(248, 113, 113, .26); }
.rv-v-bad .rv-vic { background: rgba(248, 113, 113, .16); color: var(--danger); }
.rv-v-bad .rv-vt { color: var(--danger); }
.rv-v-warn { background: rgba(251, 191, 119, .08); border-color: rgba(251, 191, 119, .26); }
.rv-v-warn .rv-vic { background: rgba(251, 191, 119, .16); color: var(--amber); }
.rv-v-warn .rv-vt { color: var(--amber); }

/* ---- Settings page ------------------------------------------------------- */

/* Snapshot card: a stat-card like every other page's, deliberately not one of
   the settings group cards below — what it reports is not a setting but whether
   the settings below are the ones actually in force. State and action sit
   bottom-right, the corner the eye lands on last after reading the numbers. */
/* Rides in the same column flow as the group cards, so it is one column wide by
   construction and the groups pack around it instead of leaving the right half
   empty beside it. Kept visually a stat-card, because what it reports is not a
   setting but whether the settings below are the ones actually in force. */
.snapshot-card { break-inside: avoid; margin-bottom: 14px; }
.snapshot-card.drifted { border-color: rgba(248, 113, 113, .35); background: rgba(248, 113, 113, .04); }
.snapshot-card .d .sep { margin: 0 7px; opacity: .45; }
.snapshot-card .d .hi { color: var(--text-body); }
.snapshot-note { margin: 11px 0 0; font-size: 11.5px; line-height: 1.6; color: var(--text-faint); }
.snapshot-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; margin-top: 14px; }
/* Matches btn-sm's box exactly — a pill and a button side by side read as one
   control strip only if they share a baseline and a height */
.snapshot-actions .pill { height: 30px; padding: 0 11px; box-sizing: border-box; border-radius: var(--radius-control); }
.snapshot-drift { margin-top: 9px; font-size: 11.5px; color: var(--danger); }
.snapshot-drift .keys { display: block; margin-top: 4px; color: var(--text-body); overflow-wrap: anywhere; }

/* Masonry via CSS columns: the seven groups are wildly uneven (1 row vs 20),
   so a row-aligned grid stretches short cards and strands the tall Sweep card
   beside an empty half-width. Columns pack each card to its content and
   balance the two column heights instead. */
.settings-grid { columns: 2; column-gap: 14px; }
@media (max-width: 900px) { .settings-grid { columns: 1; } }

.settings-card { background: var(--surface); border: 1px solid rgba(255, 255, 255, .08); border-radius: var(--radius-card); overflow: hidden; break-inside: avoid; margin-bottom: 14px; }
.settings-card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--hairline); }
.settings-card-head .t { font-size: 13.5px; font-weight: 600; color: var(--text-high); }
.settings-card-head .p { font-size: 11px; color: var(--text-faint); }

.setting-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; text-align: left; padding: 11px 16px; border: none; border-top: 1px solid rgba(255, 255, 255, .04); background: transparent; cursor: pointer; transition: background .1s; }
.setting-row:first-of-type { border-top: none; }
.setting-row:hover { background: rgba(255, 255, 255, .03); }
.setting-row.danger { background: rgba(248, 113, 113, .05); }
.setting-row.danger:hover { background: rgba(248, 113, 113, .09); }

.setting-key-wrap { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.setting-key-wrap .k { font-size: 12px; color: var(--text-body); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.setting-key-wrap .d { font-size: 11.5px; color: var(--text-faint); }

.setting-val { font-size: 12.5px; font-weight: 500; flex: none; max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-body); }
.setting-val.on { color: var(--accent); }
.setting-val.off { color: var(--text-muted); }
.setting-val.danger { color: var(--orange); }

/* ---- Account page -------------------------------------------------------- */

.account { max-width: 720px; }

.account-card { background: var(--surface); border: 1px solid rgba(255, 255, 255, .08); border-radius: var(--radius-card); padding: 20px; }
.account-card + .account-card { margin-top: 14px; }

.profile-head { display: flex; align-items: center; gap: 14px; }
.profile-head .avatar {
    width: 48px;
    height: 48px;
    flex: none;
    border-radius: 12px;
    background: var(--surface-raised);
    border: 1px solid var(--hairline-strong);
    display: grid;
    place-items: center;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-high);
    text-transform: uppercase;
}
.profile-id { min-width: 0; }
.profile-id .name { font-size: 16px; font-weight: 600; color: var(--text); }
.profile-id .sub { font-size: 12px; color: var(--text-muted); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.session-pill { margin-left: auto; flex: none; }

.profile-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 20px; border-top: 1px solid var(--hairline); padding-top: 16px; }
.profile-grid .k { font-size: 11.5px; color: var(--text-faint); }
.profile-grid .v { font-size: 13px; color: var(--text-body); margin-top: 3px; }

/* Security rows card: tighter vertical padding, the rows own their spacing */
.account-card.sec-list { padding: 6px 20px; }
.sec-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 15px 0; border-top: 1px solid var(--hairline); }
.sec-row:first-child { border-top: none; }
.sec-info { min-width: 0; }
.sec-btns { display: flex; gap: 8px; flex: none; }

/* Quiet link-shaped button (modal alternates, e.g. "use the recovery code") */
.link-btn { background: none; border: none; padding: 0; margin-top: 2px; align-self: flex-start; font-size: 12px; color: var(--text-faint); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.link-btn:hover { color: var(--text-body); }
.sec-info .t { font-size: 13.5px; font-weight: 500; color: var(--text-high); display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.sec-info .d { font-size: 12px; color: var(--text-muted); margin-top: 3px; line-height: 1.5; }

/* Two-factor setup modal: QR + manual setup key, then the shown-once code */
.tfa-setup { display: flex; gap: 14px; align-items: center; margin: 16px 0 4px; }
.tfa-qr {
    width: 116px;
    height: 116px;
    flex: none;
    border-radius: 10px;
    border: 1px solid var(--hairline-strong);
    background: #FFFFFF;
    padding: 6px;
}
.tfa-qr svg { width: 100%; height: 100%; display: block; }
.tfa-key { min-width: 0; }
.tfa-key .k { font-size: 11.5px; color: var(--text-faint); margin-bottom: 6px; }
.tfa-key .hint { font-size: 11.5px; color: var(--text-faint); margin-top: 9px; line-height: 1.45; }

.copy-row { display: flex; align-items: center; gap: 8px; }
.copy-row .mono { font-family: var(--mono); font-size: 12px; color: var(--text-high); word-break: break-all; }

.recovery-box { background: var(--surface-sunk); border: 1px solid rgba(52, 211, 153, .25); border-radius: 9px; padding: 12px 13px; margin-top: 14px; }
.recovery-box .k { font-size: 11px; color: var(--accent); margin-bottom: 8px; }
.recovery-box .copy-row .mono { font-size: 15px; letter-spacing: .04em; }

/* A monospaced 6-digit code input (2FA), spaced for legibility */
.modal-body input.code { font-family: var(--mono); letter-spacing: .2em; }

/* ---- IP blocklist page --------------------------------------------------- */

/* Inline mono span inside body copy (e.g. /manager · /v1) */
.mono-inline { font-family: var(--mono); color: var(--text-body); }
/* An expiry dropdown used as a full-width form control inside a modal */
.modal-body .field .dd-trigger { width: 100%; justify-content: space-between; margin-top: 0; }

/* ---- Custom dropdown (portaled popover) ---------------------------------- */

.dd-trigger {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 34px;
    padding: 0 11px;
    background: var(--surface-sunk);
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 8px;
    color: var(--text-body);
    font-size: 12.5px;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
    transition: border-color .12s, color .12s;
}

.dd-trigger:hover { border-color: rgba(255, 255, 255, .26); color: var(--text-high); }
/* Inline-block so a scripted min-width (widest-option lock) holds and the label
   left-aligns instead of the trigger resizing with the selection */
/* Left-align inside the (min-width) box: the trigger is a <button>, whose
   default text-align: center would otherwise centre a short value */
.dd-value { display: inline-block; text-align: left; }
.dd-trigger svg { color: var(--text-faint); flex: none; opacity: .6; }

.dd-menu {
    position: fixed;
    z-index: 200;
    max-height: 300px;
    overflow-y: auto;
    background: #161616;
    border: 1px solid rgba(255, 255, 255, .14);
    border-radius: 9px;
    box-shadow: 0 16px 44px rgba(0, 0, 0, .55);
    padding: 5px;
    animation: pop-in .13s ease;
}

@keyframes pop-in {
    from { opacity: 0; transform: translateY(6px) scale(.98); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

.dd-option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 10px;
    border-radius: 7px;
    font-size: 13px;
    color: var(--text-body);
    cursor: pointer;
    /* Never wrap: the menu sizes to its widest label (dropdown.js sets a
       min-width and lets the content decide the rest) */
    white-space: nowrap;
}

/* Only engages when a label is long enough that the menu hit the viewport cap;
   min-width:0 is what lets a flex item shrink below its own content at all */
.dd-option .dd-label { overflow: hidden; text-overflow: ellipsis; min-width: 0; }

.dd-option:hover { background: rgba(255, 255, 255, .06); color: var(--text); }
.dd-option .tick { color: var(--accent); opacity: 0; }
.dd-option.selected .tick { opacity: 1; }
.dd-option.selected { color: var(--text-high); }

/* ---- Toast --------------------------------------------------------------- */

.toast-wrap { position: fixed; right: 22px; bottom: 22px; z-index: 300; display: flex; flex-direction: column; gap: 10px; }

.toast {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--surface-raised);
    border: 1px solid var(--hairline-strong);
    border-radius: 10px;
    box-shadow: var(--shadow-toast);
    padding: 12px 15px;
    font-size: 13px;
    color: var(--text-high);
    animation: toast-in .22s ease;
}

.toast .dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--accent); }
.toast.danger .dot { background: var(--danger); }
.toast.info .dot { background: var(--blue); }

@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

/* Copy affordance on drawer values / cells */
.copy-btn { background: none; border: none; color: var(--text-faint); cursor: pointer; padding: 2px; display: inline-flex; transition: color .12s; }
.copy-btn:hover { color: var(--accent); }

/* Solid confirm tones (tinted confirm button) + drawer close + demo layout */
.btn-danger-solid { background: var(--danger-solid); color: #FFFFFF; font-weight: 600; }
.btn-danger-solid:not([disabled]):hover { background: #E5352F; }
.btn-info-solid { background: var(--blue); color: var(--accent-deep); font-weight: 600; }
.btn-info-solid:not([disabled]):hover { background: #A5E0FD; }

.drawer-head .title-row { align-items: flex-start; }
.drawer-head .title-right { display: flex; align-items: center; gap: 10px; flex: none; }
.drawer-close {
    background: none;
    border: none;
    color: var(--text-faint);
    cursor: pointer;
    padding: 3px;
    display: inline-flex;
    border-radius: 6px;
    transition: color .12s, background .12s;
}
.drawer-close:hover { color: var(--text-high); background: rgba(255, 255, 255, .06); }

.demo-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; flex: none; }
.signout-row { margin-top: 22px; }

/* ---- Dashboard ----------------------------------------------------------- */

/* Range toggle. Buttons, not links: the choice re-reads a payload rather than
   navigating, and the page must stay where the reader left it */
.range-toggle { display: flex; gap: 2px; flex: none; background: var(--surface); border: 1px solid var(--hairline-strong); border-radius: var(--radius-control); padding: 3px; }
.range-opt { appearance: none; background: transparent; border: none; font: inherit; font-size: 12.5px; color: var(--text-muted); padding: 5px 12px; border-radius: 6px; cursor: pointer; transition: color .12s, background .12s; }
.range-opt:hover { color: var(--text-high); }
.range-opt.on { background: var(--text); color: var(--bg); font-weight: 500; }

.dash-grid { display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); gap: 14px; }

/* The card detail line takes a tone only where rising is good news —
   settlement. Nothing else on this page colours a direction */
.stat-card .d.tone-green { color: var(--accent); }

/* ---- Dashboard · settlement chart ---------------------------------------- */

.chart-card { padding: 18px 18px 14px; }
.chart-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.chart-title { font-size: 13.5px; font-weight: 600; color: var(--text-high); }
.chart-sub { font-size: 12px; color: var(--text-faint); margin-top: 3px; }

/* The plot box: the SVG fills it, and the hover overlay is positioned over it by
   percentage. overflow is visible so an edge dot or the tooltip can sit a few px
   into the card's padding rather than being clipped at the frame. */
.chart-plot { position: relative; margin-top: 16px; overflow: visible; }
.chart-svg { display: block; width: 100%; height: 190px; }
.chart-grid { stroke: rgba(255, 255, 255, .05); stroke-width: 1; }

/* Hover overlay — HTML over the SVG, so text and dots stay true under the SVG's
   non-uniform scale. pointer-events pass through to the plot underneath. */
.chart-layer { position: absolute; inset: 0; pointer-events: none; }
.chart-cross { position: absolute; top: 0; bottom: 14px; width: 1px; background: var(--hairline-strong); transform: translateX(-0.5px); }
.chart-dot { position: absolute; width: 9px; height: 9px; border-radius: 50%; transform: translate(-50%, -50%); box-shadow: 0 0 0 2px var(--surface); }
.chart-sw { width: 8px; height: 8px; border-radius: 2px; flex: none; }

.chart-tip { position: absolute; top: 4px; z-index: 2; pointer-events: none; transform: translateX(12px); }
.chart-tip.flip { transform: translateX(calc(-100% - 12px)); }
.chart-tip-card { min-width: 132px; padding: 8px 10px; background: var(--surface-raised); border: 1px solid var(--hairline-strong); border-radius: 8px; box-shadow: 0 8px 22px rgba(0, 0, 0, .4); }
.chart-tip-h { font-size: 11.5px; font-weight: 600; color: var(--text-high); margin-bottom: 6px; }
.chart-tip-row { display: flex; align-items: center; gap: 7px; font-size: 11.5px; line-height: 1.75; }
.chart-tip-nm { color: var(--text-muted); }
.chart-tip-val { margin-left: auto; font-family: var(--mono); color: var(--text-high); font-variant-numeric: tabular-nums; }

.chart-axis { display: flex; justify-content: space-between; margin-top: 8px; font-family: var(--mono); font-size: 10.5px; color: var(--text-faint); }

.chart-legend { display: flex; justify-content: center; gap: 22px; margin-top: 12px; }
.chart-leg-item { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--text-muted); }
.chart-leg-name { color: var(--text-high); font-weight: 500; }
.chart-leg-val { font-family: var(--mono); color: var(--text-high); font-variant-numeric: tabular-nums; }

/* ---- Dashboard · needs attention ----------------------------------------- */

.attn-card { display: flex; flex-direction: column; padding: 16px 18px; }
.attn-list { display: flex; flex-direction: column; flex: 1; gap: 8px; margin-top: 14px; }
.attn-item { display: flex; gap: 11px; padding: 10px 11px; border: 1px solid var(--hairline); border-radius: 9px; text-decoration: none; transition: background .12s, border-color .12s; }
.attn-item:hover { background: var(--row-hover); border-color: var(--hairline-strong); }
.attn-dot { width: 8px; height: 8px; flex: none; margin-top: 5px; border-radius: 50%; background: var(--grey); }
.attn-dot.tone-red { background: var(--danger); }
.attn-dot.tone-amber { background: var(--amber); }
.attn-text { min-width: 0; }
.attn-t { font-size: 13px; font-weight: 500; color: var(--text-high); }
.attn-d { font-size: 12px; color: var(--text-muted); line-height: 1.45; margin-top: 2px; }
/* Centred, because this panel is as tall as the chart beside it and a good-news
   message pinned to the top of all that space reads as content that failed to
   arrive */
.attn-clear { margin: auto 0; padding: 22px 4px; font-size: 12.5px; color: var(--text-muted); line-height: 1.45; }
.attn-clear-t { font-size: 13px; color: var(--text-high); }
.attn-clear-d { margin-top: 4px; }

/* ---- Dashboard · chain health -------------------------------------------- */

.section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 26px 0 12px; }
.section-link { font-size: 12.5px; color: var(--text-muted); text-decoration: none; transition: color .12s; }
.section-link:hover { color: var(--accent); }

.chain-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.chain-card { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius-card); padding: 15px 16px; }
.chain-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
/* One line, always. A wrapped network name would push that card's metrics half
   a line below its neighbours', and those rows exist to be compared across
   cards — the comparison is worth more than the two words a long name loses at
   the narrowest width. The full name is on the element's title */
.chain-name { min-width: 0; font-size: 13.5px; font-weight: 600; color: var(--text-high); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chain-head .pill { flex: none; }
.chain-meta { font-family: var(--mono); font-size: 11px; color: var(--text-faint); margin-top: 3px; }
.chain-metric { display: flex; justify-content: space-between; gap: 10px; font-size: 11.5px; margin-top: 12px; }
.chain-metric .k { color: var(--text-faint); }
.chain-metric .v { font-family: var(--mono); color: var(--text-body); font-variant-numeric: tabular-nums; }
.chain-metric .v.tone-green { color: var(--accent); }
.chain-metric .v.tone-amber { color: var(--amber); }
.chain-bar { height: 5px; margin-top: 6px; border-radius: 5px; background: rgba(255, 255, 255, .07); overflow: hidden; }
.chain-bar-fill { height: 100%; border-radius: 5px; background: var(--grey); }
.chain-bar-fill.tone-green { background: var(--accent); }
.chain-bar-fill.tone-amber { background: var(--amber); }
.chain-idle { margin-top: 14px; font-size: 11.5px; line-height: 1.5; color: var(--text-faint); }

/* ---- Performance page ---------------------------------------------------- */

/* A measurement whose value carries a verdict — a subscription share the
   reconciler has overtaken, a gas ratio past the gate. The existing tone rules
   are all scoped to a card or a drawer row, and a table cell is neither */
.table td.tone-green { color: var(--accent); }
.table td.tone-amber { color: var(--amber); }

/* The pipeline table's share column: the chain card's health bar, laid on its
   side in a cell. The track keeps a floor width so five bars stay comparable
   when the widest is 4% */
.hop-share { display: flex; align-items: center; gap: 10px; min-width: 132px; }
.hop-bar { flex: 1; height: 5px; border-radius: 5px; background: rgba(255, 255, 255, .07); overflow: hidden; }
.hop-bar-fill { height: 100%; border-radius: 5px; background: var(--accent); }
/* A share that is real but rounds to nothing still leaves a mark. An empty
   track is how a stage with no samples draws, and the two must not look alike */
.hop-bar-fill.some { min-width: 3px; }
/* Green is time we spent; grey is time we chose to wait. Drawing a configured
   confirmation depth in the same colour as our own latency is what sends an
   operator looking for a fault in a setting they picked */
.hop-bar-fill.chosen { background: rgba(255, 255, 255, .26); }
.hop-note { font-family: var(--mono); font-size: 10px; letter-spacing: .04em; color: var(--text-faint);
    border: 1px solid var(--hairline-strong); border-radius: 6px; padding: 1px 6px; white-space: nowrap; }

@media (max-width: 1100px) {
    .dash-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Four across, then straight to two. Never three: the registry holds four
   networks, and a three-wide grid renders them as a row of three with one
   stranded underneath. The breakpoint is where a card stops fitting the longest
   network name beside its pill, not where the viewport hits a round number */
@media (max-width: 1240px) {
    .chain-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 820px) {
    .console { grid-template-columns: 1fr; }
    .sidebar { display: none; }
    .chain-grid { grid-template-columns: minmax(0, 1fr); }
}
