/* ==========================================================================
   Steward design system — ported from the Lovable reference
   (https://steward-church-funds.lovable.app). "Liquid glass" tiffany theme:
   translucent blurred navigation, pill-shaped controls, soft card shadows.
   Colors use the CSS oklch() function with the exact channel values captured
   from the reference site's compiled stylesheet, so hues match precisely.
   ========================================================================== */

:root {
    --radius: 1rem;

    /* Tells the browser to render native controls (select dropdowns,
       scrollbars, checkboxes) with light-appropriate colors; overridden to
       dark below so dropdown popups aren't stuck with a white background. */
    color-scheme: light;

    --background: oklch(99% .008 190);
    --foreground: oklch(24% .03 210);
    --card: oklch(100% 0 0);
    --card-foreground: oklch(24% .03 210);
    --popover: oklch(100% 0 0);
    --popover-foreground: oklch(24% .03 210);
    --primary: oklch(78% .115 187);
    --primary-foreground: oklch(22% .035 210);
    --secondary: #f7e7ce;
    --secondary-foreground: #4a3b28;
    --tertiary: #d2b48c;
    --tertiary-foreground: #3d2f1f;
    --quaternary: #ffc1cc;
    --quaternary-foreground: #5c2a35;
    --quinary: #d5d5d5;
    --quinary-foreground: #2f2f2f;
    --muted: oklch(96% .015 195);
    --muted-foreground: oklch(52% .03 208);
    --accent: oklch(90% .07 190);
    --accent-foreground: oklch(24% .04 210);
    --destructive: oklch(60% .2 25);
    --destructive-foreground: oklch(99% .005 200);
    --border: oklch(90% .025 195);
    --input: oklch(90% .025 195);
    --ring: oklch(78% .115 187);

    --gradient-tiffany: linear-gradient(135deg, oklch(86% .09 188), oklch(72% .12 195));
    --shadow-soft: 0 10px 30px -12px oklch(72% .12 195 / .35);
    --shadow-card: 0 2px 10px -4px oklch(60% .05 205 / .18);
    --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / .05);
}

/* Dark palette, matching the reference's .dark tokens 1:1. Applied from OS/browser
   preference unless overridden by the footer's dark-mode switch, which stamps
   data-theme on <html> (see wwwroot/js/theme.js) and wins either direction. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;
        --background: oklch(12.9% .042 264.695);
        --foreground: oklch(98.4% .003 247.858);
        --card: oklch(20.8% .042 265.755);
        --card-foreground: oklch(98.4% .003 247.858);
        --popover: oklch(20.8% .042 265.755);
        --popover-foreground: oklch(98.4% .003 247.858);
        --primary: oklch(92.9% .013 255.508);
        --primary-foreground: oklch(20.8% .042 265.755);
        --secondary: oklch(27.9% .041 260.031);
        --secondary-foreground: oklch(98.4% .003 247.858);
        --muted: oklch(27.9% .041 260.031);
        --muted-foreground: oklch(70.4% .04 256.788);
        --accent: oklch(27.9% .041 260.031);
        --accent-foreground: oklch(98.4% .003 247.858);
        --destructive: oklch(70.4% .191 22.216);
        --destructive-foreground: oklch(98.4% .003 247.858);
        --border: oklch(100% 0 0 / .1);
        --input: oklch(100% 0 0 / .15);
        --ring: oklch(55.1% .027 264.364);
    }
}

:root[data-theme="dark"] {
    color-scheme: dark;
    --background: oklch(12.9% .042 264.695);
    --foreground: oklch(98.4% .003 247.858);
    --card: oklch(20.8% .042 265.755);
    --card-foreground: oklch(98.4% .003 247.858);
    --popover: oklch(20.8% .042 265.755);
    --popover-foreground: oklch(98.4% .003 247.858);
    --primary: oklch(92.9% .013 255.508);
    --primary-foreground: oklch(20.8% .042 265.755);
    --secondary: oklch(27.9% .041 260.031);
    --secondary-foreground: oklch(98.4% .003 247.858);
    --muted: oklch(27.9% .041 260.031);
    --muted-foreground: oklch(70.4% .04 256.788);
    --accent: oklch(27.9% .041 260.031);
    --accent-foreground: oklch(98.4% .003 247.858);
    --destructive: oklch(70.4% .191 22.216);
    --destructive-foreground: oklch(98.4% .003 247.858);
    --border: oklch(100% 0 0 / .1);
    --input: oklch(100% 0 0 / .15);
    --ring: oklch(55.1% .027 264.364);
}

/* ---------- Reset & base ---------- */

*, *::before, *::after {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    padding: 0;
}

body {
    font-family: 'Manrope', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    background-color: var(--background);
    color: var(--foreground);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
    margin: 0;
    font-weight: 800;
    letter-spacing: -0.01em;
}

a {
    color: inherit;
}

code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* ---------- Layout shell ---------- */

.app-shell {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

.app-main {
    flex: 1;
    width: 100%;
    max-width: 72rem;
    margin: 0 auto;
    padding: 1.5rem 1rem 2rem;
}

@media (max-width: 639px) {
    .app-main {
        padding-bottom: 6rem; /* clears the fixed bottom nav */
    }
}

/* ---------- Glass header (top nav) ---------- */

.app-header {
    position: sticky;
    top: 0;
    z-index: 30;
    border-bottom: 1px solid color-mix(in oklab, var(--border) 70%, transparent);
    background-color: color-mix(in oklab, var(--background) 85%, transparent);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}

.app-header-inner {
    max-width: 72rem;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .75rem 1rem;
}

.brand {
    display: flex;
    align-items: center;
    gap: .5rem;
    text-decoration: none;
    flex-shrink: 0;
}

.brand-logo-img {
    width: 2.25rem;
    height: 2.25rem;
    object-fit: contain;
    flex-shrink: 0;
    display: block;
}

.brand-logo-img-lg {
    width: 3.25rem;
    height: 3.25rem;
}

.brand-wordmark {
    display: flex;
    flex-direction: column;
    justify-content: center;
    line-height: 1.05;
}

.brand-name {
    font-size: 1.125rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    white-space: nowrap;
}

.brand-name-lg {
    font-size: 1.5rem;
}

.brand-tagline {
    margin-top: .1875rem;
    font-size: .625rem;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--muted-foreground);
    white-space: nowrap;
}

.nav-pills {
    display: flex;
    align-items: center;
    gap: .25rem;
}

@media (max-width: 639px) {
    .nav-pills {
        display: none;
    }
}

.nav-pill {
    border-radius: 9999px;
    padding: .5rem 1rem;
    font-size: .875rem;
    font-weight: 600;
    color: var(--muted-foreground);
    text-decoration: none;
    white-space: nowrap;
    transition: background-color .15s ease, color .15s ease;
}

    .nav-pill:hover {
        background-color: var(--secondary);
        color: var(--foreground);
    }

    .nav-pill.active {
        background-color: var(--secondary);
        color: var(--foreground);
    }

/* A nav pill that opens a menu (e.g. Reports); reuses the settings menu panel. */
.nav-dropdown {
    position: relative;
}

    .nav-dropdown > .nav-pill {
        display: inline-flex;
        align-items: center;
        gap: .25rem;
        border: none;
        background: transparent;
        font-family: inherit;
        cursor: pointer;
    }

        .nav-dropdown > .nav-pill.active,
        .nav-dropdown > .nav-pill[aria-expanded="true"] {
            background-color: var(--secondary);
            color: var(--foreground);
        }

.nav-dropdown-caret {
    font-size: .75rem;
}

.settings-menu-panel.nav-dropdown-panel {
    left: 0;
    right: auto;
}

.header-right {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    min-width: 0;
}

.settings-menu {
    position: relative;
}

.header-right-row {
    display: flex;
    align-items: center;
    gap: .5rem;
}

.org-name {
    display: flex;
    align-items: center;
    gap: .375rem;
    font-size: .8125rem;
    font-weight: 700;
    color: var(--foreground);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 12rem;
}

    .org-name svg {
        width: .9rem;
        height: .9rem;
        color: var(--primary);
        flex-shrink: 0;
    }

.settings-menu-trigger {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    flex-shrink: 0;
    border: none;
    border-radius: 9999px;
    background-color: var(--secondary);
    color: var(--secondary-foreground);
    cursor: pointer;
    transition: filter .15s ease;
    -webkit-tap-highlight-color: transparent;
}

    .settings-menu-trigger svg {
        width: 1.1rem;
        height: 1.1rem;
    }

    .settings-menu-trigger:hover,
    .settings-menu-trigger[aria-expanded="true"] {
        filter: brightness(.97);
    }

.settings-menu-panel {
    position: absolute;
    top: calc(100% + .5rem);
    right: 0;
    z-index: 40;
    min-width: 12rem;
    max-width: calc(100vw - 2rem);
    padding: .375rem;
    background-color: var(--popover);
    color: var(--popover-foreground);
    border: 1px solid color-mix(in oklab, var(--border) 70%, transparent);
    border-radius: 1rem;
    box-shadow: 0 20px 60px -12px oklch(0% 0 0 / .35);
    animation: modal-scale-in .15s cubic-bezier(.34,1.36,.64,1);
}

.settings-menu-item {
    display: flex;
    align-items: center;
    gap: .625rem;
    padding: .5rem .625rem;
    border-radius: .625rem;
    font-size: .875rem;
    font-weight: 600;
    color: var(--foreground);
    text-decoration: none;
    white-space: nowrap;
}

    .settings-menu-item svg {
        width: 1rem;
        height: 1rem;
        flex-shrink: 0;
        color: var(--muted-foreground);
    }

    .settings-menu-item:hover,
    .settings-menu-item.active {
        background-color: var(--secondary);
        color: var(--foreground);
    }

.settings-menu-divider {
    margin: .375rem .25rem;
    border-top: 1px solid color-mix(in oklab, var(--border) 70%, transparent);
}

/* ---------- Fixed bottom nav (mobile) ---------- */

.bottom-nav {
    display: none;
}

@media (max-width: 639px) {
    .bottom-nav {
        display: flex;
        position: fixed;
        inset-inline: 0;
        bottom: 0;
        z-index: 30;
        border-top: 1px solid var(--border);
        background-color: color-mix(in oklab, var(--card) 95%, transparent);
        -webkit-backdrop-filter: blur(8px);
        backdrop-filter: blur(8px);
    }
}

.bottom-nav-inner {
    display: flex;
    align-items: stretch;
    width: 100%;
}

.bottom-nav-link {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .25rem;
    padding: .75rem 0;
    font-size: .6875rem;
    font-weight: 600;
    color: var(--muted-foreground);
    text-decoration: none;
}

    .bottom-nav-link svg {
        width: 1.25rem;
        height: 1.25rem;
    }

    .bottom-nav-link.active {
        color: var(--primary);
    }

/* ---------- Page heading ---------- */

.page-heading {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
}

.page-title {
    font-size: 1.5rem;
    font-weight: 800;
    letter-spacing: -0.01em;
}

.page-subtitle {
    margin: .25rem 0 0;
    font-size: .875rem;
    font-weight: 500;
    color: var(--muted-foreground);
}

/* ---------- Buttons ---------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    white-space: nowrap;
    font-family: inherit;
    font-size: .875rem;
    font-weight: 600;
    border: none;
    border-radius: 9999px;
    height: 2.25rem;
    padding: 0 1rem;
    cursor: pointer;
    transition: background-color .15s ease, filter .15s ease, opacity .15s ease, box-shadow .15s ease;
}

    .btn svg {
        width: 1rem;
        height: 1rem;
        flex-shrink: 0;
        pointer-events: none;
    }

    .btn:disabled {
        opacity: .5;
        cursor: not-allowed;
        pointer-events: none;
    }

    .btn:focus-visible {
        outline: none;
        box-shadow: 0 0 0 2px var(--background), 0 0 0 4px var(--ring);
    }

.btn-lg {
    height: 2.5rem;
    padding: 0 2rem;
}

.btn-sm {
    height: 2rem;
    padding: 0 .75rem;
    font-size: .8125rem;
}

.btn-primary {
    background-color: var(--primary);
    color: var(--primary-foreground);
    box-shadow: var(--shadow-sm);
}

    .btn-primary:hover {
        filter: brightness(1.05);
    }

.btn-secondary {
    background-color: var(--secondary);
    color: var(--secondary-foreground);
    box-shadow: var(--shadow-sm);
}

    .btn-secondary:hover {
        filter: brightness(.97);
    }

.btn-outline {
    background-color: transparent;
    color: var(--foreground);
    border: 1px solid var(--border);
}

    .btn-outline:hover {
        background-color: var(--secondary);
    }

.btn-destructive-outline {
    background-color: transparent;
    color: var(--destructive);
    border: 1px solid color-mix(in oklab, var(--destructive) 40%, transparent);
}

    .btn-destructive-outline:hover {
        background-color: color-mix(in oklab, var(--destructive) 10%, transparent);
    }

.btn-ghost {
    background-color: transparent;
    color: var(--muted-foreground);
    padding: 0 .5rem;
}

    .btn-ghost:hover {
        background-color: var(--secondary);
        color: var(--foreground);
    }

/* ---------- Card ---------- */

.card {
    background-color: var(--card);
    color: var(--card-foreground);
    border: 1px solid color-mix(in oklab, var(--border) 70%, transparent);
    border-radius: 1rem;
    box-shadow: var(--shadow-card);
}

.card-body {
    padding: 1.5rem;
}

.card-title {
    font-size: 1.0625rem;
    font-weight: 700;
}

.card-description {
    margin: .25rem 0 0;
    font-size: .8125rem;
    color: var(--muted-foreground);
}

/* ---------- Inputs ---------- */

.field {
    display: flex;
    flex-direction: column;
    gap: .375rem;
    margin-bottom: 1rem;
}

.field-label {
    font-size: .8125rem;
    font-weight: 600;
    color: var(--foreground);
}

.input {
    display: flex;
    width: 100%;
    height: 2.25rem;
    border: 1px solid var(--input);
    background-color: transparent;
    border-radius: 9999px;
    padding: 0 1rem;
    font-family: inherit;
    font-size: .875rem;
    color: var(--foreground);
    box-shadow: var(--shadow-sm);
    transition: box-shadow .15s ease, border-color .15s ease;
}

    .input::placeholder {
        color: var(--muted-foreground);
    }

    .input:focus {
        outline: none;
        border-color: var(--ring);
        box-shadow: 0 0 0 1px var(--ring);
    }

select.input {
    -webkit-appearance: none;
    appearance: none;
    padding-right: 2.25rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2352606e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .75rem center;
    background-size: 1rem;
    cursor: pointer;
}

    /* Belt-and-suspenders for the dropdown popup itself: color-scheme (above)
       drives most browsers' native rendering, but Chromium/Firefox also honor
       an explicit color/background on <option>, which color-scheme alone
       doesn't guarantee on every platform. */
    select.input option {
        background-color: var(--popover);
        color: var(--popover-foreground);
    }

/* ---------- List toolbar (search) ---------- */

.list-toolbar {
    display: flex;
    align-items: center;
    gap: .75rem;
    flex-wrap: wrap;
    padding: 1.25rem 1.5rem;
    border-bottom: 1px solid var(--border);
}

.search-wrap {
    position: relative;
    flex: 1;
    min-width: 12rem;
}

    .search-wrap svg {
        position: absolute;
        left: .875rem;
        top: 50%;
        transform: translateY(-50%);
        width: 1rem;
        height: 1rem;
        color: var(--muted-foreground);
        pointer-events: none;
    }

.search-input {
    padding-left: 2.25rem;
}

/* ---------- Badge ---------- */

.badge {
    display: inline-flex;
    align-items: center;
    border-radius: .5rem;
    padding: .125rem .625rem;
    font-size: .75rem;
    font-weight: 600;
    white-space: nowrap;
}

.badge-muted {
    background-color: var(--muted);
    color: var(--muted-foreground);
}

.badge-active {
    background-color: var(--primary);
    color: var(--primary-foreground);
    box-shadow: var(--shadow-sm);
}

.badge-resigned {
    background-color: var(--secondary);
    color: var(--secondary-foreground);
}

/* ---------- Table ---------- */

.table-card {
    overflow: hidden;
}

.table-scroll {
    overflow-x: auto;
}

table.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: .875rem;
}

    .data-table thead tr {
        border-bottom: 1px solid var(--border);
    }

    .data-table th {
        height: 2.5rem;
        padding: 0 .5rem;
        text-align: left;
        font-weight: 600;
        font-size: .8125rem;
        color: var(--muted-foreground);
    }

    .data-table td {
        padding: .625rem .5rem;
        vertical-align: middle;
    }

    .data-table tbody tr {
        border-bottom: 1px solid var(--border);
        transition: background-color .15s ease;
    }

        .data-table tbody tr:last-child {
            border-bottom: none;
        }

        .data-table tbody tr:hover {
            background-color: color-mix(in oklab, var(--muted) 50%, transparent);
        }

    .data-table .cell-name {
        font-weight: 600;
    }

    .data-table .cell-muted {
        color: var(--muted-foreground);
    }

    .data-table .cell-subtext {
        margin-top: .125rem;
        font-size: .75rem;
        font-weight: 500;
        color: var(--muted-foreground);
    }

    .data-table .cell-actions {
        display: flex;
        gap: .375rem;
        justify-content: flex-end;
    }

    .data-table th.text-right, .data-table td.text-right {
        text-align: right;
    }

    .data-table tfoot .data-table-summary td {
        border-top: 1px solid var(--border);
        padding-top: .75rem;
        font-weight: 700;
        color: var(--foreground);
    }

/* Mirrors the desktop table's summary row for the mobile card list. */
.mobile-row-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-weight: 700;
    color: var(--foreground);
}

/* ---------- Tree table ---------- */

.table-group-row td {
    padding-top: 1rem;
    font-weight: 600;
    font-size: .8125rem;
    color: var(--muted-foreground);
    text-transform: uppercase;
    letter-spacing: .03em;
    cursor: pointer;
    user-select: none;
}

.table-group-row:hover {
    background-color: transparent !important;
}

.mobile-group-header {
    padding: .75rem 1.25rem .25rem;
    font-weight: 600;
    font-size: .8125rem;
    color: var(--muted-foreground);
    text-transform: uppercase;
    letter-spacing: .03em;
    cursor: pointer;
    user-select: none;
}

/* Export icon on a branch-group row — sits right after the group name. */
.group-export-btn {
    width: 1.75rem;
    height: 1.75rem;
    margin-left: .375rem;
    vertical-align: middle;
    color: var(--muted-foreground);
}

    .group-export-btn:hover {
        color: var(--primary);
    }

.spin {
    animation: spin 1s linear infinite;
}

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

.group-toggle {
    display: inline-block;
    margin-right: .375rem;
    transition: transform .15s ease;
}

    .group-toggle.collapsed {
        transform: rotate(-90deg);
    }

.tree-cell {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
}

.tree-connector {
    color: var(--muted-foreground);
    font-weight: 400;
}

/* ---------- Picker list (e.g. Expense Category picker) ---------- */

.picker-row {
    display: flex;
    align-items: center;
    width: 100%;
    gap: .5rem;
    padding: .625rem .75rem;
    border: none;
    background: transparent;
    border-radius: .625rem;
    font-family: inherit;
    font-size: .875rem;
    text-align: left;
    color: var(--foreground);
    cursor: pointer;
    transition: background-color .15s ease;
}

    .picker-row:hover:not(:disabled) {
        background-color: var(--secondary);
    }

    .picker-row:disabled {
        color: var(--muted-foreground);
        cursor: default;
        font-weight: 600;
    }

/* The category a transaction currently points to, shown when Browse reopens
   the picker — so editing an existing transaction doesn't leave the user
   hunting through the tree for what's already selected. */
.picker-row-selected {
    background-color: color-mix(in oklab, var(--primary) 12%, transparent);
    color: var(--primary);
    font-weight: 600;
}

    .picker-row-selected:hover:not(:disabled) {
        background-color: color-mix(in oklab, var(--primary) 18%, transparent);
    }

    .picker-row-selected svg {
        width: 1rem;
        height: 1rem;
        flex-shrink: 0;
        margin-left: auto;
    }

/* Section header grouping the picker list (e.g. "Fixed" / "Variable") — acts
   like an extra, unclickable parent level above the category tree. */
.picker-group-label {
    padding: .75rem .75rem .25rem;
    font-size: .8125rem;
    font-weight: 700;
    color: var(--foreground);
}

    .picker-group-label:first-child {
        padding-top: .25rem;
    }

/* ---------- Field with an inline action button beside the value ---------- */

.field-with-action {
    display: flex;
    align-items: center;
    gap: .5rem;
}

    .field-with-action .input {
        flex: 1;
    }

/* Mobile card list, mirrors the reference's stacked-card fallback for narrow screens */
.mobile-list {
    display: none;
}

@media (max-width: 639px) {
    .table-scroll {
        display: none;
    }

    .mobile-list {
        display: flex;
        flex-direction: column;
        gap: .75rem;
        padding: 1rem;
    }
}

.mobile-row {
    border-radius: .75rem;
    background-color: color-mix(in oklab, var(--muted) 60%, transparent);
    padding: .75rem 1rem;
}

.mobile-row-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
}

.mobile-row-name {
    font-size: .875rem;
    font-weight: 700;
}

.mobile-row-id {
    margin: .25rem 0 0;
    font-size: .75rem;
    font-weight: 500;
    color: var(--muted-foreground);
}

.mobile-row-actions {
    display: flex;
    gap: .375rem;
    margin-top: .625rem;
}

/* ---------- Sync status (footer, middle section) ---------- */

.sync-status {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    justify-content: center;
    gap: .5rem;
}

.sync-badge {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    font-size: .75rem;
    font-weight: 600;
    color: var(--muted-foreground);
}

.sync-dot {
    display: inline-block;
    width: .5rem;
    height: .5rem;
    border-radius: 9999px;
    flex-shrink: 0;
}

.sync-dot-online {
    background-color: oklch(72% .17 145);
}

.sync-dot-offline {
    background-color: oklch(75% .16 60);
}

.sync-dot-syncing {
    background-color: var(--primary);
    animation: sync-pulse 1s ease-in-out infinite;
}

@keyframes sync-pulse {
    0%, 100% {
        opacity: 1;
    }

    50% {
        opacity: .35;
    }
}

.sync-detail {
    font-size: .6875rem;
    font-weight: 500;
    color: var(--muted-foreground);
}

.sync-conflict {
    color: var(--destructive);
}

/* ---------- Misc ---------- */

.empty-state {
    padding: 2.5rem 1rem;
    text-align: center;
    color: var(--muted-foreground);
    font-size: .875rem;
}

.alert {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    border-radius: .75rem;
    padding: .75rem 1rem;
    font-size: .8125rem;
    font-weight: 600;
    margin-bottom: 1rem;
}

.alert-destructive {
    background-color: color-mix(in oklab, var(--destructive) 12%, var(--background));
    color: var(--destructive);
    border: 1px solid color-mix(in oklab, var(--destructive) 30%, transparent);
}

.alert-dismiss {
    background: none;
    border: none;
    color: inherit;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    opacity: .7;
}

    .alert-dismiss:hover {
        opacity: 1;
    }

/* ---------- Footer ---------- */

.app-footer {
    display: flex;
    align-items: center;
    gap: 1rem;
    max-width: 72rem;
    margin: 0 auto;
    width: 100%;
    padding: 1rem 1rem 1.5rem;
    border-top: 1px solid var(--border);
}

@media (max-width: 639px) {
    .app-footer {
        padding-bottom: 6rem; /* clears the fixed bottom nav */
    }
}

/* Left/right thirds share the remaining width equally, so the middle
   (sync status) section sits truly centered regardless of how wide the
   footer text or theme toggle end up being. */
.app-footer-side {
    display: flex;
    align-items: center;
    flex: 1;
    min-width: 0;
}

.app-footer-right {
    justify-content: flex-end;
}

.app-footer-middle {
    display: flex;
    justify-content: center;
    flex-shrink: 0;
}

.app-footer-text {
    font-size: .8125rem;
    font-weight: 500;
    color: var(--muted-foreground);
}

.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 9999px;
    border: 1px solid var(--border);
    background-color: var(--card);
    color: var(--foreground);
    cursor: pointer;
    flex-shrink: 0;
    transition: background-color .15s ease;
}

    .theme-toggle:hover {
        background-color: var(--secondary);
    }

    .theme-toggle svg {
        width: 1.125rem;
        height: 1.125rem;
    }

/* ---------- Modal ---------- */

.modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow-y: auto;
    padding: 1rem;
    background-color: oklch(0% 0 0 / .45);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
    animation: modal-fade-in .15s ease;
}

    /* `safe center` keeps the dialog centered when it fits, but falls back to
       start-aligned (rather than clipping the top) when it's taller than the
       viewport — letting modal-backdrop's own scroll reach the whole dialog.
       Declared as a second, separate declaration so browsers that don't
       recognize the `safe` keyword simply ignore this line and keep the
       plain `center` above instead of dropping the property entirely. */
    .modal-backdrop {
        align-items: safe center;
    }

/* Used for a picker opened "Browse"-style on top of an already-open modal —
   same fixed-full-viewport backdrop, painted above it. */
.modal-backdrop-elevated {
    z-index: 60;
}

@keyframes modal-fade-in {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

.modal-dialog {
    position: relative;
    width: 100%;
    max-width: 26rem;
    max-height: 100%;
    display: flex;
    flex-direction: column;
    background-color: var(--card);
    color: var(--card-foreground);
    border: 1px solid color-mix(in oklab, var(--border) 70%, transparent);
    border-radius: 1.25rem;
    box-shadow: 0 20px 60px -12px oklch(0% 0 0 / .35);
    animation: modal-scale-in .18s cubic-bezier(.34,1.36,.64,1);
}

/* Played when a backdrop click is deliberately ignored (modals never close on
   outside click) — a quick side-to-side nudge so the click still registers as
   feedback instead of appearing to do nothing.

   Listed together with modal-scale-in (rather than as a standalone override)
   so the entrance animation's name stays in the same list position the whole
   time modal-shake toggles on and off — if .modal-shake overrode the
   `animation` shorthand on its own, removing it would hand `animation` back
   to plain modal-scale-in, which reads as a brand new animation-name value
   and replays the opacity 0→1 entrance fade (a visible "blink") every time
   the shake ends. */
.modal-dialog.modal-shake {
    animation: modal-scale-in .18s cubic-bezier(.34,1.36,.64,1), modal-shake .35s ease;
}

@keyframes modal-shake {
    0%, 100% { transform: translateX(0); }
    20% { transform: translateX(-.5rem); }
    40% { transform: translateX(.4rem); }
    60% { transform: translateX(-.3rem); }
    80% { transform: translateX(.2rem); }
}

@keyframes modal-scale-in {
    from {
        opacity: 0;
        transform: scale(.94) translateY(6px);
    }
    to {
        opacity: 1;
        transform: scale(1) translateY(0);
    }
}

/* Near-full-screen variant — used for pickers that need room to browse a list
   (e.g. the Expense Category picker) instead of a compact form. */
.modal-dialog-full {
    max-width: 56rem;
    width: 95vw;
    height: 90vh;
    display: flex;
    flex-direction: column;
}

    .modal-dialog-full .modal-body {
        flex: 1;
        overflow-y: auto;
    }

/* Double-width variant — used by the Expense Transaction form to make room
   for the receipt image panel beside the fields. */
.modal-dialog-wide {
    max-width: 52rem;
}

.transaction-form-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 1.5rem;
}

/* Contribution form: the cash breakdown needs more room than the fields. */
.modal-dialog-contribution {
    max-width: 58rem;
}

.contribution-form-grid {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
}

/* Square icon-only button, sized to sit beside an input. */
.btn-icon {
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    flex-shrink: 0;
}

@media (max-width: 639px) {
    .transaction-form-grid {
        grid-template-columns: 1fr;
    }
}

.receipt-panel {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .625rem;
}

.receipt-dropzone {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    width: 100%;
    aspect-ratio: 4 / 3;
    border: 1px dashed var(--border);
    border-radius: .75rem;
    color: var(--muted-foreground);
    font-size: .8125rem;
    font-weight: 500;
    text-align: center;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease;
}

    .receipt-dropzone:hover {
        background-color: var(--secondary);
        border-color: var(--ring);
    }

    .receipt-dropzone svg {
        width: 1.75rem;
        height: 1.75rem;
        flex-shrink: 0;
    }

.receipt-preview-button {
    display: block;
    width: 100%;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: .75rem;
    background: transparent;
    cursor: pointer;
    overflow: hidden;
}

    .receipt-preview-button:disabled {
        cursor: not-allowed;
        opacity: .6;
    }

.receipt-preview-image {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
}

.receipt-file-input {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.receipt-error {
    margin: 0;
    font-size: .8125rem;
    color: var(--destructive);
}

.receipt-actions {
    display: flex;
    gap: .5rem;
}

/* ---------- Image viewer (e.g. full-size receipt) ---------- */

.image-viewer-body {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 1.5rem 1.5rem;
}

.image-viewer-img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: .5rem;
}

.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-shrink: 0;
    padding: 1.5rem 1.5rem 1rem;
}

.modal-title {
    font-size: 1.0625rem;
    font-weight: 700;
}

.modal-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 9999px;
    border: none;
    background: transparent;
    color: var(--muted-foreground);
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
    flex-shrink: 0;
    font-size: 1.125rem;
    line-height: 1;
}

    .modal-close:hover {
        background-color: var(--secondary);
        color: var(--foreground);
    }

.modal-body {
    padding: .5rem 1.5rem 1.5rem;
    overflow-y: auto;
    min-height: 0;
}

.modal-footer {
    display: flex;
    flex-shrink: 0;
    gap: .5rem;
    padding: 1rem 1.5rem 1.5rem;
}

@media (max-width: 639px) {
    .modal-header {
        padding: 1.25rem 1.25rem .75rem;
    }

    .modal-body {
        padding: .375rem 1.25rem 1rem;
    }

    .modal-footer {
        padding: .75rem 1.25rem 1.25rem;
        flex-wrap: wrap;
    }

    .modal-footer > * {
        flex: 1 1 auto;
    }
}

/* ---------- Page tabs ---------- */

.page-tabs {
    display: flex;
    gap: .25rem;
    margin-top: 1.25rem;
    border-bottom: 1px solid var(--border);
    padding-bottom: 0;
}

.page-tab {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    padding: .625rem 1rem;
    font-size: .875rem;
    font-weight: 600;
    color: var(--muted-foreground);
    border: none;
    background: none;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color .15s ease, border-color .15s ease;
    font-family: inherit;
}

    .page-tab:hover {
        color: var(--foreground);
    }

    .page-tab.active {
        color: var(--foreground);
        border-bottom-color: var(--primary);
    }

    a.page-tab {
        text-decoration: none;
    }

    .page-tab svg {
        width: 1rem;
        height: 1rem;
        flex-shrink: 0;
    }

/* ---------- Paged picker (e.g. Select Week) ---------- */

.pager {
    align-items: center;
}

.pager-info {
    margin-right: auto;
    font-size: .8125rem;
    color: var(--muted-foreground);
}

.picker-row .cell-subtext {
    margin-top: .125rem;
    font-size: .75rem;
    font-weight: 500;
    color: var(--muted-foreground);
}

/* ---------- Contributions ---------- */

.week-banner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem 1rem;
    margin-top: 1.25rem;
    padding: .875rem 1.25rem;
}

.week-banner-label {
    font-size: .75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--muted-foreground);
}

.week-banner-name {
    font-size: 1.125rem;
    font-weight: 800;
}

.week-banner-dates {
    font-size: .875rem;
    color: var(--muted-foreground);
}

.week-banner-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    margin-left: auto;
}

.summary-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: .75rem;
    margin-top: 1rem;
}

.summary-tile {
    padding: 1rem 1.25rem;
}

.summary-tile-label {
    font-size: .8125rem;
    font-weight: 600;
    color: var(--muted-foreground);
}

.summary-tile-value {
    margin-top: .25rem;
    font-size: 1.5rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

.summary-tile-meta {
    font-size: .75rem;
    color: var(--muted-foreground);
}

.summary-tile-grand {
    border-color: var(--primary);
}

.amount {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.table-total-row td {
    font-weight: 800;
    border-top: 2px solid var(--border);
}

.branch-link-row {
    cursor: pointer;
}

.branch-link-row .tree-cell {
    color: var(--primary);
    font-weight: 600;
}

.mobile-total {
    display: flex;
    justify-content: space-between;
    padding: .75rem 1.25rem;
    font-weight: 800;
}

/* Cash breakdown: denomination · quantity · subtotal */
.cash-breakdown {
    border: 1px solid var(--border);
    border-radius: .75rem;
    padding: .75rem;
}

.cash-breakdown-columns {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .75rem 1.25rem;
}

@media (max-width: 639px) {
    .cash-breakdown-columns {
        grid-template-columns: 1fr;
    }
}

.cash-breakdown-heading {
    font-size: .75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--muted-foreground);
    margin-bottom: .375rem;
}

.cash-row {
    display: grid;
    grid-template-columns: 3.5rem 4.5rem minmax(0, 1fr);
    align-items: center;
    gap: .5rem;
    padding: .1875rem 0;
    font-variant-numeric: tabular-nums;
}

.cash-row .input {
    height: 2rem;
    padding: 0 .75rem;
    text-align: right;
    -moz-appearance: textfield;
    appearance: textfield;
}

    /* Counts are typed, not stepped — hide the spinner arrows. */
    .cash-row .input::-webkit-outer-spin-button,
    .cash-row .input::-webkit-inner-spin-button {
        -webkit-appearance: none;
        margin: 0;
    }

.cash-row-denomination {
    font-weight: 600;
}

.cash-row-subtotal {
    text-align: right;
    font-size: .8125rem;
    color: var(--muted-foreground);
}

.cash-breakdown-total {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: .75rem;
    padding-top: .625rem;
    border-top: 1px solid var(--border);
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

.qr-video {
    width: 100%;
    max-height: 60vh;
    border-radius: .75rem;
    background: #000;
    object-fit: cover;
}

/* ---------- Tither picker (Add Tithe flow) ---------- */

/* The search box sits between the header and the scrolling result list, so it
   stays in reach while the list scrolls. */
.tither-picker-search {
    flex-shrink: 0;
    padding: 0 1.5rem .75rem;
}

    .tither-picker-search .alert {
        margin-bottom: .75rem;
    }

.tither-picker-scan {
    flex-shrink: 0;
}

.tither-picker-new-label-short {
    display: none;
}

.alert-success {
    background-color: color-mix(in oklab, oklch(62% .15 150) 12%, var(--background));
    color: oklch(48% .13 150);
    border: 1px solid color-mix(in oklab, oklch(62% .15 150) 30%, transparent);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .alert-success {
        color: oklch(80% .13 150);
    }
}

:root[data-theme="dark"] .alert-success {
    color: oklch(80% .13 150);
}

/* ---------- Full-screen modals on phones ---------- */

/* Data-entry modals used one-handed on a phone (tither picker, QR scanner,
   contribution form) take the whole screen instead of floating as a card:
   more room for the list/camera, and the footer buttons stay pinned at the
   bottom within thumb reach. */
@media (max-width: 639px) {
    .modal-backdrop-mobile-full {
        padding: 0;
        align-items: stretch;
    }

    .modal-dialog-mobile-full {
        max-width: none;
        width: 100%;
        height: 100vh;
        height: 100dvh;
        max-height: none;
        border: none;
        border-radius: 0;
        box-shadow: none;
    }

        .modal-dialog-mobile-full .modal-body {
            flex: 1;
        }

        .modal-dialog-mobile-full .modal-footer {
            padding-bottom: calc(1.25rem + env(safe-area-inset-bottom));
            border-top: 1px solid var(--border);
        }

        /* 16px inputs stop iOS Safari from zooming the page on focus. */
        .modal-dialog-mobile-full .input {
            height: 2.75rem;
            font-size: 1rem;
        }

        .modal-dialog-mobile-full .btn-icon {
            width: 2.75rem;
            height: 2.75rem;
        }

        .modal-dialog-mobile-full .modal-footer .btn {
            min-height: 2.75rem;
        }

        .modal-dialog-mobile-full .picker-row {
            padding: .875rem .75rem;
            font-size: 1rem;
        }

        .modal-dialog-mobile-full .qr-video {
            max-height: none;
            aspect-ratio: 3 / 4;
        }

    .tither-picker-search {
        padding: 0 1.25rem .75rem;
    }

    .tither-picker-scan {
        height: 2.75rem;
        padding: 0 .875rem;
    }

    /* Search + Scan + New share one row on a phone; keep the label short. */
    .tither-picker-new-label {
        display: none;
    }

    .tither-picker-new-label-short {
        display: inline;
    }
}

.field-hint {
    margin-top: .25rem;
    font-size: .75rem;
    color: var(--muted-foreground);
}

/* ---------- Auth (login / change password) ---------- */

.auth-shell {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem 1rem;
}

.auth-card {
    width: 100%;
    max-width: 24rem;
}

.auth-brand {
    justify-content: center;
    margin-bottom: 1.5rem;
}

.auth-actions {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    margin-top: .5rem;
}

    .auth-actions .btn {
        width: 100%;
        justify-content: center;
    }

/* Signed-in user block at the top of the settings menu. */
.settings-menu-user {
    padding: .5rem .625rem;
}

.settings-menu-user-name {
    font-size: .875rem;
    font-weight: 700;
    white-space: nowrap;
}

.settings-menu-user-meta {
    font-size: .75rem;
    color: var(--muted-foreground);
}

/* Menu entries that are actions rather than links (e.g. Log out). */
button.settings-menu-item {
    width: 100%;
    background: none;
    border: none;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
}

/* One-time temporary password shown after create / reset. */
.temp-password {
    display: block;
    padding: .75rem 1rem;
    border-radius: .75rem;
    background-color: var(--secondary);
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-align: center;
    user-select: all;
}

/* ---------- Settings: consolidated tither lists ---------- */

.consolidation-list {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    margin-top: 1rem;
}

.consolidation-item {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
    padding: .875rem 1rem;
    border: 1px solid var(--border);
    border-radius: .75rem;
}

    .consolidation-item p {
        margin: 0;
    }

.consolidation-chips {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
    margin-top: .5rem;
}

.consolidation-group {
    margin-top: .5rem;
}

.consolidation-group-name {
    font-size: .75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--muted-foreground);
}

.consolidation-option {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .375rem 0;
    font-size: .875rem;
    cursor: pointer;
}

    .consolidation-option.disabled {
        opacity: .55;
        cursor: not-allowed;
    }

    .consolidation-option .field-hint {
        margin-top: 0;
    }

/* Printing a report (e.g. the cash count summary): just the page content. */
@media print {
    .app-header,
    .app-footer,
    .bottom-nav,
    .no-print {
        display: none !important;
    }

    .app-main {
        max-width: none;
        padding: 0;
    }
}
