html, body {
    background-color: #191919;
}

.budgie-login-input {
    display: block;
    width: 100%;
    padding: 0.5rem;
    margin-top: 0.25rem;
    font-size: 1rem;
}

/* Below the md breakpoint the grid stacks; put the period summary first. */
.budgie-summary {
    order: -1;
}

@media (min-width: 960px) {
    .budgie-summary {
        order: 0;
    }
}

/* Someone else is currently editing this row (see LiveUpdateService locks). */
.budgie-locked-row > td {
    background-color: rgba(255, 193, 7, 0.08) !important;
}

/* Desktop: pin a page's title/nav/Add-button row below the app bar while scrolling.
   48px matches MudAppBar's rendered height with Dense="true" (NOT the --mud-appbar-height
   CSS var, which is 64px and doesn't account for Dense) - verified against the live layout,
   not assumed from the variable. The header sits perfectly flush against the app bar the
   instant it's actually stuck (measured gapAboveHeader: 0 on all three pages, even though
   they looked fine at the top of the page beforehand - that gap came from each container's
   own mt-4/mt-8 margin, which stops being visible once the header is truly pinned, since it's
   now scrolled out of view above it rather than a running gap). padding-top/bottom (not a
   bigger `top` offset) adds the breathing room instead, specifically so it doesn't leave an
   unfilled strip above the header for scrolled-up content to show through - the
   background-color still fills the padding box flush to the app bar either way. On mobile the
   inline Add button is hidden in favor of the floating one below, so the header just scrolls
   away normally there. */
@media (min-width: 600px) {
    .budgie-sticky-header {
        position: sticky;
        top: 48px;
        z-index: 10;
        background-color: #191919;
        padding-top: 12px;
        padding-bottom: 12px;
    }
}

/* Mobile floating "Add" button, replacing a page's inline Add button (hidden via d-sm-none
   on the button itself). Pair with .budgie-fab-spacer at the bottom of the page's content so
   the last item in a list can be scrolled clear of it instead of sitting permanently under it. */
.budgie-fab {
    position: fixed;
    bottom: 16px;
    right: 16px;
    z-index: 1000;
}

.budgie-fab-spacer {
    height: 88px;
}

/* Expenses page only: the Household summary sheet below occupies the bottom of the screen
   on mobile, so its FAB floats above the sheet's collapsed peek height (64px) instead of the
   screen edge, and the page needs extra bottom clearance to match. */
.budgie-fab-raised {
    bottom: 80px;
}

.budgie-fab-spacer-tall {
    height: 152px;
}

/* Mobile-only bottom sheet (see HouseholdSummarySheet.razor) replacing the desktop
   "Household"/"This Period" sidebar. Built with the classic bottom-sheet technique: the
   panel has a FIXED total height (max-height, with internal scroll if content ever
   overflows it) and sits translated down by everything except a 64px "peek" strip - that
   64px must match the handle row (24px) + collapsed line (40px) below exactly, or there's
   either a gap or the collapsed text gets clipped. Expanding is just sliding the whole
   panel up via transform, not resizing it - smoother than animating height/max-height
   because the end-state height doesn't have to be known in advance. */
.budgie-summary-sheet {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1200;
    background-color: #2d2d2d;
    border-top-left-radius: 16px;
    border-top-right-radius: 16px;
    box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.4);
    transform: translateY(calc(100% - 64px));
    transition: transform 0.25s ease;
    max-height: 75vh;
    display: flex;
    flex-direction: column;
}

.budgie-summary-sheet.budgie-summary-expanded {
    transform: translateY(0);
}

.budgie-summary-handle-row {
    position: relative;
    height: 24px;
    flex-shrink: 0;
    cursor: pointer;
}

.budgie-summary-handle {
    position: absolute;
    left: 50%;
    top: 10px;
    width: 40px;
    height: 4px;
    border-radius: 2px;
    background-color: rgba(255, 255, 255, 0.3);
    transform: translateX(-50%);
}

.budgie-summary-collapsed-line {
    height: 40px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    padding: 0 16px;
    cursor: pointer;
}

.budgie-summary-content {
    overflow-y: auto;
    padding: 0 16px 16px;
}

.budgie-summary-backdrop {
    position: fixed;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.5);
    z-index: 1190;
}

/* Phones (MudBlazor xs, under 600px) */
@media (max-width: 599.98px) {
    .mud-container {
        padding-left: 12px;
        padding-right: 12px;
    }

    .mud-typography-h4 {
        font-size: 1.75rem;
    }

    .mud-typography-h5 {
        font-size: 1.35rem;
    }

    .mud-tab {
        min-width: 0;
        padding: 6px 10px;
        font-size: 0.8rem;
    }

    .mud-table-root .mud-table-cell {
        padding-top: 6px;
        padding-bottom: 6px;
    }
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}