/* ============================================================
   tos.css - shared design system for app.tosiu.com + hub.tosiu.com
   Single source: /home/tagra/public_html/hub.tagra.it/assets/css/tos.css, symlinked into
   both docroots. Sections 1-31 shared (app-led), 33-34 + legacy appendix hub-only.
   Mobile-first. Pairs with assets/js/tos.js.
   ============================================================ */

/* ---------- 1. Tokens ---------- */
:root {
    --header-h: 56px;
    --subheader-h: 48px;
    --sidebar-w: 264px;

    --surface: #ffffff;
    --bg-page: #f8f9fa;
    --bg-soft: #f9fafb;
    --bg-hover: #f4f4f5;
    --bg-active: #f0f0f1;

    --text: #111318;
    --text-2: #6b7280;
    --text-3: #9ca3af;

    --border: #e5e7eb;
    --border-strong: #d1d5db;
    --neutral-100: #f3f4f6;
    --skeleton: #e9eaec;

    --black: #000000;
    --black-hover: #1f2430;

    --success: #059669;
    --success-bg: #ecfdf5;
    --success-strong: #166534;
    --danger: #dc2626;
    --danger-bg: #fef2f2;
    --warning: #b45309;
    --warning-bg: #fffbeb;
    --info: #2563eb;
    --info-bg: #eff6ff;

    --radius-xs: 6px;
    --radius-sm: 8px;
    --radius: 10px;
    --radius-lg: 14px;
    --radius-sheet: 16px;

    --shadow-1: 0 1px 2px rgba(16, 24, 40, 0.05);
    --shadow-2: 0 4px 16px rgba(16, 24, 40, 0.08);
    --shadow-3: 0 12px 40px rgba(16, 24, 40, 0.16);

    --ring: 0 0 0 3px rgba(17, 19, 24, 0.08);

    --font: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

    /* Hub legacy aliases: consumed only by not-yet-migrated pages + the legacy
       appendix at the bottom of this file. Mapped onto the tokens above so those
       pages stay ~pixel-stable during the migration. Deleted (with the appendix)
       once every hub page is rebuilt onto the shared components. */
    --font-sans: var(--font);
    --white: #ffffff;
    --bg: var(--bg-page);
    --gray-1: #f6f6f6;
    --gray-2: #f3f4f6;
    --gray-3: #cbcbcb;
    --gray-4: #4b4b4b;
    --text-primary: var(--text);
    --text-secondary: var(--text-2);
    --text-muted: var(--text-3);
    --primary: var(--black);
    --sidebar-width: var(--sidebar-w);
    --header-height: var(--header-h);
}

/* ---------- 2. Reset / base ---------- */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

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

body {
    font-family: var(--font);
    font-size: 15px;
    line-height: 1.55;
    color: var(--text);
    background: var(--surface);
    padding-top: var(--header-h);
    /* svh, not vh: on iPad/mobile Chrome 100vh is the LARGE viewport (toolbar hidden),
       taller than the visible area, which made even near-empty pages scrollable by the
       toolbar delta. svh = toolbars-shown height; the vh line is the fallback. */
    min-height: 100vh;
    min-height: 100svh;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
}

body.tos-lock { overflow: hidden; }

img, svg { display: inline-block; vertical-align: middle; }
a { color: inherit; }
button { font-family: inherit; }

/* the display rules above must never beat the hidden attribute */
[hidden] { display: none !important; }

h1, h2, h3, h4, h5, h6 { font-weight: 600; color: var(--text); line-height: 1.3; }

::selection { background: rgba(17, 19, 24, 0.9); color: #fff; }

/* ---------- 3. App shell: header ---------- */
.app-header {
    position: fixed;
    top: 0; left: 0; right: 0;
    height: var(--header-h);
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 8px;
    z-index: 1001;
}

.mobile-menu-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--text);
    cursor: pointer;
    transition: background 0.15s ease;
}
.mobile-menu-toggle:active { background: var(--bg-hover); }

.header-logo {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
}
.header-logo a {
    display: flex;
    align-items: center;
    gap: 8px;
    text-decoration: none;
}
.logo-img { height: 18px; width: auto; display: block; }

.logo-tag {
    display: none;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 2px 7px 1px;
    border-radius: 5px;
    position: relative;
    top: 1px;
    white-space: nowrap;
}
.logo-tag.is-paid { color: #fff; background: var(--black); border: 1px solid var(--black); }
.logo-tag.is-free { color: var(--text); background: var(--surface); border: 1px solid var(--black); }

/* Right cluster: Claude button + account (hub header) */
.header-right { display: flex; align-items: center; gap: 4px; }

/* Claude quick-access button (hub) */
.header-claude-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    padding: 6px 8px;
    color: var(--text-2);
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}
.header-claude-btn:hover { background: var(--bg-hover); color: var(--text); }
.header-claude-btn.active { color: var(--text); background: var(--bg-soft); }
.header-claude-btn svg { flex-shrink: 0; }
.header-claude-label {
    display: none;
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
}

/* Account toggle */
.header-account-menu { position: relative; display: flex; align-items: center; }

.header-account-toggle {
    display: flex;
    align-items: center;
    gap: 10px;
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    padding: 6px;
    cursor: pointer;
    transition: background 0.15s ease;
}
.header-account-toggle:hover { background: var(--bg-hover); }

.header-user-avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--black);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 11px;
    letter-spacing: 0.02em;
    flex-shrink: 0;
}

.header-user-name {
    display: none;
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.header-chevron { display: none; color: var(--text-2); transition: transform 0.2s ease; }
.header-account-menu.open .header-chevron { transform: rotate(180deg); }

/* Account dropdown: bottom sheet on mobile, anchored dropdown on desktop */
.account-scrim {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.45);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease, visibility 0.2s ease;
    z-index: 1002;
}
.account-scrim.active { opacity: 1; visibility: visible; }

.header-account-dropdown {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    background: var(--surface);
    border-radius: 16px 16px 0 0;
    box-shadow: var(--shadow-3);
    padding-bottom: max(8px, env(safe-area-inset-bottom));
    transform: translateY(100%);
    visibility: hidden;
    transition: transform 0.25s cubic-bezier(0.32, 0.72, 0, 1), visibility 0.25s;
    z-index: 1003;
}
.header-account-dropdown.active { transform: translateY(0); visibility: visible; }

/* sheet grab handle (mobile only) */
.header-account-dropdown::before {
    content: '';
    display: block;
    width: 36px;
    height: 4px;
    border-radius: 999px;
    background: var(--border-strong);
    margin: 8px auto 4px;
}

.header-dropdown-plan {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 12px 18px;
    border-bottom: 1px solid var(--border);
}
.header-dropdown-plan-name {
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.header-user-plan {
    display: inline-block;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.6;
    flex-shrink: 0;
}
.header-user-plan.is-paid { background: var(--black); color: #fff; }
.header-user-plan.is-free { background: var(--bg-soft); color: var(--text-2); border: 1px solid var(--border); }

.header-account-dropdown a {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 18px;
    font-size: 14px;
    font-weight: 500;
    color: var(--text);
    text-decoration: none;
    transition: background 0.15s ease;
}
.header-account-dropdown a:hover { background: var(--bg-soft); }
.header-account-dropdown a svg { color: var(--text-2); flex-shrink: 0; }
.header-account-dropdown a.separator-top { border-top: 1px solid var(--border); }
.header-account-dropdown .flag-inline { border-radius: 3px; }

@media (min-width: 992px) {
    .app-header { padding: 0 24px; }
    .mobile-menu-toggle { display: none; }
    .header-logo { position: static; transform: none; }
    .logo-tag { display: inline-block; }
    .header-user-name { display: block; }
    .header-claude-label { display: block; }
    .header-chevron { display: block; }
    .header-account-toggle { padding: 6px 10px; }
    .account-scrim { display: none; }

    .header-account-dropdown {
        position: absolute;
        top: calc(100% + 8px);
        left: auto; right: 0; bottom: auto;
        min-width: 240px;
        border: 1px solid var(--border);
        border-radius: var(--radius);
        box-shadow: var(--shadow-2);
        padding-bottom: 4px;
        transform: translateY(-6px);
        opacity: 0;
        transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
    }
    .header-account-dropdown.active { opacity: 1; transform: translateY(0); }
    .header-account-dropdown::before { display: none; }
    .header-dropdown-plan { background: var(--bg-soft); border-radius: var(--radius) var(--radius) 0 0; }
    .header-account-dropdown a { padding: 10px 16px; }
    .header-account-dropdown a.mobile-only { display: none; }
}

/* ---------- 4. App shell: sidebar ---------- */
.mobile-overlay {
    position: fixed;
    top: var(--header-h);
    left: 0; right: 0; bottom: 0;
    background: rgba(15, 23, 42, 0.45);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.25s ease, visibility 0.25s ease;
    z-index: 999;
}
.mobile-overlay.active { opacity: 1; visibility: visible; }

.sidebar {
    position: fixed;
    top: var(--header-h);
    bottom: 0;
    left: 0;
    width: min(300px, 84vw);
    background: var(--surface);
    border-right: 1px solid var(--border);
    transform: translateX(-100%);
    transition: transform 0.25s cubic-bezier(0.32, 0.72, 0, 1);
    display: flex;
    flex-direction: column;
    z-index: 1000;
}
.sidebar.active { transform: translateX(0); }

.sidebar-nav {
    flex: 1;
    padding: 14px 12px calc(14px + env(safe-area-inset-bottom));
    overflow-y: auto;
    overscroll-behavior: contain;
}
.sidebar-nav::-webkit-scrollbar { width: 6px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

.nav-item {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 44px;
    padding: 9px 12px;
    color: #333a45;
    text-decoration: none;
    border-radius: var(--radius-sm);
    margin-bottom: 2px;
    font-size: 14px;
    font-weight: 500;
    transition: background 0.15s ease, color 0.15s ease;
}
.nav-item svg { width: 17px; height: 17px; flex-shrink: 0; color: #5b6472; transition: color 0.15s ease; }
/* only the bare label span stretches; badges keep their natural width */
.nav-item span:not([class]) { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.nav-item:hover { background: var(--bg-hover); color: var(--text); }
.nav-item:hover svg { color: var(--text); }
.nav-item.active { background: var(--bg-active); color: var(--text); font-weight: 600; }
.nav-item.active svg { color: var(--text); }

.nav-item-expandable { margin-bottom: 2px; }
.nav-item-parent { position: relative; }
.nav-item-chevron {
    width: 14px !important;
    height: 14px !important;
    flex: none;
    color: var(--text-3) !important;
    transition: transform 0.2s ease !important;
}
.nav-item-expandable.expanded .nav-item-chevron { transform: rotate(180deg); }

/* parent highlighted only while collapsed (active child takes over when open) */
.nav-item-expandable.expanded .nav-item-parent.active { background: transparent; font-weight: 500; }

.nav-submenu {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.25s ease;
    margin-left: 20px;
    padding-left: 9px;
    border-left: 1px solid var(--border);
}
.nav-item-expandable.expanded .nav-submenu { max-height: 500px; }

.nav-subitem {
    display: flex;
    align-items: center;
    min-height: 40px;
    padding: 8px 12px;
    color: var(--text-2);
    text-decoration: none;
    border-radius: var(--radius-sm);
    margin-bottom: 1px;
    font-size: 13.5px;
    font-weight: 400;
    transition: background 0.15s ease, color 0.15s ease;
}
.nav-subitem:hover { background: var(--bg-hover); color: var(--text); }
.nav-subitem.active { background: var(--bg-active); color: var(--text); font-weight: 600; }

.nav-updates-badge {
    flex: none;
    background: #dc2626;
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    padding: 1px 7px;
    border-radius: 999px;
    min-width: 18px;
    text-align: center;
    line-height: 16px;
}
.nav-new-badge {
    flex: none;
    background: #009f81;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    padding: 1px 7px;
    border-radius: 999px;
    line-height: 16px;
}
.nav-subitem { gap: 8px; }
.nav-subitem > span:not([class]) { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-subitem > .nav-new-badge, .nav-subitem > .nav-parent-count { margin-left: auto; }
.nav-new-badge.nav-new-badge--alert { background: #dc2626; text-transform: none; letter-spacing: 0; font-size: 11px; }
/* compact count pill on collapsed parents; the child's text badge takes over once open */
.nav-parent-count {
    flex: none;
    background: #dc2626;
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    line-height: 18px;
    min-width: 18px;
    height: 18px;
    padding: 0 6px;
    border-radius: 999px;
    text-align: center;
    margin-right: 2px;
}
.nav-item-expandable.expanded .nav-item-parent > .nav-parent-count { display: none; }

@media (min-width: 992px) {
    .sidebar { width: var(--sidebar-w); transform: none; }
    .mobile-overlay { display: none; }
    .nav-item { min-height: 0; padding: 8px 12px; }
    .nav-subitem { min-height: 0; padding: 7px 12px; }
}

/* header: the right cluster (25 Aug 2026): site tile, "Supporto n" pill, separator, account.
   Square idiom (owner): the site tile is the favicon as a cover background on a
   30px rounded square; the support control is a rounded rectangle with icon,
   label and an inline red count. */
.header-site-btn { position: relative; height: 30px; padding: 0 10px 0 8px; border-radius: 8px; border: 0; background: var(--neutral-100); color: var(--text); display: inline-flex; align-items: center; gap: 6px; text-decoration: none; margin-left: auto; font: 600 13px/30px var(--font); white-space: nowrap; transition: background-color .15s, box-shadow .15s; flex-shrink: 0; }
.header-site-btn svg { flex-shrink: 0; }
.header-site-fav { width: 18px; height: 18px; border-radius: 4px; object-fit: cover; flex-shrink: 0; display: block; }
.header-site-fav + svg { display: none; } /* the favicon replaces the generic icon; a broken image removes itself and the icon returns */
.header-site-btn:hover { background: var(--bg-active); box-shadow: 0 0 0 3px var(--bg-active); }
.header-site-lab { max-width: 220px; overflow: hidden; text-overflow: ellipsis; line-height: 30px; }   /* full line box: overflow:hidden with line-height 1 clipped the descenders */
.header-site-btn ~ .header-support { margin-left: 8px; }
/* the account toggle carries 6px of its own left padding: 12px left + (2px + 6px + 4px) right = centred */
.header-vsep { width: 1px; height: 20px; background: var(--border); margin: 0 2px 0 12px; flex-shrink: 0; }
/* phones: the centred logo would collide with a wider cluster, so the site tile stays desktop-only */
@media (max-width: 767px) { .header-site-btn { display: none; } .header-vsep { margin: 0 2px 0 8px; } .header-site-btn ~ .header-support { margin-left: 0; } }
/* header: support tickets menu (24 Aug 2026) */
/* Sits right before the account menu. The header is flex space-between, so the
   first right-side element takes the auto margin: this one, or the internal
   .ccap-tools when a super-admin machine shows it (two auto margins would
   split the space and centre the wrench). */
.header-support { position: relative; display: flex; align-items: center; margin-right: 0; margin-left: auto; }
.header-support-btn { position: relative; height: 30px; padding: 0 10px 0 8px; border: 0; background: var(--neutral-100); border-radius: 8px; color: var(--text); display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font: 600 13px/30px var(--font); transition: background-color .15s, box-shadow .15s; white-space: nowrap; }
.header-support-btn svg { width: 16px; height: 16px; flex-shrink: 0; }
.header-support-btn:hover, .header-support.open .header-support-btn { background: var(--bg-active); box-shadow: 0 0 0 3px var(--bg-active); }
.header-support-count { min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; background: #dc2626; color: #fff; font: 700 11px/18px var(--font); text-align: center; box-sizing: border-box; margin-left: 2px; }
@media (max-width: 767px) { .header-support-lab { display: none; } .header-support-btn { padding: 0 8px; } }
.header-support > .tos-menu.header-support-menu { width: 460px; max-width: calc(100vw - 16px); padding: 0; overflow: hidden; }
.header-support-head { padding: 12px 14px 8px; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--text-2); }
.header-support-empty { padding: 6px 14px 14px; font-size: 13.5px; color: var(--text-2); }
.header-support-row { display: flex; flex-direction: column; gap: 4px; padding: 10px 14px; border-top: 1px solid var(--border); color: var(--text); text-decoration: none; }
.header-support-row:hover { background: var(--bg-hover); }
.header-support-row.is-unread .header-support-subj::before { content: ''; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #dc2626; margin-right: 8px; vertical-align: 1px; }
.header-support-subj { font-size: 13.5px; font-weight: 600; line-height: 1.4; white-space: normal; overflow-wrap: anywhere; }
.header-support-meta { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-2); }
.header-support-num { font-family: ui-monospace, Menlo, monospace; font-size: 11.5px; }
.header-support-foot { display: flex; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--border); background: var(--bg-soft); }
.header-support-foot .btn { flex: 1; justify-content: center; }
@media (max-width: 767px) {
    /* phone: the menu spans the viewport under the header instead of hanging off the icon */
    .header-support > .tos-menu.header-support-menu { position: fixed; top: calc(var(--header-h) + 4px); left: 8px; right: 8px; width: auto; max-width: none; }
}

/* ---------- 5. App shell: main + footer ---------- */
.app-main { min-height: calc(100vh - var(--header-h)); min-height: calc(100svh - var(--header-h)); display: flex; flex-direction: column; }
.main-content { flex: 1; width: 100%; }

@media (min-width: 992px) {
    .app-main { margin-left: var(--sidebar-w); }
}

.app-footer {
    border-top: 1px solid var(--border);
    padding: 16px 24px;
    margin-top: 64px;
}
.footer-content {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 4px;
}
.footer-tz { color: var(--text-2); font-size: 11px; }
.footer-links { display: flex; align-items: center; gap: 4px; }
.footer-links a { color: var(--text-2); text-decoration: none; font-size: 13px; transition: color 0.15s ease; }
.footer-links a:hover { color: var(--text); }
.footer-separator { color: var(--border-strong); margin: 0 8px; font-size: 13px; }

.footer-language { position: relative; }
.language-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    background: transparent;
    border: none;
    border-radius: var(--radius-xs);
    color: var(--text-2);
    font-size: 13px;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}
.language-toggle:hover { background: var(--bg-hover); color: var(--text); }
.language-toggle img { border-radius: 2px; }

.language-dropdown {
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%) translateY(6px);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-2);
    min-width: 150px;
    padding: 4px;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
    z-index: 1000;
}
.language-dropdown.active,
[data-dropdown].open > .language-dropdown { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }
.language-dropdown .language-option {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 12px;
    background: transparent;
    border: none;
    border-radius: var(--radius-xs);
    text-align: left;
    color: var(--text);
    font-size: 13px;
    cursor: pointer;
    transition: background 0.15s ease;
}
.language-dropdown .language-option:hover { background: var(--bg-hover); }
.language-dropdown .language-option.active { background: var(--bg-active); font-weight: 600; }
.language-dropdown .language-option img { border-radius: 2px; }

/* ---------- 5b. Site subheader (v2/website-subheader.php) ---------- */
.website-subheader {
    position: fixed;
    top: var(--header-h);
    left: 0;
    right: 0;
    height: 48px;
    background: var(--bg-soft);
    border-bottom: 1px solid var(--border);
    padding: 0 16px;
    z-index: 998;
    display: flex;
    align-items: center;
}
@media (min-width: 992px) {
    .website-subheader { left: var(--sidebar-w); padding: 0 24px; }
}
/* track the content-wrapper's side padding on wide screens so the domain/switcher
   line up with the page content below (wrapper jumps to 40px at 1200) */
@media (min-width: 1200px) {
    .website-subheader { padding: 0 40px; }
}

.subheader-content {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    max-width: 1600px;
    margin: 0 auto;
}
.subheader-left { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; }

/* Guide trigger inside the site bar, right-aligned. Sized to sit inside the
   48px bar rather than stretch it, and muted so the domain and status stay the
   subject of the bar. */
.subheader-guide {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
    height: 28px;
    padding: 0 10px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 999px;
    font-family: var(--font);
    font-size: 12.5px;
    font-weight: 500;
    color: var(--text-2);
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
}
.subheader-guide:hover { color: var(--text); border-color: var(--border-strong); }
.subheader-guide svg { width: 14px; height: 14px; flex-shrink: 0; }
.subheader-guide .guide-lbl-short { display: none; }
@media (max-width: 767px) {
    /* The bar is already carrying the domain and the status badge, so the long
       label swaps for the one-word short one. The invisible extension keeps a
       44px thumb target without growing the 48px bar. */
    .subheader-guide { padding: 0 8px; }
    .subheader-guide .guide-lbl-full { display: none; }
    .subheader-guide .guide-lbl-short { display: inline; }
    .subheader-guide::after { content: ''; position: absolute; inset: -8px; }
}

.subheader-logo {
    height: 24px;
    width: auto;
    flex-shrink: 0;
    object-fit: contain;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 2px;
    background: var(--surface);
}

.subheader-domain {
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: color 0.15s ease;
}
.subheader-domain:hover { color: var(--info); }
.subheader-domain-btn { background: none; border: none; padding: 0; font-family: inherit; cursor: pointer; }

.subheader-sep { width: 3px; height: 3px; border-radius: 50%; background: var(--border-strong); flex-shrink: 0; }

.subheader-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 9px;
    border-radius: 999px;
    font-weight: 600;
    font-size: 11px;
    white-space: nowrap;
    flex-shrink: 0;
    border: none;
    font-family: var(--font);
}
.subheader-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
.website-subheader .status-active      { background: var(--success-bg); color: var(--success); }
.website-subheader .status-pending     { background: #fef3c7; color: #d97706; }
.website-subheader .status-inactive    { background: #f3f4f6; color: var(--text-2); }
.website-subheader .status-suspended   { background: var(--danger-bg); color: var(--danger); }
.website-subheader .status-maintenance { background: #fef3c7; color: #b45309; }
.subheader-badge-btn { cursor: pointer; transition: opacity 0.15s ease; }
.subheader-badge-btn:hover { opacity: 0.8; }

.subheader-status-mobile { display: inline-flex; }
.subheader-status-desktop { display: none; }
@media (min-width: 640px) {
    .subheader-status-mobile { display: none; }
    .subheader-status-desktop { display: inline-flex; }
}

/* Switcher: compact Tos.select on desktop, icon button + sheet on mobile */
.subheader-switcher { position: relative; width: 220px; flex-shrink: 0; }
.subheader-switcher .tos-sel-trigger { padding: 5px 12px; font-size: 13px; border-radius: 7px; border-color: var(--border); background: var(--surface); }
.subheader-switcher .tos-sel-panel { min-width: 240px; }
@media (min-width: 768px) {
    .subheader-switcher .tos-sel-panel { left: auto; right: 0; }
}

.subheader-switcher-mobile {
    position: relative;
    display: none;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: 1px solid var(--border-strong);
    border-radius: 7px;
    background: var(--surface);
    color: var(--text);
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.15s ease;
}
/* expand the tap zone to 44px without enlarging the visible box (fits the 48px bar) */
.subheader-switcher-mobile::after { content: ''; position: absolute; inset: -6px; }
.subheader-switcher-mobile:hover { background: var(--bg-hover); }
@media (max-width: 767px) {
    .subheader-switcher { width: 0; }
    .subheader-switcher .tos-sel-trigger { display: none; }
    .subheader-switcher-mobile { display: flex; }
}

/* ---------- 6. Content wrappers ---------- */
.content-wrapper,
.content-wrapper-sm,
.content-wrapper-md,
.content-wrapper-lg,
.content-wrapper-xxl,
.content-wrapper-xxxl,
.content-wrapper-fluid {
    width: 100%;
    margin: 0 auto;
    padding: 20px 16px 40px;
}
.content-wrapper-sm { max-width: 800px; }
.content-wrapper-md { max-width: 1020px; }
.content-wrapper-lg { max-width: 1200px; }
.content-wrapper, .content-wrapper-xxxl { max-width: 1600px; }
.content-wrapper-xxl { max-width: 1400px; }

@media (min-width: 768px) {
    .content-wrapper,
    .content-wrapper-sm,
    .content-wrapper-md,
    .content-wrapper-lg,
    .content-wrapper-xxl,
    .content-wrapper-xxxl,
    .content-wrapper-fluid { padding: 28px 24px 56px; }
}
@media (min-width: 1200px) {
    .content-wrapper,
    .content-wrapper-sm,
    .content-wrapper-md,
    .content-wrapper-lg,
    .content-wrapper-xxl,
    .content-wrapper-xxxl,
    .content-wrapper-fluid { padding: 32px 40px 64px; }
}

.page-head { margin-bottom: 22px; }
.page-head h1 { font-size: 22px; font-weight: 700; letter-spacing: -0.01em; margin-bottom: 3px; }
.page-head p { font-size: 14px; color: var(--text-2); }
@media (min-width: 768px) {
    .page-head h1 { font-size: 24px; }
}

/* ---------- 7. Buttons ---------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 18px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font-family: var(--font);
    font-size: 14px;
    font-weight: 600;
    /* Height is declared, not inherited from the content. A button's box used
       to be padding + whatever it happened to contain, so an icon-only button
       (16px svg) came out ~10px shorter than the identical button with a
       label (19.6px line box) and the two never lined up in a row: the ONE
       size class was not actually one size. min-height, so a wrapping label
       can still grow the box; the px line-height keeps the arithmetic whole
       (20 + 20 padding + 2 border = 42) instead of landing on 41.6. */
    line-height: 20px;
    min-height: 42px;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
    -webkit-tap-highlight-color: transparent;
}
.btn:focus-visible { outline: none; box-shadow: var(--ring); }
.btn:disabled { opacity: 0.6; cursor: not-allowed; }
.btn svg { width: 16px; height: 16px; flex-shrink: 0; }

.btn-primary { background: var(--black); color: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--black-hover); }

.btn-outline {
    background: var(--surface);
    color: var(--text);
    border-color: var(--border-strong);
}
.btn-outline:hover:not(:disabled) { background: var(--bg-soft); border-color: #9ca3af; }

.btn-ghost { background: transparent; color: var(--text-2); }
.btn-ghost:hover:not(:disabled) { background: var(--bg-hover); color: var(--text); }

.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover:not(:disabled) { background: #b91c1c; }

.btn-danger-outline { background: var(--surface); color: var(--danger); border-color: #fca5a5; }
.btn-danger-outline:hover:not(:disabled) { background: var(--danger-bg); border-color: var(--danger); }

/* The size scale: 34 / 42 / 50, each one padding + line-height + border, so a
   labelled and an icon-only button of the same class are the same box. */
.btn-sm { padding: 7px 13px; font-size: 13px; line-height: 18px; min-height: 34px; border-radius: 7px; }
.btn-lg { padding: 13px 26px; font-size: 15px; line-height: 22px; min-height: 50px; border-radius: var(--radius); }
.btn-block { width: 100%; }

/* Mobile touch targets: the canon is >=44px on phones. These lift the shared
   compact controls (and the common bespoke .action-btn icon buttons repeated
   across locations/routes/countries/promo-codes) to a comfortable tap size
   without changing anything on desktop. Uses min-* so nothing ever shrinks. */
@media (max-width: 767px) {
    .btn-sm { min-height: 44px; }
    .action-btn,
    .action-btn-menu { min-width: 44px; min-height: 44px; }
}

/* input-affix action buttons (password eye toggles, copy buttons) to 44px on phones */
@media (max-width: 767px) {
    .input-affix-btn { width: 44px; height: 44px; }
}

/* Consistent keyboard focus ring on the app-shell chrome (buttons already have it) */
.mobile-menu-toggle:focus-visible,
.header-account-toggle:focus-visible,
.tos-modal-x:focus-visible,
.nav-item:focus-visible,
.nav-subitem:focus-visible,
.language-toggle:focus-visible,
.subheader-domain-btn:focus-visible,
.subheader-switcher-mobile:focus-visible {
    outline: none;
    box-shadow: var(--ring);
}

/* ---------- 8. Cards ---------- */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.card-header {
    padding: 16px 18px;
    border-bottom: 1px solid var(--border);
    font-size: 16px;
    font-weight: 600;
}
.card-body { padding: 18px; }
.card-footer {
    padding: 14px 18px;
    border-top: 1px solid var(--border);
    background: var(--bg-soft);
    border-radius: 0 0 var(--radius) var(--radius);
}

@media (min-width: 768px) {
    .card-header { padding: 18px 24px; }
    .card-body { padding: 24px; }
    .card-footer { padding: 16px 24px; }
}

/* Full-bleed cards on phones (app-like) */
@media (max-width: 767px) {
    .card-flush-sm {
        border-left: none;
        border-right: none;
        border-radius: 0;
        margin-left: -16px;
        margin-right: -16px;
    }
    .card-flush-sm .card-footer { border-radius: 0; }

    /* The first flush card in a wrapper carries the page's title in its header
       (these pages have no separate <h1>). Two things go wrong there on phones:
       edge-to-edge, its top border reads as a stray separator under the header
       bar rather than as a card edge; and a 16px header sits one pixel above the
       15px .form-section-title inside it, so the title does not read as the level
       above its own sections. Scoped to :first-child of a wrapper so stacked
       cards (settings/booking-setup components) keep their normal header. */
    :is(.content-wrapper,
        .content-wrapper-sm,
        .content-wrapper-md,
        .content-wrapper-lg,
        .content-wrapper-xxl,
        .content-wrapper-xxxl,
        .content-wrapper-fluid) > .card-flush-sm:first-child {
        border-top: none;
    }
    :is(.content-wrapper,
        .content-wrapper-sm,
        .content-wrapper-md,
        .content-wrapper-lg,
        .content-wrapper-xxl,
        .content-wrapper-xxxl,
        .content-wrapper-fluid) > .card-flush-sm:first-child > .card-header {
        padding-top: 6px;
        font-size: 21px;
        font-weight: 700;
        letter-spacing: -0.02em;
        line-height: 1.25;
    }
}

/* ---------- 9. Forms ---------- */
.form-label {
    display: block;
    font-size: 13px;
    font-weight: 500;
    color: #374151;
    margin-bottom: 6px;
}
.form-label .optional { color: var(--text-3); font-weight: 400; }

/* ---------- iOS zoom-on-focus safety net ----------
   Safari on iOS zooms the whole page when a focused text control renders below
   16px, and the only way back out is a pinch. .form-control below sets 16px,
   but any page that restyles an input with its own class silently opts out, and
   nine such controls had crept in across booking-setup, routes, settings and
   drivers. This is the backstop so it cannot happen again.

   `!important` is deliberate and is the whole point of the rule. Specificity
   alone is not enough: page CSS reaches these controls through ids
   (`.rev-page-box #revPageUrl`), two-class descendants (`.payment-field
   .form-control`) and even inline styles, and a net that loses any of those
   races is not a net. There is no legitimate case for a sub-16px focusable
   input on a touch screen, so there is nothing worth preserving an override
   for. Desktop is untouched, so intentional dense/monospace inputs keep their
   sizing on the screens where they belong.

   NOT solved with `maximum-scale=1` on the viewport meta: that also kills
   pinch-zoom for everyone, which is an accessibility regression.

   WIDTH ALONE IS NOT THE NET (learned on a real iPad, 23 Jul 2026): an iPad is
   820px portrait / 1180px landscape, so a max-width:767px gate leaves every
   hub/app page auto-zooming on iPads — and once iOS zooms, position:fixed
   headers visually scroll away and the whole site feels broken. The gate is
   therefore width OR coarse pointer: any touch device gets 16px at any width. */
@media (max-width: 767px), (pointer: coarse) {
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="color"]):not([type="image"]),
    select,
    textarea {
        font-size: 16px !important;
    }
}

.form-control,
.form-select {
    display: block;
    width: 100%;
    font-family: var(--font);
    font-size: 16px; /* 16px stops iOS zoom-on-focus */
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    padding: 10px 14px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    appearance: none;
    -webkit-appearance: none;
}
.form-control:focus, .form-select:focus {
    outline: none;
    border-color: var(--text);
    box-shadow: var(--ring);
}
.form-control::placeholder { color: var(--text-3); }
.form-control[readonly] { background: var(--bg-soft); color: var(--text-2); cursor: not-allowed; }

.form-select {
    padding-right: 40px;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M6 9l6 6 6-6'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right 12px center;
    cursor: pointer;
}

@media (min-width: 768px) {
    .form-control, .form-select { font-size: 14.5px; }
}

.form-hint { font-size: 12.5px; color: var(--text-2); margin-top: 6px; }

/* input with trailing icon/button */
.input-affix { position: relative; }
.input-affix .form-control { padding-right: 44px; }
.input-affix-btn {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    background: transparent;
    border: none;
    border-radius: var(--radius-xs);
    color: var(--text-2);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}
.input-affix-btn:hover { background: var(--bg-hover); color: var(--text); }
.input-affix-icon {
    position: absolute;
    top: 50%;
    right: 14px;
    transform: translateY(-50%);
    color: var(--text-3);
    pointer-events: none;
}

/* form layout */
.form-grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 768px) {
    .form-grid { grid-template-columns: 1fr 1fr; gap: 18px 20px; }
    .form-grid .span-2 { grid-column: span 2; }
}

.form-section + .form-section {
    margin-top: 28px;
    padding-top: 24px;
    border-top: 1px solid var(--border);
}
.form-section-title {
    font-size: 15px;
    font-weight: 600;
    margin-bottom: 16px;
}

/* switch */
.switch {
    appearance: none;
    -webkit-appearance: none;
    width: 44px;
    height: 25px;
    border-radius: 999px;
    background: var(--border-strong);
    border: none;
    position: relative;
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.2s ease;
}
.switch::after {
    content: '';
    position: absolute;
    top: 3px;
    left: 3px;
    width: 19px;
    height: 19px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
    transition: transform 0.2s ease;
}
.switch:checked { background: var(--black); }
.switch:checked::after { transform: translateX(19px); }
.switch:focus-visible { outline: none; box-shadow: var(--ring); }
.switch:disabled { opacity: 0.55; cursor: not-allowed; }

.switch-row { display: flex; align-items: flex-start; gap: 12px; }
.switch-row-label { cursor: pointer; }
.switch-row-label strong { display: block; font-size: 14px; font-weight: 600; color: var(--text); }
.switch-row-label small { display: block; font-size: 13px; color: var(--text-2); line-height: 1.5; margin-top: 2px; }

/* ---------- 10. Badges ---------- */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.6;
    white-space: nowrap;
}
.badge svg { width: 11px; height: 11px; }
.badge-success { background: var(--success-bg); color: var(--success-strong); }
.badge-warning { background: #fef3c7; color: #92400e; }
.badge-danger { background: #fee2e2; color: #991b1b; }
.badge-info { background: var(--info-bg); color: #1e40af; }
.badge-neutral { background: #f3f4f6; color: #4b5563; }
.badge-dark { background: var(--black); color: #fff; }

/* ---------- 11. Alerts ---------- */
.alert {
    display: block;
    padding: 14px 16px;
    border-radius: var(--radius);
    font-size: 14px;
    line-height: 1.55;
}
.alert ul { margin: 6px 0 0; padding-left: 18px; }
.alert-info { background: var(--info-bg); color: #1e3a8a; }
.alert-success { background: var(--success-bg); color: #065f46; }
.alert-warning { background: var(--warning-bg); color: #92400e; }
.alert-danger { background: var(--danger-bg); color: #991b1b; }

/* ---------- 12. Tables (base for later pages) ---------- */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table { width: 100%; border-collapse: collapse; }
.table thead th {
    background: var(--bg-soft);
    color: var(--text-2);
    font-weight: 600;
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    text-align: left;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}
.table tbody td {
    padding: 14px 16px;
    border-bottom: 1px solid var(--border);
    font-size: 14px;
    vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: none; }
.table-hover tbody tr:hover { background: var(--bg-soft); }

/* ---------- 13. Modal (Tos.modal) ---------- */
.tos-modal {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}
.tos-modal[hidden] { display: none; }

.tos-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, 0.5);
    opacity: 0;
    transition: opacity 0.2s ease;
}
.tos-modal.is-open .tos-modal-backdrop { opacity: 1; }

.tos-modal-card {
    position: relative;
    background: var(--surface);
    border-radius: var(--radius-lg);
    width: 100%;
    max-width: 420px;
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    box-shadow: var(--shadow-3);
    opacity: 0;
    transform: scale(0.96) translateY(8px);
    transition: opacity 0.2s ease, transform 0.2s ease;
}
/* the open state must end at transform:none, NOT scale(1): any lingering
   transform makes the card the containing block for position:fixed children
   (select panels/sheets would get trapped inside the modal) */
.tos-modal.is-open .tos-modal-card { opacity: 1; transform: none; }

.tos-modal-md .tos-modal-card { max-width: 560px; }
.tos-modal-lg .tos-modal-card { max-width: 720px; }
/* xl (25 Aug 2026): record drawers that carry several sections side by side
   (the customer card with its reserved-area block) breathe at ~1000px. */
.tos-modal-xl .tos-modal-card { max-width: 1000px; }

/* ----- Pinned header + footer, scrolling body (ALL viewports) -----
   The card is `max-height: calc(100vh - 32px); overflow-y: auto`, so a card
   taller than the screen used to scroll as ONE box: on a long form (the
   "Nuovo cliente" modal is the canonical case) the title scrolled off the top
   and Annulla / Crea cliente sat below the fold, so the primary action of the
   modal was invisible until you scrolled. The body is what should scroll.

   These rules were mobile-only (the bottom-sheet block below); they are
   hoisted here because the failure is identical on desktop. bookings/
   view-details.php has done exactly this in page CSS since it shipped, and
   that is the modal that reads as correct.

   Two card shapes exist in this codebase and each is matched EXPLICITLY,
   never with a blanket "everything that is not the header scrolls":
     A. header + .tos-modal-body + footer  (the common case)
     B. header + one injected wrapper      (#viewModalContent, AJAX, <form>)
   A blanket rule would also hit the hand-rolled cards in website/routes
   (.bulk-header/.bulk-controls/.bulk-body/.bulk-footer), turning all four
   children into competing scrollers. Those match neither shape, so they keep
   the whole-card scroll they have today. Tos.dialog cards are excluded on
   both counts: they are short and centered by design. */

/* Shape A */
.tos-modal > .tos-modal-card:not(.tos-dialog-card):has(> .tos-modal-body) {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.tos-modal > .tos-modal-card:not(.tos-dialog-card):has(> .tos-modal-body) > .tos-modal-header,
.tos-modal > .tos-modal-card:not(.tos-dialog-card):has(> .tos-modal-body) > .tos-modal-footer {
    flex: 0 0 auto;
}
.tos-modal > .tos-modal-card:not(.tos-dialog-card):has(> .tos-modal-body) > .tos-modal-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}

/* Shape B: `header + *:last-child` is exactly the two-child card (an injected
   #viewModalContent div, or a <form> wrapping the fields) and nothing else.
   The routes cards have 3 and 4 children and do not lead with a
   .tos-modal-header, so they stay out of this on both counts. */
.tos-modal > .tos-modal-card:not(.tos-dialog-card):has(> .tos-modal-header + *:last-child) {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.tos-modal > .tos-modal-card:not(.tos-dialog-card):has(> .tos-modal-header + *:last-child) > .tos-modal-header {
    flex: 0 0 auto;
}
.tos-modal > .tos-modal-card:not(.tos-dialog-card):has(> .tos-modal-header + *:last-child) > .tos-modal-header + * {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}

/* Shape B, refined: when that wrapper is a <form> holding its own body and
   footer (the long edit forms on locations / countries / promo-codes /
   help-center / routes), pass the flex column through it so the Save button
   pins to the bottom of the card instead of scrolling away below the fields.
   Without this the wrapper itself scrolls and the footer goes with it, which
   on a 20-field form means a long scroll to reach Save. */
.tos-modal > .tos-modal-card:not(.tos-dialog-card):has(> .tos-modal-header + *:last-child) > .tos-modal-header + *:has(> .tos-modal-body) {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.tos-modal > .tos-modal-card:not(.tos-dialog-card) > .tos-modal-header + *:has(> .tos-modal-body) > .tos-modal-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}
.tos-modal > .tos-modal-card:not(.tos-dialog-card) > .tos-modal-header + *:has(> .tos-modal-body) > .tos-modal-footer {
    flex: 0 0 auto;
}

/* The pinned header needs a hairline once content slides under it. */
.tos-modal > .tos-modal-card:not(.tos-dialog-card):has(> .tos-modal-body) > .tos-modal-header,
.tos-modal > .tos-modal-card:not(.tos-dialog-card):has(> .tos-modal-header + *:last-child) > .tos-modal-header {
    padding-bottom: 14px;
    border-bottom: 1px solid var(--border);
}

/* Sheet variant: on phones EVERY content modal slides up from the bottom with a
   grab handle. This is the default now (was opt-in via .tos-modal--sheet). Two
   escape hatches stay centered: Tos.dialog cards (small confirm/alert, matched
   with :has()) and anything explicitly tagged .tos-modal--center. */
@media (max-width: 767px) {
    .tos-modal:not(.tos-modal--center):not(:has(.tos-dialog-card)) {
        align-items: flex-end;
        padding: 0;
    }
    .tos-modal:not(.tos-modal--center) > .tos-modal-card:not(.tos-dialog-card) {
        max-width: none;
        width: 100%;
        border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
        padding-bottom: env(safe-area-inset-bottom);
        transform: translateY(30px);
        /* 92vh left only ~68px of backdrop on a 844px screen, so a long modal
           read as a full-screen takeover rather than a sheet over the page.
           dvh (with a vh fallback) because mobile browser chrome makes vh lie. */
        max-height: 85vh;
        max-height: 85dvh;
    }
    .tos-modal:not(.tos-modal--center) > .tos-modal-card:not(.tos-dialog-card)::before {
        content: '';
        display: block;
        width: 36px;
        height: 4px;
        border-radius: 999px;
        background: var(--border-strong);
        background-clip: padding-box;
        margin: 8px auto 0;
        flex: 0 0 auto;
    }
    .tos-modal:not(.tos-modal--center).is-open > .tos-modal-card:not(.tos-dialog-card) { transform: none; }

    /* A real bottom sheet scrolls its BODY, not the whole card, so the grab
       handle and the title do not scroll away with the content. That is now
       the base behaviour on every viewport (shape A / shape B rules above);
       only the sheet chrome is left here. */
}

.tos-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 18px 20px 0;
}
.tos-modal-title { font-size: 17px; font-weight: 700; }
.tos-modal-x {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--text-3);
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.15s ease, color 0.15s ease;
}
.tos-modal-x:hover { background: var(--bg-hover); color: var(--text); }
.tos-modal-body { padding: 16px 20px 20px; }
.tos-modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding: 12px 20px 20px;
    position: relative;
}
/* The pinned footer needs its own hairline, for the same reason the pinned
   header does: content scrolls under it. `:not(:empty)` because Tos.select's
   filter sheet ships an empty footer it fills later, and a stray line above
   nothing reads as a rendering bug. No position: sticky anywhere here: the
   shape rules above make the card a flex column, so the footer is already
   pinned as a non-shrinking flex item, and sticky inside an overflow:hidden
   parent would do nothing anyway. */
.tos-modal-footer:not(:empty) { border-top: 1px solid var(--border); }
/* Scroll fade. The body is clipped by the pinned footer, so mid-scroll a line
   of text was being guillotined horizontally through the glyphs, which is the
   single thing that made a long modal look broken. This dissolves it into the
   surface instead. It pairs with the body's padding-bottom: at full scroll the
   fade covers only that padding, never the last line. */
.tos-modal-footer:not(:empty)::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    height: 28px;
    background: linear-gradient(to top, var(--surface), transparent);
    pointer-events: none;
}
/* Breathing room so the final line clears the fade when scrolled to the end. */
.tos-modal-body { padding-bottom: 32px; }
/* Three-button footers (Close + WhatsApp + Copy link) are wider than a 360px
   sheet, and without wrapping the leftmost button loses its edge. */
@media (max-width: 767px) {
    .tos-modal-footer { flex-wrap: wrap; }
}

/* ---------- 14. Dialog (Tos.dialog / confirm / alert) ---------- */
.tos-dialog-card { text-align: center; padding: 28px 24px 24px; }
.tos-dialog-icon {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 16px;
}
.tos-dialog-icon svg { width: 28px; height: 28px; }
.tos-dialog-icon.icon-success { background: var(--success-bg); color: var(--success); }
.tos-dialog-icon.icon-error { background: var(--danger-bg); color: var(--danger); }
.tos-dialog-icon.icon-warning { background: var(--warning-bg); color: #d97706; }
.tos-dialog-icon.icon-info { background: var(--info-bg); color: var(--info); }
.tos-dialog-icon.icon-question { background: #f3f4f6; color: #6b7280; }

.tos-dialog-title { font-size: 18px; font-weight: 700; margin-bottom: 8px; }
.tos-dialog-text { font-size: 14px; color: var(--text-2); line-height: 1.6; }
.tos-dialog-actions {
    display: flex;
    flex-direction: column-reverse;
    gap: 10px;
    margin-top: 22px;
}
.tos-dialog-actions .btn { width: 100%; }
@media (min-width: 480px) {
    .tos-dialog-actions { flex-direction: row; justify-content: center; }
    .tos-dialog-actions .btn { width: auto; min-width: 110px; }
}

/* ---------- 15. Toasts ---------- */
.tos-toast-stack {
    position: fixed;
    top: calc(var(--header-h) + 10px);
    left: 12px;
    right: 12px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    z-index: 1400;
    pointer-events: none;
}
@media (min-width: 768px) {
    .tos-toast-stack { left: auto; right: 20px; align-items: flex-end; }
}

.tos-toast {
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: 400px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-2);
    padding: 11px 16px;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--text);
    pointer-events: auto;
    opacity: 0;
    transform: translateY(-8px);
    transition: opacity 0.2s ease, transform 0.2s ease;
}
.tos-toast.is-in { opacity: 1; transform: translateY(0); }
.tos-toast svg { width: 17px; height: 17px; flex-shrink: 0; }
.tos-toast-success svg { color: var(--success); }
.tos-toast-error svg { color: var(--danger); }
.tos-toast-warning svg { color: #d97706; }
.tos-toast-info svg { color: var(--info); }

/* ---------- 16. Tooltip ---------- */
.tos-tooltip {
    position: fixed;
    z-index: 1500;
    max-width: 260px;
    background: #0f172a;
    color: #e2e8f0;
    font-size: 12px;
    font-weight: 500;
    line-height: 1.55;
    padding: 8px 11px;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-3);
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.12s ease;
}
.tos-tooltip.is-in { opacity: 0.98; }
.tos-tooltip-content { white-space: pre-line; }
.tos-tooltip code {
    display: inline-block;
    background: #1e293b;
    color: #fbbf24;
    border: 1px solid #334155;
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 11px;
    font-family: ui-monospace, monospace;
}
.tos-tooltip-arrow {
    position: absolute;
    width: 8px;
    height: 8px;
    background: #0f172a;
    transform: rotate(45deg);
}
[data-tip] { cursor: default; }
/* a tooltip must not steal the pointer from something clickable (20 Aug 2026:
   the toolbar icon buttons on /work-plan showed the arrow cursor) */
button[data-tip]:not(:disabled), a[data-tip], .btn[data-tip]:not(:disabled), [role="button"][data-tip], label[data-tip] { cursor: pointer; }

/* ---------- 17. Popover ---------- */
.tos-popover {
    position: fixed;
    z-index: 1300;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-2);
    padding: 14px 16px;
    max-width: 300px;
    font-size: 13.5px;
    color: var(--text);
    opacity: 0;
    transform: translateY(-4px);
    transition: opacity 0.15s ease, transform 0.15s ease;
}
.tos-popover.is-in { opacity: 1; transform: translateY(0); }
.tos-popover-title { font-size: 13.5px; font-weight: 600; margin-bottom: 4px; }

/* ---------- 18. Dropdown menu (Tos generic) ---------- */
[data-dropdown] { position: relative; }
.tos-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 180px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-2);
    padding: 4px;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-4px);
    transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
    z-index: 1100;
}
[data-dropdown].open > .tos-menu { opacity: 1; visibility: visible; transform: translateY(0); }
.tos-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 12px;
    background: transparent;
    border: none;
    border-radius: var(--radius-xs);
    font-size: 13.5px;
    font-weight: 500;
    color: var(--text);
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s ease;
}
.tos-menu-item:hover { background: var(--bg-hover); }
.tos-menu-item.danger { color: var(--danger); }

/* ---------- 19. Language options (modal) ---------- */
.language-options { display: flex; flex-direction: column; gap: 8px; }
.language-option-btn {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 13px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-family: var(--font);
    font-size: 15px;
    font-weight: 500;
    color: var(--text);
    cursor: pointer;
    text-align: left;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.language-option-btn img { border-radius: 3px; flex-shrink: 0; }
.language-option-btn span { flex: 1; }
.language-option-btn .checkmark { opacity: 0; color: var(--text); flex-shrink: 0; }
.language-option-btn:hover { background: var(--bg-soft); border-color: var(--border-strong); }
.language-option-btn.active { border-color: var(--text); background: var(--bg-soft); font-weight: 600; }
.language-option-btn.active .checkmark { opacity: 1; }

/* ---------- 19b. Custom select (Tos.select) ---------- */
.tos-sel { position: relative; }
.tos-sel-native { display: none !important; }

.tos-sel-trigger {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 10px 14px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    font-family: var(--font);
    font-size: 16px;
    color: var(--text);
    line-height: 1.5;
    text-align: left;
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
@media (min-width: 768px) {
    .tos-sel-trigger { font-size: 14.5px; }
}
.tos-sel-trigger:hover { border-color: #9ca3af; }
.tos-sel-trigger:focus-visible,
.tos-sel.is-open .tos-sel-trigger {
    outline: none;
    border-color: var(--text);
    box-shadow: var(--ring);
}
.tos-sel-trigger-img { width: 21px; height: 15px; border-radius: 2px; object-fit: cover; flex-shrink: 0; }
.tos-sel-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tos-sel-label.is-placeholder { color: var(--text-3); }
.tos-sel-caret { flex-shrink: 0; color: var(--text-2); transition: transform 0.2s ease; }
.tos-sel.is-open .tos-sel-caret { transform: rotate(180deg); }

/* multi-select: chips inside the trigger */
.tos-sel-trigger--multi {
    flex-wrap: nowrap;
    align-items: flex-start;
    min-height: 44px;
    padding: 6px 12px 6px 7px;
}
.tos-sel-trigger--multi .tos-sel-caret { margin-top: 8px; }
.tos-sel-tags {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 5px;
}
.tos-sel-tags .tos-sel-label { padding: 3px 0 3px 7px; }
.tos-sel-tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: #f3f4f6;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 3px 6px 3px 8px;
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
    max-width: 100%;
}
.tos-sel-tag-img { width: 17px; height: 12px; border-radius: 2px; object-fit: cover; flex-shrink: 0; }
.tos-sel-tag-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tos-sel-tag-x {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 17px;
    height: 17px;
    border-radius: 4px;
    color: var(--text-3);
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.12s ease, color 0.12s ease;
}
.tos-sel-tag-x:hover { background: #e5e7eb; color: var(--text); }
/* in multi mode a selected option can be tapped again to deselect */
.tos-sel--multi .tos-sel-option.is-selected { background: var(--bg-soft); }
.tos-sel--multi .tos-sel-option.is-selected.is-active { background: var(--bg-hover); }

/* backdrop: only used in sheet mode */
.tos-sel-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.45);
    opacity: 0;
    transition: opacity 0.2s ease;
    z-index: 1190;
}

.tos-sel-panel {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 1195;
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-2);
    /* CLOSED = display:none (20 Aug 2026). A visibility:hidden absolute panel
       is still laid out, so every select near the foot of a modal added ~140px
       of phantom scroll to the modal body (measured on /project). The open
       state fades in with a keyframe instead of a transition; closing is
       instant, which nobody perceives. */
    display: none;
}
@keyframes tos-sel-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.tos-sel.is-open .tos-sel-panel { display: flex; animation: tos-sel-in 0.15s ease; }

.tos-sel-head { display: none; }

.tos-sel-search {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
    color: var(--text-3);
    flex-shrink: 0;
}
.tos-sel-search input {
    flex: 1;
    min-width: 0;
    border: none;
    outline: none;
    background: transparent;
    font-family: var(--font);
    font-size: 16px;
    color: var(--text);
}
@media (min-width: 768px) {
    .tos-sel-search input { font-size: 14px; }
}
.tos-sel-search input::placeholder { color: var(--text-3); }

.tos-sel-list {
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    max-height: 264px;
    padding: 5px;
}
.tos-sel-group {
    padding: 10px 11px 4px;
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-3);
}
.tos-sel-option {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 11px;
    border-radius: var(--radius-xs);
    font-size: 14px;
    color: #374151;
    cursor: pointer;
}
.tos-sel-option.is-active { background: var(--bg-hover); color: var(--text); }
.tos-sel-option.is-selected { font-weight: 600; color: var(--text); }
.tos-sel-option.is-disabled { opacity: 0.45; cursor: not-allowed; }
.tos-sel-img { width: 21px; height: 15px; border-radius: 2px; object-fit: cover; flex-shrink: 0; }
.tos-sel-opt-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* opt-in wrapping (Tos.select {wrap:true}): sentence-length options */
.tos-sel--wrap .tos-sel-label,
.tos-sel--wrap .tos-sel-opt-label { white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.35; text-align: left; }
.tos-sel--wrap .tos-sel-trigger { align-items: flex-start; }
.tos-sel--wrap .tos-sel-trigger .tos-sel-caret { margin-top: 3px; }
.tos-sel--wrap .tos-sel-option { align-items: flex-start; }
.tos-sel--wrap .tos-sel-option .tos-sel-check { margin-top: 2px; }
.tos-sel-check { flex-shrink: 0; color: var(--text); opacity: 0; }
.tos-sel-option.is-selected .tos-sel-check { opacity: 1; }

/* sheet mode on phones */
@media (max-width: 767px) {
    .tos-sel.is-open .tos-sel-backdrop { display: block; opacity: 1; }
    .tos-sel-panel {
        position: fixed;
        top: auto;
        left: 0;
        right: 0;
        bottom: 0;
        border: none;
        border-radius: 16px 16px 0 0;
        box-shadow: var(--shadow-3);
        max-height: 78vh;
        padding-bottom: env(safe-area-inset-bottom);
        z-index: 1200;
    }
    @keyframes tos-sel-in-sheet { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: none; } }
    .tos-sel.is-open .tos-sel-panel { animation: tos-sel-in-sheet 0.2s ease; }
    .tos-sel-head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 10px;
        padding: 14px 16px 10px;
        flex-shrink: 0;
    }
    .tos-sel-head::before {
        content: '';
        position: absolute;
        top: 6px;
        left: 50%;
        transform: translateX(-50%);
        width: 36px;
        height: 4px;
        border-radius: 999px;
        background: var(--border-strong);
    }
    .tos-sel-head-title { font-size: 16px; font-weight: 700; }
    .tos-sel-x {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        background: transparent;
        border: none;
        border-radius: var(--radius-sm);
        color: var(--text-3);
        cursor: pointer;
    }
    .tos-sel-search { padding: 10px 16px; }
    .tos-sel-list { max-height: none; flex: 1; padding: 6px 8px; }
    .tos-sel-option { padding: 12px; font-size: 15px; }
}
@media (min-width: 768px) {
    .tos-sel-x { display: none; }
}

/* ---------- 19c. Checkbox ---------- */
.checkbox {
    width: 18px;
    height: 18px;
    accent-color: var(--black);
    cursor: pointer;
    flex-shrink: 0;
}

/* ---------- 20. Utilities ---------- */
.mobile-only { display: none !important; }
.desktop-only { display: block !important; }
@media (max-width: 767px) {
    .mobile-only { display: flex !important; }
    .desktop-only { display: none !important; }
    .app-footer { display: none !important; }
}

.text-muted { color: var(--text-2) !important; }
.text-end { text-align: right !important; }
.text-center { text-align: center !important; }
.w-100 { width: 100% !important; }
.fw-600 { font-weight: 600 !important; }
.d-none { display: none !important; }

.flag-inline { border-radius: 3px; }

/* intl-tel-input plugin fit */
.iti { width: 100%; display: block; }
.iti__input { width: 100%; }
.iti__country-list {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-2);
    margin-top: 4px;
    max-height: 260px;
    font-family: var(--font);
}
.iti__country { padding: 9px 12px; font-size: 14px; }
.iti__country.iti__highlight { background: var(--bg-hover); }
.iti__dial-code { color: var(--text-2); }
.iti__selected-flag { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.iti__selected-flag:hover, .iti__selected-flag:focus { background: var(--bg-hover); }
.iti--separate-dial-code .iti__selected-flag { background: var(--bg-soft); border-right: 1px solid var(--border); }
.iti--separate-dial-code .iti__selected-dial-code { font-size: 14px; }

/* ============================================================
   Shared list / CRUD components. Every list page used to
   re-implement these locally with hardcoded colors; these are
   the canonical, token-driven versions. Collision-free names,
   so adding them is inert until a page opts in.
   ============================================================ */

/* ---------- 21. Page toolbar (title row + actions) ---------- */
.page-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px 16px;
    margin-bottom: 20px;
}
.page-toolbar-title { font-size: 22px; font-weight: 700; letter-spacing: -0.01em; }
@media (min-width: 768px) { .page-toolbar-title { font-size: 24px; } }
.page-toolbar-actions { display: flex; align-items: center; gap: 10px; }
/* One toolbar, one button size, and the compact one wins. Pages mix `btn-sm`
   secondaries (export, guide, numbering) with a full-size `btn-primary`
   new-record button; side by side that is 34px against 42px and reads as a
   mistake. Worse, an ICON-ONLY btn-sm (the numbering gear) is shorter again at
   ~32px, because its height comes from the 16px svg while its neighbours get
   the 18.2px text line box, so a toolbar could show three different heights.

   So the toolbar sets the size itself instead of trusting whatever classes a
   page happened to use: an explicit `height` (not padding) is what guarantees
   text buttons and icon buttons agree, since height no longer depends on the
   content box. Icon-only buttons then go square via :has, which is already
   used elsewhere in this file. Doing it here rather than in the 20-odd page
   templates is also what keeps the next new page from reintroducing it.

   Scoped to >=768px: the mobile rules below deliberately re-size these
   (secondaries collapse to 36px icon squares) and must keep winning. */
@media (min-width: 768px) {
    .page-toolbar-actions .btn,
    .page-toolbar-actions .advanced-filters-btn {
        height: 34px;
        min-height: 0;
        padding: 0 13px;
        font-size: 13px;
        border-radius: 7px;
    }
    .page-toolbar-actions .btn svg,
    .page-toolbar-actions .advanced-filters-btn svg { width: 15px; height: 15px; }
    /* Icon-only: square, so it reads as a peer of the labelled buttons rather
       than a stubby version of one. Marked with a class, NOT `:has(>
       svg:only-child)` — a label echoed straight into the button is a text
       node, which :only-child does not count, so the :has form would also
       catch every icon+label button and crush it to 34px wide. */
    .page-toolbar-actions .btn-icon { width: 34px; padding: 0; }
}
/* Mobile toolbar: title and actions share ONE line.
   Measured at 390px the content column is 358px, while titles run to 301px
   ("Gestisci richieste di contatto") and primary buttons to 191px ("Nuovo
   documento"). Full labels therefore cannot coexist on a line at any size, and
   the actions were dropping to a row of their own and eating vertical space on
   the screen where it is scarcest.

   The rule is: a phone toolbar shows exactly ONE labelled action, and every
   other control collapses to its icon. Verified first that every secondary
   button in .page-toolbar-actions actually carries an svg, so none of them
   collapses to an empty square.

   `flex: 1 1 0` on the title is what guarantees the single line: flex wrapping
   breaks lines on hypothetical main size, so a content-sized title would still
   shove the actions onto row two. A zero flex-basis makes the title claim no
   width up front, then grow into whatever is left, truncating instead of
   wrapping the row. Anything else in the toolbar (the preset chip rows) no
   longer fits beside them and wraps below on its own, which is where it wants
   to be anyway. */
@media (max-width: 767px) {
    /* Some toolbars carry a third child between the title and the actions
       (fleet's Veicoli/Documenti tabs, the preset chip rows). In source order
       that child pairs with the title and pushes the actions to row two, so the
       row is ordered explicitly: title, actions, then everything else below. */
    .page-toolbar > * { order: 2; }
    .page-toolbar > .page-toolbar-title { order: 0; }
    .page-toolbar > .page-toolbar-actions { order: 1; }
    /* countries and locations wrap the title in a group div (it carries an
       extra badge alongside), so the title is a grandchild and the plain child
       selector above misses it. Match whichever child holds the title. */
    .page-toolbar > :has(.page-toolbar-title) {
        order: 0;
        flex: 1 1 0;
        min-width: 0;
    }

    .page-toolbar-title {
        font-size: 18px;
        flex: 1 1 0;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .page-toolbar-actions {
        width: auto;
        flex-wrap: nowrap;
        flex-shrink: 0;
        gap: 8px;
    }
    .page-toolbar-actions .btn,
    .page-toolbar-actions .filter-toggle {
        min-height: 36px;
        height: 36px;
    }
    .page-toolbar-actions .btn-primary {
        padding: 0 12px;
        font-size: 12.5px;
    }
    /* Everything that is not the primary action keeps only its icon.
       font-size:0 is what hides the bare text nodes: the labels are echoed
       straight into the button, not wrapped in an element we could target. */
    .page-toolbar-actions .btn:not(.btn-primary),
    .page-toolbar-actions .filter-toggle {
        width: 36px;
        padding: 0;
        gap: 0;
        justify-content: center;
        font-size: 0;
    }
    .page-toolbar-actions .filter-count { font-size: 10px; }

    /* A [data-tb-keep] action stays in the toolbar but drops its label, so the
       page keeps a visible one-tap primary action without the words that made
       the row wrap. font-size:0 hides the bare text node; the svg is sized
       explicitly because it would otherwise inherit that zero. */
    .page-toolbar-actions .btn-primary[data-tb-keep] {
        width: 36px;
        padding: 0;
        gap: 0;
        justify-content: center;
        font-size: 0;
    }
    .page-toolbar-actions .btn-primary[data-tb-keep] svg { width: 18px; height: 18px; }

    /* ---- Mobile toolbar sheet ----
       tos.js moves the chips, the filter card and the page actions into a
       bottom sheet, leaving the toolbar as title + one control. The page's own
       "Filtri" button is hidden rather than intercepted, so its click handler
       never fires and each page's filter wiring is left alone. */
    body.has-tb-sheet .page-toolbar .filter-toggle { display: none !important; }
    .tb-sheet-btn {
        position: relative;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex-shrink: 0;
        width: 36px;
        height: 36px;
        padding: 0;
        background: var(--surface);
        border: 1px solid var(--border-strong);
        border-radius: var(--radius-sm);
        color: var(--text);
        cursor: pointer;
    }
    .tb-sheet-btn svg { width: 18px; height: 18px; }
    .tb-sheet-btn::after { content: ''; position: absolute; inset: -4px; }

    /* Inside the sheet the filter card is the content, so it drops the card
       chrome and the collapse rule that hides it on a phone. */
    .tb-sheet .filter-bar {
        display: block;
        border: none;
        background: none;
        padding: 0;
        margin: 0 0 4px;
    }
    /* Chip rows read as a wrapped group here rather than a scroller. */
    .tb-sheet .tos-modal-body > div { margin-bottom: 14px; }
    .tb-sheet .tos-modal-body > div:last-child { margin-bottom: 0; }
    .tb-sheet .tos-modal-body [id="presetChips"],
    .tb-sheet .tos-modal-body > div:first-child {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        overflow: visible;
        width: auto;
    }
    /* Actions sit in the pinned footer, primary full-width and last. */
    .tb-sheet .tos-modal-footer { flex-wrap: wrap; gap: 8px; }
    .tb-sheet .tos-modal-footer > * { flex: 1 1 auto; height: 44px; min-height: 44px; }
    .tb-sheet .tos-modal-footer .btn-primary { flex: 1 1 100%; order: 2; font-size: 14px; }
    /* Undo the icon-only collapse: in the sheet there is room for words. */
    .tb-sheet .tos-modal-footer .btn {
        width: auto;
        padding: 0 14px;
        gap: 8px;
        font-size: 13px;
        justify-content: center;
    }
    .tb-sheet .tos-modal-footer .btn::after { content: none; }

    /* 36px is under the 44px thumb floor the rest of the app holds to, so the
       target is restored invisibly rather than by growing the row back. The 4px
       horizontal bleed sits inside the 8px gap, so neighbouring targets meet
       without overlapping. */
    .page-toolbar-actions .btn,
    .page-toolbar-actions .filter-toggle { position: relative; }
    .page-toolbar-actions .btn::after,
    .page-toolbar-actions .filter-toggle::after {
        content: '';
        position: absolute;
        inset: -4px;
    }
}


/* ---------- 22. Filter bar (search + selects card) ---------- */
.filter-bar {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px;
    margin-bottom: 22px;
}
@media (min-width: 768px) { .filter-bar { padding: 18px 20px; } }
.filter-bar-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 14px 16px;
}
.filter-field { display: flex; flex-direction: column; }
.filter-label {
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-2);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 6px;
}
/* mobile: collapse the bar behind a toggle button */
.filter-toggle {
    display: none;
    align-items: center;
    gap: 8px;
    padding: 9px 14px;
    min-height: 44px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    font-family: var(--font);
    font-size: 14px;
    font-weight: 500;
    color: var(--text);
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.filter-toggle:hover { background: var(--bg-soft); border-color: #9ca3af; }
.filter-toggle:focus-visible { outline: none; box-shadow: var(--ring); }
.filter-count {
    display: inline-block;
    min-width: 18px;
    padding: 1px 6px;
    border-radius: 999px;
    background: var(--black);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    text-align: center;
    line-height: 16px;
}
@media (max-width: 767px) {
    .filter-bar { display: none; }
    .filter-bar.is-open { display: block; }
    .filter-bar-grid { grid-template-columns: 1fr; }
    .filter-toggle { display: inline-flex; }
}

/* ---------- 23. Card grid (responsive auto-fill) ---------- */
.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 16px;
}
@media (min-width: 768px) { .card-grid { gap: 20px; } }
.card-grid-sm { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
@media (max-width: 520px) { .card-grid, .card-grid-sm { grid-template-columns: 1fr; } }

/* ---------- 24. Icon action button ---------- */
/* Compact bordered square for row/card actions. Neutral hover by
   default; .act-btn--danger for destructive (delete). */
.act-btns { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.act-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    color: var(--text-2);
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.act-btn svg { width: 17px; height: 17px; }
/* Same square, but holding a WORD instead of an icon: dispatch's day nav puts
   "Oggi" between its two arrows. The fixed 38px width clipped that in every
   language but Italian ("Today", "Danas" overflow a 36px content box), and a
   bare <button> also falls back to the browser UI font, so the label did not
   even match the app. Height stays 38 so it still lines up with its arrows. */
.act-btn--text {
    width: auto;
    min-width: 38px;
    padding: 0 12px;
    font-family: var(--font);
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
}
.act-btn:hover:not(:disabled) { background: var(--bg-hover); border-color: #9ca3af; color: var(--text); }
.act-btn:focus-visible { outline: none; box-shadow: var(--ring); }
.act-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.act-btn--danger:hover:not(:disabled) { background: var(--danger-bg); border-color: #fca5a5; color: var(--danger); }
@media (max-width: 767px) { .act-btn { min-width: 44px; min-height: 44px; } }

/* ---------- 25. Empty panel ---------- */
.empty-panel { text-align: center; padding: 56px 20px; }
.empty-panel-icon {
    display: flex; align-items: center; justify-content: center;
    margin: 0 auto 16px;
    color: var(--text-3);
}
.empty-panel-icon svg { width: 56px; height: 56px; }
.empty-panel-title { font-size: 17px; font-weight: 600; margin-bottom: 6px; }
.empty-panel-text { font-size: 14px; color: var(--text-2); max-width: 420px; margin: 0 auto; }
.empty-panel .btn { margin-top: 18px; }

/* ---------- 26. Skeleton loading ---------- */
@keyframes tos-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
.skeleton-bar, .skeleton-box {
    background: var(--skeleton);
    border-radius: var(--radius-xs);
    animation: tos-pulse 1.4s ease-in-out infinite;
}
.skeleton-bar { height: 14px; }

/* ---------- 27. Detail rows (key/value) ---------- */
/* .kv-* = space-between rows inside cards; .detail-grid = 2-col
   read-only pairs inside view modals (labels reuse .form-label). */
.kv-list { display: flex; flex-direction: column; gap: 8px; }
.kv-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 13px; }
.kv-key { color: var(--text-2); font-weight: 500; }
.kv-val { color: var(--text); font-weight: 600; text-align: right; }
.detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 16px; }
.detail-grid + .detail-grid { margin-top: 14px; }

/* ---------- 28. Small helpers ---------- */
.req-mark { color: var(--danger); font-weight: 600; }
.code-text { font-family: ui-monospace, "SF Mono", Menlo, monospace; letter-spacing: 0.03em; }

/* ---------- 29. Segmented control (pill tabs / mode toggle) ---------- */
.seg-ctl {
    display: inline-flex;
    background: var(--neutral-100);
    border-radius: var(--radius-sm);
    padding: 3px;
    gap: 2px;
}
.seg-opt {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 6px 14px;
    border: none;
    background: transparent;
    border-radius: var(--radius-xs);
    font-family: var(--font);
    font-size: 13px;
    font-weight: 600;
    color: var(--text-2);
    white-space: nowrap;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.seg-opt:hover { color: var(--text); }
.seg-opt.is-active { background: var(--surface); color: var(--text); box-shadow: var(--shadow-1); }
.seg-opt:focus-visible { outline: none; box-shadow: var(--ring); }
.seg-ctl--block { display: flex; width: 100%; }
.seg-ctl--block .seg-opt { flex: 1; }

/* ---------- 30. Stat tiles (KPI) ---------- */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.stat-tile { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px 18px; }
.stat-cap { font-size: 12px; font-weight: 500; color: var(--text-2); }
.stat-metric { font-size: 24px; font-weight: 700; letter-spacing: -0.01em; margin-top: 4px; }
.stat-sub { font-size: 12px; color: var(--text-3); margin-top: 2px; }

/* ── 31. Guide modal (Phase D) ─────────────────────────────────────────────
   Shared so the ~18 pages that carry a Guide button do not each duplicate this.
   Same rules the first 6 guide pages used inline; promoted here verbatim. The
   modal itself is .tos-modal.tos-modal-lg.tos-modal--sheet (sheet = bottom-sheet
   on mobile, already in section on modals). */
.guide-section { margin-bottom: 4px; }
.guide-section-title { font-size: 16px; font-weight: 700; color: var(--text); margin-bottom: 10px; }
.guide-text { font-size: 14px; color: var(--text-2); line-height: 1.65; margin-bottom: 10px; }
.guide-text:last-child { margin-bottom: 0; }
.guide-hr { border: none; border-top: 1px solid var(--border); margin: 20px 0; }
.guide-info-card { margin-bottom: 10px; }
.guide-info-card-title { font-size: 14px; font-weight: 700; color: var(--text); margin-bottom: 6px; }
.guide-info-card-text { font-size: 13px; color: var(--text-2); line-height: 1.55; }
.guide-scenario { background: var(--bg-soft); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 12px 16px; margin-bottom: 10px; }
.guide-scenario-title { font-size: 13px; font-weight: 600; color: var(--text); margin-bottom: 4px; }
.guide-scenario-desc { font-size: 12px; color: var(--text-2); line-height: 1.5; }
/* The Guide trigger is a help affordance, not an action, so it is muted:
   lighter weight, smaller text, softer border. It used to pin its own 30px
   height as well, which made it the one control that never matched the row it
   sat in (34px in a toolbar, 44px beside "Richiedi un sito" on /websites/).
   Being quiet is a colour job, not a height job, so the height now comes from
   .btn-sm like everything else. */
.guide-btn.btn {
    position: relative;
    align-self: center;
    flex-shrink: 0;
    padding: 0 12px;
    gap: 6px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--text-2);
    border-color: var(--border);
}
.guide-btn.btn:hover { color: var(--text); border-color: var(--border-strong); }
.guide-btn .guide-lbl-short { display: none; }
/* Shrinking the box must not shrink the thumb target: this restores the 44px
   touch height invisibly. Vertical only, so it cannot overlap a neighbouring
   button in the same row. */
@media (max-width: 767px) {
    .guide-btn.btn::after {
        content: '';
        position: absolute;
        left: 0;
        right: 0;
        top: -7px;
        bottom: -7px;
    }
    /* Same label swap as the subheader button: the long name on desktop, one
       word on mobile where the toolbar has no room for it. */
    .guide-btn .guide-lbl-full { display: none; }
    .guide-btn .guide-lbl-short { display: inline; }
}
.guide-btn-svg { width: 18px; height: 18px; }
/* Any svg, not just .guide-btn-svg: the invoices and analytics buttons are
   hand-rolled and carry their own inline width/height attributes. */
.guide-btn svg { width: 15px; height: 15px; flex-shrink: 0; }

/* ============================================================
   HUB CHROME (section 33) — hub-only shell pieces layered on
   top of the shared app-shell above. Additive, collision-free
   names (grepped): .sidebar-clocks*, .nav-badge*, .mind-fab*.
   ============================================================ */

/* main content: hub renders pages full-width inside a padded main
   (no per-page .content-wrapper), matching the dense admin console */
.main-content.hub-main {
    padding: 24px 16px 40px;
}
@media (min-width: 768px) { .main-content.hub-main { padding: 28px 24px 48px; } }
@media (min-width: 1200px) { .main-content.hub-main { padding: 32px 40px 56px; } }

/* sidebar multi-timezone clocks (pinned to the bottom of the nav) */
.sidebar-clocks {
    margin-top: auto;
    padding: 12px 12px 4px;
    border-top: 1px solid var(--border);
    font-size: 11px;
    color: var(--text-2);
}
.sidebar-clocks-title {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-3);
    margin-bottom: 6px;
}
.sidebar-clocks-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 3px 0;
}
.sidebar-clocks-row.is-server { color: var(--text); font-weight: 600; }
.sidebar-clocks-label { color: var(--text-2); }
.sidebar-clocks-row.is-server .sidebar-clocks-label { color: var(--text); }
.sidebar-clocks-time { font-variant-numeric: tabular-nums; }

/* sidebar nav count badges (pending leads / today calendar / stale backup) */
.nav-badge {
    flex: none;
    background: var(--black);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    min-width: 18px;
    padding: 1px 7px;
    border-radius: 999px;
    text-align: center;
    line-height: 16px;
}
.nav-badge-warning { background: var(--danger); }

/* the expandable nav parents (Analytics/Boost/etc.) are <button> toggles in hub,
   not <a> links like the app; strip the user-agent button chrome so they match
   the plain nav items instead of rendering as an outlined grey box */
button.nav-item-parent {
    width: 100%;
    background: transparent;
    border: none;
    cursor: pointer;
    text-align: left;
    font-family: var(--font);
}

/* ---------- Mind quick-capture FAB (floating, every hub page) ---------- */
.mind-fab-wrap { position: fixed; bottom: 22px; right: 22px; z-index: 900; }
.mind-fab {
    width: 52px; height: 52px; border-radius: 50%;
    background: var(--black); color: #fff; border: none; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    box-shadow: var(--shadow-3);
    transition: transform .15s ease, box-shadow .15s ease;
}
.mind-fab:hover { transform: scale(1.07); }
.mind-fab:focus-visible { outline: none; box-shadow: var(--ring); }
.mind-fab-pop {
    display: none; position: absolute; bottom: 64px; right: 0;
    width: 300px; background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius-lg); box-shadow: var(--shadow-3); padding: 12px;
    animation: mindFabIn .14s ease-out;
}
.mind-fab-pop.show { display: block; }
@keyframes mindFabIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
.mind-fab-pop textarea {
    width: 100%; border: none; border-radius: var(--radius-sm); resize: none;
    background: #FEF3C0; padding: 10px 12px; outline: none;
    font-family: var(--font); font-size: 14px; font-weight: 500; line-height: 1.45;
    color: #111318; transition: background .2s ease;
}
.mind-fab-pop textarea::placeholder { color: rgba(17, 19, 24, 0.38); }
.mind-fab-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; }
.mind-fab-dots { display: flex; gap: 6px; }
.mfb-dot {
    width: 16px; height: 16px; border-radius: 50%; padding: 0;
    border: 2px solid transparent; cursor: pointer; transition: transform .12s ease;
    position: relative;
}
.mfb-dot:hover { transform: scale(1.18); }
.mfb-dot.active { border-color: rgba(17, 19, 24, 0.55); }
/* No ::after tooltip here either: tos.js owns [data-tip]. This one doubled on EVERY hub
   page, since the mind FAB is in footer.php. */
.mind-fab-client {
    flex: 1; min-width: 0; max-width: 175px;
    display: inline-flex; align-items: center; justify-content: space-between; gap: 6px;
    font-family: var(--font); font-size: 12px; font-weight: 600;
    padding: 5px 10px; border: 1px solid var(--border-strong); border-radius: 999px;
    background: var(--surface); color: var(--text-2); cursor: pointer; transition: all .12s ease;
}
.mind-fab-client:hover { border-color: var(--text); color: var(--text); }
.mind-fab-client span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mind-fab-client svg { flex-shrink: 0; }
.mind-fab-client.has-client { background: var(--black); color: #fff; border-color: var(--black); }
.mind-fab-clientdd {
    display: none; position: absolute; bottom: 76px; left: 12px; right: 12px;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
    box-shadow: var(--shadow-2); overflow: hidden; z-index: 5;
}
.mind-fab-clientdd.show { display: block; }
.mind-fab-clientdd input {
    width: 100%; border: none; border-bottom: 1px solid var(--border);
    padding: 9px 12px; font-family: var(--font); font-size: 13px; outline: none;
}
.mind-fab-clientdd-opts { max-height: 190px; overflow-y: auto; }
.mind-fab-deadline {
    display: inline-flex; align-items: center; gap: 5px; flex-shrink: 0;
    font-family: var(--font); font-size: 12px; font-weight: 600;
    padding: 5px 9px; border: 1px solid var(--border-strong); border-radius: 999px;
    background: var(--surface); color: var(--text-2); cursor: pointer; transition: all .12s ease;
}
.mind-fab-deadline:hover { border-color: var(--text); color: var(--text); }
.mind-fab-deadline.has-client { background: var(--black); color: #fff; border-color: var(--black); }
.mind-fab-deadline span:empty { display: none; }
.mind-fab-datedd {
    display: none; position: absolute; bottom: 76px; left: 12px; right: 12px;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
    box-shadow: var(--shadow-2); padding: 10px;
    align-items: center; gap: 8px; z-index: 6;
}
.mind-fab-datedd.show { display: flex; }
.mind-fab-datedd input {
    flex: 1; min-width: 0; font-family: var(--font); font-size: 13px;
    padding: 6px 8px; border: 1px solid var(--border-strong); border-radius: 7px; outline: none;
}
.mind-fab-datedd button {
    border: none; background: transparent; font-family: var(--font);
    font-size: 12px; font-weight: 600; color: var(--text-2); cursor: pointer;
}
.mind-fab-datedd button:hover { color: var(--danger); }
.mind-fab-filerow {
    display: none; align-items: center; gap: 6px; margin-top: 8px;
    font-size: 12px; font-weight: 600; color: var(--text-2);
}
.mind-fab-filerow.show { display: flex; }
.mind-fab-filerow span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1; }
.mind-fab-filerow button {
    border: none; background: transparent; cursor: pointer;
    font-size: 15px; line-height: 1; color: var(--text-2); padding: 0 2px;
}
.mind-fab-filerow button:hover { color: var(--danger); }
.mfb-opt { padding: 8px 12px; font-size: 12.5px; cursor: pointer; color: var(--text); }
.mfb-opt:hover { background: var(--bg-hover); }
.mfb-opt.muted { color: var(--text-2); font-style: italic; }
.mind-fab-actions { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.mind-fab-board { font-size: 11px; font-weight: 600; color: var(--text-2); text-decoration: none; }
.mind-fab-board:hover { color: var(--text); }
.mind-fab-hint { margin-left: auto; font-size: 11px; color: var(--text-3); font-weight: 500; }
#mindFabSave {
    font-family: var(--font); font-size: 12px; font-weight: 600;
    background: var(--black); color: #fff; border: none; border-radius: 7px;
    padding: 7px 16px; cursor: pointer;
}
#mindFabSave:hover { background: var(--black-hover); }
.mind-fab-toast {
    position: fixed; bottom: 88px; right: 22px; z-index: 901;
    background: #0f172a; color: #fff; font-size: 13px; font-weight: 600;
    padding: 10px 16px; border-radius: var(--radius); box-shadow: var(--shadow-3);
    opacity: 0; pointer-events: none; transform: translateY(6px);
    transition: opacity .2s ease, transform .2s ease;
}
.mind-fab-toast.show { opacity: 1; pointer-events: auto; transform: translateY(0); }
.mind-fab-toast a { color: #F5D663; text-decoration: underline; }
@media (max-width: 640px) {
    .mind-fab-wrap { bottom: 16px; right: 16px; }
    .mind-fab-pop { width: min(300px, calc(100vw - 32px)); }
}

/* ============================================================
   HUB LIST / ANALYTICS COMPONENTS (section 34)

   Hub-specific shared components with no app equivalent: the
   expandable session/analytics row list and its filter + pagination
   chrome. Genuinely shared - used by analytics, clients-analytics,
   app-analytics, boost-analytics, leads, clients and calendar, so
   these are KEPT (not legacy cruft). They are page-content only
   (no shell) and fully tokenized; .session-header/.session-badges
   wrap on phones so a wide badge strip can't overflow the viewport.

   All dead hub.css leftovers (stat-card/status-badge/contact-message/
   coming-soon/...) were pruned once every page was migrated; the old
   hub.css is deleted. Prefer the app components in sections 1-30
   (.stat-tile, .badge, .card, .table, .filter-bar) for anything new -
   only touch this section when changing the session-list itself.
   ============================================================ */

/* ═══ FILTERS ════════════════════════════════════════════════════════════════ */
.analytics-filters {
    display: flex;
    gap: 8px;
    margin-bottom: 16px;
    align-items: center;
    flex-wrap: wrap;
    position: sticky;
    top: var(--header-height);
    /* must match the PAGE background so the bar masks content scrolling under it.
       The page is --surface (white) now; using --bg here painted a grey band. */
    background: var(--surface);
    z-index: 10;
    padding: 12px 0;
}
.analytics-filters select,
.analytics-filters input[type="date"] {
    padding: 7px 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 13px;
    font-family: var(--font-sans);
    color: var(--text-primary);
    background: var(--white);
    cursor: pointer;
    outline: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}
.analytics-filters select {
    padding-right: 32px;
}
.analytics-filters select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%234B4B4B' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
}
.analytics-filters select:focus,
.analytics-filters input[type="date"]:focus {
    border-color: var(--black);
}
.filter-search-wrap {
    margin-left: auto;
    position: relative;
}
.filter-search-wrap svg {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    pointer-events: none;
}
.filter-search {
    padding: 7px 12px 7px 32px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 13px;
    font-family: var(--font-sans);
    color: var(--text-primary);
    background: var(--white);
    outline: none;
    width: 240px;
}
.filter-search:focus { border-color: var(--black); }
.filter-search::placeholder { color: var(--text-muted); }
.filter-search-clear {
    position: absolute; right: 8px; top: 50%;
    transform: translateY(-50%);
    background: none; border: none; font-size: 16px;
    color: var(--text-muted); cursor: pointer; padding: 0 4px;
    line-height: 1;
}
.filter-search-clear:hover { color: var(--text-primary); }
.filter-clear {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-secondary);
    padding: 7px 12px;
}
.filter-clear:hover { color: var(--text-primary); }

/* ═══ SESSION / ROW LIST ═════════════════════════════════════════════════════ */
.sessions-list {
    display: flex;
    flex-direction: column;
    gap: 1px;
    background: var(--border);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.sessions-empty {
    background: var(--white);
    padding: 40px;
    text-align: center;
    font-size: 14px;
    border-radius: 8px;
    color: var(--text-muted);
}
.session-row { background: var(--white); }
.session-row:first-child { border-radius: 8px 8px 0 0; }
.session-row:first-child .session-header { border-radius: 8px 8px 0 0; }
.session-row:last-child { border-radius: 0 0 8px 8px; }
.session-row:last-child .session-header { border-radius: 0 0 8px 8px; }
.session-row:first-child:last-child,
.session-row:first-child:last-child .session-header { border-radius: 8px; }
.session-row.open:last-child .session-header { border-radius: 0; }
.session-row.open:first-child:last-child .session-header { border-radius: 8px 8px 0 0; }
.session-row.first-visible { border-radius: 8px 8px 0 0; }
.session-row.first-visible .session-header { border-radius: 8px 8px 0 0; }
.session-row.last-visible { border-radius: 0 0 8px 8px; }
.session-row.last-visible .session-header { border-radius: 0 0 8px 8px; }
.session-row.first-visible.last-visible,
.session-row.first-visible.last-visible .session-header { border-radius: 8px; }
.session-row.open.last-visible .session-header { border-radius: 0; }
.session-row.open.first-visible.last-visible .session-header { border-radius: 8px 8px 0 0; }
.session-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 18px;
    cursor: pointer;

    gap: 10px;
}
.session-header:hover { background: var(--gray-1); }

.session-left {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
    margin-right: 4px;
}
.session-flag {
    flex-shrink: 0;
}
.session-flag-empty {
    width: 22px;
    height: 15px;
    background: var(--gray-1);
    flex-shrink: 0;
}
.session-device-icon {
    color: var(--text-primary);
    display: flex;
    align-items: center;
    flex-shrink: 0;
}
.session-left-separator {
    width: 1px;
    height: 16px;
    background: var(--gray-3);
    flex-shrink: 0;
    margin-left: 2px;
}

.session-main { flex: 1; min-width: 0; }
.session-meta-single {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.session-time { font-size: 13px; font-weight: 600; color: var(--text-primary); }
.session-separator {
    color: var(--text-muted);
    font-size: 12px;
    margin: 0 6px;
}
.session-header:hover .session-tag {
    border-color: var(--border);
}
.session-header:hover .session-left-separator {
    background: var(--border);
}
.session-tag {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-secondary);
    background: var(--gray-1);
    padding: 3px 9px;
    border-radius: 4px;
    border: 1px solid transparent;
}
.session-tag-company { color: var(--text-primary); font-weight: 600; }
.session-tag-bounce { color: var(--text-secondary); opacity: .65; font-style: italic; }
.session-row.is-bounce { background: var(--gray-1, #fafafa); }
.session-row.is-bounce .session-time { font-weight: 500; opacity: .8; }

/* Engaged / All session view toggle (clients-analytics) */
.ca-sessions-toolbar { display: flex; justify-content: flex-end; margin: 4px 0 10px; }
.ca-viewtoggle { display: inline-flex; background: var(--gray-1, #f3f4f6); border-radius: 8px; padding: 2px; gap: 2px; }
.ca-vt-btn { border: none; background: transparent; color: var(--text-secondary); font-size: 12px; font-weight: 600; padding: 5px 12px; border-radius: 6px; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; transition: all .12s; text-decoration: none; }
.ca-vt-btn:hover { color: var(--text-primary); }
.ca-vt-btn.is-active { background: var(--white, #fff); color: var(--text-primary); box-shadow: 0 1px 2px rgba(0,0,0,.08); }
.ca-vt-count { font-size: 11px; font-weight: 700; background: rgba(0,0,0,.06); color: var(--text-secondary); padding: 0 6px; border-radius: 10px; }
.ca-vt-btn.is-active .ca-vt-count { background: #eff6ff; color: #2563eb; }

/* Loading overlay: dim current list under a spinner instead of flashing empty */
.ca-site-body.is-loading { position: relative; min-height: 100px; }
.ca-site-body.is-loading .sessions-list,
.ca-site-body.is-loading .sessions-empty { opacity: .3; transition: opacity .12s ease; pointer-events: none; }
.ca-site-body.is-loading::after {
    content: ""; position: absolute; top: 60px; left: 50%; width: 26px; height: 26px; margin-left: -13px;
    border-radius: 50%; border: 3px solid var(--gray-2, #e5e7eb); border-top-color: #2563eb;
    animation: ca-spin .7s linear infinite;
}
@keyframes ca-spin { to { transform: rotate(360deg); } }
.lead-account-icon { vertical-align: -2px; margin-right: 4px; color: var(--text-secondary); }
.session-tag-note {
    display: inline-flex; align-items: center; gap: 5px;
    position: relative; cursor: pointer;
    color: var(--text-primary); font-weight: 600;
}
.session-tag-note-tooltip {
    display: none;
    position: absolute; bottom: calc(100% + 10px); left: 50%;
    transform: translateX(-50%); white-space: pre-wrap;
    background: var(--text-primary); color: #fff;
    font-size: 12px; font-weight: 400; line-height: 1.5;
    padding: 8px 12px; border-radius: 6px;
    max-width: 360px; width: max-content;
    box-shadow: 0 4px 16px rgba(0,0,0,0.15);
    pointer-events: none;
    z-index: 200;
}
.session-tag-note-tooltip::after {
    content: '';
    position: absolute; top: 100%; left: 50%;
    margin-left: -6px;
    border: 6px solid transparent;
    border-top-color: var(--text-primary);
}
.session-tag-note-tooltip.tooltip-bottom {
    bottom: auto;
    top: calc(100% + 10px);
}
.session-tag-note-tooltip.tooltip-bottom::after {
    top: auto;
    bottom: 100%;
    border-top-color: transparent;
    border-bottom-color: var(--text-primary);
}
.session-tag-note:hover .session-tag-note-tooltip,
.session-tag-event:hover .session-tag-note-tooltip { display: block; }
.session-tag-source { color: var(--text-primary); font-weight: 600; }
.session-badges {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}
.client-login-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--white);
    color: var(--text-secondary);
    cursor: pointer;
    transition: all 0.15s ease;
}
.client-login-icon-btn:hover {
    color: var(--text-primary);
    border-color: var(--text-primary);
}
.session-badge {
    font-size: 11px;
    font-weight: 600;
    padding: 5px 12px;
    border-radius: 4px;
    min-width: 76px;
    text-align: center;
}
.badge-lead-complete,
.badge-lead-started,
.badge-contact { background: var(--white); color: var(--text-secondary); border: 1px solid var(--border); }
.badge-noroute { background: #fee2e2; color: #b91c1c; border: 1px solid #fecaca; }
.session-chevron {
    color: var(--text-muted);

    margin-left: 8px;
}
.session-row.open .session-chevron { transform: rotate(180deg); }

/* Expandable detail */
.session-events {
    display: none;
    border-top: 1px solid var(--border);
    padding: 14px 18px;
    background: var(--gray-1);
}
.session-row.open > .session-events { display: block; }
.session-detail-row {
    display: flex;
    gap: 12px;
    padding: 3px 0;
    font-size: 12px;
}
.detail-label { font-weight: 600; color: var(--text-secondary); min-width: 90px; flex-shrink: 0; }
.detail-value { color: var(--text-primary); word-break: break-all; }

/* Event timeline */
.events-timeline {
    margin-top: 12px;
    border-top: 1px solid var(--border);
    padding-top: 10px;
}
.event-row {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 4px 0;
    font-size: 12px;
}
.event-time {
    font-family: monospace;
    font-size: 11px;
    color: var(--text-secondary);
    flex-shrink: 0;
}
.event-name { font-weight: 600; color: var(--text-primary); flex-shrink: 0; }
.event-page { color: var(--text-secondary); }
.event-detail { color: var(--text-secondary); font-size: 11px; }
.event-detail.has-tip { border-bottom: 1px dotted var(--border-color, #d1d5db); cursor: help; position: relative; outline: none; }
.event-detail.has-tip:hover { color: var(--text-primary); border-bottom-color: var(--text-secondary); }
/* No ::after tooltip here: [data-tip] is owned by tos.js, which portals one tooltip and
   already honours multi-line text (.tos-tooltip-content is white-space: pre-line). A CSS
   copy renders a SECOND tooltip on the opposite side of the element. */

/* Pagination */
.analytics-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    margin-top: 20px;
    padding: 16px 0;
}
.pagination-btn {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
    padding: 8px 16px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--white);
}
.pagination-btn:hover { background: var(--gray-1); }
.pagination-info { font-size: 13px; color: var(--text-secondary); }

/* legacy mobile tweaks (page-content only) */
@media (max-width: 768px) {
    /* the session row header + its trailing badge strip must wrap on phones,
       otherwise a wide top-pages/meta strip pushes the page past the viewport */
    .session-header { padding: 12px 14px; flex-wrap: wrap; }
    .session-badges { flex-wrap: wrap; flex-shrink: 1; min-width: 0; }
    .session-events { padding: 12px 14px; }
}

/* ═══ CLIENTS ════════════════════════════════════════════════════════════════ */
.session-flag-icon {
    color: var(--text-muted);
    flex-shrink: 0;
}

.session-tag-sites {
    font-size: 13px;
    font-weight: 600;
    color: var(--white);
    background: var(--text-primary);
    padding: 3px 9px;
    border-radius: 4px;
    border: 1px solid transparent;
}

.session-header:hover .session-tag-sites {
    border-color: var(--text-primary);
}

.client-sites-section {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--gray-2);
}
.client-sites-title {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-primary);
    margin-bottom: 8px;
}
.client-sites-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.client-site-row {
    padding: 14px 16px;
    background: var(--white);
    border: 1px solid var(--gray-2);
    border-radius: 8px;
}
.client-site-top {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}
.preview-dropdown-wrap {
    position: relative;
    display: flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
}
.preview-badge {
    cursor: pointer;
}
.preview-open-link {
    cursor: pointer;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.preview-open-link:hover {
    background: var(--gray-2);
}
.preview-dropdown {
    display: none;
    position: fixed;
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0,0,0,0.1);
    width: 200px;
    padding: 4px;
    z-index: 500;
}
.preview-dropdown.show { display: block; }
.preview-dropdown button {
    display: block;
    width: 100%;
    padding: 8px 12px;
    font-size: 12px;
    font-weight: 500;
    font-family: var(--font-sans);
    color: var(--text-primary);
    background: none;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    text-align: left;
}
.preview-dropdown button:hover { background: var(--gray-1); }
.preview-dropdown button.active { font-weight: 700; }
.preview-dropdown button.disabled {
    color: var(--text-muted);
    cursor: default;
}
.preview-dropdown button.disabled:hover { background: none; }
.preview-taken { color: var(--text-muted); font-weight: 400; }
.preview-disable { color: var(--text-secondary); }
.client-site-domain {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
}
.client-site-meta {
    font-size: 12px;
    color: var(--text-secondary);
    background: var(--gray-1);
    padding: 2px 8px;
    border-radius: 4px;
}

/* ── header Claude-usage pill (hub chrome, section 33 addition) ── */
.header-usage {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 7px 10px; margin-right: 2px; border-radius: 8px;
    font-size: 12.5px; font-weight: 600; color: var(--text-2);
    text-decoration: none; white-space: nowrap;
    font-variant-numeric: tabular-nums;
    transition: background 0.15s ease, color 0.15s ease;
}
.header-usage:hover { background: var(--bg-hover); color: var(--text); }
.header-usage svg { flex: none; color: var(--text-3); }
.header-usage:hover svg { color: var(--text); }
@media (max-width: 767px) { .header-usage-extra { display: none; } .header-usage { padding: 7px 8px; } }
.header-usage.is-warn, .header-usage.is-warn svg { color: #b45309; }
.header-usage.is-hot, .header-usage.is-hot svg { color: #b91c1c; }

/* usage-pill tooltip: wider than the default 260px cap so the limit rows
   (label + right-aligned percent + full-width bar) never clip */
.tos-tooltip:has(.cl-usage-tip) { max-width: 320px; }
.cl-usage-tip { width: 100%; white-space: normal; }

/* ============================================================
   35. Form validation state (25 Aug 2026, shared)
   Promoted from the site portal rebuild: an invalid control and the
   one-line message under it. Inert until a page opts in.
   ============================================================ */
.form-control.is-invalid,
.form-select.is-invalid,
.tos-sel.is-invalid .tos-sel-trigger,
.iti.is-invalid .form-control { border-color: var(--danger); }
.form-control.is-invalid:focus,
.form-select.is-invalid:focus { box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.12); }
.form-error { display: none; font-size: 12.5px; color: var(--danger); margin-top: 6px; line-height: 1.4; }
.form-error.is-on, .has-error > .form-error { display: block; }

/* ============================================================
   36. Dark palette, OPT-IN BY ATTRIBUTE (25 Aug 2026)
   Applied only when <html data-theme="dark">, or data-theme="auto" while the
   OS prefers dark. The app and the hub never set the attribute, so nothing
   there changes; the site portal ({site}/portal) does, and its three-way
   theme rides these tokens instead of a hand-copied palette. The block is
   repeated under the media query because a selector list cannot express
   "dark, or auto only inside a media query". The few components that carry
   a hardcoded hex (badges, alerts, labels, primary buttons' white text) are
   re-pointed here so the whole system flips together.
   ============================================================ */
html[data-theme="dark"] {
    --surface: #16181d; --bg-page: #0d0f13; --bg-soft: #1b1e24; --bg-hover: #21252c; --bg-active: #262a31;
    --text: #f3f4f6; --text-2: #9aa3af; --text-3: #6b7280;
    --border: #262a31; --border-strong: #363b44; --neutral-100: #21252c; --skeleton: #21252c;
    --black: #f3f4f6; --black-hover: #ffffff;
    --success: #34d399; --success-bg: rgba(16, 185, 129, 0.14); --success-strong: #6ee7b7;
    --danger: #f87171; --danger-bg: rgba(248, 113, 113, 0.14);
    --warning: #fbbf24; --warning-bg: rgba(251, 191, 36, 0.14);
    --info: #60a5fa; --info-bg: rgba(96, 165, 250, 0.14);
    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4); --shadow-2: 0 4px 16px rgba(0, 0, 0, 0.5); --shadow-3: 0 12px 40px rgba(0, 0, 0, 0.6);
    --ring: 0 0 0 3px rgba(243, 244, 246, 0.14);
    color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
    html[data-theme="auto"] {
        --surface: #16181d; --bg-page: #0d0f13; --bg-soft: #1b1e24; --bg-hover: #21252c; --bg-active: #262a31;
        --text: #f3f4f6; --text-2: #9aa3af; --text-3: #6b7280;
        --border: #262a31; --border-strong: #363b44; --neutral-100: #21252c; --skeleton: #21252c;
        --black: #f3f4f6; --black-hover: #ffffff;
        --success: #34d399; --success-bg: rgba(16, 185, 129, 0.14); --success-strong: #6ee7b7;
        --danger: #f87171; --danger-bg: rgba(248, 113, 113, 0.14);
        --warning: #fbbf24; --warning-bg: rgba(251, 191, 36, 0.14);
        --info: #60a5fa; --info-bg: rgba(96, 165, 250, 0.14);
        --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4); --shadow-2: 0 4px 16px rgba(0, 0, 0, 0.5); --shadow-3: 0 12px 40px rgba(0, 0, 0, 0.6);
        --ring: 0 0 0 3px rgba(243, 244, 246, 0.14);
        color-scheme: dark;
    }
}
/* Components with a hardcoded colour, re-pointed while dark is active. The
   selector pair covers both the explicit and the OS-driven dark state; the
   attribute flag .tos-dark is stamped by the page JS for the auto case so
   the media query does not have to be repeated per rule. */
html[data-theme="dark"], html.tos-dark {
    --on-black: #0d0f13;
}
html[data-theme="dark"] .btn-primary, html.tos-dark .btn-primary,
html[data-theme="dark"] .badge-dark, html.tos-dark .badge-dark,
html[data-theme="dark"] .filter-count, html.tos-dark .filter-count { color: var(--on-black); }
html[data-theme="dark"] .form-label, html.tos-dark .form-label,
html[data-theme="dark"] .tos-sel-option, html.tos-dark .tos-sel-option { color: var(--text-2); }
html[data-theme="dark"] .tos-sel-option.is-active, html.tos-dark .tos-sel-option.is-active,
html[data-theme="dark"] .tos-sel-option.is-selected, html.tos-dark .tos-sel-option.is-selected { color: var(--text); }
html[data-theme="dark"] .tos-sel-tag, html.tos-dark .tos-sel-tag,
html[data-theme="dark"] .tos-dialog-icon.icon-question, html.tos-dark .tos-dialog-icon.icon-question,
html[data-theme="dark"] .badge-neutral, html.tos-dark .badge-neutral { background: var(--neutral-100); color: var(--text-2); }
html[data-theme="dark"] .badge-warning, html.tos-dark .badge-warning { background: var(--warning-bg); color: var(--warning); }
html[data-theme="dark"] .badge-danger, html.tos-dark .badge-danger { background: var(--danger-bg); color: var(--danger); }
html[data-theme="dark"] .badge-info, html.tos-dark .badge-info { background: var(--info-bg); color: var(--info); }
html[data-theme="dark"] .badge-success, html.tos-dark .badge-success { background: var(--success-bg); color: var(--success); }
html[data-theme="dark"] .alert-info, html.tos-dark .alert-info { color: var(--info); }
html[data-theme="dark"] .alert-success, html.tos-dark .alert-success { color: var(--success); }
html[data-theme="dark"] .alert-warning, html.tos-dark .alert-warning { color: var(--warning); }
html[data-theme="dark"] .alert-danger, html.tos-dark .alert-danger { color: var(--danger); }
html[data-theme="dark"] .btn-danger-outline, html.tos-dark .btn-danger-outline { border-color: rgba(248, 113, 113, 0.45); }
html[data-theme="dark"] .tos-modal-backdrop, html.tos-dark .tos-modal-backdrop,
html[data-theme="dark"] .tos-sel-backdrop, html.tos-dark .tos-sel-backdrop { background: rgba(0, 0, 0, 0.62); }
html[data-theme="dark"] ::selection, html.tos-dark ::selection { background: var(--text); color: var(--surface); }
html[data-theme="dark"] .tos-toast, html.tos-dark .tos-toast { background: var(--bg-soft); }
html[data-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator, html.tos-dark input[type="date"]::-webkit-calendar-picker-indicator,
html[data-theme="dark"] input[type="time"]::-webkit-calendar-picker-indicator, html.tos-dark input[type="time"]::-webkit-calendar-picker-indicator { filter: invert(1) opacity(0.65); }
html[data-theme="dark"] .iti__country-list, html.tos-dark .iti__country-list { background: var(--surface); color: var(--text); }

/* ============================================================
   37. Avatar (profile picture) 25 Aug 2026, shared
   The picture inside any round chip (.dr-avatar / .cu-avatar / .pt-avatar):
   the chip keeps its size and radius, the image fills it. And the picker of
   the edit modals (assets/js/avatar-picker.js).
   ============================================================ */
.tos-avatar-img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; display: block; }
.av-picker { display: flex; align-items: center; gap: 16px; padding: 4px 0 14px; margin-bottom: 14px; border-bottom: 1px solid var(--border); }
.av-picker-face { width: 64px; height: 64px; border-radius: 50%; overflow: hidden; background: var(--neutral-100); color: var(--text); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 18px; flex-shrink: 0; }
.av-picker-actions { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.av-picker-row { display: flex; gap: 8px; flex-wrap: wrap; }
.av-picker-hint { font-size: 12.5px; color: var(--text-2); }

/* ============================================================
   38. Modal tabs + summary chips + people log (26 Aug 2026, shared)
   The shape every record drawer/modal of the app takes (customers, partners,
   drivers, partnership requests): sticky header (title + status chips),
   a tab strip, a body that scrolls inside a viewport-bound card, a sticky
   footer with the actions. On phones the card is a full-height sheet.
   Markup:
     .tos-modal.tos-modal--tall > .tos-modal-card
       .tos-modal-header (title)  [+ .tos-modal-chips]
       .tos-mtabs > button.tos-mtab[data-pane=x].is-active ...
       .tos-modal-body > .tos-pane[data-pane=x].is-active ...
       .tos-modal-footer
   Tab switching is one line of JS (toggle .is-active on strip + panes and
   reset body.scrollTop); pages keep their own ids/endpoints.
   ============================================================ */
.tos-modal--tall .tos-modal-card { height: min(88vh, 900px); }
@media (max-width: 767px) {
    .tos-modal--tall:not(.tos-modal--center) > .tos-modal-card:not(.tos-dialog-card) { height: 100dvh; max-height: 100dvh; border-radius: 0; }
}
.tos-modal-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; padding: 0 20px 12px; }
.tos-modal-chips .badge { font-weight: 500; }
.tos-modal-chips .tos-chip-muted { font-size: 12.5px; color: var(--text-2); }
.tos-modal-sub { font-size: 13px; color: var(--text-2); font-weight: 400; margin-top: 2px; }
.tos-modal-head-id { display: flex; align-items: center; gap: 12px; min-width: 0; flex: 1; }
.tos-modal-head-id .tos-avatar { width: 40px; height: 40px; border-radius: 50%; background: var(--neutral-100); color: var(--text); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 14px; flex-shrink: 0; overflow: hidden; }
.tos-modal-head-text { min-width: 0; }
.tos-modal-head-text .tos-modal-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tos-mtabs { display: flex; gap: 0; padding: 0 20px; border-bottom: 1px solid var(--border); overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; flex: 0 0 auto; background: var(--surface); }
.tos-mtabs::-webkit-scrollbar { display: none; }
.tos-mtab { flex: 0 0 auto; appearance: none; background: none; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; padding: 10px 12px; min-height: 44px; font: inherit; font-size: 13.5px; font-weight: 600; color: var(--text-2); cursor: pointer; white-space: nowrap; display: inline-flex; align-items: center; gap: 6px; transition: color 0.15s ease, border-color 0.15s ease; }
.tos-mtab:hover { color: var(--text); }
.tos-mtab.is-active { color: var(--text); border-bottom-color: var(--text); }
.tos-mtab .tos-mtab-count { min-width: 18px; padding: 0 5px; border-radius: 999px; background: var(--bg-active); color: var(--text-2); font-size: 11px; font-weight: 700; line-height: 17px; text-align: center; }
.tos-mtab.is-active .tos-mtab-count { background: var(--black); color: var(--surface); }
.tos-pane { display: none; }
.tos-pane.is-active { display: block; }
.tos-imark { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; border-radius: 50%; border: 1px solid var(--border-strong); color: var(--text-3); font-size: 10px; font-weight: 700; line-height: 1; margin-left: 5px; vertical-align: 1px; cursor: help; font-style: normal; }
.tos-imark:hover { color: var(--text); border-color: var(--text); }
.tos-sec { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--text-3); margin: 18px 0 10px; }
.tos-sec.is-first { margin-top: 0; }
/* people log (assets/js/people-log.js) */
.pl-sec { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--text-3); margin: 18px 0 10px; display: flex; align-items: center; gap: 8px; }
.pl-sec:first-child { margin-top: 0; }
.pl-sec .act-btn { width: 28px; height: 28px; min-height: 28px; }
.pl-list { display: flex; flex-direction: column; gap: 8px; }
.pl-row { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); }
.pl-row.is-failed { border-color: rgba(220, 38, 38, 0.35); }
.pl-main { flex: 1; min-width: 0; }
.pl-kind { font-size: 13.5px; font-weight: 600; color: var(--text); display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.pl-ref { font-size: 11.5px; }
.pl-sub { font-size: 12px; color: var(--text-2); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-err { color: var(--danger); }
.pl-side { flex-shrink: 0; }
.pl-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; display: inline-block; margin-right: 5px; }
.pl-empty { padding: 14px 0; }
.pl-activity { background: var(--bg-soft); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 12px 14px; }
.pl-activity-head { margin-bottom: 8px; }
.pl-kv .kv-row { padding: 6px 0; font-size: 13px; }
.pl-kv .kv-row:last-child { padding-bottom: 0; }
@media (max-width: 767px) { .pl-row { flex-wrap: wrap; } .pl-side { width: 100%; } }
