/* ---------------------------------------------------------------------------
   Cortex Meridian admin panel — hand-written stylesheet.

   Design notes: a single blue accent lifted from the logo, everything else is
   neutral graphite. Surfaces are layered (window over desk), corners are
   generously rounded, borders are hairline, and shadows stay soft and low so
   the panel reads as calm rather than decorated.
   --------------------------------------------------------------------------- */

:root {
    --desk: #eceef1;
    --desk-tint: #f6f7f9;
    --surface: #ffffff;
    --surface-sunken: #f4f5f7;
    --hairline: rgba(16, 20, 32, 0.10);
    --hairline-soft: rgba(16, 20, 32, 0.06);

    --ink: #10131a;
    --ink-soft: #4b5361;
    --ink-faint: #838b98;

    --accent: #1f6fd0;
    --accent-deep: #17579f;
    --accent-wash: rgba(31, 111, 208, 0.10);

    --danger: #c0392f;
    --danger-wash: rgba(192, 57, 47, 0.09);
    --good: #1f7a4d;
    --good-wash: rgba(31, 122, 77, 0.10);
    --warn: #96601a;
    --warn-wash: rgba(150, 96, 26, 0.10);

    --r-sm: 7px;
    --r-md: 11px;
    --r-lg: 16px;
    --r-xl: 22px;

    --lift-1: 0 1px 1px rgba(16, 20, 32, 0.04), 0 2px 6px rgba(16, 20, 32, 0.05);
    --lift-2: 0 1px 2px rgba(16, 20, 32, 0.06), 0 12px 30px rgba(16, 20, 32, 0.10);
    --lift-3: 0 2px 4px rgba(16, 20, 32, 0.07), 0 26px 60px rgba(16, 20, 32, 0.16);

    --sidebar: 244px;
}

/* Dark palette, applied in two situations:
     1. the operating system asks for dark and the user has not overridden it,
     2. the user picked dark explicitly with the toggle.
   The token list is repeated for each because a media query cannot be shared
   with a plain selector — the values below must stay in step. */

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --desk: #16181d;
        --desk-tint: #1b1e24;
        --surface: #212429;
        --surface-sunken: #1a1d22;
        --hairline: rgba(255, 255, 255, 0.11);
        --hairline-soft: rgba(255, 255, 255, 0.06);

        --ink: #f0f2f5;
        --ink-soft: #a9b1bd;
        --ink-faint: #78808c;

        --accent: #4a95ec;
        --accent-deep: #6dabf2;
        --accent-wash: rgba(74, 149, 236, 0.16);

        --danger: #ec7069;
        --danger-wash: rgba(236, 112, 105, 0.14);
        --good: #55c68d;
        --good-wash: rgba(85, 198, 141, 0.14);
        --warn: #e2a25c;
        --warn-wash: rgba(226, 162, 92, 0.15);

        --lift-1: 0 1px 1px rgba(0, 0, 0, 0.30), 0 2px 6px rgba(0, 0, 0, 0.28);
        --lift-2: 0 1px 2px rgba(0, 0, 0, 0.35), 0 12px 30px rgba(0, 0, 0, 0.42);
        --lift-3: 0 2px 4px rgba(0, 0, 0, 0.40), 0 26px 60px rgba(0, 0, 0, 0.55);
    }
}

:root[data-theme="dark"] {
    --desk: #16181d;
    --desk-tint: #1b1e24;
    --surface: #212429;
    --surface-sunken: #1a1d22;
    --hairline: rgba(255, 255, 255, 0.11);
    --hairline-soft: rgba(255, 255, 255, 0.06);

    --ink: #f0f2f5;
    --ink-soft: #a9b1bd;
    --ink-faint: #78808c;

    --accent: #4a95ec;
    --accent-deep: #6dabf2;
    --accent-wash: rgba(74, 149, 236, 0.16);

    --danger: #ec7069;
    --danger-wash: rgba(236, 112, 105, 0.14);
    --good: #55c68d;
    --good-wash: rgba(85, 198, 141, 0.14);
    --warn: #e2a25c;
    --warn-wash: rgba(226, 162, 92, 0.15);

    --lift-1: 0 1px 1px rgba(0, 0, 0, 0.30), 0 2px 6px rgba(0, 0, 0, 0.28);
    --lift-2: 0 1px 2px rgba(0, 0, 0, 0.35), 0 12px 30px rgba(0, 0, 0, 0.42);
    --lift-3: 0 2px 4px rgba(0, 0, 0, 0.40), 0 26px 60px rgba(0, 0, 0, 0.55);
}

*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
                 Roboto, Helvetica, Arial, sans-serif;
    font-size: 14px;
    line-height: 1.55;
    color: var(--ink);
    background: var(--desk);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 {
    margin: 0;
    font-weight: 600;
    letter-spacing: -0.014em;
    line-height: 1.25;
}

h1 { font-size: 24px; }
h2 { font-size: 17px; }
h3 { font-size: 15px; }

p { margin: 0 0 12px; }
p:last-child { margin-bottom: 0; }

a {
    color: var(--accent);
    text-decoration: none;
}
a:hover { text-decoration: underline; }

img { max-width: 100%; display: block; }

:focus-visible {
    outline: 3px solid var(--accent-wash);
    outline-offset: 2px;
    border-radius: var(--r-sm);
}

/* --- Sign-in / password screens ------------------------------------------ */

.gate {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 32px 20px;
    background:
        radial-gradient(1100px 520px at 50% -12%, var(--accent-wash), transparent 70%),
        var(--desk);
}

.gate-card {
    width: 100%;
    max-width: 396px;
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-xl);
    box-shadow: var(--lift-3);
    overflow: hidden;
}

.gate-body { padding: 32px 30px; }

/* The artwork is transparent with near-black lettering, so it always sits on
   its own white plate — otherwise the wordmark disappears in dark mode. */
.gate-logo-plate {
    display: flex;
    justify-content: center;
    padding: 18px 22px;
    margin: 0 auto 22px;
    max-width: 300px;
    background: #ffffff;
    border: 1px solid var(--hairline-soft);
    border-radius: var(--r-lg);
    box-shadow: var(--lift-1);
}

.gate-logo-plate img {
    width: 100%;
    max-width: 250px;
    height: auto;
}

.gate-title {
    text-align: center;
    margin-bottom: 4px;
}

.gate-sub {
    text-align: center;
    color: var(--ink-soft);
    font-size: 13px;
    margin-bottom: 24px;
}

.gate-foot {
    margin-top: 22px;
    padding-top: 18px;
    border-top: 1px solid var(--hairline-soft);
    text-align: center;
    font-size: 13px;
    color: var(--ink-soft);
}

/* --- Forms ---------------------------------------------------------------- */

.field { margin-bottom: 16px; }

.field label,
.label {
    display: block;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.01em;
    color: var(--ink-soft);
    margin-bottom: 6px;
}

.input,
.textarea,
.select {
    width: 100%;
    padding: 9px 12px;
    font: inherit;
    color: var(--ink);
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-md);
    box-shadow: inset 0 1px 1px rgba(16, 20, 32, 0.04);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.textarea {
    min-height: 104px;
    resize: vertical;
    line-height: 1.6;
}

.input:focus,
.textarea:focus,
.select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3.5px var(--accent-wash);
}

.input[aria-invalid="true"],
.textarea[aria-invalid="true"] {
    border-color: var(--danger);
}

.hint {
    display: block;
    margin-top: 6px;
    font-size: 12px;
    color: var(--ink-faint);
}

.error {
    display: block;
    margin-top: 6px;
    font-size: 12px;
    color: var(--danger);
}

.check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--ink-soft);
    cursor: pointer;
}

.check input {
    width: 15px;
    height: 15px;
    accent-color: var(--accent);
    margin: 0;
}

.row-between {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

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

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 9px 16px;
    font: inherit;
    font-weight: 550;
    color: var(--ink);
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-md);
    box-shadow: var(--lift-1);
    cursor: pointer;
    transition: transform 0.12s ease, box-shadow 0.15s ease, background 0.15s ease;
}

.btn:hover { text-decoration: none; background: var(--surface-sunken); }
.btn:active { transform: translateY(1px); box-shadow: none; }

.btn-primary {
    color: #fff;
    background: linear-gradient(180deg, var(--accent), var(--accent-deep));
    border-color: transparent;
}

.btn-primary:hover {
    background: linear-gradient(180deg, var(--accent-deep), var(--accent-deep));
}

.btn-quiet {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    color: var(--ink-soft);
}

.btn-quiet:hover { background: var(--surface-sunken); color: var(--ink); }

.btn-danger { color: var(--danger); }
.btn-danger:hover { background: var(--danger-wash); }

.btn-wide { width: 100%; }
.btn-wide svg { width: 16px; height: 16px; flex: none; }
.btn-sm { padding: 6px 12px; font-size: 13px; }

/* --- Light / dark switch -------------------------------------------------- */

.theme-toggle {
    display: inline-grid;
    place-items: center;
    width: 34px;
    height: 34px;
    padding: 0;
    flex: none;
    color: var(--ink-soft);
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: 50%;
    box-shadow: var(--lift-1);
    cursor: pointer;
    transition: color 0.15s ease, background 0.15s ease, transform 0.12s ease;
}

.theme-toggle:hover { color: var(--accent); background: var(--surface-sunken); }
.theme-toggle:active { transform: scale(0.94); }

.theme-toggle svg {
    grid-area: 1 / 1;
    width: 17px;
    height: 17px;
}

/* Only the icon for the mode you can switch *to* is shown, so the button
   always reads as the action rather than the current state. */
.theme-toggle .icon-moon { display: block; }
.theme-toggle .icon-sun { display: none; }

:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: block; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .theme-toggle .icon-moon { display: none; }
    :root:not([data-theme="light"]) .theme-toggle .icon-sun { display: block; }
}

/* On the signed-out screens there is no top bar, so the switch floats in the
   corner of the window instead. */
.theme-toggle-floating {
    position: fixed;
    top: 18px;
    right: 18px;
    z-index: 10;
}

/* --- Notices -------------------------------------------------------------- */

.notice {
    display: flex;
    gap: 10px;
    padding: 11px 14px;
    border-radius: var(--r-md);
    font-size: 13px;
    margin-bottom: 18px;
    border: 1px solid transparent;
}

.notice-good {
    color: var(--good);
    background: var(--good-wash);
    border-color: var(--good-wash);
}

.notice-bad {
    color: var(--danger);
    background: var(--danger-wash);
    border-color: var(--danger-wash);
}

/* --- Application shell ---------------------------------------------------- */

.shell {
    display: grid;
    grid-template-columns: var(--sidebar) 1fr;
    min-height: 100vh;
    transition: grid-template-columns 0.22s cubic-bezier(0.4, 0, 0.2, 1);
}

.sidebar {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 18px 14px;
    background: var(--desk-tint);
    border-right: 1px solid var(--hairline);
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
    transition: padding 0.22s cubic-bezier(0.4, 0, 0.2, 1);
}

.brand-row {
    display: flex;
    align-items: center;
    gap: 4px;
    padding-bottom: 12px;
}

.brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 8px;
    min-width: 0;
    flex: 1;
}

.brand img { height: 46px; width: auto; flex: none; }

.brand-name {
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 0.01em;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    opacity: 1;
    transition: opacity 0.16s ease;
}

.brand-name small {
    display: block;
    font-weight: 450;
    font-size: 11px;
    color: var(--ink-faint);
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.sidebar-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 28px;
    height: 28px;
    border-radius: var(--r-md);
    border: 1px solid transparent;
    background: transparent;
    color: var(--ink-faint);
    cursor: pointer;
    transition: background 0.14s ease, color 0.14s ease, transform 0.22s cubic-bezier(0.4, 0, 0.2, 1);
}

.sidebar-toggle:hover {
    background: var(--hairline-soft);
    color: var(--ink);
}

.sidebar-toggle svg { width: 16px; height: 16px; transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1); }

.sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding-right: 2px;
    margin-right: -2px;
}

.sidebar-nav::-webkit-scrollbar { width: 6px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: var(--hairline); border-radius: 3px; }
.sidebar-nav::-webkit-scrollbar-track { background: transparent; }

.nav-label {
    white-space: nowrap;
    overflow: hidden;
    opacity: 1;
    transition: opacity 0.14s ease;
}

/* --- Collapsed sidebar ------------------------------------------------- */

html[data-sidebar="collapsed"] .shell { --sidebar: 76px; }

html[data-sidebar="collapsed"] .shell .sidebar { padding: 18px 12px; }

html[data-sidebar="collapsed"] .shell .brand-row { flex-direction: column-reverse; gap: 10px; justify-content: center; }
html[data-sidebar="collapsed"] .shell .brand { flex: none; padding: 4px; justify-content: center; }
html[data-sidebar="collapsed"] .shell .brand-name { width: 0; opacity: 0; pointer-events: none; }
html[data-sidebar="collapsed"] .shell .sidebar-toggle svg { transform: rotate(180deg); }

html[data-sidebar="collapsed"] .shell .nav-heading {
    height: 0;
    padding: 0;
    margin: 0;
    opacity: 0;
    overflow: hidden;
}

html[data-sidebar="collapsed"] .shell .nav-label,
html[data-sidebar="collapsed"] .shell .who-text,
html[data-sidebar="collapsed"] .shell .nav-count {
    width: 0;
    opacity: 0;
    overflow: hidden;
    white-space: nowrap;
    pointer-events: none;
}

/* gap: 0 matters here: the label and the count are squeezed to zero width,
   but as flex items they would still claim a gap each — which pushed the
   icon off-centre exactly on the links that carry an unread count. */
html[data-sidebar="collapsed"] .shell .nav-link,
html[data-sidebar="collapsed"] .shell .who { justify-content: center; padding-left: 0; padding-right: 0; gap: 0; }

html[data-sidebar="collapsed"] .shell .nav-link-sub { padding-left: 0; }
html[data-sidebar="collapsed"] .shell .nav-rung { display: none; }

html[data-sidebar="collapsed"] .shell .sidebar-foot form { display: flex; justify-content: center; }
html[data-sidebar="collapsed"] .shell .btn-wide { width: 34px; padding: 8px 0; overflow: hidden; gap: 0; }

/* --- Collapsed-sidebar tooltip ------------------------------------------ */
/* One fixed element, placed by sidebar.js beside whichever icon the pointer
   is over. Fixed rather than a ::after on the link because the nav scrolls,
   and a tooltip positioned inside a scroll container is clipped at its edge. */

.sidebar-tip {
    position: fixed;
    z-index: 90;
    padding: 5px 10px;
    border-radius: var(--r-sm);
    background: #14161b;
    color: #ffffff;
    font-size: 11.5px;
    font-weight: 550;
    letter-spacing: 0.01em;
    line-height: 1.3;
    white-space: nowrap;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3);
    pointer-events: none;
    opacity: 0;
    transform: translateY(-50%) translateX(-4px);
    transition: opacity 0.12s ease, transform 0.12s ease;
}

.sidebar-tip.is-on { opacity: 1; transform: translateY(-50%); }

/* The little arrow pointing back at the icon. */
.sidebar-tip::before {
    content: '';
    position: absolute;
    right: 100%;
    top: 50%;
    transform: translateY(-50%);
    border: 5px solid transparent;
    border-right-color: #14161b;
}

:root[data-theme="dark"] .sidebar-tip { background: #3a3f47; }
:root[data-theme="dark"] .sidebar-tip::before { border-right-color: #3a3f47; }

.nav-heading {
    padding: 12px 10px 6px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

.nav-link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--r-md);
    color: var(--ink-soft);
    font-weight: 500;
    transition: background 0.14s ease, color 0.14s ease;
}

.nav-link:hover {
    text-decoration: none;
    background: var(--hairline-soft);
    color: var(--ink);
}

.nav-link.is-active {
    background: var(--accent-wash);
    color: var(--accent);
    font-weight: 600;
}

.nav-link svg { width: 17px; height: 17px; flex: none; }

.sidebar-foot { margin-top: auto; }

.who {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 10px;
    border-radius: var(--r-md);
    background: var(--surface);
    border: 1px solid var(--hairline-soft);
    margin-bottom: 8px;
}

.who-text { min-width: 0; }

.who-text strong {
    display: block;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.who-text span {
    display: block;
    font-size: 11px;
    color: var(--ink-faint);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* --- Main column ---------------------------------------------------------- */

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

.topbar {
    position: sticky;
    top: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 14px 28px;
    background: color-mix(in srgb, var(--desk) 78%, transparent);
    backdrop-filter: saturate(180%) blur(18px);
    -webkit-backdrop-filter: saturate(180%) blur(18px);
    border-bottom: 1px solid var(--hairline-soft);
}

.topbar-actions {
    display: flex;
    align-items: center;
    gap: 10px;
}

.topbar-title { font-size: 15px; font-weight: 600; }
.topbar-sub { font-size: 12px; color: var(--ink-faint); }

/* Every page runs the full desk width. Pages needing a narrower column can add
   one via the layout's content-class section. */
.content {
    padding: 26px 28px 44px;
    width: 100%;
}

/* Past a comfortable reading width the dashboard pairs its cards side by
   side, so the extra room becomes content rather than blank desk. */
.dash-pair {
    display: grid;
    gap: 18px;
    align-items: start;
    margin-top: 18px;
}

/* The grid gap already spaces these, so drop the stacked-card rule. */
.dash-pair > .card + .card { margin-top: 0; }

@media (min-width: 1500px) {
    .dash-pair { grid-template-columns: 1fr 1fr; }
}

.page-head { margin-bottom: 22px; }
.page-head p { color: var(--ink-soft); margin-top: 6px; }

/* --- Cards ---------------------------------------------------------------- */

.card {
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-lg);
    box-shadow: var(--lift-1);
    overflow: hidden;
}

/* Cards keep their distance from one another — including when one of them is
   wrapped in a <form>, which the plain sibling selector cannot see through:
   the banner screen's heading and counters cards both post as whole forms,
   and without these the counters card sat flush against the chips card. */
.card + .card,
.card + form > .card,
form + .card,
form + form > .card { margin-top: 18px; }

.card-head {
    padding: 15px 20px;
    border-bottom: 1px solid var(--hairline-soft);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.card-head p { font-size: 12px; color: var(--ink-faint); margin: 3px 0 0; }

.card-body { padding: 20px; }
.card-foot {
    padding: 14px 20px;
    border-top: 1px solid var(--hairline-soft);
    background: var(--surface-sunken);
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}

/* --- Stats ---------------------------------------------------------------- */

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 14px;
    margin-bottom: 20px;
}

.stat {
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-lg);
    box-shadow: var(--lift-1);
    padding: 16px 18px;
}

.stat-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--ink-faint);
    letter-spacing: 0.02em;
}

.stat-value {
    font-size: 30px;
    font-weight: 650;
    letter-spacing: -0.03em;
    margin: 4px 0 2px;
    font-variant-numeric: tabular-nums;
}

.stat-note { font-size: 12px; color: var(--ink-faint); }

/* --- Avatars -------------------------------------------------------------- */

.avatar {
    flex: none;
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--accent-wash);
    color: var(--accent);
    font-size: 12px;
    font-weight: 650;
    overflow: hidden;
    border: 1px solid var(--hairline-soft);
}

.avatar img { width: 100%; height: 100%; object-fit: cover; }

.avatar-lg { width: 76px; height: 76px; font-size: 25px; }

/* --- Tables / lists ------------------------------------------------------- */

.table { width: 100%; border-collapse: collapse; font-size: 13px; }

.table th {
    text-align: left;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-faint);
    padding: 10px 20px;
    border-bottom: 1px solid var(--hairline-soft);
    background: var(--surface-sunken);
}

.table td {
    padding: 12px 20px;
    border-bottom: 1px solid var(--hairline-soft);
    vertical-align: middle;
}

.table tr:last-child td { border-bottom: none; }

.cell-user { display: flex; align-items: center; gap: 10px; }
.cell-user strong { font-weight: 600; }
.cell-user span { display: block; font-size: 12px; color: var(--ink-faint); }

.table-wrap { overflow-x: auto; }

/* Read-only profile rows. */
.detail-list { margin: 0; }

.detail-row {
    display: grid;
    grid-template-columns: 172px 1fr;
    gap: 16px;
    padding: 12px 0;
    border-bottom: 1px solid var(--hairline-soft);
}

.detail-row:last-child { border-bottom: none; }
.detail-row dt { font-size: 13px; color: var(--ink-faint); font-weight: 500; }
.detail-row dd { margin: 0; font-size: 14px; }
.detail-row dd.is-empty { color: var(--ink-faint); font-style: italic; }

.pill {
    display: inline-block;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    background: var(--accent-wash);
    color: var(--accent);
}

/* Fields stay readable even when the page itself runs the full desk width. */
.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 0 18px;
    max-width: 980px;
}

.form-grid .span-2 { grid-column: 1 / -1; }

.identity {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}

.identity-text h2 { margin-bottom: 2px; }
.identity-text p { color: var(--ink-soft); font-size: 13px; }

/* --- Narrow screens ------------------------------------------------------- */

/* The drawer controls exist on every screen but only phones show them. */
.drawer-open, .drawer-close { display: none; }
.drawer-backdrop { display: none; }
.topbar-lead { display: flex; align-items: center; gap: 10px; min-width: 0; }

/* --- The bell ------------------------------------------------------------ */
.notif { position: relative; margin-left: 6px; flex: none; }
.notif > summary { list-style: none; }
.notif > summary::-webkit-details-marker { display: none; }
.notif-bell {
    position: relative;
    display: inline-grid;
    place-items: center;
    width: 34px;
    height: 34px;
    color: var(--ink-soft);
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: 50%;
    box-shadow: var(--lift-1);
    cursor: pointer;
    transition: color .15s, border-color .15s, background .15s;
}
.notif-bell svg { width: 19px; height: 19px; }
.notif-bell:hover, .notif[open] > .notif-bell { color: var(--accent); border-color: var(--accent-wash); background: var(--accent-wash); }
.notif-bell:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-wash); }
.notif-bell.has-new { color: var(--ink); }
/* The count: a true circle — the same width and height whatever the number,
   so "3", "11" and "99+" all sit centred in one clean round badge. */
.notif-count {
    position: absolute;
    top: -6px;
    right: -6px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border-radius: 50%;
    background: var(--danger);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.02em;
    border: 2px solid var(--surface);
    box-shadow: 0 1px 3px rgba(16, 20, 32, .25);
    font-variant-numeric: tabular-nums;
    pointer-events: none;
}
/* Three characters ("99+") get a touch smaller type rather than a wider shape. */
.notif-count.is-wide { font-size: 9px; letter-spacing: -0.03em; }
.notif-bell.has-new svg { color: var(--ink); }

.notif-panel {
    position: absolute;
    top: calc(100% + 10px);
    left: 0;
    z-index: 60;
    width: min(380px, calc(100vw - 32px));
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: 14px;
    box-shadow: 0 0 0 1px rgba(16, 20, 32, .04), 0 24px 60px -18px rgba(16, 20, 32, .45);
    overflow: hidden;
    animation: notif-in .14s ease-out;
}
@keyframes notif-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .notif-panel { animation: none; } }

.notif-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--hairline-soft);
    background: var(--surface-sunken);
}
.notif-head strong { font-size: 13.5px; }
.notif-head-count { font-size: 11.5px; font-weight: 600; color: var(--ink-faint); }
.notif-all { margin-left: auto; font-size: 12.5px; font-weight: 600; color: var(--accent); text-decoration: none; }
.notif-all:hover { text-decoration: underline; }

.notif-list { list-style: none; margin: 0; padding: 0; max-height: min(60vh, 440px); overflow-y: auto; }
.notif-list li + li { border-top: 1px solid var(--hairline-soft); }
.notif-item {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 14px;
    text-decoration: none;
    color: inherit;
    transition: background .12s;
}
.notif-item:hover { background: var(--accent-wash); }
.notif-item-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.notif-item-main strong { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.notif-item-sub { font-size: 12px; color: var(--ink-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.notif-item-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex: none; }
.notif-item-meta time { font-size: 11px; color: var(--ink-faint); white-space: nowrap; font-variant-numeric: tabular-nums; }
.notif-item-meta .pill { max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.notif-empty { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 26px 16px; text-align: center; color: var(--ink-faint); }
.notif-empty svg { width: 26px; height: 26px; color: var(--good); margin-bottom: 4px; }
.notif-empty strong { font-size: 13.5px; color: var(--ink); }
.notif-empty span { font-size: 12.5px; }
.notif-empty-page { padding: 40px 16px; }
.notif-loading { flex-direction: row; justify-content: center; gap: 10px; padding: 22px 16px; font-size: 12.5px; }
.notif-spinner { width: 16px; height: 16px; border: 2px solid var(--hairline); border-top-color: var(--accent); border-radius: 50%; animation: notif-spin .8s linear infinite; }
@keyframes notif-spin { to { transform: rotate(360deg); } }

.notif-foot { display: flex; justify-content: center; padding: 10px 14px; border-top: 1px solid var(--hairline-soft); background: var(--surface-sunken); }

.notif-row-title { font-weight: 600; color: var(--ink); text-decoration: none; }
.notif-row-title:hover { color: var(--accent); }
.notif-row-sub { max-width: 38ch; color: var(--ink-soft); }

@media (max-width: 700px) {
    .notif-panel { position: fixed; top: 64px; left: 12px; right: 12px; width: auto; }
}

@media (max-width: 860px) {
    .shell { grid-template-columns: 1fr; }

    /* The menu becomes an app-style drawer: off-canvas to the left, slid in
       by the hamburger in the top bar, dismissed by the backdrop, the close
       button, Escape, or choosing a page. The list stays a single column
       with roomy touch targets and the section headings kept. */
    .sidebar {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        z-index: 40;
        width: min(320px, 86vw);
        height: 100dvh;
        padding: 14px 14px calc(14px + env(safe-area-inset-bottom));
        border-right: 1px solid var(--hairline);
        box-shadow: none;
        transform: translateX(-102%);
        transition: transform 0.26s cubic-bezier(0.32, 0.72, 0, 1), box-shadow 0.26s ease;
        overflow: hidden;
    }

    html[data-drawer="open"] .sidebar {
        transform: none;
        box-shadow: var(--lift-3);
    }

    .drawer-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 39;
        background: rgba(16, 20, 32, 0.45);
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.26s ease;
    }

    html[data-drawer="open"] .drawer-backdrop { opacity: 1; pointer-events: auto; }
    html[data-drawer="open"] body { overflow: hidden; }

    .brand-row { padding-bottom: 10px; border-bottom: 1px solid var(--hairline-soft); margin-bottom: 4px; }
    .brand img { height: 40px; }
    .sidebar-toggle { display: none; }

    .drawer-close {
        display: flex;
        align-items: center;
        justify-content: center;
        flex: none;
        width: 36px;
        height: 36px;
        border-radius: 50%;
        border: 1px solid var(--hairline);
        background: var(--surface);
        color: var(--ink-soft);
        cursor: pointer;
    }
    .drawer-close svg { width: 16px; height: 16px; }

    .drawer-open {
        display: flex;
        align-items: center;
        justify-content: center;
        flex: none;
        width: 40px;
        height: 40px;
        border-radius: var(--r-md);
        border: 1px solid var(--hairline);
        background: var(--surface);
        color: var(--ink);
        cursor: pointer;
    }
    .drawer-open svg { width: 20px; height: 20px; }

    /* A single column, app-style: full-width rows, bigger targets, counts
       pushed to the right edge. */
    .sidebar-nav { flex-direction: column; flex-wrap: nowrap; overflow-y: auto; gap: 2px; padding-right: 4px; }
    .nav-heading { display: block; margin: 14px 10px 6px; }
    .nav-link { padding: 11px 12px; font-size: 15px; border-radius: var(--r-md); }
    .nav-link svg { width: 20px; height: 20px; }
    .nav-link-sub { padding: 9px 12px 9px 18px; font-size: 14px; }
    .nav-count { margin-left: auto; }
    .sidebar-foot { margin-top: auto; padding-top: 10px; border-top: 1px solid var(--hairline-soft); }

    /* The desktop "collapsed" (icon-only) state has no meaning in a drawer:
       labels, headings and counts always show. */
    html[data-sidebar="collapsed"] .shell { --sidebar: 0px; }
    html[data-sidebar="collapsed"] .shell .sidebar { padding: 14px 14px calc(14px + env(safe-area-inset-bottom)); }
    html[data-sidebar="collapsed"] .shell .brand-row { flex-direction: row; justify-content: flex-start; gap: 4px; }
    html[data-sidebar="collapsed"] .shell .brand { flex: 1; padding: 4px 8px; justify-content: flex-start; }
    html[data-sidebar="collapsed"] .shell .brand-name { width: auto; opacity: 1; pointer-events: auto; }
    html[data-sidebar="collapsed"] .shell .nav-heading { height: auto; padding: 0; margin: 14px 10px 6px; opacity: 1; overflow: visible; }
    html[data-sidebar="collapsed"] .shell .nav-label,
    html[data-sidebar="collapsed"] .shell .who-text,
    html[data-sidebar="collapsed"] .shell .nav-count { width: auto; opacity: 1; overflow: visible; pointer-events: auto; }
    html[data-sidebar="collapsed"] .shell .nav-link { justify-content: flex-start; padding: 11px 12px; gap: 10px; }
    html[data-sidebar="collapsed"] .shell .who { justify-content: flex-start; gap: 10px; }
    html[data-sidebar="collapsed"] .shell .nav-link-sub { padding-left: 18px; }
    html[data-sidebar="collapsed"] .shell .nav-rung { display: block; }
    html[data-sidebar="collapsed"] .shell .btn-wide { width: auto; padding: 8px 14px; gap: 8px; }
    html[data-sidebar="collapsed"] .shell .sidebar-foot form { display: block; }

    .topbar, .content { padding-left: 16px; padding-right: 16px; }
    .detail-row { grid-template-columns: 1fr; gap: 2px; }

    /* --- The top bar, app-style: ☰ · title · ⋯ ------------------------------
       One line for the title; the date is dropped (the dashboard has it);
       every action moves into a drawer on the right, opened by ⋯, so the
       Tour, Logs, counts, theme and timezone are a tidy tap-sized list. */
    .topbar { padding-top: 10px; padding-bottom: 10px; gap: 10px; }
    .topbar-lead { flex: 1; }
    .topbar-lead > div { min-width: 0; }
    .topbar-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 16px; }
    .topbar-sub { display: none; }

    .drawer-open-actions { margin-left: auto; }

    .topbar-actions {
        position: fixed;
        top: 0;
        bottom: 0;
        right: 0;
        z-index: 40;
        width: min(300px, 84vw);
        height: 100dvh;
        padding: 14px 14px calc(14px + env(safe-area-inset-bottom));
        background: var(--desk-tint);
        border-left: 1px solid var(--hairline);
        flex-direction: column;
        align-items: stretch;
        gap: 8px;
        overflow-y: auto;
        transform: translateX(102%);
        transition: transform 0.26s cubic-bezier(0.32, 0.72, 0, 1), box-shadow 0.26s ease;
    }
    html[data-actions="open"] .topbar-actions { transform: none; box-shadow: var(--lift-3); }
    html[data-actions="open"] .drawer-backdrop { opacity: 1; pointer-events: auto; }
    html[data-actions="open"] body { overflow: hidden; }

    /* The drawer is a child of the top bar, and the bar's z-index and
       backdrop-filter make a stacking context that would hold the drawer
       under the dimming backdrop. While the drawer is open the bar itself
       is lifted above the backdrop — made transparent, its blur switched
       off and its own controls hidden — so the drawer is drawn crisp and
       on top, and the bar's strip does not show through undimmed. */
    html[data-actions="open"] .topbar {
        z-index: 41;
        background: transparent;
        border-color: transparent;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }
    html[data-actions="open"] .topbar-lead,
    html[data-actions="open"] .drawer-open-actions { visibility: hidden; }

    .actions-head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 10px;
        padding: 2px 2px 12px;
        margin-bottom: 4px;
        border-bottom: 1px solid var(--hairline-soft);
        font-size: 15px;
    }

    /* Every action becomes a full-width row with a label — including the
       icon-only theme and timezone buttons, which borrow their aria-label. */
    .topbar-actions > .btn,
    .topbar-actions > form,
    .topbar-actions > .theme-toggle,
    .topbar-actions > [data-tour-start] {
        width: 100%;
        min-height: 46px;
        justify-content: flex-start;
        gap: 12px;
        padding: 10px 14px;
        border-radius: var(--r-md);
        font-size: 14.5px;
    }
    .topbar-actions > form .btn { width: 100%; justify-content: flex-start; min-height: 46px; }
    .topbar-actions > .theme-toggle { display: flex; align-items: center; height: auto; border: 1px solid var(--hairline); border-radius: var(--r-md); box-shadow: none; background: var(--surface); color: var(--ink); }
    .topbar-actions > .theme-toggle::after { content: attr(aria-label); font-weight: 500; }
    .topbar-actions > .theme-toggle svg { width: 18px; height: 18px; flex: none; }
    .topbar-actions .btn-tour-label { display: inline; }
}

/* Sits in the normal flow on desktop, where the bar has room for it. */
.actions-head { display: none; }

@media (prefers-reduced-motion: reduce) {
    .sidebar, .topbar-actions, .drawer-backdrop { transition: none; }
}

@media (prefers-reduced-motion: reduce) {
    * { transition: none !important; animation: none !important; }
}

/* --- Menu manager --------------------------------------------------------- */

.menu-filter {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.menu-filter .input { max-width: 190px; }
.menu-filter .select { max-width: 130px; }

.menu-title { display: flex; align-items: center; gap: 10px; }
.menu-title strong { font-weight: 600; }

.menu-title span span,
.menu-title > span > span {
    display: block;
    font-size: 12px;
    color: var(--ink-faint);
}

/* Rides on the title line rather than dropping under it like the sub-labels
   the rule above is written for, so it has to out-specify them. */
.menu-title .pill-new {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 7px;
    font-size: 10px;
    letter-spacing: 0.06em;
    color: var(--good);
    vertical-align: 1px;
}

/* The elbow that marks a row as a child of the one above it. */
.menu-branch {
    width: 14px;
    height: 10px;
    flex: none;
    margin-left: 8px;
    border-left: 1px solid var(--hairline);
    border-bottom: 1px solid var(--hairline);
    border-bottom-left-radius: 5px;
    align-self: flex-start;
    margin-top: 2px;
}

.menu-row-child td:first-child { padding-left: 20px; }
.menu-row-parent td { background: var(--surface-sunken); }
.menu-row-parent td:first-child strong { font-weight: 650; }

/* The link, shown under the title it belongs to. It gets a line of its own
   whether or not the item has a description, so the column reads as a stack
   of title / note / link rather than shifting layout row by row. */
.menu-title .menu-url {
    display: block;
    width: fit-content;
    max-width: 100%;
    margin-top: 4px;
    overflow-wrap: anywhere;
}

.menu-url {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 11.5px;
    color: var(--ink-soft);
    background: var(--surface-sunken);
    border: 1px solid var(--hairline-soft);
    border-radius: var(--r-sm);
    padding: 2px 6px;
}

.pill-muted { background: var(--hairline-soft); color: var(--ink-faint); }

.col-actions { text-align: right; white-space: nowrap; }

.row-actions {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    justify-content: flex-end;
}

.row-actions form { display: inline-flex; margin: 0; }

@media (max-width: 860px) {
    .menu-filter { width: 100%; }
    .menu-filter .input, .menu-filter .select { max-width: none; flex: 1; }
    .col-actions { text-align: left; }
    .row-actions { flex-wrap: wrap; justify-content: flex-start; }
}

/* Column widths for the menu manager: the title column carries a label plus a
   caption, so it gets the room and the narrow columns stop stealing it. */
/* The action column is sized by its own buttons (it never wraps), so the
   layout stays correct as buttons are added or removed. The title column
   absorbs whatever is left. */
/* Column order: select · menu item (title, note and link) · type · position ·
   status · updated · actions. The item column takes whatever is left. */
/* Widths are given as minimums rather than one min-width on the table:
   columns can be switched on and off from the Columns menu, so the table has
   to grow and shrink with them. A minimum per column means a row never
   collapses — the table scrolls sideways instead. */
.table-menus { min-width: 940px; }
.table-menus th:nth-child(1) { width: 34px; }

.table-menus th:nth-child(2),
.table-menus td:nth-child(2) { width: 40%; min-width: 250px; overflow-wrap: anywhere; }

.table-menus th:nth-child(3) { width: 118px; min-width: 108px; }
.table-menus td:nth-child(3) .pill { white-space: nowrap; }
.table-menus th:nth-child(4) { width: 86px; min-width: 78px; }
.table-menus th:nth-child(6) { width: 124px; min-width: 116px; }

/* The three optional "created" columns. */
.table-menus th:nth-child(7) { min-width: 116px; }
.table-menus th:nth-child(8) { min-width: 150px; }
.table-menus th:nth-child(9) { min-width: 176px; }

/* --- Industry / category tables ------------------------------------------- */

/* select · industry (name, note, page) · categories · reports · position ·
   status · updated · the three optional "created" columns · actions. */
.table-industries { min-width: 960px; }
.table-industries th:nth-child(1) { width: 34px; }
.table-industries th:nth-child(2),
.table-industries td:nth-child(2) { width: 38%; min-width: 250px; overflow-wrap: anywhere; }
.table-industries th:nth-child(3) { min-width: 96px; }
.table-industries th:nth-child(4) { min-width: 86px; }
.table-industries th:nth-child(5) { min-width: 86px; }
.table-industries th:nth-child(7) { min-width: 116px; }
.table-industries th:nth-child(8) { min-width: 116px; }
.table-industries th:nth-child(9) { min-width: 150px; }
.table-industries th:nth-child(10) { min-width: 176px; }

/* select · name · sits under · nested · reports · position · status ·
   updated · the three optional "created" columns · actions. */
.table-categories { min-width: 1080px; }
.table-categories th:nth-child(1) { width: 34px; }
.table-categories th:nth-child(2),
.table-categories td:nth-child(2) { width: 30%; min-width: 240px; }
.table-categories th:nth-child(3),
.table-categories td:nth-child(3) { min-width: 150px; }
.table-categories th:nth-child(4) { min-width: 82px; }
.table-categories th:nth-child(5) { min-width: 86px; }
.table-categories th:nth-child(6) { min-width: 86px; }
.table-categories th:nth-child(8) { min-width: 116px; }
.table-categories th:nth-child(9) { min-width: 116px; }
.table-categories th:nth-child(10) { min-width: 150px; }
.table-categories th:nth-child(11) { min-width: 176px; }

/* Each level steps in by --cat-indent, so the tree reads as a hierarchy while
   staying a flat table that sorts and scrolls normally. */
.cat-title {
    display: flex;
    align-items: center;
    gap: 10px;
    padding-left: var(--cat-indent, 0);
}

.cat-title strong { font-weight: 600; }

.cat-title > span > span {
    display: block;
    font-size: 12px;
    color: var(--ink-faint);
}

.cat-level-1 td { background: var(--surface-sunken); }
.cat-level-1 td:first-child strong { font-weight: 650; }
.cat-level-3 td:first-child strong { font-weight: 500; }

/* --- Tab bars -------------------------------------------------------------- */

.tab-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 14px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--hairline);
}

.tab-bar-sub {
    margin-top: -6px;
    border-bottom: none;
    padding-bottom: 0;
}

.tab {
    padding: 7px 14px;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 550;
    color: var(--ink-soft);
    background: var(--surface);
    border: 1px solid var(--hairline);
    transition: background 0.14s ease, color 0.14s ease, border-color 0.14s ease;
}

.tab:hover {
    text-decoration: none;
    color: var(--ink);
    border-color: var(--ink-faint);
}

.tab.is-active {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

.tab-sm { padding: 5px 12px; font-size: 12.5px; }

/* --- Industry picker --------------------------------------------------------
   Thirty-odd industries would wrap a row of pill tabs into a wall nobody could
   scan, so the choice is one control instead: the current industry on the
   button, the rest behind it in a searchable list. Built on <details>, so it
   opens without a script; picker.js adds the filtering and the closing. */

.picker-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 14px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--hairline);
}

.picker { position: relative; }

.picker > summary {
    list-style: none;
    user-select: none;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 7px 12px 7px 14px;
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-md);
    cursor: pointer;
    transition: border-color 0.14s ease, box-shadow 0.14s ease;
}

.picker > summary::-webkit-details-marker { display: none; }
.picker > summary:hover { border-color: var(--ink-faint); }
.picker[open] > summary { border-color: var(--accent); box-shadow: 0 0 0 3.5px var(--accent-wash); }

.picker-label {
    font-size: 10.5px;
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

.picker-current {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--ink);
}

.picker-chevron {
    width: 14px;
    height: 14px;
    color: var(--ink-faint);
    transition: transform 0.14s ease;
}

.picker[open] .picker-chevron { transform: rotate(180deg); }

.picker-panel {
    position: absolute;
    z-index: 30;
    top: calc(100% + 7px);
    left: 0;
    width: min(340px, calc(100vw - 40px));
    padding: 10px;
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-lg);
    box-shadow: var(--lift-3);
}

.picker-search { position: relative; margin-bottom: 8px; }

.picker-search svg {
    position: absolute;
    top: 50%;
    left: 10px;
    width: 14px;
    height: 14px;
    transform: translateY(-50%);
    color: var(--ink-faint);
    pointer-events: none;
}

.picker-search .input { padding-left: 32px; }

/* Taller than the download menu: this list is the whole point of the panel,
   and seeing many rows at once is what makes it quicker than the tabs were. */
.picker-list {
    max-height: 336px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.picker-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 7px 9px;
    border-radius: var(--r-sm);
    font-size: 13px;
    color: var(--ink-soft);
}

.picker-item:hover,
.picker-item:focus-visible {
    background: var(--surface-sunken);
    color: var(--ink);
    text-decoration: none;
}

.picker-item.is-active {
    background: var(--accent-wash);
    color: var(--accent);
    font-weight: 600;
}

.picker-count {
    flex: none;
    font-size: 11px;
    font-weight: 600;
    color: var(--ink-faint);
    background: var(--hairline-soft);
    border-radius: 999px;
    padding: 1px 7px;
}

.picker-item.is-active .picker-count {
    background: var(--accent-wash);
    color: var(--accent);
}

.picker-empty {
    margin: 4px 6px 6px;
    font-size: 12.5px;
    color: var(--ink-faint);
}

.picker-note {
    font-size: 12.5px;
    color: var(--ink-faint);
}

@media (max-width: 640px) {
    .picker-note { display: none; }
}

/* --- Read-only taxonomy tree ---------------------------------------------- */

.tax-tree, .tax-tree ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.tax-tree ul {
    margin: 4px 0 8px 10px;
    padding-left: 14px;
    border-left: 1px solid var(--hairline);
}

.tax-tree li { padding: 3px 0; font-size: 13px; }
.tax-tree > li { padding: 5px 0; }
.tax-tree > li > a { font-weight: 600; color: var(--ink); }
.tax-tree ul a { color: var(--ink-soft); }
.tax-tree ul ul a { color: var(--ink-faint); font-size: 12.5px; }

.tax-count {
    display: inline-block;
    margin-left: 7px;
    font-size: 11px;
    font-weight: 600;
    color: var(--ink-faint);
    background: var(--hairline-soft);
    border-radius: 999px;
    padding: 1px 7px;
}

@media (max-width: 860px) {
    .tab-bar { gap: 5px; }
    .tab { padding: 6px 11px; font-size: 12.5px; }
}

/* --- Category level entries in the sidebar -------------------------------- */
/* Indented under "Category tree", with a rung that grows by level so the
   three depths are distinguishable at a glance. */

.nav-link-sub {
    padding: 6px 10px 6px 14px;
    font-size: 13px;
    font-weight: 450;
}

.nav-rung {
    flex: none;
    height: 2px;
    border-radius: 1px;
    background: currentColor;
    opacity: 0.35;
    margin-left: 4px;
}

.nav-rung-1 { width: 13px; }
.nav-rung-2 { width: 9px;  margin-left: 8px; }
.nav-rung-3 { width: 5px;  margin-left: 12px; }

.nav-link-sub.is-active .nav-rung { opacity: 1; }

/* --- Per-level category list ---------------------------------------------- */

.table-levels { min-width: 860px; }
.table-levels th:nth-child(1) { width: 28%; }
.table-levels th:nth-child(2) { width: 22%; }

.cat-trail { color: var(--ink-faint); font-size: 12.5px; }

.tab-count {
    display: inline-block;
    margin-left: 6px;
    padding: 0 6px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    background: var(--hairline-soft);
    color: var(--ink-faint);
}

.tab.is-active .tab-count {
    background: rgba(255, 255, 255, 0.22);
    color: #fff;
}

/* --- Two-factor authentication -------------------------------------------- */
/* The security card on the profile page, the dialogs it opens, and the
   verification step of signing in. Everything here is built from the same
   tokens as the rest of the panel so it changes with the theme. */

.tfa-lead {
    display: flex;
    gap: 14px;
    align-items: flex-start;
}

.tfa-mark {
    flex: none;
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    border-radius: var(--r-md);
    background: var(--accent-wash);
    color: var(--accent);
}

.tfa-mark svg { width: 21px; height: 21px; }
.tfa-mark-good { background: var(--good-wash); color: var(--good); }
.tfa-mark-warn { background: var(--warn-wash); color: var(--warn); }

.tfa-lead p { color: var(--ink-soft); max-width: 62ch; }

.tfa-points {
    margin: 12px 0 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 7px;
}

.tfa-points li {
    display: flex;
    gap: 9px;
    align-items: flex-start;
    font-size: 13px;
    color: var(--ink-soft);
}

.tfa-points svg {
    flex: none;
    width: 15px;
    height: 15px;
    margin-top: 3px;
    color: var(--good);
}

/* Facts about an active setup: when it was turned on, codes left. */
.tfa-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 16px;
}

.tfa-fact {
    flex: 1 1 190px;
    padding: 11px 14px;
    border: 1px solid var(--hairline-soft);
    border-radius: var(--r-md);
    background: var(--surface-sunken);
}

.tfa-fact dt {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

.tfa-fact dd {
    margin: 2px 0 0;
    font-size: 14px;
    font-weight: 550;
}

/* --- Setup, as three numbered steps --------------------------------------- */

.tfa-steps {
    list-style: none;
    margin: 0;
    padding: 0;
    counter-reset: step;
}

.tfa-step {
    display: flex;
    gap: 14px;
    padding-bottom: 22px;
    position: relative;
}

/* A hairline runs from one number to the next so the three read as a path. */
.tfa-step::before {
    content: "";
    position: absolute;
    top: 30px;
    bottom: 4px;
    left: 13px;
    width: 1px;
    background: var(--hairline);
}

.tfa-step:last-child { padding-bottom: 0; }
.tfa-step:last-child::before { display: none; }

.tfa-step-number {
    flex: none;
    display: grid;
    place-items: center;
    width: 27px;
    height: 27px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    font-size: 12px;
    font-weight: 650;
    position: relative;
    z-index: 1;
}

.tfa-step-body { min-width: 0; flex: 1; }
.tfa-step-body h3 { margin-bottom: 3px; }
.tfa-step-body > p { font-size: 13px; color: var(--ink-soft); }

.tfa-step-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 11px;
}

/* --- QR code and the typed-in alternative --------------------------------- */

.tfa-scan {
    display: flex;
    flex-wrap: wrap;
    gap: 18px;
    margin-top: 13px;
    align-items: flex-start;
}

/* Codes are read by a camera, so this plate stays white in both themes. */
.qr-plate {
    flex: none;
    padding: 10px;
    background: #ffffff;
    border: 1px solid var(--hairline);
    border-radius: var(--r-md);
    box-shadow: var(--lift-1);
    line-height: 0;
}

.tfa-manual { flex: 1 1 240px; min-width: 0; }

.tfa-manual p {
    font-size: 12.5px;
    color: var(--ink-soft);
    margin-bottom: 8px;
}

.setup-key {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border: 1px solid var(--hairline);
    border-radius: var(--r-md);
    background: var(--surface-sunken);
}

.setup-key code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12.5px;
    letter-spacing: 0.06em;
    word-break: break-all;
    color: var(--ink);
}

/* The six-digit field: wide-spaced digits, as they look in the app. */
.otp-input {
    max-width: 210px;
    text-align: center;
    font-size: 22px;
    font-weight: 600;
    letter-spacing: 0.42em;
    text-indent: 0.42em;
    font-variant-numeric: tabular-nums;
    padding: 10px 12px;
}

.tfa-confirm {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 10px;
    margin-top: 12px;
}

/* --- Recovery codes -------------------------------------------------------- */

.tfa-codes {
    margin-top: 20px;
    padding: 16px;
    border: 1px solid var(--warn-wash);
    border-radius: var(--r-md);
    background: var(--warn-wash);
}

.tfa-codes-head {
    display: flex;
    gap: 11px;
    align-items: flex-start;
}

.tfa-codes-head svg {
    flex: none;
    width: 18px;
    height: 18px;
    margin-top: 2px;
    color: var(--warn);
}

.tfa-codes-head strong { display: block; font-size: 13px; }
.tfa-codes-head p { font-size: 12.5px; color: var(--ink-soft); margin: 2px 0 0; }

.code-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(124px, 1fr));
    gap: 8px;
    margin: 14px 0;
}

.code-chip {
    padding: 7px 4px;
    text-align: center;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px;
    letter-spacing: 0.04em;
    background: var(--surface);
    border: 1px solid var(--hairline-soft);
    border-radius: var(--r-sm);
}

.code-chip.is-spent {
    color: var(--ink-faint);
    text-decoration: line-through;
}

.tfa-codes-actions { display: flex; flex-wrap: wrap; gap: 8px; }

/* --- Status pills ---------------------------------------------------------- */

.pill-good { background: var(--good-wash); color: var(--good); }
.pill-warn { background: var(--warn-wash); color: var(--warn); }

.pill-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-right: 6px;
    border-radius: 50%;
    background: currentColor;
    vertical-align: 1px;
}

/* --- Dialogs --------------------------------------------------------------- */
/* Native <dialog>, so focus trapping, Esc and the backdrop come from the
   browser rather than from a framework. */

.modal {
    width: min(540px, calc(100vw - 32px));
    max-height: calc(100vh - 64px);
    padding: 0;
    color: var(--ink);
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-lg);
    box-shadow: var(--lift-3);
    overflow: hidden;
}

.modal-wide { width: min(680px, calc(100vw - 32px)); }

.modal::backdrop {
    background: rgba(16, 20, 32, 0.5);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}

.modal-head {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--hairline-soft);
}

.modal-head h2 { font-size: 16px; }
.modal-head p { font-size: 12.5px; color: var(--ink-faint); margin: 3px 0 0; }

.modal-close {
    margin-left: auto;
    flex: none;
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    padding: 0;
    color: var(--ink-faint);
    background: transparent;
    border: none;
    border-radius: var(--r-sm);
    cursor: pointer;
}

.modal-close:hover { background: var(--surface-sunken); color: var(--ink); }
.modal-close svg { width: 16px; height: 16px; }

/* Some dialogs close with a glyph rather than an icon. */
.modal-close { font-size: 19px; line-height: 1; font-family: inherit; }

/* --- Timezone picker ------------------------------------------------------ */

.tz-quick {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.tz-chip {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1px;
    padding: 7px 14px;
    font: inherit;
    color: var(--ink-soft);
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-md);
    cursor: pointer;
    transition: border-color 0.14s ease, background 0.14s ease, color 0.14s ease;
}

.tz-chip:hover { background: var(--surface-sunken); color: var(--ink); }

.tz-chip.is-on {
    color: var(--accent);
    background: var(--accent-wash);
    border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}

.tz-chip-name { font-size: 13px; font-weight: 600; }

.tz-chip-time {
    font-size: 11.5px;
    color: var(--ink-faint);
    font-variant-numeric: tabular-nums;
}

.tz-chip.is-on .tz-chip-time { color: inherit; opacity: 0.8; }

/* A list rather than a dropdown, so the search above it can narrow it live. */
.tz-list {
    height: auto;
    padding: 4px;
    overflow-y: auto;
}

.tz-list option { padding: 4px 8px; border-radius: var(--r-sm); }
.tz-list optgroup { font-weight: 600; color: var(--ink-faint); }

/* --- Timezone preview inside the settings dialog -------------------------- */

.tz-preview {
    margin-top: 16px;
    border: 1px solid var(--hairline-soft);
    border-radius: var(--r-md);
    background: var(--surface-sunken);
    overflow: hidden;
}

.tz-preview-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 8px 14px;
}

.tz-preview-row + .tz-preview-row { border-top: 1px solid var(--hairline-soft); }

.tz-preview-label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

.tz-preview-value {
    font-size: 13px;
    font-weight: 550;
    text-align: right;
}

/* The seconds tick, so the digits need a stable width to stop the row
   jittering once a second. */
.tz-preview-clock {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum";
}

.topbar-sub { font-variant-numeric: tabular-nums; }

.modal-body {
    padding: 20px;
    max-height: min(62vh, 560px);
    overflow-y: auto;
}

.modal-foot {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding: 14px 20px;
    border-top: 1px solid var(--hairline-soft);
    background: var(--surface-sunken);
}

/* --- Authenticator app guide ----------------------------------------------- */

.app-note {
    display: flex;
    gap: 11px;
    padding: 12px 14px;
    margin-bottom: 18px;
    font-size: 13px;
    color: var(--ink-soft);
    background: var(--accent-wash);
    border-radius: var(--r-md);
}

.app-note svg { flex: none; width: 17px; height: 17px; color: var(--accent); margin-top: 1px; }

.how-list {
    margin: 0 0 20px;
    padding-left: 20px;
    display: grid;
    gap: 6px;
    font-size: 13px;
    color: var(--ink-soft);
}

.app-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }

.app-row {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 12px 14px;
    border: 1px solid var(--hairline);
    border-radius: var(--r-md);
}

.app-row-text { flex: 1 1 200px; min-width: 0; }
.app-row-text strong { display: block; font-size: 13.5px; font-weight: 600; }
.app-row-text span { font-size: 12px; color: var(--ink-faint); }

.app-badge {
    flex: none;
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border-radius: var(--r-sm);
    font-size: 13px;
    font-weight: 700;
    background: var(--surface-sunken);
    border: 1px solid var(--hairline-soft);
    color: var(--ink-soft);
}

/* The app tile carries the product's own colour, set inline per app. */
.app-tile {
    flex: none;
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: 10px;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: #fff;
    background: var(--tile, var(--accent));
    box-shadow: var(--lift-1);
}

/* --- Store buttons --------------------------------------------------------- */

.app-stores {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.store-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px 6px 10px;
    color: var(--ink);
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-md);
    box-shadow: var(--lift-1);
    transition: border-color 0.14s ease, background 0.14s ease;
}

.store-link:hover {
    text-decoration: none;
    background: var(--surface-sunken);
    border-color: color-mix(in srgb, var(--ink) 22%, transparent);
}

.store-link svg { width: 20px; height: 20px; flex: none; }

.store-link span {
    display: block;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.15;
}

.store-link small {
    display: block;
    font-size: 9.5px;
    font-weight: 500;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

@media (max-width: 620px) {
    .app-stores { width: 100%; }
    .store-link { flex: 1 1 auto; justify-content: center; }
}

/* --- Verification step of signing in --------------------------------------- */

.gate-shield {
    display: grid;
    place-items: center;
    width: 52px;
    height: 52px;
    margin: 0 auto 16px;
    border-radius: var(--r-lg);
    background: var(--accent-wash);
    color: var(--accent);
}

.gate-shield svg { width: 26px; height: 26px; }

.gate .otp-input { max-width: none; margin: 0 auto; }

.gate-swap {
    margin-top: 18px;
    text-align: center;
    font-size: 13px;
}

.gate-swap button {
    font: inherit;
    font-weight: 550;
    color: var(--accent);
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
}

.gate-swap button:hover { text-decoration: underline; }

/* Panels swapped by the "use a recovery code" link; hidden before the script
   runs so neither flashes on a slow load. */
[data-swap-panel][hidden] { display: none; }

@media (max-width: 860px) {
    .tfa-scan { gap: 14px; }
    .otp-input { max-width: none; width: 100%; }
    .modal-body { max-height: 66vh; }
}

/* --- Activity log ---------------------------------------------------------
   One audit trail for every module, so these styles are written against the
   log itself rather than against any one screen that links into it.
   --------------------------------------------------------------------------- */

/* The "Logs" entry point. It sits next to the primary action, so it reads as
   a peer of it without competing for the eye. */
.btn-log { color: var(--ink-soft); }
.btn-log:hover { color: var(--accent); border-color: var(--accent-wash); }
.btn-log svg { width: 15px; height: 15px; flex: none; }

.btn-count {
    display: inline-grid;
    place-items: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    margin-left: 1px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 650;
    color: var(--accent);
    background: var(--accent-wash);
}

.avatar-xs { width: 26px; height: 26px; font-size: 10px; }

.pill-danger { background: var(--danger-wash); color: var(--danger); }

/* Filters. Six controls, each labelled, wrapping into as many rows as the
   width allows. */
.log-filter-bar { border-bottom: 1px solid var(--hairline-soft); }

.log-filter {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px;
}

.log-filter-field { display: grid; gap: 5px; min-width: 140px; }
.log-filter-field .label { margin: 0; }
.log-filter-field .input, .log-filter-field .select { min-width: 0; }
.log-filter-grow { flex: 1 1 200px; }

.log-filter-actions { display: flex; gap: 8px; margin-left: auto; }

/* Wide enough that an opened "what changed" card does not have to win its
   width off the record and actor columns. The wrap scrolls if the desk is
   narrower. */
.table-logs { min-width: 1360px; }
.table-logs th:nth-child(7) { width: 22%; }

/* Auto layout otherwise spends the record column down to its break points and
   stacks "ENQ-2026-0001" one fragment per line. */
.table-logs td:nth-child(3) { min-width: 156px; }
.table-logs td { vertical-align: top; }

.log-when strong { display: block; font-weight: 600; white-space: nowrap; }
.log-when span { display: block; font-size: 12px; color: var(--ink-faint); white-space: nowrap; }

.log-sub { display: block; font-size: 12px; color: var(--ink-faint); }
.log-empty { color: var(--ink-soft); }
.log-agent { font-size: 12.5px; color: var(--ink-soft); overflow-wrap: anywhere; }

/* Collapsed field list. <details> keeps a busy edit from pushing every other
   row off the screen, and needs no script. */
.log-details summary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ink-soft);
    list-style: none;
    user-select: none;
}

.log-details summary::-webkit-details-marker { display: none; }
.log-details summary:hover { color: var(--accent); }

.log-details-hint {
    font-size: 0;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--accent);
    background: var(--accent-wash);
    border-radius: 999px;
    padding: 1px 7px;
}

.log-details-hint::before { content: 'show'; font-size: 11px; }

/* The word is drawn by CSS so it can flip with the open state. */
.log-details[open] .log-details-hint { color: var(--ink-faint); background: var(--hairline-soft); }
.log-details[open] .log-details-hint::before { content: 'hide'; }

.log-details .diff-list { margin-top: 10px; }

/* old → new. The two values are told apart by colour and by a strikethrough,
   so the direction survives a greyscale print or a colour-blind reader.

   The card is laid out narrowest-first — field name on its own line above the
   values — because the same partial has to sit inside the cramped "What
   changed" table column as well as in a full-width record timeline. A fixed
   label column there left the values a couple of characters wide and spelled
   them out downwards. The label moves back alongside the values on a container
   query, so the layout follows the space the card actually has rather than the
   width of the window. */
.diff-list {
    display: grid;
    gap: 8px;
    /* Stops auto table layout from starving the column it lives in. */
    min-width: 216px;
    container-type: inline-size;
}

.diff-row {
    display: grid;
    gap: 6px;
    padding: 8px 10px;
    background: var(--surface-sunken);
    border: 1px solid var(--hairline-soft);
    border-radius: var(--r-sm);
}

.diff-field {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ink-faint);
}

.diff-values {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
    min-width: 0;
    font-size: 13px;
    line-height: 1.45;
}

.diff-old, .diff-new {
    max-width: 100%;
    padding: 2px 8px;
    border-radius: var(--r-sm);
    overflow-wrap: anywhere;
}

.diff-old {
    color: var(--danger);
    background: var(--danger-wash);
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}

.diff-new {
    color: var(--good);
    background: var(--good-wash);
    font-weight: 600;
}

.diff-arrow { flex: none; font-size: 12px; line-height: 1; color: var(--ink-faint); }

.diff-old.is-empty, .diff-new.is-empty {
    color: var(--ink-faint);
    background: var(--hairline-soft);
    font-style: italic;
    font-weight: 500;
    text-decoration: none;
}

/* Room to put the field name back beside its values. */
@container (min-width: 460px) {
    .diff-row { grid-template-columns: 132px minmax(0, 1fr); gap: 10px; align-items: baseline; padding: 7px 10px; }
}

.table-diff { min-width: 620px; }
.table-diff th:nth-child(1) { width: 22%; }

/* Per-record history, shown on the record's own page. */
.timeline-item { display: flex; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--hairline-soft); }
.timeline-item:first-child { padding-top: 0; }
.timeline-item:last-child { border-bottom: none; padding-bottom: 0; }

.timeline-dot {
    flex: none;
    width: 9px;
    height: 9px;
    margin-top: 6px;
    border-radius: 50%;
    background: var(--ink-faint);
}

.timeline-dot-created { background: var(--good); }
.timeline-dot-updated { background: var(--warn); }
.timeline-dot-deleted { background: var(--danger); }

.timeline-body { min-width: 0; flex: 1; }

.timeline-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    font-size: 13px;
}

.timeline-head .log-sub { display: inline; }
.timeline-link { margin-left: auto; font-size: 12.5px; font-weight: 600; }

/* --- Paging ---------------------------------------------------------------- */

.pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 20px;
    border-top: 1px solid var(--hairline-soft);
    background: var(--surface-sunken);
}

.pager-count { font-size: 12.5px; color: var(--ink-faint); }
.pager-links { display: inline-flex; align-items: center; gap: 8px; }
.pager-page { font-size: 12.5px; color: var(--ink-soft); }

.btn.is-disabled {
    opacity: 0.45;
    pointer-events: none;
    box-shadow: none;
}

@media (max-width: 860px) {
    .log-filter-field { min-width: 0; flex: 1 1 140px; }
    .log-filter-actions { margin-left: 0; width: 100%; }
    .pager { justify-content: center; }
}

/* --- Data table -----------------------------------------------------------
   The enhanced table: toolbar, sortable headers, tree rows, selection,
   paging and the download menu. Written against the data-dt- markup rather
   than against the menu screen, so every module can use it.
   --------------------------------------------------------------------------- */

.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.check-box {
    width: 15px;
    height: 15px;
    accent-color: var(--accent);
    cursor: pointer;
    margin: 0;
}

.num { text-align: right; font-variant-numeric: tabular-nums; }

.pill-soft { background: var(--accent-wash); color: var(--accent); }

/* --- Toolbar --------------------------------------------------------------- */

.dt-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 14px 20px;
    border-bottom: 1px solid var(--hairline-soft);
    background: var(--desk-tint);
}

.dt-bar-left,
.dt-bar-right {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.dt-search { position: relative; display: flex; align-items: center; }

.dt-search svg {
    position: absolute;
    left: 11px;
    width: 15px;
    height: 15px;
    color: var(--ink-faint);
    pointer-events: none;
}

.dt-search .input {
    width: 280px;
    max-width: 100%;
    padding-left: 33px;
    border-radius: 999px;
}

.dt-select { width: auto; min-width: 132px; }
.dt-length { min-width: 118px; }

/* Two buttons that read as one control. */
.dt-group { display: inline-flex; }
.dt-group .btn { border-radius: 0; margin-left: -1px; }
.dt-group .btn:first-child { border-radius: var(--r-md) 0 0 var(--r-md); margin-left: 0; }
.dt-group .btn:last-child { border-radius: 0 var(--r-md) var(--r-md) 0; }

/* --- Dropdown menus (native <details>, no script needed to open) ----------- */

.dt-menu { position: relative; }

.dt-menu > summary {
    list-style: none;
    user-select: none;
}

.dt-menu > summary::-webkit-details-marker { display: none; }
.dt-menu > summary svg { width: 15px; height: 15px; }
.dt-menu[open] > summary { box-shadow: 0 0 0 3.5px var(--accent-wash); }

.dt-menu-panel {
    position: absolute;
    z-index: 30;
    top: calc(100% + 7px);
    left: 0;
    width: 236px;
    padding: 10px;
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-lg);
    box-shadow: var(--lift-3);
}

.dt-menu-right .dt-menu-panel { left: auto; right: 0; }
.dt-menu-panel-wide { width: 302px; }

.dt-menu-head {
    margin: 2px 6px 8px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

.dt-menu-foot {
    margin: 8px 6px 2px;
    font-size: 11.5px;
    color: var(--ink-faint);
    line-height: 1.45;
}

.dt-menu-split { height: 1px; background: var(--hairline-soft); margin: 8px 0; }

/* "Fields to include" inside the Download menu: a two-column grid of ticks,
   All/None shortcuts, and the note shown when nothing is ticked. */
.dt-fields { padding: 2px 4px 4px; }
.dt-fields-head {
    display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
    margin: 0 0 6px; font-size: 11px; font-weight: 650; letter-spacing: 0.06em;
    text-transform: uppercase; color: var(--ink-faint);
}
.dt-fields-links { text-transform: none; letter-spacing: 0; font-weight: 500; }
.dt-fields-link {
    border: 0; background: none; padding: 0; cursor: pointer; font: inherit;
    font-size: 12px; color: var(--accent);
}
.dt-fields-link:hover { text-decoration: underline; }
.dt-fields-grid {
    display: grid; grid-template-columns: 1fr 1fr; gap: 2px 10px;
    max-height: 200px; overflow-y: auto;
}
.dt-fields-item {
    display: flex; align-items: center; gap: 7px; padding: 4px 5px;
    border-radius: var(--r-sm); font-size: 12.5px; color: var(--ink-soft); cursor: pointer;
}
.dt-fields-item:hover { background: var(--surface-sunken); color: var(--ink); }
.dt-fields-note { margin: 6px 0 0; font-size: 12px; color: var(--danger); }
.dt-file.is-disabled { opacity: 0.45; cursor: not-allowed; }

/* The same picker on the Reports module, one per table, folded under the
   table head as a <details> so the page stays scannable. */
.report-fields { margin: 0 18px 4px; }
.report-fields > summary {
    list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 8px;
    padding: 4px 0; font-size: 12px; font-weight: 650; letter-spacing: 0.06em;
    text-transform: uppercase; color: var(--ink-faint);
}
.report-fields > summary::-webkit-details-marker { display: none; }
.report-fields > summary::before { content: "▸"; font-size: 10px; }
.report-fields[open] > summary::before { content: "▾"; }
.report-fields-count {
    padding: 1px 8px; border-radius: 999px; background: var(--surface-sunken);
    font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--ink-soft);
}
.report-fields-body { padding: 6px 0 10px; }
.report-fields-grid { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); max-height: none; margin-top: 6px; }
.report-downloads .btn.is-disabled { opacity: 0.45; pointer-events: none; }

.dt-menu-item {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 7px 8px;
    border-radius: var(--r-sm);
    font-size: 13px;
    cursor: pointer;
}

.dt-menu-item:hover { background: var(--surface-sunken); }

/* --- Download rows --------------------------------------------------------- */

.dt-file {
    display: flex;
    align-items: center;
    gap: 11px;
    width: 100%;
    padding: 9px 8px;
    border: 1px solid transparent;
    border-radius: var(--r-md);
    background: none;
    font: inherit;
    text-align: left;
    color: var(--ink);
    cursor: pointer;
}

.dt-file:hover {
    text-decoration: none;
    background: var(--surface-sunken);
    border-color: var(--hairline-soft);
}

.dt-file-mark {
    flex: none;
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    border-radius: var(--r-md);
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: #fff;
}

/* The colours people already associate with each file type. */
.dt-file-csv { background: linear-gradient(160deg, #4b8f4e, #2f6b34); }
.dt-file-xls { background: linear-gradient(160deg, #1f8a4c, #146239); }
.dt-file-pdf { background: linear-gradient(160deg, #d0453b, #a3271f); }
.dt-file-copy { background: linear-gradient(160deg, #5b6673, #3c454f); }
.dt-file-print { background: linear-gradient(160deg, #2f6fd0, #1d4f9c); }

.dt-file-text { min-width: 0; }
.dt-file-text strong { display: block; font-size: 13px; font-weight: 600; }
.dt-file-text span { display: block; font-size: 11.5px; color: var(--ink-faint); }

/* --- Selection bar --------------------------------------------------------- */

.dt-selected {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 9px 20px;
    background: var(--accent-wash);
    border-bottom: 1px solid var(--hairline-soft);
    font-size: 12.5px;
}

/* The attribute alone would lose to display:flex. */
.dt-selected[hidden] { display: none; }

.dt-selected-count { font-weight: 650; color: var(--accent); }
.dt-selected-note { color: var(--ink-soft); }

/* Bulk actions: buttons that act on whatever is ticked. Forms sit inline so
   the row of buttons reads as one group. */
.dt-bulk { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.dt-bulk form { display: contents; }

/* View and edit sleep until exactly one row is ticked. */
.dt-bulk .is-disabled {
    opacity: .45;
    pointer-events: none;
    cursor: not-allowed;
}

/* --- Bulk upload ----------------------------------------------------------- */

.up-steps {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 22px;
}

.up-step { display: flex; gap: 14px; align-items: flex-start; }

.up-step-num {
    flex: none;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--accent);
    color: #fff;
    font-weight: 700;
    font-size: 14px;
}

.up-step strong { display: block; font-size: 14px; margin-bottom: 2px; }
.up-step p { margin: 0 0 10px; color: var(--ink-soft); font-size: 13px; max-width: 62ch; }

/* One row per template flavour: everything, categories, sub, sub-sub. */
.up-tpls { display: grid; gap: 8px; max-width: 640px; }

.up-tpl {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    border: 1px solid var(--hairline);
    border-radius: var(--r-sm, 7px);
    background: var(--surface);
}

.up-tpl.is-picked { border-color: var(--accent); background: var(--accent-wash); }

.up-tpl-text { display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: baseline; min-width: 0; }
.up-tpl-text strong { font-size: 13px; }
.up-tpl-text > span:last-child { display: block; width: 100%; color: var(--ink-soft); font-size: 12px; }

.up-choices { display: inline-flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.up-choices .dt-file-mark { width: 30px; height: 20px; font-size: 8.5px; border-radius: 4px; }

.up-form { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.up-form input[type="file"] { max-width: 340px; }

/* The "please wait" overlay while a file is being read in. */
.up-overlay {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: grid;
    place-items: center;
    background: rgba(13, 17, 23, .55);
    backdrop-filter: blur(2px);
}

.up-overlay[hidden] { display: none; }

.up-overlay-box {
    background: var(--surface);
    border-radius: 14px;
    padding: 28px 34px;
    max-width: 340px;
    text-align: center;
    box-shadow: 0 18px 50px rgba(0, 0, 0, .35);
}

.up-overlay-box strong { display: block; margin-top: 14px; font-size: 15px; }
.up-overlay-box p { margin: 6px 0 0; color: var(--ink-soft); font-size: 12.5px; }

.up-spinner {
    display: inline-block;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 3.5px solid var(--hairline-soft, #d9dce1);
    border-top-color: var(--accent);
    animation: up-spin .8s linear infinite;
}

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

/* --- The table itself ------------------------------------------------------ */

.dt-table thead th { position: sticky; top: 0; z-index: 2; }

.dt-table th[data-dt-sort] {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
    padding-right: 26px;
    position: relative;
}

.dt-table th[data-dt-sort]:hover { color: var(--ink); }

/* The arrow is always drawn, faint until the column is the sorted one. */
.dt-table th[data-dt-sort]::after {
    content: '';
    position: absolute;
    right: 10px;
    top: 50%;
    width: 7px;
    height: 7px;
    margin-top: -5px;
    border-right: 1.6px solid currentColor;
    border-bottom: 1.6px solid currentColor;
    transform: rotate(45deg);
    opacity: 0.22;
    transition: opacity 0.15s ease, transform 0.15s ease;
}

.dt-table th.is-sorted-asc::after {
    opacity: 1;
    margin-top: -2px;
    transform: rotate(-135deg);
    color: var(--accent);
}

.dt-table th.is-sorted-desc::after { opacity: 1; color: var(--accent); }

.dt-check { width: 34px; padding-right: 0 !important; text-align: left; }

.dt-table tbody tr { transition: background 0.12s ease; }
.dt-table tbody tr:hover td { background: var(--accent-wash); }
.dt-table tbody tr.is-selected td { background: var(--accent-wash); }
/* A selected row keeps a marker of its own, so it stays distinct from the
   row the pointer happens to be over. */
.dt-table tbody tr.is-selected td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* A parent kept on screen only because one of its submenus matched. */
.dt-table tbody tr.is-ghost td { opacity: 0.62; }

.dt-toggle {
    flex: none;
    display: grid;
    place-items: center;
    width: 20px;
    height: 20px;
    padding: 0;
    border: none;
    border-radius: var(--r-sm);
    background: none;
    color: var(--ink-faint);
    cursor: pointer;
    transition: transform 0.15s ease, background 0.15s ease;
    transform: rotate(90deg);
}

.dt-toggle:hover { background: var(--hairline-soft); color: var(--ink); }
.dt-toggle.is-collapsed { transform: rotate(0deg); }
.dt-toggle svg { width: 13px; height: 13px; }
.dt-toggle[hidden] { display: none; }

.menu-when { white-space: nowrap; font-size: 12.5px; }
.menu-when span { display: block; font-size: 11.5px; color: var(--ink-faint); }

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

.dt-empty {
    display: grid;
    justify-items: center;
    gap: 4px;
    padding: 44px 20px;
    text-align: center;
    color: var(--ink-soft);
}

.dt-empty[hidden] { display: none; }
.dt-empty svg { width: 34px; height: 34px; color: var(--ink-faint); opacity: 0.6; margin-bottom: 4px; }
.dt-empty strong { font-size: 14px; color: var(--ink); }
.dt-empty p { font-size: 12.5px; margin: 0; }

/* --- Footer and paging ------------------------------------------------------ */

.dt-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 12px 20px;
    background: var(--surface-sunken);
}

/* The same bar sits above and below the table; each draws only the border
   that faces the rows. */
.dt-foot-top { border-bottom: 1px solid var(--hairline-soft); }
.dt-foot-bottom { border-top: 1px solid var(--hairline-soft); }

.dt-pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

/* Type a page number instead of clicking through to it. */
.dt-goto {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding-left: 10px;
    border-left: 1px solid var(--hairline);
}

.dt-goto[hidden] { display: none; }

.dt-goto-label { font-size: 12.5px; color: var(--ink-faint); white-space: nowrap; }

.dt-goto-input {
    width: 62px;
    padding: 4px 8px;
    font-size: 12.5px;
    text-align: center;
    border-radius: var(--r-sm);
}

/* The spinners are noise at this size; the arrows are the pager's job. */
.dt-goto-input::-webkit-outer-spin-button,
.dt-goto-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.dt-goto-input { -moz-appearance: textfield; }

.dt-info { font-size: 12.5px; color: var(--ink-faint); font-variant-numeric: tabular-nums; }

.dt-pages { display: inline-flex; align-items: center; gap: 4px; }

.dt-page {
    min-width: 30px;
    height: 30px;
    padding: 0 8px;
    font: inherit;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ink-soft);
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-sm);
    cursor: pointer;
    transition: background 0.14s ease, color 0.14s ease;
}

.dt-page:hover:not(:disabled) { background: var(--surface-sunken); color: var(--ink); }
.dt-page:disabled { opacity: 0.4; cursor: default; }

.dt-page.is-current {
    color: #fff;
    background: linear-gradient(180deg, var(--accent), var(--accent-deep));
    border-color: transparent;
}

.dt-gap { padding: 0 2px; color: var(--ink-faint); }

@media (max-width: 860px) {
    .dt-bar { flex-direction: column; align-items: stretch; }
    .dt-bar-left, .dt-bar-right { justify-content: space-between; }
    .dt-search { flex: 1 1 100%; }
    .dt-search .input { width: 100%; }
    .dt-menu-panel { width: min(300px, calc(100vw - 40px)); }
    .dt-foot { justify-content: center; }
}

/* --- Print ------------------------------------------------------------------
   "Print" on the download menu prints the table as it stands on screen, so
   everything around it is dropped and the ink-heavy styling is flattened. */
@media print {
    .sidebar, .topbar, .dt-bar, .dt-foot, .dt-selected,
    .col-actions, .dt-check, .stat-grid, .notice, .page-head p {
        display: none !important;
    }

    body { background: #fff; color: #000; }
    .shell { display: block; }
    .content { padding: 0; }
    .card { border: none; box-shadow: none; margin: 0; }
    .card-head { border-bottom: 1px solid #ccc; padding: 0 0 8px; }
    .table-wrap { overflow: visible; }
    .table { font-size: 10pt; }
    .table th { background: #eee !important; color: #000; }
    .table td, .table th { padding: 5px 7px; border-bottom: 1px solid #ddd; }
    .dt-toggle, .menu-branch { display: none !important; }

    /* Screen-only affordances: the sort arrows, the hover tint and whatever
       happened to be selected when Print was pressed. */
    .dt-table th[data-dt-sort]::after { display: none; }
    .dt-table th[data-dt-sort] { padding-right: 7px; }
    .dt-table tbody tr:hover td,
    .dt-table tbody tr.is-selected td { background: none !important; box-shadow: none !important; }
    .pill { border: 1px solid #999; color: #000 !important; background: none !important; }
    tr { page-break-inside: avoid; }
}

/* --- Icon row actions -------------------------------------------------------
   Six labelled buttons per row made the action column wider than the data.
   These carry the same actions as icons, named by title and aria-label. */

.icon-btn {
    display: inline-grid;
    place-items: center;
    width: 28px;
    height: 28px;
    padding: 0;
    color: var(--ink-faint);
    background: none;
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    cursor: pointer;
    transition: color 0.14s ease, background 0.14s ease, border-color 0.14s ease;
}

.icon-btn:hover {
    color: var(--accent);
    background: var(--surface);
    border-color: var(--hairline);
    text-decoration: none;
}

.icon-btn svg { width: 16px; height: 16px; }
.icon-btn-danger:hover { color: var(--danger); background: var(--danger-wash); border-color: transparent; }

.row-actions-icons { gap: 2px; }
.row-actions-icons form { display: inline-flex; margin: 0; }

.dt-file.is-done .dt-file-mark { background: linear-gradient(160deg, #1f8a4c, #146239); }
.dt-file.is-done .dt-file-text strong { color: var(--good); }

/* --- Status mark ------------------------------------------------------------
   Green for visible, red for hidden. The column is a single glyph wide; the
   word behind it lives in the tooltip, in the sort key and in the copied
   table, so nothing is lost by dropping the label. */

.col-status { width: 68px; text-align: center; }

.status-mark {
    display: inline-grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
}

.status-mark svg { width: 18px; height: 18px; }

.status-on { color: var(--good); background: var(--good-wash); }
.status-off { color: var(--danger); background: var(--danger-wash); }

/* --- Where a change came from ----------------------------------------------
   Four tiles for the headline facts, then the long tail as a detail list. */

.origin-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 10px;
    margin-bottom: 16px;
}

.origin-tile {
    padding: 12px 14px;
    background: var(--surface-sunken);
    border: 1px solid var(--hairline-soft);
    border-radius: var(--r-md);
    min-width: 0;
}

.origin-label {
    display: block;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-bottom: 4px;
}

.origin-value {
    display: block;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.35;
    overflow-wrap: anywhere;
}

.origin-note {
    display: block;
    margin-top: 3px;
    font-size: 11.5px;
    color: var(--ink-faint);
    overflow-wrap: anywhere;
}

.origin-flags {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    margin-bottom: 16px;
    background: var(--warn-wash);
    border-radius: var(--r-md);
}

.origin-flags .origin-note { margin: 0; color: var(--ink-soft); }

/* The flag sits in the card header, at the size of a heading. */
.origin-flag { font-size: 26px; line-height: 1; }

.log-from { min-width: 150px; }
.log-from-place { display: block; font-weight: 550; }
.log-flag { margin-right: 4px; }

/* --- Tooltips ---------------------------------------------------------------
   Drawn in CSS above the control they belong to: dark plate, white text.
   The native title attribute is not used on these — the browser's own
   tooltip is slow to appear, sits under the pointer and cannot be styled.
   The label still reaches a screen reader through aria-label. */

[data-tip] { position: relative; }

[data-tip]::after,
[data-tip]::before {
    position: absolute;
    left: 50%;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.12s ease, transform 0.12s ease;
    z-index: 40;
}

/* The plate. */
[data-tip]::after {
    content: attr(data-tip);
    bottom: calc(100% + 7px);
    transform: translate(-50%, 3px);
    padding: 5px 9px;
    border-radius: var(--r-sm);
    background: #14161b;
    color: #ffffff;
    font-size: 11.5px;
    font-weight: 550;
    line-height: 1.3;
    letter-spacing: 0.01em;
    white-space: nowrap;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3);
}

/* The little arrow under it. */
[data-tip]::before {
    content: '';
    bottom: calc(100% + 2px);
    transform: translate(-50%, 3px);
    border: 5px solid transparent;
    border-top-color: #14161b;
}

[data-tip]:hover::after,
[data-tip]:hover::before,
[data-tip]:focus-visible::after,
[data-tip]:focus-visible::before {
    opacity: 1;
    transform: translate(-50%, 0);
}

/* In dark mode the plate lifts off the page rather than sinking into it. */
:root[data-theme="dark"] [data-tip]::after { background: #3a3f47; }
:root[data-theme="dark"] [data-tip]::before { border-top-color: #3a3f47; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) [data-tip]::after { background: #3a3f47; }
    :root:not([data-theme="light"]) [data-tip]::before { border-top-color: #3a3f47; }
}

/* The first row's tooltip would otherwise be clipped by the scroll box. */
.table-wrap { padding-top: 0; }
.dt-table tbody tr:first-child [data-tip]::after { bottom: auto; top: calc(100% + 7px); }
.dt-table tbody tr:first-child [data-tip]::before {
    bottom: auto;
    top: calc(100% + 2px);
    border-top-color: transparent;
    border-bottom-color: #14161b;
}

:root[data-theme="dark"] .dt-table tbody tr:first-child [data-tip]::before { border-bottom-color: #3a3f47; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .dt-table tbody tr:first-child [data-tip]::before { border-bottom-color: #3a3f47; }
}

/* The action column sits against the right edge of the scroll box, so its
   tooltips hang from that edge instead of straddling it and being clipped. */
.col-actions [data-tip]::after {
    left: auto;
    right: -2px;
    transform: translate(0, 3px);
}

.col-actions [data-tip]:hover::after,
.col-actions [data-tip]:focus-visible::after { transform: translate(0, 0); }

/* Print and the copied table ignore tooltips entirely. */
@media print {
    [data-tip]::after, [data-tip]::before { display: none !important; }
}

/* Category depth, shown by indenting the name. The tree can be three deep,
   so each level steps in a little further than the last. */
.cat-indent-2 { padding-left: 16px; }
.cat-indent-3 { padding-left: 32px; }

.cat-title .dt-toggle { margin-left: -2px; }
.cat-title > span > span { display: block; font-size: 12px; color: var(--ink-faint); }

/* --- Login activity ---------------------------------------------------------
   The sidebar entry sits in the account block at the foot, so it needs its
   own spacing rather than the content nav's. */

.nav-link-foot {
    margin: 0 0 8px;
    padding: 8px 10px;
    font-size: 13px;
}

.table-logins { min-width: 1220px; }
.table-logins th:nth-child(1) { width: 34px; }
.table-logins th:nth-child(2) { min-width: 132px; }
.table-logins th:nth-child(3),
.table-logins td:nth-child(3) { min-width: 190px; }
.table-logins th:nth-child(4) { min-width: 150px; }
.table-logins th:nth-child(5),
.table-logins td:nth-child(5) { min-width: 180px; }
.table-logins th:nth-child(6) { min-width: 150px; }
.table-logins th:nth-child(7) { min-width: 96px; }
.table-logins th:nth-child(8) { min-width: 76px; }
.table-logins th:nth-child(9) { min-width: 150px; }
.table-logins th:nth-child(10) { min-width: 120px; }

/* A session that is still going, marked while it is happening. */
.pill-live { margin-left: 4px; }

.pill-live .pill-dot {
    animation: dt-pulse 1.8s ease-in-out infinite;
}

@keyframes dt-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.25; }
}

@media (prefers-reduced-motion: reduce) {
    .pill-live .pill-dot { animation: none; }
}

/* --- Enquiries --------------------------------------------------------------
   Rows carry a paragraph of somebody's own words, so the message column is
   given room and the rest is kept tight. */

.table-enquiries { min-width: 1300px; }
.table-enquiries th:nth-child(1) { width: 34px; }
.table-enquiries th:nth-child(2) { min-width: 128px; }
.table-enquiries th:nth-child(3),
.table-enquiries td:nth-child(3) { min-width: 200px; }
.table-enquiries th:nth-child(4) { min-width: 140px; }
.table-enquiries th:nth-child(5),
.table-enquiries td:nth-child(5) { width: 26%; min-width: 240px; }
.table-enquiries th:nth-child(6) { min-width: 160px; }
.table-enquiries th:nth-child(7) { min-width: 130px; }
.table-enquiries th:nth-child(8) { min-width: 90px; }
.table-enquiries th:nth-child(9) { min-width: 120px; }
.table-enquiries th:nth-child(10) { min-width: 150px; }

.enq-ref { font-weight: 650; font-variant-numeric: tabular-nums; }
.enq-message span:first-child { display: block; color: var(--ink-soft); }

/* The enquiry itself, quoted rather than paraphrased. */
.enq-quote {
    margin: 0 0 16px;
    padding: 14px 16px;
    border-left: 3px solid var(--accent);
    border-radius: 0 var(--r-md) var(--r-md) 0;
    background: var(--surface-sunken);
    font-size: 14px;
    line-height: 1.6;
    white-space: pre-line;
}

.enq-list { margin: 0 0 16px; padding-left: 18px; font-size: 13px; }
.enq-list li { padding: 2px 0; }
.enq-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }

/* --- Enquiry discussion (chat) ----------------------------------------------
   Read as a messaging app: the reader's own messages on the right, colleagues'
   on the left with their name above, and the panel's own events centred. A
   reply quotes what it answers instead of indenting under it, so a long
   conversation keeps one reading order however many replies it collects. */

.chat {
    padding: 18px 20px;
    max-height: 30rem;
    overflow-y: auto;
    background: var(--surface-sunken);
    border-top: 1px solid var(--hairline-soft);
    border-bottom: 1px solid var(--hairline-soft);
}

/* A date line whenever the day changes. */
.chat-day {
    display: flex;
    justify-content: center;
    margin: 6px 0 14px;
}

.chat-day span {
    padding: 3px 11px;
    border-radius: 999px;
    background: var(--surface);
    border: 1px solid var(--hairline-soft);
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ink-faint);
}

/* Closed, marked spam, reopened: nobody's message, so it belongs to neither
   side. */
.chat-event {
    display: flex;
    justify-content: center;
    margin: 10px 0;
    text-align: center;
}

.chat-event span {
    max-width: 32rem;
    padding: 5px 12px;
    border-radius: var(--r-md);
    background: var(--warn-wash);
    color: var(--warn);
    font-size: 12px;
    line-height: 1.5;
}

.chat-event time { opacity: 0.75; margin-left: 4px; }

.chat-row {
    display: flex;
    align-items: flex-end;
    gap: 8px;
    margin-bottom: 12px;
}

/* Own messages, mirrored to the right. */
.chat-row-mine { flex-direction: row-reverse; }

.chat-avatar { margin-bottom: 2px; }

.chat-bubble {
    position: relative;
    max-width: min(34rem, 78%);
    padding: 9px 13px 7px;
    border-radius: var(--r-lg);
    background: var(--surface);
    border: 1px solid var(--hairline-soft);
    box-shadow: var(--lift-1);
    /* The corner nearest its own side is squared off, which is what makes a
       bubble look like it is spoken from there. */
    border-bottom-left-radius: var(--r-sm);
}

.chat-row-mine .chat-bubble {
    background: var(--accent-wash);
    border-color: transparent;
    border-bottom-left-radius: var(--r-lg);
    border-bottom-right-radius: var(--r-sm);
}

/* Group chat: the name sits above the words, once per message. */
.chat-author {
    margin: 0 0 3px;
    font-size: 12.5px;
    font-weight: 650;
    color: var(--accent);
}

.chat-text {
    margin: 0;
    font-size: 14px;
    line-height: 1.55;
    color: var(--ink);
    /* Typed line breaks are meaning in a note about a phone call. */
    white-space: pre-line;
    overflow-wrap: anywhere;
}

/* What this message is answering. */
.chat-quote {
    display: block;
    margin: 0 0 6px;
    padding: 6px 10px;
    border-left: 3px solid var(--accent);
    border-radius: 0 var(--r-sm) var(--r-sm) 0;
    background: var(--surface-sunken);
    text-decoration: none;
}

.chat-quote strong {
    display: block;
    font-size: 11.5px;
    color: var(--accent);
}

.chat-quote span {
    display: block;
    font-size: 12px;
    color: var(--ink-soft);
    line-height: 1.45;
}

.chat-quote:hover { background: var(--hairline-soft); }

/* Channel and time, small and quiet under the words. */
.chat-foot {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
    margin-top: 3px;
    font-size: 11px;
    color: var(--ink-faint);
}

.chat-foot .pill { padding: 0 7px; font-size: 10.5px; }
.chat-foot time { white-space: nowrap; }

/* Reply and Remove, beside the bubble and revealed on hover: a conversation
   should read as messages, not as rows of buttons. */
.chat-actions {
    flex: none;
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 2px 4px;
    border-radius: 999px;
    background: var(--surface);
    border: 1px solid var(--hairline);
    box-shadow: var(--lift-1);
    opacity: 0;
    transition: opacity 0.12s ease;
}

/* Kept in the layout while invisible, so revealing it never shifts the
   conversation sideways under the pointer. */
.chat-row:hover .chat-actions,
.chat-row:focus-within .chat-actions { opacity: 1; }

.chat-action {
    padding: 2px 8px;
    border: none;
    border-radius: 999px;
    background: none;
    font: inherit;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--accent);
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
}

.chat-action:hover { background: var(--accent-wash); }

.chat-empty {
    margin: 0;
    padding: 20px 0;
    text-align: center;
    font-size: 13px;
    color: var(--ink-faint);
}

/* --- The composer ---------------------------------------------------------- */

.chat-composer { padding: 14px 20px 18px; }

.chat-composer-row {
    display: flex;
    align-items: flex-end;
    gap: 8px;
}

.chat-channel { width: auto; min-width: 136px; flex: none; }

/* The custom channel's name, revealed beside the dropdown that asked for it.
   The counter sits inside the field's own footprint so showing it does not
   change the height of the composer row. */
.chat-channel-custom {
    position: relative;
    flex: none;
    width: 11.5rem;
}

.chat-channel-custom .input { padding-right: 3.4rem; }

.chat-channel-count {
    position: absolute;
    top: 50%;
    right: 10px;
    transform: translateY(-50%);
    font-size: 10.5px;
    font-variant-numeric: tabular-nums;
    color: var(--ink-faint);
    pointer-events: none;
}

/* Nothing left to type: say so plainly rather than only stopping. */
.chat-channel-count.is-spent { color: var(--warn); font-weight: 650; }

.chat-input {
    flex: 1;
    min-height: 42px;
    max-height: 180px;
    padding-top: 10px;
    padding-bottom: 10px;
    resize: none;
    line-height: 1.5;
}

.chat-send { flex: none; }

/* What the next message will answer, shown above the box with a way out. */
.chat-replying {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
    padding: 7px 10px 7px 12px;
    border-left: 3px solid var(--accent);
    border-radius: 0 var(--r-md) var(--r-md) 0;
    background: var(--surface-sunken);
}

.chat-replying-body { min-width: 0; flex: 1; }

.chat-replying-label {
    display: block;
    font-size: 11.5px;
    font-weight: 650;
    color: var(--accent);
}

.chat-replying-text {
    display: block;
    font-size: 12px;
    color: var(--ink-soft);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.chat-replying-cancel {
    flex: none;
    display: grid;
    place-items: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    font-size: 17px;
    line-height: 1;
    color: var(--ink-faint);
    text-decoration: none;
}

.chat-replying-cancel:hover { background: var(--hairline-soft); color: var(--ink); }

/* --- Frozen -----------------------------------------------------------------
   The composer is removed rather than disabled: a box you can type into but
   not send is a worse answer than no box at all. */

.chat-frozen {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    padding: 16px 20px;
}

.chat-frozen-text { flex: 1; min-width: 15rem; }
.chat-frozen-text strong { display: block; font-size: 13.5px; }
.chat-frozen-text span { font-size: 12.5px; color: var(--ink-faint); }

/* --- Handling -------------------------------------------------------------- */

.handling-row {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    flex-wrap: wrap;
}

.handling-status { margin-bottom: 0; min-width: 13rem; }
.handling-status .select { max-width: 16rem; }

/* Lines up with the select rather than its label. */
.handling-save { margin-top: 22px; }

.handling-summary { margin-top: 16px; max-width: 44rem; }
.handling-summary .field { margin-bottom: 0; }

.handling-required {
    margin-left: 4px;
    font-size: 11px;
    font-weight: 600;
    color: var(--warn);
    text-transform: none;
    letter-spacing: 0;
}

.handling-note-text { white-space: pre-line; }

@media (max-width: 640px) {
    .chat { padding: 14px 12px; }
    .chat-bubble { max-width: 88%; }
    .chat-composer { padding: 12px 12px 16px; }
    .chat-composer-row { flex-wrap: wrap; }
    .chat-channel { width: 100%; }
    .chat-channel-custom { width: 100%; }
    .chat-input { flex: 1 1 100%; }
    .chat-send { width: 100%; }
    .chat-frozen { padding: 14px 12px; }
    /* Hover cannot be relied on, so the actions stay visible. */
    .chat-actions { opacity: 1; box-shadow: none; }
}

/* --- Consultations ----------------------------------------------------------
   The same table as enquiries, plus the slot somebody asked for and the page
   they asked from — the two things this form has that an enquiry does not. */

.table-consultations { min-width: 1360px; }
.table-consultations th:nth-child(1) { width: 34px; }
.table-consultations th:nth-child(2) { min-width: 128px; }
.table-consultations th:nth-child(3),
.table-consultations td:nth-child(3) { min-width: 200px; }
.table-consultations th:nth-child(4) { min-width: 140px; }
.table-consultations th:nth-child(5) { min-width: 150px; }
.table-consultations th:nth-child(6) { min-width: 140px; }
.table-consultations th:nth-child(7),
.table-consultations td:nth-child(7) { width: 22%; min-width: 210px; }
.table-consultations th:nth-child(8) { min-width: 130px; }
.table-consultations th:nth-child(9) { min-width: 90px; }
.table-consultations th:nth-child(10) { min-width: 120px; }
.table-consultations th:nth-child(11) { min-width: 150px; }

/* The requested day, called out because it is what decides urgency. */
.slot-headline {
    margin: 0 0 16px;
    padding: 14px 16px;
    border-left: 3px solid var(--warn);
    border-radius: 0 var(--r-md) var(--r-md) 0;
    background: var(--warn-wash);
    font-size: 16px;
    font-weight: 650;
    color: var(--ink);
}

/* A day that has gone by on a request still waiting. */
.cell-stale { color: var(--danger); font-weight: 600; }

/* The page the dialog was opened from: a path, kept on one line. */
.cell-page {
    display: inline-block;
    max-width: 13rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

/* --- SEO --------------------------------------------------------------------
   A table of the site's pages with the tags describing each. Pages are derived
   from the navigation, the industries and the site's own fixed pages, so there
   is nothing to create and nothing to delete — only editing. */

.table-seo { min-width: 1180px; }
.table-seo th:nth-child(1) { min-width: 170px; }
.table-seo th:nth-child(2) { min-width: 190px; }
.table-seo th:nth-child(3),
.table-seo td:nth-child(3) { min-width: 220px; }
.table-seo th:nth-child(4),
.table-seo td:nth-child(4) { width: 26%; min-width: 220px; }
.table-seo th:nth-child(5) { min-width: 130px; }
.table-seo th:nth-child(6) { min-width: 150px; }

/* A title past what search engines show. Said plainly rather than in red: it
   is a note about how it will look, not a mistake to correct. */
.seo-long { color: var(--warn); }

/* Title and keyword boxes: textareas so a long value can be read while it is
   written, but line breaks are not allowed in them (public/js/seo.js), so they
   read as a field that has grown rather than as a place for paragraphs. */
.seo-line,
.seo-title,
.seo-fields textarea[data-seo-single-line] {
    resize: vertical;
    min-height: 60px;
    line-height: 1.5;
}

.seo-required {
    margin-left: 4px;
    font-size: 11px;
    font-weight: 600;
    color: var(--warn);
    text-transform: none;
    letter-spacing: 0;
}

/* The count beside a field, turning amber once it passes the ideal length. */
[data-seo-count-out].is-over { color: var(--warn); font-weight: 650; }

.seo-fields .field:last-child { margin-bottom: 0; }

/* Indexing, links and card style: three narrow choices on one line. */
.seo-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 0 14px;
}

/* Said once at the top of the dialog, for a page still on the defaults. */
.seo-inherit-note {
    margin: 0 0 16px;
    padding: 10px 13px;
    border-left: 3px solid var(--accent);
    border-radius: 0 var(--r-md) var(--r-md) 0;
    background: var(--accent-wash);
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--ink-soft);
}

/* The fields asked for less often, folded away so an ordinary edit is short. */
.seo-more {
    margin-top: 4px;
    padding-top: 14px;
    border-top: 1px solid var(--hairline-soft);
}

.seo-more summary {
    cursor: pointer;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--accent);
    list-style: none;
}

.seo-more summary::-webkit-details-marker { display: none; }
.seo-more summary:hover { color: var(--accent-deep); }
.seo-more[open] > summary { margin-bottom: 14px; }

/* The unread count beside the sidebar entry. */
.nav-count {
    margin-left: auto;
    min-width: 20px;
    padding: 1px 6px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 650;
    text-align: center;
    color: #fff;
    background: var(--accent);
}

.nav-link.is-active .nav-count { background: var(--accent-deep); }

/* --- Busy state on the sign-in screens --------------------------------------
   A round trip that takes a second looks identical to a page that has done
   nothing, so the button and the page both say what is happening. */

.btn-spinner {
    display: inline-block;
    width: 15px;
    height: 15px;
    margin-right: 2px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    opacity: 0.9;
    animation: busy-spin 0.7s linear infinite;
    vertical-align: -2px;
}

.btn.is-busy {
    cursor: progress;
    opacity: 0.92;
}

/* A disabled button still has to look like the one that was pressed. */
.btn.is-busy:disabled { opacity: 0.92; }

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

.busy-overlay {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: grid;
    place-items: center;
    padding: 24px;
    background: rgba(16, 20, 32, 0.55);
    backdrop-filter: blur(2px);
    opacity: 0;
    transition: opacity 0.18s ease;
}

.busy-overlay.is-shown { opacity: 1; }

.busy-card {
    width: min(340px, 100%);
    padding: 30px 28px 26px;
    text-align: center;
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-xl);
    box-shadow: var(--lift-3);
    transform: translateY(6px);
    transition: transform 0.18s ease;
}

.busy-overlay.is-shown .busy-card { transform: translateY(0); }

/* The ring: a heavier version of the button's spinner, in the accent. */
.busy-ring {
    width: 42px;
    height: 42px;
    margin: 0 auto 18px;
    border: 3px solid var(--accent-wash);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: busy-spin 0.8s linear infinite;
}

.busy-title {
    margin: 0 0 6px;
    font-size: 15.5px;
    font-weight: 650;
    color: var(--ink);
}

.busy-note {
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--ink-soft);
}

.busy-slow {
    margin: 14px 0 0;
    padding-top: 12px;
    border-top: 1px solid var(--hairline-soft);
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--warn);
}

.busy-slow[hidden] { display: none; }

/* Somebody who has asked for less movement gets the same information
   without anything spinning at them. */
@media (prefers-reduced-motion: reduce) {
    .btn-spinner,
    .busy-ring {
        animation: none;
    }

    .busy-ring { border-top-color: var(--accent); opacity: 0.9; }
    .busy-overlay, .busy-card { transition: none; }
}

/* --- Show password ----------------------------------------------------------
   The eye sits inside the field's right edge. The input keeps room for it so
   a long password never runs underneath. */

.pw-field { position: relative; display: block; }

.pw-field.has-toggle .pw-input { padding-right: 44px; }

.pw-toggle {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    padding: 0;
    color: var(--ink-faint);
    background: none;
    border: none;
    border-radius: var(--r-sm);
    cursor: pointer;
    transition: color 0.14s ease, background 0.14s ease;
}

.pw-toggle:hover { color: var(--ink); background: var(--surface-sunken); }
.pw-toggle svg { width: 17px; height: 17px; }

/* Revealed is a state worth seeing at a glance. */
.pw-field.is-revealed .pw-toggle { color: var(--accent); }

/* Chrome and Edge add their own eye to password fields; two is one too many. */
.pw-input::-ms-reveal,
.pw-input::-ms-clear { display: none; }

/* --- Error pages ------------------------------------------------------------
   A 404 to a stranger is a closed door; to somebody signed in it is a wrong
   turn, and wants a map. Two looks, one stylesheet. */

/* Signed out: inside the gate card. */
.err-gate { text-align: center; }

.err-code {
    font-size: 44px;
    font-weight: 700;
    letter-spacing: 0.04em;
    line-height: 1;
    color: var(--ink-faint);
    opacity: 0.45;
    margin-bottom: 14px;
}

.err-gate-note {
    font-size: 13px;
    line-height: 1.6;
    color: var(--ink-soft);
    margin-bottom: 22px;
}

/* Signed in: a signpost in the content area, with the panel's own menus
   still around it. Deliberately plain — the real menu is on the left, and a
   grid of cards here would be a second one competing with it. */
.err-panel { max-width: 640px; padding-top: 24px; }

/* The number, said quietly: the sentence under it is what matters. */
.err-status {
    font-size: 40px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.03em;
    color: var(--ink-faint);
    opacity: 0.4;
    margin-bottom: 12px;
}

.err-panel h1 { margin-bottom: 12px; }

.err-lead {
    font-size: 14.5px;
    line-height: 1.65;
    color: var(--ink-soft);
    margin-bottom: 14px;
}

.err-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 20px 0 22px;
}


/* The shortcuts on the signed-in 404: plain links in two columns, with no
   border or shadow, so they read as a list rather than a second menu. */
.err-links-head {
    font-size: 13px;
    font-weight: 600;
    color: var(--ink-faint);
    margin: 26px 0 10px;
}

.err-links {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 2px 24px;
}

.err-links li {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 7px 0;
    border-bottom: 1px solid var(--hairline-soft);
}

.err-links a {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
}

.err-links a svg {
    width: 13px;
    height: 13px;
    flex: none;
    transition: transform 0.14s ease;
}

.err-links a:hover svg { transform: translateX(2px); }

.err-link-note {
    font-size: 12.5px;
    color: var(--ink-faint);
    min-width: 0;
    overflow-wrap: anywhere;
}

@media (prefers-reduced-motion: reduce) {
    .err-links a:hover svg { transform: none; }
}

/* --- Choosing a timezone ----------------------------------------------------
   Asked once, on the first visit, inside the sign-in card. */

.tz-gate-note {
    font-size: 13px;
    line-height: 1.6;
    color: var(--ink-soft);
    margin-bottom: 18px;
}

/* The browser's own guess, offered rather than applied. */
.tz-guess {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 12px;
    margin-bottom: 16px;
    background: var(--accent-wash);
    border-radius: var(--r-md);
}

.tz-guess[hidden] { display: none; }

.tz-guess-text { flex: 1; min-width: 0; }
.tz-guess-text strong { display: block; font-size: 13px; color: var(--ink); }
.tz-guess-text span { display: block; font-size: 12px; color: var(--ink-soft); }

/* The sign-out escape hatch on the timezone screen. */
.gate-swap-button {
    font: inherit;
    font-size: 13px;
    color: var(--ink-faint);
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
}

.gate-swap-button:hover { color: var(--ink); text-decoration: underline; }

/* --- Rearranging the menu ----------------------------------------------------
   The arrange screen. A plain nested list rather than the data table: the order
   here is arranged by hand, and a table the reader can re-sort would contradict
   the one thing this screen is for.
   ---------------------------------------------------------------------------- */

.arrange-list,
.arrange-sub {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.arrange-list > .arrange-item + .arrange-item { margin-top: 8px; }

/* Submenus sit inside their main item, indented and marked with a rule, so it
   is obvious at a glance which block a row will travel with. */
.arrange-sub {
    margin: 8px 0 0 26px;
    padding-left: 14px;
    border-left: 2px solid var(--hairline-soft);
}

.arrange-sub:empty { display: none; }

.arrange-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-sm);
    /* A mouse may take hold of the row anywhere that is not a control. */
    cursor: grab;
}

.arrange-row:hover { border-color: var(--hairline-strong, rgba(16, 20, 32, 0.18)); }

/* The grip. Only a signpost for a mouse, which can grab the whole row — but
   the handle itself for touch, where the rest of the row must stay free to
   scroll the page. touch-action says exactly that to the browser. */
.arrange-grip {
    flex: none;
    display: grid;
    place-items: center;
    width: 22px;
    height: 26px;
    color: var(--ink-faint);
    border-radius: 5px;
    touch-action: none;
    cursor: grab;
}

.arrange-grip svg { width: 18px; height: 18px; }
.arrange-row:hover .arrange-grip { color: var(--ink-soft); background: var(--surface-sunken); }

.arrange-item.is-child > .arrange-row {
    background: var(--surface-sunken);
    border-style: dashed;
}

/* The live position. It renumbers as rows move, so what you see is what will
   be written when the order is saved. */
.arrange-pos {
    flex: none;
    width: 24px;
    height: 24px;
    display: grid;
    place-items: center;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ink-soft);
    background: var(--surface-sunken);
    border: 1px solid var(--hairline-soft);
    border-radius: 50%;
}

.arrange-item.is-child .arrange-pos { background: var(--surface); }

.arrange-name {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.arrange-name strong { font-weight: 600; }

.arrange-meta {
    font-size: 12px;
    color: var(--ink-faint);
}

.arrange-hidden-note { color: var(--warn); }

.arrange-name .menu-url {
    width: fit-content;
    max-width: 100%;
    margin-top: 3px;
    overflow-wrap: anywhere;
}

.arrange-moves {
    flex: none;
    display: flex;
    gap: 6px;
}

.arrange-moves .icon-btn:disabled {
    opacity: 0.32;
    cursor: default;
}

/* Says the list has been moved but not yet written down — the counterpart to
   the Save button, which stays disabled until there is something to save. */
.arrange-flag {
    flex: none;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--warn);
    background: var(--warn-wash);
    border-radius: 999px;
    padding: 4px 10px;
}

/* The header copy of Cancel and Save order, beside the unsaved-changes mark.
   The list is taller than a screen, so the same pair sits at both ends of it. */
.arrange-head-actions {
    flex: none;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.arrange-empty {
    color: var(--ink-faint);
    font-size: 13px;
    margin: 0;
}

@media (max-width: 640px) {
    .arrange-sub { margin-left: 12px; }
    .arrange-row { gap: 8px; padding: 9px 10px; }
}

/* --- Dragging a row ----------------------------------------------------------
   The row being carried is lifted off the list and follows the pointer; the
   rows it passes slide out of its way, so the gap under the pointer is always
   the one it will drop into. Both movements are transforms, which the browser
   can run without laying the list out again.
   ---------------------------------------------------------------------------- */

.arrange-item.is-dragging {
    position: relative;
    z-index: 5;
}

.arrange-item.is-dragging > .arrange-row {
    cursor: grabbing;
    border-color: var(--accent);
    box-shadow: var(--lift-2);
    background: var(--surface);
    /* Just off the list, so it reads as picked up rather than slid along. */
    transform: scale(1.012);
    transition: box-shadow 140ms ease, transform 140ms ease, border-color 140ms ease;
}

.arrange-item.is-dragging .arrange-grip { color: var(--accent); background: none; }

/* While a row is in hand: no text selected by the dragging, and one cursor
   over the whole page rather than whatever each element would ask for. */
body.is-arranging { user-select: none; -webkit-user-select: none; }
body.is-arranging,
body.is-arranging .arrange-row { cursor: grabbing; }

/* A row in flight must not answer the pointer, or it would be judged as the
   neighbour the pointer is over. */
.arrange-item.is-dragging > .arrange-row { pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
    .arrange-item,
    .arrange-item > .arrange-row {
        transition: none !important;
    }
    .arrange-item.is-dragging > .arrange-row { transform: none; }
}

/* --- Splitting a dropdown into columns ---------------------------------------
   How the dropdown is drawn on the site, arranged the way it will be read: the
   columns sit side by side, and an entry is dragged into the one it belongs in.
   ---------------------------------------------------------------------------- */

.arrange-split {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin: 10px 0 0 26px;
    padding: 7px 10px;
    background: var(--surface-sunken);
    border: 1px solid var(--hairline-soft);
    border-radius: var(--r-sm);
}

.arrange-split-label {
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ink-soft);
}

.arrange-split-picker {
    display: inline-flex;
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-sm);
    overflow: hidden;
}

.arrange-split-option {
    min-width: 30px;
    padding: 4px 9px;
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    color: var(--ink-soft);
    background: none;
    border: 0;
    border-left: 1px solid var(--hairline-soft);
    cursor: pointer;
}

.arrange-split-option:first-child { border-left: 0; }
.arrange-split-option:hover { background: var(--surface-sunken); color: var(--ink); }

.arrange-split-option.is-on {
    color: #fff;
    background: var(--accent);
}

.arrange-split-note {
    font-size: 11.5px;
    color: var(--ink-faint);
}

/* The columns themselves. One column reads as a plain list; two or three sit
   side by side, which is what the site will draw. */
.arrange-columns {
    display: grid;
    gap: 10px;
    margin: 8px 0 0 26px;
}

.arrange-columns[data-count="1"] { grid-template-columns: 1fr; }
.arrange-columns[data-count="2"] { grid-template-columns: 1fr 1fr; }
.arrange-columns[data-count="3"] { grid-template-columns: 1fr 1fr 1fr; }
.arrange-columns[hidden] { display: none; }

.arrange-column {
    position: relative;
    padding: 8px;
    border: 1px dashed var(--hairline);
    border-radius: var(--r-sm);
    background: var(--desk-tint);
    min-height: 74px;
}

.arrange-column[hidden] { display: none; }

.arrange-column-head {
    display: block;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-bottom: 6px;
}

/* Only shown while the column is empty, so a column you have just switched on
   says what to do with it. */
.arrange-column-empty {
    display: none;
    position: absolute;
    left: 0;
    right: 0;
    bottom: 14px;
    text-align: center;
    font-size: 11.5px;
    color: var(--ink-faint);
}

.arrange-column .arrange-sub:empty + .arrange-column-empty { display: block; }

/* Inside a column the entries are the list itself: the indent and the rule
   that mark a submenu belong to the single-column case, not to this one. */
.arrange-column .arrange-sub {
    margin: 0;
    padding: 0;
    border-left: 0;
    min-height: 42px;
}

/* One column is the plain case, so it keeps the indented look it had. */
.arrange-columns[data-count="1"] .arrange-column {
    border: 0;
    background: none;
    padding: 0;
    min-height: 0;
}

.arrange-columns[data-count="1"] .arrange-column-head { display: none; }

.arrange-columns[data-count="1"] .arrange-sub {
    padding-left: 14px;
    border-left: 2px solid var(--hairline-soft);
}

@media (max-width: 900px) {
    .arrange-columns[data-count="2"],
    .arrange-columns[data-count="3"] { grid-template-columns: 1fr; }
    .arrange-split, .arrange-columns { margin-left: 12px; }
}

/* --- Footer manager -------------------------------------------------------
   The footer laid out as the site lays it out, so the screen reads like the
   thing it edits. Columns wrap rather than scroll: six narrow columns on one
   line would leave no room for the URL under each label.
   --------------------------------------------------------------------------- */

/* Cards stretch to the tallest in their row (the grid default — do not put
   align-items:start back). Every card is a flex column whose link list takes
   the slack, so the Add link / Edit column row sits on the bottom edge of each
   one and the whole row of cards lines up top and bottom. */
.foot-board {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
    gap: 16px;
}

/* The global .card + .card spacing is for stacked cards; in this grid it
   pushed every card after the first down inside its cell, so the row's tops
   never lined up. The grid gap is the spacing here. */
.foot-board > .card + .card { margin-top: 0; }

.foot-col { display: flex; flex-direction: column; padding: 18px 20px 16px; }

/* Hidden is stated by the pill; the fade keeps it readable while making the
   column recede next to the live ones. */
.foot-col.is-hidden { opacity: 0.62; }

.foot-col-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--hairline-soft);
}

.foot-col-title { display: flex; align-items: flex-start; gap: 10px; min-width: 0; }

.foot-col-pos {
    flex: none;
    width: 22px;
    height: 22px;
    margin-top: 1px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--accent-wash);
    color: var(--accent);
    font-size: 11px;
    font-weight: 700;
}

.foot-col-head h2 { margin: 0; font-size: 14.5px; font-weight: 700; }
.foot-col-slug { font-size: 11px; color: var(--ink-faint); overflow-wrap: anywhere; }

.foot-col-body {
    margin: 12px 0 0;
    font-size: 12.5px;
    line-height: 1.65;
    color: var(--ink-soft);
}

.foot-links { list-style: none; margin: 10px 0 0; padding: 0; flex: 1; }

.foot-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 7px 0;
    border-bottom: 1px solid var(--hairline-soft);
}

.foot-link:last-child { border-bottom: none; }
.foot-link.is-hidden .foot-link-body { opacity: 0.55; }

.foot-link-body { min-width: 0; display: grid; gap: 2px; }
.foot-link-body strong { font-size: 13px; font-weight: 600; }
.foot-link-body code { font-size: 11px; color: var(--ink-faint); overflow-wrap: anywhere; }

/* Held at a fixed width so the labels beside them line up down the column
   whether or not a row carries a Hidden pill. */
.foot-link-actions { flex: none; display: inline-flex; align-items: center; gap: 2px; }
.foot-link-actions form { display: inline-flex; }
.foot-link-actions .pill { margin-right: 4px; }

.foot-links-empty {
    padding: 12px 0;
    font-size: 12.5px;
    color: var(--ink-faint);
}

.foot-col-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 14px;
    padding-top: 13px;
    border-top: 1px solid var(--hairline-soft);
}

.foot-col-foot form { display: inline-flex; }

.foot-empty { grid-column: 1/-1; padding: 40px 24px; text-align: center; }
.foot-empty strong { display: block; font-size: 15px; margin-bottom: 6px; }
.foot-empty p { margin: 0; font-size: 13px; color: var(--ink-soft); }

/* --- Report enquiries --------------------------------------------------------
   The studies a pre-purchase question names, listed on the enquiry's page. */
.enq-report-list {
    margin: 0;
    padding-left: 20px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.enq-report-list li { font-weight: 600; }

/* The one thing a report request is about, said large. */
.enq-subject { margin: 0 0 14px; font-size: 16px; font-weight: 650; letter-spacing: -0.01em; line-height: 1.4; }

/* --- Home banner -------------------------------------------------------------
   The screen that edits the site's hero: chips as a numbered list with move
   and remove on each row, and the three counters side by side, each with its
   icon picked from a fixed row of tiles. */

.banner-add-row {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    margin-bottom: 14px;
}

.banner-add-pick { flex: 1 1 auto; margin: 0; }
/* What a picked chip would find on the site: a count pill and one line. */
.topic-preview { display: flex; align-items: center; gap: 10px; margin-top: 8px; padding: 8px 12px; border-radius: 8px; background: #eff6ff; border: 1px solid #bfdbfe; font-size: 13px; color: #1e3a8a; }
.topic-preview-count { flex: none; min-width: 30px; height: 30px; padding: 0 9px; border-radius: 999px; display: grid; place-items: center; background: #2563eb; color: #fff; font-weight: 700; font-size: 13px; }
.topic-preview-text { display: flex; flex-direction: column; gap: 1px; line-height: 1.35; }
.topic-preview-text b { color: #172554; }
.topic-preview.is-empty { background: #fff7ed; border-color: #fed7aa; color: #7c2d12; }
.topic-preview.is-empty .topic-preview-count { background: #ea580c; }
.topic-preview.is-empty .topic-preview-text b { color: #431407; }
/* Customer search chips: the switch and count side by side, the table beneath. */
.cust-chips-form { align-items: center; margin-bottom: 18px; }
.cust-chips-switch { flex: 1 1 auto; margin: 0; }
.cust-chips-limit .hint { display: none; }
.cust-chips-limit { flex: 0 0 200px; margin: 0; }
.cust-chips-table { margin-top: 4px; }
/* The count pill beside each chip on the banner list. */
.banner-chip-arrange .arrange-name { display: flex; flex-direction: row; align-items: center; justify-content: flex-start; gap: 10px; flex-wrap: wrap; text-align: left; flex: 1 1 auto; min-width: 0; }
.chip-count { display: inline-flex; align-items: center; height: 22px; padding: 0 9px; border-radius: 999px; font-size: 12px; font-weight: 600; white-space: nowrap; }
.chip-count-some { background: #dcfce7; color: #166534; }
.chip-count-zero { background: #ffedd5; color: #9a3412; }
.chip-count-none { background: #f1f5f9; color: #64748b; font-weight: 500; }
.banner-add-btn { flex: none; }

.banner-chip-list {
    list-style: none;
    margin: 16px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.banner-chip-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--r-sm);
}

.banner-chip-pos {
    flex: none;
    width: 22px;
    height: 22px;
    display: grid;
    place-items: center;
    font-size: 11px;
    font-weight: 600;
    color: var(--ink-soft);
    background: var(--surface-sunken);
    border: 1px solid var(--hairline-soft);
    border-radius: 50%;
}

.banner-chip-label { flex: 1 1 auto; font-weight: 600; }

.banner-chip-actions { flex: none; display: flex; gap: 4px; }
.banner-chip-actions .icon-btn:disabled { opacity: 0.32; cursor: default; }

.banner-stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 16px;
}

.banner-stat {
    border: 1px solid var(--hairline-soft);
    border-radius: var(--r-md);
    background: var(--surface-sunken);
    padding: 14px;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.banner-icon-row { display: flex; gap: 6px; flex-wrap: wrap; }

.banner-icon-choice { position: relative; cursor: pointer; }
.banner-icon-choice input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.banner-icon-tile {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    border: 1px solid var(--hairline);
    border-radius: var(--r-sm);
    background: var(--surface);
    color: var(--ink-soft);
}

.banner-icon-tile svg { width: 20px; height: 20px; }

.banner-icon-choice:hover .banner-icon-tile { border-color: var(--accent); color: var(--ink); }

.banner-icon-choice input:checked + .banner-icon-tile {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--accent-wash);
    box-shadow: 0 0 0 1px var(--accent);
}

.banner-icon-choice input:focus-visible + .banner-icon-tile {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

@media (max-width: 640px) {
    .banner-add-row { flex-direction: column; align-items: stretch; }
}

/* The banner's chip list borrows the arrange styles wholesale; this is only
   what differs — the remove form sits among the move buttons, and the save
   row closes the card. */
.banner-chip-arrange .arrange-moves form { display: contents; }

.banner-order-foot {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 12px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--hairline-soft);
}

/* ---------------------------------------------------------------- Offers */
/* The pop-up poster module: the form's radio rows and upload previews,
   the table's thumbnail, and the show page's poster proofs. */

.check-row { display: flex; flex-wrap: wrap; gap: 6px 22px; }

.offer-thumb {
    display: block;
    width: 84px;
    height: 52px;
    object-fit: cover;
    border-radius: 6px;
    border: 1px solid var(--hairline);
    background: var(--surface-sunken);
}

.offer-excerpt { color: var(--ink-soft); font-size: 12.5px; }

.offer-schedule span { display: block; white-space: nowrap; }

.upload-preview {
    display: block;
    margin-top: 8px;
    max-width: 300px;
    border: 1px solid var(--hairline);
    border-radius: 8px;
    overflow: hidden;
    background: var(--surface-sunken);
}

.upload-preview-tall { max-width: 180px; }

.upload-preview img { display: block; width: 100%; }

.poster-grid { display: flex; flex-wrap: wrap; gap: 20px; align-items: flex-start; }

.poster-preview {
    margin: 0;
    max-width: 560px;
    border: 1px solid var(--hairline);
    border-radius: 10px;
    overflow: hidden;
    background: var(--surface-sunken);
}

.poster-preview-mobile { max-width: 240px; }

.poster-preview img { display: block; width: 100%; }

.poster-preview figcaption {
    padding: 8px 12px;
    font-size: 12px;
    color: var(--ink-faint);
    border-top: 1px solid var(--hairline-soft);
}

.offer-content-preview {
    border: 1px solid var(--hairline);
    border-radius: 10px;
    padding: 20px 24px;
    background: var(--surface);
}

/* The editor: room to work in, and the panel's own font. */
.ck-editor__editable_inline { min-height: 280px; }
.ck.ck-editor { width: 100%; }

/* The offer form's page picker and stacked radio rows. */
.check-col { display: flex; flex-direction: column; gap: 8px; }

.page-pick {
    display: flex;
    flex-wrap: wrap;
    gap: 16px 32px;
    padding: 14px 16px;
    border: 1px solid var(--hairline);
    border-radius: 10px;
    background: var(--surface-sunken);
}

.page-pick-group { display: flex; flex-direction: column; gap: 6px; min-width: 200px; }

.page-pick-heading {
    margin: 0 0 2px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

/* "optional" beside a field label, quieter than the label itself. */
.label-optional { font-style: normal; font-weight: 400; font-size: 11px; color: var(--ink-faint); margin-left: 4px; }

/* ------------------------------------------------------------- Dashboard */
/* The overview grid: charts in cards, small lists, coverage meters. */

.stat-grid-6 { grid-template-columns: repeat(6, 1fr); }
@media (max-width: 1400px) { .stat-grid-6 { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 760px) { .stat-grid-6 { grid-template-columns: repeat(2, 1fr); } }

.stat-link { text-decoration: none; color: inherit; display: block; transition: border-color .15s, box-shadow .15s; }
.stat-link:hover { border-color: var(--accent); box-shadow: 0 2px 10px rgba(16, 20, 32, .06); }

.dash-grid {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 18px;
    align-items: stretch;
}
.dash-grid .card { margin: 0; display: flex; flex-direction: column; }
.dash-span-4 { grid-column: span 4; }
.dash-span-6 { grid-column: span 6; }
.dash-span-8 { grid-column: span 8; }
/* Chosen by the page when a card would otherwise sit alone in its row —
   an employee sees only the panels their user type opens. */
.dash-span-12 { grid-column: span 12; }
@media (max-width: 1200px) {
    .dash-span-4 { grid-column: span 6; }
    .dash-span-8 { grid-column: span 12; }
}
@media (max-width: 860px) {
    .dash-span-4, .dash-span-6 { grid-column: span 12; }
}

/* A chart fills whatever card height the row settles on. */
.dash-chart { position: relative; flex: 1; min-height: 240px; }
.dash-chart-tall { min-height: 300px; }
.dash-chart canvas { position: absolute; inset: 16px 18px; width: calc(100% - 36px) !important; height: calc(100% - 32px) !important; }

/* One row in a dashboard list: a name and its note, a mark on the right. */
.dash-row {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 9px 0; border-bottom: 1px solid var(--hairline-soft);
}
.dash-row:last-child { border-bottom: none; }
.dash-row-main { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.dash-row-main a { text-decoration: none; color: inherit; }
.dash-row-main a:hover { color: var(--accent); }
.dash-row-note { font-size: 11.5px; color: var(--ink-faint); }
.dash-row-when { font-size: 11.5px; color: var(--ink-faint); white-space: nowrap; }
.dash-empty { margin: 4px 0; font-size: 13px; color: var(--ink-faint); }

/* Coverage meters: label, count, and a quiet bar underneath. */
.dash-meter { display: block; padding: 8px 0; text-decoration: none; color: inherit; }
.dash-meter-head { display: flex; justify-content: space-between; font-size: 12.5px; margin-bottom: 6px; }
.dash-meter:hover .dash-meter-head span:first-child { color: var(--accent); }
.dash-meter-count { color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.dash-meter-track { display: block; height: 6px; border-radius: 3px; background: var(--hairline-soft); overflow: hidden; }
.dash-meter-fill { display: block; height: 100%; border-radius: 3px; background: var(--accent); transition: width .4s ease; }

/* --- Employees & roles -------------------------------------------------------
   The team module: the employee list with its Active / Inactive / Deleted
   tabs, and the permission grid a user type is drawn as.
   ---------------------------------------------------------------------------- */

.emp-cell { display: flex; align-items: center; gap: 10px; }
.emp-cell > span:last-child { display: flex; flex-direction: column; min-width: 0; }

.avatar-sm {
    width: 30px;
    height: 30px;
    font-size: 11px;
    flex: none;
}

.emp-search { flex: none; min-width: 260px; }

/* The permission grid: modules down, the four operations across. */
.perm-wrap { margin-top: 20px; }

.perm-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
    margin-bottom: 10px;
}

.perm-head h3 { margin: 0 0 3px; font-size: 14px; font-weight: 650; }
.perm-head p { margin: 0; font-size: 12.5px; color: var(--ink-faint); max-width: 56ch; }

.perm-master { flex: none; font-weight: 600; }

.perm-grid th.perm-col,
.perm-grid td.perm-col {
    width: 84px;
    text-align: center;
}

.perm-grid td:first-child strong { display: block; font-weight: 600; }

.perm-note { display: block; font-size: 11.5px; color: var(--ink-faint); margin-top: 1px; }

.perm-col-head {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    font-weight: 600;
}

.perm-none { color: var(--ink-faint); opacity: 0.55; }

/* Root owner rows carry no actions at all — this says so where the icons
   would have been, rather than leaving the column looking broken. */
.row-actions-none {
    display: inline-block;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ink-faint);
    background: var(--hairline-soft);
    border-radius: 999px;
    padding: 3px 10px;
    cursor: default;
}

/* Switching a suspended account back on is the one encouraging action in a
   row of neutral ones, so it carries the accent rather than sitting grey. */
.icon-btn-on { color: var(--accent); }
.icon-btn-on:hover { color: var(--accent); background: var(--accent-wash); border-color: transparent; }

/* A permission grid read back, on the employee's own page. */
.perm-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 10px;
}

.perm-item {
    padding: 11px 13px;
    border: 1px solid var(--hairline);
    border-radius: var(--r-md);
    background: var(--surface-sunken);
}

.perm-item strong { display: block; font-size: 13px; font-weight: 650; }

.perm-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; }

.perm-chip {
    font-size: 10.5px;
    font-weight: 650;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--accent-wash);
    color: var(--accent);
}

/* A stat whose value is words or a date rather than a number. */
.stat-value-sm { font-size: 19px; line-height: 1.3; }

/* -------------------------------------------------------------- Reports */
/* The range picker: quiet segmented buttons, radio inputs underneath. */

.report-ranges { display: inline-flex; gap: 0; border: 1px solid var(--hairline); border-radius: 8px; overflow: hidden; }
.report-range { display: block; cursor: pointer; }
.report-range input { position: absolute; opacity: 0; pointer-events: none; }
.report-range span {
    display: block; padding: 8px 16px; font-size: 12.5px; font-weight: 500;
    color: var(--ink-soft); border-right: 1px solid var(--hairline-soft); transition: background .15s, color .15s;
}
.report-range:last-child span { border-right: none; }
.report-range:hover span { color: var(--ink); }
.report-range.is-picked span, .report-range input:checked + span { background: var(--accent); color: #fff; }

.report-custom { display: flex; gap: 14px; margin-top: 14px; max-width: 420px; }
.report-custom .field { flex: 1; }

.report-downloads { display: flex; gap: 6px; }

.report-schedule-actions { display: flex; gap: 6px; }
.report-schedule-actions form { margin: 0; }

/* The schedule form's recipient picker: one compact row per registered
   user — photo, name, email, type — ticked by clicking anywhere on it. */
.recipient-picker { display: grid; gap: 14px; }
.recipient-summary { margin: 0; }
.recipient-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 6px;
}
.recipient-card {
    position: relative; display: flex; align-items: center; gap: 9px; cursor: pointer;
    padding: 6px 30px 6px 8px; border: 1px solid var(--hairline); border-radius: 8px;
    background: var(--surface); transition: border-color .15s, background .15s, box-shadow .15s;
    min-width: 0;
}
.recipient-card:hover { border-color: var(--accent); }
.recipient-card:has(input:focus-visible) { box-shadow: 0 0 0 3px var(--accent-wash); }
.recipient-card:has(input:checked) { border-color: var(--accent); background: var(--accent-wash); }
.recipient-card input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.recipient-avatar { width: 28px; height: 28px; font-size: 10.5px; }
.recipient-card-body { display: flex; flex-direction: column; gap: 0; min-width: 0; flex: 1; line-height: 1.25; }
.recipient-name { font-size: 12.5px; font-weight: 550; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.recipient-email {
    font-size: 11px; color: var(--ink-faint);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.recipient-meta { display: inline-flex; gap: 4px; flex: none; }
.recipient-type {
    padding: 2px 7px; border-radius: 999px;
    font-size: 10px; font-weight: 600; letter-spacing: 0.03em; white-space: nowrap;
    background: var(--hairline-soft); color: var(--ink-soft);
}
.recipient-type-owner { background: var(--accent-wash); color: var(--accent-deep); }
.recipient-type-off { background: transparent; border: 1px dashed var(--hairline); }
.recipient-check {
    position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
    width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid var(--hairline);
    display: grid; place-items: center; color: transparent; background: var(--surface);
    transition: background .15s, border-color .15s, color .15s;
}
.recipient-card:has(input:checked) .recipient-check { background: var(--accent); border-color: var(--accent); color: #fff; }
.recipient-card-off { opacity: .55; }
.recipient-card-off:hover, .recipient-card-off:has(input:checked) { opacity: 1; }

/* Recipient groups: root owners first, then one block per user type. */
.recipient-group { display: grid; gap: 6px; }
.recipient-group-head { margin: 0; display: flex; align-items: center; gap: 8px; min-width: 0; }
.recipient-group-label {
    font-size: 11px; font-weight: 600; letter-spacing: 0.06em;
    text-transform: uppercase; color: var(--ink-soft); flex: none;
}
.recipient-group-count { font-size: 11px; color: var(--ink-faint); flex: none; font-variant-numeric: tabular-nums; }
.recipient-group-note { font-size: 11.5px; color: var(--ink-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.recipient-group-all {
    margin-left: auto; flex: none; background: none; border: 0; padding: 2px 4px; cursor: pointer;
    font: inherit; font-size: 11.5px; font-weight: 550; color: var(--accent);
}
.recipient-group-all:hover { text-decoration: underline; }

/* ------------------------------------------------------------- Guided tour */
/* driver.js's popover, dressed in the panel's own variables so it matches
   the chrome in both themes. The vendor sheet (css/vendor-driver.css) keeps
   the positioning; everything visual is restated here. tour.js adds the
   kicker (step count + progress bar) above the title and a Skip button in
   the footer. */

.driver-popover.tour-popover {
    background: var(--surface);
    color: var(--ink);
    border: 1px solid var(--hairline);
    border-radius: 14px;
    box-shadow:
        0 0 0 1px rgba(16, 20, 32, .04),
        0 24px 60px -16px rgba(16, 20, 32, .45),
        0 8px 20px -10px rgba(16, 20, 32, .25);
    padding: 16px 18px 14px;
    min-width: 280px;
    max-width: 360px;
    font-family: inherit;
    overflow: hidden;
}
:root[data-theme="dark"] .driver-popover.tour-popover {
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, .05),
        0 24px 60px -16px rgba(0, 0, 0, .7),
        0 8px 20px -10px rgba(0, 0, 0, .5);
}

/* A thin accent line along the top, the panel's signature on cards. */
.driver-popover.tour-popover::after {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 3px;
    background: linear-gradient(90deg, var(--accent), var(--accent-deep));
    pointer-events: none;
}

/* The kicker: "Step 2 of 7" on the left, a progress bar filling as you go. */
.tour-kicker {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 2px 34px 10px 0;
}
.tour-kicker-step {
    flex: none;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--accent);
}
.tour-kicker-bar {
    flex: 1;
    height: 4px;
    border-radius: 999px;
    background: var(--hairline-soft);
    overflow: hidden;
}
.tour-kicker-fill {
    display: block;
    height: 100%;
    width: 0;
    border-radius: inherit;
    background: var(--accent);
    transition: width .35s ease;
}

.tour-popover .driver-popover-title {
    font: inherit;
    font-size: 15.5px;
    font-weight: 680;
    letter-spacing: -0.01em;
    color: var(--ink);
    line-height: 1.35;
    padding-right: 28px;
}

.tour-popover .driver-popover-description {
    font: inherit;
    font-size: 13.25px;
    line-height: 1.65;
    color: var(--ink-soft);
    margin-top: 7px;
}
.tour-popover .driver-popover-description strong { color: var(--ink); font-weight: 650; }

/* The welcome and the sign-off sit in the middle of the screen, a little
   larger and a touch more generous. */
.tour-popover.tour-first .driver-popover-title,
.tour-popover.tour-last .driver-popover-title { font-size: 17px; }
.tour-popover.tour-first .driver-popover-description,
.tour-popover.tour-last .driver-popover-description { font-size: 13.75px; }
.tour-popover.tour-first,
.tour-popover.tour-last { max-width: 400px; }

/* driver.js's own "1 of 7" is replaced by the kicker. */
.tour-popover .driver-popover-progress-text { display: none; }

.tour-popover .driver-popover-footer {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--hairline-soft);
    gap: 8px;
}
.tour-popover .driver-popover-navigation-btns { gap: 6px; }

/* The buttons, restyled to the panel's own. */
.tour-popover .driver-popover-navigation-btns button {
    all: unset;
    cursor: pointer;
    padding: 7px 14px;
    border-radius: 8px;
    font-size: 12.75px;
    font-weight: 600;
    font-family: inherit;
    line-height: 1.2;
    border: 1px solid var(--hairline);
    color: var(--ink-soft);
    background: var(--surface);
    text-shadow: none;
    transition: background .15s, color .15s, border-color .15s, transform .1s;
}
.tour-popover .driver-popover-navigation-btns button:hover {
    background: var(--surface-sunken);
    color: var(--ink);
}
.tour-popover .driver-popover-navigation-btns button:active { transform: translateY(1px); }
.tour-popover .driver-popover-navigation-btns button:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--accent-wash);
    border-color: var(--accent);
}

/* Next / Finish carries the accent, exactly like .btn-primary. */
.tour-popover .driver-popover-navigation-btns .driver-popover-next-btn {
    background: linear-gradient(180deg, var(--accent), var(--accent-deep));
    border-color: transparent;
    color: #fff;
    padding-left: 16px;
    padding-right: 16px;
}
.tour-popover .driver-popover-navigation-btns .driver-popover-next-btn:hover {
    background: linear-gradient(180deg, var(--accent-deep), var(--accent-deep));
    border-color: transparent;
    color: #fff;
}

/* Back is quiet on the first step: there is nothing behind it. */
.tour-popover .driver-popover-navigation-btns .driver-popover-btn-disabled { display: none; }

/* Skip, at the left of the footer: a plain link, not a button. */
.tour-skip {
    all: unset;
    cursor: pointer;
    margin-right: auto;
    font-family: inherit;
    font-size: 12px;
    font-weight: 550;
    color: var(--ink-faint);
    padding: 6px 2px;
    border-radius: 6px;
}
.tour-skip:hover { color: var(--ink); text-decoration: underline; }
.tour-skip:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-wash); color: var(--accent); }
.tour-skip[hidden] { display: none; }

.tour-popover .driver-popover-close-btn {
    top: 10px;
    right: 10px;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    font-size: 20px;
    line-height: 28px;
    color: var(--ink-faint);
    transition: background .15s, color .15s;
}
.tour-popover .driver-popover-close-btn:hover,
.tour-popover .driver-popover-close-btn:focus-visible {
    color: var(--ink);
    background: var(--surface-sunken);
    outline: none;
}

/* The little arrow matches the popover's surface in either theme. */
.tour-popover .driver-popover-arrow-side-left { border-left-color: var(--surface); }
.tour-popover .driver-popover-arrow-side-right { border-right-color: var(--surface); }
.tour-popover .driver-popover-arrow-side-top { border-top-color: var(--surface); }
.tour-popover .driver-popover-arrow-side-bottom { border-bottom-color: var(--surface); }

/* The spotlight: a soft ring round the thing being described. */
.driver-active .driver-active-element {
    box-shadow: 0 0 0 2px var(--accent), 0 0 0 7px var(--accent-wash) !important;
    border-radius: 12px;
    transition: box-shadow .2s ease;
}
/* Cards and tables already have their own radius; rows and fields take a
   tighter one so the ring hugs them. */
.driver-active tr.driver-active-element,
.driver-active td.driver-active-element,
.driver-active input.driver-active-element,
.driver-active select.driver-active-element,
.driver-active textarea.driver-active-element { border-radius: 8px; }
/* Nothing underneath the page should pulse while the tour is running. */
html.tour-running { scroll-behavior: auto; }

@media (prefers-reduced-motion: reduce) {
    .tour-kicker-fill,
    .driver-active .driver-active-element,
    .tour-popover .driver-popover-navigation-btns button { transition: none; }
}

/* --- The tour on a phone: a bottom sheet ---------------------------------
   driver.js places the popover beside the element with inline left/top
   values and an arrow; on a small screen that lands it half off the edge,
   over the thing it describes, or too narrow to read. Below 860px tour.js
   adds .tour-sheet, and the popover becomes a sheet pinned along the foot of
   the screen — full width, no arrow, big buttons — while tour.js scrolls the
   spotlighted element into the space above it. The !important overrides are
   what beat driver.js's inline positioning. */
@media (max-width: 860px) {
    .driver-popover.tour-sheet {
        position: fixed;
        left: 0 !important;
        right: 0 !important;
        bottom: 0 !important;
        top: auto !important;
        transform: none !important;
        width: 100vw;
        min-width: 0;
        max-width: none;
        max-height: min(62vh, 440px);
        overflow-y: auto;
        padding: 12px 18px calc(16px + env(safe-area-inset-bottom));
        border-radius: 20px 20px 0 0;
        border-left: 0;
        border-right: 0;
        border-bottom: 0;
        box-shadow: 0 -18px 50px -12px rgba(16, 20, 32, .45);
    }
    .driver-popover.tour-sheet::after { display: none; }

    /* The grab-handle look a sheet is known by. */
    .driver-popover.tour-sheet::before {
        content: "";
        display: block;
        width: 40px;
        height: 4px;
        margin: 0 auto 12px;
        border-radius: 2px;
        background: var(--hairline);
    }

    .tour-sheet .driver-popover-arrow { display: none !important; }
    .tour-sheet .tour-kicker { margin-right: 40px; }
    .tour-sheet .driver-popover-title { font-size: 17px; padding-right: 36px; }
    .tour-sheet .driver-popover-description { font-size: 14.25px; line-height: 1.6; margin-top: 8px; }

    .tour-sheet .driver-popover-close-btn {
        top: 10px;
        right: 10px;
        width: 36px;
        height: 36px;
        font-size: 22px;
        line-height: 36px;
    }

    /* Footer: Skip on its own line, the two buttons side by side and full
       width, thumb-sized. */
    .tour-sheet .driver-popover-footer {
        flex-wrap: wrap;
        gap: 10px;
        margin-top: 14px;
    }
    .tour-sheet .tour-skip { width: 100%; margin: 0; text-align: center; font-size: 13px; padding: 4px; }
    .tour-sheet .driver-popover-navigation-btns { width: 100%; gap: 10px; }
    .tour-sheet .driver-popover-navigation-btns button {
        flex: 1;
        min-height: 44px;
        padding: 10px 14px;
        border-radius: var(--r-md);
        font-size: 14.5px;
        text-align: center;
        margin-left: 0 !important;
    }
}

/* The Tour button in the topbar: quiet until wanted, like the theme toggle.
   A small dot sits on it until the tour for this screen has been taken once. */
.btn-tour { position: relative; gap: 6px; }
.btn-tour svg { width: 15px; height: 15px; }
.btn-tour-dot {
    position: absolute;
    top: -3px;
    right: -3px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--accent);
    border: 2px solid var(--surface);
    box-shadow: 0 0 0 0 var(--accent-wash);
    display: none;
}
.btn-tour.is-unseen .btn-tour-dot { display: block; animation: tour-dot-pulse 2.4s ease-out infinite; }
.btn-tour.is-unseen { color: var(--accent); border-color: var(--accent-wash); }
@keyframes tour-dot-pulse {
    0% { box-shadow: 0 0 0 0 rgba(31, 111, 208, .45); }
    70% { box-shadow: 0 0 0 8px rgba(31, 111, 208, 0); }
    100% { box-shadow: 0 0 0 0 rgba(31, 111, 208, 0); }
}
@media (prefers-reduced-motion: reduce) {
    .btn-tour.is-unseen .btn-tour-dot { animation: none; }
}
@media (max-width: 700px) {
    .btn-tour-label { display: none; }
    .btn-tour { padding-left: 9px; padding-right: 9px; }
}

/* The inline "add a level" row at the foot of each designation card. */
.level-add { display: flex; gap: 10px; align-items: center; }
.level-add input[name="name"] { max-width: 200px; }
.level-add input[name="description"] { flex: 1; }

/* --- Digital products --------------------------------------------------------
   The catalogue list and its product pages: the little cover thumbnail in the
   table, the filter row in the card head, and the full cover on the show page.
   ---------------------------------------------------------------------------- */

.table-products { min-width: 940px; }

.dp-cell { display: flex; align-items: center; gap: 12px; }
.dp-cell > span:last-child { display: flex; flex-direction: column; min-width: 0; gap: 1px; }

/* The cover, card-shaped: the site draws these figures wider than tall. */
.dp-thumb {
    flex: none;
    width: 56px;
    height: 38px;
    display: grid;
    place-items: center;
    border-radius: 6px;
    border: 1px solid var(--hairline);
    background: var(--surface-sunken);
    color: var(--ink-faint);
    overflow: hidden;
}

.dp-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dp-thumb svg { width: 18px; height: 18px; }

.dp-filters {
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

/* Sized to their words, not to the card — three controls share the row. */
.dp-filters .select { width: auto; min-width: 150px; }

.dp-filters .dt-search { min-width: 210px; }

.dp-cover {
    display: block;
    border-radius: var(--r-md);
    border: 1px solid var(--hairline);
    overflow: hidden;
    background: var(--surface-sunken);
}

.dp-cover img { display: block; width: 100%; height: auto; }

/* --- The table of contents, in the report brochure's design ---------------
   Numbered blue chapter headings with an italic "(PAGE NO. …)" note, and
   sub-sections stepped in by how deep their numbering runs (1.1 → 5.2.1.1).
   The form's paste handler (product-form.js) produces this markup; the same
   classes style it inside the editor and on the show page, so what the
   admin pastes from the PDF looks the same everywhere. */

.toc-sec {
    display: flex;
    align-items: baseline;
    gap: 12px;
    margin: 22px 0 10px;
    color: var(--accent-deep);
    font-size: 14px;
    font-weight: 700;
    line-height: 1.45;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.toc-sec:first-child { margin-top: 0; }

.toc-sec .toc-num { flex: 0 0 auto; min-width: 20px; }

.toc-page {
    color: var(--ink-faint);
    font-size: 11.5px;
    font-style: italic;
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    white-space: nowrap;
}

.toc-item {
    display: flex;
    align-items: baseline;
    gap: 12px;
    margin: 0 0 7px;
    color: var(--ink-soft);
    font-size: 13px;
    line-height: 1.5;
}

.toc-item .toc-num { flex: 0 0 auto; min-width: 30px; color: var(--ink); }

/* Each extra numbering level steps in, and leaves room for a longer trail. */
.toc-d3 { padding-left: 26px; }
.toc-d4 { padding-left: 56px; }
.toc-d5 { padding-left: 90px; }
.toc-d6 { padding-left: 128px; }
.toc-d3 .toc-num { min-width: 44px; }
.toc-d4 .toc-num { min-width: 58px; }
.toc-d5 .toc-num { min-width: 74px; }
.toc-d6 .toc-num { min-width: 96px; }

/* The show page: the PDF's own layout — a big light title over two brochure
   columns, entries kept whole rather than split across the fold. */
.toc-render { columns: 2; column-gap: 52px; }

.toc-render-title {
    column-span: all;
    margin-bottom: 20px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--hairline);
    color: var(--accent);
    font-size: 26px;
    font-weight: 300;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.toc-render .toc-sec { break-inside: avoid; break-after: avoid; }
.toc-render .toc-item { break-inside: avoid; }

@media (max-width: 900px) {
    .toc-render { columns: 1; }
}

/* --- Searchable selects (js/select-search.js) ----------------------------
   A <select data-searchable> in a form, dressed as the picker: the summary
   sits in the form grid like an input, the native select stays for the
   submit but is kept out of sight and out of the tab order. */

.select-searchable-native {
    position: absolute !important;
    width: 1px; height: 1px;
    opacity: 0;
    pointer-events: none;
}

.picker-form > summary {
    display: flex;
    justify-content: space-between;
    width: 100%;
    min-height: 40px;
    padding: 8px 12px 8px 13px;
    font-weight: 500;
}

.picker-form .picker-current { font-weight: 500; }
.picker-form .picker-current.is-placeholder { color: var(--ink-faint); }
.picker-form .picker-panel { left: 0; right: 0; min-width: 0; }
.picker-form .picker-item {
    width: 100%;
    border: 0;
    background: transparent;
    text-align: left;
    cursor: pointer;
    font: inherit;
    font-size: 13px;
}
.picker-form .picker-item.is-active { background: var(--accent-wash); color: var(--accent-deep); }
.field:has(.picker-form[open]) { position: relative; z-index: 5; }

/* A card hides its overflow so its corners stay rounded — which also cuts
   off a picker opened near its foot, halfway down the list. While one is
   open the card lets it through and lifts itself over whatever follows;
   closed, the card is exactly as it was. */
.card:has(.picker-form[open]),
.card:has(.picker-form[open]) .card-body,
.card:has(.picker-form[open]) form {
    overflow: visible;
}

.card:has(.picker-form[open]) { position: relative; z-index: 6; }

/* --- Customer emails, per form (Settings → contact recipients) ------------ */

.ce-table { min-width: 900px; }
.ce-col-on { width: 130px; }
.ce-col-subject { width: 26%; }
.ce-col-message { width: 32%; }
.ce-table td { vertical-align: top; }
.ce-table .input { width: 100%; min-width: 0; }
.ce-table textarea.input { resize: vertical; min-height: 72px; font-size: 13px; }

.ce-switch { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-weight: 600; }
.ce-switch-text { font-size: 12.5px; color: var(--ink-faint); }
tr.is-on .ce-switch-text { color: var(--good); }
tr.is-off td:not(.ce-col-on) { opacity: 0.72; }
tr.is-off td:not(.ce-col-on):focus-within { opacity: 1; }
.ce-actions { display: inline-flex; align-items: center; gap: 6px; flex-wrap: nowrap; }
.ce-test { color: var(--accent); }
.ce-test:hover { background: var(--accent-wash); color: var(--accent-deep); }

/* --- The section manager on the product edit page ------------------------- */

.ps-col-order { width: 84px; }

.ps-arrows { display: inline-flex; gap: 4px; }

.ps-arrows form { margin: 0; }

.ps-arrow { padding: 2px 9px; line-height: 1.4; }

.ps-arrow[disabled] { opacity: 0.35; cursor: default; }

/* --- Section previews on the product show page ---------------------------- */

.ps-preview { padding: 18px 0; border-top: 1px solid var(--hairline-soft); }

.ps-preview:first-child { padding-top: 0; border-top: 0; }

.ps-preview-hidden { opacity: 0.55; }

.ps-preview-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
}

.ps-preview-head h3 {
    margin: 0;
    color: var(--accent-deep);
    font-size: 16px;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.ps-preview-head span { color: var(--ink-faint); font-size: 12.5px; white-space: nowrap; }

.ps-preview-image { display: block; max-width: 640px; margin-bottom: 12px; }

/* Rich section content pasted from documents: honest defaults for the bits
   the editor can produce, so a table or list reads like one. */
.toc-render table { width: 100%; margin: 10px 0 16px; border-collapse: collapse; font-size: 13px; }
.toc-render th, .toc-render td { padding: 7px 10px; border: 1px solid var(--hairline); text-align: left; }
.toc-render th { background: var(--surface-sunken); }
.toc-render img { max-width: 100%; height: auto; }
.toc-render ul, .toc-render ol { margin: 8px 0 14px; padding-left: 24px; }

/* ==========================================================================
   Master images
   The picture wall on the index, and the crop editor. The dotted frame is
   the slot's display shape; what it encloses is what the site shows.
   ========================================================================== */
.mi-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:16px}
.mi-slot{border:1px solid var(--line,#e2e5ea);border-radius:10px;overflow:hidden;background:#fff}
.mi-thumb{display:block;background:#f4f5f8;overflow:hidden;position:relative}
.mi-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.mi-thumb-none{
  position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:8px;font-size:12px;color:#8a93a6;border:2px dashed #d5dae3;border-radius:8px;margin:10px
}
.mi-thumb-none svg{width:30px;height:30px}
.mi-slot-body{padding:12px 14px 14px}
.mi-slot-body h3{margin:0 0 4px;font-size:13.5px;line-height:1.4}
.mi-meta{margin:0 0 10px;font-size:12px;color:#7b8797}
.mi-slot-actions{display:flex;gap:8px;align-items:center}
.mi-slot-actions form{margin:0}

.mi-editor{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:18px;align-items:start}
.mi-side{display:grid;gap:14px}
.mi-actions{display:flex;gap:10px}
.mi-current{max-width:100%;border-radius:8px;border:1px solid var(--line,#e2e5ea);margin-top:8px}

.mi-stage{position:relative;display:inline-block;max-width:100%;user-select:none;touch-action:none}
.mi-stage canvas{display:block;border-radius:6px}
.mi-stage-empty{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;
  min-height:280px;border:2px dashed #d5dae3;border-radius:10px;color:#8a93a6;
  font-size:13.5px;text-align:center
}
.mi-stage-empty svg{width:40px;height:40px}
.mi-stage-empty small{color:#a2aab8}

/* The crop frame — dotted, as the guide the user sizes against. The huge
   box-shadow dims everything outside it. */
.mi-crop{
  position:absolute;border:2px dashed #fff;outline:1px dashed rgba(0,0,0,.55);
  box-shadow:0 0 0 4000px rgba(13,27,46,.45);cursor:move;border-radius:2px
}
.mi-crop-size{
  position:absolute;left:6px;top:6px;background:rgba(13,27,46,.78);color:#fff;
  font-size:11px;padding:2px 7px;border-radius:4px;pointer-events:none;white-space:nowrap
}
.mi-crop-handle{
  position:absolute;right:-9px;bottom:-9px;width:18px;height:18px;border-radius:50%;
  background:#fff;border:2px solid #1f6fd0;cursor:nwse-resize;touch-action:none
}
.mi-tools{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:14px}
/* Until a picture is loaded the stage and its tools are hidden — the display
   rules above must not win over the attribute. */
.mi-stage[hidden],.mi-tools[hidden]{display:none}
.mi-tool-check{display:inline-flex;align-items:center;gap:7px;font-size:13px;cursor:pointer}
.mi-tool-note{font-size:12px;color:#8a93a6}

@media (max-width:980px){
  .mi-editor{grid-template-columns:minmax(0,1fr)}
}

/* Which notification column belongs to which form on the public site. */
.cr-legend{display:flex;flex-wrap:wrap;gap:8px;list-style:none;margin:0 0 4px;padding:0}
.cr-legend li{
  display:inline-flex;align-items:center;padding:5px 7px 5px 12px;border:1px solid var(--hairline);
  border-radius:999px;background:var(--surface-sunken);font-size:12px;font-weight:650;color:var(--ink)
}
.cr-legend .help-tip{margin-left:7px}

/* =========================================================================
   Tasks
   Work handed from one person to another: the list, the task screen with
   its conversation, the progress controls, the people on it.
   ========================================================================= */

.task-stat-danger { color: var(--danger); }

.stat-link { display: block; text-decoration: none; color: inherit; transition: border-color 0.12s ease, box-shadow 0.12s ease; }
.stat-link:hover { border-color: var(--accent); box-shadow: var(--lift-2); }
.stat-link.is-active { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-wash); }

/* The filters on the list: two dropdowns and the search, one row. */
/* The filter toolbar: labelled dropdowns on the left, search on the right,
   wrapping into two rows only when the screen is narrow. */
.task-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 10px 16px;
    padding: 12px 20px;
    border-bottom: 1px solid var(--hairline-soft);
    background: var(--desk-tint);
}
.task-toolbar-left, .task-toolbar-right { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.task-toolbar-field { display: flex; flex-direction: column; gap: 4px; margin: 0; }
.task-toolbar-field > span { font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-faint); }
.task-toolbar .select { width: auto; min-width: 140px; padding: 7px 30px 7px 11px; font-size: 13px; border-radius: 999px; }
.task-toolbar .dt-search .input { width: 260px; padding-top: 7px; padding-bottom: 7px; font-size: 13px; }
.task-result-count { font-size: 12px; font-weight: 600; color: var(--ink-faint); white-space: nowrap; }

/* The table. Everything but the title stays on one line, so a row is a row. */
.table-tasks th, .table-tasks td { white-space: nowrap; }
.table-tasks th { padding: 10px 16px; }
.table-tasks td { padding: 13px 16px; }
.table-tasks td:first-child, .table-tasks th:first-child { padding-left: 20px; }
.table-tasks tbody tr { transition: background 0.1s ease; }
.table-tasks tbody tr:hover { background: var(--surface-sunken); }
.table-tasks .pill { white-space: nowrap; }
.task-col-title { white-space: normal !important; min-width: 240px; max-width: 420px; }
.task-title { display: block; font-weight: 600; font-size: 13.5px; color: var(--ink); text-decoration: none; line-height: 1.35; }
.task-title:hover { color: var(--accent); }
.task-sub {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: 5px;
    margin-top: 4px;
    font-size: 12px;
    color: var(--ink-faint);
    min-width: 0;
    overflow: hidden;
}
.task-sub > * { white-space: nowrap; }
.task-sub .menu-url { padding: 1px 5px; font-size: 11px; }
.task-sub-sep { opacity: 0.6; }
.task-sub-desc { overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 1; }
.task-col-progress { width: 160px; }
.task-col-when time { display: block; font-size: 13px; }
.task-col-when .log-sub { margin-top: 2px; }
.task-col-when .pill-sm { display: inline-block; margin-top: 4px; }
.pill-sm { padding: 1px 7px; font-size: 10.5px; }
.task-row-overdue td:first-child { box-shadow: inset 3px 0 0 var(--danger); }
.task-overdue { color: var(--danger); font-weight: 600; }
.task-pager { justify-content: center; }
.task-empty { white-space: normal !important; padding: 28px 20px !important; text-align: center; color: var(--ink-soft); }

/* Sortable headings: the active one in ink with its arrow. */
.task-sort {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: inherit;
    text-decoration: none;
    letter-spacing: inherit;
}
.task-sort:hover { color: var(--ink); }
.task-sort.is-active { color: var(--ink); }
.task-sort-arrow { display: inline-block; width: 10px; font-size: 11px; }

/* Who carries it, with the others stacked beside the name. */
.task-people-cell { display: flex; align-items: center; gap: 10px; }
.task-people-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.task-people-text strong { font-weight: 600; font-size: 13px; line-height: 1.2; }
.task-avatars { display: inline-flex; align-items: center; }
.task-avatars .avatar { width: 20px; height: 20px; font-size: 8.5px; border: 1.5px solid var(--surface); margin-left: -6px; }
.task-avatars .avatar:first-child { margin-left: 0; }
.task-avatars-more { background: var(--hairline-soft); color: var(--ink-soft); }

/* The bar's colour says how far along: thin early, amber midway, green done. */
.task-meter[data-band="low"] .task-meter-fill { background: linear-gradient(90deg, var(--accent-deep), var(--accent)); }
.task-meter[data-band="mid"] .task-meter-fill { background: linear-gradient(90deg, #b07a1f, #d99a2b); }
.task-meter[data-band="done"] .task-meter-fill { background: linear-gradient(90deg, #1f7a4d, #2ea56a); }
.task-meter[data-band="done"] .task-meter-num { color: var(--good); }

/* --- The percentage bar ------------------------------------------------- */

.task-meter { display: flex; align-items: center; gap: 10px; }
.task-meter-track {
    display: block;
    flex: 1;
    height: 8px;
    border-radius: 999px;
    background: var(--hairline-soft);
    overflow: hidden;
}
.task-meter-fill {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--accent-deep), var(--accent));
    transition: width 0.4s ease;
}
.task-meter[data-progress="100"] .task-meter-fill { background: linear-gradient(90deg, #1f7a4d, #2ea56a); }
.task-meter-num { font-size: 12.5px; font-weight: 650; font-variant-numeric: tabular-nums; color: var(--ink-soft); min-width: 38px; text-align: right; }
.task-meter-sm .task-meter-track { height: 6px; }

/* --- The task head ---------------------------------------------------- */

.task-head {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 24px;
    padding: 22px 24px;
    margin-bottom: 18px;
}
.task-head-main { min-width: 0; }
.task-head-title h1 { margin: 4px 0 10px; font-size: 22px; letter-spacing: -0.02em; line-height: 1.25; }
.task-ref {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--ink-faint);
}
.task-head-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.task-description {
    margin: 14px 0 0;
    font-size: 14px;
    line-height: 1.65;
    color: var(--ink-soft);
    white-space: pre-line;
    overflow-wrap: anywhere;
    max-width: 70ch;
}
.task-description.is-empty { font-style: italic; color: var(--ink-faint); }
.task-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 28px;
    margin: 16px 0 0;
    padding-top: 14px;
    border-top: 1px solid var(--hairline-soft);
}
.task-facts dt { font-size: 11.5px; font-weight: 600; letter-spacing: 0.02em; color: var(--ink-faint); text-transform: uppercase; }
.task-facts dd { margin: 2px 0 0; font-size: 13.5px; }
.task-facts dd.is-empty { color: var(--ink-faint); }

.task-head-progress {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    min-width: 170px;
    padding-left: 24px;
    border-left: 1px solid var(--hairline-soft);
}
.task-head-progress .task-meter { width: 100%; }

/* The ring: a conic sweep behind a disc, the number in the middle. */
.task-ring {
    --pct: 0;
    position: relative;
    width: 124px;
    height: 124px;
    border-radius: 50%;
    background: conic-gradient(var(--accent) calc(var(--pct) * 1%), var(--hairline-soft) 0);
    display: grid;
    place-items: center;
    transition: background 0.4s ease;
}
.task-ring::before {
    content: "";
    position: absolute;
    inset: 10px;
    border-radius: 50%;
    background: var(--surface);
    box-shadow: inset 0 1px 2px rgba(16, 20, 32, 0.06);
}
.task-ring.is-done { background: conic-gradient(var(--good) 100%, var(--good) 0); }
.task-ring-num, .task-ring-label { position: relative; }
.task-ring-num { font-size: 30px; font-weight: 700; letter-spacing: -0.04em; line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; }
.task-ring-num small { font-size: 14px; font-weight: 600; margin-left: 1px; color: var(--ink-faint); }
.task-ring-label { margin-top: 2px; font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); }
.task-ring.is-done .task-ring-num { color: var(--good); }

/* --- Two columns: the conversation and the controls ------------------- */

.task-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: 18px;
    align-items: start;
}
.task-main, .task-side { min-width: 0; }
.task-side .card { margin-bottom: 18px; }
.task-side .card:last-child { margin-bottom: 0; }
.task-side-actions { display: flex; justify-content: flex-end; margin-top: 12px; }
.task-head-counts { display: flex; gap: 6px; flex-wrap: wrap; }

@media (max-width: 1100px) {
    .task-layout { grid-template-columns: 1fr; }
    .task-head { grid-template-columns: 1fr; }
    .task-head-progress { flex-direction: row; justify-content: space-between; padding-left: 0; border-left: none; padding-top: 16px; border-top: 1px solid var(--hairline-soft); }
    .task-head-progress .task-meter { flex: 1; margin-left: 20px; }
}

/* --- The conversation ------------------------------------------------- */

.task-chat { max-height: 40rem; min-height: 14rem; }
.task-bubble { max-width: min(40rem, 84%); }
.task-author-tag {
    margin-left: 6px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--accent-wash);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}
.task-hidden-note span { background: var(--surface); color: var(--ink-faint); border: 1px dashed var(--hairline); }

/* A move of the bar, as a centred line with the from and to. */
.task-progress-event span { background: var(--accent-wash); color: var(--accent-deep); }
.task-progress-delta { display: inline-flex; align-items: center; gap: 4px; margin: 0 3px; font-variant-numeric: tabular-nums; }
.task-progress-delta svg { width: 12px; height: 12px; }
.task-progress-delta b { font-weight: 700; }
.task-progress-delta b.is-done { color: var(--good); }
.task-progress-event em { font-style: normal; opacity: 0.85; }
:root[data-theme="dark"] .task-progress-event span { color: #9cc4f5; }

/* Pictures posted into the chat. */
.task-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
    gap: 6px;
    margin: 8px 0 4px;
}
.task-gallery-one { grid-template-columns: minmax(0, 260px); }
.task-gallery-item {
    display: block;
    aspect-ratio: 4 / 3;
    border-radius: var(--r-sm);
    overflow: hidden;
    border: 1px solid var(--hairline-soft);
    background: var(--surface-sunken);
}
.task-gallery-one .task-gallery-item { aspect-ratio: auto; max-height: 280px; }
.task-gallery-item img { display: block; width: 100%; height: 100%; object-fit: cover; }
.task-gallery-one .task-gallery-item img { height: auto; max-height: 280px; object-fit: contain; }
.task-gallery-item:hover { border-color: var(--accent); }

/* Documents, as chips you can download. */
.task-files { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 4px; }
.task-file {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    border-radius: var(--r-md);
    border: 1px solid var(--hairline-soft);
    background: var(--surface);
    text-decoration: none;
    color: inherit;
    min-width: 0;
}
.task-file:hover { border-color: var(--accent); }
.task-file svg { width: 16px; height: 16px; color: var(--ink-faint); flex: none; }
.task-file:hover svg { color: var(--accent); }
.task-file-kind {
    flex: none;
    min-width: 40px;
    padding: 4px 6px;
    border-radius: var(--r-sm);
    background: var(--hairline-soft);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-align: center;
    color: var(--ink-soft);
}
.task-file-pdf { background: var(--danger-wash); color: var(--danger); }
.task-file-doc, .task-file-docx { background: var(--accent-wash); color: var(--accent); }
.task-file-xls, .task-file-xlsx, .task-file-csv { background: var(--good-wash); color: var(--good); }
.task-file-ppt, .task-file-pptx { background: var(--warn-wash); color: var(--warn); }
.task-file-text { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.task-file-text strong { font-size: 12.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.task-file-text span { font-size: 11px; color: var(--ink-faint); }

/* The composer: a box, then the attach button, the hint and Send. */
.task-composer .chat-input { min-height: 56px; }
.task-composer-row { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.task-attach { cursor: pointer; gap: 6px; }
.task-attach svg { width: 15px; height: 15px; }
.task-attach-hint { flex: 1; margin: 0; }
.task-composer .chat-send { margin-left: auto; }

.task-pending-files { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.task-pending-files li {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 6px 3px 10px;
    border-radius: 999px;
    background: var(--accent-wash);
    font-size: 12px;
    color: var(--accent-deep);
    max-width: 100%;
}
.task-pending-files li.is-too-big { background: var(--danger-wash); color: var(--danger); }
.task-pending-files li span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 240px; }
.task-pending-files li small { opacity: 0.75; }
.task-pending-files button {
    border: none;
    background: none;
    padding: 0 4px;
    font: inherit;
    font-size: 15px;
    line-height: 1;
    color: inherit;
    cursor: pointer;
    opacity: 0.7;
}
.task-pending-files button:hover { opacity: 1; }
:root[data-theme="dark"] .task-pending-files li { color: #9cc4f5; }

/* --- Progress controls ------------------------------------------------ */

.task-progress-badge {
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
    color: var(--accent);
}
.task-progress-badge.is-done { color: var(--good); }

.task-range-row { display: flex; align-items: center; gap: 12px; }
.task-range {
    --pct: 0;
    flex: 1;
    height: 8px;
    margin: 0;
    appearance: none;
    -webkit-appearance: none;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--accent) calc(var(--pct) * 1%), var(--hairline-soft) 0);
    outline: none;
    cursor: pointer;
}
.task-range::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--surface);
    border: 2px solid var(--accent);
    box-shadow: var(--lift-1);
    cursor: grab;
}
.task-range::-moz-range-thumb {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--surface);
    border: 2px solid var(--accent);
    box-shadow: var(--lift-1);
    cursor: grab;
}
.task-range:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--accent-wash); }
.task-range-num { display: inline-flex; align-items: center; gap: 4px; margin: 0; font-weight: 600; color: var(--ink-soft); }
.task-range-num .input { width: 72px; padding: 7px 8px; text-align: right; font-variant-numeric: tabular-nums; }
.task-range-ticks { display: flex; justify-content: space-between; margin-top: 8px; }
.task-tick {
    border: none;
    background: none;
    padding: 2px 6px;
    border-radius: 999px;
    font: inherit;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ink-faint);
    cursor: pointer;
}
.task-tick:hover { background: var(--accent-wash); color: var(--accent); }

/* --- People ----------------------------------------------------------- */

.task-member-list { list-style: none; margin: 0; padding: 6px 0; }
.task-member { display: flex; align-items: center; gap: 10px; padding: 8px 20px; }
.task-member + .task-member { border-top: 1px solid var(--hairline-soft); }
.task-member.is-assignee { background: var(--accent-wash); }
.task-member-text { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.task-member-text strong { font-size: 13.5px; font-weight: 600; }
.task-member-text span { font-size: 11.5px; color: var(--ink-faint); }
.task-member form { margin-left: auto; }

/* The tick-list of people, with a filter above it. */
.task-people { border: 1px solid var(--hairline); border-radius: var(--r-md); overflow: hidden; background: var(--surface); box-shadow: inset 0 1px 1px rgba(16, 20, 32, 0.04); }
.task-people-bar { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-bottom: 1px solid var(--hairline-soft); background: var(--surface-sunken); }
.task-people-bar .dt-search { flex: 1; }
.task-people-bar .input { background: var(--surface); }
.task-people-count { font-size: 12px; font-weight: 600; color: var(--ink-faint); white-space: nowrap; }
.task-people-count.is-some { color: var(--accent); }
.task-people-list { max-height: 18rem; overflow-y: auto; }
/* Each row is a <label>, and it may sit inside a .field — whose own
   `label` rule would turn it into a small block heading. Scoped selectors
   outrank that and keep the row a row. */
.task-people-list .task-person {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 0;
    padding: 9px 14px;
    font-size: 13.5px;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--ink);
    cursor: pointer;
    transition: background 0.1s ease;
}
.task-people-list .task-person + .task-person { border-top: 1px solid var(--hairline-soft); }
.task-people-list .task-person:hover { background: var(--surface-sunken); }
.task-people-list .task-person:has(input:checked) { background: var(--accent-wash); }
.task-people-list .task-person input {
    width: 16px;
    height: 16px;
    accent-color: var(--accent);
    margin: 0;
    flex: none;
}
.task-person .avatar { flex: none; }
.task-person-text { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 1px; }
.task-person-text strong { font-size: 13.5px; font-weight: 600; line-height: 1.3; }
.task-person-text span { font-size: 12px; color: var(--ink-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.task-person-type {
    flex: none;
    padding: 2px 9px;
    border-radius: 999px;
    background: var(--hairline-soft);
    font-size: 11px;
    font-weight: 600;
    color: var(--ink-soft);
    white-space: nowrap;
}
.task-person:has(input:checked) .task-person-type { background: var(--surface); color: var(--accent); }
.task-people-empty { margin: 0; padding: 18px; text-align: center; font-size: 12.5px; color: var(--ink-faint); }

/* The people already ticked, as chips above the list — so what has been
   chosen is visible without scrolling through everybody. */
.task-people-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--hairline-soft);
    background: var(--surface);
}
.task-people-chips[hidden] { display: none; }
.task-people-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 6px 3px 4px;
    border-radius: 999px;
    background: var(--accent-wash);
    color: var(--accent-deep);
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1;
}
.task-people-chip .avatar { width: 20px; height: 20px; font-size: 9px; }
.task-people-chip button {
    display: inline-grid;
    place-items: center;
    width: 18px;
    height: 18px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    opacity: 0.7;
}
.task-people-chip button:hover { background: rgba(16, 20, 32, 0.08); opacity: 1; }
:root[data-theme="dark"] .task-people-chip { color: #9cc4f5; }
.task-people-clear {
    border: none;
    background: none;
    padding: 0;
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    color: var(--accent);
    cursor: pointer;
    white-space: nowrap;
}
.task-people-clear:hover { text-decoration: underline; }

/* Priority as four pills, one chosen. */
.task-priority-pick { display: flex; flex-wrap: wrap; gap: 6px; padding-top: 4px; }
/* Scoped past `.field label`, which would stack the pills as blocks. */
.task-priority-pick .task-priority-option { position: relative; display: inline-flex; margin: 0; cursor: pointer; }
.task-priority-option input { position: absolute; opacity: 0; width: 0; height: 0; }
.task-priority-option .pill { padding: 6px 14px; font-size: 12.5px; border: 1.5px solid transparent; opacity: 0.6; transition: opacity 0.12s ease, border-color 0.12s ease; }
.task-priority-option input:checked + .pill { opacity: 1; border-color: currentColor; }
.task-priority-option input:focus-visible + .pill { box-shadow: 0 0 0 3px var(--accent-wash); }

.task-check { align-items: flex-start; margin-top: 4px; }
.task-check input { margin-top: 2px; }

/* The deleted banner on the task screen. */
.task-deleted-notice { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }

.task-change-list { list-style: none; margin: 0; padding: 6px 20px 14px; }
.task-change-list li { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; font-size: 13px; border-bottom: 1px solid var(--hairline-soft); }
.task-change-list li:last-child { border-bottom: none; }
.task-change-list .timeline-dot { margin-top: 4px; }
.task-change-list .log-sub { display: block; }

/* "(optional)" beside a field label, used across the forms. */
.hint-inline { font-weight: 500; color: var(--ink-faint); }

/* --- Task documents: the brief and its like, on the task and its edit form. --- */
.task-doc-list { list-style: none; margin: 0; padding: 6px 0; }
.task-doc { display: flex; align-items: center; gap: 8px; padding: 8px 20px; }
.task-doc + .task-doc { border-top: 1px solid var(--hairline-soft); }
.task-doc form { margin: 0; }
.task-doc-open {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    min-width: 0;
    text-decoration: none;
    color: inherit;
}
.task-doc-open:hover strong { color: var(--accent); }
.task-doc-empty { margin: 0; font-size: 13px; color: var(--ink-faint); }

/* The same list inside the create/edit form, each row with a Remove tick. */
.task-doc-list-form { padding: 0; margin: 0 0 10px; border: 1px solid var(--hairline); border-radius: var(--r-md); background: var(--surface); }
.task-doc-list-form .task-doc { padding: 8px 12px; }
.task-doc-list-form .task-doc.is-removing .task-doc-open { opacity: 0.5; text-decoration: line-through; }
/* Scoped past `.field label`, which would stack the tick as a block heading. */
.field .task-doc-remove { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: 12.5px; font-weight: 600; color: var(--danger); cursor: pointer; white-space: nowrap; }
.task-doc-remove input { accent-color: var(--danger); margin: 0; }

/* The "I confirm" box: only shown without the script, which asks in a dialog. */
.task-confirm-check { margin-top: 8px; }
.task-confirm-check[hidden] { display: none; }
.task-confirm-files { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.task-confirm-files li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 12px;
    border: 1px solid var(--hairline-soft);
    border-radius: var(--r-md);
    background: var(--surface-sunken);
    font-size: 13px;
}
.task-confirm-files strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.task-confirm-files span { color: var(--ink-faint); white-space: nowrap; font-size: 12px; }

/* --- An offer of ownership in flight ---------------------------------- */
.notice-offer { background: var(--warn-wash); color: var(--ink); border-color: transparent; }
.task-offer-notice { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.task-offer-text { flex: 1; min-width: 16rem; display: flex; flex-direction: column; gap: 2px; }
.task-offer-text strong { font-size: 13.5px; }
.task-offer-text span { font-size: 12.5px; color: var(--ink-soft); }
.task-offer-text em { display: block; margin-top: 4px; font-style: italic; color: var(--ink); }
.task-offer-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.task-offer-actions form { margin: 0; }
.task-offer-list strong { display: block; font-size: 13.5px; }
.task-offer-list > span { display: block; font-size: 12.5px; color: var(--ink-soft); margin-top: 2px; }
.task-offer-list ul { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.task-offer-list li { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 8px 10px; border-radius: var(--r-md); background: var(--surface); }
.task-offer-list li > a:first-child { flex: 1; min-width: 12rem; font-weight: 600; text-decoration: none; color: var(--ink); }
.task-offer-list li > a:first-child:hover { color: var(--accent); }
.task-offer-list li form { margin: 0; }
.task-facts dd .pill-sm { margin-left: 6px; vertical-align: middle; }

/* --- Profile photo editor (square crop, 400x400 WebP) -------------------- */
.pa-editor{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:18px;align-items:start;margin:6px 0 22px;padding:16px;border:1px solid var(--hairline);border-radius:10px;background:var(--surface)}
.pa-editor[hidden]{display:none}
.pa-side{display:grid;gap:14px}
.pa-side .mi-tools{margin-top:0}
.pa-preview-row{display:flex;align-items:flex-end;gap:12px;margin-top:6px}
.pa-preview{border:1px solid var(--hairline);background:var(--accent-wash);display:block}
.pa-preview-round{border-radius:50%}
.pa-preview#pa-preview-sm{border-radius:50%}
.pa-stage-wrap{min-width:0;display:flex;justify-content:center;align-items:flex-start;background:var(--accent-wash);border-radius:8px;padding:8px}
/* Clip the crop frame's page-sized dimming shadow to the picture. */
.pa-stage{overflow:hidden;border-radius:6px;max-width:100%}
.pa-crop{border-radius:2px}
.pa-range{width:100%;accent-color:var(--accent)}
@media (max-width:760px){.pa-editor{grid-template-columns:1fr}}

/* --- Scheduled report: which records each send covers --------------------- */
.report-window-pick{display:grid;gap:8px;margin-top:4px}
.report-window-opt{display:flex;gap:10px;align-items:flex-start;padding:10px 12px;border:1px solid var(--hairline);border-radius:8px;cursor:pointer}
.report-window-opt:has(input:checked){border-color:var(--accent);background:var(--accent-wash)}
.report-window-opt input[type=radio]{margin-top:3px}
.report-window-opt > span{display:grid;gap:4px;flex:1;min-width:0}
.report-window-opt small{color:var(--ink-faint);font-size:12px}
.report-window-n{display:flex;gap:8px;margin-top:6px;max-width:280px}
.report-window-n .input{width:96px}
.report-window-quick{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
.report-window-n[hidden],.report-window-quick[hidden]{display:none}

/* --- Profile: side-menu order ---------------------------------------------- */
.sidebar-arrange > .arrange-item + .arrange-item { margin-top: 10px; }
.sidebar-arrange .arrange-sub { margin-top: 6px; }
.sidebar-arrange-title { display: inline-flex; align-items: center; gap: 8px; }
.sidebar-arrange-icon { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 6px; background: var(--accent-wash); color: var(--accent); }
.sidebar-arrange-icon svg { width: 15px; height: 15px; }
.sidebar-custom-note { color: var(--accent); font-weight: 550; }
.sidebar-arrange-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.sidebar-arrange-foot-actions { display: flex; gap: 8px; }
.sidebar-arrange-foot-actions .btn[disabled] { opacity: .5; cursor: default; }

/* --- Roles: grouped permission grid, read view, people ------------------- */
.perm-head-side { display: flex; align-items: center; gap: 14px; flex: none; }
.perm-summary { font-size: 12.5px; font-weight: 550; color: var(--accent); white-space: nowrap; }
.perm-summary.is-empty { color: var(--ink-faint); font-weight: 500; }
.perm-tools { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 8px; flex-wrap: wrap; }
.perm-search { position: relative; display: block; width: min(100%, 280px); }
.perm-search svg { position: absolute; left: 10px; top: 50%; width: 15px; height: 15px; transform: translateY(-50%); color: var(--ink-faint); pointer-events: none; }
.perm-search .input { padding-left: 32px; height: 34px; }
.perm-legend { display: none; }
.perm-scroll { max-height: 70vh; overflow: auto; }
.perm-grid thead th { position: sticky; top: 0; z-index: 2; background: var(--surface); box-shadow: inset 0 -1px 0 var(--hairline); }
.perm-group-row th { background: var(--surface-sunken); font-size: 11px; font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); padding-top: 8px; padding-bottom: 8px; }
.perm-group-label { margin-right: 10px; }
.row-link { color: inherit; text-decoration: none; }
.row-link:hover { color: var(--accent); text-decoration: underline; }
.perm-group-count { font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.perm-grid tr[data-perm-row].is-granted td:first-child strong { color: var(--accent-deep, var(--accent)); }
.perm-grid tr[data-perm-row]:hover td { background: var(--accent-wash); }
.perm-grid tr[hidden], .perm-grid tbody[hidden] { display: none; }
.perm-empty { margin: 14px 0 4px; font-size: 13px; color: var(--ink-faint); text-align: center; }
.perm-grid-read tr.is-denied td { color: var(--ink-faint); }
.perm-grid-read tr.is-denied td:first-child strong { color: var(--ink-soft); font-weight: 500; }
.perm-yes { display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: var(--accent); color: #fff; }
.perm-no { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--hairline); }
.role-access { display: grid; gap: 1px; }
.role-access-list { font-size: 11.5px; color: var(--ink-faint); max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; }
.role-people { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 8px; }
.role-person { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--hairline); border-radius: 8px; color: inherit; text-decoration: none; min-width: 0; }
.role-person:hover { border-color: var(--accent); background: var(--accent-wash); }
.role-person-body { display: grid; min-width: 0; flex: 1; line-height: 1.25; }
.role-person-body strong { font-size: 13px; font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.role-person-body span { font-size: 11.5px; color: var(--ink-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }


/* --- Access denied (403), signed in ------------------------------------------
   A single centred card in the content area, the panel's own menus still
   around it: the person did nothing wrong, so the page should feel calm and
   point them somewhere, not shout a status code at them. */
.denied-wrap {
    display: flex;
    justify-content: center;
    align-items: flex-start;
    padding: 28px 0 12px;
    min-height: calc(100vh - 64px - 70px);
}

.denied-card {
    width: 100%;
    max-width: 600px;
    padding: 44px 40px 36px;
    text-align: center;
    position: relative;
}

/* A faint wash across the top of the card, so the lock sits on colour. */
.denied-card::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 150px;
    background: linear-gradient(180deg, var(--accent-wash), transparent);
    pointer-events: none;
}

.denied-badge {
    position: relative;
    width: 72px;
    height: 72px;
    margin: 0 auto 22px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    color: var(--accent);
    background: var(--surface);
    border: 1px solid var(--hairline);
    box-shadow: 0 0 0 8px var(--accent-wash), var(--lift-1);
}

.denied-badge svg { width: 34px; height: 34px; }

.denied-status {
    position: relative;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-bottom: 8px;
}

.denied-title {
    position: relative;
    font-size: 26px;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--ink);
    margin-bottom: 10px;
}

.denied-reason {
    position: relative;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.55;
    color: var(--ink);
    margin: 0 auto 18px;
    max-width: 460px;
}

.denied-note {
    position: relative;
    margin: 0 auto 26px;
    max-width: 470px;
}

.denied-note p {
    font-size: 13.5px;
    line-height: 1.7;
    color: var(--ink-soft);
}

.denied-note p + p { margin-top: 10px; }

.denied-actions {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
}

.denied-actions .btn svg { width: 16px; height: 16px; }

.denied-foot {
    position: relative;
    margin-top: 26px;
    padding-top: 18px;
    border-top: 1px solid var(--hairline-soft);
    font-size: 12.5px;
    color: var(--ink-faint);
}

@media (max-width: 640px) {
    .denied-wrap { padding-top: 8px; min-height: 0; }
    .denied-card { padding: 34px 22px 28px; }
    .denied-title { font-size: 22px; }
    .denied-actions .btn { flex: 1 1 100%; justify-content: center; }
}


/* --- "FrontEnd Page" line in a module's page head ---------------------------
   Which page on the public website carries the form that feeds this module,
   as a link that opens the site in a new tab. Sits between the title and
   the description, so whoever works the module can open what the visitor
   saw in one click. */
.site-page {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
    font-size: 13px;
    color: var(--ink-soft);
}

.site-page-key { font-weight: 600; color: var(--ink-faint); }

.site-page a {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 9px 2px 8px;
    border-radius: 999px;
    background: var(--accent-wash);
    color: var(--accent);
    font-weight: 600;
}

.site-page a:hover { text-decoration: none; background: var(--accent); color: #fff; }
.site-page a svg { width: 13px; height: 13px; flex: none; }

.site-page-url { font-size: 12px; color: var(--ink-faint); overflow-wrap: anywhere; }

.page-head .site-page + p { margin-top: 8px; }


/* --- Labelled filters on one line (card head) --------------------------------
   Two or three selects side by side, each with a small caption above it, so
   the card head stays one row and each control says what it filters. */
.filter-row {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    flex: none;
    flex-wrap: nowrap;
}

.filter-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

.filter-field > span {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ink-faint);
    white-space: nowrap;
}

.filter-field .select { min-width: 150px; }

@media (max-width: 860px) {
    .card-head:has(.filter-row) { flex-wrap: wrap; }
    .filter-row { width: 100%; }
    .filter-field { flex: 1; }
    .filter-field .select { width: 100%; min-width: 0; }
}

/* --- A list of tick boxes in a form (topics, interests) ----------------------
   Two columns of labelled boxes that read as one field. */
.check-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 6px 18px;
    margin-top: 4px;
}

.check-item {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: 13.5px;
    color: var(--ink-soft);
    cursor: pointer;
}

.check-item .check-box { margin-top: 2px; flex: none; }
.check-item:hover { color: var(--ink); }

fieldset.field { border: 0; padding: 0; margin: 0 0 16px; min-width: 0; }
fieldset.field legend { font-size: 13px; font-weight: 600; color: var(--ink); margin-bottom: 6px; padding: 0; }


/* A second line under the permissions intro, for what Create and Update
   mean on the lead modules. */
.perm-head-note { margin-top: 6px; font-size: 12.5px; color: var(--ink-faint); }


/* --- "?" help beside a heading ----------------------------------------------
   A small circled question mark; hover or focus it and a plate of wrapping
   text opens beneath. For explanations too long for a one-line tooltip. */
.help-tip {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    margin-left: 6px;
    vertical-align: -2px;
    border-radius: 50%;
    color: var(--ink-faint);
    cursor: help;
    outline: none;
}

.help-tip svg { width: 18px; height: 18px; }
.help-tip:hover, .help-tip:focus-visible { color: var(--accent); }

.help-tip-text {
    position: absolute;
    top: calc(100% + 8px);
    left: -8px;
    z-index: 40;
    width: min(420px, 80vw);
    padding: 12px 14px;
    border-radius: var(--r-md);
    background: #14161b;
    color: #fff;
    font-size: 12.5px;
    font-weight: 450;
    line-height: 1.55;
    text-align: left;
    letter-spacing: 0;
    text-transform: none;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transform: translateY(3px);
    pointer-events: none;
    transition: opacity 0.12s ease, transform 0.12s ease;
}

.help-tip-text > span { display: block; }
.help-tip-text > span + span { margin-top: 8px; }
.help-tip-text strong { color: #fff; font-weight: 700; }

/* The little arrow above the plate, under the icon. */
.help-tip-text::before {
    content: '';
    position: absolute;
    bottom: 100%;
    left: 13px;
    border: 6px solid transparent;
    border-bottom-color: #14161b;
}

.help-tip:hover .help-tip-text,
.help-tip:focus-visible .help-tip-text,
.help-tip:focus-within .help-tip-text {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

:root[data-theme="dark"] .help-tip-text { background: #3a3f47; }
:root[data-theme="dark"] .help-tip-text::before { border-bottom-color: #3a3f47; }


/* --- Assignment card and dialog --------------------------------------------- */
.assign-people { display: flex; flex-wrap: wrap; gap: 28px; }
.assign-person { display: flex; align-items: center; gap: 10px; min-width: 220px; }
.assign-person > div { display: flex; flex-direction: column; }
.assign-person strong { font-size: 14px; }
.assign-label { font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-faint); }
.assign-current { margin: 0 0 10px; font-size: 13px; color: var(--ink-soft); }
.notice-soft { background: var(--surface-sunken); border: 1px solid var(--hairline); color: var(--ink-soft); }
[data-assign-dialog] .task-person input[type="radio"] { margin: 0; }


/* --- "Assigned to" cell in the lead lists ----------------------------------
   Green when somebody holds it, amber when nobody does — so the ones still
   to hand out can be picked off the list at a glance. */
.assign-cell { display: inline-flex; align-items: center; gap: 8px; }
.assign-cell-text { display: flex; flex-direction: column; gap: 2px; }
.assign-cell-text .pill { align-self: flex-start; white-space: nowrap; }
.assign-cell.is-unassigned { flex-direction: column; align-items: flex-start; gap: 4px; }
.assign-cell-link {
    border: 0; background: none; padding: 0; cursor: pointer;
    font: inherit; font-size: 12px; font-weight: 600; color: var(--accent);
}
.assign-cell-link:hover { text-decoration: underline; }
/* A faint amber wash down the left of an unassigned row. */
tr[data-assigned="no"] td:first-child { box-shadow: inset 3px 0 0 var(--warn); }
tr[data-assigned="yes"] td:first-child { box-shadow: inset 3px 0 0 var(--good); }

/* The line an assignee-only reader sees above a lead list. */
.assigned-only-note { margin-bottom: 18px; }

/* --- Settings: Terms & Privacy links on the order form --------------------- */
.ll-choice { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); margin-bottom: 0; }
.ll-choice .rs-opt { background: var(--surface); }
.ll-choice strong { display: inline-flex; align-items: center; gap: 8px; }
.ll-icon { width: 18px; height: 18px; flex: none; color: var(--accent); }

/* --- Settings: Reports Store industries ------------------------------------ */
.rs-choice { display: grid; gap: 8px; margin-bottom: 16px; }
.rs-opt { display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; border: 1px solid var(--hairline); border-radius: 8px; cursor: pointer; }
.rs-opt:has(input:checked) { border-color: var(--accent); background: var(--accent-wash); }
.rs-opt input { margin-top: 3px; }
.rs-opt > span { display: grid; gap: 3px; }
.rs-opt small { color: var(--ink-soft); font-size: 12.5px; line-height: 1.5; }
/* The licence-price switches: one card per licence, ticked = printed on the
   site's catalogue card. Sits between the industries choice and the tally. */
.rs-prices { margin: 4px 0 18px; padding: 14px 16px; border: 1px solid var(--hairline); border-radius: 8px; background: var(--surface-sunken); }
.rs-prices-head { display: grid; gap: 4px; margin-bottom: 12px; }
.rs-prices-head strong { font-size: 13.5px; }
.rs-prices-head small { color: var(--ink-soft); font-size: 12.5px; line-height: 1.5; }
.rs-prices-head em { font-style: normal; font-weight: 600; color: var(--ink); }
.rs-prices-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 8px; }
.rs-opt-check { background: var(--surface); }
.rs-opt-check .check-box { margin-top: 2px; flex: none; }
/* Filter-panel layout choice: a card per option with a sketch of the page. */
.rs-layout-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 10px; }
.rs-opt-layout { background: var(--surface); align-items: flex-start; }
.rs-opt-layout > span { gap: 6px; }
.rs-sketch { display: block; height: 84px; border: 1px solid var(--hairline); border-radius: 6px; background: #fff; overflow: hidden; position: relative; margin-bottom: 4px; }
.rs-sketch-head { display: block; height: 12px; background: #1B3A6B; }
.rs-sketch-body { position: absolute; inset: 12px 0 0; display: grid; grid-template-columns: 34% 1fr; gap: 6px; padding: 6px; }
.rs-sketch-panel { display: grid; align-content: start; gap: 4px; padding: 4px; border-radius: 3px; background: #EEF2F8; border: 1px solid #D9E1EC; }
.rs-sketch-panel i { display: block; height: 5px; border-radius: 2px; background: #B8C6DB; }
.rs-sketch-panel i:first-child { background: #C9A24B; width: 60%; }
.rs-sketch-list { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; align-content: start; }
.rs-sketch-list i { display: block; height: 16px; border-radius: 3px; background: #F1F3F7; border: 1px solid #E3E7EE; }
/* Scrolls with the page: the panel has started to slide up under the header. */
.rs-sketch-static .rs-sketch-panel { margin-top: -10px; height: 34px; }
.rs-sketch-static .rs-sketch-list { margin-top: -10px; }
/* Pinned: the panel sits flush beneath the header while the list has scrolled. */
.rs-sketch-sticky .rs-sketch-panel { height: 40px; }
.rs-sketch-sticky .rs-sketch-list { margin-top: -10px; }
/* Full height: the panel runs to the bottom edge with its own scrollbar. */
.rs-sketch-full .rs-sketch-panel { height: calc(100% + 6px); margin-bottom: -6px; border-radius: 3px 3px 0 0; box-shadow: inset -3px 0 0 #D9E1EC; }
.rs-sketch-full .rs-sketch-list { margin-top: -10px; }
/* Floating: a raised card part-way down, following the scroll. */
.rs-sketch-floating .rs-sketch-panel { margin-top: 10px; height: 40px; box-shadow: 0 6px 14px -6px rgba(13,27,46,.45); background: #fff; }
.rs-sketch-floating .rs-sketch-list { margin-top: -10px; }
.rs-opt-layout:has(input:checked) .rs-sketch { border-color: var(--accent); }
.rs-tally { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; }
.rs-tally-list { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 0; }
.rs-tally-list .pill { text-decoration: none; }
.rs-load-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 8px; }
.rs-load-custom { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
.rs-load-custom .input { width: 96px; padding-block: 5px; }
.rs-load-mode-head { margin: 16px 0 10px; }
.rs-load-mode { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 8px; }

/* =========================================================================
   Digital products — top-bar icon tools, and the AI images screen
   ========================================================================= */

/* Icon buttons, each in its own tone on hover. The name hangs BELOW the
   button: the bar sits against the top edge, where a label above is cut off. */
.dp-action {
    position: relative;
    width: 38px;
    height: 38px;
    padding: 0;
    border-radius: 11px;
    color: var(--dp-tone, var(--ink-soft));
    transition: transform .14s ease, box-shadow .16s ease, background .16s ease, border-color .16s ease, color .16s ease;
}
.dp-action svg { width: 18px; height: 18px; flex: none; }
.dp-action:hover {
    color: var(--dp-tone, var(--ink));
    background: color-mix(in srgb, var(--dp-tone, var(--accent)) 12%, var(--surface));
    border-color: color-mix(in srgb, var(--dp-tone, var(--accent)) 38%, var(--hairline));
    box-shadow: 0 8px 18px -10px color-mix(in srgb, var(--dp-tone, var(--accent)) 70%, transparent);
    transform: translateY(-1px);
}
.dp-action-label { display: none; }
.dp-action-logs { --dp-tone: #64748b; }
.dp-action-trash { --dp-tone: #e0564b; }
.dp-action-upload { --dp-tone: #1f9d74; }
.dp-action-ai { --dp-tone: #8b5cf6; color: #fff; border-color: transparent; background: linear-gradient(135deg, #8b5cf6, #ec4899); }
.dp-action-ai:hover { color: #fff; background: linear-gradient(135deg, #7c3aed, #db2777); }
.dp-action-add { --dp-tone: var(--accent); color: #fff; border-color: transparent; background: linear-gradient(180deg, var(--accent), var(--accent-deep)); }
.dp-action-add:hover { color: #fff; background: linear-gradient(180deg, var(--accent-deep), var(--accent-deep)); }
.dp-action-badge {
    position: absolute; top: -6px; right: -6px;
    min-width: 18px; height: 18px; padding: 0 5px;
    border-radius: 999px; background: #e0564b; color: #fff;
    font-size: 10.5px; font-weight: 700; line-height: 18px; text-align: center;
    box-shadow: 0 0 0 2px var(--surface);
}

.topbar-actions .dp-action[data-tip]::after { bottom: auto; top: calc(100% + 9px); }
.topbar-actions .dp-action[data-tip]::before {
    bottom: auto; top: calc(100% - 1px);
    border-top-color: transparent; border-bottom-color: #14161b;
}
:root[data-theme="dark"] .topbar-actions .dp-action[data-tip]::before { border-bottom-color: #3a3f47; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .topbar-actions .dp-action[data-tip]::before { border-bottom-color: #3a3f47; }
}

/* In the phone drawer the icons become labelled rows like every other action. */
html[data-actions="open"] .dp-action-label { display: inline; }
html[data-actions="open"] .dp-action:not(.dp-action-ai):not(.dp-action-add) { color: var(--ink); }
html[data-actions="open"] .dp-action[data-tip]::after,
html[data-actions="open"] .dp-action[data-tip]::before { display: none; }
html[data-actions="open"] .dp-action-badge { position: static; margin-left: auto; box-shadow: none; }

/* --- AI images ------------------------------------------------------------ */
.ai-badge-preview {
    display: inline-block; margin-left: 10px; padding: 3px 10px; vertical-align: middle;
    border-radius: 999px; font-size: 12px; font-weight: 650; letter-spacing: .01em;
    color: #8b5cf6; background: color-mix(in srgb, #8b5cf6 14%, transparent);
}
.ai-notice { margin-bottom: 16px; }
.ai-icon-btn svg { width: 16px; height: 16px; flex: none; }

.ai-steps { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: 0 0 18px; padding: 0; }
.ai-steps li {
    display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px 6px 6px;
    border: 1px solid var(--hairline); border-radius: 999px; background: var(--surface);
    color: var(--ink-faint); font-size: 13px; font-weight: 600;
}
.ai-steps li span { display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--surface-sunken); font-size: 12px; }
.ai-steps li.is-on { color: var(--ink); border-color: color-mix(in srgb, #8b5cf6 35%, var(--hairline)); }
.ai-steps li.is-on span { color: #fff; background: linear-gradient(135deg, #8b5cf6, #ec4899); }

/* The industry bar. */
.ai-filterbar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; padding: 14px 16px; margin-bottom: 18px; }
.ai-field { display: grid; gap: 5px; min-width: 190px; }
.ai-field > span { font-size: 11.5px; font-weight: 650; letter-spacing: .03em; text-transform: uppercase; color: var(--ink-faint); }
.ai-field-grow { flex: 1; min-width: 220px; }
.ai-filterbar .ai-field:first-child { min-width: 260px; }
.ai-filter-stat { margin: 0 0 9px auto; font-size: 13px; color: var(--ink-soft); }
.ai-filter-stat strong { color: var(--ink); }

/* The report list: switch · report · your prompt · auto prompt. */
.ai-table { min-width: 980px; table-layout: fixed; }
.ai-table .ai-col-on { width: 74px; text-align: center; }
.ai-table .ai-col-report { width: 25%; }
.ai-table .ai-col-pics { width: 21%; }
.ai-table .ai-col-own { width: 26%; }
.ai-table tbody td { vertical-align: top; }
.ai-table thead th .ai-priority { margin-right: 4px; }
.ai-table tbody tr[data-ai-row] > td { transition: opacity .16s ease, background .16s ease; }
.ai-table tbody tr[data-ai-row]:not(.is-picked) > td:not(.ai-col-on) { opacity: .62; }
.ai-table tbody tr.is-picked > td { background: color-mix(in srgb, #8b5cf6 6%, transparent); }
.ai-table tbody td.ai-col-report { cursor: pointer; }

.ai-report { display: flex; gap: 12px; align-items: flex-start; }
.ai-report > div { display: grid; gap: 2px; min-width: 0; }
.ai-report strong { line-height: 1.35; }
.ai-thumb { flex: none; display: block; width: 56px; height: 40px; object-fit: cover; border-radius: 7px; border: 1px solid var(--hairline); }
.ai-thumb-empty { display: grid; place-items: center; color: var(--ink-faint); background: var(--surface-sunken); }
.ai-thumb-empty svg { width: 18px; height: 18px; }
.ai-cover-note { margin-top: 3px; font-size: 11.5px; color: var(--ink-faint); }

.ai-col-own, .ai-col-auto { position: relative; }
.ai-col-own.is-used, .ai-col-auto.is-used { box-shadow: inset 3px 0 0 #8b5cf6; }
.ai-in-use { display: block; margin-bottom: 4px; font-size: 11.5px; font-weight: 700; color: #1f9d74; }
.ai-in-use[hidden] { display: none; }
.ai-own-input { width: 100%; resize: vertical; min-height: 76px; font-size: 13px; }
.ai-auto-snippet {
    margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--ink-soft);
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.ai-col-auto.is-open .ai-auto-snippet { display: block; -webkit-line-clamp: unset; }
.ai-more { margin-top: 4px; padding: 0; border: 0; background: none; font: inherit; font-size: 12px; font-weight: 650; color: var(--accent); cursor: pointer; }
.ai-no-match { margin: 0; padding: 18px; text-align: center; color: var(--ink-faint); }

.ai-priority { display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; font-size: 11px; font-weight: 700; color: #fff; background: linear-gradient(135deg, #8b5cf6, #ec4899); vertical-align: 1px; }
.ai-priority-2 { background: var(--ink-faint); }

/* The on/off switch. */
.ai-switch { position: relative; display: inline-block; width: 38px; height: 22px; vertical-align: middle; }
.ai-switch input { position: absolute; inset: 0; z-index: 1; margin: 0; opacity: 0; cursor: pointer; }
.ai-switch span { position: absolute; inset: 0; border-radius: 999px; background: color-mix(in srgb, var(--ink-faint) 45%, transparent); transition: background .16s ease; }
.ai-switch span::after { content: ''; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .25); transition: transform .16s ease; }
.ai-switch input:checked + span { background: linear-gradient(135deg, #8b5cf6, #ec4899); }
.ai-switch input:checked + span::after { transform: translateX(16px); }
.ai-switch input:indeterminate + span { background: color-mix(in srgb, #8b5cf6 55%, transparent); }
.ai-switch input:indeterminate + span::after { transform: translateX(8px); }
.ai-switch input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Settings and connection, side by side under the list. */
.ai-panels { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 18px; margin-top: 18px; align-items: start; }
.ai-panels > .card { margin: 0; }
@media (max-width: 1000px) { .ai-panels { grid-template-columns: 1fr; } }
#ai-results { margin-top: 18px; }
.ai-stack { display: grid; gap: 18px; min-width: 0; }
.ai-stack > .card { margin: 0; }
.ai-style-default { margin-bottom: 14px; }
.ai-style-pick { margin-bottom: 8px; }
.ai-style-pick .select:disabled { opacity: .65; cursor: not-allowed; }
.ai-style-desc { margin: 0 0 12px; font-size: 13px; color: var(--ink-soft); }
.ai-style-line { margin: 0; padding: 10px 12px; border: 1px dashed var(--hairline); border-radius: 8px; background: var(--surface-sunken); font-size: 12.5px; line-height: 1.5; color: var(--ink); }
.ai-style-line span { display: block; margin-bottom: 3px; font-size: 11px; font-weight: 650; letter-spacing: .03em; text-transform: uppercase; color: var(--ink-faint); }
.ai-style-line q { quotes: none; }
/* Pictures per report, and for many at once. */
.ai-slots { margin-top: 10px; }
.ai-slots summary { display: inline-flex; align-items: flex-start; gap: 5px; padding: 5px 11px; cursor: pointer; list-style: none; border: 1px solid var(--hairline); border-radius: 10px; line-height: 1.4; background: var(--surface); font-size: 12px; font-weight: 650; color: var(--ink-soft); }
.ai-slots summary::-webkit-details-marker { display: none; }
.ai-slots summary::after { content: '▾'; font-size: 10px; }
.ai-slots[open] summary::after { content: '▴'; }
.ai-slots.has-ticks summary { color: #7c3aed; border-color: color-mix(in srgb, #8b5cf6 45%, var(--hairline)); background: color-mix(in srgb, #8b5cf6 9%, var(--surface)); }
.ai-slots-panel { display: grid; gap: 2px; max-height: 300px; margin-top: 8px; padding: 10px; overflow-y: auto; cursor: default; border: 1px solid var(--hairline); border-radius: 10px; background: var(--surface-sunken); }
.ai-slots-tools { display: flex; gap: 12px; margin-bottom: 2px; }
.ai-slots-tools button, .ai-link-btn { padding: 0; border: 0; background: none; font: inherit; font-size: 12px; font-weight: 650; color: var(--accent); cursor: pointer; }
.ai-slot-group { margin: 8px 0 2px; font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-faint); }
.ai-slot { display: flex; align-items: flex-start; gap: 8px; padding: 3px 2px; font-size: 12.5px; line-height: 1.35; color: var(--ink); cursor: pointer; }
.ai-slot .check-box { flex: none; margin-top: 1px; }
.ai-slot small { display: block; font-size: 11px; color: var(--ink-faint); }
.ai-row-warn { display: block; margin-top: 6px; font-size: 11.5px; font-weight: 650; color: #d97706; }
.ai-row-warn[hidden] { display: none; }
.ai-auto-note { display: block; margin-top: 4px; font-size: 11.5px; color: var(--ink-faint); }
#ai-pictures { margin-bottom: 18px; }
.ai-bulk { display: grid; gap: 16px; }
.ai-bulk-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; margin-bottom: 6px; }
.ai-bulk-head strong { font-size: 13.5px; }
.ai-bulk-head small { font-size: 12px; color: var(--ink-faint); }
.ai-bulk-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 4px 16px; }
.ai-bulk-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding-top: 14px; border-top: 1px solid var(--hairline); }
.ai-bulk-actions .hint { margin: 0; }
.ai-bulk-icon { width: 16px; height: 16px; flex: none; color: #8b5cf6; }
.ai-bar-skip.is-warn strong, .ai-bar-skip.is-warn { color: #d97706; }
.ai-size-frames { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 18px; }
.ai-size-cap { display: block; margin-top: 6px; font-size: 11.5px; text-align: center; color: var(--ink-faint); }
.ai-tile-slot { font-weight: 650; color: #7c3aed; }
.ail-slot { position: absolute; left: 8px; bottom: 8px; max-width: calc(100% - 120px); padding: 2px 8px; overflow: hidden; border-radius: 6px; font-size: 11px; font-weight: 650; white-space: nowrap; text-overflow: ellipsis; color: #fff; background: rgba(16, 20, 32, .62); }
/* Where each picture goes. */
.ai-flow { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 4px; list-style: none; margin: -4px 0 18px; padding: 0; font-size: 12.5px; color: var(--ink-soft); }
.ai-flow li { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border: 1px solid color-mix(in srgb, #8b5cf6 22%, var(--hairline)); border-radius: 10px; background: color-mix(in srgb, #8b5cf6 7%, var(--surface)); }
.ai-flow li b { color: var(--ink); }
.ai-flow li + li::before { content: '→'; margin-right: 2px; font-weight: 700; color: #8b5cf6; }
/* One row per ticked picture, under its report. */
.ai-sub > td { background: var(--surface-sunken); border-top: 1px dashed var(--hairline); }
.ai-sub.is-off > td { opacity: .55; }
.ai-sub-branch { display: block; width: 14px; height: 16px; margin: 4px auto 0; border-left: 2px solid color-mix(in srgb, #8b5cf6 45%, var(--hairline)); border-bottom: 2px solid color-mix(in srgb, #8b5cf6 45%, var(--hairline)); border-bottom-left-radius: 6px; }
.ai-sub-name { display: grid; gap: 2px; padding-left: 14px; }
.ai-sub-name strong { font-size: 13px; }
.ai-sub-where { font-size: 11.5px; color: var(--ink-faint); }
.ai-size-chip { display: inline-block; padding: 2px 9px; border: 1px solid var(--hairline); border-radius: 999px; background: var(--surface); font-size: 11.5px; font-weight: 650; color: var(--ink-soft); }
.ai-sub .ai-own-input { min-height: 62px; }
.ai-row-prompts { display: block; font-size: 12.5px; line-height: 1.45; color: var(--ink-faint); }
/* Columns shown in the report list. */
.ai-head-tools { display: flex; align-items: center; gap: 10px; }
.ai-columns { position: relative; }
.ai-columns > summary { list-style: none; }
.ai-columns > summary::-webkit-details-marker { display: none; }
.ai-columns-menu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 20; display: grid; gap: 4px; min-width: 240px; padding: 10px 12px; border: 1px solid var(--hairline); border-radius: 10px; background: var(--surface); box-shadow: 0 14px 30px -14px rgba(16, 20, 32, .4); }
.ai-columns-note { margin: 4px 0 0; font-size: 11.5px; color: var(--ink-faint); }
.ai-table.hide-details .ai-details,
.ai-table.hide-pictures [data-col="pictures"],
.ai-table.hide-own [data-col="own"],
.ai-table.hide-auto [data-col="auto"] { display: none; }
/* How to get an API key. */
.ai-guide-open { display: flex; align-items: center; gap: 10px; width: 100%; margin: 0 0 14px; padding: 10px 12px; text-align: left; cursor: pointer; border: 1px dashed color-mix(in srgb, #8b5cf6 45%, var(--hairline)); border-radius: 10px; background: color-mix(in srgb, #8b5cf6 7%, var(--surface)); font: inherit; color: var(--ink); transition: background .15s ease, border-color .15s ease; }
.ai-guide-open:hover { border-style: solid; background: color-mix(in srgb, #8b5cf6 12%, var(--surface)); }
.ai-guide-open strong { display: block; font-size: 13.5px; }
.ai-guide-open small { display: block; font-size: 12px; color: var(--ink-faint); }
.ai-guide-open-icon { display: grid; place-items: center; flex: none; width: 28px; height: 28px; border-radius: 50%; font-weight: 800; color: #fff; background: linear-gradient(135deg, #8b5cf6, #ec4899); }
.ai-guide { width: min(760px, calc(100vw - 32px)); }
.ai-guide .modal-head > div { flex: 1; }
.ai-guide-badge { display: grid; place-items: center; flex: none; width: 36px; height: 36px; border-radius: 10px; color: #fff; background: linear-gradient(135deg, #8b5cf6, #ec4899); }
.ai-guide-badge svg { width: 20px; height: 20px; }
.ai-guide-progress { display: flex; align-items: center; gap: 12px; padding: 10px 20px; border-bottom: 1px solid var(--hairline-soft); font-size: 12.5px; }
.ai-guide-bar { flex: 1; height: 6px; overflow: hidden; border-radius: 999px; background: var(--surface-sunken); }
.ai-guide-bar span { display: block; width: 0; height: 100%; border-radius: inherit; background: linear-gradient(90deg, #8b5cf6, #ec4899); transition: width .25s ease; }
.ai-guide[open] { display: flex; flex-direction: column; }
.ai-guide-body { flex: 1; min-height: 0; max-height: none; overflow-y: auto; display: grid; align-content: start; gap: 16px; }
.ai-guide .modal-foot { flex: none; }
.ai-guide-before, .ai-guide-safe, .ai-guide-help { padding: 12px 14px; border: 1px solid var(--hairline); border-radius: 10px; background: var(--surface-sunken); font-size: 13px; }
.ai-guide-safe { border-color: color-mix(in srgb, #d97706 40%, var(--hairline)); background: color-mix(in srgb, #d97706 7%, var(--surface)); }
.ai-guide-before ul, .ai-guide-safe ul { margin: 6px 0 0; padding-left: 18px; display: grid; gap: 3px; color: var(--ink-soft); }
.ai-guide-steps { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }
.ai-guide-step { display: flex; gap: 12px; padding: 12px 14px; border: 1px solid var(--hairline); border-radius: 12px; background: var(--surface); transition: border-color .15s ease, background .15s ease; }
.ai-guide-step.is-done { border-color: color-mix(in srgb, #1f9d74 45%, var(--hairline)); background: color-mix(in srgb, #1f9d74 6%, var(--surface)); }
.ai-guide-num { display: grid; place-items: center; flex: none; width: 28px; height: 28px; border-radius: 50%; font-size: 13px; font-weight: 800; color: #fff; background: linear-gradient(135deg, #8b5cf6, #ec4899); }
.ai-guide-step.is-done .ai-guide-num { background: #1f9d74; }
.ai-guide-content { flex: 1; min-width: 0; font-size: 13px; line-height: 1.55; }
.ai-guide-step-head { display: flex; align-items: center; gap: 10px; }
.ai-guide-step-head h3 { flex: 1; margin: 0; font-size: 14.5px; }
.ai-guide-done { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 650; color: var(--ink-soft); cursor: pointer; }
.ai-guide-content > p { margin: 4px 0 6px; color: var(--ink-soft); }
.ai-guide-content ul { margin: 0 0 8px; padding-left: 18px; display: grid; gap: 3px; }
.ai-guide-content code { padding: 1px 5px; border-radius: 4px; background: var(--surface-sunken); font-size: 12px; }
.ai-guide-link { margin: 2px 6px 0 0; }
.ai-guide-help { display: grid; gap: 6px; }
.ai-guide-help details { padding: 6px 10px; border-radius: 8px; background: var(--surface); }
.ai-guide-help summary { cursor: pointer; font-weight: 650; }
.ai-guide-help details p { margin: 6px 0 2px; color: var(--ink-soft); }
.ai-guide-note { margin: 0; }
/* Sizes, style and ChatGPT: one folded panel under the filters. */
.ai-setup { margin-bottom: 18px; padding: 0; overflow: visible; }
.ai-setup > summary { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; padding: 14px 18px; cursor: pointer; list-style: none; border-radius: inherit; }
.ai-setup > summary::-webkit-details-marker { display: none; }
.ai-setup > summary:hover { background: var(--surface-sunken); }
.ai-setup[open] > summary { border-bottom: 1px solid var(--hairline-soft); border-radius: var(--r-lg) var(--r-lg) 0 0; }
.ai-setup-icon { display: grid; place-items: center; flex: none; width: 34px; height: 34px; border-radius: 10px; color: #fff; background: linear-gradient(135deg, #8b5cf6, #ec4899); }
.ai-setup-icon svg { width: 18px; height: 18px; }
.ai-setup-text { display: grid; gap: 1px; }
.ai-setup-title { font-size: 15px; font-weight: 650; color: var(--ink); }
.ai-setup-sub { font-size: 12px; color: var(--ink-faint); }
.ai-setup-sub::after { content: 'Click to open'; }
.ai-setup[open] .ai-setup-sub::after { content: 'Click to fold away'; }
.ai-setup-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-left: auto; }
.ai-setup-chevron { flex: none; width: 20px; height: 20px; color: var(--ink-faint); transition: transform .18s ease; }
.ai-setup[open] .ai-setup-chevron { transform: rotate(180deg); }
.ai-setup .ai-panels { margin-top: 0; padding: 18px; }
.ai-setup .ai-panels .card { box-shadow: none; }
/* The OpenAI connection and its key dialog. */
.ai-conn-status.is-on i { background: #1f9d74; box-shadow: 0 0 0 3px color-mix(in srgb, #1f9d74 22%, transparent); }
.ai-conn-facts { display: grid; gap: 6px; margin: 0 0 14px; }
.ai-conn-facts div { display: flex; justify-content: space-between; gap: 12px; padding: 7px 10px; border-radius: 8px; background: var(--surface-sunken); font-size: 12.5px; }
.ai-conn-facts dt { color: var(--ink-faint); }
.ai-conn-facts dd { margin: 0; font-weight: 600; text-align: right; }
.ai-ok { color: #1f9d74; }
.ai-bad { color: #e0564b; }
.ai-conn-empty { margin: -6px 0 14px; }
.ai-conn-error { margin: 0 0 12px; }
.ai-conn-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; }
.ai-conn-actions form { margin: 0; }
.ai-model-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px; padding-top: 12px; border-top: 1px solid var(--hairline-soft); }
.ai-model-form .ai-field { flex: 1; min-width: 180px; }
.ai-key-dialog { width: min(560px, calc(100vw - 32px)); }
.ai-key-dialog .modal-head > div { flex: 1; }
.ai-key-promises { display: grid; gap: 6px; margin: 4px 0 0; padding: 12px 14px 12px 30px; border: 1px solid var(--hairline); border-radius: 10px; background: var(--surface-sunken); font-size: 12.5px; line-height: 1.5; color: var(--ink-soft); }
.ai-key-promises b { color: var(--ink); }
/* Real pictures in the results. */
.ai-tile .ai-tile-img { background: var(--surface-sunken); }
.ai-tile .ai-tile-img::after { display: none; }
.ai-tile-img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.ai-tile-state { position: absolute; left: 8px; bottom: 8px; padding: 2px 8px; border-radius: 6px; font-size: 11px; font-weight: 650; color: var(--ink-soft); background: color-mix(in srgb, var(--surface) 85%, transparent); }
.ai-tile.is-done .ai-tile-state { color: #fff; background: rgba(16, 20, 32, .62); }
.ai-tile.is-failed .ai-tile-img { background: color-mix(in srgb, #e0564b 10%, var(--surface-sunken)); }
.ai-tile.is-failed .ai-tile-state { color: #e0564b; }
.ai-tile.is-stopped .ai-tile-img { opacity: .6; }
.ai-tile.is-applied { border-color: color-mix(in srgb, #1f9d74 45%, var(--hairline)); }
.ai-tile-error { font-size: 12px; line-height: 1.45; color: #e0564b; }
.ai-tile-actions { flex-wrap: wrap; }
.ai-tile-actions [data-lib] { flex: none; }
.btn.is-applied, .btn.is-applied:disabled { opacity: 1; color: #fff; background: #1f9d74; border-color: transparent; }
.ai-bar-hint { font-size: 12.5px; font-weight: 650; color: #d97706; }
.ai-bar-hint[hidden] { display: none; }
.pill.pill-warn { color: #b45309; background: color-mix(in srgb, #d97706 14%, transparent); }
.ai-size { display: flex; flex-wrap: wrap; align-items: center; gap: 22px; }
.ai-size-frame {
    flex: none; display: grid; place-items: center; border-radius: 6px;
    border: 1.5px dashed color-mix(in srgb, #8b5cf6 55%, var(--hairline));
    background: linear-gradient(135deg, color-mix(in srgb, #8b5cf6 16%, var(--surface)), color-mix(in srgb, #ec4899 12%, var(--surface)));
}
.ai-size-frame span { font-size: 13px; font-weight: 700; color: var(--ink-soft); }
.ai-size-facts { flex: 1; min-width: 220px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin: 0; }
.ai-size-facts div { padding: 9px 12px; border: 1px solid var(--hairline); border-radius: 10px; background: var(--surface-sunken); }
.ai-size-facts dt { font-size: 11.5px; color: var(--ink-faint); }
.ai-size-facts dd { margin: 2px 0 0; font-size: 13.5px; font-weight: 650; }
.ai-conn-status { display: flex; align-items: center; gap: 8px; margin: 0 0 14px; font-size: 13px; font-weight: 600; color: var(--ink-soft); }
.ai-conn-status i { width: 8px; height: 8px; border-radius: 50%; background: #e0564b; box-shadow: 0 0 0 3px color-mix(in srgb, #e0564b 20%, transparent); }

/* The bar that stays at the foot of the screen. */
.ai-bar {
    position: sticky; bottom: 14px; z-index: 4;
    display: flex; flex-wrap: wrap; align-items: center; gap: 14px;
    margin-top: 18px; padding: 12px 14px 12px 18px;
    border: 1px solid color-mix(in srgb, #8b5cf6 30%, var(--hairline)); border-radius: 14px;
    background: color-mix(in srgb, var(--surface) 92%, transparent);
    backdrop-filter: saturate(180%) blur(14px); -webkit-backdrop-filter: saturate(180%) blur(14px);
    box-shadow: 0 16px 34px -16px rgba(16, 20, 32, .45);
}
.ai-bar-stats { display: flex; flex-wrap: wrap; gap: 6px 18px; font-size: 13px; color: var(--ink-soft); }
.ai-bar-stats strong { font-size: 15px; color: var(--ink); }
.ai-bar-stats b { color: var(--ink); font-weight: 650; }
.ai-go-btn { margin-left: auto; min-height: 44px; padding-inline: 20px; font-size: 14.5px; background: linear-gradient(135deg, #8b5cf6, #ec4899); }
.ai-go-btn:hover { background: linear-gradient(135deg, #7c3aed, #db2777); }
.ai-go-btn svg { width: 18px; height: 18px; }
.ai-go-btn:disabled { opacity: .5; cursor: not-allowed; transform: none; }

/* Results. */
.ai-results-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(236px, 1fr)); gap: 14px; }
.ai-tile-actions .btn { white-space: nowrap; font-size: 12.5px; }

/* --- AI images library ------------------------------------------------- */
.ail-folder { font-size: 18px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.ail-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }
.ail-card { display: grid; grid-template-rows: auto 1fr; overflow: hidden; border: 1px solid var(--hairline); border-radius: 14px; background: var(--surface); box-shadow: var(--lift-1); transition: transform .16s ease, box-shadow .16s ease; }
.ail-card:hover { transform: translateY(-2px); box-shadow: 0 14px 30px -18px rgba(16, 20, 32, .45); }
.ail-pic { position: relative; display: block; aspect-ratio: 186 / 124; background: var(--surface-sunken); }
.ail-pic img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ail-badge { position: absolute; top: 8px; left: 8px; padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 700; color: #fff; background: linear-gradient(135deg, #8b5cf6, #ec4899); }
.ail-size { position: absolute; right: 8px; bottom: 8px; padding: 2px 7px; border-radius: 6px; font-size: 11px; font-weight: 650; color: #fff; background: rgba(16, 20, 32, .62); }
.ail-body { display: grid; gap: 8px; align-content: start; padding: 12px 14px 14px; }
.ail-title { margin: 0; font-size: 14.5px; line-height: 1.35; }
.ail-title a { color: var(--ink); }
.ail-meta { display: flex; flex-wrap: wrap; gap: 6px; }
.ail-when { margin: 0; font-size: 12px; line-height: 1.5; color: var(--ink-faint); }
.ail-prompt summary { cursor: pointer; font-size: 12.5px; font-weight: 650; color: var(--accent); }
.ail-prompt p { margin: 6px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--ink-soft); }
.ail-actions { display: flex; align-items: center; gap: 6px; }
.ail-actions form:last-of-type { margin-left: auto; }
.ail-empty { display: grid; justify-items: center; gap: 8px; padding: 48px 20px; text-align: center; color: var(--ink-faint); }
.ail-empty svg { width: 42px; height: 42px; }
.ail-empty p { margin: 0; }
.ail-pager { display: flex; align-items: center; justify-content: center; gap: 12px; margin-top: 18px; font-size: 13px; color: var(--ink-soft); }
.ail-pager [aria-disabled="true"] { opacity: .5; pointer-events: none; }
.ai-tile { margin: 0; display: grid; gap: 8px; align-content: start; padding: 10px; border: 1px solid var(--hairline); border-radius: 12px; background: var(--surface); }
.ai-tile-img {
    position: relative; overflow: hidden; border-radius: 8px;
    background: linear-gradient(135deg, hsl(var(--ai-hue, 260) 70% 62%), hsl(calc(var(--ai-hue, 260) + 60) 70% 46%));
}
.ai-tile-img::after { content: ''; position: absolute; inset: 0; background: radial-gradient(circle at 30% 25%, rgba(255, 255, 255, .45), transparent 48%); }
.ai-tile.is-loading .ai-tile-img {
    background: linear-gradient(100deg, var(--surface-sunken) 30%, color-mix(in srgb, var(--surface-sunken) 55%, #ffffff) 50%, var(--surface-sunken) 70%);
    background-size: 220% 100%;
    animation: ai-shimmer 1.1s linear infinite;
}
.ai-tile.is-loading .ai-tile-img::after { display: none; }
@keyframes ai-shimmer { to { background-position: -220% 0; } }
@media (prefers-reduced-motion: reduce) { .ai-tile.is-loading .ai-tile-img { animation: none; } }
.ai-tile figcaption { display: grid; gap: 2px; font-size: 12.5px; }
.ai-tile figcaption strong { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ai-tile figcaption span { color: var(--ink-faint); }
.ai-tile-actions { display: flex; gap: 6px; }
.ai-tile-actions .btn { flex: 1; padding-inline: 8px; }

/* The CMS-status picker in a stat card (digital-products/show) */
.stat-form{display:flex;align-items:center;gap:8px;margin:2px 0 4px}
.stat-form .select-sm{padding:6px 30px 6px 10px;font-size:13px;font-weight:600;min-width:0}

/* Back-to-top button (public/js/scroll-top.js) */
.scroll-top {
    position: fixed;
    right: 20px;
    bottom: 20px;
    z-index: 900;
    width: 44px;
    height: 44px;
    border: 0;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--accent);
    color: #fff;
    cursor: pointer;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);
    opacity: 0;
    visibility: hidden;
    transform: translateY(10px);
    transition: opacity .2s, transform .2s, visibility .2s, background .15s;
}
.scroll-top.is-visible { opacity: 1; visibility: visible; transform: none; }
.scroll-top:hover { background: var(--accent-deep); }
.scroll-top:focus-visible { outline: 3px solid var(--accent-wash); outline-offset: 2px; }
@media print { .scroll-top { display: none; } }
.ai-bar-picks { display: flex; flex-wrap: wrap; gap: 8px 12px; }
.ai-bar-picks .select { min-width: 180px; }
/* Generate button while pictures are being made */
.ai-go-spinner { display: none; width: 18px; height: 18px; border-radius: 50%; border: 2.5px solid rgba(255, 255, 255, .35); border-top-color: #fff; animation: ai-go-spin .8s linear infinite; flex: none; }
.ai-go-btn.is-busy .ai-go-spinner { display: inline-block; }
.ai-go-btn.is-busy .ai-go-icon { display: none; }
.ai-go-btn.is-busy, .ai-go-btn.is-busy:disabled { opacity: 1; cursor: progress; }
@keyframes ai-go-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .ai-go-spinner { animation-duration: 2s; } }
/* Review the images: select several, use or try again */
.ai-review-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin-bottom: 14px; padding: 10px 12px; border: 1px solid var(--hairline); border-radius: 10px; background: var(--surface-sunken); }
.ai-review-bar[hidden] { display: none; }
.ai-review-all { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 650; cursor: pointer; }
.ai-review-count { font-size: 13px; color: var(--ink-soft); }
.ai-review-actions { display: flex; gap: 8px; margin-left: auto; }
.ai-tile-pick { position: absolute; top: 8px; left: 8px; z-index: 2; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 8px; background: color-mix(in srgb, var(--surface) 90%, transparent); box-shadow: 0 1px 4px rgba(0, 0, 0, .18); cursor: pointer; }
.ai-tile-pick[hidden] { display: none; }
.ai-tile.is-picked { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-wash); }
.ai-retry-body { display: grid; gap: 10px; }
.ai-retry-quote { margin: -2px 0 4px; padding: 10px 12px; border-left: 3px solid var(--accent); border-radius: 6px; background: var(--surface-sunken); font-size: 13px; line-height: 1.55; color: var(--ink-soft); max-height: 160px; overflow-y: auto; white-space: pre-wrap; }
.ai-retry-quote[hidden], .ai-retry-new[hidden] { display: none; }
.ai-retry-new .textarea { width: 100%; resize: vertical; }
.ai-tile-img img[hidden] { display: none; }

/* AI image generator: the connection, for someone who may not change it. */
.ai-conn-locked { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--ink-soft); }
