
[hidden],
.hidden {
    display: none !important;
}

.push-banner {
    background: #1a73e8;
    color: #fff;
    padding: 0.75rem 1rem;
    border-radius: 6px;
    margin-bottom: 1rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.push-banner button {
    background: #fff;
    color: #1a73e8;
    border: none;
    border-radius: 4px;
    padding: 0.4rem 0.8rem;
    cursor: pointer;
    white-space: nowrap;
    font-weight: 500;
}

.category-breakdown {
    margin: 0.25rem 0 0;
    padding-left: 1.2em;
    font-size: 0.8em;
    color: var(--color-gray-3);
}

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

blockquote.warning {
    border-left: 0.25rem solid var(--color-warning);
}

/* Layout variables */
:root {
    --topbar-h: 48px;
    --sidebar-w: 240px;
    /* Shared-tenant strip. The chrome below it is offset by exactly this, so the
       banner is pinned to it (min-height + nowrap) rather than free to grow. */
    --share-banner-h: 40px;
}

/* Top bar */
#topBar {
    display: none; /* JS shows when authenticated */
    position: sticky;
    top: 0;
    z-index: 2000;
    height: var(--topbar-h);
    background: var(--color-background);
    border-bottom: 1px solid var(--color-border);
}
#topBar .topbar__inner {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    height: 100%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 0.75rem;
}
#topBar .topbar__spacer {
    flex: 1;
}
.nav-toggle-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 32px;
    border-radius: var(--roundness-2);
    cursor: pointer;
    color: var(--color-gray-1);
}
.nav-toggle-btn:hover {
    background: var(--color-gray-6);
    text-decoration: none;
}
@media (min-width: 768px) {
    .nav-toggle-btn {
        display: none;
    }
}
.topbar__logout {
    display: inline-flex;
    align-items: center;
}
.nav-logout {
    padding: 0.75rem 1rem 1.5rem;
}
@media (min-width: 768px) {
    .nav-logout {
        display: none;
    }
}
.topbar__status-group {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
    overflow: hidden;
}
.status-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.65rem;
    border-radius: var(--roundness-3, 999px);
    border: 1px solid var(--color-border);
    background: var(--color-background);
    color: var(--color-gray-2);
    font-size: 0.8rem;
    line-height: 1.2;
    transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
    min-width: 0;
    flex-shrink: 1;
}
button.status-chip {
    font: inherit;
    background: var(--color-background);
    cursor: pointer;
}
button.status-chip:focus-visible {
    outline: 2px solid var(--color-focus, #0dcaf0);
    outline-offset: 2px;
}
button.status-chip:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}
.status-chip__icon {
    font-size: 1rem;
    line-height: 1;
}
.status-chip__label {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* A phone has room for the connection and sync icons only; cut to "Co…" the labels said
   nothing. The label stays for screen readers and in the title. Scoped to the status group:
   the scope switcher wears the same class, and whose books you are in must stay legible.
   Neither the chips nor their group give way (the chips in elements say so themselves):
   squeezed, a chip ended narrower than its icon, and the group cut off the last one. The
   scope chip is the one that shrinks. */
@media (max-width: 767px) {
    .topbar__status-group {
        flex-shrink: 0;
    }
    .topbar__status-group .status-chip {
        flex-shrink: 0;
        padding: 0.3rem 0.45rem;
    }
    /* No room beside the status chips; the menu has it. */
    .topbar__logout {
        display: none;
    }
    .topbar__status-group .status-chip__label {
        position: absolute;
        width: 1px;
        height: 1px;
        clip-path: inset(50%);
    }
}
.status-chip[data-state="good"] {
    color: var(--color-success, #28a745);
    border-color: color-mix(in srgb, var(--color-success, #28a745) 50%, var(--color-border));
}
.status-chip[data-state="warning"] {
    color: var(--color-warning, #f0a500);
    border-color: color-mix(in srgb, var(--color-warning, #f0a500) 50%, var(--color-border));
}
.status-chip[data-state="error"] {
    color: var(--color-error, #e74c3c);
    border-color: color-mix(in srgb, var(--color-error, #e74c3c) 50%, var(--color-border));
}
.status-chip[data-state="unknown"] {
    color: var(--color-gray-3, #adb5bd);
    border-color: color-mix(in srgb, var(--color-gray-4, #6c757d) 35%, var(--color-border));
}
.status-chip[data-mode="offline"] {
    opacity: 0.65;
}
.status-chip[data-sync-indicator][data-syncing] .status-chip__icon {
    animation: sync-chip-spin 1.2s linear infinite;
}
@keyframes sync-chip-spin {
    to { transform: rotate(360deg); }
}
.db-overlay {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background: rgba(0, 0, 0, 0.6);
    z-index: 4000;
}
.db-overlay__panel {
    display: flex;
    align-items: center;
    gap: 1rem;
    max-width: 420px;
    width: 100%;
    padding: 1.25rem 1.5rem;
    border-radius: var(--roundness-3, 12px);
    border: 1px solid var(--color-border);
    background: var(--color-background);
    box-shadow: 0 15px 35px rgba(0, 0, 0, 0.45);
}
.db-overlay__icon {
    font-size: 2rem;
    color: var(--color-warning, #f0a500);
}
.db-overlay[data-tone="error"] .db-overlay__icon {
    color: var(--color-error, #e74c3c);
}
.db-overlay[data-tone="warning"] .db-overlay__icon {
    color: var(--color-warning, #f0a500);
}
.db-overlay[data-tone="info"] .db-overlay__icon {
    color: var(--color-success, #28a745);
}
.db-overlay__title {
    margin: 0;
    font-size: 1.1rem;
    color: var(--color-gray-1);
}
.db-overlay__subtitle {
    margin: 0.15rem 0 0;
    color: var(--color-gray-3);
    font-size: 0.95rem;
}
body[data-db-blocked="true"] {
    overflow: hidden;
}

.boot-overlay {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background: var(--color-background, #000);
    z-index: 4500;
    pointer-events: all;
}
.boot-overlay__panel {
    display: flex;
    align-items: center;
    gap: 1rem;
    max-width: 420px;
    width: 100%;
    padding: 1.75rem 2rem;
    border-radius: var(--roundness-3, 12px);
    border: 1px solid var(--color-border);
    background: var(--color-background);
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.55);
}
.boot-overlay__spinner {
    width: 2.5rem;
    height: 2.5rem;
    flex-shrink: 0;
    border-radius: 50%;
    border: 3px solid color-mix(in srgb, var(--color-border) 70%, transparent);
    border-top-color: var(--color-primary, #0d6efd);
    animation: boot-overlay-spin 0.9s linear infinite;
}
.boot-overlay__title {
    margin: 0;
    font-size: 1.15rem;
    color: var(--color-gray-1);
}
.boot-overlay__subtitle {
    margin: 0.2rem 0 0;
    font-size: 0.95rem;
    color: var(--color-gray-3);
}
.boot-overlay__reset {
    margin-top: 0.75rem;
    padding: 0.45rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--roundness-2, 8px);
    background: color-mix(in srgb, var(--color-background) 90%, var(--color-gray-4));
    color: var(--color-gray-1);
    font-size: 0.85rem;
    cursor: pointer;
    transition: background 0.2s ease, border-color 0.2s ease;
}
.boot-overlay__reset:hover,
.boot-overlay__reset:focus-visible {
    border-color: var(--color-primary, #0d6efd);
    background: color-mix(in srgb, var(--color-background) 75%, var(--color-primary) 25%);
    color: var(--color-light, #fff);
}
.boot-overlay__reset:focus-visible {
    outline: 2px solid var(--color-primary, #0d6efd);
    outline-offset: 2px;
}
@keyframes boot-overlay-spin {
    to {
        transform: rotate(360deg);
    }
}
body[data-boot-blocked="true"] {
    overflow: hidden;
}
body[data-boot-blocked="true"] #topBar,
body[data-boot-blocked="true"] #mainNav,
body[data-boot-blocked="true"] .nav-overlay,
body[data-boot-blocked="true"] main[page-render],
body[data-boot-blocked="true"] .app-footer,
body[data-boot-blocked="true"] .db-overlay {
    visibility: hidden;
}
body[data-boot-blocked="true"] .boot-overlay {
    visibility: visible;
}

/* Sidebar base (hidden by default; JS toggles display) */
#mainNav {
    display: none;
    background: var(--color-background);
}

/* Nav sections — #mainNav prefix overrides ul.reset / ul.reset li from feather */
#mainNav ul.nav-sections {
    display: block;
    list-style: none;
    margin: 0;
    padding: 0.5rem 0;
}
#mainNav ul.nav-sections > li.nav-section {
    display: block;
    border-bottom: 1px solid var(--color-border);
}
#mainNav ul.nav-sections > li.nav-section:last-child {
    border-bottom: none;
}

/* Direct link sections (Now, Actions) */
.nav-section__link {
    font-weight: 600;
}
/* Collapsible section headings */
.nav-section__heading {
    display: block;
    width: 100%;
    padding: 0.6rem 0.85rem;
    font-weight: 600;
    cursor: pointer;
    list-style: none;
    color: inherit;
}
.nav-section__heading::-webkit-details-marker {
    display: none;
}
.nav-section__heading::before {
    content: "\25B8";
    display: inline-block;
    width: 1em;
    margin-right: 0.25rem;
    transition: transform 0.15s ease;
}
details[open] > .nav-section__heading::before {
    transform: rotate(90deg);
}
.nav-section__heading:hover {
    background: var(--color-gray-6);
}

/* Active section indicator */
.nav-section--active .nav-section__heading {
    border-left: 3px solid var(--color-primary);
    padding-left: calc(0.85rem - 3px);
}

/* Sub-items within a section — ul.reset li override */
#mainNav .nav-section__items {
    list-style: none;
    margin: 0;
    padding: 0 0 0.3rem 0;
}
#mainNav .nav-section__items > li {
    display: block;
}
#mainNav a.button,
#mainNav a.primary-button {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.55rem 0.85rem;
    border-radius: 0;
}
#mainNav .nav-section__items a.button,
#mainNav .nav-section__items a.primary-button {
    padding-left: 1.6rem;
}

/* Desktop/Tablet: fixed left sidebar */
@media (min-width: 768px) {
    #mainNav {
        position: fixed;
        left: 0;
        top: var(--topbar-h);
        width: var(--sidebar-w);
        height: calc(100vh - var(--topbar-h));
        overflow-y: auto;
        border-right: 1px solid var(--color-border);
        z-index: 150;
    }
    /* Push content to the right when sidebar is visible */
    body.has-sidebar #mainNav ~ main[page-render] {
        margin-left: var(--sidebar-w);
    }
}

/* Mobile: off-canvas drawer controlled by checkbox */
@media (max-width: 767px) {
    #mainNav {
        position: fixed;
        top: var(--topbar-h);
        left: -100vw;
        width: min(85vw, 320px);
        height: calc(100vh - var(--topbar-h));
        overflow-y: auto;
        border-right: 1px solid var(--color-border);
        /* Off screen is not gone: closed, its links (Logout among them) must not take Tab or a
           screen reader. Hidden once it has slid out. */
        visibility: hidden;
        transition: left 0.2s ease, visibility 0s linear 0.2s;
        z-index: 300;
    }
    /* When toggled, slide in */
    #navToggle:checked ~ #mainNav {
        left: 0;
        visibility: visible;
        transition: left 0.2s ease;
    }
    /* Full-screen overlay to close the drawer */
    .nav-overlay {
        display: none;
    }
    #navToggle:checked ~ .nav-overlay {
        display: block;
        position: fixed;
        top: var(--topbar-h);
        left: min(85vw, 320px);
        right: 0;
        bottom: 0;
        background: rgba(0,0,0,0.35);
        z-index: 250;
    }
}

/* Content spacing below the top bar */
body.has-sidebar main[page-render] {
    padding-top: var(--topbar-h);
}

/* A heading with an inline "add" affordance lays out as a flex row so the
   action icon(s) sit inline at the right, vertically centred with the title,
   instead of the .addSign float below, which could wrap the icon under the
   title. The home page already does this via .page-heading; its icons live in
   a .heading-actions span (not a direct child here), so it keeps its own rule.
   Only ADD scoped rules — the base .addSign is left untouched so nothing else
   that relies on it (e.g. the home icons) shifts. */
h1:has(> .addSign),
h2:has(> .addSign),
h3:has(> .addSign) {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
/* Een lange samenstelling moet kunnen afbreken, anders duwt hij de pagina breder dan het
   scherm. Gemeten op 390px: "Grootboekrekeningen" werd 393px breed en de hele pagina schoof
   19px mee, met een h1 van 358px eromheen. Een Nederlandse fout die in het Engels
   ("Ledgers") nooit opvalt -- en dus een die je alleen in de Nederlandse weergave ziet.

   Op de kop EN op de kinderen: de titel zit soms in een eigen span, en overflow-wrap werkt
   op het element dat de tekst bevat. min-width 0 is voor de flex-variant hieronder, waar
   een item anders niet onder zijn min-content krimpt -- bij één onbreekbaar woord is dat de
   volle woordbreedte. */
h1,
h2,
h3,
h1 > *,
h2 > *,
h3 > * {
    min-width: 0;
    /* `hyphens` EERST, want die breekt op een lettergreep en zet er een koppelteken bij
       ("Bankreke-ningen"). overflow-wrap staat er alleen achter als vangnet voor een woord
       waar geen afbreekpatroon voor is; die breekt namelijk op een willekeurige letter, en
       dat las als "Bankrekeninge / n" -- netter dan een schuivende pagina, maar lelijk.
       Afbreekpatronen komen uit het `lang`-attribuut, dat de taalwisselaar al zet. */
    hyphens: auto;
    overflow-wrap: break-word;
}
/* 32px kop naast twee icoontjes laat op een telefoon ~270px over, en
   "Bankrekeningen" vraagt er 281 -- net te weinig, waarna het woord middenin brak
   ("Bankrekeninge / n"). Chrome heeft hier geen Nederlands afbreekpatroon, dus `hyphens`
   redt het niet; een kop die op een klein scherm wat kleiner staat wel, en dat is daar
   toch beter. Gemeten op 390px. */
@media (max-width: 30rem) {
    h1 {
        font-size: 1.625rem;
    }
}
h1:has(> .addSign) > .addSign,
h2:has(> .addSign) > .addSign,
h3:has(> .addSign) > .addSign {
    /* De min-width: 0 hierboven geldt ook voor deze icoontjes, en met de standaard
       flex-shrink zouden ze een deel van elke overloop absorberen en gaan samendrukken --
       dezelfde "de knop is niet meer te raken"-fout die deze wijziging juist oplost. */
    flex-shrink: 0;
    margin-top: 0; /* flex centres them; drop the float-era nudge in this scope */
    margin-left: auto; /* the first icon pushes the whole group to the right */
}
/* Keep several icons grouped at the right (gap handles spacing); class-based so
   a mixed anchor/button or a preceding non-.addSign sibling can't break it.
   `:not([hidden])` because `data-requires` hides an icon with the hidden ATTRIBUTE and
   `~` matches a hidden sibling just the same: without it, a role that may not see the
   first icon loses the `margin-left: auto` that right-aligns the whole group, and the
   remaining icon sits against the title. Only reachable once a heading carries two. */
h1:has(> .addSign) > .addSign:not([hidden]) ~ .addSign,
h2:has(> .addSign) > .addSign:not([hidden]) ~ .addSign,
h3:has(> .addSign) > .addSign:not([hidden]) ~ .addSign {
    margin-left: 0;
}
.addSign {
    color: var(--color-primary);
    float: right;
    vertical-align: top;
    cursor: pointer;
    margin-top: -12px;
}
.addSign:hover {
    background-color: var(--color-gray-6);
    text-decoration: none;
    color: var(--color-gray-4);
}

input:user-invalid {
    border-color: var(--color-error);
}

select[is="select-collection"] {
    height: fit-content;
    min-height: 130px;
}

/* In the footer's flow: pinned to the corner it sat on top of the menu's last item. */
.app-version {
    font-size: 11px;
    color: var(--color-gray-4);
    opacity: 0.6;
    user-select: text;
}

/* When Assistant is docked on desktop, push main content */
body.assistant-docked main[page-render] {
    margin-right: var(--assistant-dock-width, 420px);
    transition: margin-right 0.2s ease;
}
@media (max-width: 1024px) {
    body.assistant-docked main[page-render] {
        margin-right: 0;
    }
}

/* Keep top bar content visible when Assistant is docked */
@media (min-width: 1025px) {
    body.assistant-docked #topBar .topbar__inner {
        padding-right: calc(var(--assistant-dock-width, 420px) + 0.75rem);
    }
}
loading-animation {
    display: block;
    width: 32px;
    margin: 2rem auto;
}

blockquote.warning {
    border-left: 0.25rem solid var(--color-warning);
}

/* Layout variables */
:root { --topbar-h: 48px; --sidebar-w: 240px; }

/* The root paints itself rather than borrowing body's background: Android colours the bar below an
   installed app from it. */
html { background-color: var(--color-background); }

body {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    overflow-x: hidden;
}

main[page-render] {
    flex: 1 0 auto;
    /* Fill the space next to the sidebar with gutters. Pages set their own inner
       widths (readable list vs. wide table). No max-width here: a single cap
       without centering would left-anchor content beside the fixed sidebar on
       wide screens, and centering can't work while the sidebar is position:fixed. */
    box-sizing: border-box;
    padding-inline: clamp(1rem, 3vw, 2.75rem);
}
/* The Assistant's round button sits in a phone's bottom corner: the last control of a page must
   be able to scroll clear of it, and the footer below main is not always tall enough for that. */
@media (max-width: 767px) {
    body.has-assistant main[page-render] {
        padding-bottom: 4.5rem;
    }
}

/* The open terminals' bar floats at the bottom at every width (terminal-layer-element.js): the
   footer's links, the last controls on any page, must be able to scroll clear of it. */
body.has-terminal-dock .app-footer {
    padding-bottom: 5.5rem;
}

.app-footer {
    flex-shrink: 0;
    margin-top: 2rem;
    padding: 1rem;
    border-top: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    gap: 1rem;
    color: var(--color-gray-2);
    font-size: 0.9rem;
}
.app-footer__links a {
    margin-right: 1rem;
    color: inherit;
}
.app-footer__links a:hover {
    color: var(--color-primary);
    text-decoration: underline;
}

@media (min-width: 768px) {
    body.has-sidebar .app-footer {
        margin-left: var(--sidebar-w);
    }
}

/* NB: everything below is intentionally GLOBAL. The @media above previously ran
   unclosed, trapping all the wizard styling as desktop-only, so both wizards
   were under-styled on a phone (#402). */
wizard-form {
    display: block;
    /* Steady width so the content-hugging modal doesn't jump size between steps
       (a one-field step would otherwise shrink to that field); capped to the
       modal on a phone. */
    width: 26rem;
    max-width: 100%;
}

/* Full-width fields for the action-add wizard. input-duration is excluded — it's
   an inline-flex pill that hugs its own segments and shouldn't stretch. (The
   onboarding wizard keeps its own .time-row flex layout.) */
#actionAddWizard input:not([type="radio"]):not([type="checkbox"]),
#actionAddWizard select {
    width: 100%;
}

wizard-form section {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
}

wizard-form .hidden {
    display: none !important;
}

wizard-form h3 {
    margin: 0;
}

wizard-form .step-hint {
    margin: -0.25rem 0 0.35rem;
    color: var(--color-gray-3);
}

.location-choice,
.preset-buttons {
    display: grid;
    gap: 0.5rem;
}

.preset-buttons {
    grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}

.location-option,
.preset-buttons label {
    position: relative;
}

.location-option input[type="radio"],
.preset-buttons input[type="radio"] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: pointer;
}

.location-option span,
.preset-option {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.85rem 1rem;
    border: 0.063rem solid var(--color-border);
    border-radius: var(--roundness-2);
    background: var(--color-gray-8);
    color: var(--color-gray-1);
    font-weight: 600;
    min-height: 48px;
    transition: background-color 0.2s ease, border-color 0.2s ease,
        color 0.2s ease;
    pointer-events: none;
}

.location-option input[type="radio"]:focus-visible + span,
.preset-buttons input[type="radio"]:focus-visible + span {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.location-option input[type="radio"]:checked + span,
.preset-buttons input[type="radio"]:checked + span {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

.location-option input[type="radio"] ~ span::before,
.location-option input[type="radio"] ~ span::after,
.preset-buttons input[type="radio"] ~ span::before,
.preset-buttons input[type="radio"] ~ span::after {
    content: none;
}

wizard-form .address-picker {
    border: 0.063rem solid var(--color-border);
    border-radius: var(--roundness-2);
    padding: 0.75rem;
    background: var(--color-gray-8);
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

wizard-form .address-picker.is-muted {
    opacity: 0.5;
    pointer-events: none;
}

wizard-form .address-picker label {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    font-weight: 600;
    margin: 0;
}

wizard-form .address-actions {
    display: inline-flex;
    gap: 0.35rem;
}

wizard-form .address-preview {
    margin: 0;
    color: var(--color-gray-3);
}

wizard-form .location-summary {
    margin: 0.25rem 0 0;
    color: var(--color-gray-3);
}

wizard-form .suggestion-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

wizard-form .suggestion-row input[type="datetime-local"] {
    flex: 1;
    min-width: 220px;
}

wizard-form .suggestion-note {
    margin: 0;
    color: var(--color-gray-3);
}

wizard-form .repeat-block {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

wizard-form #recurringSettings {
    border: 0.063rem solid var(--color-border);
    border-radius: var(--roundness-2);
    padding: 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

wizard-form #recurrenceActionList {
    margin: 0;
    padding-left: 1rem;
}

/* Whose administration a "shared with me" card is — the identity you pick by,
   so it outranks the role line beneath it (#355). */
.share-card__owner {
    font-weight: 600;
}

/* Shared-tenant strip (#296/#355). "You are in someone else's data" is global
   state, not page content, so it spans the FULL width above every other chrome
   layer and stays put while scrolling — the sidebar can never clip it. All of
   this is gated on .has-share-banner (set by share-banner-element when it
   actually renders), so an ordinary own-tenant session is untouched.
   The strip overlays the top of the viewport, so the whole document flow shifts
   down by its height; #mainNav is FIXED, so body padding misses it — it gets an
   explicit offset instead. */
body.has-share-banner {
    padding-top: var(--share-banner-h);
}
body.has-share-banner share-banner {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2500; /* above #topBar (2000) */
}
body.has-share-banner #topBar {
    top: var(--share-banner-h);
}
body.has-share-banner #mainNav {
    top: calc(var(--topbar-h) + var(--share-banner-h));
    height: calc(100vh - var(--topbar-h) - var(--share-banner-h));
}

/* Terms-gate strip (#488). Same layer and same offsets as the shared-tenant strip
   above — "your changes are staying on this device" is global state that must not be
   scrollable out of view. The two never coexist: the gate is skipped in a shared
   context, so the offsets below can reuse --share-banner-h without stacking. */
/* Beats `body.has-terms-gate .terms-gate` (0,2,1), which it otherwise loses to — an
   ordering where the class is still set while the strip is hidden would paint an empty
   40px bar. */
.terms-gate[hidden],
body.has-terms-gate .terms-gate[hidden] {
    display: none;
}
body.has-terms-gate {
    padding-top: var(--share-banner-h);
}
body.has-terms-gate .terms-gate {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2500;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    height: var(--share-banner-h);
    box-sizing: border-box;
    padding: 0 1rem;
    font-size: 0.95rem;
    background: var(--color-danger, #e5534b);
    color: #fff;
}
/* Gated but not actually offline: writes are being refused outright, so it is not the
   reassuring state the red strip otherwise describes. */
body.has-terms-gate .terms-gate[data-state="blocked"] {
    background: var(--color-warning, #ffca28);
    color: #222;
}
.terms-gate__message {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.terms-gate__action {
    flex: none;
    color: inherit;
    font-weight: 600;
    text-decoration: underline;
}
body.has-terms-gate #topBar {
    top: var(--share-banner-h);
}
body.has-terms-gate #mainNav {
    top: calc(var(--topbar-h) + var(--share-banner-h));
    height: calc(100vh - var(--topbar-h) - var(--share-banner-h));
}
