:root {
  /* Ported from the School app's theme system: one selectable accent (11 fixed swatches,
     see the palette picker in the topbar) drives --brand-500/600/700 everywhere — sidebar,
     topbar, buttons, active nav, badges — via the aliases below. Default is the "gold"
     swatch, the closest match to this app's original identity, until the admin picks
     another one from the picker (stored client-side in localStorage, same as School). */
  --brand-500: #ca8a04;
  --brand-600: #a16207;
  --brand-700: #854d0e;
  --brand-500-rgb: 202, 138, 4;
  --brand-tint: color-mix(in srgb, var(--brand-500) 55%, white);
  --nav-bg: color-mix(in srgb, var(--brand-700) 62%, #05080f);
  --nav-hover: rgba(255,255,255,.06);
  --nav-text: rgba(255,255,255,.78);
  --nav-text-hi: #ffffff;
  --nav-muted: rgba(255,255,255,.55);
  --nav-border: rgba(255,255,255,.06);
  --group-bg: rgba(0,0,0,.15);

  /* This app's own existing token names, now aliased onto the system above instead of
     fixed hex — every page/component that already reads var(--brand)/var(--accent)/etc.
     re-tints automatically when the accent changes, with no per-file changes needed. */
  --brand: var(--brand-500);
  --brand-dark: var(--nav-bg);
  --brand-light: color-mix(in srgb, var(--brand-500) 12%, white);
  --accent: var(--brand-500);

  --bg: #f4f5f7;
  --border: #e2e4e9;
  --text: #1f2228;
  --muted: #6b7280;
  --surface: #ffffff;
  --topbar-bg: #ffffff;
}

[data-bs-theme="dark"] {
  --brand-light: color-mix(in srgb, var(--brand-500) 20%, #1a1d23);
  --bg: #101215;
  --border: #2b2f38;
  --text: #e6e7ea;
  --muted: #98a0ac;
  --surface: #1a1d23;
  --topbar-bg: #1a1d23;
}

/* The 11 fixed accent swatches, copied verbatim from the School app's themes.css — each
   overrides only the 3 brand shades + rgb variant; everything else cascades from those via
   the aliases above. No swatch selected (no data-accent attribute) = the "gold" default in
   :root above. */
:root[data-accent="teal"]      { --brand-500:#0d9488; --brand-600:#0f766e; --brand-700:#115e59; --brand-500-rgb:13,148,136; }
:root[data-accent="steel"]     { --brand-500:#475569; --brand-600:#334155; --brand-700:#1e293b; --brand-500-rgb:71,85,105; }
:root[data-accent="ocean"]     { --brand-500:#2563eb; --brand-600:#1d4ed8; --brand-700:#1e40af; --brand-500-rgb:37,99,235; }
:root[data-accent="graphite"]  { --brand-500:#334155; --brand-600:#1e293b; --brand-700:#0f172a; --brand-500-rgb:51,65,85; }
:root[data-accent="forest"]    { --brand-500:#15803d; --brand-600:#166534; --brand-700:#14532d; --brand-500-rgb:21,128,61; }
:root[data-accent="sandstone"] { --brand-500:#a16207; --brand-600:#854d0e; --brand-700:#713f12; --brand-500-rgb:161,98,7; }
:root[data-accent="copper"]    { --brand-500:#c2410c; --brand-600:#9a3412; --brand-700:#7c2d12; --brand-500-rgb:194,65,12; }
:root[data-accent="gold"]      { --brand-500:#ca8a04; --brand-600:#a16207; --brand-700:#854d0e; --brand-500-rgb:202,138,4; }
:root[data-accent="ruby"]      { --brand-500:#be123c; --brand-600:#9f1239; --brand-700:#881337; --brand-500-rgb:190,18,60; }
:root[data-accent="amethyst"]  { --brand-500:#7c3aed; --brand-600:#6d28d9; --brand-700:#5b21b6; --brand-500-rgb:124,58,237; }
:root[data-accent="indigo"]    { --brand-500:#4338ca; --brand-600:#3730a3; --brand-700:#312e81; --brand-500-rgb:67,56,202; }

* { box-sizing: border-box; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif;
  margin: 0;
}

.app-shell { display: flex; min-height: 100vh; }

/* Sidebar */
.sidebar {
  width: 250px;
  flex-shrink: 0;
  background: linear-gradient(180deg, color-mix(in srgb, var(--brand-700) 55%, black) 0%, var(--nav-bg) 18%, var(--nav-bg) 100%);
  color: #fff;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}
/* Floating diagonal streaks. Same recipe as the restaurant (Chop Chain)
   app's #sidebar::before / .book-cover::before (its login page's cover
   panel): rounded-cap <line> strokes on a tall 300x400 viewBox, not
   flat-opacity shapes. The earlier attempt here used ~5% flat white
   fill with no blend mode, which read as invisible against a dark
   background. mix-blend-mode:overlay plus varied per-line opacity is
   what actually makes the streaks read as light picking out the
   gradient underneath, not just a faint wash. repeat-y (not both axes)
   since the sidebar is a tall narrow strip, not a tiled swatch: one
   big pattern scrolling down its height. */
.sidebar::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 400'%3E%3Cg stroke='white' stroke-linecap='round' fill='none'%3E%3Cline x1='10' y1='380' x2='58' y2='296' stroke-width='28' stroke-opacity='.9'/%3E%3Cline x1='74' y1='396' x2='98' y2='348' stroke-width='10' stroke-opacity='.55'/%3E%3Cline x1='62' y1='330' x2='152' y2='150' stroke-width='22' stroke-opacity='.75'/%3E%3Cline x1='122' y1='382' x2='148' y2='330' stroke-width='8' stroke-opacity='.5'/%3E%3Cline x1='142' y1='360' x2='208' y2='228' stroke-width='16' stroke-opacity='.6'/%3E%3Cline x1='192' y1='340' x2='248' y2='230' stroke-width='24' stroke-opacity='.7'/%3E%3Cline x1='212' y1='218' x2='232' y2='178' stroke-width='9' stroke-opacity='.5'/%3E%3Cline x1='242' y1='300' x2='292' y2='200' stroke-width='14' stroke-opacity='.55'/%3E%3Cline x1='30' y1='230' x2='50' y2='190' stroke-width='8' stroke-opacity='.4'/%3E%3Cline x1='100' y1='190' x2='118' y2='154' stroke-width='6' stroke-opacity='.35'/%3E%3C/g%3E%3C/svg%3E");
  background-repeat: repeat-y; background-size: 200% auto; background-position: -30% 0%;
  mix-blend-mode: overlay; opacity: .4;
  animation: login-drift 26s ease-in-out infinite;
}
@keyframes login-drift { 0%, 100% { background-position: 0% 100%; } 50% { background-position: 14% 84%; } }
@media (prefers-reduced-motion: reduce) { .sidebar::before { animation: none; } }
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: 1.15rem 1.2rem;
  font-weight: 700;
  font-size: 1.05rem;
  border-bottom: 1px solid rgba(255,255,255,.1);
}
.sidebar-brand i { color: var(--accent); font-size: 1.3rem; }
.sidebar-nav { padding: .8rem .6rem; display: flex; flex-direction: column; gap: .15rem; }
.sidebar-nav a {
  color: rgba(255,255,255,.82);
  text-decoration: none;
  padding: .55rem .8rem;
  border-radius: .5rem;
  font-size: .92rem;
  display: flex;
  align-items: center;
  gap: .6rem;
  transition: background .15s;
}
.sidebar-nav a i { width: 18px; text-align: center; }
.sidebar-nav a:hover { background: var(--nav-hover); color: var(--nav-text-hi); }
.sidebar-nav a.active {
  background: linear-gradient(135deg, rgba(var(--brand-500-rgb),.85), rgba(var(--brand-500-rgb),.55));
  color: #fff;
  font-weight: 600;
  box-shadow: 0 6px 16px rgba(0,0,0,.4), 0 2px 6px rgba(var(--brand-500-rgb),.3), inset 0 1px 0 rgba(255,255,255,.25);
  transform: translateY(-1px);
}
.nav-group { display: flex; flex-direction: column; }
.nav-group-toggle {
  display: flex;
  align-items: center;
  gap: .6rem;
  width: 100%;
  background: none;
  border: none;
  text-align: left;
  text-transform: uppercase;
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .06em;
  color: rgba(255,255,255,.5);
  padding: .95rem .8rem .4rem;
  cursor: pointer;
  transition: color .15s;
}
.nav-group-toggle:hover { color: rgba(255,255,255,.85); }
.nav-group-toggle .chevron {
  margin-left: auto;
  font-size: .65rem;
  transition: transform .2s ease;
}
.nav-group-toggle[aria-expanded="false"] .chevron { transform: rotate(-90deg); }
.nav-group-body { display: flex; flex-direction: column; gap: .15rem; }
/* Visually distinct from .nav-group above — this ISN'T another collapsible topic
   accordion, it's "you are inside event X right now" — a tinted, bordered, always-
   expanded panel so that context reads immediately instead of blending into the list. */
.nav-event-group {
  display: flex; flex-direction: column; gap: .15rem;
  margin: .7rem .2rem; padding: .5rem;
  background: var(--group-bg);
  border: 1px solid rgba(var(--brand-500-rgb),.3);
  border-radius: .7rem;
}
.nav-event-group-label {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  font-size: .78rem; font-weight: 700; color: var(--brand-tint);
  padding: .3rem .6rem .5rem;
}
.nav-event-group-label span { display: flex; align-items: center; gap: .5rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-event-exit { color: var(--brand-tint); opacity: .7; flex-shrink: 0; }
.nav-event-exit:hover { opacity: 1; }
.nav-event-group a.active {
  background: linear-gradient(135deg, rgba(var(--brand-500-rgb),.85), rgba(var(--brand-500-rgb),.55));
  color: #fff;
  font-weight: 600;
  box-shadow: 0 6px 16px rgba(0,0,0,.4), 0 2px 6px rgba(var(--brand-500-rgb),.3), inset 0 1px 0 rgba(255,255,255,.25);
  transform: translateY(-1px);
}
.sidebar-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.4);
  z-index: 35;
}
.sidebar-backdrop.show { display: block; }

/* Main */
.app-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.topbar {
  background: linear-gradient(135deg, var(--brand-700) 0%, var(--brand-600) 55%, var(--brand-500) 100%);
  border-bottom: 1px solid rgba(255,255,255,.06);
  box-shadow: 0 1px 0 rgba(0,0,0,.2), 0 4px 12px rgba(0,0,0,.08);
  padding: .85rem 1.5rem;
  display: flex;
  align-items: center;
  gap: 1rem;
  position: sticky;
  top: 0;
  z-index: 20;
}
.topbar-title {
  font-size: 1.15rem;
  font-weight: 700;
  margin: 0;
  flex: 1;
  min-width: 0;
  color: #fff;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* The topbar is now always a colored gradient (see .topbar above, same in light/dark
   mode, matching the School app's own chrome) — Bootstrap's plain .btn-light would read
   as a flat white block against it, so this gives it the same "glassy pill on gradient"
   treatment School uses for its topbar icon/user buttons, without touching every
   button's classes in includes/header.php. */
.topbar .btn-light {
  background: rgba(255,255,255,.12);
  border-color: rgba(255,255,255,.18);
  color: rgba(255,255,255,.92);
}
.topbar .btn-light:hover, .topbar .btn-light:focus, .topbar .btn-light:active {
  background: rgba(255,255,255,.22);
  border-color: rgba(255,255,255,.3);
  color: #fff;
}
.content { padding: 1.25rem 1.5rem; flex: 1; }

/* Cards & widgets — a real resting shadow (not just a hairline) plus a lift on hover,
   same "raised surface" depth School/Share use instead of a near-flat 1px shadow. */
.stat-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: .8rem;
  padding: 1.1rem 1.3rem;
  display: flex;
  align-items: center;
  gap: 1rem;
  box-shadow: 0 4px 12px rgba(15,23,42,.08), 0 1px 3px rgba(15,23,42,.06);
  height: 100%;
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
[data-bs-theme="dark"] .stat-card { box-shadow: 0 4px 14px rgba(0,0,0,.4), 0 1px 3px rgba(0,0,0,.3); }
.stat-card .icon {
  width: 46px; height: 46px; border-radius: .7rem;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.3rem; color: #fff; flex-shrink: 0;
}
/* min-width:0 lets a long money value truncate/shrink inside its flex cell
   instead of forcing the card wider or overflowing the grid column. */
.stat-card .stat-card-text { min-width: 0; }
.stat-card .value {
  font-size: clamp(1.05rem, 1.7vw, 1.4rem);
  font-weight: 700;
  line-height: 1.15;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.stat-card .label { color: var(--muted); font-size: .8rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The one stat card that's also a link (Outstanding Pledges → Pledges list) gets a
   visible hover affordance so it doesn't look clickable-but-inert next to the five
   plain ones beside it. */
.stat-card-link { display: block; text-decoration: none; color: inherit; }
.stat-card-link:hover .stat-card { border-color: var(--accent); box-shadow: 0 8px 20px rgba(var(--brand-500-rgb),.22); transform: translateY(-1px); }

.card { border: 1px solid var(--border); border-radius: .8rem; box-shadow: 0 4px 12px rgba(15,23,42,.08), 0 1px 3px rgba(15,23,42,.06); }
[data-bs-theme="dark"] .card { box-shadow: 0 4px 14px rgba(0,0,0,.4), 0 1px 3px rgba(0,0,0,.3); }
.card-header { background: var(--surface); border-bottom: 1px solid var(--border); font-weight: 600; }

/* Table header row — Bootstrap's own .table-light/.table-dark variants are
   fixed regardless of color mode, so we use our own theme-aware tokens instead. */
.table-head-themed { background: var(--brand-light); }
.table-head-themed th { color: var(--text); border-color: var(--border); }

/* In-table column filter row (assets/js/app.js's initDataTableColumnFilters()) — a compact
   second header row holding one filter control per column, replacing the separate filter
   form every list page used to show above its table. */
.dt-filter-row th { background: var(--surface); padding: 6px 8px; border-top: none; }
.dt-filter-row input.form-control, .dt-filter-row select.form-select { font-size: .8rem; }
.dt-filter-daterange { display: flex; gap: 4px; }
.dt-filter-daterange input { min-width: 0; }

/* General DataTable polish — row hover and pagination tied to the chosen accent color
   (var(--brand-500-rgb)) instead of Bootstrap's fixed defaults, same "ties to whichever
   accent is picked in Settings -> Appearance" direction as the event cards. */
table.dataTable tbody tr:hover { background: rgba(var(--brand-500-rgb),.05); }
.dataTables_wrapper .dataTables_paginate .paginate_button.current,
.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
  background: var(--brand-500); border-color: var(--brand-500); color: #fff !important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
  background: rgba(var(--brand-500-rgb),.12); border-color: rgba(var(--brand-500-rgb),.3); color: var(--text) !important;
}
.dataTables_wrapper .dataTables_processing { color: var(--text); }

.alert-surface { background: var(--surface); color: var(--text); border-color: var(--border) !important; }

/* Every button gets a slight raise — School gives even its outline/secondary buttons a
   bit of lift on hover instead of a flat, dead color swap. */
.btn { transition: all .15s ease; }
.btn:not(.btn-link):hover { transform: translateY(-1px); }
.btn:not(.btn-link):active { transform: translateY(0); }
.btn-outline-secondary, .btn-outline-dark, .btn-outline-danger, .btn-outline-warning {
  box-shadow: 0 1px 2px rgba(15,23,42,.06);
}
.btn-outline-secondary:hover, .btn-outline-dark:hover, .btn-outline-danger:hover, .btn-outline-warning:hover {
  box-shadow: 0 4px 10px rgba(15,23,42,.12);
}

/* Raised-glow style copied from the School app's .btn-primary — a resting shadow tinted
   by the current accent, plus a lift-and-brighten on hover, instead of a flat fill. */
.btn-brand {
  background: var(--brand-500); border-color: var(--brand-500); color: #fff;
  box-shadow: 0 2px 8px rgba(var(--brand-500-rgb),.28);
  transition: all .2s ease;
}
.btn-brand:hover {
  background: var(--brand-600); border-color: var(--brand-600); color: #fff;
  box-shadow: 0 6px 16px rgba(var(--brand-500-rgb),.4);
  transform: translateY(-1px);
}
.btn-brand:active { transform: translateY(0); }
.btn-accent { background: var(--brand-500); border-color: var(--brand-500); color: #fff; }
.btn-accent:hover { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }

.theme-toggle-btn { display: inline-flex; align-items: center; justify-content: center; }

/* Appearance settings (settings/sections/appearance.php) — one card per :root[data-accent="..."]
   palette, each showing its three brand shades. Click previews live; Save persists it. */
.palette-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .6rem; }
.palette-card {
  display: flex; flex-direction: column; align-items: flex-start; gap: .5rem;
  background: var(--surface); border: 1px solid var(--border); border-radius: .75rem;
  padding: .7rem .8rem; cursor: pointer; text-align: left;
}
.palette-card:hover { border-color: var(--brand-500); }
.palette-card.active { border-color: var(--brand-500); box-shadow: 0 0 0 2px rgba(var(--brand-500-rgb),.25); }
.palette-chip { display: flex; width: 100%; height: 26px; border-radius: .4rem; overflow: hidden; box-shadow: inset 0 0 0 1px rgba(0,0,0,.12); }
.palette-chip i { flex: 1; display: block; }
.palette-label { font-size: .85rem; color: var(--text); font-weight: 600; }
.palette-card.active .palette-label { color: var(--brand-700); }

/* Printable receipt — deliberately stays paper-white in both themes, with a gold
   letterhead band and a soft shadow for a more "premium" printed-document feel. */
.receipt-paper {
  position: relative;
  background: #ffffff;
  color: #1f2937;
  border: 1px solid #dcc79a;
  border-radius: .9rem;
  max-width: 480px;
  margin: 0 auto;
  overflow: hidden;
  box-shadow: 0 18px 40px -12px rgba(35,38,46,.28), 0 2px 8px rgba(35,38,46,.10);
  /* Settings > Event Settings > Receipt Style sets these as inline custom properties on
     this element (see receipt_style_vars() in includes/functions.php) — the values here
     are just the fallback for the "system"/default choice, so nothing changes for anyone
     who hasn't touched that setting. */
  font-family: var(--receipt-font-family, "Segoe UI", system-ui, sans-serif);
  font-size: var(--receipt-font-size, 14px);
  font-weight: var(--receipt-font-weight, 400);
  font-style: var(--receipt-font-style, normal);
  text-shadow: var(--receipt-text-shadow, none);
}
.receipt-paper .receipt-band {
  position: relative;
  z-index: 1;
  background: linear-gradient(135deg, #2b2f38, #1a1d23);
  color: #fff;
  text-align: center;
  padding: 1.5rem 1.8rem 1.2rem;
}
.receipt-paper .receipt-band::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: linear-gradient(90deg, #b8944f, #e9d5a6, #b8944f);
}
.receipt-paper .receipt-title { font-weight: 700; font-size: 1.15rem; letter-spacing: .02em; }
.receipt-paper .receipt-sub { color: #cfd2d8; font-size: .8rem; margin-top: .25rem; }
.receipt-paper .receipt-sub.receipt-deceased { color: #d4af6a; font-style: italic; }
.receipt-paper .receipt-badge {
  display: inline-block; margin-top: .7rem; padding: .3rem .9rem; border-radius: 999px;
  background: rgba(184,148,79,.18); border: 1px solid rgba(212,175,106,.5);
  color: #e9d5a6; font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; font-weight: 600;
}
.receipt-paper .receipt-body { position: relative; z-index: 1; padding: 1.6rem 1.8rem 1.8rem; }
.receipt-paper .receipt-watermark {
  position: absolute; z-index: 0; top: 52%; left: 50%; transform: translate(-50%, -50%) rotate(-22deg);
  font-size: 6.5rem; color: #b8944f; opacity: .05; pointer-events: none;
}
.receipt-paper table { width: 100%; }
.receipt-paper table td { padding: .4rem 0; color: #1f2937; }
/* Deliberately not Bootstrap's .text-muted: that class resolves via a dark-mode-aware
   CSS variable and goes near-invisible on this always-white paper. */
.receipt-paper .receipt-muted { color: #6b7280 !important; }
.receipt-paper .receipt-amount-box {
  position: relative; z-index: 1;
  background: linear-gradient(135deg, #f4e8d0, #ecd9ab);
  border: 1px solid #dcc79a;
  border-radius: .7rem;
  text-align: center;
  padding: .9rem 1rem;
  margin: 1rem 0;
}
.receipt-paper .receipt-amount-box .receipt-amount-label {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .1em; color: #8a6f3f; font-weight: 700;
}
.receipt-paper .receipt-amount { font-size: 1.75rem; font-weight: 800; font-style: normal; color: #23262e; line-height: 1.3; }
.receipt-paper hr { border: none; border-top: 1px dashed #dcc79a; margin: 1rem 0; }
.receipt-paper .receipt-footer {
  position: relative; z-index: 1; text-align: center; padding-top: .2rem;
}
.receipt-paper .receipt-footer .receipt-flourish { color: #b8944f; letter-spacing: .3em; font-size: .7rem; margin-bottom: .4rem; }
.receipt-paper .receipt-footer .receipt-thanks { color: #8a6f3f; font-style: italic; font-size: .88rem; margin-top: .15rem; }
.receipt-paper .receipt-footer .receipt-devcontact { font-size: .68rem; margin-top: .5rem; opacity: .85; }
.receipt-paper .receipt-footer .receipt-qr { width: 76px; height: 76px; margin: 0 auto .3rem; display: block; }

@media print {
  /* Only the receipt itself should print — everything else (sidebar, topbar, any
     SweetAlert toast that happened to be showing) has to be explicitly hidden, since
     print doesn't otherwise know which part of the page is "the document". */
  .no-print, .sidebar, .sidebar-backdrop, .topbar, .swal2-container { display: none !important; }
  .app-shell, .app-main, .content { display: block !important; padding: 0 !important; margin: 0 !important; height: auto !important; min-height: 0 !important; }
  body { background: #fff !important; }

  /* The on-screen "deep" gold/charcoal design is deliberately NOT what prints. A thermal
     receipt printer can't render gradients or dark fills at all (it's heat, not ink), and
     on a regular printer that dark band alone would be the single most ink-hungry thing
     on the page for a document you're printing over and over, all day, per donor. Print
     output is plain black-on-white with rule lines instead — same information, laid out
     narrow enough (80mm) to also work as-is on an actual thermal receipt printer.
     Font choice matters for sharpness, not just ink: thermal heads print at a low ~180-203
     dpi, and a monospace/serif face's thin, uneven strokes break up and blur at that
     resolution — real POS receipts use a plain sans-serif at a semi-bold weight because
     its strokes stay uniformly thick enough for every dot to register cleanly. Rule lines
     are solid, not dashed, for the same reason: a 1px dash can drop out entirely at low dpi. */
  .receipt-paper {
    width: 80mm;
    max-width: 80mm;
    margin: 0 auto;
    background: #fff !important;
    color: #000 !important;
    border: none;
    border-radius: 0;
    box-shadow: none;
    /* Same Receipt Style setting as the on-screen version above — these fallbacks are
       just the printer's original defaults, tuned for thermal legibility (see note above). */
    font-family: var(--receipt-font-family, Arial, Helvetica, sans-serif);
    font-size: var(--receipt-font-size, 13px);
    font-weight: var(--receipt-font-weight, 500);
    font-style: var(--receipt-font-style, normal);
    text-shadow: var(--receipt-text-shadow, none);
    line-height: 1.45;
  }
  .receipt-paper .receipt-watermark { display: none; }
  .receipt-paper .receipt-band {
    background: none !important;
    color: #000 !important;
    padding: 0 0 .4rem;
    border-bottom: 2px solid #000;
  }
  .receipt-paper .receipt-band::after { display: none; }
  .receipt-paper .receipt-title { font-size: 16px; font-weight: 800; letter-spacing: 0; }
  .receipt-paper .receipt-sub,
  .receipt-paper .receipt-sub.receipt-deceased { color: #000 !important; font-style: normal; font-weight: 600; }
  .receipt-paper .receipt-badge {
    background: none !important; border: 1.5px solid #000; border-radius: 0; color: #000 !important; font-weight: 700;
  }
  .receipt-paper .receipt-body { padding: .6rem 0 0; }
  .receipt-paper table td { color: #000 !important; padding: .25rem 0; font-weight: var(--receipt-font-weight, 600); }
  .receipt-paper .receipt-muted { color: #000 !important; font-weight: var(--receipt-font-weight, 500); }
  .receipt-paper .receipt-amount-box {
    background: none !important; border: 2px solid #000; border-radius: 0; box-shadow: none;
  }
  .receipt-paper .receipt-amount-label { color: #000 !important; font-weight: 700; }
  .receipt-paper .receipt-amount { color: #000 !important; font-size: 19px; font-weight: 800; }
  .receipt-paper hr { border: none; border-top: 2px solid #000; }
  .receipt-paper .receipt-footer .receipt-flourish { color: #000 !important; }
  .receipt-paper .receipt-footer .receipt-thanks { color: #000 !important; font-style: normal; font-weight: 700; }
}

/* Login page card, in case dark mode was chosen before logging in */
[data-bs-theme="dark"] .login-card { background: var(--surface); color: var(--text); }
[data-bs-theme="dark"] .login-card .text-muted { color: var(--muted) !important; }

/* SweetAlert2 doesn't read data-bs-theme itself */
[data-bs-theme="dark"] .swal2-popup { background: var(--surface); color: var(--text); }

@media (max-width: 991.98px) {
  .sidebar { position: fixed; left: -260px; z-index: 40; transition: left .2s; box-shadow: 4px 0 12px rgba(0,0,0,.15); }
  .sidebar.show { left: 0; }
}

@media (max-width: 575.98px) {
  .content { padding: 1rem; }
  .topbar { padding: .7rem .75rem; gap: .5rem; }
  .topbar-user-name { display: none; }
  .topbar-user .dropdown-toggle { padding-left: .55rem; padding-right: .55rem; }
  .stat-card { padding: .9rem 1rem; }
  .receipt-paper { padding: 1.3rem 1.1rem; }
}

/* Three-way "Cash / In-Kind / Cash + In-Kind" radio-button-group toggles
   (contributions/form.php, pledges/form.php): on a narrow phone the longest
   label can't share a row with the other two at full size, so let the group
   wrap instead of clipping or forcing the page wider than the screen. */
@media (max-width: 420px) {
  .btn-group.w-100 { flex-wrap: wrap; }
  .btn-group.w-100 > .btn { flex: 1 1 auto; font-size: .82rem; padding-left: .5rem; padding-right: .5rem; }
}

/* Modal depth — ported from the School/Share apps' shared recipe (Share's own header.php
   explicitly credits School's system for this). Flat corners, but a real soft drop shadow
   instead of Bootstrap's near-invisible default, brand-tinted dividers under the header
   and above the footer, and a pill-shaped title badge instead of plain bold text. Applies
   to every modal in the app, not just one — "flat" was a general complaint. */
.modal-content {
  border-radius: 0; border: 0;
  box-shadow: 0 24px 64px rgba(0,0,0,.35);
  display: flex; flex-direction: column;
  max-height: calc(100vh - 4rem);
  overflow: hidden;
}
.modal-header {
  padding: 20px 28px 12px;
  border-bottom: 2px solid rgba(var(--brand-500-rgb),.3);
  flex-shrink: 0;
}
.modal-body { padding: 16px 28px; overflow-y: auto; min-height: 0; }
.modal-footer {
  padding: 14px 28px 20px;
  border-top: 2px solid rgba(var(--brand-500-rgb),.3);
  flex-shrink: 0;
}
.modal-title {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 18px; border-radius: 50rem;
  background: var(--brand-700); color: #fff;
  box-shadow: 0 2px 8px rgba(var(--brand-500-rgb),.25);
  border-left: 4px solid #f2a900;
  font-size: .95rem; font-weight: 700;
}
.form-control:focus, .form-select:focus {
  border-color: var(--brand-500);
  box-shadow: 0 0 0 3px rgba(var(--brand-500-rgb),.15);
}
