/* The platform's one stylesheet. Hand-written, no framework; the pages carry
   no inline style (the Content-Security-Policy refuses it).

   Colours: light by default. Dark when the operator chose it
   (<html data-theme="dark">, written by the server) or, when they chose
   nothing or nobody is signed in, when the device asks for it. The dark
   values are therefore written twice below -- keep the two blocks the same. */

:root {
    --bg:           #f4f5f7;
    --surface:      #ffffff;
    --border:       #dfe2e8;
    --text:         #1b1f27;
    --text-muted:   #5d6573;
    --primary:      #1f4fd8;
    --primary-text: #ffffff;
    --env-dev:      #8a5a00;
    --env-dev-bg:   #fff1cc;
    --env-live:     #8f1d1d;
    --env-live-bg:  #fde2e2;
    --ok:           #17603a;
    --ok-bg:        #dff5e7;
    --danger:       #b42318;
    --hover:        #eceef2;
    --shadow:       0 12px 32px rgba(17, 24, 39, 0.18);
    --radius:       8px;
    --topbar-h:     3.25rem;
    --nav-w:        14rem;
    --nav-w-closed: 3.5rem;
    --font:         -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

:root[data-theme="dark"] {
    --bg:           #12151b;
    --surface:      #1b1f27;
    --border:       #2c323d;
    --text:         #e8eaee;
    --text-muted:   #9aa3b2;
    --primary:      #6f93ff;
    --primary-text: #0b1020;
    --env-dev:      #ffd77a;
    --env-dev-bg:   #3b2e0a;
    --env-live:     #ff9c9c;
    --env-live-bg:  #401515;
    --ok:           #8fe0ae;
    --ok-bg:        #12351f;
    --danger:       #ff8a80;
    --hover:        #252a34;
    --shadow:       0 12px 32px rgba(0, 0, 0, 0.5);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --bg:           #12151b;
        --surface:      #1b1f27;
        --border:       #2c323d;
        --text:         #e8eaee;
        --text-muted:   #9aa3b2;
        --primary:      #6f93ff;
        --primary-text: #0b1020;
        --env-dev:      #ffd77a;
        --env-dev-bg:   #3b2e0a;
        --env-live:     #ff9c9c;
        --env-live-bg:  #401515;
        --ok:           #8fe0ae;
        --ok-bg:        #12351f;
        --danger:       #ff8a80;
        --hover:        #252a34;
        --shadow:       0 12px 32px rgba(0, 0, 0, 0.5);
    }
}

* { box-sizing: border-box; }

/* "hidden" means hidden, whatever display a class gives the element. */
[hidden] { display: none !important; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font);
    font-size: 15px;
    line-height: 1.5;
}

/* --- Buttons --- */
.btn {
    display: inline-block;
    padding: 0.6rem 1.1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.btn-primary { background: var(--primary); border-color: var(--primary); color: var(--primary-text); }
.btn-secondary { background: var(--surface); border-color: var(--border); color: var(--text); }
.btn-danger { background: var(--danger); border-color: var(--danger); color: var(--surface); }
.btn-block { display: block; width: 100%; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* --- Environment badge: never mistake live for dev --- */
.env-badge {
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
}
.env-dev  { background: var(--env-dev-bg);  color: var(--env-dev); }
.env-live { background: var(--env-live-bg); color: var(--env-live); }

/* --- Sign-in and enrolment (views/auth.view.php) --- */
.auth-body {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.auth-card {
    width: 100%;
    max-width: 22rem;
    padding: 2rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.auth-brand {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1.5rem;
}
.brand-name { font-weight: 700; letter-spacing: 0.02em; }
.auth-title { margin: 0 0 0.5rem; font-size: 1.3rem; }
.auth-text  { margin: 0 0 1.25rem; color: var(--text-muted); }

.auth-card .btn-block + .btn-block,
.auth-card form { margin-top: 0.6rem; }

/* --- Messages --- */
.notice {
    margin: 0.9rem 0 0;
    padding: 0.55rem 0.75rem;
    border-radius: var(--radius);
    font-size: 0.9rem;
}
.notice[hidden] { display: none; }
.notice-ok    { margin: 0 0 1rem; background: var(--ok-bg); color: var(--ok); }
.notice-error { background: var(--env-live-bg); color: var(--env-live); }
.notice-info  { background: var(--bg); color: var(--text-muted); }
.notice-above { margin: 0 0 1rem; }
.notice-warn  { margin: 0 0 1rem; background: var(--env-dev-bg); color: var(--env-dev); }
.missing-list { margin: 0.35rem 0 0; padding-left: 1.2rem; }

/* --- Form fields --- */
.field-label { display: block; margin: 0 0 0.3rem; font-size: 0.85rem; font-weight: 600; }
.field-input {
    display: block;
    width: 100%;
    margin: 0 0 0.8rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    font: inherit;
}
.field-input:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }

/* --- An operator's keys --- */
.key-list { list-style: none; margin: 0 0 1.25rem; padding: 0; border: 1px solid var(--border); border-radius: var(--radius); }
.key-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.55rem 0.75rem;
}
.key-item + .key-item { border-top: 1px solid var(--border); }
.key-name { font-weight: 600; overflow-wrap: anywhere; }
.key-kind {
    flex: none;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
}
.key-kind-hardware { background: var(--ok-bg); color: var(--ok); }
.key-kind-synced   { background: var(--bg); color: var(--text-muted); border: 1px solid var(--border); }

/* --- The error page (complex/base/errorhandler.class.php) --- */
.error-card { max-width: 26rem; }
.error-ref { margin: 0 0 1.25rem; color: var(--text-muted); font-size: 0.9rem; }
.error-ref-code {
    margin-left: 0.35rem;
    padding: 0.1rem 0.45rem;
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text);
    font-family: ui-monospace, Consolas, "Courier New", monospace;
    letter-spacing: 0.08em;
}
.error-actions { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.error-actions .btn { text-decoration: none; }
/* Only shown when Config::DEBUG is on. */
.error-card pre {
    margin: 0 0 1.25rem;
    padding: 0.75rem;
    background: var(--bg);
    border-radius: 4px;
    font-size: 0.75rem;
    white-space: pre-wrap;
    word-break: break-word;
}

/* --- Icons: 24x24 stroke drawings (Shell::Icon in vault/classes, CMPLX.popup) --- */
.icon {
    flex: none;
    width: 1.25rem;
    height: 1.25rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* --- The signed-in layout (views/shell.view.php, assets/scripts/shell.js) ---
   A top bar across the page, the side menu under it on the left, the page
   beside the menu. <html class="menu-closed">: the menu shows only its icons.
   Under 800px the menu is out of sight until <html class="menu-open"> slides
   it over the page. */
.shell-body { min-height: 100vh; }

.skip-link {
    position: absolute;
    left: 0.5rem;
    top: -4rem;
    z-index: 40;
    padding: 0.5rem 0.9rem;
    border-radius: var(--radius);
    background: var(--primary);
    color: var(--primary-text);
}
.skip-link:focus { top: 0.5rem; }

.topbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    height: var(--topbar-h);
    padding: 0 1rem 0 0.6rem;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
}
.topbar .brand-name { color: var(--text); text-decoration: none; }
.topbar-gap { flex: 1; }

.icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border: 0;
    border-radius: var(--radius);
    background: transparent;
    color: var(--text);
    cursor: pointer;
}
.icon-btn:hover { background: var(--hover); }
.icon-btn:focus-visible,
.account-btn:focus-visible,
.account-item:focus-visible,
.nav-item:focus-visible,
.brand-name:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* The session countdown. Amber in the last two minutes, and in the last ten
   before the 8-hour limit. */
.session-clock {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    color: var(--text-muted);
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.session-clock .icon { width: 1rem; height: 1rem; }
.session-clock.is-soon { background: var(--env-dev-bg); color: var(--env-dev); font-weight: 600; }

.account { position: relative; }
.account-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0.5rem 0.3rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    cursor: pointer;
}
.account-btn:hover { background: var(--hover); }
.account-who { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.2; }
.account-name { max-width: 12rem; overflow: hidden; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
.account-role { color: var(--text-muted); font-size: 0.75rem; }
.account-btn .icon { width: 1rem; height: 1rem; color: var(--text-muted); }

.account-menu {
    position: absolute;
    top: calc(100% + 0.4rem);
    right: 0;
    min-width: 13rem;
    padding: 0.35rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}
.account-menu form { margin: 0; }
.account-item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.5rem 0.6rem;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--text);
    font: inherit;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}
.account-item:hover { background: var(--hover); }
.account-item .icon { color: var(--text-muted); }

.sidenav {
    position: fixed;
    top: var(--topbar-h);
    bottom: 0;
    left: 0;
    z-index: 20;
    width: var(--nav-w);
    padding: 0.6rem 0.5rem;
    overflow-x: hidden;
    overflow-y: auto;
    background: var(--surface);
    border-right: 1px solid var(--border);
}
.nav-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    height: 2.5rem;
    padding: 0 0.65rem;
    border-radius: var(--radius);
    color: var(--text-muted);
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}
.nav-item + .nav-item { margin-top: 0.15rem; }
.nav-item:hover { background: var(--hover); color: var(--text); }
.nav-item.is-current { background: var(--bg); color: var(--primary); }
.sidenav-shade { display: none; }

.content {
    max-width: 62rem;
    margin-left: var(--nav-w);
    padding: calc(var(--topbar-h) + 1.5rem) 1.5rem 3rem;
}
.page-title { margin: 0 0 1.25rem; font-size: 1.4rem; }

@media (min-width: 800px) {
    .menu-closed .sidenav { width: var(--nav-w-closed); }
    .menu-closed .nav-label { display: none; }
    .menu-closed .content { margin-left: var(--nav-w-closed); }
}

@media (max-width: 799.98px) {
    .sidenav { transform: translateX(-100%); visibility: hidden; box-shadow: var(--shadow); }
    .menu-open .sidenav { transform: none; visibility: visible; }
    .menu-open .sidenav-shade {
        display: block;
        position: fixed;
        inset: var(--topbar-h) 0 0 0;
        z-index: 15;
        background: rgba(17, 24, 39, 0.45);
    }
    .content { margin-left: 0; padding-left: 1rem; padding-right: 1rem; }
    .account-role { display: none; }
    .account-name { max-width: 7rem; }
}
@media (max-width: 479.98px) {
    .clock-label { display: none; }
    .session-clock { padding: 0.2rem 0.45rem; }
}

@media (prefers-reduced-motion: no-preference) {
    .sidenav { transition: width 160ms ease, transform 160ms ease; }
    .content { transition: margin-left 160ms ease; }
}

/* --- Cards: one block of a page --- */
.card {
    margin: 0 0 1rem;
    padding: 1.1rem 1.25rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.card-warn { border-color: var(--env-dev); }
.card-title { margin: 0 0 0.75rem; font-size: 1rem; }
.card-text { margin: 0; color: var(--text-muted); }
.card-text + .row-list { margin-top: 0.6rem; }
.card-note { margin: 0.9rem 0 0; color: var(--text-muted); font-size: 0.9rem; }
.card-list { margin: 0; padding-left: 1.2rem; }
.card-list li + li { margin-top: 0.3rem; }
.card .notice { margin: 0 0 0.9rem; }

/* Label and value pairs. */
.facts { display: grid; grid-template-columns: max-content 1fr; gap: 0.35rem 1.25rem; margin: 0; }
.facts dt { color: var(--text-muted); }
.facts dd { margin: 0; overflow-wrap: anywhere; }

.row-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--border); border-radius: var(--radius); }
.row-item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.25rem 1rem;
    padding: 0.55rem 0.75rem;
    overflow-wrap: anywhere;
}
.row-item + .row-item { border-top: 1px solid var(--border); }
.row-side { color: var(--text-muted); font-size: 0.9rem; }

/* --- Lists with actions, small controls (My account, and the screens after it) --- */
a { color: var(--primary); }

.btn-small { padding: 0.25rem 0.7rem; font-size: 0.85rem; }
.btn-quiet-danger { color: var(--danger); }
.btn-quiet-danger:hover { border-color: var(--danger); }

.facts dd .btn-small { margin-left: 0.6rem; }
.facts-middle { align-items: center; }

.row-main { display: flex; flex: 1 1 16rem; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.6rem; min-width: 0; }
.row-sub { flex-basis: 100%; color: var(--text-muted); font-size: 0.85rem; }
.row-actions { display: flex; flex: none; gap: 0.4rem; }
.row-bad .row-side { color: var(--danger); font-weight: 600; }

.card-subtitle { margin: 1.4rem 0 0.6rem; font-size: 0.95rem; }
.card-actions { margin: 0.9rem 0 0; }
.card-note a { white-space: nowrap; }

/* Label, field and button on one line; stacked on a phone. */
.inline-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.6rem; margin-top: 1.1rem; }
.inline-field { flex: 1 1 14rem; max-width: 22rem; }
.inline-field .field-input { margin: 0; }
.field-inline { width: auto; margin: 0; }

/* One of a few: the pressed one is the current choice. */
.choice { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.choice-item {
    padding: 0.35rem 0.85rem;
    border: 0;
    background: var(--surface);
    color: var(--text-muted);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.choice-item + .choice-item { border-left: 1px solid var(--border); }
.choice-item:hover { background: var(--hover); color: var(--text); }
.choice-item[aria-pressed="true"] { background: var(--primary); color: var(--primary-text); }
.choice-item:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }

/* --- Tables, filters and paging (the audit viewer, and the lists after it) --- */
.table-wrap {
    margin: 0 0 1rem;
    overflow-x: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.table th, .table td { padding: 0.5rem 0.75rem; text-align: left; vertical-align: top; }
.table th { color: var(--text-muted); font-size: 0.8rem; font-weight: 600; white-space: nowrap; border-bottom: 1px solid var(--border); }
.table tbody tr + tr td { border-top: 1px solid var(--border); }
.table tbody tr:hover td { background: var(--hover); }
.nowrap { white-space: nowrap; }
.muted { color: var(--text-muted); }

/* What went wrong stands out without being filtered for. */
.outcome { font-weight: 600; }
.outcome-denied td { background: var(--env-dev-bg); }
.outcome-failed td { background: var(--env-live-bg); }
.outcome-denied .outcome, .outcome.outcome-denied { color: var(--env-dev); }
.outcome-failed .outcome, .outcome.outcome-failed { color: var(--env-live); }
.table tbody tr.outcome-denied:hover td { background: var(--env-dev-bg); }
.table tbody tr.outcome-failed:hover td { background: var(--env-live-bg); }
.card-bad { border-color: var(--env-live); }

.filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem 1rem; }
/* Two to a row on a phone, as many as fit on a wide screen. */
.filter { flex: 1 1 8rem; min-width: 7.5rem; max-width: 13rem; }
.filter .field-input { margin: 0; }
.filter-pair { display: flex; gap: 0.4rem; }
.filter-pair .field-input { min-width: 0; }
.filter-pair input { flex: 0 0 5.5rem; }
.filter-buttons { display: flex; flex: 0 0 auto; gap: 0.5rem; min-width: 0; }
.filter-buttons .btn { text-decoration: none; }

.pager { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 1rem; }
.pager .btn, .card-actions .btn { text-decoration: none; }

/* The chain's status, on top of every page of the viewer. */
.chain-line {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    margin: 0 0 1rem;
    color: var(--text-muted);
    font-size: 0.9rem;
}
.chain-line.notice { padding: 0.7rem 0.9rem; }
.chain-line .btn { flex: none; }

.code {
    padding: 0.05rem 0.35rem;
    border: 1px solid var(--border);
    border-radius: 4px;
    font-family: ui-monospace, Consolas, "Courier New", monospace;
    font-size: 0.85em;
}
.code-hash { overflow-wrap: anywhere; }
.facts .code-plain { margin-left: 0; color: var(--text); }
.fact-link { margin-left: 0.6rem; font-size: 0.9rem; white-space: nowrap; }
.fact-more { display: block; margin-top: 0.25rem; font-size: 0.9rem; }
.card-notice { margin: 0 0 0.9rem; }
.facts .code { margin-left: 0.4rem; color: var(--text-muted); }
.card-text-gap { margin-bottom: 0.9rem; }

/* --- Operators --- */
.state {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
}
.state-active   { background: var(--ok-bg); color: var(--ok); }
.state-invited  { background: var(--env-dev-bg); color: var(--env-dev); }
.state-org-trial, .state-org-cancelled { background: var(--env-dev-bg); color: var(--env-dev); }
.state-org-active { background: var(--ok-bg); color: var(--ok); }
.state-org-past_due, .state-org-restricted { background: var(--env-dev-bg); color: var(--env-dev); }
.state-org-suspended { background: var(--danger); color: #fff; }
.state-org-closed { background: var(--bg); color: var(--text-muted); border: 1px solid var(--border); }
.note-body { display: block; white-space: normal; overflow-wrap: anywhere; }
.state-disabled { background: var(--bg); color: var(--text-muted); border: 1px solid var(--border); }
.state + .muted { margin-left: 0.4rem; font-size: 0.85rem; }

.note-under { margin: -0.5rem 0 1rem; }
.filter-wide { flex: 2 1 12rem; max-width: 20rem; }

/* A number with what it counts beside it (Settings). */
.field-with-unit { display: flex; align-items: center; gap: 0.5rem; }
.field-with-unit .field-input { flex: 1 1 auto; min-width: 0; }
.note-above { margin: 0 0 1rem; }
.setting + .setting { border-top: 1px solid var(--border); padding-top: 1rem; }

/* Several of a few: a row of tick boxes under one label (an operator's roles). */
.checks { border: 0; margin: 0; padding: 0; min-width: 0; max-width: none; flex: 1 1 100%; }
.checks > legend { padding: 0; }
.checks-list { margin-top: 0.75rem; }
.checks-list .check { display: flex; margin-right: 0; }
.checks-list .check-child { margin-left: 1.6rem; }
.check { display: inline-flex; align-items: center; gap: 0.4rem; margin: 0 1rem 0.35rem 0; cursor: pointer; }
.check input { width: 1rem; height: 1rem; margin: 0; accent-color: var(--primary); }
.card > .filters, .manage-row > .filters { margin: 0; }

/* One thing an Owner may do, with its own Save: a line between each. */
.manage-row { margin: 0; padding: 0 0 1rem; }
.manage-row + .manage-row { padding-top: 1rem; border-top: 1px solid var(--border); }
.manage-buttons { display: flex; flex-wrap: wrap; gap: 0.5rem; padding-bottom: 0; }

/* The one-time link in its popup: the link, Copy under it. */
.link-box { display: flex; flex-direction: column; gap: 0.6rem; }
.link-box .form-input { font-family: ui-monospace, Consolas, "Courier New", monospace; font-size: 0.8rem; }
.link-copied { min-height: 1.2em; margin: 0; color: var(--ok); font-size: 0.85rem; text-align: center; }

/* --- Popups: CMPLX.popup (assets/scripts/main.js) ---
   A native <dialog>; .popup__box is the card, the rest of the <dialog> is the
   click-to-dismiss backdrop. The class names are set by main.js and must stay
   as they are. These rules started as the ".popup" block of the SaaS main.css
   and were rewritten with this file's colours (docs/VENDORS.md).
   Close animation length = CMPLX.popup.closeMs (180ms). */
.popup {
    width: 100%;
    max-width: 24rem;
    padding: 1rem;
    margin: auto;
    border: none;
    background: transparent;
    overflow: visible;
    animation: popup-in 180ms ease;
}
.popup--wide { max-width: 32rem; }
.popup::backdrop {
    background: rgba(17, 24, 39, 0.45);
    animation: popup-fade-in 180ms ease;
}
.popup.is-closing { animation: popup-out 180ms ease forwards; }
.popup.is-closing::backdrop { animation: popup-fade-out 180ms ease forwards; }
.popup__box {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    padding: 2rem 1.5rem 1.5rem;
    text-align: center;
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: var(--shadow);
}
.popup__icon { width: 2.75rem; height: 2.75rem; color: var(--primary); }
.popup__icon--success { color: var(--ok); }
.popup__icon--warning { color: var(--env-dev); }
.popup__icon--error { color: var(--danger); }
.popup__title { margin: 0; font-size: 1.2rem; color: var(--text); overflow-wrap: anywhere; }
.popup__text { margin: 0; color: var(--text-muted); white-space: pre-line; overflow-wrap: anywhere; }
.popup__controls {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.75rem;
    width: 100%;
    margin-top: 0.75rem;
}
.popup__field { width: 100%; margin-top: 0.5rem; text-align: left; }
.popup__controls .btn { flex: 1 1 8rem; }
/* Choices top to bottom in the order given, Cancel moved to the bottom. */
.popup__controls--stacked { flex-direction: column; }
.popup__controls--stacked .popup__cancel { order: 1; }
.popup__controls--stacked .btn { flex: none; width: 100%; }
/* main.js gives the field of a select() popup these two class names. */
.popup .form-label { display: block; margin: 0 0 0.3rem; font-size: 0.85rem; font-weight: 600; }
.popup .form-input {
    display: block;
    width: 100%;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    font: inherit;
}
.popup .form-input:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
@keyframes popup-in { from { opacity: 0; transform: scale(0.94); } }
@keyframes popup-out { to { opacity: 0; transform: scale(0.94); } }
@keyframes popup-fade-in { from { opacity: 0; } }
@keyframes popup-fade-out { to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
    .popup, .popup::backdrop, .popup.is-closing, .popup.is-closing::backdrop { animation: none; }
}

/* --- A tree inside a table, and the picker that adds to it (SaaS roles) --- */
.table-wrap-inset { margin-top: 1rem; }
.table .cell-action { text-align: right; white-space: nowrap; }
.table-tree .tree-parent .tree-name { font-weight: 600; }
.table-tree .tree-child .tree-name { padding-left: 2.25rem; }
.table-tree .tree-partial .tree-name { font-weight: 400; color: var(--text-muted); }
.pick { text-align: left; }
.pick-list { max-height: 45vh; overflow-y: auto; margin-top: 0.75rem; padding: 0.5rem 0.25rem; border: 1px solid var(--border); border-radius: var(--radius); }
.pick-list .check { display: flex; margin: 0 0 0.4rem; }
.pick-list .check-child { margin-left: 1.6rem; }

/* --- Plans: a card in parts, fields inside a table --- */
.card-subtitle { margin: 1.25rem 0 0; font-size: 0.95rem; font-weight: 600; }
fieldset.plain { border: 0; margin: 0; padding: 0; min-width: 0; }
.table .field-input { margin: 0; }
.field-number { max-width: 9rem; }
.filter-button { align-self: flex-end; }
.state-disabled { background: var(--bg); color: var(--text-muted); border: 1px solid var(--border); }

/* --- Billing: amounts, an invoice, printing one --- */
.table .num, .num { text-align: right; font-variant-numeric: tabular-nums; }
.pre { white-space: pre-line; margin: 0; }
.state-invoice-open { background: var(--env-dev-bg); color: var(--env-dev); }
.state-invoice-overdue { background: var(--danger); color: #fff; }
.state-invoice-paid { background: var(--ok-bg); color: var(--ok); }
.state-invoice-void { background: var(--bg); color: var(--text-muted); border: 1px solid var(--border); }
.state-po-draft { background: var(--bg); color: var(--text-muted); border: 1px solid var(--border); }
.state-po-approved { background: var(--env-dev-bg); color: var(--env-dev); }
.state-po-closed { background: var(--ok-bg); color: var(--ok); }
.state-po-cancelled { background: var(--bg); color: var(--text-muted); border: 1px solid var(--border); text-decoration: line-through; }
.invoice-parties { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 1.25rem; margin: 0.75rem 0 0.5rem; }
.facts.totals { max-width: 22rem; margin-left: auto; }
.table tfoot th { border-top: 1px solid var(--border); padding: 0.5rem 0.75rem; }
.table-journal tbody tr.entry-first td { border-top: 1px solid var(--border); }
.table-journal tbody tr:not(.entry-first) td { border-top: 0; }
textarea.field-input { resize: vertical; font: inherit; }
@media print {
    .no-print, .side, .topbar, .shell-side, .shell-top, nav, header, aside { display: none !important; }
    body, .card { background: #fff !important; color: #000 !important; border: 0 !important; box-shadow: none !important; }
}
.table tr.row-head th { text-align: left; color: var(--text-muted); font-size: 0.8rem; padding-top: 1rem; }
.table tbody th { text-align: left; padding: 0.5rem 0.75rem; }

/* Charts (assets/scripts/charts.js): a figure the wrapper fills, beside the table it was made from. */
.chart { position: relative; height: 16rem; margin: 0.9rem 0 0; }
.chart[hidden] { display: none; }
.chart-data { margin-top: 0.9rem; }
.facts-below { margin-top: 1rem; }
.chart-data summary { cursor: pointer; color: var(--text-muted); font-size: 0.9rem; }
.chart-data .table-wrap { margin-top: 0.6rem; max-height: 22rem; overflow: auto; }
.range-picker { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 1rem; }
.range-picker .btn { text-decoration: none; }
.rule-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem 1rem; margin-top: 0.9rem; }
.rule-form .filter { flex: 1 1 10rem; }
.rule-form .filter-narrow { flex: 0 0 6rem; }

/* Alerts (stage 6) */
.state-alert-info { background: var(--bg); color: var(--text-muted); border: 1px solid var(--border); }
.state-alert-warning { background: var(--env-dev-bg); color: var(--env-dev); }
.state-alert-critical { background: var(--danger); color: #fff; }
.nav-badge { margin-left: auto; min-width: 1.3rem; padding: 0 0.35rem; border-radius: 0.65rem; background: var(--danger); color: #fff; font-size: 0.75rem; font-weight: 600; line-height: 1.3rem; text-align: center; }
.form-stack { margin-top: 1rem; }
.form-stack .field { margin: 0 0 1rem; }
.field-short { max-width: 16rem; }
.field-help { display: block; margin-top: 0.3rem; color: var(--text-muted); font-size: 0.85rem; }

/* The helpdesk (stage 7) */
.state-ticket-open { background: var(--env-dev-bg); color: var(--env-dev); }
.state-ticket-pending { background: var(--bg); color: var(--text-muted); border: 1px solid var(--border); }
.state-ticket-solved { background: var(--ok-bg); color: var(--ok); }
.state-ticket-closed { background: var(--bg); color: var(--text-muted); border: 1px solid var(--border); }
.state-priority-low { background: var(--bg); color: var(--text-muted); border: 1px solid var(--border); }
.state-priority-high { background: var(--env-dev-bg); color: var(--env-dev); }
.state-priority-urgent { background: var(--danger); color: #fff; }
.ticket-message { margin: 0 0 0.9rem; padding: 0.75rem 0.9rem; border: 1px solid var(--border); border-radius: 0.5rem; }
.ticket-message-operator { margin-left: 2rem; background: var(--bg); }
.ticket-message-note { margin-left: 2rem; border-style: dashed; border-color: var(--env-dev); }
.ticket-message-head { margin: 0 0 0.4rem; font-size: 0.9rem; }
.ticket-message-head .muted { margin-left: 0.4rem; }
.ticket-message-body { margin: 0; overflow-wrap: anywhere; }
textarea.field-input { width: 100%; resize: vertical; font: inherit; }

/* Privacy (stage 7) */
.sealed-text { max-height: 24rem; overflow: auto; margin: 0; padding: 0.75rem; border: 1px solid var(--border); border-radius: 0.4rem; background: var(--bg); font-size: 0.8rem; text-align: left; white-space: pre-wrap; overflow-wrap: anywhere; }

/* The health score (stage 8) */
.state-health-healthy { background: var(--ok-bg); color: var(--ok); }
.state-health-watch { background: var(--env-dev-bg); color: var(--env-dev); }
.state-health-at_risk { background: var(--danger); color: #fff; }
