/* =============================================================
   AppCenter WebConsole — refinement overlay
   Loaded AFTER site.css. site.css is the canonical Robeeta theme
   (mirrored verbatim into the other SSO consoles) and MUST NOT be
   edited here. Everything below is additive / WebConsole-only:
   later source order wins at equal specificity, so these rules
   layer cleanly on top without touching the shared file.
   Direction: "mission control, calmed" — depth, restored
   hierarchy, one orchestrated entrance, tactile controls.
   Palette/fonts/icons unchanged (#206bc4 · Inter · Tabler).
   ============================================================= */

:root {
    --ac-blue: #206bc4;
    --ac-blue-dark: #1a5ba8;
    --ac-blue-soft: rgba(32, 107, 196, 0.14);
    --ac-shadow-sm: 0 1px 2px rgba(26, 35, 50, 0.04), 0 2px 8px rgba(26, 35, 50, 0.05);
    --ac-shadow-md: 0 2px 6px rgba(26, 35, 50, 0.06), 0 12px 28px rgba(26, 35, 50, 0.10);
    --ac-teal: #0f766e;
    --ac-gray: #475569;
    /* Secondary text. This value was already living in site.css as .text-muted and was ALSO being
       hand-written as color:#6b7a90 in nine views — the same colour by three routes. Named here so
       there is one source for it. Distinct from --ac-gray on purpose: gray is body text, muted is
       supporting text beside it. */
    --ac-muted: #6b7a90;
    /* Danger. Views were using #c0392b for error text while the badges beside them used #b42318, so
       the same idea rendered as two different reds depending on which element carried it. */
    --ac-danger: #b42318;
}

/* ── Atmosphere ─────────────────────────────────────────────
   Two faint highlights bleeding in from the top corners over the
   base #f0f2f5 so cards feel lifted rather than pasted on a slab. */
body {
    background:
        radial-gradient(1200px 480px at 12% -8%, rgba(32, 107, 196, 0.06), transparent 60%),
        radial-gradient(1000px 460px at 92% -12%, rgba(15, 118, 110, 0.05), transparent 60%),
        #f0f2f5;
    background-attachment: fixed;
}

/* Counts/metrics read as data, not prose. */
.metric-value, .role-stat b, .matrix-savebar .count,
tbody td.num, .badge.count { font-variant-numeric: tabular-nums; }

/* ── Topbar — translucent, blurred, with a hairline gradient ── */
.topbar {
    background: rgba(255, 255, 255, 0.82);
    -webkit-backdrop-filter: saturate(1.4) blur(10px);
    backdrop-filter: saturate(1.4) blur(10px);
    border-bottom: 1px solid transparent;
    border-image: linear-gradient(90deg, rgba(32,107,196,0.28), rgba(230,233,239,0.9) 40%) 1;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.6) inset;
}

/* Active nav item: keep the blue fill, add a soft glow + underline anchor. */
.topnav-item {
    position: relative;
    transition: background 0.14s, color 0.14s, transform 0.14s;
}
.topnav-item:hover { transform: translateY(-1px); }
.topnav-item.active {
    background: var(--ac-blue);
    box-shadow: 0 4px 12px rgba(32, 107, 196, 0.32);
}
.topnav-item.active::after {
    content: "";
    position: absolute; left: 0.7rem; right: 0.7rem; bottom: -7px;
    height: 2px; border-radius: 2px;
    background: var(--ac-blue);
}

/* Brand chip — gradient + lift so the rocket reads as a mark. */
.brand-icon {
    background: linear-gradient(150deg, #2f7fd6, var(--ac-blue) 55%, var(--ac-blue-dark));
    box-shadow: 0 2px 6px rgba(32, 107, 196, 0.4);
}

/* ── Restore action hierarchy ───────────────────────────────
   site.css ghosts EVERY button to grey (its trailing override
   block). Bring the *primary* and *save* actions back to color so
   the eye lands on the one thing to click; secondaries stay ghost. */
.btn-primary {
    background: linear-gradient(180deg, #2f7fd6, var(--ac-blue));
    border-color: var(--ac-blue-dark);
    color: #fff;
    box-shadow: 0 1px 2px rgba(26, 35, 50, 0.12), 0 6px 16px rgba(32, 107, 196, 0.22);
    transition: filter 0.14s, box-shadow 0.14s, transform 0.06s;
}
.btn-primary:hover {
    background: linear-gradient(180deg, #2f7fd6, var(--ac-blue));
    border-color: var(--ac-blue-dark);
    color: #fff;
    filter: brightness(1.05);
    box-shadow: 0 2px 4px rgba(26, 35, 50, 0.14), 0 10px 22px rgba(32, 107, 196, 0.28);
}
.btn-primary:active { transform: translateY(1px); }
.btn-primary:disabled {
    background: #aab6c6; border-color: #aab6c6; color: #fff;
    box-shadow: none; filter: none;
}

.btn-save {
    background: linear-gradient(180deg, #36c053, #2fb344);
    border-color: #28a03c; color: #fff;
    box-shadow: 0 1px 2px rgba(26,35,50,0.12), 0 6px 16px rgba(47,179,68,0.24);
}
.btn-save:hover {
    background: linear-gradient(180deg, #36c053, #2fb344);
    border-color: #28a03c; color: #fff; filter: brightness(1.04);
}
.btn-save:active { transform: translateY(1px); }

/* Secondary/icon buttons: keep ghost, just sharpen the press. */
.btn-row:active, .btn-icon:active { transform: translateY(1px); }

/* ── Cards — layered depth; lift only when interactive ─────── */
.card { box-shadow: var(--ac-shadow-sm); }
.card-header {
    border-bottom-color: #eef1f6;
    background: linear-gradient(180deg, rgba(248, 250, 252, 0.7), transparent);
}
a.card, .module-card, .role-card {
    transition: box-shadow 0.16s, border-color 0.16s, transform 0.14s;
}
a.card:hover, .module-card:hover, .role-card:hover {
    box-shadow: var(--ac-shadow-md);
    border-color: #b0bac8;
    transform: translateY(-2px);
}

/* ── Long-list tables: sticky head + accented hover row ────── */
.table-wrap.scrolls { max-height: 70vh; overflow-y: auto; }
.table-wrap.scrolls thead th { position: sticky; top: 0; z-index: 2; }
tbody tr { box-shadow: inset 0 0 0 0 var(--ac-blue); transition: box-shadow 0.12s; }
tbody tr:hover { box-shadow: inset 2px 0 0 0 var(--ac-blue); }

/* ── Motion: one orchestrated entrance ─────────────────────── */
@keyframes ac-rise {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: no-preference) {
    .reveal { animation: ac-rise 0.4s cubic-bezier(0.22, 0.61, 0.36, 1) both; }
    .reveal-stagger > * {
        animation: ac-rise 0.42s cubic-bezier(0.22, 0.61, 0.36, 1) both;
    }
    .reveal-stagger > *:nth-child(1) { animation-delay: 0.02s; }
    .reveal-stagger > *:nth-child(2) { animation-delay: 0.06s; }
    .reveal-stagger > *:nth-child(3) { animation-delay: 0.10s; }
    .reveal-stagger > *:nth-child(4) { animation-delay: 0.14s; }
    .reveal-stagger > *:nth-child(5) { animation-delay: 0.18s; }
    .reveal-stagger > *:nth-child(6) { animation-delay: 0.22s; }
    .reveal-stagger > *:nth-child(7) { animation-delay: 0.26s; }
    .reveal-stagger > *:nth-child(8) { animation-delay: 0.30s; }
}

/* ── Dashboard greeting ─────────────────────────────────────── */
.dash-greeting h1 { display: flex; align-items: center; gap: 0.5rem; }
/* Fixed-size icon box (not just the glyph's intrinsic width) so the heading text lines up with the
   subtitle below it even if this particular icon glyph is ever missing from the loaded icon font. */
.dash-greeting .wave {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.1em; height: 1.1em; flex-shrink: 0;
    color: var(--ac-blue);
}

/* =============================================================
   RBAC — Roles page (card grid)
   ============================================================= */
.role-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1rem;
}
.role-card {
    position: relative;
    background: #fff;
    border: 1px solid #e6e9ef;
    border-radius: 12px;
    box-shadow: var(--ac-shadow-sm);
    padding: 1.1rem 1.2rem 1rem 1.45rem;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    overflow: hidden;
}
/* Color stripe down the left edge, keyed by role. */
.role-card::before {
    content: "";
    position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
    background: var(--role-accent, var(--ac-gray));
}
.role-card.role-account_admin { --role-accent: var(--ac-blue); }
.role-card.role-manager       { --role-accent: var(--ac-teal); }
.role-card.role-developer     { --role-accent: #6b7a90; }

.role-card-head {
    display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
}
.role-card-name {
    font-size: 15px; font-weight: 700; color: #1a2332; letter-spacing: -0.01em;
}
.role-card-desc {
    font-size: 12.5px; color: #6b7a90; line-height: 1.45; flex: 1;
}
.role-stats { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.1rem; }
.role-stat {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.3rem 0.6rem;
    background: #f7f9fc; border: 1px solid #eef1f6; border-radius: 8px;
    font-size: 11.5px; color: #6b7a90; font-weight: 600;
}
.role-stat i { font-size: 15px; color: #9aa5b4; }
.role-stat b { color: #1a2332; font-size: 13px; font-weight: 700; }
.role-card-foot {
    margin-top: auto; padding-top: 0.75rem;
    border-top: 1px solid #f0f2f5;
}
.role-card-foot a {
    display: inline-flex; align-items: center; gap: 0.35rem;
    font-size: 12.5px; font-weight: 600; color: var(--ac-blue);
    text-decoration: none;
}
.role-card-foot a:hover { color: var(--ac-blue-dark); }
.role-card-foot a i { font-size: 15px; transition: transform 0.12s; }
.role-card-foot a:hover i { transform: translateX(2px); }

/* =============================================================
   RBAC — Permissions matrix
   ============================================================= */
.perm-matrix-wrap { overflow: auto; max-height: calc(100vh - 320px); }
.perm-matrix { width: 100%; border-collapse: separate; border-spacing: 0; }

/* Sticky header row (role names) and sticky first column (labels). */
.perm-matrix thead th {
    position: sticky; top: 0; z-index: 3;
    background: #f9fafb;
    padding: 0.6rem 0.9rem;
    border-bottom: 1px solid #e6e9ef;
}
.perm-matrix thead th.perm-corner {
    left: 0; z-index: 4; text-align: left; min-width: 240px;
}
.perm-matrix tbody th.perm-label,
.perm-matrix td.perm-label {
    position: sticky; left: 0; z-index: 1;
    background: #fff;
    text-align: left; vertical-align: top;
    padding: 0.7rem 0.9rem;
    border-bottom: 1px solid #f0f2f5;
    min-width: 240px; max-width: 340px;
}
.perm-matrix tbody tr:hover td.perm-label,
.perm-matrix tbody tr:hover td.perm-cell { background: #f7f9fc; }
.perm-label .lbl { font-weight: 600; color: #1a2332; font-size: 13px; }
.perm-label .dsc { font-size: 11.5px; color: #6b7a90; margin-top: 0.15rem; line-height: 1.4; }

/* Role column header chip — color-coded to match the role cards. */
.role-col { text-align: center; min-width: 116px; }
.role-col-chip {
    display: inline-flex; align-items: center; gap: 0.35rem;
    padding: 0.25rem 0.6rem; border-radius: 999px;
    font-size: 11px; font-weight: 700; letter-spacing: 0.02em;
    text-transform: uppercase; white-space: nowrap;
    background: #f1f5f9; color: #475569;  /* default for custom roles */
}
.role-col-chip.role-account_admin { background: #dbeafe; color: #1d4ed8; }
.role-col-chip.role-manager       { background: #ccfbf1; color: #0f766e; }
.role-col-chip.role-developer     { background: #f1f5f9; color: #475569; }

/* Category divider rows. */
.perm-cat-row td {
    position: sticky; left: 0;
    background: #eef2f7;
    padding: 0.45rem 0.9rem;
    border-bottom: 1px solid #e2e8f0;
    border-top: 1px solid #e2e8f0;
}
.perm-cat-row .cat {
    display: inline-flex; align-items: center; gap: 0.45rem;
    font-size: 10.5px; font-weight: 800; letter-spacing: 0.08em;
    text-transform: uppercase; color: #5a6b80;
}
.perm-cat-row .cat i { font-size: 14px; color: #8a96a6; }

.perm-cell {
    text-align: center; vertical-align: middle;
    padding: 0.55rem 0.9rem;
    border-bottom: 1px solid #f0f2f5;
}
/* Center the existing .switch component (it ships as inline-flex). */
.perm-cell .switch { justify-content: center; }

/* Locked cell — "always on, by design": faint blue field + lock glyph. */
.cell-locked { background: rgba(32, 107, 196, 0.045); }
.cell-locked .lockmark {
    display: inline-flex; align-items: center; justify-content: center;
    gap: 0.3rem; color: #6b7a90; font-size: 11px;
}
.cell-locked .lockmark i { font-size: 13px; color: var(--ac-blue); opacity: 0.7; }

/* Sticky save bar at the foot of the matrix. */
.matrix-savebar {
    position: sticky; bottom: 0; z-index: 5;
    display: flex; align-items: center; justify-content: flex-end;
    gap: 0.85rem;
    margin-top: 1.25rem;
    padding: 0.75rem 1rem;
    background: rgba(255, 255, 255, 0.9);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    border: 1px solid #e6e9ef;
    border-radius: 10px;
    box-shadow: 0 -2px 12px rgba(26, 35, 50, 0.06);
}
.matrix-savebar .count {
    font-size: 12.5px; font-weight: 600; color: #6b7a90;
    margin-right: auto;
}
.matrix-savebar .count.dirty { color: #9a3412; }

@media (max-width: 768px) {
    .perm-matrix-wrap { max-height: none; }
    .perm-matrix thead th.perm-corner,
    .perm-matrix tbody td.perm-label { min-width: 160px; }
}

/* =============================================================
   Tabbed forms (deployment target edit, and reusable elsewhere)
   ============================================================= */
.tabs-nav {
    display: flex; gap: 0.25rem;
    margin: -0.25rem 0 1.25rem;
    border-bottom: 1px solid #e6e9ef;
}
.tab-btn {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.55rem 0.9rem;
    margin-bottom: -1px;
    background: transparent; border: 0; border-bottom: 2px solid transparent;
    font: inherit; font-size: 13px; font-weight: 600; color: #6b7a90;
    cursor: pointer; white-space: nowrap;
    transition: color 0.14s, border-color 0.14s, background 0.14s;
}
.tab-btn:hover { color: #1a2332; }
.tab-btn i { font-size: 16px; }
.tab-btn.active { color: var(--ac-blue); border-bottom-color: var(--ac-blue); }
.tab-pane[hidden] { display: none; }

/* Type chip on the "Target settings" tab — echoes the value the form resolved. */
.type-badge {
    display: inline-flex; align-items: center;
    padding: 0.1rem 0.5rem; border-radius: 999px;
    background: var(--ac-blue-soft); color: var(--ac-blue);
    font-size: 10.5px; font-weight: 800; letter-spacing: 0.03em;
    text-transform: uppercase;
}

/* Type-driven field visibility (also enforced inline by the page script). */
.form-group[hidden] { display: none; }
.required-marker[hidden] { display: none; }

/* =============================================================
   Authentication screens (sign in · 2FA challenge · 2FA setup)
   On-theme with the rest of the console: Tabler blue, Inter,
   the shared .card / .form-input / .check-group components.
   ============================================================= */
.auth-shell {
    display: flex;
    justify-content: center;
    padding: 1.5rem 1rem 3rem;
}
.auth-shell .card { width: 100%; max-width: 400px; }
.auth-shell .card.auth-card--wide { max-width: 440px; }

.auth-sub {
    font-size: 13px; color: #6b7a90; line-height: 1.5;
    margin: 0 0 1.25rem;
}

/* Stack the form fields with consistent spacing. */
.auth-form { display: flex; flex-direction: column; gap: 1rem; }
.auth-form .form-actions { margin-top: 0.25rem; }
.auth-form .btn-primary { width: 100%; justify-content: center; }

/* Back-to-sign-in link row under the card body. */
.auth-altrow { margin-top: 1rem; text-align: center; }
.auth-altrow a {
    display: inline-flex; align-items: center; gap: 0.35rem;
    font-size: 12.5px; font-weight: 600; color: var(--ac-blue); text-decoration: none;
}
.auth-altrow a:hover { color: var(--ac-blue-dark); }

/* TOTP code entry — large, centered, monospaced. */
.otp-input {
    text-align: center;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 26px; font-weight: 700;
    letter-spacing: 0.4em; text-indent: 0.4em;
    padding: 0.6rem 0.5rem;
}

/* Checkbox membership picker (e.g. target-group members). */
.check-list {
    max-height: 320px;
    overflow-y: auto;
    border: 1px solid #e6e9ef;
    border-radius: 8px;
    padding: 0.35rem;
    background: #fff;
}
.check-item {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.4rem 0.55rem;
    border-radius: 6px;
    cursor: pointer;
    font-size: 13px;
}
.check-item:hover { background: var(--ac-blue-soft); }
.check-item input { width: 15px; height: 15px; flex-shrink: 0; accent-color: var(--ac-blue); }

/* =============================================================
   UI/UX polish pass — section sub-tabs, dropdowns, tables,
   empty states, headers, cards. Additive (loads after site.css).
   ============================================================= */

/* Section sub-navigation (siblings of a top-nav dropdown). */
.subnav {
    display: flex; flex-wrap: wrap; gap: 0.15rem;
    margin: 0 0 1.5rem;
    border-bottom: 1px solid #e6e9ef;
}
.subnav-item {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.55rem 0.9rem; margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    color: #6b7a90; font-size: 13px; font-weight: 600; text-decoration: none;
    white-space: nowrap; transition: color 0.14s, border-color 0.14s, background 0.14s;
}
.subnav-item:hover { color: #1a2332; background: #f6f8fb; border-radius: 6px 6px 0 0; }
.subnav-item i { font-size: 16px; opacity: 0.85; }
.subnav-item.active { color: var(--ac-blue); border-bottom-color: var(--ac-blue); }
.subnav-item.active i { opacity: 1; }

/* Nav dropdown panel — open chevron + tidy spacing. */
.actions-menu.open .actions-menu-trigger .chevron { transform: rotate(180deg); }
.topnav-dropdown .actions-menu-trigger { display: inline-flex; align-items: center; gap: 0.4rem; }
.actions-menu-panel .user-menu-item { white-space: nowrap; }
.actions-menu-panel .user-menu-item.active { color: var(--ac-blue); font-weight: 600; }

/* Account switcher — sits left of the profile menu in the topbar. */
.account-switcher { position: relative; margin-right: 0.5rem; }
.account-switcher-trigger {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.4rem 0.7rem; border: 1px solid #e6e9ef; border-radius: 8px;
    background: #fff; color: #1a2332; font-size: 13px; font-weight: 600;
    cursor: pointer; transition: background 0.14s, border-color 0.14s;
}
.account-switcher-trigger:hover { background: #f6f8fb; border-color: #d5dbe6; }
.account-switcher-trigger .account-name { max-width: 12rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-switcher .actions-menu-panel form { margin: 0; }
.account-switcher .actions-menu-panel .user-menu-item { width: 100%; }
.account-switcher .actions-menu-panel .user-menu-item .account-switch-name {
    flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Role badge shown on the switcher trigger and in the dropdown rows. */
.account-role-badge { margin-left: 0.4rem; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.03em; }
.user-menu-sep { height: 1px; background: #eef1f6; margin: 0.35rem 0; }

/* Members screen — compact inline role-change form. */
.inline-role-form { display: inline-flex; align-items: center; gap: 0.4rem; margin: 0; }
.form-input-sm { padding: 0.3rem 0.5rem; font-size: 12.5px; height: auto; }
.btn-row-sm { padding: 0.3rem 0.6rem; font-size: 12.5px; }

/* Empty states — center, calmer icon, comfortable padding. */
.empty { text-align: center; padding: 2.75rem 1.5rem; color: #6b7a90; }
.empty i { font-size: 30px; color: #c4ccd8; display: block; margin: 0 auto 0.6rem; }
/* Two lines, deliberately: the <p> states the situation, the <span> says what to do about it. An empty
   screen is an invitation to act, so it needs both — but the direction must read as secondary to the
   statement, otherwise the two lines compete. Without this rule the span would inherit the default
   font size and end up LARGER than the heading above it. */
.empty p { margin: 0; font-size: 13.5px; font-weight: 600; color: #5a677a; }
.empty span { display: block; margin-top: 0.3rem; font-size: 12.5px; color: var(--ac-muted); }

/* Tables — lighter header, comfortable rows, aligned action cells. */
.table-wrap table thead th {
    font-size: 11.5px; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase;
    color: #8a97a8;
}
.table-wrap table td, .table-wrap table th { padding: 0.6rem 0.85rem; }
.table-wrap td .row-actions { gap: 0.15rem; }

/* Page header — consistent rhythm between title block and actions. */
.page-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 1.25rem; }
.page-header-text h1 { margin: 0 0 0.15rem; }
.page-header-text p { margin: 0; color: #6b7a90; font-size: 13px; }
.page-header-actions { display: flex; gap: 0.5rem; flex-shrink: 0; flex-wrap: wrap; }

/* Cards — softer elevation + consistent inter-card spacing. */
.card { box-shadow: 0 1px 2px rgba(26,35,50,0.05), 0 1px 3px rgba(26,35,50,0.04); }
.card + .card { margin-top: 1.5rem; }

/* Search/toolbar bars are a .form-grid whose trailing cell is .form-actions (Search + Clear).
   .form-actions is otherwise a form *footer* (top divider + margin); strip that here and bottom-align
   the cell so the buttons line up with the search input rather than floating above it with a divider. */
.form-grid > .form-actions {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
    align-self: end;
}

@media (max-width: 768px) {
    .subnav { flex-wrap: nowrap; overflow-x: auto; }
    .page-header { flex-direction: column; }
    .page-header-actions { width: 100%; }
}
.otp-input::placeholder { color: #c2cad6; letter-spacing: 0.4em; }

/* QR enrollment card. */
.qr-card {
    width: 188px; height: 188px;
    margin: 0 auto 1.1rem;
    padding: 10px; background: #fff;
    border: 1px solid #e6e9ef; border-radius: 10px;
    box-shadow: var(--ac-shadow-sm);
}
.qr-card img { display: block; width: 100%; height: 100%; image-rendering: pixelated; }

/* Manual setup key with a copy button. */
.manual-key { display: flex; align-items: stretch; gap: 0.4rem; margin-bottom: 1.1rem; }
.manual-key code {
    flex: 1; min-width: 0;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12.5px; color: #1a2332;
    padding: 0.5rem 0.6rem;
    background: #f7f9fc; border: 1px solid #e6e9ef; border-radius: 6px;
    overflow-wrap: anywhere; display: flex; align-items: center;
}
.manual-key button {
    flex: none; width: 38px;
    display: grid; place-items: center;
    background: #fff; border: 1px solid #ccd3dd; border-radius: 6px;
    color: #6b7a90; font-size: 15px; cursor: pointer;
    transition: color 0.12s, background 0.12s, border-color 0.12s;
}
.manual-key button:hover { color: #1a2332; background: #f9fafb; }
.manual-key button.copied { color: #166534; border-color: #bbf7d0; background: #f0fdf4; }

.auth-steps { margin: 0 0 1.25rem; padding-left: 1.15rem; }
.auth-steps li { font-size: 12.5px; color: #6b7a90; line-height: 1.5; margin-bottom: 0.4rem; }

/* =============================================================
   SafeRoute AdminConsole — local additions
   ============================================================= */

/* Active impersonation action — amber accent matching the impersonation banner. */
.btn-icon.is-active {
    color: #b45309; border-color: #f59e0b; background: #fef3c7;
}
.btn-icon.is-active:hover { color: #92400e; border-color: #d97706; background: #fde68a; }

/* Tenant GUID — compact, copyable monospace chip. Click to copy the full value. */
.guid-chip {
    display: inline-flex; align-items: center; gap: 0.4rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12px; color: #1a2332;
    padding: 0.18rem 0.5rem;
    background: #f7f9fc; border: 1px solid #e6e9ef; border-radius: 6px;
    cursor: pointer; max-width: 100%;
    transition: color 0.12s, background 0.12s, border-color 0.12s;
}
.guid-chip:hover { background: #f1f5fb; border-color: #d3deeb; }
.guid-chip.copied { color: #166534; border-color: #bbf7d0; background: #f0fdf4; }
.guid-chip i { font-size: 13px; color: #9aa6b6; }
.guid-chip.copied i { color: #166534; }
.guid-chip code { font-family: inherit; }

/* Footer — quiet links pinned under the content. */
.admin-footer {
    display: flex; flex-wrap: wrap; gap: 1.25rem;
    padding: 0.9rem 1.5rem;
    border-top: 1px solid #e6e9ef;
    background: rgba(255, 255, 255, 0.6);
    font-size: 12px;
}
.admin-footer a { color: #6b7a90; text-decoration: none; }
.admin-footer a:hover { color: var(--ac-blue); }

/* Event-type / rule-type token — small colored pill keyed by class. */
.evt-token {
    display: inline-flex; align-items: center; gap: 0.35rem;
    font-size: 12px; font-weight: 600; color: #475569;
}
.evt-token::before {
    content: ""; width: 7px; height: 7px; border-radius: 50%;
    background: #94a3b8; flex-shrink: 0;
}
.evt-token.is-good::before    { background: #2fb344; }
.evt-token.is-bad::before     { background: #d63939; }
.evt-token.is-warn::before    { background: #f59f00; }

/* Read-only key/value table on the IP Access page. */
.kv-table th {
    width: 220px; text-transform: none; letter-spacing: 0;
    font-size: 12.5px; color: #3d4a5c; vertical-align: top;
}

/* =============================================================
   PlatformConsole home dashboard
   Signature: the engine card's trace line is a literal heartbeat —
   steady and blue while the engine is reporting in, flat and red
   the moment it goes quiet. Everything else stays deliberately
   plain so that one element carries the page.
   ============================================================= */

/* ── Engine pulse card ──────────────────────────────────────── */
.engine-pulse-card {
    position: relative;
    display: flex; align-items: stretch; gap: 1.5rem;
    background: #fff;
    border: 1px solid #e6e9ef;
    border-radius: 14px;
    box-shadow: var(--ac-shadow-sm);
    padding: 1.35rem 1.6rem;
    margin-bottom: 1.5rem;
    overflow: hidden;
}
.pulse-trace {
    flex: 0 0 240px;
    position: relative;
    align-self: center;
    overflow: hidden;
    border-radius: 8px;
}
.pulse-trace svg { width: 100%; height: 64px; display: block; overflow: visible; }
.pulse-line-track, .pulse-line {
    fill: none; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
}
.pulse-line-track { stroke: #eceff3; }

/* Two mutually-exclusive traces, toggled by health state — swapping paths reads more honestly
   than dimming the same shape, since a dim heartbeat still looks like a heartbeat. */
.pulse-line-beat { stroke: var(--ac-blue); display: none; }
.pulse-line-flat { stroke: #cfd6e0; stroke-width: 3.5; display: none; }
.engine-pulse-card.is-online .pulse-line-beat { display: inline; }
.engine-pulse-card.is-stale .pulse-line-flat,
.engine-pulse-card.is-unknown .pulse-line-flat { display: inline; }
.engine-pulse-card.is-stale .pulse-line-track,
.engine-pulse-card.is-unknown .pulse-line-track { opacity: 0; }

/* Traversal: three beat cycles are drawn across a wider-than-visible canvas (viewBox -150..310) and
   slid left on a loop, like a monitor sweep — the waveform is always mid-motion, never resetting
   mid-frame. One cycle spans 210 viewBox units; the loop offsets by exactly that so it's seamless. */
@media (prefers-reduced-motion: no-preference) {
    .engine-pulse-card.is-online .pulse-line-beat {
        animation: ac-pulse-sweep 3.2s linear infinite;
    }
}
@keyframes ac-pulse-sweep {
    from { transform: translateX(0); }
    to   { transform: translateX(-210px); }
}

.pulse-body { flex: 1; min-width: 0; padding: 0.15rem 0; }
.pulse-status { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.35rem; }
.pulse-dot {
    width: 9px; height: 9px; border-radius: 50%;
    background: var(--ac-blue); flex-shrink: 0;
    box-shadow: 0 0 0 4px var(--ac-blue-soft);
}
.engine-pulse-card.is-stale .pulse-dot { background: #d63939; box-shadow: 0 0 0 4px rgba(214,57,57,0.14); }
.engine-pulse-card.is-unknown .pulse-dot { background: #9aa5b4; box-shadow: 0 0 0 4px rgba(154,165,180,0.14); }
@media (prefers-reduced-motion: no-preference) {
    .engine-pulse-card.is-online .pulse-dot { animation: ac-pulse-dot 2.4s ease-in-out infinite; }
}
@keyframes ac-pulse-dot {
    0%, 100% { box-shadow: 0 0 0 4px var(--ac-blue-soft); }
    50%      { box-shadow: 0 0 0 7px rgba(32,107,196,0.06); }
}
.pulse-label {
    font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--ac-blue);
}
.engine-pulse-card.is-stale .pulse-label { color: #b91c1c; }
.engine-pulse-card.is-unknown .pulse-label { color: #6b7a90; }
.pulse-body h2 { font-size: 1.05rem; font-weight: 700; color: #1a2332; letter-spacing: -0.01em; margin-bottom: 0.2rem; }
.pulse-meta { font-size: 12.5px; color: #6b7a90; }
.pulse-meta strong { color: #3d4a5c; font-weight: 600; font-variant-numeric: tabular-nums; }
.pulse-warning {
    display: flex; align-items: center; gap: 0.4rem;
    margin-top: 0.6rem; font-size: 12.5px; color: #9a3412;
}
.pulse-warning i { font-size: 15px; color: #d97706; }
.pulse-warning.is-quiet { color: #166534; }
.pulse-warning.is-quiet i { color: #2fb344; }

@media (max-width: 700px) {
    .engine-pulse-card { flex-direction: column; gap: 1rem; }
    .pulse-trace { flex-basis: auto; }
}

/* ── Estate stat row ─────────────────────────────────────────── */
.estate-heading {
    font-size: 11px; font-weight: 700; color: #6b7a90;
    text-transform: uppercase; letter-spacing: 0.08em;
    margin-bottom: 0.6rem;
}
.stat-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1rem;
    margin-bottom: 1.5rem;
}
.stat-card {
    position: relative;
    padding: 1.1rem 1.25rem; text-decoration: none; color: inherit;
    display: flex; align-items: center; gap: 0.9rem;
    transition: box-shadow 0.15s, border-color 0.15s, transform 0.12s;
}
.stat-card:hover { box-shadow: var(--ac-shadow-md); border-color: #b0bac8; transform: translateY(-2px); }
.stat-icon {
    width: 42px; height: 42px; border-radius: 10px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: var(--ac-blue-soft); color: var(--ac-blue); font-size: 20px;
}
.stat-icon i { font-size: 20px; line-height: 1; }
.stat-body { display: flex; flex-direction: column; min-width: 0; }
.stat-value { font-size: 1.5rem; font-weight: 700; color: #1a2332; line-height: 1.2; font-variant-numeric: tabular-nums; }
.stat-label { font-size: 12px; color: #6b7a90; }
.stat-arrow {
    position: absolute; top: 1rem; right: 1rem;
    color: #c3cad6; font-size: 15px; transition: color 0.12s, transform 0.12s;
}
.stat-card:hover .stat-arrow { color: var(--ac-blue); transform: translate(2px, -2px); }

/* ── Dashboard stat cards (Tabler-style) ──────────────────────────────────────────────────────────
   Uniform 4-up in the Tabler admin pattern: a coloured "avatar" chip (soft -lt tint + solid icon) on the
   LEFT, the value + uppercase subheader label + meta line stacked on the RIGHT. Fixed equal columns keep
   all four on one line; collapses to 2-up then 1-up. Card 1 is engine health (health-tinted avatar +
   status word + coloured left rail); cards 2–4 are estate counts that link deeper. --stat-accent is the
   Tabler theme colour per card. */
.stat-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); align-items: stretch; gap: 0.9rem; }
/* Reset the stacked-card top margin (.card + .card) that would shove grid siblings down and break the
   row, and lay each card out as icon-left / text-right. */
.stat-grid-4 .stat-card {
    margin: 0; height: 100%; min-height: 116px;
    padding: 1.15rem 1.25rem;
    display: flex; flex-direction: row; align-items: center; justify-content: flex-start; gap: 1rem;
    border: 1px solid #e6eaf0;
}
/* Tabler avatar chip: rounded square, soft theme tint, solid theme-coloured icon. */
.stat-grid-4 .stat-avatar {
    width: 48px; height: 48px; border-radius: 10px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--stat-accent, var(--ac-blue)) 13%, #fff);
    color: var(--stat-accent, var(--ac-blue));
}
.stat-grid-4 .stat-avatar i { font-size: 24px; line-height: 1; }
.stat-grid-4 .stat-body {
    display: flex; flex-direction: column; min-width: 0; gap: 0.05rem;
}
.stat-grid-4 .stat-value {
    font-size: 1.7rem; line-height: 1.1; letter-spacing: -0.02em;
}
.stat-value-sm { font-size: 1.2rem !important; letter-spacing: -0.01em; }
/* Tabler "subheader": small uppercase muted label. */
.stat-grid-4 .stat-label {
    font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
    color: #8894a5;
}
/* Every card's meta line (engine "Last seen …" or the "View …" links) is exactly one line, so all four
   cards render the same three content lines (value, label, sub) and stay the same height. The text
   portion truncates with an ellipsis if it would overflow the narrower icon-left column; the dot/arrow
   stay fixed-size. */
.stat-sub {
    display: flex; align-items: center; gap: 0.35rem;
    margin-top: 0.4rem; font-size: 11.5px; font-weight: 500; color: #6b7a90;
    min-width: 0;
}
.stat-sub-text {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.stat-sub i { font-size: 14px; transition: transform 0.14s; flex-shrink: 0; }
/* Status dot on the engine card's meta line, coloured by health. */
.stat-dot {
    width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
    background: var(--stat-accent, #9aa5b4);
}
/* The three linking cards: sub-line is a "go deeper" affordance whose arrow slides on hover. */
.stat-grid-4 a.stat-card .stat-sub { color: var(--ac-blue); font-weight: 600; }
.stat-grid-4 a.stat-card:hover .stat-sub { color: var(--ac-blue-dark); }
.stat-grid-4 a.stat-card:hover .stat-sub i { transform: translateX(3px); }
.stat-grid-4 a.stat-card:hover { border-color: color-mix(in srgb, var(--ac-blue) 35%, #e6eaf0); }

/* Per-card Tabler theme accent. Estate cards share brand blue; the engine card is health-driven and also
   carries a coloured left rail so its state reads instantly. */
.stat-grid-4 .stat-card.is-good { --stat-accent: #2fb344; }
.stat-grid-4 .stat-card.is-bad  { --stat-accent: #d63939; }
.stat-grid-4 .stat-card.is-warn { --stat-accent: #f59f00; }
.stat-grid-4 .stat-card.is-good .stat-value { color: #15803d; }
.stat-grid-4 .stat-card.is-bad  .stat-value { color: #b91c1c; }
.stat-grid-4 .stat-card.is-warn .stat-value { color: #b45309; }
.stat-grid-4 .stat-card.is-good, .stat-grid-4 .stat-card.is-bad, .stat-grid-4 .stat-card.is-warn {
    border-left: 3px solid var(--stat-accent);
}
@media (prefers-reduced-motion: no-preference) {
    .stat-grid-4 .stat-card.is-good .stat-dot { animation: ac-stat-dot 2.4s ease-in-out infinite; }
}
@keyframes ac-stat-dot {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--stat-accent) 55%, transparent); }
    50%      { box-shadow: 0 0 0 4px color-mix(in srgb, var(--stat-accent) 0%, transparent); }
}

@media (max-width: 900px) { .stat-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .stat-grid-4 { grid-template-columns: 1fr; } }

/* Section-heading tick — a small monitor-style leading mark tying the label to the telemetry theme. */
.estate-heading { display: flex; align-items: center; gap: 0.5rem; margin-top: 1.75rem; }
.estate-tick {
    width: 3px; height: 12px; border-radius: 2px;
    background: var(--ac-blue); flex-shrink: 0;
}

/* ── Recent sign-ins log ──────────────────────────────────────────────────────────────────────── */
.signin-table td, .signin-table th { padding-top: 0.7rem; padding-bottom: 0.7rem; }
.signin-table td.cell-strong { display: flex; align-items: center; gap: 0.5rem; }
.signin-table td.cell-strong i { color: #8894a5; font-size: 15px; }
.signin-table tr.is-latest td { background: rgba(47, 179, 68, 0.045); }
.signin-table tr.is-latest td.cell-strong i { color: #2fb344; }
.signin-latest-tag {
    font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
    color: #15803d; background: rgba(47, 179, 68, 0.14);
    padding: 0.1rem 0.4rem; border-radius: 999px; margin-left: 0.15rem;
}
.signin-ip { color: #3d4a5c; }

/* Empty state for the sign-ins log. */
.signin-empty { text-align: center; padding: 2.25rem 1.25rem; color: #6b7a90; }
.signin-empty i { font-size: 28px; color: #c3cad6; }
.signin-empty p { margin: 0.6rem 0 0.15rem; font-weight: 600; color: #3d4a5c; }
.signin-empty span { font-size: 12.5px; }

/* Empty-state row inside a data table. */
.cell-empty { text-align: center; color: #6b7a90; padding: 1.25rem; }

.kv-table td { font-size: 13.5px; }


/* ══════════════════════════════════════════════════════════════════════════
   API KEYS — credential ledger
   The API Keys screen manages machine credentials, so it reads as a ledger of
   key tags rather than a generic admin table: every row is anchored by a
   monospace fingerprint chip, and a key's health (active / locked with its
   failed-attempt meter / revoked) is legible at a glance. Stays inside the
   console's blue+teal identity; the one bold moment is the secret-reveal plate
   on the "created" screen (.cred-reveal), where copy-once-or-lose-it lives.
   ══════════════════════════════════════════════════════════════════════════ */

/* Roster health strip — three counts above the ledger. */
.key-stats { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.key-stat {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.6rem 0.9rem; background: #fff;
    border: 1px solid #e6e9ef; border-radius: 10px;
    box-shadow: var(--ac-shadow-sm); min-width: 8.5rem;
}
.key-stat .dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.key-stat .dot.active  { background: var(--ac-teal); box-shadow: 0 0 0 3px rgba(15,118,110,0.15); }
.key-stat .dot.locked  { background: #dc2626;        box-shadow: 0 0 0 3px rgba(220,38,38,0.14); }
.key-stat .dot.revoked { background: #94a3b8;        box-shadow: 0 0 0 3px rgba(148,163,184,0.16); }
.key-stat .n { font-size: 20px; font-weight: 700; line-height: 1; color: #1a2332; font-variant-numeric: tabular-nums; }
.key-stat .lbl { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: #8a97a8; }

/* Inline create panel — collapsed by default; the header button reveals it. */
.key-create { border-bottom: 1px solid #eef1f6; background: linear-gradient(180deg, rgba(15,118,110,0.03), transparent); }
.key-create[hidden] { display: none; }
.key-create-inner { display: flex; align-items: flex-end; gap: 0.75rem; flex-wrap: wrap; padding: 1rem 1.25rem; }
.key-create .field { display: flex; flex-direction: column; gap: 0.3rem; flex: 1 1 18rem; min-width: 14rem; }
.key-create label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: #8a97a8; }
.key-create .hint { font-size: 12px; color: #6b7a90; padding: 0 1.25rem 1rem; margin: 0; }
.key-create .hint i { color: var(--ac-teal); }

/* The ledger itself — a table of credential rows. */
.key-ledger { width: 100%; border-collapse: collapse; }
.key-ledger th {
    font-size: 11px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
    color: #8a97a8; text-align: left; padding: 0.6rem 1rem; border-bottom: 1px solid #eef1f6;
}
.key-ledger th.right { text-align: right; }
.key-ledger td { padding: 0.85rem 1rem; border-bottom: 1px solid #f1f4f8; vertical-align: middle; }
.key-ledger tr:last-child td { border-bottom: none; }
.key-ledger tbody tr { transition: background 0.12s; }
.key-ledger tbody tr:hover { background: #fafcfe; }
.key-ledger tbody tr.is-locked  { box-shadow: inset 3px 0 0 0 #dc2626; }
.key-ledger tbody tr.is-revoked td { opacity: 0.62; }

/* Fingerprint chip — the row's anchor; monospace, faint teal wash, non-secret. */
.fp-cell { display: flex; align-items: center; gap: 0.7rem; }
.fp-chip {
    width: 2.35rem; height: 2.35rem; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    border-radius: 8px; background: rgba(15,118,110,0.07);
    border: 1px solid rgba(15,118,110,0.16); color: var(--ac-teal);
}
.fp-chip i { font-size: 18px; }
.is-locked  .fp-chip { background: rgba(220,38,38,0.07); border-color: rgba(220,38,38,0.18); color: #b91c1c; }
.is-revoked .fp-chip { background: #f1f4f8; border-color: #e2e8f0; color: #94a3b8; }
.fp-name { font-weight: 600; color: #1a2332; font-size: 14px; }
.fp-sub {
    display: block; font-size: 11.5px; color: #94a3b8; margin-top: 1px;
}

/* Status lozenge with an inline attempt meter for locked/at-risk keys. */
.key-status { display: inline-flex; align-items: center; gap: 0.5rem; }
.status-pill {
    display: inline-flex; align-items: center; gap: 0.35rem;
    font-size: 11px; font-weight: 700; padding: 0.22rem 0.55rem; border-radius: 999px;
}
.status-pill i { font-size: 13px; }
.status-pill.active  { background: rgba(15,118,110,0.12); color: #0f766e; }
.status-pill.locked  { background: #fee2e2; color: #991b1b; }
.status-pill.revoked { background: #eef1f6; color: #64748b; }
.attempt-meter { display: inline-flex; align-items: center; gap: 0.4rem; }
.attempt-bar { display: inline-flex; gap: 2px; }
.attempt-bar span { width: 5px; height: 12px; border-radius: 1.5px; background: #e2e8f0; }
.attempt-bar span.on { background: #dc2626; }
.attempt-count {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 11px; font-weight: 600; color: #b91c1c; font-variant-numeric: tabular-nums;
}

.key-time { font-size: 12.5px; color: #64748b; font-variant-numeric: tabular-nums; }
.key-time.never { color: #aeb8c6; }
.key-actions { display: flex; gap: 0.35rem; justify-content: flex-end; align-items: center; }
/* Danger variant for the square icon button (delete) — matches .btn-row.danger. */
.btn-icon.danger { color: #b0562f; }
.btn-icon.danger:hover { background: #fff0f0; border-color: #d63939; color: #991b1b; }

/* ── Secret-reveal plate (Created screen) — the one bold moment ──────────── */
.cred-reveal {
    background: linear-gradient(160deg, #0f1b2d 0%, #14283f 100%);
    border-radius: 12px; padding: 1.5rem 1.5rem 1.35rem; color: #e7edf5;
    box-shadow: 0 10px 30px rgba(15,27,45,0.28); position: relative; overflow: hidden;
}
.cred-reveal::before { /* soft teal glow bleeding from the top-right, no icon-font dependency */
    content: ""; position: absolute; right: -6rem; top: -8rem;
    width: 20rem; height: 20rem; border-radius: 50%;
    background: radial-gradient(circle, rgba(15,118,110,0.28), transparent 62%);
    pointer-events: none;
}
.cred-seal {
    display: inline-flex; align-items: center; gap: 0.4rem;
    font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em;
    color: #fbbf24; background: rgba(251,191,36,0.12); border: 1px solid rgba(251,191,36,0.28);
    padding: 0.25rem 0.6rem; border-radius: 999px; margin-bottom: 1rem;
}
.cred-field-label {
    font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
    color: #7e93ad; margin: 0 0 0.4rem;
}
.cred-secret-row { display: flex; gap: 0.6rem; align-items: stretch; }
.cred-secret {
    flex: 1; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 15px; letter-spacing: 0.02em; color: #fff;
    background: rgba(0,0,0,0.28); border: 1px solid rgba(255,255,255,0.12);
    border-radius: 8px; padding: 0.7rem 0.85rem; overflow-x: auto; white-space: nowrap;
}
.cred-copy {
    display: inline-flex; align-items: center; gap: 0.4rem; flex-shrink: 0;
    padding: 0 1.1rem; font-size: 13px; font-weight: 600; cursor: pointer;
    color: #0f1b2d; background: #fbbf24; border: none; border-radius: 8px;
    transition: background 0.12s, transform 0.08s;
}
.cred-copy:hover { background: #fcd34d; }
.cred-copy:active { transform: translateY(1px); }
.cred-copy.done { background: #34d399; color: #063a2b; }
.cred-name {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13.5px;
    color: #cdd8e6; background: rgba(0,0,0,0.22); border: 1px solid rgba(255,255,255,0.1);
    border-radius: 6px; padding: 0.4rem 0.6rem; display: inline-block; margin-bottom: 1.1rem;
}
/* Usage snippet under the plate. */
.cred-usage { margin-top: 1.25rem; }
.cred-usage h3 { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: #8a97a8; margin: 0 0 0.5rem; }
.cred-snippet {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; line-height: 1.7;
    background: #0f1b2d; color: #d7e0ec; border-radius: 8px; padding: 0.9rem 1rem;
    overflow-x: auto; white-space: pre;
}
.cred-snippet .k { color: #7dd3fc; }
.cred-snippet .s { color: #86efac; }
.cred-snippet .c { color: #64748b; }

@media (max-width: 640px) {
    .key-ledger .hide-sm { display: none; }
    .cred-secret-row { flex-direction: column; }
    .cred-copy { justify-content: center; padding: 0.6rem; }
}


/* ══════════════════════════════════════════════════════════════════════════
   PROFILE / SETTINGS AREA — identity banner, segmented nav, kv panels, JSON viewer
   Scoped under .settings so it never leaks into other console pages.
   ══════════════════════════════════════════════════════════════════════════ */
.settings { --s-accent: #206bc4; --s-teal: #0f766e; max-width: 940px; }

.settings .reveal-up { opacity: 0; transform: translateY(12px);
    animation: sReveal .55s cubic-bezier(.22,.61,.36,1) forwards; animation-delay: var(--d, 0s); }
@keyframes sReveal { to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .settings .reveal-up { animation: none; opacity: 1; transform: none; } }

/* ── Identity banner ── */
.settings-hero {
    position: relative; overflow: hidden;
    border-radius: 18px; padding: 28px 30px; color: #fff;
    background:
        radial-gradient(130% 150% at 100% 0%, rgba(15,118,110,.60), transparent 58%),
        linear-gradient(120deg, #0b3d91 0%, #1f6ac2 54%, #0f766e 122%);
    box-shadow: 0 14px 34px rgba(11,61,145,.30);
}
.settings-hero::before {
    content: ""; position: absolute; inset: 0;
    background-image: radial-gradient(rgba(255,255,255,.18) 1px, transparent 1.5px);
    background-size: 18px 18px; opacity: .5;
    -webkit-mask-image: linear-gradient(90deg, #000, transparent 72%);
            mask-image: linear-gradient(90deg, #000, transparent 72%);
}
.settings-hero::after {
    content: ""; position: absolute; right: -70px; top: -80px; width: 260px; height: 260px;
    background: radial-gradient(circle, rgba(255,255,255,.30), transparent 70%); filter: blur(4px);
}
.settings-hero__row { position: relative; display: flex; align-items: center; gap: 20px; }
.settings-hero__avatar {
    width: 74px; height: 74px; flex: 0 0 auto; border-radius: 21px;
    display: flex; align-items: center; justify-content: center;
    font-size: 27px; font-weight: 800; letter-spacing: .01em;
    background: rgba(255,255,255,.16); border: 1px solid rgba(255,255,255,.38);
    -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
    box-shadow: inset 0 1px 0 rgba(255,255,255,.45);
}
.settings-hero__id { min-width: 0; }
.settings-hero__name { font-size: 23px; font-weight: 800; letter-spacing: -.02em; line-height: 1.12; }
.settings-hero__email { font-size: 13.5px; color: rgba(255,255,255,.85); margin-top: 3px; }
.settings-hero__meta { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.settings-hero__meta .chip {
    background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.3); color: #fff;
}

/* ── Segmented sub-nav ── */
.settings-nav { display: flex; gap: 6px; margin: 18px 0 22px; flex-wrap: wrap; }
.settings-nav a {
    display: inline-flex; align-items: center; gap: 7px; text-decoration: none;
    padding: 9px 16px; border-radius: 11px; font-size: 13.5px; font-weight: 600;
    color: #475569; background: #fff; border: 1px solid #e6e9ef;
    transition: transform .16s, border-color .16s, color .16s, box-shadow .16s;
}
.settings-nav a:hover { color: var(--s-accent); border-color: #c9d6e8; transform: translateY(-1px); }
.settings-nav a.is-active {
    color: #fff; border-color: transparent;
    background: linear-gradient(120deg, #1f6ac2, #206bc4);
    box-shadow: 0 5px 14px rgba(32,107,196,.36);
}
.settings-nav a i { font-size: 16px; }

/* ── Card head ── */
.settings-card__head { display: flex; align-items: center; gap: 12px; padding: 18px 20px 8px; }
.settings-card__head .ic {
    width: 36px; height: 36px; border-radius: 10px; flex: 0 0 auto;
    display: flex; align-items: center; justify-content: center;
    background: var(--ac-blue-soft); color: var(--s-accent); font-size: 18px;
}
.settings-card__head .ic.teal { background: rgba(15,118,110,.13); color: var(--s-teal); }
.settings-card__head h2 { font-size: 15px; font-weight: 700; margin: 0; letter-spacing: -.01em; }
.settings-card__head p { font-size: 12.5px; color: #6b7a90; margin: 2px 0 0; }
.settings-card__body { padding: 6px 20px 20px; }

/* ── Key/value grid ── */
.kv { display: grid; grid-template-columns: 200px 1fr; gap: 1px;
    background: #eef1f5; border: 1px solid #eef1f5; border-radius: 12px; overflow: hidden; }
.kv dt, .kv dd { background: #fff; padding: 12px 16px; margin: 0; font-size: 13.5px; }
.kv dt { color: #6b7a90; font-weight: 600; font-size: 12.5px; }
.kv dd { color: #1a2332; word-break: break-word; }
.kv dd code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; }
@media (max-width: 640px) { .kv { grid-template-columns: 1fr; } .kv dt { padding-bottom: 2px; } }

/* ── Chips ── */
.chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: 999px;
    font-size: 12px; font-weight: 600; background: #f1f5f9; color: #334155; border: 1px solid #e2e8f0; }
.chip i { font-size: 13px; }
.chip.chip-accent { background: var(--ac-blue-soft); color: var(--s-accent); border-color: transparent; }
.chip.chip-teal { background: rgba(15,118,110,.12); color: var(--s-teal); border-color: transparent; }
.chip.chip-owner { background: #fff7e6; color: #b45309; border-color: #fde3a7; }
.chip-row { display: flex; gap: 6px; flex-wrap: wrap; }
.chip-empty { color: #94a3b8; font-size: 12.5px; }

/* ── Terminal-style JSON viewer ── */
.code-panel { border-radius: 13px; overflow: hidden; border: 1px solid #1e293b;
    box-shadow: var(--ac-shadow-md); margin-top: 16px; }
.code-panel__bar { display: flex; align-items: center; gap: 10px; padding: 10px 14px;
    background: #0b1220; border-bottom: 1px solid #1e293b; }
.code-panel__dots { display: flex; gap: 6px; }
.code-panel__dots i { width: 11px; height: 11px; border-radius: 50%; display: inline-block; }
.code-panel__dots i:nth-child(1) { background: #ff5f57; }
.code-panel__dots i:nth-child(2) { background: #febc2e; }
.code-panel__dots i:nth-child(3) { background: #28c840; }
.code-panel__title { color: #94a3b8; font-size: 12px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.code-panel__copy { margin-left: auto; background: #1e293b; color: #cbd5e1; border: 1px solid #334155;
    border-radius: 7px; padding: 5px 11px; font-size: 12px; font-weight: 600; cursor: pointer;
    display: inline-flex; gap: 6px; align-items: center; transition: .15s; }
.code-panel__copy:hover { background: #334155; color: #fff; }
.code-panel pre { margin: 0; padding: 16px 18px; background: #0f172a; color: #e2e8f0;
    font-size: 12.5px; line-height: 1.65; max-height: 460px; overflow: auto;
    white-space: pre-wrap; word-break: break-word; }

/* ── Settings: simple data table + inline actions ── */
.settings .tbl { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.settings .tbl th { text-align: left; font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em;
    color: #6b7a90; font-weight: 700; padding: 9px 12px; border-bottom: 1px solid #e6e9ef; }
.settings .tbl td { padding: 11px 12px; border-bottom: 1px solid #f0f2f5; vertical-align: middle; }
.settings .tbl tr:last-child td { border-bottom: none; }
.settings .tbl code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; }
.settings .btn-mini { background: #fff; border: 1px solid #e6e9ef; color: #475569; border-radius: 7px;
    padding: 4px 11px; font-size: 12px; font-weight: 600; cursor: pointer; transition: .15s; }
.settings .btn-mini:hover { border-color: #d63939; color: #d63939; }
.chip.chip-danger { background: #fdeaea; color: #d63939; border-color: #f7c9c9; }
.chip.chip-muted  { background: #f1f5f9; color: #94a3b8; border-color: #e2e8f0; }

/* ══════════════════════════════════════════════════════════════════════════
   MAIL SETTING — test result panel
   A mail test either works or leaves you guessing, so the result is a panel
   rather than a one-line banner: it has to carry WHICH step failed, against
   which server, and where a message actually went. A green tick alone is the
   least useful thing this screen can say.
   ══════════════════════════════════════════════════════════════════════════ */
.mail-result { margin-bottom: 1rem; border-left: 3px solid transparent; overflow: hidden; }
.mail-result.is-ok  { border-left-color: var(--ac-teal); }
.mail-result.is-bad { border-left-color: var(--ac-danger); }

.mail-result__head { display: flex; align-items: flex-start; gap: 12px; padding: 16px 20px 12px; }
.mail-result__icon {
    width: 34px; height: 34px; border-radius: 10px; flex: 0 0 auto;
    display: flex; align-items: center; justify-content: center; font-size: 19px;
}
.mail-result.is-ok  .mail-result__icon { background: rgba(15,118,110,.12); color: var(--ac-teal); }
.mail-result.is-bad .mail-result__icon { background: #fdeaea; color: var(--ac-danger); }

.mail-result__title { flex: 1 1 auto; min-width: 0; }
.mail-result__title h2 { font-size: 15px; font-weight: 700; margin: 0; letter-spacing: -.01em; }
.mail-result__title p  { font-size: 13px; color: #52606d; margin: 3px 0 0; line-height: 1.5; }

/* Elapsed time is diagnostic: a 20s failure is a timeout, a 40ms one is a refused connection. */
.mail-result__timing {
    flex: 0 0 auto; font-size: 11.5px; font-weight: 600; color: #94a3b8;
    font-variant-numeric: tabular-nums; padding-top: 4px;
}

.mail-result__body { padding: 0 20px 18px; }

/* ── Per-step trace ── */
.mail-steps { list-style: none; margin: 0 0 14px; padding: 0; display: grid; gap: 2px; }
.mail-step {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 9px 12px; border-radius: 9px; background: #f8fafc; font-size: 13px;
}
.mail-step i {
    flex: 0 0 auto; width: 18px; height: 18px; border-radius: 50%; margin-top: 1px;
    display: flex; align-items: center; justify-content: center; font-size: 12px; color: #fff;
}
.mail-step.is-ok   i { background: var(--ac-teal); }
.mail-step.is-bad  i { background: var(--ac-danger); }
.mail-step.is-skip i { background: #cbd5e1; }
.mail-step.is-skip   { opacity: .6; }
.mail-step__name   { font-weight: 600; color: #1a2332; }
.mail-step__detail { display: block; color: #6b7a90; font-size: 12.5px; margin-top: 1px; word-break: break-word; }

.mail-result__facts { margin-top: 2px; }

.mail-result__note {
    display: flex; align-items: flex-start; gap: 7px;
    margin: 12px 0 0; font-size: 12.5px; color: #6b7a90; line-height: 1.55;
}
.mail-result__note i { flex: 0 0 auto; margin-top: 2px; }
.mail-result__note.is-warn { color: #92400e; }

/* ── The two test actions ──
   Stacked rows rather than a button cluster: each test answers a different question, and the
   difference between "sends nothing" and "mails a real person" is worth a sentence each. */
.mail-tests { display: grid; gap: 10px; }
.mail-test {
    display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
    padding: 13px 15px; border: 1px solid #eef1f5; border-radius: 11px; background: #fcfdfe;
}
.mail-test__text { flex: 1 1 240px; min-width: 0; }
.mail-test__text h3 { font-size: 13.5px; font-weight: 700; margin: 0; color: #1a2332; }
.mail-test__text p  { font-size: 12.5px; color: #6b7a90; margin: 2px 0 0; line-height: 1.5; }
.mail-test form { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

@media (max-width: 560px) {
    .mail-test { align-items: stretch; }
    .mail-test form { width: 100%; }
    .mail-test form .form-input { flex: 1 1 auto; max-width: none !important; }
}

/* Spinner for the in-flight test button. An SMTP connect can take the full 20s timeout, which
   without feedback reads as "nothing happened" and invites a second click. */
@keyframes sr-spin { to { transform: rotate(360deg); } }
.spin { display: inline-block; animation: sr-spin .8s linear infinite; }
@media (prefers-reduced-motion: reduce) { .spin { animation: none; } }

/* ── My VPN · access pass ───────────────────────────────────
   The Info tab renders each VPN profile as an access pass rather than a table row: an identity, a
   validity window, and the gate it opens. Built entirely from the existing tokens (--ac-blue,
   --ac-teal, --ac-gray) so the page still reads as part of this console — the personality comes from
   the type treatment and the validity meter, not from a new palette.

   Personality note: the common name is set in the house MONO face at display size. It is a machine
   credential, so letting the type say so does more than a decorative display face would, and adds no
   new font dependency. */
.pass-card {
    position: relative;
    overflow: hidden;
    padding: 1.5rem 1.6rem 1.5rem 2.1rem;   /* extra left padding clears the stripe */
    max-width: 720px;
}
.pass-card + .pass-card { margin-top: 1rem; }

/* State belongs to the whole pass, not to one cell — so it is the card's edge. */
.pass-stripe {
    position: absolute; inset: 0 auto 0 0; width: 4px;
    background: var(--ac-gray);
}
.pass-stripe.is-ok   { background: var(--ac-teal); }
.pass-stripe.is-bad  { background: #b42318; }
.pass-stripe.is-idle { background: #94a3b8; }

.pass-body {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 1.25rem; flex-wrap: wrap;
}
/* Takes the slack so a long common name wraps inside the card instead of pushing the status badge
   off the end. min-width:0 is what actually lets a flex child shrink below its content width. */
.pass-identity { flex: 1 1 16rem; min-width: 0; }

/* Uppercase tracked micro-labels: they label, and nothing else. */
.pass-label {
    display: block;
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
    color: #8a94a6;
}

.pass-cn {
    margin: 0.35rem 0 0;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: clamp(1.15rem, 2.4vw, 1.55rem);
    font-weight: 600; letter-spacing: -0.01em; line-height: 1.15;
    color: #16202f;
    overflow-wrap: anywhere;                 /* long CNs must not blow out the card */
}
.pass-display { margin: 0.3rem 0 0; color: var(--ac-gray); font-size: 0.92rem; }

.pass-state { display: flex; align-items: center; gap: 0.75rem; flex-shrink: 0; }
.pass-live {
    display: inline-flex; align-items: center; gap: 0.4rem;
    font-size: 0.85rem; font-weight: 600; color: var(--ac-teal);
}

.pass-dot {
    width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
    background: var(--ac-teal);
}
.pass-dot.is-ok   { background: var(--ac-teal); }
.pass-dot.is-idle { background: #94a3b8; }

/* ── Signature: the validity meter ──────────────────────────
   One hairline rule carrying elapsed vs remaining certificate life. Time-bounded access is the truth
   of a credential, and this replaces three table columns with a single readable object. */
.pass-validity {
    margin-top: 1.4rem; padding-top: 1.25rem;
    border-top: 1px solid #e8ecf2;
}
.pass-validity-head {
    display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
}
.pass-validity-remaining {
    font-size: 0.88rem; font-weight: 650; color: var(--ac-gray);
    font-variant-numeric: tabular-nums;
}
.pass-validity-remaining.is-urgent { color: #b42318; }

.pass-meter {
    position: relative; height: 3px; margin: 0.6rem 0 0.5rem;
    background: #e8ecf2; border-radius: 2px; overflow: hidden;
}
.pass-meter-fill {
    position: absolute; inset: 0 auto 0 0;
    background: var(--ac-teal); border-radius: 2px;
}
.pass-meter-fill.is-urgent { background: #b42318; }

.pass-validity-foot {
    display: flex; justify-content: space-between; gap: 1rem;
    font-size: 0.78rem; color: #8a94a6; font-variant-numeric: tabular-nums;
}

/* ── The gate ───────────────────────────────────────────────
   Availability only. The hostname, port and protocol are deliberately absent: they are the tenant's
   infrastructure, and a customer user cannot act on them. */
.pass-gate {
    margin-top: 1.25rem; padding: 0.95rem 1.1rem;
    background: #f8fafc; border: 1px solid #eef1f6; border-radius: 10px;
}
.pass-gate-state {
    display: flex; align-items: center; gap: 0.5rem;
    margin: 0.4rem 0 0; font-weight: 650; color: #16202f;
}
.pass-gate-note { margin: 0.3rem 0 0; font-size: 0.85rem; color: var(--ac-gray); }

@media (max-width: 560px) {
    .pass-card { padding: 1.25rem 1.1rem 1.25rem 1.6rem; }
    .pass-state { width: 100%; }
    .pass-validity-foot { flex-direction: column; gap: 0.2rem; }
}

/* ── Vocabulary the views were improvising ──────────────────
   Each rule here replaces an inline style that had been copied across many views. They add no new
   appearance: the point is that there is now one place to change each of these, instead of ~20. */

/* The single-column form card. Was style="max-width:640px" in 18 views — and 760px/720px in a few
   others, which is the drift you get without a name for it. */
.card-form { max-width: 640px; }
/* Wider variant for forms that carry a table or a side-by-side pair. */
.card-form-wide { max-width: 760px; }

/* The trailing actions column in a list table. Was style="width:1%" on the th plus
   style="text-align:right; white-space:nowrap" on the td, in ten tables — two inline styles that had
   to agree with each other by hand. width:1% makes the cell shrink to its content, which is what
   keeps the buttons hugging the right edge. */
th.col-actions { width: 1%; }
td.col-actions { text-align: right; white-space: nowrap; }

/* A POST form sitting inline among row buttons (delete, impersonate, retry). Was
   style="display:inline" in 17 places. */
.form-inline { display: inline; }

/* Secondary text, now from the token. site.css also defines .text-muted with the same literal value;
   this declaration wins on load order and points it at --ac-muted so both routes agree. */
.text-muted { color: var(--ac-muted); }


/* Explanatory note under a form control or section heading. Was hand-written three times in
   Profile/Security as color + font-size + margin; the margins stay inline there because they differ
   per position, but the colour and size are the same idea every time. */
.form-note { color: var(--ac-muted); font-size: 13px; }
/* Fainter note, for the least-important line in a stack of help text. */
.form-note-faint { color: #94a3b8; font-size: 12.5px; }

/* Centred error line under an auth form. Was color:#c0392b inline on three screens — a red that did
   not match the badge red used elsewhere, so the same meaning had two colours depending on the
   element. Now from --ac-danger. */
.form-error-note { text-align: center; color: var(--ac-danger); }

/* Counterpart to form-error-note for a confirmation on the auth pages (e.g. "your password has been
   set — please sign in"). Same geometry so the two read as one slot, only the colour differs.
   Uses the existing --ac-teal accent rather than introducing a green: the palette has no green token,
   and adding a one-off hex here is how a design system starts drifting. */
.form-success-note { text-align: center; color: var(--ac-teal); }

/* An ordered list of real steps (enrolling an authenticator, recovering an account). Numbered markers
   are right here because the order genuinely matters — the reader must do these in sequence. */
.steps-list { color: #334155; font-size: 13.5px; line-height: 1.7; padding-left: 1.1rem; }

/* ── Server run receipts ────────────────────────────────────
   The Log tab on a VPN server. Each provisioning run is a receipt: outcome, what ran, how long, and
   the ordered steps it went through. Replaces three levels of nested card — a card inside a card
   inside a card — with one flat list, which is what let the newest run finally look different from the
   old ones. Built from existing tokens; no new colours or fonts. */
.card-runs { max-width: 960px; }

.run {
    padding: 1rem 0;
    border-top: 1px solid #eef1f6;
}
.run:first-child { border-top: 0; padding-top: 0.25rem; }

/* Recency is the hierarchy here: the run you just triggered is the one you came to read. A tinted
   panel and a little breathing room do that without another badge or border colour. */
.run.is-latest {
    background: #f8fafc;
    border-radius: 10px;
    padding: 1rem 1.1rem;
    margin-bottom: 0.5rem;
    border-top: 0;
}
.run.is-failed.is-latest { background: #fef6f5; }

.run-head { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }

/* Outcome as a glyph rather than a word: at three runs the shape is read faster than the label, and
   the status word is still on the message line when it matters. */
.run-status {
    width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 13px; color: #fff;
}
.run-status.is-ok      { background: var(--ac-teal); }
.run-status.is-failed  { background: var(--ac-danger); }
.run-status.is-pending { background: #94a3b8; }

/* The task type is a literal command name (check-ssh, setup, health) — mono says so. */
.run-type {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-weight: 600; font-size: 0.95rem; color: #16202f;
}
.run-tag { flex-shrink: 0; }

.run-when {
    margin-left: auto; font-size: 0.8rem; color: var(--ac-muted);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
.run-dur { margin-left: 0.45rem; padding-left: 0.45rem; border-left: 1px solid #dfe5ee; }

.run-msg { margin: 0.55rem 0 0 2.2rem; font-size: 0.88rem; color: var(--ac-gray); }
.run-msg.is-failed { color: var(--ac-danger); }

/* ── Signature: the step ladder ─────────────────────────────
   The Engine writes "[step] detail" per line. Parsed into rows, a failed run shows exactly where it
   stopped without expanding anything — previously that was buried behind a "Full output" disclosure,
   so the most useful content on the page was the one thing you had to click for.
   Numbered markers are justified here because this genuinely IS a sequence: the reader needs to know
   which step came before the one that broke. */
.run-steps {
    list-style: none;
    margin: 0.7rem 0 0 2.2rem;
    padding: 0;
    counter-reset: runstep;
}
.run-steps li {
    counter-increment: runstep;
    display: flex; align-items: baseline; gap: 0.6rem;
    padding: 0.28rem 0;
    font-size: 0.84rem;
    border-bottom: 1px dashed #eef1f6;
}
.run-steps li:last-child { border-bottom: 0; }
.run-steps li::before {
    content: counter(runstep);
    flex-shrink: 0; min-width: 1.15rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.72rem; color: #b3bdcc; text-align: right;
    font-variant-numeric: tabular-nums;
}
.run-step-name {
    flex-shrink: 0; min-width: 7.5rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-weight: 600; color: #16202f;
}
.run-step-detail { color: var(--ac-gray); overflow-wrap: anywhere; }

.run-more { margin: 0.6rem 0 0 2.2rem; }
.run-more > summary {
    cursor: pointer; font-size: 0.82rem; color: var(--ac-blue); width: fit-content;
}
.run-more > summary:hover { text-decoration: underline; }
.run-more .run-steps { margin-left: 0; }

.run-raw {
    margin: 0.5rem 0 0;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.78rem; line-height: 1.6; white-space: pre-wrap;
    color: var(--ac-gray); background: #f8fafc;
    padding: 0.7rem 0.85rem; border-radius: 8px; overflow: auto;
}

.run-foot { margin: 1rem 0 0; }

@media (max-width: 560px) {
    .run-when { margin-left: 0; width: 100%; }
    .run-msg, .run-steps, .run-more { margin-left: 0; }
    .run-steps li { flex-wrap: wrap; }
    .run-step-name { min-width: 0; }
}
