:root {
    --bg: #f4f5f7;
    --card-bg: #ffffff;
    --text: #1f2430;
    --muted: #6b7280;
    --primary: #b3202e;   /* nods to the New Year red */
    --primary-dark: #8c1922;
    --accent: #d4a017;    /* gold accent */
    --border: #e5e7eb;
    --success: #1a7f4e;
    --warning: #b7791f;
    --danger: #c0392b;
    --radius: 10px;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    background: var(--bg);
    color: var(--text);
}

/* --- Loading bar: shown while htmx is fetching a boosted navigation --- */
.loading-bar {
    position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 1000;
    background: linear-gradient(90deg, var(--primary), var(--accent));
    background-size: 200% 100%;
    animation: loading-sweep 1s linear infinite;
}
@keyframes loading-sweep {
    0% { background-position: 0% 0; }
    100% { background-position: 200% 0; }
}

/* --- Header / nav (never re-renders on boosted navigation - only #page-content does) --- */
.app-header {
    background: var(--card-bg);
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 10;
}
.app-header-inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 12px 24px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
}
.app-title { font-weight: 700; font-size: 1.05rem; }
.app-nav { display: flex; gap: 4px; flex-wrap: wrap; }
.app-nav a {
    padding: 8px 12px;
    border-radius: 8px;
    text-decoration: none;
    color: var(--muted);
    font-size: 0.9rem;
    font-weight: 500;
}
.app-nav a:hover { background: var(--bg); color: var(--text); }
.app-nav a.active { background: var(--primary); color: #fff; }

.nav-dropdown { position: relative; display: inline-flex; }
.nav-dropdown-toggle {
    padding: 8px 12px;
    border-radius: 8px;
    border: none;
    background: none;
    color: var(--muted);
    font-size: 0.9rem;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}
.nav-dropdown-toggle:hover { background: var(--bg); color: var(--text); }
.nav-dropdown-toggle.active { background: var(--primary); color: #fff; }
.nav-chevron { font-size: 0.7rem; }
.nav-flyout {
    display: none;
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    min-width: 220px;
    padding: 6px;
    z-index: 20;
}
.nav-flyout.open { display: block; }
.nav-flyout-item {
    display: block;
    padding: 10px 12px;
    border-radius: 8px;
    text-decoration: none;
    color: var(--text);
}
.nav-flyout-item:hover, .nav-flyout-item.active { background: var(--bg); }
.nav-flyout-title { display: block; font-size: 0.88rem; font-weight: 600; }
.nav-flyout-desc { display: block; font-size: 0.74rem; color: var(--muted); margin-top: 2px; }
.nav-flyout-hint { padding: 8px 12px; font-size: 0.76rem; color: var(--muted); }
.logout-link { color: var(--primary); text-decoration: none; font-weight: 600; font-size: 0.9rem; }
/* Public Dashboard's "Login" link - same look as .logout-link, but its own
   class on purpose: it's the only thing in that page's header, with no
   hamburger-menu drawer to fall back to on mobile, so it must never be
   caught by .logout-link's max-width:780px hide rule below (that rule
   exists only because layout_top.php's logged-in header repeats those
   same links inside #mobile-nav-drawer). */
.public-login-link { color: var(--primary); text-decoration: none; font-weight: 600; font-size: 0.9rem; }

.page-content { max-width: 1200px; margin: 0 auto; padding: 24px; }

h1 { font-size: 1.5rem; margin: 0 0 6px; }
h2 { font-size: 1.15rem; margin: 0 0 14px; }
.subtitle { color: var(--muted); margin: 0 0 24px; }

.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px; margin-bottom: 24px; }
.card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 18px 20px;
}
.card .label { color: var(--muted); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 6px; }
.card .value { font-size: 1.6rem; font-weight: 700; }

/*
 * "What does this number mean?" markers on the stat cards.
 *
 * A real <button> rather than a title attribute or a hover-only span, for two
 * reasons: a title tooltip is invisible on a phone, and a button can be tapped
 * (which focuses it) and reached by keyboard. Shown on :hover AND :focus-visible
 * so both work.
 *
 * Deliberately CSS-only, no JavaScript: public_dashboard.php renders these same
 * cards and loads no app JS at all, so anything script-driven would silently do
 * nothing there.
 */
.card { position: relative; }
.card .label { display: flex; align-items: center; gap: 6px; }
.stat-help {
    flex: 0 0 auto;
    width: 16px; height: 16px; padding: 0;
    border: 1px solid var(--border); border-radius: 50%;
    background: transparent; color: var(--muted);
    font-size: 0.68rem; font-weight: 700; line-height: 1;
    display: inline-flex; align-items: center; justify-content: center;
    cursor: help;
}
.stat-help:hover, .stat-help:focus-visible { border-color: var(--muted); color: var(--text); }
.stat-help-text {
    position: absolute; left: 16px; right: 16px; top: 100%;
    z-index: 20;
    background: var(--text); color: var(--card-bg);
    padding: 10px 12px; border-radius: var(--radius);
    font-size: 0.78rem; font-weight: 400; line-height: 1.45;
    text-transform: none; letter-spacing: 0;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
    /* Hidden without display:none, so it stays in the accessibility tree for
       the aria-describedby reference on the button. */
    opacity: 0; visibility: hidden; transform: translateY(-4px);
    /* visibility is not smoothly animatable - it flips at the END of its
       transition. Transitioning it would leave the tooltip invisible for the
       whole fade-in, i.e. lagging behind the tap. So it is delayed on the way
       OUT (to let the fade finish) and instant on the way IN. */
    transition: opacity 0.12s ease, transform 0.12s ease, visibility 0s linear 0.12s;
    pointer-events: none;
}
.stat-help:hover + .stat-help-text,
.stat-help:focus + .stat-help-text {
    opacity: 1; visibility: visible; transform: translateY(0);
    transition: opacity 0.12s ease, transform 0.12s ease, visibility 0s;
}
/* The tooltips are hidden for print in the responsive/print section at the
   bottom of this file, which is where every @media block now lives. */
.card .value.pos { color: var(--success); }
.card .value.neg { color: var(--danger); }

.panel {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px;
    margin-bottom: 20px;
    overflow-x: auto;
}

.chart-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); gap: 20px; margin-bottom: 24px; }
.chart-box { position: relative; height: 300px; }

.toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.toolbar select, .toolbar input { padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px; font-size: 0.9rem; }

table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border); }
th { color: var(--muted); font-weight: 600; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.03em; }
tbody tr:hover { background: #fafafa; }
.actions-cell { white-space: nowrap; text-align: right; }

.btn {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 8px 14px; border-radius: 8px; border: 1px solid var(--border);
    background: var(--card-bg); color: var(--text); cursor: pointer;
    font-size: 0.88rem; font-weight: 600; text-decoration: none;
}
.btn:hover { background: var(--bg); }
.btn-primary { background: var(--primary); border-color: var(--primary); color: #fff; }
.btn-primary:hover { background: var(--primary-dark); }
.btn-danger { color: var(--danger); border-color: var(--danger); }
.btn-danger:hover { background: #fdecea; }
.btn-sm { padding: 5px 10px; font-size: 0.8rem; }
.btn-block { width: 100%; justify-content: center; }

.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 14px; margin-bottom: 14px; }
.field label { display: block; font-size: 0.82rem; font-weight: 600; margin-bottom: 6px; color: var(--muted); }
.field input, .field select, .field textarea {
    width: 100%; padding: 9px 11px; border: 1px solid var(--border); border-radius: 8px; font-size: 0.9rem;
    font-family: inherit;
}
.field textarea { resize: vertical; min-height: 60px; }

/* --- Login page (standalone, no nav shell) --- */
.login-body {
    display: flex; align-items: center; justify-content: center;
    min-height: 100vh; margin: 0; padding: 16px;
}
.login-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 32px;
    width: 100%;
    max-width: 340px;
    text-align: center;
}
.login-card h1 { font-size: 1.2rem; margin-bottom: 18px; }
.login-card .field { text-align: left; margin-bottom: 14px; }

.error-banner { background: #fdecea; color: var(--danger); padding: 10px 14px; border-radius: 8px; margin-bottom: 14px; font-size: 0.88rem; }
.success-banner { background: #e8f5ee; color: var(--success); padding: 10px 14px; border-radius: 8px; margin-bottom: 14px; font-size: 0.88rem; }

.htmx-indicator { opacity: 0; transition: opacity 150ms ease; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { opacity: 1; }

.empty-state { text-align: center; padding: 40px 20px; color: var(--muted); }

/* --- Event Donations (donor cards with variable in-kind items) --- */
.muted { color: var(--muted); }

.donor-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px 18px;
    margin-bottom: 12px;
}
.donor-card-head {
    display: flex; justify-content: space-between; align-items: baseline;
    flex-wrap: wrap; gap: 8px; margin-bottom: 8px;
}
.donor-card-head .muted { font-size: 0.85rem; }
.donor-card-total { font-size: 1.1rem; font-weight: 700; white-space: nowrap; }
.donor-items { margin-bottom: 10px; }
.donor-card-actions { display: flex; gap: 8px; justify-content: flex-end; }

.item-badge {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 3px 8px 3px 10px; border-radius: 999px;
    font-size: 0.78rem; margin: 2px 4px 2px 0;
}
.cat-cash { background: #e8f5ee; color: #1a7f4e; }
.cat-building { background: #eef0fb; color: #3d4a8a; }
.cat-food { background: #faeeda; color: #854f0b; }
.cat-drinks { background: #e6f1fb; color: #185fa5; }
.cat-alcohol { background: #fbf0da; color: #a5680b; }
.cat-supplies { background: #e3f2f0; color: #0e6b5c; }
.cat-entertainment { background: #f5e9fb; color: #6a3d99; }
.cat-tax { background: #f1efe8; color: #5f5e5a; }
.cat-other { background: #fdecea; color: #c0392b; }
.badge-remove {
    background: none; border: none; cursor: pointer;
    font-size: 0.95rem; line-height: 1; color: inherit; opacity: 0.6; padding: 0;
}
.badge-remove:hover { opacity: 1; }

.item-form-grid {
    display: grid; grid-template-columns: 130px 1fr 110px auto auto;
    gap: 8px; align-items: center; margin-top: 8px;
}
.item-form-grid select, .item-form-grid input {
    padding: 7px 9px; border: 1px solid var(--border); border-radius: 8px; font-size: 0.85rem;
    font-family: inherit;
}

/* --- Combined donor+items entry form --- */
.items-section {
    border-top: 1px solid var(--border);
    padding-top: 14px;
    margin-top: 4px;
}
.items-section-label {
    font-size: 0.82rem; font-weight: 600; color: var(--muted); margin: 0 0 10px;
}
.item-row-grid {
    display: grid; grid-template-columns: 130px 1fr 110px 36px;
    gap: 8px; align-items: center; margin-bottom: 8px;
}
.item-row-grid select, .item-row-grid input {
    padding: 7px 9px; border: 1px solid var(--border); border-radius: 8px; font-size: 0.85rem;
    font-family: inherit;
}
.remove-item-row-btn {
    width: 36px; height: 36px; padding: 0;
    display: flex; align-items: center; justify-content: center;
}

.dashboard-progress-row { margin-bottom: 14px; }
.dashboard-progress-row .progress-labels { display: flex; justify-content: space-between; font-size: 0.85rem; margin-bottom: 4px; }
.dashboard-progress-row .progress-labels .amounts { color: var(--muted); }
.dashboard-progress-track { height: 8px; border-radius: 999px; background: var(--border); overflow: hidden; }
.dashboard-progress-fill { height: 100%; border-radius: 999px; }
.dashboard-progress-fill.status-success { background: var(--success); }
.dashboard-progress-fill.status-warning { background: var(--warning); }
.dashboard-progress-fill.status-danger { background: var(--danger); }
.card.status-warning { background: #fdf3e2; }
.card.status-warning .label, .card.status-warning .value { color: var(--warning); }
.dashboard-legend { color: var(--muted); font-size: 0.8rem; border-top: 1px solid var(--border); padding-top: 10px; margin-top: 4px; }

.dashboard-donut-panel { margin-bottom: 24px; }
.dashboard-donut-row { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; }
.dashboard-donut-wrap { position: relative; width: 160px; height: 160px; flex-shrink: 0; }
.dashboard-donut-center {
    position: absolute; inset: 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; text-align: center; pointer-events: none;
    /* Constrained to roughly the doughnut's own hole width (cutout: "72%"
       in the chart script) so the $ figures wrap onto their own line
       instead of spilling out past the ring - matters most for a big
       multi-year budget where these numbers only get longer. */
    width: 62%; margin: 0 auto;
}
.dashboard-donut-pct { font-size: 1.3rem; font-weight: 700; line-height: 1.1; }
.dashboard-donut-sub { font-size: 0.72rem; color: var(--muted); margin-top: 4px; line-height: 1.3; }
.dashboard-donut-legend { list-style: none; margin: 0; padding: 0; font-size: 0.85rem; }
.dashboard-donut-legend li { display: flex; align-items: center; gap: 8px; padding: 4px 0; }
.dashboard-donut-legend .swatch { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }
.dashboard-donut-legend .swatch.spent { background: var(--primary); }
.dashboard-donut-legend .swatch.available { background: var(--border); }

/* --- Mobile nav (hamburger + slide-in drawer, hidden on desktop) --- */
.mobile-nav-toggle {
    display: none;
    align-items: center; justify-content: center;
    width: 40px; height: 40px;
    border: none; background: none; cursor: pointer; padding: 0;
}
.hamburger-icon { display: inline-flex; flex-direction: column; justify-content: space-between; width: 22px; height: 15px; }
.hamburger-icon span { display: block; height: 2px; border-radius: 2px; background: var(--text); }

.mobile-nav-backdrop {
    display: none;
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.4);
    z-index: 40;
}
.mobile-nav-backdrop.open { display: block; }

.mobile-nav-drawer {
    position: fixed; top: 0; right: 0; height: 100%;
    width: 280px; max-width: 85vw;
    background: var(--card-bg);
    z-index: 50;
    padding: 16px;
    overflow-y: auto;
    transform: translateX(100%);
    transition: transform 220ms ease;
}
.mobile-nav-drawer.open { transform: translateX(0); }
.mobile-nav-drawer-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.mobile-nav-close { background: none; border: none; font-size: 1.6rem; line-height: 1; cursor: pointer; color: var(--muted); padding: 4px 8px; }
.mobile-nav-list { display: flex; flex-direction: column; }
.mobile-nav-link {
    display: block; padding: 12px 10px; border-radius: 8px;
    text-decoration: none; color: var(--text); font-weight: 500; font-size: 0.95rem;
}
.mobile-nav-link.active { background: var(--primary); color: #fff; }
.mobile-nav-sublink { padding-left: 22px; font-size: 0.88rem; color: var(--muted); }
.mobile-nav-sublink.active { color: #fff; }
.mobile-nav-group-label {
    padding: 14px 10px 2px; margin-top: 4px;
    font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.04em;
    font-weight: 700; color: var(--muted);
}
.mobile-nav-logout { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 10px; }

/* --- Responsive breakpoint: phones and narrow tablets --- */

/* --- Shared validation popup modal (e.g. "please select a location") --- */
.modal-backdrop {
    display: none;
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.4);
    z-index: 60;
}
.modal-backdrop.open { display: block; }
.modal-box {
    display: none;
    position: fixed; top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    background: var(--card-bg);
    border-radius: var(--radius);
    padding: 24px;
    width: 100%; max-width: 360px;
    z-index: 61;
    text-align: center;
}
.modal-box.open { display: block; }
.modal-box p { margin: 0 0 18px; font-size: 0.95rem; }

/* --- Bulk action row above a management table (e.g. Locations activate/deactivate all) --- */
.bulk-actions { display: flex; justify-content: flex-end; margin-bottom: 12px; }

/* --- Planning page: Sections, each holding Items, each holding a
   checkable/plain note list (see PROJECT_NOTES.md for why Items lost
   their own checkbox and single Notes field). --- */
.plan-section { margin-bottom: 20px; }
.plan-section-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; flex-wrap: wrap; }
.plan-section-title { display: flex; align-items: center; gap: 4px; }
.plan-section-title h3 { margin: 0; font-size: 1.05rem; }
.plan-section-actions { display: flex; align-items: center; gap: 2px; }

.plan-items { border-top: 1px solid var(--border); }

/* One Item: a plain title (no checkbox, no notes field of its own - just
   a grouping label) plus its own indented, nested note list. */
.plan-item-block { padding: 10px 2px; border-bottom: 1px solid var(--border); }
.plan-item-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.plan-item-title { display: flex; align-items: center; gap: 4px; }
.plan-item-title strong { font-size: 0.95rem; }
.plan-item-actions { display: flex; align-items: center; gap: 2px; }

.plan-item-notelist { margin: 8px 0 0 4px; padding-left: 14px; border-left: 2px solid var(--border); }

/* One note line - a real checkbox for a Checklist line, a plain dash
   marker for a Note (nothing to click, nothing to mark done), plus (for
   an editor) its own move/edit/delete. */
.plan-note {
    display: grid; grid-template-columns: 20px 1fr auto; gap: 8px; align-items: start;
    padding: 5px 0;
}
.plan-note input[type="checkbox"] { margin-top: 3px; width: 15px; height: 15px; accent-color: var(--primary); }
.plan-note-marker { color: var(--border); font-size: 0.9rem; text-align: center; margin-top: 2px; }
.plan-note-text { font-size: 0.88rem; color: var(--text); }
/* Done reads as "confirmed" (green, same as "Fully covered" elsewhere in
   this app), not "faded out/no longer relevant" - gray or strikethrough
   would read as the line not mattering anymore, when it's the opposite:
   it's been handled. A plain (non-checkable) line stays full-strength
   text, since it's a standing fact, not something that's ever "finished." */
.plan-note-text.done { color: var(--success); }
.plan-note.plain .plan-note-text { color: var(--text); }
.plan-note-actions { display: flex; gap: 1px; opacity: 0.7; }
.plan-note-edit { padding: 6px 0; }
.plan-note-edit form { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.plan-note-edit input[type="text"] { flex: 1; min-width: 160px; padding: 6px 9px; border: 1px solid var(--primary); border-radius: 6px; font-size: 0.85rem; font-family: inherit; }

.icon-btn { border: none; background: none; color: var(--muted); cursor: pointer; font-size: 0.85rem; padding: 2px 5px; border-radius: 5px; line-height: 1; }
.icon-btn:hover { background: var(--bg); color: var(--text); }

/* The Checklist/Note segmented toggle (real radios, styled) shown on the
   add-a-line form and a line's own edit form. */
.type-toggle { display: inline-flex; border: 1px solid var(--border); border-radius: 7px; overflow: hidden; flex-shrink: 0; }
.type-opt { margin: 0; }
.type-opt input { position: absolute; opacity: 0; pointer-events: none; }
.type-opt span { display: inline-block; padding: 5px 9px; font-size: 0.76rem; color: var(--muted); cursor: pointer; }
.type-opt input:checked + span { background: var(--text); color: #fff; font-weight: 600; }

.plan-add-note-form { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; padding: 8px 0 2px; }
.plan-add-note-form input[type="text"] {
    flex: 1; min-width: 160px; padding: 6px 9px; border: 1px dashed var(--border); border-radius: 6px;
    font-size: 0.82rem; color: var(--muted); font-family: inherit;
}

.plan-inline-form { display: inline-flex; gap: 8px; align-items: center; }
.plan-inline-form input[type="text"] { padding: 6px 9px; border: 1px solid var(--border); border-radius: 8px; font-size: 0.95rem; font-family: inherit; }

.plan-copy-forward {
    display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
    background: #fdf3e2; border: 1px solid #f0d99a; border-radius: 10px; padding: 14px 18px; margin-bottom: 20px;
}
.plan-copy-forward p { margin: 0; font-size: 0.88rem; color: #6b5216; line-height: 1.5; }
.plan-copy-forward strong { color: #52410f; }

.plan-print-btn { margin-bottom: 20px; }
/* Screen never sees this - it exists purely as @media print's stand-in for
   the on-screen Year picker, which isn't meaningful on paper (see
   renderPlanPrintHeader() in includes/planning_render.php). */
.plan-print-header { display: none; }

/* Cash on Hand: the Cash/status pills (Expenses table + Cash Report),
   the add-expense form's checkbox fields, and the Cash Report's own
   ledger/advances/carry-forward panels. */
.pill {
    display: inline-block; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.02em;
    text-transform: uppercase; border-radius: 999px; padding: 3px 9px; margin: 1px 3px 1px 0;
}
.pill.outstanding { background: #fdf3e2; color: var(--warning); }
.pill.reconciled { background: #e7f4ec; color: var(--success); }
.pill.cash { background: #fdecec; color: var(--primary); }

.checkbox-field { display: flex; align-items: center; gap: 8px; font-size: 0.9rem; margin-bottom: 10px; }
.checkbox-field input { width: 16px; height: 16px; accent-color: var(--primary); }
.checkbox-field label { margin: 0; font-weight: 400; }
.indent-reveal { margin: 0 0 10px 24px; padding-left: 14px; border-left: 2px solid var(--border); }
.checkbox-field-inline { display: flex; align-items: center; gap: 4px; font-size: 0.78rem; font-weight: 400; margin-bottom: 4px; white-space: nowrap; }
.checkbox-field-inline input { width: 14px; height: 14px; accent-color: var(--primary); }

.cash-panel-title { margin: 0 0 12px; }
.cash-panel-subtitle { font-weight: 400; font-size: 0.8rem; margin-left: 6px; }
.cash-ledger { border-top: 1px solid var(--border); }
.cash-ledger-row {
    display: flex; justify-content: space-between; align-items: center;
    padding: 10px 2px; border-bottom: 1px solid var(--border); font-size: 0.92rem;
}
.cash-ledger-row .cash-ledger-amt { font-variant-numeric: tabular-nums; font-weight: 600; }
.cash-ledger-row.in .cash-ledger-amt { color: var(--success); }
.cash-ledger-row.out .cash-ledger-amt { color: var(--primary); }
.cash-ledger-row.total { border-top: 2px solid var(--text); border-bottom: none; margin-top: 4px; padding-top: 14px; font-size: 1.05rem; font-weight: 700; }
.cash-ledger-desc { font-size: 0.8rem; font-weight: 400; margin-left: 8px; }

.cash-advance-list { border-top: 1px solid var(--border); }
.cash-advance-row {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 12px 2px; border-bottom: 1px solid var(--border); flex-wrap: wrap;
}
.cash-advance-row:last-child { border-bottom: none; }
.cash-advance-main strong { font-size: 0.95rem; }
.cash-advance-meta { font-size: 0.8rem; margin-top: 2px; }
.cash-advance-amt { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }

.cash-carry-form { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.cash-carry-form p { margin: 0; font-size: 0.88rem; color: var(--muted); line-height: 1.5; }
.cash-carry-input { display: flex; align-items: center; gap: 8px; }
.cash-carry-input input { width: 110px; padding: 6px 9px; border: 1px solid var(--border); border-radius: 6px; font-size: 0.9rem; text-align: right; }
.cash-confirmed-note { margin: -14px 0 16px; }

/* --- Shared read-only view (view.php), reached by scanning a QR code, and the
   printable sheet that carries the code (view_link_sheet.php). Base rules only;
   anything responsive or print-specific belongs in the block at the end of this
   file, or it will not win. --- */
.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;
}
body.shared-view { background: var(--bg); }
.shared-view-wrap { max-width: 900px; margin: 0 auto; padding: 24px 18px 48px; }
.shared-view-head { margin-bottom: 18px; }
.shared-view-head h1 { margin: 0 0 4px; font-size: 1.4rem; }
.shared-view-wrap h2 { font-size: 1.05rem; margin: 26px 0 10px; }
.shared-view-foot { margin-top: 30px; font-size: 0.8rem; color: var(--muted); text-align: center; }

/* Year switching is plain links - this page loads no app JS at all. */
.shared-view-years { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.shared-year {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 58px; min-height: 38px; padding: 0 12px;
    border: 1px solid var(--border); border-radius: 8px;
    background: var(--card-bg); color: var(--text);
    font-size: 0.9rem; text-decoration: none;
}
.shared-year:hover { border-color: var(--primary); }
.shared-year.is-current { background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600; }

.shared-plan-meta { margin: 0 0 14px; font-size: 0.85rem; color: var(--muted); }
.shared-plan-section { margin-bottom: 20px; }
.shared-plan-section h3 { font-size: 0.98rem; margin: 0 0 8px; padding-bottom: 5px; border-bottom: 1px solid var(--border); }
.shared-plan-item { margin: 0 0 12px 2px; }
.shared-plan-item strong { display: block; font-size: 0.92rem; margin-bottom: 3px; }
.shared-plan-itemnote { display: block; font-size: 0.82rem; color: var(--muted); margin-bottom: 4px; }
.shared-plan-line { display: flex; gap: 9px; align-items: baseline; padding: 3px 0 3px 10px; font-size: 0.88rem; }
.shared-plan-line.is-empty { color: var(--muted); font-style: italic; }
/* A drawn mark, never an <input> - there is nothing here to submit. */
.shared-plan-mark { flex: 0 0 auto; width: 14px; text-align: center; color: var(--muted); }
.shared-plan-line.is-done .shared-plan-text { color: var(--success); }
.shared-plan-line.is-done .shared-plan-mark { color: var(--success); }

/* --- Admin: the list of view links, and one printable sheet per link. --- */
.view-link-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding: 12px 0; border-bottom: 1px solid var(--border); }
.view-link-row:last-child { border-bottom: 0; }
.view-link-main { flex: 1 1 260px; min-width: 0; }
.view-link-label { font-weight: 600; font-size: 0.95rem; }
.view-link-meta { font-size: 0.8rem; color: var(--muted); margin-top: 3px; line-height: 1.6; }
/* The token is a live credential: shown truncated in the list, in full only on
   the sheet, and never in the audit log. */
.view-link-token { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 0.78rem; color: var(--muted); }
.view-link-actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.view-link-state { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.02em; }
.view-link-state.is-active { background: #dcfce7; color: #166534; }
.view-link-state.is-revoked { background: #fee2e2; color: #991b1b; }
.view-link-state.is-expired { background: #f3f4f6; color: #4b5563; }
.view-link-scopes { font-size: 0.78rem; color: var(--muted); }

/* Caption above a table inside a shared-view panel. The reports page does this
   with an inline style; here it is a class so both panels match. */
/* A plain, VISIBLE checkbox with its label.

   Deliberately not .type-opt: that class exists for the segmented
   Checklist/Note toggle and hides its input on purpose
   (position: absolute; opacity: 0; pointer-events: none) so the styled
   <span> can act as the control. Reusing it for a real checkbox leaves a
   switch nobody can see - which is exactly what happened to the Turnstile
   and throttling switches and to the view-link scope boxes. */
.check-opt { display: flex; align-items: center; gap: 9px; margin: 0; cursor: pointer; font-size: 0.9rem; }
.check-opt input[type="checkbox"] {
    width: 17px; height: 17px; margin: 0; flex: 0 0 auto;
    accent-color: var(--primary); cursor: pointer;
}
.check-opt span { cursor: pointer; }
.check-opt-group { display: flex; flex-direction: column; gap: 7px; margin-top: 4px; }

.shared-table-title { font-size: 0.9rem; font-weight: 600; margin-bottom: 10px; }

.view-sheet-wrap { max-width: 680px; margin: 0 auto; padding: 30px 20px 50px; text-align: center; }
.view-sheet-qr { display: inline-block; margin: 22px 0 14px; padding: 14px; background: #fff; border: 1px solid var(--border); border-radius: 12px; }
.view-sheet-qr svg { display: block; width: 100%; height: auto; max-width: 380px; }
.view-sheet-url { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 0.72rem; color: var(--muted); word-break: break-all; margin: 0 auto; max-width: 420px; }
.view-sheet-caption { font-size: 1.05rem; font-weight: 600; margin: 0 0 4px; }
.view-sheet-sub { font-size: 0.86rem; color: var(--muted); margin: 0; }

/* ============================================================
   RESPONSIVE AND PRINT OVERRIDES - KEEP THESE LAST

   Media queries add NO specificity, so whether a rule in here wins
   depends purely on it appearing after the base rule it targets. These
   blocks used to sit in the middle of the file, which silently killed
   four responsive rules (.icon-btn and the three Planning action rows -
   the entire mobile touch-target fix) and one print rule
   (.plan-print-header, so the Planning printout never showed its header).

   Anything added below stays below. Do not move base rules after this.
   ============================================================ */
@media (max-width: 780px) {
    .app-nav, .app-header-inner > .logout-link { display: none; }
    .mobile-nav-toggle { display: inline-flex; }

    .app-header-inner { padding: 10px 16px; }
    .page-content { padding: 16px; }
    .panel { padding: 16px; }

    .btn { padding: 10px 14px; }
    .btn-sm { padding: 8px 10px; }

    /* NO .icon-btn sizing here, deliberately.
     *
     * 48x48 bordered buttons were tried and reverted: with 404 of them on the
     * Planning page (every note, item and section row carries four) the result
     * was a wall of boxes, and the page grew from 5,830 to 8,484 pixels tall -
     * 46%, not the ~19% estimated from the note rows alone. Bigger targets made
     * each control easier to hit and the page as a whole harder to use.
     *
     * The targets ARE still too small for touch: 16.8x17.6px with a 1-2px gap,
     * against 44px (Apple) / 48px (Material). And .plan-note-actions fades them
     * to 0.7 opacity, putting grey #6b7280 near 2.6:1 where an interactive
     * control needs 3:1. Both remain open.
     *
     * What is worth trying next, in order of how little space it costs:
     *   1. ~34px bare glyphs - no border, no surface: roughly doubles the target
     *      for about 2px per row. This is what the original August rule intended
     *      before it was overridden.
     *   2. Keep edit and delete inline at 44px and move up/down behind one "more"
     *      control: three targets instead of four, so each can be larger without
     *      the row growing as much. Costs a second tap to reorder.
     *   3. Drag-to-reorder, which removes up/down entirely and is the only option
     *      that makes the row shorter rather than taller.
     */

    .item-form-grid, .item-row-grid {
        grid-template-columns: 1fr;
    }
    .remove-item-row-btn { width: auto; justify-self: start; }

    .donor-card-actions { justify-content: flex-start; }

    /* .chart-grid's minmax(380px, 1fr) column floor is wider than most
       phones in portrait (~360-412px viewport, minus this breakpoint's
       16px page-content padding on each side) - and unlike every other
       wide element in the app, chart-grid sits directly in the page
       flow rather than inside a .panel (which would have contained any
       overflow with its own scrollbar via overflow-x:auto). Forcing a
       single column here removes that 380px floor entirely so the trend
       cards just stack instead of forcing the whole page to scroll
       sideways. */
    .chart-grid { grid-template-columns: 1fr; }
}

@media (max-width: 480px) {
    h1 { font-size: 1.3rem; }
    .card .value { font-size: 1.35rem; }
    .app-title { font-size: 0.95rem; }

    /* The note row's actions used to drop onto their own line here, to make
     * room for 48px targets. Reverted with them: at the current icon size the
     * row fits comfortably, and wrapping every line would add height for no
     * benefit. If a larger target is tried again, this is the rule that keeps
     * the text readable at 375px - four 48px targets plus gaps is 216px, which
     * leaves about 70px for the text otherwise. */
}

/* --- Printing the Planning page (window.print(), triggered by
   .plan-print-btn - see planning.php) to a formal, checklist-style
   document, using the browser's own "Save as PDF" print destination
   rather than a server-side PDF library this app doesn't otherwise
   depend on. Every interactive control (nav, forms, add/edit/delete/move
   icons, the Year <select> itself) is print:none - paper has no click
   handlers - and .plan-print-header (see includes/planning_render.php)
   steps in as the plain-text replacement for what the Year picker was
   showing on screen. --- */
@media print {
    .app-header, #nav-loading, .mobile-nav-drawer, .mobile-nav-backdrop,
    #mobile-nav-toggle, #app-modal, #app-modal-backdrop, .subtitle,
    .plan-page-title, .plan-print-btn, .toolbar, .plan-copy-forward,
    .plan-inline-form, .plan-add-note-form, .plan-section-actions,
    .plan-item-actions, .plan-note-actions, .icon-btn {
        display: none !important;
    }

    body { background: #fff; color: #000; }
    .page-content { padding: 0; max-width: none; }

    .plan-print-header { display: block; margin-bottom: 18px; }
    .plan-print-header h1 { font-size: 16pt; margin: 0 0 2px; }
    .plan-print-header h2 { font-size: 13pt; font-weight: 600; margin: 0 0 4px; }
    .plan-print-meta { font-size: 9pt; color: #555; }

    .plan-section {
        border: none; box-shadow: none; padding: 0; margin-bottom: 16px;
        page-break-inside: avoid;
    }
    .plan-section-title h3 {
        font-size: 12pt; border-bottom: 1.5px solid #000; padding-bottom: 4px; margin: 0 0 6px;
    }
    .plan-items { border-top: none; }
    .plan-item-block { padding: 6px 0; page-break-inside: avoid; }
    .plan-item-title strong { font-size: 11pt; }
    .plan-item-notelist { border-left-color: #ccc; }
    .plan-note { border-bottom: 0.5px solid #ccc; padding: 4px 0; page-break-inside: avoid; }
    .plan-note-text { font-size: 10pt; }

    /* The native checkbox's print rendering varies a lot browser to
       browser, so it's redrawn as a plain square with the input's own
       :checked state (still reflects the real DOM regardless of print vs.
       screen) driving a manually-drawn checkmark, rather than trusting
       whatever the browser's default control looks like on paper. Plain
       (non-checkable) notes never had a checkbox to begin with - their
       .plan-note-marker dash prints as-is, no extra rule needed. */
    .plan-note input[type="checkbox"] {
        -webkit-appearance: none; appearance: none;
        width: 11px; height: 11px; margin: 3px 8px 0 0;
        border: 1.3px solid #000; border-radius: 2px; position: relative;
        print-color-adjust: exact; -webkit-print-color-adjust: exact;
    }
    .plan-note input[type="checkbox"]:checked { background: #000; }
    .plan-note input[type="checkbox"]:checked::after {
        content: "\2713"; position: absolute; top: -4px; left: 1px;
        color: #fff; font-size: 9px; line-height: 1;
    }
}

@media print { .stat-help, .stat-help-text { display: none !important; } }

/* The view-link sheet (view_link_sheet.php) prints as just the code and its
   caption - the buttons and the back link are screen furniture. */
@media print {
    .no-print { display: none !important; }
    body.view-sheet { background: #fff; }
    .view-sheet-wrap { padding: 0; max-width: none; }
    .view-sheet-qr { border: 0; padding: 0; margin: 10mm auto 6mm; }
    .view-sheet-qr svg { max-width: 105mm; }
    .view-sheet-url { color: #444; }
}

