/*
 * Nordcopy Service design system: Bootstrap 5.3 with the CRM's look.
 *
 * Bootstrap sits in the lowest cascade layer, so every rule below wins over it
 * without fighting its selectors. Colours, radius and shadow strength come from
 * the administrator's theme settings as custom properties (core/src/Theme/Theme.php
 * writes :root); the values below are only fallbacks. bootstrap-bridge.css maps
 * Bootstrap's variables onto them and restyles its components to the CRM's
 * sizes. The layout partial links the two in this order. Flat class names, no
 * nesting, so older office browsers render them.
 */
/*
 * A module's stylesheet wraps its rules in `@layer modules { ... }`: above every core
 * component, so a module restyles one without fighting its selectors, and below the
 * utilities, so a utility class in the markup still wins.
 */
@layer bootstrap, vendor, tokens, theme, base, layout, components, modules, utilities;
@import url("../vendor/bootstrap/bootstrap.min.css") layer(bootstrap);

/*
 * Element defaults over Reboot. In Bootstrap's own layer and after it, so a
 * Bootstrap class on the same element still wins by specificity: a link styled
 * here would otherwise recolour every .btn and .nav-link that is an <a>.
 */
@layer bootstrap {
    /* a jump to an anchor or a focused field stops below the sticky top bar */
    html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; background: var(--color-bg); scroll-padding-top: var(--sticky-top); }
    /* Reboot scrolls smoothly; jumps to an anchor and scripted scrolls stay instant */
    :root { scroll-behavior: auto; }
    body { min-height: 100vh; background: var(--color-bg); -webkit-font-smoothing: antialiased; }
    h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, ul, ol { margin: 0; }
    ul, ol { padding-left: 40px; }
    ul[role="list"], ol[role="list"] { list-style: none; padding: 0; }
    img, picture, svg, video { display: block; max-width: 100%; }
    input, button, textarea, select { font: inherit; color: inherit; }
    a { text-decoration: none; }
    a:where(:hover) { text-decoration: underline; }
    h1 { font-size: var(--text-2xl); line-height: 1.2; font-weight: 700; letter-spacing: -0.02em; }
    h2 { font-size: var(--text-xl); line-height: 1.25; font-weight: 650; letter-spacing: -0.01em; }
    h3 { font-size: var(--text-lg); line-height: 1.3; font-weight: 600; }
    /* as browsers draw them, which Reboot enlarges: contract templates use them */
    h4, h5, h6 { line-height: inherit; font-weight: 700; }
    h4 { font-size: 1em; }
    h5 { font-size: .83em; }
    h6 { font-size: .67em; }
    small { color: var(--color-muted); }
    code, kbd { font-family: var(--font-mono); font-size: 0.92em; color: inherit; }
    mark { padding: 0; }
    dt { font-weight: inherit; }
    /* a legend at the top of its fieldset, not floated and enlarged as in Reboot */
    legend { float: none; width: auto; margin-bottom: 0; padding: 0; font-size: inherit; line-height: inherit; }
    :where(:focus-visible) { outline: 3px solid var(--color-focus); outline-offset: 2px; border-radius: var(--radius-sm); }
    ::selection { background: var(--color-primary-soft); }
}

@layer tokens {
    :root {
        --color-primary: #0071e3;
        --color-primary-strong: #0066cc;
        --color-primary-soft: #eaf4ff;
        --color-bg: #f5f5f7;
        --color-surface: #ffffff;
        --color-card: #ffffff;
        --color-text: #1d1d1f;
        --color-muted: #6e6e73;
        --color-border: #d8d8dc;
        --color-border-strong: #bfc0c5;
        --color-row-hover: #f2f7fd;
        --color-row-selected: #e8f2ff;
        --color-header-bg: #f5f5f7;
        --color-chat: #0071e3;
        --color-chat-new: #f59e0b;
        --color-chat-new-text: #1d1d1f; /* white or dark by the luminance of --color-chat-new, chosen by Theme::css() */
        /* text links: --color-primary as text keeps 4.5:1 on white only, not on --color-bg, a selected row or --color-primary-soft */
        --color-link: var(--color-primary-strong);
        /*
         * --color-muted and the link colour shaded by Theme::css() until they keep 4.5:1 on the panel
         * (--color-surface), table header and selected row colours. The box that paints one of these
         * colours takes .on-surface, .on-header or .on-row-selected (components below), which set
         * --color-muted, --bs-secondary-color and the link colours to them for its content.
         */
        --color-surface-muted: #6e6e73;
        --color-header-muted: #6e6e73;
        --color-row-selected-muted: #6d6d72;
        --color-row-selected-link: #0066cc;
        --color-row-selected-link-rgb: 0, 102, 204;
        /* the lines of the sidebar and the tab bar: --color-border, or a shade of --color-surface where the border does not show on it */
        --color-surface-border: #d8d8dc;
        --shadow-alpha: 0.10;
        --radius-lg: 14px;
        --radius-md: 10px;
        --radius-sm: 6px;

        --color-success: #1c7c44;
        --color-success-soft: #e6f6ec;
        --color-warning: #a95909;
        --color-warning-soft: #fff4e0;
        --color-danger: #d70015;
        --color-danger-soft: #fdecee;
        --color-info: #0a6fc2;
        --color-info-soft: #e8f3fd;
        /* translucent variants: computed by Theme::css() from the colours above, since color-mix() is missing in older office browsers */
        --color-focus: rgba(0, 113, 227, .35);
        --color-primary-glow: rgba(0, 113, 227, .40);
        --color-bg-glass: rgba(245, 245, 247, .82);
        --color-surface-glass: rgba(255, 255, 255, .88);
        --color-card-glass: rgba(255, 255, 255, .92);
        --color-hover-tint: rgba(29, 29, 31, .06);
        --color-neutral-soft: rgba(29, 29, 31, .075);

        --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
        --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
        --text-xs: 12px;
        --text-sm: 13px;
        --text-md: 14px;
        --text-lg: 16px;
        --text-xl: 20px;
        --text-2xl: 26px;

        --space-1: 4px;
        --space-2: 8px;
        --space-3: 12px;
        --space-4: 16px;
        --space-5: 20px;
        --space-6: 24px;
        --space-8: 32px;

        --control-height: 38px;
        --control-height-sm: 30px;
        --sidebar-width: 248px;
        --topbar-height: 60px;
        --tabbar-height: 64px;
        /* where a box that sticks while the page scrolls stops: just below the top bar */
        --sticky-top: calc(var(--topbar-height) + var(--space-3));
        --ease: cubic-bezier(.2, .7, .2, 1);
        --duration: 160ms;
    }

    /*
     * The shadows follow the strength the settings choose. A box that sets the theme's
     * tokens on itself ([data-theme-scope], the preview of the theme settings) declares
     * them again, since a variable that refers to another one resolves where it is declared.
     */
    :root, [data-theme-scope] {
        --shadow-sm: 0 1px 2px rgba(0, 0, 0, calc(var(--shadow-alpha) * 0.6));
        --shadow-md: 0 1px 2px rgba(0, 0, 0, calc(var(--shadow-alpha) * 0.5)), 0 6px 18px rgba(0, 0, 0, calc(var(--shadow-alpha) * 0.7));
        --shadow-lg: 0 10px 40px rgba(0, 0, 0, calc(var(--shadow-alpha) * 1.6));
    }

    .no-animations { --duration: 0ms; }
    @media (prefers-reduced-motion: reduce) {
        :root { --duration: 0ms; }
        *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; }
    }
    /* Bootstrap's own transitions too: its scripts read the duration, so a fade or a drawer then finishes at once */
    .no-animations *, .no-animations *::before, .no-animations *::after { transition: none !important; animation: none !important; }
}

@layer base {
    .icon { width: 18px; height: 18px; flex: none; }
    .icon--sm { width: 15px; height: 15px; }
    .icon--lg { width: 22px; height: 22px; }
}

/* ---------- App shell: sidebar, top bar, content, mobile tab bar ---------- */
@layer layout {
    .shell { display: grid; grid-template-columns: var(--sidebar-width) minmax(0, 1fr); min-height: 100vh; }

    /*
     * Below 992 px the menu is Bootstrap's offcanvas-lg drawer. Above that width
     * Bootstrap forces its box transparent, so the colour sits on .sidebar inside.
     */
    .shell__sidebar {
        --bs-offcanvas-width: min(300px, 86vw); --bs-offcanvas-bg: var(--color-surface); --bs-offcanvas-border-width: 0;
        --bs-offcanvas-transition: transform var(--duration) var(--ease);
    }
    .sidebar {
        position: sticky; top: 0; height: 100vh;
        display: flex; flex-direction: column; gap: var(--space-2);
        padding: var(--space-4) var(--space-3);
        background: var(--color-surface);
        border-right: 1px solid var(--color-surface-border);
        overflow-y: auto;
    }
    .sidebar__brand { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3) var(--space-4); color: var(--color-text); }
    .sidebar__brand:hover { text-decoration: none; }
    .brand-mark {
        display: grid; place-items: center; width: 34px; height: 34px; border-radius: 10px;
        background: linear-gradient(135deg, var(--color-primary), var(--color-primary-strong));
        color: #fff; font-weight: 700; font-size: 15px; letter-spacing: -0.02em;
    }
    .no-gradients .brand-mark { background: var(--color-primary); }
    .brand-name { font-weight: 650; font-size: 15px; line-height: 1.15; }
    .brand-name small { display: block; font-weight: 400; font-size: var(--text-xs); }

    .sidebar .nav { gap: 2px; }
    .sidebar .nav-link {
        display: flex; align-items: center; gap: var(--space-3);
        min-height: 38px; padding: 0 var(--space-3);
        border-radius: var(--radius-md);
        color: var(--color-text); font-weight: 500;
        transition: background var(--duration) var(--ease), color var(--duration) var(--ease);
    }
    .sidebar .nav-link .icon { color: var(--color-muted); }
    .sidebar .nav-link:hover { background: var(--color-bg); text-decoration: none; }
    .sidebar .nav-link.active { background: var(--color-primary-soft); color: var(--color-primary-strong); }
    .sidebar .nav-link.active .icon { color: var(--color-primary); }

    .sidebar__footer { margin-top: auto; padding-top: var(--space-3); border-top: 1px solid var(--color-surface-border); }
    .user-chip { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); }
    .avatar {
        display: grid; place-items: center; width: 32px; height: 32px; flex: none; border-radius: 50%;
        background: var(--color-primary-soft); color: var(--color-primary-strong); font-weight: 650; font-size: 13px;
        text-transform: uppercase;
    }
    /* a line each, cut with «…» before the logout button; the whole name and role are in the title */
    .user-chip__name, .user-chip__role { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .user-chip__name { font-weight: 600; line-height: 1.2; }
    .user-chip__role { font-size: var(--text-xs); color: var(--color-muted); }
    .user-chip__text { min-width: 0; flex: 1; }

    .main { min-width: 0; display: flex; flex-direction: column; }
    .topbar {
        position: sticky; top: 0; z-index: 30;
        display: flex; align-items: center; gap: var(--space-4);
        min-height: var(--topbar-height); padding: var(--space-2) var(--space-6);
        border-bottom: 1px solid transparent;
        --glass-bg: var(--color-bg-glass); --glass-solid: var(--color-bg);
    }
    .topbar.is-scrolled { border-bottom-color: var(--color-border); }
    .topbar__search { flex: 1; max-width: 560px; }
    .topbar__actions { margin-left: auto; display: flex; align-items: center; gap: var(--space-2); }

    .content { flex: 1; padding: var(--space-2) var(--space-6) var(--space-8); width: 100%; }
    .content--narrow { max-width: 880px; margin: 0 auto; }
    .content--form { max-width: 960px; }

    .page-header { display: flex; align-items: flex-end; flex-wrap: wrap; gap: var(--space-3) var(--space-6); margin: var(--space-3) 0 var(--space-5); }
    .page-header__titles { min-width: 0; }
    /*
     * the way back stays on one line: the page's own crumb (a client's full name) gives way and is cut
     * at 60ch, the sections before it keep their names, and the page's buttons stay beside the title
     */
    .page-header .breadcrumb { flex-wrap: nowrap; }
    .page-header .breadcrumb-item { flex-shrink: 0; max-width: 60ch; }
    .page-header .breadcrumb-item:last-child { flex-shrink: 1; min-width: 0; }
    .page-header__subtitle { margin-top: 4px; color: var(--color-muted); }
    .page-header__actions { margin-left: auto; display: flex; flex-wrap: wrap; gap: var(--space-2); }

    .tabbar { display: none; }

    @media (max-width: 991.98px) {
        .shell { grid-template-columns: minmax(0, 1fr); }
        .shell__sidebar { box-shadow: var(--shadow-lg); }
        .sidebar { position: static; height: 100%; }
        .topbar { padding: var(--space-2) var(--space-4); }
        .content { padding: var(--space-2) var(--space-4) var(--space-8); }
    }

    /* the search folds behind a button where Bootstrap's sm breakpoint hides the inline one (.d-sm-none on the button) */
    @media (max-width: 575.98px) {
        .topbar__search { display: none; }
        .topbar.has-search-open .topbar__search { display: block; position: absolute; inset: 100% 0 auto 0; padding: var(--space-2) var(--space-4); background: var(--color-bg); }
    }

    @media (max-width: 639px) {
        .content { padding-bottom: calc(var(--tabbar-height) + var(--space-8) + env(safe-area-inset-bottom)); }
        .page-header { margin-top: var(--space-2); }
        .page-header__actions { margin-left: 0; width: 100%; }
        h1 { font-size: 22px; }
        .tabbar {
            position: fixed; left: var(--space-3); right: var(--space-3); bottom: calc(var(--space-3) + env(safe-area-inset-bottom)); z-index: 30;
            display: grid; grid-template-columns: repeat(5, 1fr); align-items: center;
            height: var(--tabbar-height); padding: 6px;
            border: 1px solid var(--color-surface-border); border-radius: 22px; box-shadow: var(--shadow-lg);
            --glass-bg: var(--color-surface-glass); --glass-solid: var(--color-surface);
        }
        .tabbar__item {
            display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
            height: 100%; border: 0; border-radius: 16px; background: none;
            color: var(--color-muted); font-size: 11px; font-weight: 500;
        }
        .tabbar__item:hover { text-decoration: none; }
        .tabbar__item.is-active { color: var(--color-primary-strong); background: var(--color-primary-soft); }
        .tabbar__item--primary .tabbar__bubble {
            display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%;
            background: var(--color-primary); color: #fff; box-shadow: 0 4px 12px var(--color-primary-glow);
        }
    }

    /* Client-facing and sign-in pages: one centred column */
    .public { min-height: 100vh; display: flex; flex-direction: column; align-items: center; padding: 48px var(--space-4) var(--space-8); }
    .public__inner { width: 100%; max-width: 640px; }
    .public__brand { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-6); color: var(--color-text); }
    .auth { min-height: 100vh; display: grid; place-items: center; padding: var(--space-6) var(--space-4); }
    .auth__card { width: 100%; max-width: 400px; }
    .auth__brand { display: flex; flex-direction: column; align-items: center; gap: var(--space-3); margin-bottom: var(--space-6); text-align: center; }
    .auth__brand .brand-mark { width: 52px; height: 52px; border-radius: 16px; font-size: 22px; }
    .gradient-bg { background: radial-gradient(1200px 600px at 100% 0%, var(--color-primary-soft), transparent 60%), var(--color-bg); }
    .no-gradients .gradient-bg { background: var(--color-bg); }
}

/* ---------- Own components: what Bootstrap has no counterpart for ---------- */
@layer components {
    /*
     * Readable shades: a box painting a colour the administrator picks (the panel, the table
     * header, the selected row) gives its content the muted text and links Theme::css() shaded
     * to keep 4.5:1 on that colour. A module's box takes the class; the core's boxes are listed.
     */
    .on-surface, .sidebar, .tabbar {
        --color-muted: var(--color-surface-muted); --bs-secondary-color: var(--color-surface-muted);
    }
    .on-header, .table > thead th, .data-grid .tabulator-header {
        --color-muted: var(--color-header-muted); --bs-secondary-color: var(--color-header-muted);
    }
    .on-row-selected, .table .table-active, .data-grid .tabulator-row.is-selected, .data-grid__card.is-selected {
        --color-muted: var(--color-row-selected-muted); --bs-secondary-color: var(--color-row-selected-muted);
        --color-link: var(--color-row-selected-link);
        --bs-link-color-rgb: var(--color-row-selected-link-rgb); --bs-link-hover-color-rgb: var(--color-row-selected-link-rgb);
    }

    /*
     * A bar the content scrolls under: translucent and blurred, opaque once the theme turns
     * blur off. A bar on another colour than the card's sets the two backgrounds, --glass-bg
     * and --glass-solid; the core's bars are listed.
     */
    .glass, .topbar, .tabbar, .form-actions--sticky {
        background: var(--glass-bg, var(--color-card-glass));
        -webkit-backdrop-filter: saturate(180%) blur(16px); backdrop-filter: saturate(180%) blur(16px);
    }
    .no-blur .glass, .no-blur .topbar, .no-blur .tabbar, .no-blur .form-actions--sticky {
        background: var(--glass-solid, var(--color-card));
        -webkit-backdrop-filter: none; backdrop-filter: none;
    }

    /* a button with no frame until hovered (the top bar, icon actions in rows) */
    .btn--ghost {
        --bs-btn-color: var(--color-text); --bs-btn-bg: transparent; --bs-btn-border-color: transparent;
        --bs-btn-hover-color: var(--color-text); --bs-btn-hover-bg: var(--color-hover-tint); --bs-btn-hover-border-color: transparent;
        --bs-btn-active-color: var(--color-text); --bs-btn-active-bg: var(--color-hover-tint); --bs-btn-active-border-color: transparent;
        --bs-btn-disabled-color: var(--color-text); --bs-btn-disabled-bg: transparent; --bs-btn-disabled-border-color: transparent;
    }
    .btn--icon { --bs-btn-padding-x: 0; width: var(--control-height); }
    .btn--icon.btn-sm { width: var(--control-height-sm); }

    /* a small heading in capitals over what follows (a group of tiles, a label above a value) */
    .eyebrow, .section-title { font-size: var(--text-xs); font-weight: 650; letter-spacing: .04em; text-transform: uppercase; color: var(--color-muted); }
    .section-title { margin: var(--space-6) 0 var(--space-3); }

    .stat { display: flex; flex-direction: column; gap: 6px; padding: var(--space-4) var(--space-5); color: var(--color-text); }
    a.stat:hover { text-decoration: none; border-color: var(--color-border-strong); box-shadow: var(--shadow-md); }
    .stat__label { color: var(--color-muted); font-size: var(--text-sm); }
    .stat__value { font-size: 30px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.1; font-variant-numeric: tabular-nums; }
    .stat__hint { color: var(--color-muted); font-size: var(--text-xs); }
    .stat--warning .stat__value { color: var(--color-warning); }
    .stat--danger .stat__value { color: var(--color-danger); }
    .stat--success .stat__value { color: var(--color-success); }
    /* the one figure a report is about */
    .stat--hero .stat__value { font-size: 48px; line-height: 1.05; letter-spacing: -0.03em; }

    /* a row, though a .card it sits on is a column */
    .tile {
        display: flex; flex-direction: row; align-items: flex-start; gap: var(--space-4); padding: var(--space-5);
        color: var(--color-text); transition: box-shadow var(--duration) var(--ease), border-color var(--duration) var(--ease), transform var(--duration) var(--ease);
    }
    a.tile:hover { text-decoration: none; border-color: var(--color-border-strong); box-shadow: var(--shadow-md); transform: translateY(-1px); }
    /* an icon on a square of its colour: the primary one, or a state's tone */
    .icon-box {
        display: grid; place-items: center; flex: none; width: 44px; height: 44px;
        border-radius: var(--radius-md); background: var(--color-primary-soft); color: var(--color-primary);
    }
    .icon-box .icon { width: 22px; height: 22px; }
    .icon-box--sm { width: 32px; height: 32px; border-radius: var(--radius-sm); }
    .icon-box--sm .icon { width: 18px; height: 18px; }
    .icon-box--success { background: var(--color-success-soft); color: var(--color-success); }
    .icon-box--warning { background: var(--color-warning-soft); color: var(--color-warning); }
    .icon-box--danger { background: var(--color-danger-soft); color: var(--color-danger); }
    .tile__title { font-weight: 650; font-size: var(--text-lg); }
    .tile__text { margin-top: 2px; color: var(--color-muted); font-size: var(--text-sm); }
    .tile__chevron { margin-left: auto; align-self: center; color: var(--color-border-strong); }
    .tile__links { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--space-2); }

    /* a search field with its icon inside */
    .crm-input-icon { position: relative; display: flex; align-items: center; }
    .crm-input-icon > .icon { position: absolute; left: 11px; color: var(--color-muted); pointer-events: none; }
    .crm-input-icon > .form-control { padding-left: 36px; }
    .form-actions--sticky {
        position: sticky; bottom: 0; z-index: 5; margin: var(--space-4) calc(var(--space-5) * -1) calc(var(--space-5) * -1);
        padding: var(--space-3) var(--space-5);
        border-top: 1px solid var(--color-border); border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    }
    @media (max-width: 639px) { .form-actions--sticky { bottom: calc(var(--tabbar-height) + var(--space-3) + env(safe-area-inset-bottom)); } }
    .honeypot { position: absolute !important; left: -10000px !important; width: 1px; height: 1px; overflow: hidden; }

    .row-link { color: var(--color-text); font-weight: 600; }
    /* a table column of action buttons: as narrow as they are, at the row's end */
    .col-actions { width: 1%; white-space: nowrap; text-align: end; }
    /* a code the user writes down or copies (a request number, a recovery code), framed */
    .token-box {
        padding: var(--space-3) var(--space-6); border: 1.5px dashed var(--color-border-strong); border-radius: var(--radius-md);
        font-family: var(--font-mono); font-size: 28px; font-weight: 700; letter-spacing: .06em; overflow-wrap: anywhere; user-select: all;
    }
    /* a <summary> its page draws itself: no marker, the pointer on the whole line */
    .summary-plain { cursor: pointer; list-style: none; }
    .summary-plain::-webkit-details-marker { display: none; }
    .badge--dot::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
    .count { display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px; background: var(--color-chat-new); color: var(--color-chat-new-text); font-size: 11px; font-weight: 700; }
    /*
     * A flex box clips bare text mid-letter, since text-overflow works only inside a block: text of a
     * badge or a tab that can be long goes in a <span> child, which then ends in «…» when the box is
     * narrower (max-width, a table cell).
     */
    .badge > span, .nav-pills .nav-link > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

    .empty { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); padding: 48px var(--space-4); text-align: center; color: var(--color-muted); }
    .empty > .icon { width: 36px; height: 36px; color: var(--color-border-strong); }
    .empty__title { color: var(--color-text); font-weight: 650; font-size: var(--text-lg); }

    /* ---------- Dialogs: a native <dialog> holding Bootstrap's .modal-header, .modal-body and .modal-footer ---------- */
    .dialog {
        --bs-modal-padding: var(--space-5);
        --bs-modal-header-padding-x: var(--space-5);
        --bs-modal-header-padding-y: var(--space-4);
        --bs-modal-header-padding: var(--space-4) var(--space-5);
        --bs-modal-header-border-color: var(--color-border);
        --bs-modal-header-border-width: 1px;
        --bs-modal-footer-gap: var(--space-2);
        --bs-modal-footer-bg: transparent;
        --bs-modal-footer-border-color: var(--color-border);
        --bs-modal-footer-border-width: 1px;
        --bs-modal-title-line-height: 1.3;
        --bs-modal-inner-border-radius: calc(var(--radius-lg) - 1px);
        width: min(560px, calc(100vw - 32px)); max-height: calc(100vh - 48px); padding: 0;
        border: 1px solid var(--color-border); border-radius: var(--radius-lg);
        background: var(--color-card); color: var(--color-text); box-shadow: var(--shadow-lg);
    }
    .dialog--wide { width: min(900px, calc(100vw - 32px)); }
    .dialog::backdrop { background: rgba(0, 0, 0, .32); }
    .dialog[open] { animation: dialog-in var(--duration) var(--ease); }
    .dialog .modal-header { gap: var(--space-3); }
    .dialog .modal-title { font-size: var(--text-lg); font-weight: 650; }
    .dialog .modal-body { overflow-y: auto; max-height: calc(100vh - 200px); }
    .dialog .modal-footer { gap: var(--space-2); padding: var(--space-3) var(--space-5); }
    .dialog .modal-footer > * { margin: 0; }
    @keyframes dialog-in { from { opacity: 0; transform: translateY(6px) scale(.98); } to { opacity: 1; transform: none; } }
    @media (max-width: 639px) {
        .dialog { width: 100vw; max-width: 100vw; max-height: 92vh; margin: auto 0 0; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
        .dialog .modal-body { max-height: calc(92vh - 130px); }
    }

    /* ---------- Popovers and confirmations next to their button (crm.js), toasts in the corner ---------- */
    .crm-popover {
        position: fixed; z-index: 60; min-width: 220px; max-width: min(360px, calc(100vw - 16px)); padding: 6px;
        background: var(--color-card); border: 1px solid var(--color-border); border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
    }
    .crm-confirm { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-2); max-width: 300px; }
    .crm-confirm__text { font-weight: 500; }
    .crm-confirm__actions { display: flex; justify-content: flex-end; gap: var(--space-2); }

    .toast-container { position: fixed; right: var(--space-5); bottom: var(--space-5); max-width: calc(100vw - 2 * var(--space-5)); --bs-toast-spacing: var(--space-2); }
    @media (max-width: 639px) { .toast-container { left: var(--space-3); right: var(--space-3); bottom: calc(var(--tabbar-height) + var(--space-6) + env(safe-area-inset-bottom)); width: auto; max-width: none; } }

    /* a <label> around its file input: a click anywhere picks, the ring shows the keyboard's focus on the input */
    .file-drop { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); padding: var(--space-6); border: 1.5px dashed var(--color-border-strong); border-radius: var(--radius-md); text-align: center; color: var(--color-muted); background: var(--color-card); cursor: pointer; }
    .file-drop:focus-within { border-color: var(--color-primary); box-shadow: 0 0 0 3px var(--color-focus); }
    .file-drop.is-over { border-color: var(--color-primary); background: var(--color-primary-soft); color: var(--color-primary-strong); }
    .file-list { display: flex; flex-direction: column; gap: 6px; }
    .file-item { display: flex; align-items: center; gap: var(--space-2); min-width: 0; padding: 8px 10px; border: 1px solid var(--color-border); border-radius: var(--radius-sm); background: var(--color-card); }
    .file-item__name { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .file-item__size { color: var(--color-muted); font-size: var(--text-xs); white-space: nowrap; }
}

@layer utilities {
    .text-xs { font-size: var(--text-xs); }
    .tabular { font-variant-numeric: tabular-nums; }
}

/* in the layout layer like the shell it changes, so a module's own print rules still win */
@layer layout {
    @media print {
        .shell__sidebar, .topbar, .tabbar, .toast-container { display: none !important; }
        .shell { display: block; }
        body, html { background: #fff; }
        .card { box-shadow: none; border-color: #ccc; }
    }
}
