:root {
  --green: var(--color-success);
  --green-light: var(--color-success-light);
  --blue: var(--color-primary);
  --blue-dark: var(--color-primary-dark);
  --blue-light: var(--color-primary-light);
  --purple: var(--color-purple);
  --purple-light: #f5f3ff;
  --text: var(--color-text);
  --text-muted: var(--color-text-muted);
  --bg: var(--color-bg);
  --white: var(--color-surface);
  --border: var(--color-border);
  --radius: var(--r);
  --radius-sm: var(--r-sm);
  --radius-full: var(--r-full);
}

html {
  scroll-behavior: smooth;
}

*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  min-height: 100dvh;
  background: var(--bg);
  font-family: 'Poppins', Arial, sans-serif;
  color: var(--text);
  line-height: 1.6;
  display: flex;
  flex-direction: column;
  -webkit-tap-highlight-color: transparent;
}

body:has(.sidebar.open),
body:has(.modal-overlay.show) { overflow: hidden; }

/* --- Nav (top) ---
   Excludes .site-header-nav (the centered link group inside .site-header) so the
   modern site-header layout isn't fighting this legacy frosted-bar styling.
   Also excludes .guest-drawer-nav: it is a <nav>, so it was picking up
   `position: sticky` and a fixed `height: var(--nav-height)` meant for a page
   bar. Inside the guest menu that clamped the link list to 6.4rem while its
   three links needed 15.2rem, so Sign Up Free and Log In were laid out from
   the clamped height and painted straight over About Sawa. */
nav:not(.bottom-nav):not(.site-header-nav):not(.guest-drawer-nav) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 1.6rem;
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.4);
  box-shadow: 0 1px 16px rgba(0, 0, 0, 0.06);
  position: sticky;
  top: 0;
  z-index: 20;
  height: var(--nav-height);
}

nav:not(.site-header-nav) > *:first-child { min-width: 4rem; }
nav:not(.site-header-nav) > *:last-child { margin-left: auto; }

.empty-state {
  color: var(--text-muted);
  font-size: 1.4rem;
  text-align: center;
  padding: 4rem 2rem;
  width: 100%;
  grid-column: 1 / -1;
}

nav > img {
  height: 4rem;
  width: auto;
  cursor: pointer;
}

/* Removed: .nav-links, .nav-hamburger, .nav-user, generic `nav a` legacy
   rules. These belonged to the old guest-nav design that .site-header
   replaced. No matching HTML anywhere. ~70 lines deleted. */

/* --- Layout ---
   The sidebar is a fixed drawer, so .layout no longer lays anything out in a
   row — it is a plain block. (Was `display: flex` here and `display: block`
   6,500 lines further down; the later rule won.) */
.layout {
  display: block;
  flex: 1;
}

/* --- Sidebar: fixed slide-in drawer at every width ---
   The old in-flow `position: relative + min-height: 100dvh` caused the
   sidebar to shrink/jump on mobile when Chrome's address bar collapsed.
   Replaced by a single fixed drawer with internal scroll.

   Consolidated from three separate top-level `.sidebar` rules that were
   scattered ~6,500 and ~8,300 lines apart. Each contributed a few live
   declarations and a few dead ones, so this is a merge of their computed
   result, not a deletion. Dark-mode background is overridden further down.
   Keep this the single definition — add to it rather than appending a new
   `.sidebar { }` block elsewhere. */
.sidebar {
  position: fixed;
  top: 0;
  left: 0;
  width: 28rem;
  height: 100dvh;
  /* Sits ABOVE the sticky site-header (z:50) so the duplicate user chip
     from the top header doesn't show through the drawer. The overlay (z:55)
     sits between header and sidebar to dim the page. */
  z-index: 60;
  display: flex;
  flex-direction: column;
  /* Horizontal padding from the drawer-polish pass; vertical padding keeps
     the safe-area insets it had previously clobbered with a `padding`
     shorthand, so the drawer clears notches and home indicators again. */
  padding-inline: 0.9rem;
  padding-top: max(1.2rem, env(safe-area-inset-top));
  padding-bottom: max(1.4rem, env(safe-area-inset-bottom));
  background: rgba(255, 255, 255, 0.88);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-right: 1px solid rgba(0, 0, 0, 0.07);
  border-radius: 0 1.6rem 1.6rem 0;
  box-shadow: var(--shadow-lg);
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translateX(-100%);
  transition: transform 0.3s ease;
}

.sidebar.open { transform: translateX(0); }

.sidebar-item {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  padding: 1.2rem 2rem;
  cursor: pointer;
  font-size: 1.4rem;
  font-weight: 500;
  color: var(--text-muted);
  transition: all 0.2s;
  border: none;
  background: none;
  width: 100%;
  text-align: left;
  position: relative;
}

.sidebar-item:hover {
  background: var(--bg);
  color: var(--text);
}

.sidebar-item.active {
  background: var(--blue-light);
  color: var(--blue);
  font-weight: 600;
}

.sidebar-item.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--blue);
  border-radius: 0 3px 3px 0;
}

.sidebar-item svg {
  display: block;
  width: 2rem;
  height: 2rem;
  flex-shrink: 0;
}

.sidebar-item.logout {
  color: var(--color-danger);
}

.sidebar-item.logout:hover {
  background: var(--color-danger-light);
}

/* Old .sidebar-theme-toggle rules deleted — Theme moved into the Settings
   sub-page. The sun/moon icon swap now lives on the .settings-row directly
   via [data-theme-toggle] selector below. */

/* Sidebar auth section — pinned to bottom, separated from primary nav */
.sidebar-auth-section {
  margin-top: auto;
  padding: 1.2rem 0 0.8rem;
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.sidebar-section-label {
  font-size: 1.05rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-light);
  padding: 0.4rem 2rem 0.6rem;
}

/* Secondary auth link (Log In) — outline style so the primary CTA owns the eye */
.sidebar-item.sidebar-auth-link {
  background: transparent;
  color: var(--color-primary);
  border: 1.5px solid transparent;
}
.sidebar-item.sidebar-auth-link:hover {
  background: var(--blue-light);
  color: var(--blue);
}

.sidebar-item:active,
.sidebar-item.pressed {
  background: var(--blue-light);
  color: var(--blue);
}

/* --- Main Content --- */
.main-content {
  flex: 1;
  padding: 2.4rem;
  max-width: 104rem;
  overflow-y: auto;
  overflow-x: hidden;
}

.section {
  display: none;
  opacity: 0;
  transform-origin: top center;
  min-width: 0;
}

.section.active {
  display: block;
  opacity: 1;
  animation: sectionFadeScaleIn 0.24s cubic-bezier(0.2, 0.8, 0.2, 1);
}

#campaign-new.section.active {
  animation: campaignCreateIn 0.34s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes sectionFadeScaleIn {
  from { opacity: 0; transform: translateY(0.6rem) scale(0.992); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes campaignCreateIn {
  from { opacity: 0; transform: translateY(1rem) scale(0.975); }
  65% { opacity: 1; transform: translateY(0) scale(1.006); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .section.active,
  #campaign-new.section.active {
    animation: none;
  }
}

.section-header {
  margin-bottom: 2rem;
}

.section-header h2 {
  font-size: 2.2rem;
  font-weight: 700;
  margin-bottom: 0.4rem;
}

.section-header p {
  color: var(--text-muted);
  font-size: 1.3rem;
  overflow-wrap: anywhere;
}

/* Removed: .hero-banner + .hero-content + .hero-actions + .btn-outline-light
   legacy dashboard hero. Replaced by .guest-hero-v2. .btn-white is still
   used by the wallet 'Add Funds' button so it stays. */

.btn-white {
  background: white;
  color: var(--blue);
  border: none;
}

.btn-white:hover {
  background: #f0f0f0;
}

/* Removed (Stage 4 cleanup): .card-row, .flex-1, .flex-2, full .stat-card
   stack, .activity-list/item/dot/time, .campaign-filters + .filter-row +
   .filter-group + .time-period + .location + .devider-filter.
   None of these classes appear in any HTML/PHP — ~190 lines deleted.
   Still kept: .card (used), .activity-text + .activity-empty (used). */
.card {
  background: var(--white);
  border-radius: var(--radius);
  padding: 2rem;
  box-shadow: var(--shadow);
  transition: box-shadow 0.2s;
  min-width: 0;
}
.card:hover {
  box-shadow: var(--shadow-lg);
}
.card h3 {
  font-size: 1.6rem;
  font-weight: 600;
  margin-bottom: 1.2rem;
}

.activity-text {
  flex: 1;
  color: var(--text);
}

.activity-empty {
  color: var(--text-muted);
  font-size: 1.3rem;
  text-align: center;
  padding: 2rem;
}

/* Removed (Stage 4): legacy .campaign-* design system. Replaced by .camp-*
   in php/partials/campaign-card.php. Kept only the still-used utility classes:
   .badge, .progress-bar, .progress-fill, .campaign-grid (used in #my-campaigns
   list and similar). ~120 lines deleted. */
.campaign-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(28rem, 1fr));
  gap: 1.6rem;
}

.badge {
  display: inline-block;
  padding: 0.2rem 0.8rem;
  font-size: 1rem;
  font-weight: 600;
  border-radius: var(--radius-full);
  background: var(--blue-light);
  color: var(--blue);
}

.progress-bar {
  width: 100%;
  height: 0.8rem;
  background: var(--border);
  border-radius: var(--radius-full);
  overflow: hidden;
  margin-bottom: 0.6rem;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--green), #2d9e33);
  border-radius: var(--radius-full);
  transition: width 0.5s ease;
}

/* --- Profile --- */
.profile-card {
  /* overflow:hidden removed — was clipping the avatar's camera badge that
     sits at right:-0.2rem bottom:-0.2rem on the avatar circle. */
  overflow: visible;
}

.profile-header {
  display: flex;
  align-items: flex-start;
  gap: 2.4rem;
  flex-wrap: wrap;
}

.avatar-column {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  flex-shrink: 0;
}

.profile-display-name {
  margin: 0;
  font-size: 1.8rem;
  font-weight: 700;
  color: var(--text);
  text-align: center;
  line-height: 1.2;
  max-width: 18rem;
  word-break: break-word;
}

.profile-display-name.is-placeholder {
  color: var(--text-muted);
  font-weight: 600;
  font-style: italic;
}

.profile-role-badge {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.4rem 1.2rem;
  background: var(--color-bg-deep, #f1f5f9);
  border: 1px solid var(--border);
  border-radius: 999px;
  line-height: 1;
  white-space: nowrap;
}

/* Driven by body class set by PHP (see <body class="role-…"> in userhome.html) */
body.role-donor .profile-role-badge::before { content: "Donor"; }
body.role-taker .profile-role-badge::before { content: "Recipient"; }
body.role-org   .profile-role-badge::before { content: "Organisation"; }

/* Hide the badge entirely when there is no authenticated role (e.g. guest mode) */
body.is-guest .profile-role-badge { display: none; }

/* Avatar — circular image with an always-visible camera badge in the
   bottom-right corner. Replaces the old hover/focus overlay, which on
   mobile left "Change Photo" stuck across the avatar after tap. Now the
   badge is the affordance — clear at every viewport, no sticky focus bug. */
.avatar-upload {
  position: relative;
  width: 11rem;
  height: 11rem;
  border-radius: 50%;
  border: 3px solid var(--white, #fff);
  box-shadow: 0 4px 16px rgba(37, 99, 235, 0.18), 0 0 0 3px rgba(37, 99, 235, 0.12);
  cursor: pointer;
  flex-shrink: 0;
  background: var(--color-bg-deep, #f1f5f9);
}

.avatar-upload img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 50%;
}

/* The label wraps both the image and an .avatar-overlay span. We now treat
   that span as a corner camera badge instead of an overlay sheet. */
.avatar-overlay {
  position: absolute;
  right: -0.2rem;
  bottom: -0.2rem;
  width: 3.4rem;
  height: 3.4rem;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.18);
  border: 2px solid #fff;
  transition: transform 0.18s ease, background 0.18s ease;
}
.avatar-overlay svg {
  width: 1.6rem;
  height: 1.6rem;
}
/* The "Change Photo" caption inside the overlay is now visually hidden but
   kept for screen readers and focus context. */
.avatar-overlay > span {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  border: 0;
  white-space: nowrap;
}
.avatar-upload:hover .avatar-overlay,
.avatar-upload:focus-visible .avatar-overlay {
  background: var(--color-primary-dark);
  transform: scale(1.05);
}

.profile-fields {
  flex: 1;
  min-width: 24rem;
}

.profile-fields label {
  display: block;
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 0.4rem;
}

.profile-fields input,
.profile-fields textarea {
  width: 100%;
  padding: 0.8rem 1.2rem;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 1.4rem;
  font-family: inherit;
  color: var(--text);
  transition: border-color 0.2s;
  margin-bottom: 0.4rem;
  background: var(--white);
}

.profile-fields input:focus,
.profile-fields textarea:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(37, 99, 235,.15);
}

.profile-fields textarea {
  resize: vertical;
  min-height: 8rem;
  margin-bottom: 1.2rem;
}

.field-hint {
  font-size: 1rem;
  color: var(--text-muted);
  margin-bottom: 0.8rem;
}

.field-hint.error {
  color: #ef4444;
}

input.error,
textarea.error,
select.error {
  border-color: #ef4444 !important;
}

/* --- Wallet --- */
.wallet-card {
  background: linear-gradient(135deg, var(--blue) 0%, #1d4ed8 100%);
  color: white;
}

/* The wallet page stacks three cards (balance/top-up, cash-out, history) with
   no margin on .card, so they sat flush. Give the lower two breathing room from
   the one above — matches the spacing bump on the Activity page. */
#wallet > .card + .card {
  margin-top: 2.4rem;
}

.wallet-card .balance-display {
  margin-bottom: 1.6rem;
}

.balance-label {
  font-size: 1.2rem;
  opacity: 0.8;
  margin-bottom: 0.2rem;
}

.wallet-balance {
  font-size: 3.6rem;
  font-weight: 700;
}

.wallet-card .wallet-balance {
  color: white;
}

.top-up-form {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.top-up-form input {
  width: 100%;
  padding: 0.8rem 1.2rem;
  border: 1.5px solid rgba(255,255,255,0.3);
  border-radius: var(--radius-sm);
  font-size: 1.4rem;
  transition: border-color 0.2s;
  background: rgba(255,255,255,0.15);
  color: white;
  font-family: 'Poppins', Arial, sans-serif;
}

.top-up-form input::placeholder {
  color: rgba(255,255,255,0.5);
}

.top-up-form input:focus {
  outline: none;
  border-color: white;
  background: rgba(255,255,255,0.25);
}

/* --- Buttons --- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.8rem 1.6rem;
  font-size: 1.3rem;
  font-weight: 600;
  border: none;
  border-radius: var(--radius-full);
  cursor: pointer;
  transition: all 0.2s;
  white-space: nowrap;
}

.btn:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow);
}

.btn-primary {
  background: var(--blue);
  color: white;
}

.btn-primary:hover {
  background: var(--blue-dark);
}

.btn-green {
  background: var(--green);
  color: white;
}

.btn-green:hover {
  background: var(--color-success-dark);
}

.btn-outline {
  background: transparent;
  border: 2px solid var(--border);
  color: var(--text);
}

.btn-outline:hover {
  border-color: var(--blue);
  color: var(--blue);
}

.btn-danger {
  background: #ef4444;
  color: white;
}

.btn-danger:hover {
  background: #dc2626;
}

.btn-sm {
  padding: 0.4rem 1rem;
  font-size: 1.1rem;
}

/* --- Transactions --- */
.transaction-list {
  list-style: none;
}

/* Removed: .transaction-item, .transaction-amount, .transaction-date —
   not used in HTML. Wallet transactions render via .wallet-tx partial. */

/* --- Campaign Form --- */
.campaign-form label {
  display: block;
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 0.4rem;
  margin-top: 1.2rem;
}

.campaign-form label:first-child {
  margin-top: 0;
}

.campaign-form input,
.campaign-form select,
.campaign-form textarea {
  width: 100%;
  padding: 0.8rem 1.2rem;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 1.4rem;
  font-family: inherit;
  color: var(--text);
  transition: border-color 0.2s;
  background: var(--white);
}

.campaign-form input:focus,
.campaign-form select:focus,
.campaign-form textarea:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(37, 99, 235,.15);
}

.campaign-form textarea {
  resize: vertical;
  min-height: 10rem;
}

.campaign-form select {
  appearance: none;
  background: var(--white) url("../images/chevron-down.svg") no-repeat right 1rem center / 1.2rem;
  cursor: pointer;
}

.campaign-form .form-row {
  display: flex;
  gap: 1.2rem;
  flex-wrap: wrap;
  min-width: 0;
}

.campaign-form .form-row > * {
  flex: 1;
  min-width: 20rem;
}

.campaign-form .btn {
  margin-top: 1.6rem;
}

.label_text {
  display: block;
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--text-muted);
  margin: 1.2rem 0 0.4rem;
}

.campaign-upload-hint,
.campaign-upload-count {
  font-size: 1.15rem;
  color: var(--text-muted);
  margin: 0.2rem 0 0.8rem;
}

.campaign-upload-count {
  margin-top: 0.6rem;
}

.campaign-upload {
  position: relative;
  width: 100%;
  min-height: 25rem;
  border: 2px dashed var(--border);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: border-color 0.2s, background 0.2s;
  color: var(--text-muted);
  font-size: 1.3rem;
  gap: 0.8rem;
  margin-top: 0.8rem;
  overflow: hidden;
}

.campaign-upload-multi {
  padding: 1rem;
}

.campaign-upload:hover {
  border-color: var(--blue);
  background: var(--blue-light);
}

.campaign-upload-preview {
  width: 100%;
  min-height: 20.8rem;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.8rem;
}

.campaign-upload-preview.is-empty {
  display: grid;
}

.campaign-upload-thumb,
.campaign-upload-add,
.campaign-upload-slot {
  position: relative;
  min-height: 9.8rem;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--border);
}

.campaign-upload-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  isolation: isolate;
  aspect-ratio: 4 / 3;
  transition: border-color 0.18s, box-shadow 0.18s, transform 0.18s, background 0.18s;
}

.campaign-upload-slot.is-empty {
  flex-direction: column;
  gap: 0.4rem;
  border-style: dashed;
  background:
    linear-gradient(135deg, rgba(37, 99, 235, 0.04), rgba(37, 99, 235, 0.02));
  color: var(--blue);
  text-align: center;
  font-weight: 700;
}

.campaign-upload-slot.is-empty small {
  color: var(--text-muted);
  font-size: 1.05rem;
  font-weight: 600;
}

.campaign-upload-slot-title {
  font-size: 1.15rem;
}

.campaign-upload-slot.is-empty:hover {
  border-color: var(--blue);
  background: rgba(37, 99, 235, 0.08);
}

.campaign-upload-thumb img,
.campaign-upload-slot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.campaign-upload svg {
  width: 3.2rem;
  height: 3.2rem;
}

.campaign-upload-cover {
  position: absolute;
  left: 0.6rem;
  top: 0.6rem;
  padding: 0.3rem 0.7rem;
  border-radius: var(--radius-full);
  background: rgba(15, 23, 42, 0.78);
  color: #fff;
  font-size: 1rem;
  font-weight: 700;
  z-index: 2;
}

.campaign-upload-slot:not(.is-cover) .campaign-upload-cover {
  background: rgba(15, 23, 42, 0.58);
  color: rgba(255, 255, 255, 0.86);
}

.campaign-image-remove {
  position: absolute;
  top: 0.45rem;
  right: 0.45rem;
  z-index: 3;
  width: 2.4rem;
  height: 2.4rem;
  border: 1px solid rgba(255, 255, 255, 0.54);
  border-radius: 50%;
  background: rgba(15, 23, 42, 0.68);
  color: #fff;
  cursor: pointer;
  font-size: 1.7rem;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: background 0.15s, transform 0.15s;
}

.campaign-image-remove:hover {
  background: rgba(239, 68, 68, 0.86);
  transform: scale(1.04);
}

.campaign-cover-choice {
  position: absolute;
  left: 0.6rem;
  right: 0.6rem;
  bottom: 0.6rem;
  z-index: 2;
  min-height: 2.8rem;
  border: 1px solid rgba(255, 255, 255, 0.52);
  border-radius: var(--radius-full);
  background: rgba(15, 23, 42, 0.70);
  color: #fff;
  font-family: inherit;
  font-size: 1.05rem;
  font-weight: 700;
  cursor: pointer;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.campaign-upload-thumb.is-cover,
.campaign-upload-slot.is-cover {
  border-color: rgba(37, 99, 235, 0.75);
  box-shadow:
    0 0 0 2px rgba(37, 99, 235, 0.16),
    0 10px 22px rgba(37, 99, 235, 0.16);
}

.campaign-upload-thumb.is-cover .campaign-cover-choice,
.campaign-upload-slot.is-cover .campaign-cover-choice {
  background: rgba(37, 99, 235, 0.82);
}

.campaign-upload-add {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  color: var(--blue);
  border-style: dashed;
  font-weight: 700;
}

.campaign-upload-add svg {
  width: 2.2rem;
  height: 2.2rem;
}

@media (max-width: 640px) {
  .campaign-upload-preview {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    min-height: 30rem;
  }

  .campaign-upload {
    min-height: 34rem;
  }
}

/* --- Empty State --- */
.empty-state svg {
  width: 6rem;
  height: 6rem;
  margin-bottom: 1rem;
  opacity: 0.3;
}

.empty-state h3 {
  font-size: 1.6rem;
  margin-bottom: 0.4rem;
  color: var(--text);
}

.empty-state p {
  font-size: 1.3rem;
}

/* --- Toast --- */
.toast {
  position: fixed;
  top: 7rem;
  right: 2rem;
  padding: 1rem 2rem;
  border-radius: var(--radius-sm);
  font-size: 1.3rem;
  font-weight: 600;
  color: white;
  background: var(--green);
  box-shadow: var(--shadow-lg);
  /* Above the modals (z-index 320): the donation success/fail message has to be
     readable even while a modal is still on screen, and it is the one thing the
     donor needs to see after paying. */
  z-index: 600;
  opacity: 0;
  transform: translateY(-1rem) scale(0.95);
  transition: all 0.3s;
  pointer-events: none;
}

.toast.show {
  opacity: 1;
  transform: translateY(0) scale(1);
}

.toast.error {
  background: #ef4444;
}

/* --- Modal --- */
.modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(2, 6, 23, 0.72);
  z-index: 320;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  overflow-y: auto;
}

.modal-overlay.show {
  display: flex;
}

.modal {
  background: var(--white);
  border-radius: var(--radius);
  padding: 2.4rem;
  width: 100%;
  max-width: 42rem;
  max-height: calc(100dvh - 4rem);
  overflow-y: auto;
  box-shadow: var(--shadow-xl);
  position: relative;
  animation: modalIn 0.25s ease;
}

/* Payment step sits ABOVE the campaign modal (both are .modal-overlay z-index
   320) so it can open on top of an already-open campaign without closing it. */
#donate-modal {
  z-index: 340;
}
#donate-modal .modal {
  max-width: 56rem;
}

@keyframes modalIn {
  from { opacity: 0; transform: scale(0.9) translateY(10px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}

.modal-close {
  position: absolute;
  top: 1.2rem;
  right: 1.2rem;
  width: 3.2rem;
  height: 3.2rem;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--white);
  cursor: pointer;
  font-size: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  transition: all 0.2s;
}

.modal-close:hover {
  background: var(--bg);
  color: var(--text);
}

.modal h3 {
  font-size: 1.8rem;
  font-weight: 700;
  margin-bottom: 0.4rem;
}

.modal-desc {
  font-size: 1.3rem;
  color: var(--text-muted);
  margin-bottom: 1.6rem;
}

.modal-balance {
  font-size: 1.3rem;
  color: var(--text-muted);
  margin-bottom: 1.2rem;
}

.modal-balance strong {
  color: var(--text);
}

.modal label {
  display: block;
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 0.4rem;
}

.modal input[type="number"],
.modal input[type="text"],
.modal input[type="email"],
.modal input[type="tel"] {
  width: 100%;
  padding: 0.8rem 1.2rem;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 1.6rem;
  transition: border-color 0.2s, box-shadow 0.2s;
  font-family: inherit;
}

.modal input[type="number"]:focus,
.modal input[type="text"]:focus,
.modal input[type="email"]:focus,
.modal input[type="tel"]:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(37, 99, 235,.15);
}

.donation-fee-summary {
  display: grid;
  gap: 0.7rem;
  margin: 1.2rem 0 0.2rem;
  padding: 1.2rem;
  border: 1px solid rgba(37, 99, 235, 0.18);
  border-radius: 1.2rem;
  background: var(--color-primary-light);
}
.donation-fee-summary div {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.2rem;
  font-size: 1.2rem;
  color: var(--text-muted);
}
.donation-fee-summary strong {
  font-size: 1.25rem;
  color: var(--text);
  text-align: right;
}

.payment-method-list {
  border: 0;
  padding: 0;
  margin: 1.4rem 0 0;
  display: grid;
  gap: 0.8rem;
}
.payment-method-list legend {
  font-size: 1.2rem;
  font-weight: 800;
  color: var(--text);
  margin-bottom: 0.6rem;
}
.payment-method-option {
  position: relative;
  display: grid;
  grid-template-columns: 4.4rem 1fr;
  align-items: center;
  gap: 1rem;
  padding: 1rem 4.2rem 1rem 1rem;
  border: 1.5px solid var(--color-border);
  border-radius: 1.2rem;
  background: var(--color-surface);
  cursor: pointer;
  transition: border-color 0.2s, box-shadow 0.2s, background 0.2s, transform 0.2s;
}
.payment-method-option:hover {
  border-color: rgba(37, 99, 235, 0.4);
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(15, 23, 42, 0.08);
}
.payment-method-option:has(input:focus-visible) {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.18);
}
/* Selected state — strong, unmistakable. Border thickens to primary, soft
   blue tint inside, primary-tinted glow shadow, gentle scale lift. */
.payment-method-option:has(input:checked) {
  border-color: var(--color-primary);
  border-width: 2px;
  background:
    linear-gradient(180deg, rgba(37, 99, 235, 0.14) 0%, rgba(37, 99, 235, 0.05) 100%);
  box-shadow:
    0 0 0 4px rgba(37, 99, 235, 0.14),
    0 14px 32px rgba(37, 99, 235, 0.20);
  transform: translateY(-2px);
}
/* Recommended ribbon */
.payment-method-option.is-recommended::before {
  content: 'Recommended';
  position: absolute;
  top: 0.7rem;
  right: 1rem;
  padding: 0.18rem 0.65rem;
  border-radius: var(--r-full);
  background: linear-gradient(135deg, #16a34a, #22c55e);
  color: #fff;
  font-size: 0.9rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  box-shadow: 0 2px 8px rgba(22, 163, 74, 0.3);
}
/* Best-rate ribbon (wallet — for members only) */
.payment-method-option.is-best::before {
  content: 'Best rate';
  position: absolute;
  top: 0.7rem;
  right: 1rem;
  padding: 0.18rem 0.65rem;
  border-radius: var(--r-full);
  background: linear-gradient(135deg, #7c3aed, #2563eb);
  color: #fff;
  font-size: 0.9rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  box-shadow: 0 2px 8px rgba(124, 58, 237, 0.3);
}
/* Coming-soon ribbon (wallet — backend not wired yet). Dims the card so
   users see it's not selectable. We DO NOT fake any payment success. */
.payment-method-option.is-coming-soon {
  cursor: not-allowed;
  opacity: 0.62;
}
.payment-method-option.is-coming-soon:hover {
  transform: none;
  border-color: var(--color-border);
  box-shadow: none;
}
.payment-method-option.is-coming-soon::before {
  content: 'Coming soon';
  position: absolute;
  top: 0.7rem;
  right: 1rem;
  padding: 0.18rem 0.65rem;
  border-radius: var(--r-full);
  background: linear-gradient(135deg, #f59e0b, #d97706);
  color: #fff;
  font-size: 0.9rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  box-shadow: 0 2px 8px rgba(245, 158, 11, 0.32);
}
.payment-method-option.is-coming-soon .payment-method-icon {
  background: var(--color-bg-deep);
  color: var(--color-text-muted);
}
.payment-method-fee--soon {
  background: var(--color-warning-light);
  color: var(--color-warning);
}
.payment-method-fee--save {
  background: var(--color-success-light);
  color: var(--color-success-dark);
  font-weight: 800;
}

/* Guest-only "Sign up to unlock" Wallet card — fills the 3rd column in the
   payment grid (since the real Wallet card is auth-only). Hover lifts and
   highlights to nudge signup. Anchor element, so no radio + no submit. */
.payment-method-option.is-locked {
  position: relative;
  text-decoration: none;
  cursor: pointer;
  border-style: dashed;
  border-color: var(--color-primary);
  background: var(--color-primary-light);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
.payment-method-option.is-locked:hover {
  transform: translateY(-3px);
  border-style: solid;
  background: color-mix(in srgb, var(--color-primary) 14%, var(--color-surface));
  box-shadow: 0 12px 28px rgba(37, 99, 235, 0.22);
}
.payment-method-option.is-locked::after { display: none; }   /* no check circle */
.payment-method-option.is-locked .payment-method-lock {
  position: absolute;
  bottom: 1.2rem;
  right: 1.2rem;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.payment-method-option.is-locked .payment-method-lock svg { width: 1.4rem; height: 1.4rem; }
html[data-theme="dark"] .payment-method-option.is-locked {
  background: rgba(37, 99, 235, 0.14);
  border-color: rgba(96, 165, 250, 0.5);
}
html[data-theme="dark"] .payment-method-option.is-locked:hover {
  background: rgba(37, 99, 235, 0.22);
}
/* Hide the native radio — we render a custom check on the right */
.payment-method-option input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 0.1rem;
  height: 0.1rem;
}
/* Custom check indicator (third column) */
.payment-method-option::after {
  content: '✓';
  position: absolute;
  right: 1rem;
  bottom: 1rem;
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 50%;
  border: 1.5px solid var(--color-border);
  background: var(--color-surface);
  color: transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  font-weight: 900;
  opacity: 0.72;
  transition: border-color 0.2s, background 0.2s, color 0.2s, opacity 0.2s;
}
.payment-method-option:has(input:checked)::after {
  border-color: var(--color-primary);
  background: var(--color-primary);
  color: #fff;
  opacity: 1;
}
.payment-method-icon {
  grid-column: 1;
  width: 4.4rem;
  height: 4.4rem;
  border-radius: 1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-primary);
  color: #fff;
  font-size: 1.7rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  flex-shrink: 0;
}
.payment-method-icon svg {
  width: 2.1rem;
  height: 2.1rem;
}
.payment-method-body {
  grid-column: 2;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}
.payment-method-option strong {
  display: block;
  font-size: 1.38rem;
  font-weight: 700;
  color: var(--color-text);
  line-height: 1.2;
}
.payment-method-option small {
  display: block;
  margin-top: 0.2rem;
  font-size: 1.14rem;
  color: var(--color-text-muted);
  line-height: 1.45;
}
.payment-method-fee {
  display: inline-block;
  margin-top: 0.45rem;
  padding: 0.25rem 0.7rem;
  border-radius: var(--r-full);
  background: var(--color-bg-deep);
  color: var(--color-text-muted);
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.4;
}
.payment-method-fee--best {
  background: var(--color-success-light);
  color: var(--color-success-dark);
}
.payment-method-icon--whish {
  background: linear-gradient(135deg, #e91e63, #7c3aed);
}
.payment-method-icon--card {
  background: linear-gradient(135deg, #1A1F71, #2563eb);
}
/* Auth-state fee rate switches (used inside donate modal copy) */
.fee-rate          { font-variant-numeric: tabular-nums; }
.fee-rate-note     { color: var(--color-text-muted); font-weight: 500; margin-left: 0.4rem; }
.fee-rate-note a   { color: var(--color-primary); font-weight: 700; text-decoration: none; }
.fee-rate-note a:hover { text-decoration: underline; }
body.is-auth  .fee-rate--guest { display: none !important; }
body.is-guest .fee-rate--user  { display: none !important; }
/* Expanded info panel — revealed when the radio is checked */
.payment-method-extra {
  display: none !important;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px dashed var(--color-border);
  flex-direction: column;
  gap: 0.6rem;
}
.payment-method-option:has(input:checked) .payment-method-extra { display: none !important; }
.pm-extra-row {
  display: grid;
  grid-template-columns: 9rem 1fr;
  gap: 0.8rem;
  font-size: 1.15rem;
  line-height: 1.45;
  color: var(--color-text-muted);
}
.pm-extra-label {
  font-weight: 700;
  color: var(--color-text);
  font-size: 1.1rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.payment-method-details {
  margin-top: 1rem;
  padding: 1.2rem 1.4rem;
  border: 1px solid rgba(37, 99, 235, 0.18);
  border-radius: 1.2rem;
  background: linear-gradient(135deg, rgba(37, 99, 235, 0.06), rgba(248, 250, 252, 0.92));
  display: grid;
  gap: 0.8rem;
}

.payment-method-details > strong {
  font-size: 1.3rem;
  color: var(--color-text);
}

.pm-detail-row {
  display: grid;
  grid-template-columns: 10rem 1fr;
  gap: 1rem;
  align-items: baseline;
}

.pm-detail-row > span {
  color: var(--color-text);
  font-size: 1.1rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.pm-detail-row > small {
  color: var(--color-text-muted);
  font-size: 1.2rem;
  line-height: 1.45;
}

@media (min-width: 720px) {
  #donate-modal .payment-method-list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  #donate-modal .payment-method-list legend {
    grid-column: 1 / -1;
  }

  /* Vertical payment card layout (world-class checkout feel).
     Structure top → bottom:
        Ribbon (top-right, ~3rem zone)
        Large icon (centered, 5rem)
        Title (bold, 1-line)
        Fee chip (subtle pill)
        Check circle (absolute, bottom-right)
     All cards share min-height so they line up across the row. */
  #donate-modal .payment-method-list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.4rem;
  }
  #donate-modal .payment-method-list legend {
    grid-column: 1 / -1;
  }

  #donate-modal .payment-method-option {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto;
    justify-items: center;
    text-align: center;
    align-content: start;
    gap: 3.6rem;            /* generous icon → title breathing room */
    min-height: 22rem;
    padding: 5rem 1.6rem 5.2rem;  /* top clears ribbon, bottom clears check */
    border-radius: 1.4rem;
  }

  /* Ribbons — top-right corner pill, never crowds the icon. */
  #donate-modal .payment-method-option.is-recommended::before,
  #donate-modal .payment-method-option.is-best::before,
  #donate-modal .payment-method-option.is-coming-soon::before {
    top: 1.1rem;
    right: 1.1rem;
    max-width: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    padding: 0.3rem 0.9rem;
    font-size: 0.95rem;
  }

  /* Icon — generous size for visual weight. */
  #donate-modal .payment-method-icon {
    width: 5.2rem;
    height: 5.2rem;
    border-radius: 1.4rem;
    font-size: 2rem;
  }
  #donate-modal .payment-method-icon svg {
    width: 2.6rem;
    height: 2.6rem;
  }

  /* Check circle — clearly visible bottom-right. */
  #donate-modal .payment-method-option::after {
    top: auto;
    right: 1.2rem;
    bottom: 1.2rem;
    width: 2.6rem;
    height: 2.6rem;
    font-size: 1.4rem;
  }

  /* Body stack — title + fee chip. */
  #donate-modal .payment-method-body {
    grid-column: 1;
    align-items: center;
    text-align: center;
    padding-right: 0;
    gap: 1rem;
    width: 100%;
  }

  /* Single-line bold title. */
  #donate-modal .payment-method-option strong {
    white-space: nowrap;
    font-size: 1.6rem;
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: -0.01em;
  }

  /* Hide subtext in vertical mode — fee chip already says enough. */
  #donate-modal .payment-method-option small {
    display: none;
  }

  /* Fee chip — subtle, never wraps. */
  #donate-modal .payment-method-fee {
    margin-top: 0;
    white-space: nowrap;
    padding: 0.32rem 0.9rem;
    font-size: 1rem;
    font-weight: 700;
  }

  #donate-modal .payment-method-details {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  #donate-modal .payment-method-details > strong {
    grid-column: 1 / -1;
  }

  #donate-modal .pm-detail-row {
    grid-template-columns: 1fr;
    gap: 0.2rem;
  }
}
@media (max-width: 520px) {
  .pm-extra-row { grid-template-columns: 1fr; gap: 0.2rem; }
  .pm-detail-row { grid-template-columns: 1fr; gap: 0.2rem; }
}
.modal-cover-fee {
  display: flex !important;
  align-items: flex-start;
  gap: 0.8rem;
  margin: 1.2rem 0 0;
  padding: 1rem 1.2rem;
  border-radius: 1rem;
  background: rgba(22, 163, 74, 0.08);
  color: var(--text-muted);
  text-transform: none !important;
  letter-spacing: 0 !important;
}

.modal-required-fee {
  align-items: center;
  border: 1px solid rgba(37, 99, 235, 0.18);
  background: rgba(37, 99, 235, 0.07);
}

.required-fee-icon {
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.15rem;
  font-weight: 900;
  flex-shrink: 0;
}

.modal-required-fee strong {
  color: var(--color-primary);
}

.modal-cover-fee input {
  width: 1.7rem;
  height: 1.7rem;
  margin-top: 0.1rem;
  accent-color: var(--green);
}

@media (max-width: 480px) {
  .payment-method-option {
    grid-template-columns: 3.8rem 1fr;
    padding: 1rem;
    padding-right: 3.8rem;
  }
  .payment-method-icon {
    width: 3.8rem;
    height: 3.8rem;
    border-radius: 1rem;
  }
  .modal-actions {
    flex-direction: column-reverse;
  }
  .modal-actions .btn {
    width: 100%;
    justify-content: center;
  }
}

/* Guest-only fields in donate modal: subtle divider + tighter label rhythm */
.modal .guest-only-label {
  margin-top: 1.2rem;
  display: block;
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 0.4rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.modal .guest-only-label[for="modal-donor-name"] {
  margin-top: 1.8rem;
  padding-top: 1.4rem;
  border-top: 1px dashed var(--border);
}

.modal-hint {
  font-size: 1.1rem;
  color: var(--text-muted);
  margin-top: 0.6rem;
}

.modal-goal-info {
  margin-bottom: 1.6rem;
}

.modal-goal-text {
  font-size: 1.2rem;
  color: var(--text-muted);
  margin-top: 0.4rem;
}

.modal-goal-text .raised {
  font-weight: 700;
  color: var(--green);
}

.modal-actions {
  display: flex;
  gap: 1rem;
  margin-top: 1.6rem;
  justify-content: flex-end;
}
/* Buttons with inline directional icons (Back / Continue / Review) */
.modal-back-btn,
.modal-next-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}
.modal-back-btn svg,
.modal-next-btn svg {
  width: 1.5rem;
  height: 1.5rem;
  flex-shrink: 0;
  transition: transform 0.18s ease;
}
.modal-next-btn:hover svg:last-child { transform: translateX(2px); }
.modal-back-btn:hover svg:first-child { transform: translateX(-2px); }

/* --- Mobile --- */
.mobile-overlay {
  display: none;
}

@media (max-width: 768px) {
  .sidebar {
    position: fixed;
    left: 0;
    /* Top of the stack while open: above the overlay (z:110) and the bottom
       nav (z:100). At z:30 the drawer rendered underneath both, so its items
       could be seen but not tapped. */
    z-index: 120;
    /* Full height, starting at the very top rather than 5.8rem down.
       The drawer sits at z-index 120, above the header, so it does not need to
       leave room for it — and starting below it was the source of every
       sizing complaint: the height then depended on where the header ended.
       Sized by svh, not vh/dvh and not by top+bottom: a fixed box sized by
       `bottom` resolves against the *dynamic* viewport, which is exactly what
       changes when mobile browser chrome collapses mid-scroll, so the drawer
       visibly resized while scrolling. svh is the viewport with the chrome
       showing — the smallest it ever gets — so the height cannot move. The vh
       line is the fallback for engines without svh. */
    top: 0;
    bottom: auto;
    height: 100vh;
    height: 100svh;
    /* A touch wider than the old 28rem so the longer labels breathe. */
    width: 30rem;
    border-radius: 0 1.6rem 1.6rem 0;
    transform: translateX(-100%);
    transition: transform 0.3s;
    box-shadow: var(--shadow-lg);
  }
  .sidebar.open { transform: translateX(0); }

  .mobile-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.3);
    z-index: 25;
  }
  .mobile-overlay.show { display: block; }

  .main-content { padding: 1.6rem; }

  .profile-header {
    flex-direction: column;
    align-items: stretch;
    gap: 1.8rem;
  }
  .avatar-column {
    align-self: center;
    gap: 1.2rem;
    width: 100%;
    border-bottom: 1px solid var(--border);
    padding-bottom: 1.8rem;
  }
  .avatar-upload { width: 12rem; height: 12rem; }
  /* The gradient-pill override that used to live here was left over from when
     .avatar-overlay covered the whole avatar. It is a solid blue corner camera
     badge now, and repainting its background with a transparent-to-black
     gradient made it almost invisible against the photo — the badge only
     looked present on hover, where the base rule darkens it. The badge needs
     no touch hint: it is always visible by design. */
  .avatar-upload .avatar-overlay { width: 3.8rem; height: 3.8rem; }
  .avatar-upload .avatar-overlay svg { width: 1.8rem; height: 1.8rem; }
  .profile-display-name { font-size: 2rem; }
  .profile-fields { width: 100%; min-width: 0; }
  .profile-save-btn {
    width: 100%;
    margin-top: 0.4rem;
    padding: 1.2rem;
    font-size: 1.5rem;
  }
  .wallet-balance { font-size: 2.4rem; }
  .campaign-grid { grid-template-columns: 1fr; }
}

/* Removed: @media (min-width: 769px) block that styled .campaign-filters,
   .filter-row, .time-period, .location — all dead classes from the
   legacy filter UI replaced by .discover-toolbar. */

/* --- Sidebar Brand --- */
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  padding: 2rem 2rem 1.6rem;
  flex-shrink: 0;
  position: relative;
}

.sidebar-logo-circle {
  width: 6rem;
  height: 6rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1.5px solid rgba(37, 99, 235, 0.22);
  box-shadow: 0 2px 12px rgba(37, 99, 235, 0.14), 0 0 0 3px rgba(37, 99, 235, 0.06);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.sidebar-logo-circle img {
  width: 4rem;
  height: 4rem;
}

.sidebar-brand span {
  font-size: 2.1rem;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.01em;
}

/* --- Sidebar User Card (profile chip at top) --- */
.sidebar-user {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  margin: 0 1.2rem 1.2rem;
  padding: 1rem 1.2rem;
  background: linear-gradient(135deg, rgba(37, 99, 235, 0.08) 0%, rgba(37, 99, 235, 0.03) 100%);
  border: 1px solid rgba(37, 99, 235, 0.15);
  border-radius: 1.2rem;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: all 0.2s;
  width: calc(100% - 2.4rem);
}

.sidebar-user:hover {
  background: linear-gradient(135deg, rgba(37, 99, 235, 0.14) 0%, rgba(37, 99, 235, 0.06) 100%);
  border-color: rgba(37, 99, 235, 0.28);
  transform: translateY(-1px);
}

.sidebar-user-avatar {
  width: 4rem;
  height: 4rem;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid var(--white, #fff);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
  flex-shrink: 0;
  background: var(--color-bg-deep, #f1f5f9);
}

.sidebar-user-info {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
  flex: 1;
}

.sidebar-user-name {
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--text);
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar-user-role {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--blue, #2563eb);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  line-height: 1;
}

/* Role label is set by the same body class PHP applies to .profile-role-badge */
body.role-donor .sidebar-user-role::before { content: "Donor"; }
body.role-taker .sidebar-user-role::before { content: "Recipient"; }
body.role-org   .sidebar-user-role::before { content: "Organisation"; }

.sidebar-user-chevron {
  width: 1.6rem;
  height: 1.6rem;
  color: var(--text-muted);
  flex-shrink: 0;
  opacity: 0.6;
}

/* ── Preset amount selector — segmented control ──
   Connected pill row with 4 equal segments. Replaces the old loose-button
   wrap layout that read as "too many cubes" on mobile. The selected segment
   fills primary blue; others stay quiet. Single source of truth; old styles
   deleted per the cleanup rule. */
.preset-amounts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.3rem;
  padding: 0.4rem;
  margin-bottom: 1rem;
  background: var(--color-bg-deep);
  border: 1.5px solid var(--color-border);
  border-radius: var(--r-full);
}

.preset-btn {
  padding: 0.9rem 0.4rem;
  border: none;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--color-text-muted);
  font-family: inherit;
  font-size: 1.4rem;
  font-weight: 800;
  cursor: pointer;
  min-height: 4.4rem;
  transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease;
  letter-spacing: -0.01em;
}

.preset-btn:hover:not(.selected) {
  color: var(--color-text);
  background: rgba(15, 23, 42, 0.04);
}

/* Active/selected state for the segmented amount control — was missing,
   so users got no feedback when they picked $10/$25/etc. Now a clear
   primary-color pill marks the selection. Matches the modern segmented
   control pattern (iOS, GitHub, Stripe). */
.preset-btn.selected {
  background: var(--color-primary);
  color: #fff;
  box-shadow: 0 2px 8px rgba(37, 99, 235, 0.32);
}
.preset-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.22);
}
html[data-theme="dark"] .preset-btn.selected {
  background: var(--color-primary);
  color: #fff;
  box-shadow: 0 2px 10px rgba(96, 165, 250, 0.35);
}

.preset-btn.selected {
  background: var(--color-primary);
  color: #fff;
  box-shadow: 0 4px 14px rgba(37, 99, 235, 0.32);
}

/* Wallet top-up sits on a dark navy wallet card — invert the segmented bg
   so the control still reads against the dark surface. */
.wallet-card .preset-amounts {
  background: rgba(255, 255, 255, 0.10);
  border-color: rgba(255, 255, 255, 0.18);
}
.wallet-card .preset-btn {
  color: rgba(255, 255, 255, 0.78);
}
.wallet-card .preset-btn:hover {
  background: rgba(255, 255, 255, 0.10);
  color: #fff;
}
.wallet-card .preset-btn.selected {
  background: #fff;
  color: var(--color-primary);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.24);
}

html[data-theme="dark"] .preset-amounts {
  background: rgba(15, 23, 42, 0.6);
  border-color: var(--color-border);
}

/* Top-up input row */
.top-up-input-row {
  display: flex;
  gap: 1rem;
  align-items: center;
  flex-wrap: wrap;
  border-top: 1px solid var(--border);
  padding-top: 1.2rem;
  margin-top: 0.4rem;
}

.wallet-card .top-up-input-row {
  border-top-color: rgba(255, 255, 255, 0.2);
}

.top-up-input-row input {
  flex: 1;
  min-width: 14rem;
}

.wallet-cashout-card {
  gap: 1.6rem;
}

.wallet-cashout-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1.2rem;
}

.wallet-cashout-head h3 {
  margin: 0 0 0.35rem;
  color: #0f172a;
  font-size: 1.8rem;
}

.wallet-cashout-head p {
  margin: 0;
  color: #64748b;
  font-size: 1.25rem;
  line-height: 1.45;
}

.wallet-fee-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  padding: 0.45rem 0.8rem;
  background: rgba(37, 99, 235, 0.10);
  color: var(--color-primary);
  font-size: 1.05rem;
  font-weight: 800;
  white-space: nowrap;
}

.cashout-form,
.cashout-methods {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.cashout-methods {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.cashout-method {
  position: relative;
  display: grid;
  grid-template-columns: 4rem minmax(0, 1fr);
  gap: 1.15rem;
  align-items: center;
  padding: 1rem;
  border: 1.5px solid #e2e8f0;
  border-radius: 1.2rem;
  background: #f8fafc;
  cursor: pointer;
  transition: border-color 0.16s, background 0.16s, box-shadow 0.16s;
}

.cashout-method:hover,
.cashout-method:has(input:checked) {
  border-color: rgba(37, 99, 235, 0.42);
  background: #fff;
  box-shadow: 0 8px 20px rgba(37, 99, 235, 0.10);
}

.cashout-method input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.cashout-method-icon {
  width: 4rem;
  height: 4rem;
  border-radius: 1rem;
  background: linear-gradient(135deg, #e91e63, #7c3aed);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 900;
  font-size: 1.5rem;
}

.cashout-method-icon.card-icon {
  background: linear-gradient(135deg, #1A1F71, #2563eb);
}

.cashout-method-icon svg {
  width: 2rem;
  height: 2rem;
}

.cashout-method strong {
  display: block;
  color: #0f172a;
  font-size: 1.25rem;
}

.cashout-method small {
  display: block;
  color: #64748b;
  font-size: 1.08rem;
  line-height: 1.35;
  margin-top: 0.15rem;
}

.cashout-grid {
  display: grid;
  grid-template-columns: 16rem minmax(0, 1fr);
  gap: 1rem;
}

.cashout-grid label {
  display: block;
  color: #64748b;
  font-size: 1.15rem;
  font-weight: 700;
}

.cashout-grid input {
  display: block;
  width: 100%;
  margin-top: 0.35rem;
  padding: 0.85rem 1rem;
  border: 1.5px solid #e2e8f0;
  border-radius: 0.9rem;
  background: #fff;
  color: #0f172a;
  font-family: inherit;
}

.cashout-note {
  padding: 1rem 1.2rem;
  border: 1px solid rgba(37, 99, 235, 0.18);
  border-radius: 1rem;
  background: rgba(37, 99, 235, 0.07);
  color: #475569;
  font-size: 1.15rem;
  line-height: 1.45;
}

html[data-theme="dark"] .wallet-cashout-head h3,
html[data-theme="dark"] .cashout-method strong {
  color: #e5e7eb;
}

html[data-theme="dark"] .wallet-cashout-head p,
html[data-theme="dark"] .cashout-method small,
html[data-theme="dark"] .cashout-grid label,
html[data-theme="dark"] .cashout-note {
  color: #94a3b8;
}

html[data-theme="dark"] .cashout-method {
  background: rgba(15, 23, 42, 0.76);
  border-color: rgba(148, 163, 184, 0.16);
}

html[data-theme="dark"] .cashout-method:hover,
html[data-theme="dark"] .cashout-method:has(input:checked) {
  background: rgba(37, 99, 235, 0.12);
  border-color: rgba(96, 165, 250, 0.34);
  box-shadow: none;
}

html[data-theme="dark"] .cashout-note {
  background: rgba(37, 99, 235, 0.12);
  border-color: rgba(96, 165, 250, 0.24);
}

html[data-theme="dark"] .cashout-grid input {
  background: rgba(15, 23, 42, 0.72);
  border-color: rgba(148, 163, 184, 0.24);
  color: #e5e7eb;
}

@media (max-width: 640px) {
  .wallet-cashout-head {
    align-items: flex-start;
    gap: 0.8rem;
  }

  .cashout-methods,
  .cashout-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 480px) {
  .wallet-cashout-card {
    gap: 1.05rem;
  }

  .wallet-cashout-head h3 {
    font-size: 1.65rem;
  }

  .wallet-cashout-head p {
    font-size: 1.12rem;
    line-height: 1.35;
  }

  .wallet-fee-pill {
    padding: 0.35rem 0.65rem;
    font-size: 0.95rem;
  }

  .cashout-form,
  .cashout-methods {
    gap: 0.75rem;
  }

  .cashout-method {
    grid-template-columns: 3.7rem minmax(0, 1fr);
    gap: 0.9rem;
    padding: 0.85rem;
    border-radius: 1rem;
  }

  .cashout-method-icon {
    width: 3.7rem;
    height: 3.7rem;
  }

  .cashout-method strong {
    font-size: 1.15rem;
  }

  .cashout-method small {
    font-size: 0.98rem;
    line-height: 1.28;
  }

  .cashout-grid {
    gap: 0.75rem;
  }

  .cashout-grid input {
    padding: 0.78rem 0.9rem;
  }

  .cashout-note {
    padding: 0.8rem 0.95rem;
    font-size: 1.04rem;
    line-height: 1.35;
  }
}

/* Removed: .auth-overlay / .auth-modal stack (~150 lines). The popover was
   only ever triggered from the auth-only bottom-nav, which guests can't see.
   Dead UI. If we ever need a guest auth-gate, build a fresh small modal. */

/* .sidebar-close removed — drawer closes via overlay tap or nav-item tap */

/* ── Sidebar visual polish ── */

.sidebar::before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 3px; height: 100%;
  background: linear-gradient(180deg, var(--color-primary) 0%, var(--color-purple) 100%);
  pointer-events: none;
}

/* ── Sidebar toggle button (inside brand) ── */
.sidebar-toggle {
  display: none;
  margin-left: auto;
  width: 3.2rem;
  height: 3.2rem;
  border-radius: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--text-muted);
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.2s, color 0.2s;
}
.sidebar-toggle:hover {
  background: var(--blue-light);
  color: var(--blue);
}
.sidebar-toggle:active,
.sidebar-toggle.pressed {
  background: var(--blue-light);
  color: var(--blue);
}
.sidebar-toggle svg {
  transition: transform 0.25s ease;
}

@media (min-width: 769px) {
  .sidebar-toggle { display: flex; }
  .sidebar { transition: width 0.25s ease; }
}

/* ── Sidebar collapsed (icon-only) ── */
.sidebar.collapsed {
  width: 6rem;
}
.sidebar.collapsed .sidebar-brand span,
.sidebar.collapsed .sidebar-item span {
  display: none;
}
.sidebar.collapsed .sidebar-user {
  margin: 0 0.8rem 1.2rem;
  padding: 0.6rem;
  width: calc(100% - 1.6rem);
  justify-content: center;
}
.sidebar.collapsed .sidebar-user-info,
.sidebar.collapsed .sidebar-user-chevron {
  display: none;
}
.sidebar.collapsed .sidebar-user-avatar {
  width: 3.6rem;
  height: 3.6rem;
}
.sidebar.collapsed .sidebar-brand {
  justify-content: flex-start;
  padding: 1.2rem 0 1.2rem 0.8rem;
  gap: 0;
}
.sidebar.collapsed .sidebar-item {
  justify-content: center;
  padding: 1.2rem 0;
}
.sidebar.collapsed .sidebar-brand .sidebar-toggle {
  position: absolute;
  right: -3rem;
  top: 50%;
  transform: translateY(-50%);
  margin-left: 0;
  background: var(--white);
  border: 1.5px solid var(--border);
  box-shadow: var(--shadow);
  width: 3.2rem;
  height: 3.2rem;
}
.sidebar.collapsed .sidebar-toggle svg {
  transform: rotate(180deg);
}
.sidebar.collapsed .sidebar-item.active::before {
  top: 0.6rem;
  bottom: 0.6rem;
}

/* ── Filter bar ── */
.filter-primary-row {
  display: flex;
  align-items: center;
  gap: 0.8rem;
}

.filter-scroll {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  flex: 1;
}

@media (max-width: 768px) {
  .filter-scroll {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    padding-bottom: 0.2rem;
  }
  .filter-scroll::-webkit-scrollbar { display: none; }
}

.filter-toggle-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.8rem 1.4rem;
  font-size: 1.2rem;
  font-weight: 600;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--white);
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  min-height: 4.4rem;
  font-family: 'Poppins', Arial, sans-serif;
  transition: all 0.2s;
}
.filter-toggle-btn:hover,
.filter-toggle-btn.active {
  border-color: var(--blue);
  color: var(--blue);
  background: var(--blue-light);
}

/* ── Touch targets — min 44 px (preset-btn already sets its own 4.4rem) ── */
.btn        { min-height: 4.4rem; }

/* Mobile font tweaks */
@media (max-width: 768px) {
  .card { padding: 2rem; }
  .section-header p { font-size: 1.4rem; }
}

/* ── 3-column campaign grid on wide screens ── */
@media (min-width: 1280px) {
  .campaign-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* ── Keyboard focus ring ── */
:focus-visible {
  outline: 2.5px solid var(--blue);
  outline-offset: 2px;
}
:focus:not(:focus-visible) { outline: none; }

/* ── Modal confirm step ── */
.modal-confirm-icon {
  width: 6.4rem;
  height: 6.4rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 1.6rem;
  background: var(--color-primary);
  color: #fff;
  font-size: 2.4rem;
  font-weight: 800;
}
.modal-confirm-icon svg { width: 3rem; height: 3rem; }
.modal-confirm-icon--whish {
  background: linear-gradient(135deg, #e91e63, #7c3aed);
}
.modal-confirm-icon--card {
  background: linear-gradient(135deg, #1A1F71, #2563eb);
}
.modal-confirm-icon--wallet {
  background: var(--color-primary);
}
.modal-confirm-label {
  font-size: 1.4rem;
  color: var(--text-muted);
  text-align: center;
  margin-bottom: 0.4rem;
}
.modal-confirm-amount {
  font-size: 4.4rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  background: linear-gradient(135deg, var(--color-primary), var(--color-purple));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  text-align: center;
  margin-bottom: 0.2rem;
  line-height: 1.05;
}
.modal-confirm-to {
  font-size: 1.4rem;
  color: var(--color-text-muted);
  text-align: center;
  margin-bottom: 1.8rem;
}
.modal-confirm-to strong { color: var(--color-text); }

/* Fee breakdown table */
.modal-confirm-breakdown {
  list-style: none;
  margin: 0 0 1.6rem;
  padding: 1.2rem 1.4rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--r);
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.modal-confirm-breakdown li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  font-size: 1.3rem;
  color: var(--color-text-muted);
}
.modal-confirm-breakdown li strong {
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
  font-weight: 700;
}
.modal-confirm-breakdown li small {
  color: var(--color-text-light);
  font-size: 1.1rem;
  margin-left: 0.3rem;
}
.modal-confirm-total {
  padding-top: 0.9rem;
  border-top: 1px dashed var(--color-border);
  margin-top: 0.3rem;
}
.modal-confirm-total span { color: var(--color-text); font-weight: 600; }
.modal-confirm-total strong {
  color: var(--color-primary) !important;
  font-size: 1.6rem;
}

/* Method chip (replaces the old plain "Paying with X" line) */
.modal-confirm-method-chip {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.8rem 1.2rem;
  margin: 0 auto 1.4rem;
  width: fit-content;
  max-width: 100%;
  border-radius: var(--r-full);
  background: var(--color-primary-light);
  color: var(--color-primary);
  font-size: 1.25rem;
  font-weight: 600;
}
.modal-confirm-method-icon {
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
  font-weight: 800;
  flex-shrink: 0;
}
.modal-confirm-method-icon svg { width: 1.4rem; height: 1.4rem; }
.modal-confirm-method-icon--whish { background: linear-gradient(135deg, #e91e63, #7c3aed); }
.modal-confirm-method-icon--card  { background: linear-gradient(135deg, #1A1F71, #2563eb); }

.modal-confirm-note {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-size: 1.15rem;
  color: var(--color-text-muted);
  text-align: center;
  padding: 0.8rem 1rem;
  background: var(--color-bg);
  border-radius: var(--r-sm);
  margin-bottom: 1.6rem;
  line-height: 1.45;
}
.modal-confirm-note svg { width: 1.4rem; height: 1.4rem; flex-shrink: 0; }

/* Removed: .campaign-card-body > p.expanded + .read-more-btn — orphans
   from the legacy campaign card. .camp-card has no read-more affordance. */

/* ── Empty state CTA button ── */
.empty-state .btn {
  margin-top: 1.6rem;
}

/* ════════════════════════════════════════════════════════════
   Dashboard redesign — Sawa blue palette
   Header (greeting + search + bell + CTA) → 3 stat tiles
   → 2-col (Recent Donations | Urgent Campaigns)
   ════════════════════════════════════════════════════════════ */

/* Header row */
.dash-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.6rem;
  padding: 0.4rem 0 2rem;
  border-bottom: 1px solid #e5e7eb;
  margin-bottom: 2.4rem;
}
.dash-greeting h1 {
  font-size: 2.6rem;
  font-weight: 800;
  color: #0f172a;
  margin: 0 0 0.4rem;
  letter-spacing: -0.01em;
}
.dash-greeting p {
  font-size: 1.4rem;
  color: #64748b;
  margin: 0;
}
.dash-header-actions {
  display: flex;
  align-items: center;
  gap: 1.2rem;
}
.dash-search {
  position: relative;
  display: flex;
  align-items: center;
  width: 32rem;
  max-width: 100%;
}
.dash-search svg {
  position: absolute;
  left: 1.4rem;
  width: 1.8rem;
  height: 1.8rem;
  color: #94a3b8;
  pointer-events: none;
}
.dash-search input {
  width: 100%;
  height: 4.4rem;
  border: 1.5px solid #e2e8f0;
  background: #f8fafc;
  border-radius: 9999px;
  padding: 0 1.6rem 0 4.2rem;
  font-family: inherit;
  font-size: 1.4rem;
  color: #0f172a;
  outline: none;
  transition: border-color 0.18s, background 0.18s, box-shadow 0.18s;
}
.dash-search input::placeholder { color: #94a3b8; }
.dash-search input:focus {
  border-color: var(--color-primary);
  background: #fff;
  box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.12);
}
.dash-bell-wrap { position: relative; }
.dash-bell {
  position: relative;
  width: 4.4rem;
  height: 4.4rem;
  border-radius: 50%;
  border: 1.5px solid #e2e8f0;
  background: #fff;
  color: #475569;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.18s, border-color 0.18s, color 0.18s;
}
.dash-bell-wrap.open .dash-bell { background: var(--color-primary-light); border-color: var(--color-primary); color: var(--color-primary); }

/* "View all notifications" is a <button> now, not a link — these keep it
   looking the way it did as an <a>. Deliberately outside the media query
   below, since it applies at every width. */
.dash-notif-foot {
  width: 100%;
  background: none;
  border: 0;
  font: inherit;
  cursor: pointer;
}

/* Notifications dropdown panel */
.dash-notif-panel {
  position: absolute;
  top: calc(100% + 0.8rem);
  right: 0;
  width: 36rem;
  max-width: calc(100vw - 2rem);
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 1.4rem;
  box-shadow: 0 24px 48px rgba(15, 23, 42, 0.14);
  z-index: 100;
  opacity: 0;
  transform: translateY(-6px) scale(0.98);
  pointer-events: none;
  transition: opacity 0.18s, transform 0.18s;
  overflow: hidden;
}
.dash-bell-wrap.open .dash-notif-panel {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

/* Between phone and desktop the bell does not sit at the far right of the
   header, so anchoring the panel's right edge to it pushed a 36rem card off
   the left of the screen (measured at 697px: left -52). Anchoring the left
   edge instead keeps it on screen, and max-width caps it if the card would
   otherwise run past the right. */
@media (max-width: 900px) {
  .dash-notif-panel {
    right: auto;
    left: 0;
    max-width: calc(100vw - 3.2rem);
  }
}

/* Phones only: the panel becomes a full-width sheet under the header, because
   a 36rem card cannot sit sensibly on a 360px screen.
   This used to cut in at 768px, which meant every tablet and small laptop
   window got the sheet instead of a dropdown — the bell stopped looking like a
   dropdown at all anywhere under 768px wide. Above this the card applies, and
   "View all notifications" opens the full-page section for the long list. */
@media (max-width: 520px) {
  .dash-notif-panel {
    position: fixed;
    /* Top-anchored (just under the 6.4rem top header).
       Bottom clears the 8rem-tall bottom-bar. */
    top: 6.4rem;
    bottom: 8rem;
    left: 0;
    right: 0;
    width: auto;
    max-width: none;
    max-height: none;
    margin: 0;
    border-radius: 0;
    border-left: none;
    border-right: none;
    transform: translateY(-1.2rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    box-shadow: 0 12px 32px rgba(15, 23, 42, 0.18);
  }
  .dash-bell-wrap.open .dash-notif-panel {
    transform: translateY(0);
  }
  .dash-notif-head {
    position: sticky;
    top: 0;
    background: var(--color-surface);
    z-index: 1;
  }
  .dash-notif-foot {
    position: sticky;
    bottom: 0;
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
  }
  /* Backdrop dim behind the sheet. */
  .dash-bell-wrap.open::before {
    content: '';
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.45);
    z-index: 99;
  }
}
.dash-notif-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.2rem 1.6rem;
  border-bottom: 1px solid #f1f5f9;
}
.dash-notif-head strong { font-size: 1.45rem; color: #0f172a; }
.dash-notif-mark {
  font-size: 1.2rem;
  color: var(--color-primary);
  text-decoration: none;
  font-weight: 600;
  cursor: pointer;
}
.dash-notif-mark:hover { text-decoration: underline; }

.dash-notif-list {
  list-style: none;
  padding: 0;
  margin: 0;
  max-height: 36rem;
  overflow-y: auto;
}
/* The row is now a plain <li> wrapper; the flex layout and the hit area moved
   onto .dash-notif-hit, which is the <a> or <button> inside it. Rows used to be
   inert <li>s that merely looked clickable — cursor:pointer with nothing bound
   to them. */
.dash-notif-row {
  border-bottom: 1px solid #f1f5f9;
  position: relative;
}
.dash-notif-hit {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  width: 100%;
  padding: 1.2rem 1.6rem;
  background: none;
  border: 0;
  text-align: left;
  font: inherit;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s;
}
.dash-notif-hit:hover { background: #f8fafc; }
.dash-notif-hit:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: -2px;
}
.dash-notif-chevron {
  width: 1.6rem;
  height: 1.6rem;
  margin-left: auto;
  flex-shrink: 0;
  align-self: center;
  color: var(--color-text-light);
}
html[data-theme="dark"] .dash-notif-hit:hover { background: rgba(148, 163, 184, 0.08); }
.dash-notif-row:last-child { border-bottom: none; }
.dash-notif-row.unread::before {
  content: '';
  position: absolute;
  left: 0.6rem;
  top: 50%;
  width: 0.6rem;
  height: 0.6rem;
  background: var(--color-primary);
  border-radius: 50%;
  transform: translateY(-50%);
}
.dash-notif-icon {
  width: 3.4rem;
  height: 3.4rem;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.dash-notif-icon svg { width: 1.6rem; height: 1.6rem; }
.dash-notif-icon.icon-heart { background: rgba(239, 68, 68, 0.10); color: #ef4444; }
.dash-notif-icon.icon-check { background: rgba(22, 163, 74, 0.10); color: #16a34a; }
.dash-notif-icon.icon-bell  { background: rgba(245, 158, 11, 0.12); color: #f59e0b; }
.dash-notif-icon.icon-users { background: rgba(37, 99, 235, 0.10); color: var(--color-primary); }
.dash-notif-text { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.dash-notif-text strong { font-size: 1.3rem; color: #0f172a; }
.dash-notif-text small { font-size: 1.15rem; color: #64748b; }

.dash-notif-foot {
  display: block;
  padding: 1rem;
  text-align: center;
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--color-primary);
  text-decoration: none;
  background: #f8fafc;
  border-top: 1px solid #f1f5f9;
}
.dash-notif-foot:hover { background: #eff6ff; }
.dash-bell svg { width: 1.8rem; height: 1.8rem; }
.dash-bell:hover { background: #f8fafc; color: var(--color-primary); border-color: #cbd5e1; }
.dash-bell-dot {
  position: absolute;
  top: 0.8rem;
  right: 1rem;
  width: 0.9rem;
  height: 0.9rem;
  border-radius: 50%;
  background: #ef4444;
  border: 2px solid #fff;
}
.dash-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.8rem;
  height: 4.4rem;
  padding: 0 2rem;
  background: var(--color-primary);
  color: #fff;
  border: none;
  border-radius: 9999px;
  font-family: inherit;
  font-size: 1.4rem;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(37, 99, 235, 0.28);
  transition: background 0.18s, transform 0.15s, box-shadow 0.18s;
}
.dash-cta svg { width: 1.6rem; height: 1.6rem; }
.dash-cta:hover {
  background: var(--color-primary-dark);
  transform: translateY(-1px);
  box-shadow: 0 10px 24px rgba(37, 99, 235, 0.36);
}

/* 3 stat tiles */
.dash-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.8rem;
  margin-bottom: 2.4rem;
}
.stat-tile {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 1.6rem;
  padding: 2rem 2.2rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
  transition: box-shadow 0.18s, transform 0.18s;
}
.stat-tile:hover {
  box-shadow: 0 12px 28px rgba(15, 23, 42, 0.08);
  transform: translateY(-2px);
}
.stat-tile-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.stat-tile-label {
  font-size: 1.4rem;
  color: #64748b;
  font-weight: 500;
}
.stat-tile-icon {
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.stat-tile-icon svg { width: 1.8rem; height: 1.8rem; }
.stat-icon-trend { background: rgba(22, 163, 74, 0.10); color: #16a34a; }
.stat-icon-users { background: rgba(37, 99, 235, 0.10); color: var(--color-primary); }
.stat-icon-cal   { background: rgba(245, 158, 11, 0.12); color: #f59e0b; }

.stat-tile-value {
  font-size: 3rem;
  font-weight: 800;
  color: #0f172a;
  letter-spacing: -0.02em;
  line-height: 1.1;
}
.stat-tile-delta {
  font-size: 1.25rem;
  font-weight: 500;
}
.delta-up { color: #16a34a; }
.delta-down { color: #ef4444; }

/* Two-column lower */
.dash-lower {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.8rem;
}
/* Guests only see the Urgent Campaigns card here (everything else is auth-only),
   so the 2-col grid leaves a giant empty right column. Force 1 column for guests
   so the urgent card spans the full width. Auth view stays 2-col. */
body.is-guest .dash-lower {
  grid-template-columns: 1fr;
}
.dash-card {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 1.6rem;
  padding: 2.2rem;
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}
.dash-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.dash-card-head h3 {
  font-size: 1.8rem;
  font-weight: 700;
  color: #0f172a;
  margin: 0;
}
.dash-card-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--color-primary);
  text-decoration: none;
  cursor: pointer;
}
.dash-card-link svg { width: 1.4rem; height: 1.4rem; }
.dash-card-link:hover { color: var(--color-primary-dark); }

/* Recent donations list */
.recent-donations {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
}
.recent-donation {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 1.2rem;
  padding: 1.2rem 1.4rem;
  background: #f8fafc;
  border-radius: 1.2rem;
  transition: background 0.15s;
}
.recent-donation:hover { background: #f1f5f9; }
.rd-icon {
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 50%;
  background: rgba(37, 99, 235, 0.10);
  color: var(--color-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.rd-icon svg { width: 1.6rem; height: 1.6rem; }
.rd-meta { display: flex; flex-direction: column; min-width: 0; }
.rd-meta strong { font-size: 1.4rem; font-weight: 600; color: #0f172a; }
.rd-meta small { font-size: 1.2rem; color: #64748b; }
.rd-right { display: flex; flex-direction: column; align-items: flex-end; }
.rd-amount { font-size: 1.5rem; font-weight: 700; color: #0f172a; }
.rd-time { font-size: 1.15rem; color: #94a3b8; }
.rd-status {
  font-size: 1.15rem;
  font-weight: 600;
  padding: 0.4rem 0.9rem;
  border-radius: 9999px;
  white-space: nowrap;
}
.status-delivered { background: rgba(22, 163, 74, 0.12); color: #15803d; }
.status-transit   { background: rgba(245, 158, 11, 0.14); color: #b45309; }

/* Urgent campaigns list */
.urgent-list { display: flex; flex-direction: column; gap: 1.4rem; }
.urgent-item {
  background: #f8fafc;
  border: 1px solid #e5e7eb;
  border-radius: 1.4rem;
  padding: 1.6rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.urgent-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}
.urgent-meta { display: flex; flex-direction: column; gap: 0.2rem; }
.urgent-meta strong { font-size: 1.5rem; font-weight: 700; color: #0f172a; }
.urgent-meta small { font-size: 1.2rem; color: #64748b; }
.urgent-priority {
  /* 1.1rem rendered at 11px, under the 12px minimum for body text on phones. */
  font-size: 1.2rem;
  font-weight: 700;
  padding: 0.4rem 0.9rem;
  border-radius: 9999px;
  white-space: nowrap;
}
.priority-high   { background: rgba(239, 68, 68, 0.12); color: #b91c1c; }
.priority-medium { background: rgba(245, 158, 11, 0.14); color: #b45309; }
.urgent-progress-row {
  display: flex;
  justify-content: space-between;
  font-size: 1.3rem;
  color: #475569;
}
.urgent-progress-row strong { color: #0f172a; font-weight: 700; }
/* <small> applies its own 0.8333 factor, which took the goal amount down to
   10.42px against a 1.25rem parent — the least legible text on the mobile
   dashboard. Pin it to 12px rather than letting it inherit-and-shrink. */
.urgent-progress-row small { font-size: 1.2rem; }
.urgent-item .progress-bar {
  width: 100%;
  height: 0.7rem;
  background: #e2e8f0;
  border-radius: 9999px;
  overflow: hidden;
}
.urgent-item .progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--color-primary), #60a5fa);
  border-radius: 9999px;
  transition: width 0.4s ease;
}
/* Sized to match .featured-camp-donate. This was previously a full-width
   4.4rem slab, so three stacked urgent items put three large blue blocks down
   the card and outweighed every other CTA on the dashboard. */
.urgent-donate {
  align-self: flex-end;
  margin-top: 0.4rem;
  border: none;
  border-radius: 9999px;
  padding: 0.6rem 1.6rem;
  background: var(--color-primary);
  color: #fff;
  font-family: inherit;
  font-size: 1.2rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, transform 0.12s, box-shadow 0.18s;
}
.urgent-donate:hover {
  background: var(--color-primary-dark);
  box-shadow: 0 8px 20px rgba(37, 99, 235, 0.28);
  transform: translateY(-1px);
}

/* Responsive */
@media (max-width: 960px) {
  .dash-lower { grid-template-columns: 1fr; }
  .dash-stats { grid-template-columns: 1fr 1fr; }
  .dash-search { width: 24rem; }
}
@media (max-width: 640px) {
  .dash-header { flex-direction: column; align-items: stretch; }
  .dash-header-actions { flex-wrap: wrap; }
  .dash-search { width: 100%; order: -1; }
  .dash-stats { grid-template-columns: 1fr; }
  .dash-greeting h1 { font-size: 2.2rem; }
  .stat-tile-value { font-size: 2.6rem; }
  .recent-donation {
    grid-template-columns: auto 1fr auto;
    gap: 0.8rem;
  }
  .recent-donation .rd-status { grid-column: 1 / -1; justify-self: start; }
}

/* ════════════════════════════════════════════════════════════
   Discover — improved campaign cards
   ════════════════════════════════════════════════════════════ */
.campaign-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(28rem, 1fr));
  gap: 2rem;
}

.camp-card {
  position: relative;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 1.8rem;
  overflow: hidden;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}
.camp-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 18px 40px rgba(15, 23, 42, 0.10);
  border-color: #cbd5e1;
}
.camp-card:focus-within {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* Media area: category-coloured gradient with a faded icon background */
.camp-card-media {
  position: relative;
  /* A more prominent cover: the image reads as roughly half the card rather
     than a thin band, while the title/progress/footer stay clearly the main
     body below it. */
  height: 17rem;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 1.4rem;
  overflow: hidden;
}
.camp-card-bg-icon {
  position: absolute;
  right: 1rem;
  top: 1rem;
  width: 4.4rem;
  height: 4.4rem;
  color: rgba(255, 255, 255, 0.55);
  pointer-events: none;
}
@media (max-width: 640px) {
  .camp-card-bg-icon { width: 3.6rem; height: 3.6rem; right: 0.8rem; top: 0.8rem; }
}

/* Per-category gradient + illustrated cover.
   The SVG carries its own gradient ground, so a card with no uploaded photo
   still reads as artwork rather than a flat colour block. The gradient stays
   underneath as the paint-in colour while the SVG loads. A real photo (set
   inline by js/userhome.js from data-image) overrides background-image and
   wins over both. */
.camp-card-media[class*="cat-"] {
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
}
.cat-medical { background: url("../images/cover-medical.svg")   center/cover no-repeat, linear-gradient(135deg, #f43f5e 0%, #e11d48 100%); }
.cat-food    { background: url("../images/cover-food.svg")      center/cover no-repeat, linear-gradient(135deg, #f59e0b 0%, #d97706 100%); }
.cat-shelter { background: url("../images/cover-shelter.svg")   center/cover no-repeat, linear-gradient(135deg, #8b5cf6 0%, #6d28d9 100%); }
.cat-edu     { background: url("../images/cover-education.svg") center/cover no-repeat, linear-gradient(135deg, #06b6d4 0%, #0891b2 100%); }
.cat-other   { background: url("../images/cover-other.svg")     center/cover no-repeat, linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%); }

/* The decorative corner icon duplicated the illustration's subject — the
   illustrated cover replaces it. */
.camp-card-media[class*="cat-"] .camp-card-bg-icon { display: none; }

/* Add data-image="path/to/photo.jpg" on .camp-card-media to swap the gradient
   illustration for a real photo. The decorative SVG stays hidden when a real
   image is set, but the category tag + urgent badge still float over it. */
.camp-card-media[data-image] {
  background-size: cover;
  background-position: center;
}
.camp-card-media[data-image]::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,0) 40%, rgba(0,0,0,0.55) 100%);
  pointer-events: none;
}
.camp-card-media[data-image] .camp-card-bg-icon { display: none; }
.camp-card-media[data-image] .camp-cat-tag,
.camp-card-media[data-image] .camp-urgent-badge,
.camp-card-media[data-image] .camp-status-badge { position: relative; z-index: 1; }

/* Category tag */
.camp-cat-tag {
  background: rgba(255, 255, 255, 0.94);
  color: #1e293b;
  font-size: 1.1rem;
  font-weight: 700;
  padding: 0.5rem 1rem;
  border-radius: 9999px;
  letter-spacing: 0.02em;
  z-index: 1;
}

/* Urgent badge */
.camp-urgent-badge {
  display: inline-flex;
  align-items: center;
  background: #fff;
  color: #b91c1c;
  font-size: 1.05rem;
  font-weight: 700;
  padding: 0.5rem 0.9rem;
  border-radius: 9999px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  z-index: 1;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}
.camp-urgent-badge::before {
  content: '';
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  background: #ef4444;
  margin-right: 0.5rem;
  animation: campUrgentPulse 1.6s infinite;
}

.camp-status-badge {
  display: inline-flex;
  align-items: center;
  margin-left: auto;
  background: rgba(255, 255, 255, 0.96);
  color: #334155;
  font-size: 1.05rem;
  font-weight: 750;
  padding: 0.5rem 0.9rem;
  border: 1px solid rgba(148, 163, 184, 0.45);
  border-radius: 9999px;
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.12);
  z-index: 1;
}
.camp-status-badge--pending { color: #92400e; background: #fffbeb; border-color: #fde68a; }
.camp-status-badge--active { color: #166534; background: #f0fdf4; border-color: #bbf7d0; }
.camp-status-badge--rejected,
.camp-status-badge--withdrawn { color: #991b1b; background: #fef2f2; border-color: #fecaca; }
@keyframes campUrgentPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.6); }
  50%      { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); }
}

/* Body */
.camp-card-content {
  padding: 1.6rem 1.8rem 1.8rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  flex: 1;
}
.camp-card-title {
  font-size: 1.7rem;
  font-weight: 700;
  color: #0f172a;
  margin: 0;
  line-height: 1.25;
}
.camp-card-desc {
  font-size: 1.3rem;
  line-height: 1.55;
  color: #64748b;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Progress */
/* Two-row meta + thin clean progress bar.
   Row 1: "$X raised" (bold) | "N%" (primary).
   Bar below is slim, rounded, animated fill on width change. */
.camp-progress-info {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: 1.25rem;
  color: var(--color-text-muted);
  margin-top: 0.6rem;
  margin-bottom: 0.4rem;
  gap: 0.8rem;
}
.camp-raised {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4rem;
  color: var(--color-text-muted);
  font-size: 1.2rem;
}
.camp-raised strong {
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--color-text);
}
.camp-pct {
  font-size: 1.4rem;
  font-weight: 800;
  color: var(--color-primary);
  font-variant-numeric: tabular-nums;
}
.camp-card .progress-bar {
  width: 100%;
  height: 0.6rem;
  background: var(--color-bg-deep);
  border-radius: 9999px;
  overflow: hidden;
  margin: 0;
}
.camp-card .progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--color-primary) 0%, #60a5fa 100%);
  border-radius: 9999px;
  transition: width 0.5s ease;
}

/* Footer: donors count + donate button */
.camp-card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 0.4rem;
}
.camp-donor-count {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.2rem;
  color: #64748b;
  font-weight: 500;
}
.camp-donor-count svg { width: 1.4rem; height: 1.4rem; }
.camp-donate {
  height: 4rem;
  padding: 0 1.8rem;
  background: var(--color-primary);
  color: #fff;
  border: none;
  border-radius: 9999px;
  font-family: inherit;
  font-size: 1.3rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.18s, transform 0.12s, box-shadow 0.18s;
}
.camp-donate:hover {
  background: var(--color-primary-dark);
  transform: translateY(-1px);
  box-shadow: 0 8px 20px rgba(37, 99, 235, 0.32);
}
.camp-donate:active { transform: translateY(0); }

@media (max-width: 480px) {
  .camp-card-title { font-size: 1.5rem; }
  .camp-card-media { height: 14rem; }
}

.discover-search-empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 3rem;
  color: #64748b;
  font-size: 1.4rem;
  background: #f8fafc;
  border-radius: 1.4rem;
  margin-top: 1rem;
}

/* ── Taker dashboard: wide campaign summary card spans full row ── */
.dash-card.dash-card-wide { grid-column: 1 / -1; }
.taker-camp-summary { display: flex; flex-direction: column; gap: 1rem; }
.taker-camp-summary h4 {
  font-size: 1.7rem;
  font-weight: 700;
  color: #0f172a;
  margin: 0;
}
.taker-camp-summary p {
  font-size: 1.35rem;
  color: #64748b;
  margin: 0;
}
.taker-camp-summary .progress-bar { height: 0.8rem; }
.taker-camp-actions {
  display: flex;
  gap: 1rem;
  margin-top: 0.6rem;
  flex-wrap: wrap;
}
.taker-camp-actions .btn {
  height: 4.4rem;
  padding: 0 2rem;
  border-radius: 9999px;
  font-size: 1.35rem;
  font-weight: 600;
}

/* Status pill in card header */
.status-pill {
  font-size: 1.15rem;
  font-weight: 700;
  padding: 0.4rem 0.9rem;
  border-radius: 9999px;
  letter-spacing: 0.02em;
}
.status-active { background: rgba(22, 163, 74, 0.12); color: #15803d; }
.status-pending { background: rgba(245, 158, 11, 0.14); color: #b45309; }

/* ── Donate modal: payment + thank-you steps ── */
.modal-sub {
  font-size: 1.3rem;
  color: #64748b;
  margin: 0.4rem 0 1.4rem;
}

/* Animated card preview */
.card-preview {
  position: relative;
  background: linear-gradient(135deg, #1e3a8a 0%, var(--color-primary) 60%, #3b82f6 100%);
  color: #fff;
  border-radius: 1.4rem;
  padding: 1.8rem;
  height: 14rem;
  margin: 0.4rem 0 1.8rem;
  box-shadow: 0 12px 30px rgba(37, 99, 235, 0.30);
  overflow: hidden;
}
.card-preview::before {
  content: '';
  position: absolute;
  top: -30%;
  right: -10%;
  width: 18rem;
  height: 18rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.10);
}
.card-preview::after {
  content: '';
  position: absolute;
  bottom: -40%;
  right: -20%;
  width: 22rem;
  height: 22rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
}
.card-preview-chip {
  width: 3.4rem;
  height: 2.6rem;
  background: linear-gradient(135deg, #fbbf24 0%, #f59e0b 100%);
  border-radius: 0.5rem;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.20);
  position: relative;
  z-index: 1;
}
.card-preview-brand {
  position: absolute;
  top: 1.8rem;
  right: 1.8rem;
  font-size: 1.8rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  font-style: italic;
  z-index: 1;
}
.card-preview-number {
  position: absolute;
  left: 1.8rem;
  right: 1.8rem;
  bottom: 4.2rem;
  font-size: 1.7rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  font-variant-numeric: tabular-nums;
  z-index: 1;
}
.card-preview-row {
  position: absolute;
  left: 1.8rem;
  right: 1.8rem;
  bottom: 1.2rem;
  display: flex;
  justify-content: space-between;
  font-size: 1.1rem;
  z-index: 1;
}
.card-preview-row span { display: flex; flex-direction: column; gap: 0.2rem; }
.card-preview-row small {
  font-size: 0.95rem;
  opacity: 0.7;
  letter-spacing: 0.08em;
}
.card-preview-row strong {
  font-size: 1.25rem;
  letter-spacing: 0.05em;
}

/* Removed: .card-row-2 (legacy class, not used in HTML). */

/* ════════════════════════════════════════════════════════════
   Payment step v2 — fields, brand chips, trust strip
   ════════════════════════════════════════════════════════════ */

/* Accepted brand chip strip (above the inputs) */
.payment-brand-strip {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0.4rem 0 1.6rem;
  padding: 0.8rem 1rem;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 0.8rem;
}
.payment-brand-strip::before {
  content: 'We accept';
  font-size: 1.05rem;
  font-weight: 600;
  color: #64748b;
  letter-spacing: 0.04em;
  margin-right: 0.4rem;
}
.pay-brand {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 2.2rem;
  padding: 0 0.6rem;
  border-radius: 0.4rem;
  background: #fff;
  border: 1px solid #e2e8f0;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: 0.06em;
}
.pay-brand-visa     { color: #1a1f71; font-style: italic; }
.pay-brand-amex     { color: #2e77bb; }
.pay-brand-discover { color: #ff6000; font-size: 0.9rem; }
.pay-brand-mc {
  gap: 0.2rem;
  padding: 0 0.5rem;
}
.mc-circle { width: 1rem; height: 1rem; border-radius: 50%; }
.mc-red    { background: #eb001b; }
.mc-yellow { background: #f79e1b; margin-left: -0.4rem; mix-blend-mode: multiply; }

/* Field wrapper */
.payment-field {
  margin-bottom: 1.2rem;
}
.payment-field label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 1.1rem !important;
  font-weight: 700 !important;
  color: #475569 !important;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-bottom: 0.5rem !important;
}

/* Tiny "?" help bubble next to CVV */
.payment-label-hint {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.4rem;
  height: 1.4rem;
  background: #e2e8f0;
  color: #64748b;
  border-radius: 50%;
  font-size: 0.95rem;
  font-weight: 700;
  cursor: help;
}

/* Input wrapper supports leading + trailing icons */
.payment-input-wrap {
  position: relative;
  display: flex;
  align-items: stretch;
}
.payment-input {
  flex: 1;
  width: 100%;
  height: 4.8rem;
  padding: 0 1.4rem;
  border: 1.5px solid #e2e8f0;
  border-radius: 0.8rem;
  font-size: 1.5rem;
  font-weight: 500;
  color: #0f172a;
  font-family: inherit;
  background: #fff;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
  -webkit-appearance: none;
  appearance: none;
}
.payment-input::placeholder {
  color: #94a3b8;
  font-weight: 400;
  letter-spacing: 0;
}
.payment-input:hover { border-color: #cbd5e1; }
.payment-input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.12);
  background: #fff;
}

/* Leading icon (left side of input) */
.payment-input-leading,
.payment-input-trailing {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  color: #94a3b8;
  pointer-events: none;
}
.payment-input-leading  { left: 1.2rem; }
.payment-input-trailing { right: 1.2rem; }
.payment-input-leading svg,
.payment-input-trailing svg { width: 1.8rem; height: 1.8rem; }
.payment-input-wrap:has(.payment-input-leading)  .payment-input { padding-left: 4rem; }
.payment-input-wrap:has(.payment-input-trailing) .payment-input { padding-right: 4rem; }

.payment-input-wrap:focus-within .payment-input-leading,
.payment-input-wrap:focus-within .payment-input-trailing {
  color: var(--color-primary);
}

/* Expiry + CVV side by side */
.payment-row-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

/* Trust strip below all fields */
.payment-trust {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 1.2rem 0 0.4rem;
  padding: 0.8rem 1.2rem;
  background: rgba(22, 163, 74, 0.08);
  border: 1px solid rgba(22, 163, 74, 0.22);
  border-radius: 0.8rem;
  font-size: 1.15rem;
  color: #15803d;
  font-weight: 600;
}
.payment-trust svg {
  width: 1.4rem;
  height: 1.4rem;
  flex-shrink: 0;
  color: #16a34a;
}

@media (max-width: 480px) {
  .payment-brand-strip { gap: 0.4rem; padding: 0.6rem 0.8rem; flex-wrap: wrap; }
  .payment-brand-strip::before { font-size: 1rem; margin-right: 0.2rem; }
  .payment-input { height: 4.6rem; font-size: 1.4rem; }
  .payment-row-2 { gap: 0.8rem; }
}

/* Review card line */
.modal-confirm-card {
  font-size: 1.25rem;
  color: #64748b;
  margin: 0.6rem 0 1rem;
  text-align: center;
}

/* ── Thank-you screen ── */
.modal-thanks {
  text-align: center;
  padding: 1rem 0.4rem;
}
.thanks-icon {
  width: 7rem;
  height: 7rem;
  border-radius: 50%;
  background: linear-gradient(135deg, #16a34a 0%, #22c55e 100%);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 1.4rem;
  box-shadow: 0 12px 30px rgba(22, 163, 74, 0.30);
  animation: thanksPop 0.4s ease;
}
.thanks-icon svg { width: 3.2rem; height: 3.2rem; }
@keyframes thanksPop {
  0% { transform: scale(0); opacity: 0; }
  60% { transform: scale(1.15); opacity: 1; }
  100% { transform: scale(1); }
}
.modal-thanks h3 {
  font-size: 2.2rem;
  font-weight: 800;
  color: #0f172a;
  margin: 0 0 0.8rem;
}
.thanks-amount-line {
  font-size: 1.4rem;
  color: #475569;
  margin: 0 0 0.6rem;
}
.thanks-amount-line strong { color: #0f172a; }
.thanks-receipt {
  font-size: 1.25rem;
  color: #64748b;
  margin: 0 0 1.8rem;
}

/* Guest sign-up CTA inside thank-you */
.thanks-guest-cta {
  background: linear-gradient(135deg, rgba(37, 99, 235, 0.06) 0%, rgba(96, 165, 250, 0.12) 100%);
  border: 1.5px dashed rgba(37, 99, 235, 0.30);
  border-radius: 1.4rem;
  padding: 1.6rem;
  margin: 0 0 1.4rem;
  text-align: center;
}
.thanks-cta-title {
  font-size: 1.4rem;
  font-weight: 700;
  color: #0f172a;
  margin: 0 0 0.4rem;
}
.thanks-cta-body {
  font-size: 1.3rem;
  color: #475569;
  margin: 0 0 1.2rem;
  line-height: 1.5;
}
.thanks-cta-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  height: 4.4rem;
  padding: 0 2rem;
  border-radius: 9999px;
  font-size: 1.4rem;
  font-weight: 700;
  text-decoration: none;
}
.thanks-cta-btn svg { width: 1.5rem; height: 1.5rem; }

/* ── Donors modal ── */
.donors-modal-content {
  max-width: 52rem;
  width: 100%;
  padding: 2.4rem;
  max-height: 88vh;
  display: flex;
  flex-direction: column;
}
.donors-modal-head {
  border-bottom: 1px solid #e5e7eb;
  padding-bottom: 1.6rem;
  margin-bottom: 1.4rem;
}
.donors-modal-head h3 {
  font-size: 2rem;
  font-weight: 800;
  color: #0f172a;
  margin: 0 0 0.4rem;
}
.donors-modal-head p {
  font-size: 1.3rem;
  color: #64748b;
  margin: 0 0 1.4rem;
}
.donors-summary {
  display: flex;
  align-items: center;
  gap: 2rem;
  padding: 1.2rem 1.6rem;
  background: linear-gradient(135deg, rgba(37, 99, 235, 0.06) 0%, rgba(96, 165, 250, 0.10) 100%);
  border-radius: 1.2rem;
}
.donors-summary-item {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.donors-summary-item strong {
  font-size: 1.8rem;
  font-weight: 800;
  color: var(--color-primary);
  letter-spacing: -0.01em;
}
.donors-summary-item small { font-size: 1.15rem; color: #64748b; }
.donors-summary-divider {
  width: 1px;
  align-self: stretch;
  background: rgba(37, 99, 235, 0.15);
}

.donors-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}
.donors-list::-webkit-scrollbar { width: 6px; }
.donors-list::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 3px; }

.donor-row {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  padding: 0.9rem 1rem;
  border-radius: 1rem;
  transition: background 0.15s;
}
.donor-row:hover { background: #f8fafc; }
.donor-avatar {
  width: 4rem;
  height: 4rem;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--color-primary) 0%, #60a5fa 100%);
  color: #fff;
  font-size: 1.3rem;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  letter-spacing: 0.02em;
}
.donor-avatar.donor-anon {
  background: #e2e8f0;
  color: #64748b;
}
.donor-meta { flex: 1; display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.donor-meta strong { font-size: 1.4rem; font-weight: 600; color: #0f172a; }
.donor-meta small { font-size: 1.15rem; color: #94a3b8; }
.donor-amount {
  font-size: 1.5rem;
  font-weight: 700;
  color: #0f172a;
}

.donors-modal-foot {
  border-top: 1px solid #e5e7eb;
  padding-top: 1.4rem;
  margin-top: 1.4rem;
  display: flex;
  justify-content: flex-end;
}
.donors-modal-foot .btn-primary {
  height: 4.4rem;
  padding: 0 2rem;
  border-radius: 9999px;
  font-size: 1.4rem;
}

@media (max-width: 480px) {
  .donors-modal-content { padding: 1.6rem; }
  .donors-summary { gap: 1.4rem; padding: 1rem; }
  .donors-summary-item strong { font-size: 1.6rem; }
  .donor-avatar { width: 3.4rem; height: 3.4rem; font-size: 1.15rem; }
}

/* ════════════════════════════════════════════════════════════
   Campaign detail modal — opened on .camp-card click
   ════════════════════════════════════════════════════════════ */
.camp-modal {
  max-width: 78rem;
  padding: 0;
  max-height: 92vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Full page from 769px up. A campaign is a page's worth of content — gallery,
   description, donors, comments — and a 78rem card floating in the middle left
   most of a desktop screen unused while the content inside it scrolled. Mobile
   already fills the screen, so this makes the two agree. */
@media (min-width: 769px) {
  .modal-overlay.camp-modal-overlay,
  #campaign-modal.modal-overlay {
    padding: 0;
  }
  .camp-modal {
    max-width: none;
    width: 100vw;
    height: 100vh;
    height: 100svh;
    max-height: none;
    border-radius: 0;
  }
}
.camp-modal .modal-close {
  z-index: 5;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(6px);
}

/* Slideshow */
.cm-slideshow {
  position: relative;
  background: var(--color-bg-deep);
  aspect-ratio: 16 / 9;
  /* Never let the image dominate the modal. On a wide full-screen modal the
     16/9 ratio made the slideshow taller than the viewport (e.g. 873px on a
     1552px-wide screen), which pushed the whole .cm-body below the fold and,
     because .camp-modal is overflow:hidden, left it unreachable — the image
     filled the screen and nothing scrolled. Capping the height guarantees the
     content and its scroll area are always visible, at every viewport. */
  max-height: 42vh;
  flex-shrink: 0;
  overflow: hidden;
}
.cm-slides {
  position: absolute;
  inset: 0;
}
.cm-slide {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: 0;
  transition: opacity 0.35s ease;
}
.cm-slide.is-active { opacity: 1; }
.cm-slide-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--color-primary-light), var(--color-bg));
  color: var(--color-primary);
  opacity: 1;
}
.cm-slide-placeholder svg { width: 8rem; height: 8rem; opacity: 0.4; }

.cm-slide-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 50%;
  border: 0;
  background: rgba(255, 255, 255, 0.92);
  color: var(--color-text);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
  transition: background 0.18s, transform 0.18s;
}
.cm-slide-nav svg { width: 1.8rem; height: 1.8rem; }
.cm-slide-nav:hover { background: #fff; transform: translateY(-50%) scale(1.05); }
.cm-slide-prev { left: 1.2rem; }
.cm-slide-next { right: 1.2rem; }

.cm-dots {
  position: absolute;
  bottom: 1.2rem;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 0.6rem;
  z-index: 2;
}
.cm-dot {
  width: 0.8rem;
  height: 0.8rem;
  border-radius: 50%;
  border: 0;
  background: rgba(255, 255, 255, 0.6);
  cursor: pointer;
  padding: 0;
  transition: background 0.18s, transform 0.18s;
}
.cm-dot.is-active {
  background: #fff;
  transform: scale(1.3);
}

.cm-badge {
  position: absolute;
  z-index: 2;
  padding: 0.4rem 0.9rem;
  border-radius: var(--r-full);
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  backdrop-filter: blur(6px);
}
.cm-urgent {
  top: 1.2rem;
  left: 1.2rem;
  background: rgba(239, 68, 68, 0.92);
  color: #fff;
}
.cm-category {
  top: 1.2rem;
  right: 5.6rem;
  background: rgba(255, 255, 255, 0.92);
  color: var(--color-text);
}

/* Body */
.cm-body {
  padding: 2.2rem 2.4rem 1.6rem;
  overflow-y: auto;
  flex: 1;
}
.cm-title {
  margin: 0 0 1.2rem;
  font-size: 2.2rem;
  font-weight: 700;
  color: var(--color-text);
  line-height: 1.25;
}
.cm-meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1.2rem 2rem;
  margin-bottom: 1.6rem;
}
.cm-meta-item {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.3rem;
  color: var(--color-text-muted);
}
.cm-meta-item svg { width: 1.6rem; height: 1.6rem; }

.cm-creator {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1.2rem;
  margin-bottom: 1.6rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--r);
  /* Let the Message/Report actions drop below the name when the modal is too
     narrow to hold both on one line, instead of spilling past the card border
     (the actions are flex-shrink:0, so without this they overflow on small
     screens). */
  flex-wrap: wrap;
}
/* Clickable creator chip — wraps avatar + name. Hover lifts subtly,
   tap opens the creator profile (handled by JS).
   Replaces older .cm-creator-profile-btn. */
.cm-creator-link {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 1rem;
  border: 0;
  padding: 0.4rem 0.6rem;
  margin: -0.4rem -0.6rem;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  border-radius: 0.8rem;
  transition: background 0.15s ease;
}
.cm-creator-link:hover,
.cm-creator-link:focus-visible {
  background: var(--color-bg-deep);
  outline: none;
}
.cm-creator-avatar {
  width: 4rem;
  height: 4rem;
  border-radius: 50%;
  background: var(--color-primary-light);
  color: var(--color-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 1.4rem;
  flex-shrink: 0;
}
.cm-creator-meta {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  flex: 1;
  min-width: 0;
}
.cm-creator-meta small {
  font-size: 1.1rem;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.cm-creator-meta strong {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.4rem;
  color: var(--color-text);
}

/* X-style creator actions row — sits to the right of the creator chip.
   Holds Message + Report buttons as small icon-pill pairs.
   Replaces older .cm-message-btn block. */
.cm-creator-actions {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  flex-shrink: 0;
  margin-left: auto;   /* keep it pinned right when it shares the row */
}
/* Once the row wraps, the actions take a full line under the name so they never
   sit past the card edge. */
@media (max-width: 520px) {
  .cm-creator-actions { width: 100%; justify-content: flex-start; margin-left: 0; }
}
.cm-creator-meta strong { overflow-wrap: anywhere; }
.cm-action-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1.2rem;
  border-radius: var(--r-full);
  background: var(--color-primary-light);
  color: var(--color-primary);
  font-family: inherit;
  font-size: 1.25rem;
  font-weight: 700;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, transform 0.15s ease;
}
.cm-action-btn:hover,
.cm-action-btn:focus-visible {
  background: var(--color-primary);
  color: #fff;
  transform: translateY(-1px);
  outline: none;
}
.cm-action-btn svg { width: 1.4rem; height: 1.4rem; }

/* Danger flavor (Report) — neutral until hover, then red. */
.cm-action-btn-danger {
  background: var(--color-bg-deep);
  color: var(--color-text-muted);
}
.cm-action-btn-danger:hover,
.cm-action-btn-danger:focus-visible {
  background: var(--color-danger);
  color: #fff;
}

@media (max-width: 520px) {
  /* Collapse to icon-only pills on phone so the row fits. */
  .cm-action-btn span { display: none; }
  .cm-action-btn {
    padding: 0;
    width: 3.6rem;
    height: 3.6rem;
    justify-content: center;
  }
}
.cm-verified {
  position: relative;
  display: inline-block;
  width: 1.6rem;
  height: 1.6rem;
  color: var(--color-primary);
}
.cm-verified > svg:first-child {
  position: absolute;
  inset: 0;
}
.cm-verified-tick {
  position: absolute;
  inset: 0;
  width: 0.95rem;
  height: 0.95rem;
  top: 0.32rem;
  left: 0.32rem;
}

.cm-progress { margin-bottom: 1.8rem; }
.cm-progress-figures {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  align-items: baseline;
  font-size: 1.3rem;
  color: var(--color-text-muted);
  margin-bottom: 0.6rem;
}
.cm-progress-figures strong { color: var(--color-text); font-weight: 700; }
.cm-progress-pct {
  margin-left: auto;
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--color-primary);
}

/* Tabs */
.cm-tabs {
  display: flex;
  gap: 0.4rem;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: 1.4rem;
}
.cm-tab {
  background: none;
  border: 0;
  padding: 0.9rem 1.4rem;
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--color-text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 0.18s, border-color 0.18s;
}
.cm-tab:hover { color: var(--color-text); }
.cm-tab.is-active {
  color: var(--color-primary);
  border-bottom-color: var(--color-primary);
}
.cm-tab-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2rem;
  padding: 0 0.5rem;
  height: 1.8rem;
  margin-left: 0.4rem;
  border-radius: var(--r-full);
  background: var(--color-primary-light);
  color: var(--color-primary);
  font-size: 1.1rem;
  font-weight: 700;
}
.cm-tab.is-active .cm-tab-badge {
  background: var(--color-primary);
  color: #fff;
}
.cm-panel { animation: cmPanelIn 0.2s ease; }
@keyframes cmPanelIn { from { opacity: 0; } to { opacity: 1; } }
/* The comments panel sets display:flex, which overrode the [hidden] attribute's
   default display:none — so the comment box leaked into the About tab. A hidden
   panel must stay hidden whatever its own display rule says. */
.cm-panel[hidden] { display: none !important; }
.cm-desc {
  font-size: 1.4rem;
  line-height: 1.65;
  color: var(--color-text-muted);
  white-space: pre-wrap;
}
.cm-panel .donors-list { padding: 0; }

/* ── Comments tab (Twitter/X-style thread) ── */
.cm-comments-panel {
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
}
.cm-comment-form {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  padding: 1.2rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--r);
}
.cm-comment-form-row {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
}
.cm-comment-form-avatar {
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 50%;
  border: 1px solid var(--color-border);
  object-fit: cover;
  flex-shrink: 0;
  background: var(--color-surface);
}
.cm-comment-form textarea {
  flex: 1;
  min-height: 5rem;
  padding: 0.8rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: 0.8rem;
  background: var(--color-surface);
  color: var(--color-text);
  font-family: inherit;
  font-size: 1.35rem;
  line-height: 1.5;
  resize: vertical;
  transition: border-color 0.18s, box-shadow 0.18s;
}
.cm-comment-form textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.cm-comment-form-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding-left: 4.6rem;
}
.cm-comment-counter {
  font-size: 1.15rem;
  color: var(--color-text-light);
  font-variant-numeric: tabular-nums;
}
.cm-comment-submit {
  padding: 0.7rem 1.8rem;
  font-size: 1.3rem;
}

.cm-comment-guest-cta {
  padding: 1.6rem;
  background: var(--color-primary-light);
  border: 1px solid rgba(37, 99, 235, 0.2);
  border-radius: var(--r);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.8rem;
}
.cm-comment-guest-cta p {
  margin: 0;
  font-size: 1.35rem;
  color: var(--color-text);
}

/* Comment list (PHP renders <li class="cm-comment">) */
.cm-comments-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
}
.cm-comments-list .activity-empty {
  text-align: center;
  padding: 2rem 1rem;
  color: var(--color-text-muted);
  font-size: 1.3rem;
  list-style: none;
}
.cm-comment {
  display: flex;
  gap: 1rem;
  padding: 1.2rem 0;
  border-bottom: 1px solid var(--color-border);
}
.cm-comment:last-child { border-bottom: 0; }
.cm-comment-avatar {
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 50%;
  background: var(--color-primary-light);
  color: var(--color-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 1.25rem;
  flex-shrink: 0;
}
.cm-comment-body { flex: 1; min-width: 0; }
.cm-comment-head {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin-bottom: 0.3rem;
  flex-wrap: wrap;
}
.cm-comment-name {
  font-weight: 700;
  font-size: 1.3rem;
  color: var(--color-text);
}
.cm-comment-time {
  font-size: 1.15rem;
  color: var(--color-text-light);
}
.cm-comment-text {
  font-size: 1.35rem;
  line-height: 1.5;
  color: var(--color-text);
  word-wrap: break-word;
  white-space: pre-wrap;
}
.cm-comment-actions {
  display: flex;
  gap: 1.4rem;
  margin-top: 0.6rem;
}
.cm-comment-action {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: none;
  border: 0;
  padding: 0.3rem 0.4rem;
  border-radius: 0.6rem;
  font-size: 1.2rem;
  color: var(--color-text-light);
  cursor: pointer;
  transition: color 0.18s, background 0.18s;
}
.cm-comment-action svg { width: 1.4rem; height: 1.4rem; }
.cm-comment-action:hover {
  color: var(--color-primary);
  background: var(--color-primary-light);
}
.cm-comment-action.is-liked { color: var(--color-danger); }

@media (max-width: 520px) {
  .cm-comment-form-foot { padding-left: 0; }
}

html[data-theme="dark"] .cm-comment-form,
html[data-theme="dark"] .cm-comment-guest-cta {
  background: var(--color-bg-deep);
}
html[data-theme="dark"] .cm-comment-form textarea {
  background: var(--color-surface);
  border-color: var(--color-border);
}

/* Footer */
.cm-footer {
  display: flex;
  gap: 1rem;
  padding: 1.4rem 2.4rem;
  border-top: 1px solid var(--color-border);
  background: var(--color-surface);
  flex-shrink: 0;
}
.cm-footer .btn { flex: 1; }

/* Mobile: full-screen sheet — also remove overlay padding so the sheet fills the viewport */
@media (max-width: 720px) {
  #campaign-modal { padding: 0; }
  .camp-modal {
    max-width: 100%;
    max-height: 100vh;
    max-height: 100dvh;
    height: 100vh;
    height: 100dvh;
    border-radius: 0;
  }
  .cm-slideshow { aspect-ratio: 4 / 3; }
  .cm-body { padding: 1.8rem 1.6rem 1.2rem; }
  .cm-footer { padding: 1.2rem 1.6rem; }
  .cm-title { font-size: 1.8rem; }
  .cm-category { right: 5rem; }
}

/* Dark mode */
html[data-theme="dark"] .cm-slide-nav {
  background: rgba(15, 23, 42, 0.85);
  color: var(--color-text);
}
html[data-theme="dark"] .cm-slide-nav:hover { background: rgba(15, 23, 42, 1); }
html[data-theme="dark"] .cm-category { background: rgba(15, 23, 42, 0.85); color: var(--color-text); }
html[data-theme="dark"] .cm-creator { background: var(--color-bg-deep); }
html[data-theme="dark"] .camp-modal .modal-close { background: rgba(15, 23, 42, 0.85); color: var(--color-text); }

/* ════════════════════════════════════════════════════════════
   Guest vs auth visibility toggles
   body.is-auth  → show .auth-only, hide .guest-only
   body.is-guest → show .guest-only, hide .auth-only
   ════════════════════════════════════════════════════════════ */
body.is-auth  .guest-only { display: none !important; }
body.is-guest .auth-only  { display: none !important; }

/* Role-specific gating — only one of role-donor / role-taker / role-org is active */
body:not(.role-donor) .donor-only { display: none !important; }
body:not(.role-taker) .taker-only { display: none !important; }
body:not(.role-org)   .org-only   { display: none !important; }


/* Opt-in escape hatch: a role-only block can still appear for guests if it
   also carries .guest-show. Specificity (3 classes) beats the :not() rule (2). */
body.is-guest .donor-only.guest-show,
body.is-guest .taker-only.guest-show,
body.is-guest .org-only.guest-show { display: flex !important; }

/* Guests can't access locked sections — also hide their <section> targets */
body.is-guest #profile,
body.is-guest #wallet,
body.is-guest #activity,
body.is-guest #campaign-new,
body.is-guest #campaigns { display: none !important; }

/* Sign Up CTA in sidebar — primary style */
.sidebar-item.sidebar-cta {
  background: var(--color-primary);
  color: #fff;
  margin-top: 0.4rem;
}
.sidebar-item.sidebar-cta:hover {
  background: var(--color-primary-dark);
}
.sidebar-item.sidebar-cta svg { color: #fff; }

/* Anchor sidebar-items inherit button look */
a.sidebar-item {
  text-decoration: none;
}

/* Removed: .guest-hero v1 block (~100 lines). Superseded by .guest-hero-v2
   which is the actual hero rendered on the dashboard. No HTML references
   the v1 classes anywhere. */

/* ════════════════════════════════════════════════════════════
   Guest action band (sits between hero and the dash-lower cards
   so the area doesn't read as empty white space for non-auth users).
   3 equal cards, modern, accessible, single source of truth.
   ════════════════════════════════════════════════════════════ */
.guest-actions {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.4rem;
  margin: 2.4rem 0;
}
.guest-action-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.8rem;
  padding: 2rem 1.8rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--r-lg);
  text-align: left;
  text-decoration: none;
  font-family: inherit;
  cursor: pointer;
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.guest-action-card:hover {
  transform: translateY(-3px);
  border-color: var(--color-primary);
  box-shadow: var(--shadow);
}
.guest-action-card:focus-visible {
  outline: 3px solid var(--color-primary);
  outline-offset: 2px;
  border-color: var(--color-primary);
}
.guest-action-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 4.4rem;
  height: 4.4rem;
  border-radius: 1.2rem;
  background: color-mix(in srgb, var(--color-primary) 10%, transparent);
  color: var(--color-primary);
}
.guest-action-icon svg { width: 2.2rem; height: 2.2rem; }
.guest-action-card strong {
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--color-text);
  letter-spacing: -0.01em;
}
.guest-action-card p {
  font-size: 1.2rem;
  line-height: 1.5;
  color: var(--color-text-muted);
  margin: 0;
}
.guest-action-primary {
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dark));
  border-color: var(--color-primary-dark);
}
.guest-action-primary .guest-action-icon {
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
}
.guest-action-primary strong { color: #fff; }
.guest-action-primary p { color: rgba(255, 255, 255, 0.86); }
.guest-action-primary:hover {
  border-color: #fff;
}

@media (max-width: 900px) {
  .guest-actions { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 520px) {
  .guest-actions { grid-template-columns: 1fr; gap: 1rem; margin: 1.8rem 0; }
}

html[data-theme="dark"] .guest-action-card {
  background: rgba(15, 23, 42, 0.62);
  border-color: rgba(148, 163, 184, 0.18);
}
html[data-theme="dark"] .guest-action-card:hover {
  border-color: var(--color-primary);
}

.guest-feature-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 1.8rem;
  margin-top: 2rem;
}
@media (max-width: 900px) {
  .guest-feature-grid { grid-template-columns: 1fr; }
}

/* Featured campaigns list (compact card list) */
.featured-list {
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
}
.featured-camp {
  display: grid;
  grid-template-columns: 7.2rem 1fr;
  gap: 1.4rem;
  padding: 1.2rem;
  background: #f8fafc;
  border-radius: 1.2rem;
  transition: background 0.15s, transform 0.15s;
}
.featured-camp:hover { background: #f1f5f9; transform: translateY(-1px); }
.featured-camp-thumb {
  position: relative;
  width: 7.2rem;
  height: 7.2rem;
  border-radius: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  /* Set background-image via the .has-cover modifier (see featured-camp.php) to use a real photo. */
}
.featured-camp-thumb svg { width: 3.2rem; height: 3.2rem; opacity: 0.92; }
.featured-camp-thumb.cat-medical { background: linear-gradient(135deg, #ef4444 0%, #b91c1c 100%); }
.featured-camp-thumb.cat-food    { background: linear-gradient(135deg, #f59e0b 0%, #b45309 100%); }
.featured-camp-thumb.cat-edu     { background: linear-gradient(135deg, #7c3aed 0%, #5b21b6 100%); }
.featured-camp-thumb.cat-shelter { background: linear-gradient(135deg, #0ea5e9 0%, #0369a1 100%); }
/* Real cover photo takes over when campaigns.cover_image is set */
.featured-camp-thumb.has-cover {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  color: transparent;
}
.featured-camp-thumb .camp-urgent-badge {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  /* Was 0.95rem — 9.5px, the smallest text on the dashboard. At 12px the
     word itself measures ~49.5px against a 6rem thumb, so it fits: the
     padding and letter-spacing were what pushed the pill to 73px and made it
     hang off the tile. Tightened both rather than shrinking the text back. */
  font-size: 1.2rem;
  font-weight: 700;
  padding: 0.2rem 0.4rem;
  background: rgba(255, 255, 255, 0.95);
  color: #b91c1c;
  border-radius: 9999px;
  letter-spacing: 0;
}
.featured-camp-body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
}
.featured-camp-body strong { font-size: 1.4rem; font-weight: 700; color: #0f172a; }
.featured-camp-body small { font-size: 1.2rem; color: #64748b; line-height: 1.4; }
.featured-camp-body .progress-bar { height: 0.6rem; margin: 0.2rem 0; }
.featured-camp-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  font-size: 1.2rem;
  color: #64748b;
}
.featured-camp-meta strong { color: #0f172a; font-weight: 700; font-size: 1.3rem; }
/* Goal progress is brand blue everywhere it appears (urgent list, camp cards,
   featured list) — the bare .progress-fill default is green, which made this
   one list read as a different kind of metric. */
.featured-camp .progress-fill {
  background: linear-gradient(90deg, var(--color-primary), #60a5fa);
}

.featured-camp-donate {
  border: none;
  background: var(--color-primary);
  color: #fff;
  font-weight: 600;
  font-size: 1.2rem;
  padding: 0.6rem 1.2rem;
  border-radius: 9999px;
  cursor: pointer;
  transition: background 0.15s, transform 0.1s;
}
.featured-camp-donate:hover { background: var(--color-primary-dark); }
.featured-camp-donate:active { transform: scale(0.97); }

/* How It Works card */
.how-it-works-card { justify-content: space-between; }
.how-steps {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
}
.how-steps li {
  display: grid;
  grid-template-columns: 3.6rem 1fr;
  gap: 1.2rem;
  align-items: flex-start;
}
.how-step-num {
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 50%;
  background: var(--color-primary-light);
  color: var(--color-primary);
  font-weight: 700;
  font-size: 1.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.how-steps li > div { display: flex; flex-direction: column; gap: 0.2rem; }
.how-steps li strong { font-size: 1.35rem; font-weight: 600; color: #0f172a; }
.how-steps li small { font-size: 1.2rem; color: #64748b; line-height: 1.45; }
.how-cta-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  background: var(--color-primary);
  color: #fff;
  text-decoration: none;
  padding: 1rem 1.6rem;
  border-radius: 9999px;
  font-size: 1.3rem;
  font-weight: 600;
  margin-top: 0.4rem;
  transition: background 0.15s, transform 0.1s;
}
.how-cta-btn svg { width: 1.4rem; height: 1.4rem; }
.how-cta-btn:hover { background: var(--color-primary-dark); }
.how-cta-btn:active { transform: scale(0.98); }

/* Trust strip (testimonials) */
.trust-strip {
  margin-top: 2rem;
  padding: 2.4rem 2.2rem;
  background: linear-gradient(135deg, #f8fafc 0%, #eff6ff 100%);
  border: 1px solid #e5e7eb;
  border-radius: 1.6rem;
}
.trust-strip-head { text-align: center; margin-bottom: 2rem; }
.trust-strip-head h3 { font-size: 1.8rem; font-weight: 700; color: #0f172a; margin: 0 0 0.4rem; }
.trust-strip-head p { font-size: 1.25rem; color: #64748b; margin: 0; }
.trust-strip-head em { color: #94a3b8; font-style: italic; font-size: 1.15rem; }
.testimonials-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.4rem;
}
@media (max-width: 900px) { .testimonials-grid { grid-template-columns: 1fr; } }
.testimonial-card {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 1.2rem;
  padding: 1.6rem;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
  transition: transform 0.15s, box-shadow 0.15s;
}
.testimonial-card:hover { transform: translateY(-2px); box-shadow: 0 8px 18px rgba(15, 23, 42, 0.08); }
.testimonial-card blockquote {
  margin: 0;
  font-size: 1.3rem;
  line-height: 1.55;
  color: #1f2937;
  font-style: italic;
  quotes: "\201C" "\201D";
}
.testimonial-card blockquote::before { content: open-quote; color: var(--color-primary); font-size: 1.6rem; margin-right: 0.2rem; }
.testimonial-card blockquote::after  { content: close-quote; color: var(--color-primary); font-size: 1.6rem; margin-left: 0.2rem; }
.testimonial-card figcaption {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  border-top: 1px solid #f1f5f9;
  padding-top: 1.2rem;
}
.testimonial-avatar {
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 50%;
  background: var(--color-primary-light);
  color: var(--color-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 1.4rem;
  flex-shrink: 0;
}
.testimonial-card figcaption span:last-child { display: flex; flex-direction: column; }
.testimonial-card figcaption strong { font-size: 1.3rem; color: #0f172a; }
.testimonial-card figcaption small { font-size: 1.15rem; color: #64748b; }

/* Icon-avatar variant: used when the card is a trust-pillar (no quote/figcaption pair). */
.testimonial-avatar--icon {
  width: 4.2rem;
  height: 4.2rem;
  border-radius: 1.1rem;
}
.testimonial-avatar--icon svg { width: 2rem; height: 2rem; }
.testimonial-title {
  font-size: 1.55rem;
  font-weight: 700;
  color: #0f172a;
  line-height: 1.35;
}
.testimonial-card > p {
  margin: 0;
  font-size: 1.3rem;
  color: #4b5563;
  line-height: 1.55;
}
html[data-theme="dark"] .testimonial-title { color: #f1f5f9; }
html[data-theme="dark"] .testimonial-card > p { color: #cbd5e1; }

/* ════════════════════════════════════════════════════════════
   Discover toolbar — search + sort + chip filters (redesigned)
   ════════════════════════════════════════════════════════════ */
.discover-toolbar {
  display: flex;
  gap: 1rem;
  align-items: stretch;
  margin-bottom: 1.4rem;
  padding: 1rem;
  background: rgba(255, 255, 255, 0.86);
  border: 1px solid rgba(226, 232, 240, 0.86);
  border-radius: 1.4rem;
  box-shadow: 0 10px 28px rgba(15, 23, 42, 0.05);
}
.discover-search-bar {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  background: #fff;
  border: 1.5px solid var(--border);
  border-radius: 9999px;
  padding: 0 1.4rem;
  min-height: 4.8rem;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.discover-search-bar:focus-within {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.12);
}
.discover-search-bar svg {
  width: 1.8rem;
  height: 1.8rem;
  color: #94a3b8;
  flex-shrink: 0;
}
.discover-search-bar input {
  flex: 1;
  border: none;
  outline: none;
  background: transparent;
  font-size: 1.4rem;
  font-family: inherit;
  color: #0f172a;
  min-width: 0;
}
.discover-search-bar input::placeholder { color: #94a3b8; }
.discover-search-clear {
  border: none;
  background: #f1f5f9;
  color: #64748b;
  width: 2.8rem;
  height: 2.8rem;
  border-radius: 50%;
  font-size: 1.8rem;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, color 0.15s;
}
.discover-search-clear:hover { background: #e2e8f0; color: #334155; }

/* Sort wrapper — pill-shaped button group with leading icon, label, select.
   Matches the visual weight of the .discover-filter-trigger so the toolbar
   reads as one coherent control row. */
.discover-sort-wrap {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  background: var(--color-surface);
  border: 1.5px solid var(--color-border);
  border-radius: 9999px;
  padding: 0 0.4rem 0 1.6rem;
  min-height: 4.8rem;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
  position: relative;
}
.discover-sort-wrap::before {
  content: '';
  display: inline-block;
  width: 1.6rem;
  height: 1.6rem;
  flex-shrink: 0;
  background: currentColor;
  color: var(--color-text-muted);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 6h18M6 12h12M10 18h4'/></svg>") center / contain no-repeat;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 6h18M6 12h12M10 18h4'/></svg>") center / contain no-repeat;
}
.discover-sort-wrap:hover {
  border-color: var(--color-primary);
}
.discover-sort-wrap:focus-within {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.12);
}
.discover-sort-label {
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
#discover-sort {
  border: none;
  outline: none;
  background: transparent;
  font-family: inherit;
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--color-text);
  cursor: pointer;
  padding: 0 3rem 0 0;
  min-height: 4.4rem;
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.6rem center;
}
#discover-sort:focus { color: var(--color-primary); }

/* Category chip row */
.discover-filters { margin-bottom: 1.6rem; }
.discover-filters {
  padding: 1rem;
  background: rgba(255, 255, 255, 0.78);
  border: 1px solid rgba(226, 232, 240, 0.82);
  border-radius: 1.4rem;
  box-shadow: 0 10px 28px rgba(15, 23, 42, 0.04);
}
.discover-cat-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  align-items: center;
}
.cat-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  background: #fff;
  border: 1.5px solid var(--border);
  border-radius: 9999px;
  padding: 0.8rem 1.4rem;
  font-size: 1.3rem;
  font-weight: 600;
  color: #475569;
  cursor: pointer;
  white-space: nowrap;
  min-height: 4.4rem;
  font-family: inherit;
  transition: background 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s, transform 0.15s;
}
.cat-chip svg { width: 1.6rem; height: 1.6rem; flex-shrink: 0; }
.cat-chip:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
  background: rgba(37, 99, 235, 0.05);
  transform: translateY(-1px);
}
.cat-chip.active {
  background: linear-gradient(135deg, rgba(37, 99, 235, 0.92) 0%, rgba(59, 130, 246, 0.92) 100%);
  border-color: rgba(37, 99, 235, 0.55);
  color: #fff;
  box-shadow:
    0 8px 22px rgba(37, 99, 235, 0.32),
    inset 0 1px 0 rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(14px) saturate(180%);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
}
.cat-chip.active svg { filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.16)); }
.cat-chip-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2rem;
  height: 2rem;
  padding: 0 0.5rem;
  background: rgba(15, 23, 42, 0.06);
  color: inherit;
  border-radius: 9999px;
  font-size: 1.1rem;
  font-weight: 700;
}
.cat-chip.active .cat-chip-count { background: rgba(255, 255, 255, 0.26); color: #fff; backdrop-filter: blur(4px); }
.cat-chip-more {
  margin-left: auto;
  border-style: dashed;
}
.cat-chip-more.active {
  background: var(--blue-light);
  border-color: var(--color-primary);
  border-style: solid;
  color: var(--color-primary);
  box-shadow: none;
}
.filter-active-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2rem;
  height: 2rem;
  padding: 0 0.5rem;
  background: var(--color-primary);
  color: #fff;
  border-radius: 9999px;
  font-size: 1.1rem;
  font-weight: 700;
}

/* Advanced panel */
.discover-advanced {
  margin-top: 1.2rem;
  padding: 1.6rem;
  background: rgba(248, 250, 252, 0.86);
  border: 1px solid rgba(226, 232, 240, 0.86);
  border-radius: 1.4rem;
  display: flex;
  flex-wrap: wrap;
  gap: 1.6rem 2.4rem;
  align-items: flex-end;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.72);
}
.discover-advanced[hidden] { display: none; }
.adv-group {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  min-width: 16rem;
}
.adv-label {
  font-size: 1.1rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #64748b;
}
.adv-pills { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.adv-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: #f8fafc;
  border: 1.5px solid var(--border);
  border-radius: 9999px;
  padding: 0.7rem 1.4rem;
  font-size: 1.25rem;
  font-weight: 600;
  color: #475569;
  cursor: pointer;
  min-height: 4rem;
  font-family: inherit;
  transition: all 0.15s;
}
.adv-pill svg { width: 1.4rem; height: 1.4rem; }
.adv-pill:hover { border-color: var(--color-primary); color: var(--color-primary); background: rgba(37, 99, 235, 0.04); }
.adv-pill.active {
  background: linear-gradient(135deg, rgba(37, 99, 235, 0.92) 0%, rgba(59, 130, 246, 0.92) 100%);
  border-color: rgba(37, 99, 235, 0.55);
  color: #fff;
  box-shadow:
    0 6px 16px rgba(37, 99, 235, 0.28),
    inset 0 1px 0 rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(14px) saturate(180%);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
}
.adv-group select {
  height: 4rem;
  padding: 0 2.6rem 0 1.2rem;
  border: 1.5px solid var(--border);
  border-radius: 0.8rem;
  font-family: inherit;
  font-size: 1.35rem;
  color: #0f172a;
  background: #fff;
  appearance: none;
  cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  min-width: 18rem;
}
.adv-group select:focus { border-color: var(--color-primary); outline: none; }
.adv-reset {
  margin-left: auto;
  background: transparent;
  border: 1.5px solid var(--color-danger);
  color: var(--color-danger);
  border-radius: 9999px;
  padding: 0.7rem 1.4rem;
  font-size: 1.25rem;
  font-weight: 600;
  cursor: pointer;
  min-height: 4rem;
  font-family: inherit;
  transition: all 0.15s;
}
.adv-reset:hover { background: var(--color-danger-light); }

/* Active filter pills bar */
.discover-active-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1.2rem;
  align-items: center;
}
.discover-active-filters[hidden] { display: none; }
.active-filter-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: var(--blue-light);
  color: var(--color-primary);
  border: 1px solid rgba(37, 99, 235, 0.22);
  border-radius: 9999px;
  padding: 0.4rem 0.4rem 0.4rem 1rem;
  font-size: 1.2rem;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s;
}
.active-filter-pill span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.8rem;
  height: 1.8rem;
  border-radius: 50%;
  background: rgba(37, 99, 235, 0.18);
  font-size: 1.4rem;
  margin-left: 0.2rem;
}
.active-filter-pill:hover { background: rgba(37, 99, 235, 0.18); }
.active-filter-clearall {
  background: transparent;
  border: none;
  color: #64748b;
  font-size: 1.2rem;
  font-weight: 600;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 0.3rem;
  padding: 0.4rem 0.8rem;
  font-family: inherit;
}
.active-filter-clearall:hover { color: var(--color-primary); }

/* Result count */
.discover-result-bar {
  margin-bottom: 1rem;
  font-size: 1.25rem;
  color: #64748b;
  font-weight: 600;
}
.discover-result-count { color: #0f172a; }

/* Empty state for Discover */
.discover-empty {
  text-align: center;
  padding: 4rem 2rem;
  background: #fff;
  border: 1px dashed var(--border);
  border-radius: 1.6rem;
  margin-bottom: 1.6rem;
}
.discover-empty svg { width: 4.8rem; height: 4.8rem; color: #cbd5e1; margin-bottom: 1.2rem; }
.discover-empty h3 { font-size: 1.6rem; color: #0f172a; margin: 0 0 0.4rem; }
.discover-empty p  { font-size: 1.3rem; color: #64748b; margin: 0 0 1.6rem; }

/* ────────────────────────────────────────────────────────────────────────
   Filter UI — Bottom-sheet pattern on mobile, inline panel on desktop.
   Replaces the old horizontal-scrolling chip row (which clipped on mobile).
   Single source of truth — old @media (max-width: 768px) block deleted.
   ──────────────────────────────────────────────────────────────────────── */

/* Mobile-only trigger button (shown < 768px). Hidden on desktop. */
.discover-filter-trigger {
  display: none;
  align-items: center;
  gap: 0.5rem;
  padding: 0 1.4rem;
  min-height: 4.8rem;
  border: 1.5px solid var(--color-border);
  border-radius: 9999px;
  background: var(--color-surface);
  color: var(--color-text);
  font-family: inherit;
  font-size: 1.35rem;
  font-weight: 700;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.discover-filter-trigger:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}
.discover-filter-trigger svg { width: 1.6rem; height: 1.6rem; }
.discover-filter-trigger-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2rem;
  height: 2rem;
  padding: 0 0.55rem;
  background: var(--color-primary);
  color: #fff;
  border-radius: 9999px;
  font-size: 1.05rem;
  font-weight: 800;
}

/* Sheet head — mobile-only inside the sheet. Hidden on desktop. */
.discover-filters-sheet-head { display: none; }

/* Backdrop — only when sheet is open on mobile. */
.discover-filters-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.5);
  z-index: 250;
}
.discover-filters-backdrop.is-open { display: block; }

@media (max-width: 768px) {
  /* Toolbar stacks: search full-width on top, then Sort + Filters trigger paired. */
  .discover-toolbar {
    flex-direction: column;
    gap: 0.8rem;
    padding: 0.8rem;
  }
  .discover-search-bar { width: 100%; }
  /* Sort + Filters share one row, each takes half. */
  .discover-sort-wrap,
  .discover-filter-trigger {
    flex: 1;
  }
  .discover-sort-wrap { display: flex; }
  .discover-filter-trigger { display: inline-flex; justify-content: center; }
  /* Visually pair Sort and Filters by floating them on the same row. */
  .discover-toolbar {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "search search"
      "sort   filters";
  }
  .discover-search-bar  { grid-area: search; }
  .discover-sort-wrap   { grid-area: sort; }
  .discover-filter-trigger { grid-area: filters; }

  /* The chip + advanced container becomes a bottom-sheet. Hidden by default,
     slides up when .is-open is set by JS. Inside the sheet, chips and the
     advanced panel stack vertically — no horizontal scroll anywhere. */
  .discover-filters {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 260;
    max-height: 82vh;
    overflow-y: auto;
    margin: 0;
    padding: 0;
    border-radius: 1.6rem 1.6rem 0 0;
    background: var(--color-surface);
    box-shadow: 0 -12px 32px rgba(15, 23, 42, 0.18);
    transform: translateY(100%);
    transition: transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
    box-sizing: border-box;
  }
  .discover-filters.is-open { transform: translateY(0); }

  .discover-filters-sheet-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.4rem 1.6rem 0.8rem;
    border-bottom: 1px solid var(--color-border);
    margin-bottom: 1.2rem;
  }
  .discover-filters-sheet-head h3 {
    margin: 0;
    font-size: 1.5rem;
    font-weight: 800;
    color: var(--color-text);
  }
  .discover-filters-sheet-close {
    width: 3.4rem;
    height: 3.4rem;
    border-radius: 50%;
    border: none;
    background: var(--color-bg-deep);
    color: var(--color-text-muted);
    font-size: 2.2rem;
    line-height: 1;
    cursor: pointer;
  }
  .discover-filters-sheet-close:hover {
    background: var(--color-border);
    color: var(--color-text);
  }

  /* Chip row inside sheet: vertical wrap, full-width chips, tap-friendly. */
  .discover-cat-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.8rem;
    padding: 0 1.6rem 1.2rem;
  }
  .cat-chip {
    flex: 1 1 calc(50% - 0.4rem);
    justify-content: flex-start;
  }
  /* "More filters" inline pill is redundant inside the sheet — hide it. */
  .cat-chip-more { display: none; }

  /* Advanced panel always visible inside the sheet (no toggle needed). */
  .discover-advanced {
    margin: 0;
    padding: 1.4rem 1.6rem 1.8rem;
    border-radius: 0;
    border: none;
    border-top: 1px solid var(--color-border);
    box-shadow: none;
    background: transparent;
  }
  .discover-advanced[hidden] { display: flex; }
  .adv-group { min-width: 100%; }
  .adv-reset {
    margin-left: 0;
    width: 100%;
    min-height: 4.8rem;
    border-radius: var(--r-full);
  }

  /* Body lock when sheet is open. */
  body.filters-open { overflow: hidden; }
}

/* Hide the "0" count on chips and on the trigger to avoid the ambiguous
   "More filters 0" pattern. JS sets [hidden] when count is 0. */
.cat-chip-count[hidden],
.filter-active-count[hidden],
.discover-filter-trigger-count[hidden] { display: none; }

/* ════════════════════════════════════════════════════════════
   Redesign v2 — dark navy hero, horizontal stats
   ════════════════════════════════════════════════════════════ */

/* Hero v2 — dark navy slab with horizontal stats below the CTA */
.guest-hero-v2 {
  position: relative;
  overflow: hidden;
  background:
    linear-gradient(160deg, #0b1220 0%, #0f172a 48%, #12383a 100%);
  color: #fff;
  border-radius: 2rem;
  padding: 3.6rem 3.2rem 2.8rem;
  margin-bottom: 2.4rem;
  border: 1px solid rgba(255, 255, 255, 0.06);
  box-shadow: 0 20px 50px rgba(15, 23, 42, 0.28);
}
.guest-hero-v2-inner { position: relative; z-index: 1; max-width: 76rem; }

.guest-hero-v2-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(219, 234, 254, 0.92);
  background: rgba(37, 99, 235, 0.18);
  border: 1px solid rgba(96, 165, 250, 0.32);
  padding: 0.5rem 1.1rem;
  border-radius: 9999px;
  margin-bottom: 1.4rem;
}
.hero-eyebrow-dot {
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  background: var(--color-primary);
  box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.32);
  animation: heroEyePulse 2.6s ease-in-out infinite;
}
@keyframes heroEyePulse {
  0%, 100% { box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.18); }
  50%      { box-shadow: 0 0 0 8px rgba(37, 99, 235, 0.05); }
}

.guest-hero-v2 h1 {
  /* Fluid sizing: scales smoothly between 2.2rem (small phones) and 3.6rem
     (desktop). Replaces the fixed 3.2rem that overflowed on ~360px screens.
     text-wrap: balance produces cleaner line breaks across widths. */
  font-size: clamp(2.2rem, 1.6rem + 2.4vw, 3.6rem);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.02em;
  margin: 0 0 1rem;
  color: #fff;
  text-wrap: balance;
}
.hero-accent {
  color: #93c5fd;
  background: linear-gradient(120deg, #93c5fd, #60a5fa);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.guest-hero-v2 p {
  font-size: clamp(1.3rem, 1.15rem + 0.4vw, 1.5rem);
  line-height: 1.55;
  color: rgba(241, 245, 249, 0.85);
  margin: 0 0 2rem;
  max-width: 56rem;
  text-wrap: pretty;
}

.guest-hero-v2-cta-row {
  display: flex;
  align-items: center;
  gap: 1.4rem;
  flex-wrap: wrap;
  margin-bottom: 2.8rem;
}
.hero-primary-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  background: var(--color-primary);
  color: #fff;
  font-weight: 700;
  font-size: 1.4rem;
  padding: 1.15rem 2rem;
  border: none;
  border-radius: 9999px;
  cursor: pointer;
  font-family: inherit;
  min-height: 4.8rem;
  box-shadow: 0 10px 24px rgba(37, 99, 235, 0.32);
  transition: transform 0.15s, box-shadow 0.15s, background 0.15s;
}
.hero-primary-btn svg { width: 1.6rem; height: 1.6rem; }
.hero-primary-btn:hover { background: var(--color-primary-dark); transform: translateY(-1px); box-shadow: 0 14px 32px rgba(37, 99, 235, 0.42); }
.hero-primary-btn:active { transform: translateY(0); }
.hero-primary-btn:focus-visible {
  outline: 3px solid rgba(255, 255, 255, 0.7);
  outline-offset: 3px;
}

.hero-text-link {
  color: rgba(219, 234, 254, 0.9);
  text-decoration: none;
  font-weight: 600;
  font-size: 1.3rem;
  transition: color 0.15s;
  padding: 0.6rem 0.4rem;
  min-height: 4.4rem;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.hero-text-link svg {
  width: 1.4rem;
  height: 1.4rem;
  transition: transform 0.18s ease;
}
.hero-text-link:hover { color: #fff; }
.hero-text-link:hover svg { transform: translateX(3px); }
.hero-text-link:focus-visible {
  color: #fff;
  outline: 2px solid rgba(255, 255, 255, 0.6);
  outline-offset: 4px;
  border-radius: 0.4rem;
}

/* Horizontal stats — self-healing grid. Reflows 4 → 2 → 1 on its own based
   on available width, no per-breakpoint overrides needed. */
.hero-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.6rem;
  padding-top: 2rem;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.hero-stat {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.4rem;
  min-width: 0;
}
.hero-stat-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 1rem;
  background: rgba(37, 99, 235, 0.16);
  color: var(--color-primary);
  margin-bottom: 0.4rem;
}
.hero-stat-icon-accent {
  background: rgba(34, 197, 94, 0.18);
  color: #22c55e;
}
.hero-stat-icon svg { width: 1.8rem; height: 1.8rem; }
.hero-stat strong {
  font-size: 2.4rem;
  font-weight: 800;
  color: #fff;
  letter-spacing: -0.01em;
  line-height: 1.1;
}
.hero-stat-label {
  font-size: 1.2rem;
  color: rgba(203, 213, 225, 0.78);
  line-height: 1.4;
}

/* Mobile hero adjustments. Typography now sizes itself via clamp() above,
   so this block only tightens padding + stats spacing. The hero-stats grid
   reflows on its own via auto-fit — no manual columns needed. */
@media (max-width: 768px) {
  .guest-hero-v2 { padding: 2.6rem 2rem 2.2rem; border-radius: 1.4rem; }
  .hero-stats { gap: 1.2rem; padding-top: 1.6rem; }
  .hero-stat strong { font-size: 2rem; }
}

/* ════════════════════════════════════════════════════════════
   Guest unified header + mobile drawer
   ════════════════════════════════════════════════════════════ */

/* For guests: hide the legacy sidebar + the legacy nav-user/links
   (the new .site-header replaces them entirely).
   The .layout flex collapses cleanly because aside is removed from flow. */
body.is-guest .sidebar,
body.is-guest .mobile-overlay { display: none !important; }
body.is-guest .layout .main-content { padding-top: 2.4rem; }

/* Guest mode also needs no margin where the sidebar used to sit */
body.is-guest .layout { display: block; }
body.is-guest .main-content { max-width: 124rem; margin: 0 auto; padding: 2.4rem; }
@media (max-width: 768px) {
  body.is-guest .main-content { padding: 1.6rem 1.6rem 8rem; }
}

/* The new guest-only header */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, 0.88);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--color-border);
  box-shadow: 0 1px 0 rgba(15, 23, 42, 0.02);
  overflow-x: clip;
}
.site-header-inner {
  max-width: 128rem;
  margin: 0 auto;
  padding: 0 2.4rem;
  height: 6.8rem;
  display: flex;
  align-items: center;
  gap: 2.4rem;
  min-width: 0;
}
.site-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.9rem;
  text-decoration: none;
  flex-shrink: 0;
}
.site-brand-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Grown with its img (2.4 -> 2.9rem) so the circle keeps its padding ring.
     Still well inside the 6.4rem header, which is the real constraint here. */
  width: 4.4rem;
  height: 4.4rem;
  background: #fff;
  border: 1.5px solid rgba(37, 99, 235, 0.28);
  box-shadow: 0 2px 10px rgba(37, 99, 235, 0.18);
  border-radius: 50%;
}
.site-brand-mark img { width: 2.9rem; height: 2.9rem; }
.site-brand-name {
  font-size: 1.7rem;
  font-weight: 800;
  color: var(--color-text-navy);
  letter-spacing: -0.01em;
}

.site-header-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  flex: 1;
  min-width: 0;
}
.site-nav-link {
  background: transparent;
  border: none;
  color: var(--color-text-muted);
  font-family: inherit;
  font-size: 1.35rem;
  font-weight: 600;
  padding: 0.9rem 1.4rem;
  border-radius: 9999px;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
  min-height: 4rem;
  display: inline-flex;
  align-items: center;
}
/* Hover/active blend into the frosted nav bar — no filled pill,
   just a subtle background tint + color shift so the links feel
   like part of the nav surface, not separate buttons. */
.site-nav-link:hover {
  background: rgba(15, 23, 42, 0.04);
  color: var(--color-text-navy);
}
.site-nav-link.is-active {
  background: transparent;
  color: var(--color-text-navy);
  font-weight: 700;
  position: relative;
}
.site-nav-link.is-active::after {
  content: '';
  position: absolute;
  left: 1.4rem;
  right: 1.4rem;
  bottom: -1.7rem;
  height: 0.3rem;
  background: var(--color-primary);
  border-radius: 0.3rem 0.3rem 0 0;
}

.site-header-auth {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  flex-shrink: 0;
  min-width: 0;
}
.site-header-auth .theme-toggle {
  margin-left: 0.2rem;
}
.site-auth-link {
  color: var(--color-text);
  text-decoration: none;
  font-weight: 600;
  font-size: 1.35rem;
  padding: 0.9rem 1.4rem;
  border-radius: 9999px;
  min-height: 4.4rem;
  display: inline-flex;
  align-items: center;
  transition: background 0.15s;
}
.site-auth-link:hover { background: var(--color-bg-deep); }
.site-auth-btn {
  display: inline-flex;
  align-items: center;
  background: var(--color-text-navy);
  color: #fff;
  text-decoration: none;
  font-weight: 700;
  font-size: 1.35rem;
  padding: 0.9rem 1.8rem;
  border-radius: 9999px;
  min-height: 4.4rem;
  transition: transform 0.15s, background 0.15s, box-shadow 0.15s;
  box-shadow: 0 4px 14px rgba(15, 23, 42, 0.18);
}
.site-auth-btn:hover {
  background: var(--color-primary);
  color: #fff;
  transform: translateY(-1px);
  box-shadow: 0 8px 20px rgba(37, 99, 235, 0.28);
}

.site-header-burger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 4.4rem;
  height: 4.4rem;
  background: transparent;
  border: none;
  color: var(--color-text-navy);
  border-radius: 1rem;
  cursor: pointer;
  margin-left: auto;
  transition: background 0.15s;
  flex-shrink: 0;
}
.site-header-burger:hover { background: var(--color-bg-deep); }

/* Auth header right-side: avatar + name + role pill. Clicking it goes Home. */
.site-header-user {
  display: inline-flex;
  align-items: center;
  gap: 1rem;
  padding: 0.4rem 1.2rem 0.4rem 0.4rem;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 9999px;
  cursor: pointer;
  font-family: inherit;
  flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s, transform 0.15s;
}
.site-header-user:hover {
  background: var(--color-bg-deep);
  border-color: var(--color-border);
}
.site-header-user:active { transform: scale(0.98); }
.site-header-user img {
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid var(--color-border);
  flex-shrink: 0;
}
.site-header-user-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.15;
  gap: 0.1rem;
}
.site-header-user-text strong {
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--color-text-navy);
}
.site-header-user-role {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
/* Role text is driven by body class so PHP just sets <body class="... role-X">. */
body.role-donor .site-header-user-role::before { content: "Donor"; }
body.role-taker .site-header-user-role::before { content: "Recipient"; }
body.role-org   .site-header-user-role::before { content: "Organisation"; }

/* ── Variant: profile chip on the left, nav pinned to the right (userhome only) ── */
/* Drop the centered max-width so the chip lines up with the sidebar logo below.
   Sidebar logo circle center sits at x = 2rem (sidebar-brand padding) + 2.6rem
   (half of 5.2rem circle) = 4.6rem. Chip avatar (4rem) center sits at
   inner padding-left + 0.4rem (chip padding) + 2rem. Solve for 4.6 → 2.2rem. */
.site-header--user-lead .site-header-inner {
  max-width: none;
  padding-left: 2.2rem;
  padding-right: 2.4rem;
}
.site-header--user-lead .site-header-user {
  margin-right: auto;            /* keep nav links pushed to the right */
  padding: 0.4rem 1.4rem 0.4rem 0.4rem;
  border: 1px solid var(--color-border);
  background: rgba(255, 255, 255, 0.6);
}
.site-header--user-lead .site-header-user:hover {
  background: var(--white, #fff);
  border-color: rgba(37, 99, 235, 0.35);
  box-shadow: 0 2px 10px rgba(37, 99, 235, 0.12);
}
.site-header--user-lead .site-header-user img {
  width: 4rem;
  height: 4rem;
  border-color: rgba(37, 99, 235, 0.25);
}
.site-header--user-lead .site-header-nav {
  flex: 0 0 auto;                /* don't stretch — sit on the right */
  justify-content: flex-end;
  margin-left: auto;
}

/* Slide-out drawer (mobile guest menu) */
.guest-drawer-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.45);
  z-index: 90;
  opacity: 0;
  transition: opacity 0.25s ease;
}
.guest-drawer-backdrop.is-open { opacity: 1; }

.guest-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(86vw, 34rem);
  background: #fff;
  z-index: 100;
  display: flex;
  flex-direction: column;
  padding: 2rem 2rem 2.4rem;
  transform: translateX(100%);
  transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1);
  box-shadow: -16px 0 40px rgba(15, 23, 42, 0.18);
}
.guest-drawer.is-open { transform: translateX(0); }

.guest-drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 1.6rem;
  border-bottom: 1px solid var(--color-border);
}
.guest-drawer-close {
  width: 4.4rem;
  height: 4.4rem;
  background: var(--color-bg-deep);
  border: none;
  border-radius: 50%;
  font-size: 2.4rem;
  line-height: 1;
  color: var(--color-text-muted);
  cursor: pointer;
}
.guest-drawer-close:hover { background: var(--color-border); color: var(--color-text); }

.guest-drawer-nav {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 1.4rem;
  flex: 1;
}
.guest-drawer-link {
  display: flex;
  align-items: center;
  gap: 1rem;
  background: transparent;
  border: none;
  text-align: left;
  text-decoration: none;
  font-family: inherit;
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--color-text);
  padding: 1.2rem 1.4rem;
  border-radius: 1rem;
  cursor: pointer;
  min-height: 4.8rem;
  transition: background 0.15s, color 0.15s;
}
.guest-drawer-link svg { width: 2rem; height: 2rem; color: var(--color-text-muted); flex-shrink: 0; }
.guest-drawer-link:hover { background: var(--color-bg-deep); }
.guest-drawer-link.is-active {
  background: var(--color-primary-light);
  color: var(--color-primary-dark);
}
.guest-drawer-link.is-active svg { color: var(--color-primary); }

.guest-drawer-auth {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--color-border);
  margin-top: 1rem;
}
.guest-drawer-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  background: var(--color-primary);
  color: #fff;
  text-decoration: none;
  font-weight: 700;
  font-size: 1.4rem;
  padding: 1.2rem 1.6rem;
  border-radius: 9999px;
  min-height: 4.8rem;
  box-shadow: 0 8px 20px rgba(37, 99, 235, 0.28);
}
.guest-drawer-cta svg { width: 1.6rem; height: 1.6rem; }
.guest-drawer-cta:hover { background: var(--color-primary-dark); }
.guest-drawer-link-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-muted);
  text-decoration: none;
  font-weight: 600;
  font-size: 1.3rem;
  padding: 0.9rem;
  min-height: 4.4rem;
}
.guest-drawer-link-secondary:hover { color: var(--color-primary-dark); }

/* Mobile: collapse desktop centred nav, keep brand + auth/user compact.
   Hamburger is intentionally removed on mobile — the bottom-nav handles
   primary navigation, and the profile widget opens the account drawer. */
.site-brand-mobile { display: none; }

@media (max-width: 900px) {
  .site-header-nav { display: none; }
  .site-header-burger { display: none !important; }

  /* ...except for guests. The reasoning above holds only when signed in: the
     bottom-nav and the profile widget are both auth-only, so a guest under
     900px lost the header links AND the button that opens the drawer, leaving
     no route to About at all. The drawer itself was there the whole time —
     nothing could open it. */
  body.is-guest .site-header.guest-only .site-header-burger {
    display: inline-flex !important;
  }

  .site-header-inner { padding: 0 1.6rem; height: 5.8rem; gap: 1rem; }
  /* Keep the user-lead chip aligned with the sidebar/drawer logo (x = 2.2rem) */
  .site-header--user-lead .site-header-inner { padding-left: 2.2rem; padding-right: 1.6rem; }

  /* Auth: show brand on left, user widget on right */
  .site-header.auth-only .site-brand-mobile { display: inline-flex; }
  .site-header.auth-only .site-header-user { margin-left: auto; }

  /* User-lead variant: chip stays on the LEFT on mobile.
     4-class compound selector outranks .site-header.auth-only .site-header-user. */
  .site-header.site-header--user-lead.auth-only .site-header-user { margin-left: 0; margin-right: auto; }

  /* Guest: compact the auth pair so both fit comfortably on narrow screens */
  .site-header.guest-only .site-header-auth {
    margin-left: auto;
    gap: 0.4rem;
    min-width: 0;
  }
  .site-header.guest-only .site-auth-link {
    padding: 0.6rem 1rem;
    font-size: 1.25rem;
    min-height: 4rem;
  }
  .site-header.guest-only .site-auth-btn {
    padding: 0.7rem 1.3rem;
    font-size: 1.25rem;
    min-height: 4rem;
    box-shadow: 0 2px 8px rgba(15, 23, 42, 0.16);
    white-space: nowrap;
  }
  .site-header.guest-only .site-brand-name { font-size: 1.55rem; }
  .site-header.guest-only .site-brand-mark { width: 4rem; height: 4rem; }

  /* Mobile: drop the "Account" label in the sidebar (the top-nav user widget already shows identity) */
  body.is-auth .sidebar-section-label.auth-only { display: none; }
  body.is-auth .sidebar-auth-section { border-top: none; padding-top: 0.4rem; }
}
@media (max-width: 480px) {
  /* Very narrow: keep avatar but drop the name/role text to save room */
  .site-header.auth-only .site-header-user-text { display: none; }
  .site-header.auth-only .site-header-user { padding: 0.4rem; }
  /* On very small screens, drop the "Log In" text — the Sign Up Free pill is enough */
  .site-header.guest-only .site-auth-link { display: none; }
  .site-header.guest-only .site-brand-name { display: none; }
  .site-header-inner { padding: 0 1.2rem; gap: 0.8rem; }
  .site-header .theme-toggle {
    width: 3.8rem;
    height: 3.8rem;
  }
  .site-header.guest-only .site-auth-btn {
    max-width: 10.4rem;
    padding: 0.7rem 1rem;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* ════════════════════════════════════════════════════════════
   Sticky search/filter bar for guest mode (Discover section)
   ════════════════════════════════════════════════════════════ */
body.is-guest #discover .discover-toolbar {
  position: sticky;
  top: 6.8rem;
  z-index: 30;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  padding: 1rem 0;
  margin: -1rem 0 1.4rem;
  border-bottom: 1px solid var(--color-border);
}
/* Desktop only. Under 768px .discover-filters is not a chip row at all — it is
   the filter bottom-sheet, held off screen with transform: translateY(100%)
   until the Filters button opens it. This selector carries an id and outranks
   that, so on a phone or tablet the guest got the entire sheet — heading,
   category list, urgency, location, Reset all — pinned open across the top of
   Discover, sliding over the campaign cards as they scrolled past and burying
   the Urgent badge and category tag on every one. */
@media (min-width: 769px) {
  body.is-guest #discover .discover-filters {
    position: sticky;
    top: calc(6.8rem + 6.4rem);
    z-index: 29;
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    padding-top: 0.6rem;
    margin-top: -0.4rem;
  }
}

@media (max-width: 768px) {
  body.is-guest #discover .discover-toolbar { top: 5.6rem; padding: 0.8rem 0; }
}

/* ════════════════════════════════════════════════════════════
   Campaign card v2 — location, creator, time, prominent progress
   ════════════════════════════════════════════════════════════ */

/* Location badge in card media area */
.camp-location-badge {
  position: absolute;
  bottom: 1rem;
  left: 1rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: rgba(15, 23, 42, 0.78);
  color: #fff;
  font-size: 1.1rem;
  font-weight: 600;
  padding: 0.5rem 0.9rem;
  border-radius: 9999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  z-index: 2;
}
.camp-location-badge svg { width: 1.2rem; height: 1.2rem; }

/* Creator row — sits between title and description */
.camp-creator-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0.4rem 0 0.6rem;
}
.camp-creator-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.8rem;
  height: 2.8rem;
  border-radius: 50%;
  background: var(--color-primary-light);
  color: var(--color-primary-dark);
  font-weight: 700;
  font-size: 1.15rem;
  flex-shrink: 0;
}
.camp-creator-name {
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--color-text-muted);
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.camp-verified-badge {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.8rem;
  height: 1.8rem;
  color: var(--color-primary);
  flex-shrink: 0;
}
.camp-verified-badge > svg:first-child {
  width: 1.8rem;
  height: 1.8rem;
}
.camp-verified-tick {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 0.9rem !important;
  height: 0.9rem !important;
  color: #fff;
}

/* Days remaining pill in card footer */
.camp-days-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: var(--color-bg-deep);
  color: var(--color-text-muted);
  font-size: 1.15rem;
  font-weight: 600;
  padding: 0.4rem 0.9rem;
  border-radius: 9999px;
  white-space: nowrap;
}
.camp-days-pill svg { width: 1.2rem; height: 1.2rem; }
.camp-days-pill.is-urgent {
  background: var(--color-danger-light);
  color: var(--color-danger);
}

/* Floating progress chip removed — the inline % in .camp-progress-info is
   the single source now (cleaner, properly aligned with "$X raised"). */

/* Layout: make card footer wrap on small space, keep button right */
.camp-card-footer {
  flex-wrap: wrap;
  gap: 0.6rem;
}
.camp-card-footer .camp-days-pill { margin-right: auto; }
.camp-card-footer .camp-donor-count { font-weight: 600; }

/* ════════════════════════════════════════════════════════════
   Two-column row (activity + trust)
   ════════════════════════════════════════════════════════════ */
.dash-two-col {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: 1.8rem;
  margin-top: 2rem;
}
@media (max-width: 900px) { .dash-two-col { grid-template-columns: 1fr; } }

/* Live activity feed */
.activity-card .dash-card-head h3 {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
}
.live-dot {
  width: 0.9rem;
  height: 0.9rem;
  border-radius: 50%;
  background: #ef4444;
  box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.5);
  animation: livePulse 1.8s ease-in-out infinite;
}
@keyframes livePulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.6); }
  50%      { box-shadow: 0 0 0 8px rgba(239, 68, 68, 0); }
}
.activity-feed {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  max-height: 42rem;
  overflow-y: auto;
}
.activity-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.2rem;
  border-radius: 1rem;
  transition: background 0.15s;
}
.activity-row:hover { background: #f8fafc; }
.activity-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.4rem;
  height: 3.4rem;
  border-radius: 50%;
  background: var(--color-primary-light);
  color: var(--color-primary-dark);
  font-weight: 700;
  font-size: 1.3rem;
  flex-shrink: 0;
}
.activity-avatar-anon { background: #f1f5f9; color: #94a3b8; }
.activity-text {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  font-size: 1.3rem;
  color: #0f172a;
  line-height: 1.45;
  min-width: 0;
}
.activity-text strong { font-weight: 600; }
.activity-amount { color: var(--color-success-dark); font-weight: 700; }
.activity-meta {
  font-size: 1.15rem;
  color: #64748b;
  font-weight: 500;
}

/* Trust / Why families trust Sawa */
.trust-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
}
.trust-item {
  display: grid;
  grid-template-columns: 3.6rem 1fr;
  gap: 1rem;
  align-items: flex-start;
}
.trust-icon {
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.trust-icon svg { width: 1.8rem; height: 1.8rem; }
.trust-icon-green  { background: rgba(34, 197, 94, 0.14); color: #16a34a; }
.trust-icon-blue   { background: rgba(37, 99, 235, 0.14); color: var(--color-primary); }
.trust-icon-purple { background: rgba(124, 58, 237, 0.14); color: #7c3aed; }
.trust-icon-amber  { background: rgba(245, 158, 11, 0.14); color: #d97706; }
.trust-item strong { display: block; font-size: 1.35rem; font-weight: 700; color: #0f172a; margin-bottom: 0.2rem; }
.trust-item small  { font-size: 1.2rem; color: #64748b; line-height: 1.45; }

.trust-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  margin-top: auto;
  padding-top: 1.4rem;
  border-top: 1px solid #f1f5f9;
}
.trust-stats > div { text-align: center; }
.trust-stats strong { display: block; font-size: 1.8rem; font-weight: 800; color: var(--color-primary-dark); }
.trust-stats span   { font-size: 1.2rem; color: #64748b; }

/* ════════════════════════════════════════════════════════════
   Site footer (guest-only marketing footer)
   ════════════════════════════════════════════════════════════ */
.site-footer {
  background: #0f172a;
  color: #cbd5e1;
  margin-top: 4rem;
  padding: 4rem 2rem 2rem;
}
.site-footer-inner {
  max-width: 128rem;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr 1fr;
  gap: 3rem 2.4rem;
}
.site-footer .site-brand-name { color: #fff; }
.site-footer .site-brand-mark {
  background: rgba(37, 99, 235, 0.12);
  border-color: rgba(96, 165, 250, 0.36);
  box-shadow: none;
}
.site-footer-mission {
  font-size: 1.3rem;
  line-height: 1.55;
  color: rgba(203, 213, 225, 0.78);
  margin: 1.2rem 0 1.6rem;
  max-width: 32rem;
}
.site-footer-social {
  display: flex;
  gap: 0.8rem;
}
.site-footer-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  color: rgba(203, 213, 225, 0.78);
  transition: background 0.15s, color 0.15s, transform 0.15s;
}
.site-footer-social a:hover { background: var(--color-primary); color: #fff; transform: translateY(-2px); }
.site-footer-social svg { width: 1.6rem; height: 1.6rem; }

.site-footer-col h4 {
  font-size: 1.2rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #fff;
  margin: 0 0 1.2rem;
}
.site-footer-col a,
.site-footer-col button,
.site-footer-col .site-footer-meta {
  display: block;
  background: none;
  border: none;
  padding: 0.4rem 0;
  font-family: inherit;
  font-size: 1.25rem;
  color: rgba(203, 213, 225, 0.78);
  text-decoration: none;
  text-align: left;
  cursor: pointer;
  transition: color 0.15s;
}
.site-footer-col a:hover,
.site-footer-col button:hover { color: var(--color-primary-light); }
.site-footer-col .site-footer-meta { cursor: default; color: rgba(148, 163, 184, 0.85); }

.site-footer-bottom {
  max-width: 128rem;
  margin: 3rem auto 0;
  padding-top: 2rem;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  font-size: 1.2rem;
  color: rgba(148, 163, 184, 0.85);
}
.site-footer-bottom p { margin: 0; }
.site-footer-trust {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}
.site-footer-trust svg { width: 1.4rem; height: 1.4rem; color: var(--color-primary-light); }

@media (max-width: 900px) {
  .site-footer-inner { grid-template-columns: 1fr 1fr; }
}

/* ── Mobile accordion footer (≤600px) ──
   Each .site-footer-col becomes a tap-to-expand card. Brand col stays
   always-visible at the top. JS toggles .is-closed; CSS does the rest. */
@media (max-width: 600px) {
  .site-footer { padding: 3rem 1.6rem 1.6rem; margin-top: 3rem; }
  .site-footer-inner {
    grid-template-columns: 1fr;
    gap: 0;
  }
  .site-footer-brand {
    padding-bottom: 1.6rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    margin-bottom: 0.4rem;
  }
  .site-footer-mission { max-width: none; }

  /* Each non-brand column = collapsible row */
  .site-footer-col {
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  }
  .site-footer-col h4 {
    margin: 0;
    padding: 1.4rem 0;
    position: relative;
    cursor: pointer;
    user-select: none;
    font-size: 1.3rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .site-footer-col h4::after {
    content: '';
    width: 1rem;
    height: 1rem;
    border-right: 2px solid #fff;
    border-bottom: 2px solid #fff;
    transform: rotate(45deg);
    transition: transform 0.2s ease;
    margin-right: 0.4rem;
  }
  .site-footer-col.is-closed h4::after {
    transform: rotate(-45deg);
  }
  /* Hide all children except the title when closed */
  .site-footer-col.is-closed > :not(h4) {
    display: none;
  }
  /* Open state: indent links + a bit of breathing room */
  .site-footer-col:not(.is-closed) {
    padding-bottom: 1rem;
  }
  .site-footer-col a,
  .site-footer-col button,
  .site-footer-col .site-footer-meta {
    padding: 0.6rem 0;
    font-size: 1.3rem;
  }

  .site-footer-bottom {
    flex-direction: column;
    align-items: flex-start;
    margin-top: 1.6rem;
    text-align: left;
  }
}
@media (max-width: 600px) {
  .site-footer { padding: 3rem 1.6rem 1.6rem; }
  .site-footer-inner { grid-template-columns: 1fr; gap: 2.4rem; }
  .site-footer-bottom { justify-content: flex-start; }
}

/* ════════════════════════════════════════════════════════════
   Guest "sign in to unlock" banner
   ════════════════════════════════════════════════════════════ */
.guest-unlock {
  margin-top: 2rem;
  padding: 2.4rem;
  border-radius: 1.6rem;
  background:
    linear-gradient(135deg, #fff 0%, var(--color-surface) 45%, var(--color-primary-light) 100%);
  border: 1px solid var(--color-border);
  box-shadow: 0 4px 14px rgba(15, 23, 42, 0.04);
}
.guest-unlock-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-primary-dark);
  background: rgba(37, 99, 235, 0.1);
  padding: 0.4rem 0.9rem;
  border-radius: 9999px;
  margin-bottom: 1rem;
}
.guest-unlock-eyebrow svg { width: 1.2rem; height: 1.2rem; }
.guest-unlock h3 {
  font-size: 2rem;
  font-weight: 700;
  color: #0f172a;
  margin: 0 0 0.6rem;
  line-height: 1.25;
}
.guest-unlock p {
  font-size: 1.35rem;
  color: var(--color-text-muted);
  line-height: 1.55;
  margin: 0 0 1.6rem;
  max-width: 64rem;
}
.guest-unlock-list {
  list-style: none;
  padding: 0;
  margin: 0 0 2rem;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}
.guest-unlock-list li {
  display: flex;
  align-items: flex-start;
  gap: 0.9rem;
  padding: 1rem 1.2rem;
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid rgba(37, 99, 235, 0.14);
  border-radius: 1rem;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.guest-unlock-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: 0.8rem;
  background: var(--color-primary-light);
  color: var(--color-primary);
  flex-shrink: 0;
}
.guest-unlock-icon svg { width: 1.6rem; height: 1.6rem; }
.guest-unlock-list strong { display: block; font-size: 1.3rem; font-weight: 700; color: #0f172a; margin-bottom: 0.1rem; }
.guest-unlock-list small  { font-size: 1.2rem; color: var(--color-text-muted); line-height: 1.4; }
.guest-unlock-cta-row {
  display: flex;
  align-items: center;
  gap: 1.4rem;
  flex-wrap: wrap;
}
.guest-unlock-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  background: var(--color-primary);
  color: #fff;
  text-decoration: none;
  font-weight: 700;
  font-size: 1.4rem;
  padding: 1.1rem 2rem;
  border-radius: 9999px;
  min-height: 4.8rem;
  box-shadow: 0 10px 22px rgba(37, 99, 235, 0.3);
  transition: transform 0.15s, background 0.15s, box-shadow 0.15s;
}
.guest-unlock-cta svg { width: 1.6rem; height: 1.6rem; }
.guest-unlock-cta:hover { background: var(--color-primary-dark); transform: translateY(-1px); box-shadow: 0 14px 28px rgba(37, 99, 235, 0.4); }
.guest-unlock-link {
  color: var(--color-text-muted);
  font-size: 1.3rem;
  font-weight: 600;
  text-decoration: none;
  padding: 0.8rem 0.4rem;
  min-height: 4.4rem;
  display: inline-flex;
  align-items: center;
}
.guest-unlock-link:hover { color: var(--color-primary-dark); }

@media (max-width: 768px) {
  .guest-unlock { padding: 1.8rem; }
  .guest-unlock h3 { font-size: 1.7rem; }
  .guest-unlock-list { grid-template-columns: 1fr; }
  .guest-unlock-cta-row { flex-direction: column; align-items: stretch; }
  .guest-unlock-cta { width: 100%; }
  .guest-unlock-link { justify-content: center; }
}

/* ════════════════════════════════════════════════════════════
   Fix 4: Mobile responsive — campaign grid + Featured cards
   stack cleanly, kill any horizontal overflow / overlap
   ════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  body.is-guest .main-content,
  body.is-guest .layout,
  .guest-hero-v2,
  .guest-hero-v2-inner,
  .guest-feature-grid,
  .featured-list,
  .dash-card,
  .featured-camp,
  .featured-camp-body,
  .hero-stats,
  .guest-unlock {
    min-width: 0;
    max-width: 100%;
  }

  .guest-hero-v2 {
    padding: 2rem 1.6rem;
    margin-bottom: 1.6rem;
  }

  .guest-hero-v2-eyebrow {
    max-width: 100%;
    white-space: normal;
  }

  .guest-hero-v2 h1 {
    font-size: 2.2rem;
  }

  .guest-hero-v2-cta-row {
    flex-direction: column;
    align-items: stretch;
    gap: 1rem;
    margin-bottom: 2rem;
  }

  .hero-primary-btn,
  .hero-text-link {
    width: 100%;
    justify-content: center;
    text-align: center;
  }

  .hero-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .hero-stat strong {
    font-size: 1.8rem;
  }

  /* Discover grid: single column with proper gap to prevent overlap */
  body.is-guest #discover .campaign-grid,
  #discover .campaign-grid {
    grid-template-columns: 1fr;
    gap: 1.4rem;
  }
  /* Featured-campaigns side card: stack thumb + body, center align */
  .featured-camp {
    grid-template-columns: 6rem 1fr;
    gap: 1rem;
    padding: 1rem;
  }
  .featured-camp-thumb { width: 6rem; height: 6rem; }
  .featured-camp-thumb svg { width: 2.6rem; height: 2.6rem; }
  .featured-camp-meta {
    flex-wrap: wrap;
    align-items: stretch;
  }
  .featured-camp-donate,
  .urgent-donate {
    width: 100%;
    justify-content: center;
  }
  /* Full-width on mobile, so the right-alignment from desktop must be undone. */
  .urgent-donate { align-self: stretch; }
  /* Guest feature grid stacks */
  .guest-feature-grid { grid-template-columns: 1fr; gap: 1.4rem; }
  /* Prevent main-content from overflowing the viewport */
  body.is-guest .main-content { padding: 1.6rem; }
  /* Ensure card content is contained */
  .camp-card { width: 100%; overflow: hidden; }
  .camp-card-content { padding: 1.4rem; }
  /* Activity rows: tighter spacing */
  .activity-row { padding: 0.8rem; gap: 0.8rem; }
  .activity-avatar { width: 3rem; height: 3rem; font-size: 1.2rem; }
  .activity-text { font-size: 1.2rem; }
  /* Was 1.05rem: the mobile override made timestamps *smaller* than the
     1.15rem desktop size, landing at 10.5px on the narrowest screens. */
  .activity-meta { font-size: 1.2rem; }
}

/* ════════════════════════════════════════════════════════════
   Unified drawer layout:
   - Sidebar is a slide-in drawer opened via the profile chip
   - Bottom nav is mobile-only primary navigation
   - Main content is centered with comfortable max-width
   ════════════════════════════════════════════════════════════ */

/* The collapse toggle and its .sidebar.collapsed rail were removed entirely —
   see the note in js/userhome.js. Nothing sets .collapsed any more. */

/* Sidebar drawer definition consolidated to the top of this file — see the
   `.sidebar` rule under "--- Layout ---". It fixes two bugs reported here:
   - sidebar height shrinking on scroll (was caused by top:5.8rem + Chrome
     address bar collapse changing the effective viewport)
   - drawer content was unreachable past the fold (no overflow-y) */

.mobile-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  /* 110: above the bottom nav (z:100) and below the drawer (z:120 on mobile).
     This used to be 55, and the comment here justified it as "below sidebar
     drawer (z:60)" — true of the base .sidebar rule, but the mobile media
     query drops the drawer to z:30. So on a phone the overlay covered the very
     menu it was meant to sit behind and every item in it was unclickable.
     Sitting above the bottom nav is deliberate too: while the drawer is open a
     tap outside it should close the drawer, not press a bottom-nav button. */
  z-index: 110;
}
.mobile-overlay.show { display: block; }

/* The drawer only exists below 769px. Above that the sidebar is a permanent
   column and there is nothing to dim — but the .show class can survive a
   resize, and at z-index 110 this overlay covers the sidebar (z:60) and the
   whole page, blocking every click on desktop. */
@media (min-width: 769px) {
  .mobile-overlay,
  .mobile-overlay.show { display: none; }
}

/* ════════════════════════════════════════════════════════════════════════
   Bottom nav — single Fluent-style block (replaces all legacy bottom-nav CSS).
   Mobile-only. 5 equal items. No FAB protrusion. Labels always visible.
   ════════════════════════════════════════════════════════════════════════ */
.bottom-nav {
  display: none;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 100;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.4rem;
  padding: 0.6rem 0.8rem calc(0.6rem + env(safe-area-inset-bottom, 0px));
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(18px) saturate(180%);
  -webkit-backdrop-filter: blur(18px) saturate(180%);
  border-top: 1px solid rgba(15, 23, 42, 0.08);
  box-shadow: 0 -6px 24px rgba(15, 23, 42, 0.08);
  isolation: isolate;
}

.bottom-nav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  width: 100%;
  min-height: 5.4rem;
  padding: 0.55rem 0.4rem;
  border: none;
  background: transparent;
  border-radius: 1.1rem;
  color: var(--color-text-muted, #64748b);
  font-family: inherit;
  font-size: 1.05rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease;
}

.bottom-nav-item svg {
  width: 2.2rem;
  height: 2.2rem;
  flex-shrink: 0;
  pointer-events: none;
}

.bottom-nav-item span {
  font-size: 1.05rem;
  line-height: 1.1;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.bottom-nav-item:hover {
  background: rgba(37, 99, 235, 0.06);
  color: var(--color-primary, #2563eb);
}

.bottom-nav-item.active,
.bottom-nav-item:active {
  background: rgba(37, 99, 235, 0.12);
  color: var(--color-primary, #2563eb);
}

.bottom-nav-item.active span {
  font-weight: 700;
}

/* Center FAB (Create Campaign). Lifted blue circle, white plus, no label.
   "Notch" effect: a thick page-bg colored ring around the FAB makes the
   bar appear cut around it. Soft pulsing glow underneath draws attention. */
.bottom-nav-fab {
  position: relative;
  background: var(--color-primary);
  color: #fff;
  border-radius: 50%;
  width: 5.6rem;
  height: 5.6rem;
  min-height: 0;
  justify-self: center;
  align-self: center;
  transform: translateY(-1.6rem);
  /* The first shadow = solid ring in page-bg color → fakes the notch cutout.
     Second shadow = soft drop shadow under the FAB for depth. */
  box-shadow:
    0 0 0 0.6rem var(--color-bg),
    0 10px 24px rgba(37, 99, 235, 0.38);
  padding: 0;
  overflow: visible;
}
.bottom-nav-fab svg {
  width: 2.4rem;
  height: 2.4rem;
  position: relative;
  z-index: 1;
}
/* Pulsing ring: a pseudo-element that scales out + fades. Loops every 2s.
   Pauses on hover so the user feels in control. */
.bottom-nav-fab::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--color-primary);
  opacity: 0.55;
  z-index: 0;
  animation: fabPulse 2s ease-out infinite;
  pointer-events: none;
}
.bottom-nav-fab:hover::before,
.bottom-nav-fab:active::before {
  animation-play-state: paused;
}
@keyframes fabPulse {
  0%   { transform: scale(1);    opacity: 0.55; }
  70%  { transform: scale(1.55); opacity: 0;    }
  100% { transform: scale(1.55); opacity: 0;    }
}
@media (prefers-reduced-motion: reduce) {
  .bottom-nav-fab::before { animation: none; }
}
.bottom-nav-fab:hover,
.bottom-nav-fab.active,
.bottom-nav-fab:active {
  background: var(--color-primary-dark);
  color: #fff;
  transform: translateY(-1.4rem) scale(1.04);
  transition: transform 0.18s ease, background 0.18s ease;
}
/* Dark FAB styles consolidated into the bottom-nav dark mode block below. */

/* Hide the legacy JS-driven glass indicator — the pill replaces it. */
.bottom-nav-glass-indicator {
  display: none;
}

/* Activation: visible for auth users at every viewport.
   Mobile (≤768px): edge-to-edge bar at the bottom + top header hidden so the
   bottom bar is the single primary nav surface.
   Desktop (>768px): floating pill dock centered above the bottom edge — sits
   alongside the desktop top header as a quick-access dock (modern UI/UX). */
body.is-auth .bottom-nav {
  display: grid;
}
body.is-auth .main-content {
  padding-bottom: 12rem;
}

@media (max-width: 768px) {
  /* Mobile auth top bar: SAME visual style as desktop (chip + nav). Nav
     links hidden because the bottom bar covers Home / Campaigns / Help.
     No mobile-only brand or bell added — keeps the look consistent. */
  body.is-auth .site-header.auth-only .site-header-nav {
    display: none;
  }
  body.is-auth .site-header.auth-only .site-header-user {
    margin-right: auto;
  }
  body.is-auth .main-content {
    padding-bottom: 8.5rem;
  }
}

/* Desktop floating dock styling */
@media (min-width: 769px) {
  body.is-auth .bottom-nav {
    left: 50%;
    right: auto;
    bottom: 2rem;
    transform: translateX(-50%);
    width: min(56rem, calc(100% - 4rem));
    padding: 0.5rem 0.7rem;
    border: 1px solid rgba(15, 23, 42, 0.08);
    border-top: 1px solid rgba(15, 23, 42, 0.08);
    border-radius: 9999px;
    background: rgba(255, 255, 255, 0.78);
    backdrop-filter: blur(22px) saturate(180%);
    -webkit-backdrop-filter: blur(22px) saturate(180%);
    box-shadow:
      0 12px 36px rgba(15, 23, 42, 0.14),
      0 2px 8px rgba(15, 23, 42, 0.06),
      inset 0 1px 0 rgba(255, 255, 255, 0.6);
  }
  body.is-auth .bottom-nav .bottom-nav-item {
    min-height: 5rem;
    border-radius: 9999px;
    padding: 0.4rem 0.4rem;
  }
  body.is-auth .bottom-nav .bottom-nav-item svg {
    width: 2rem;
    height: 2rem;
  }
  body.is-auth .bottom-nav .bottom-nav-item span {
    font-size: 1rem;
  }
  /* Bottom-nav dark mode lives in the consolidated block below. */
}

/* Centered main content with breathing room on the sides */
body.is-auth .main-content {
  max-width: 124rem;
  margin: 0 auto;
  padding: 2.4rem;
  padding-bottom: 4rem;
}

@media (max-width: 640px) {
  body.is-auth .main-content { padding: 1.6rem 1.6rem 11rem; }
}

@media (max-width: 480px) {
  body.is-auth,
  body.is-auth .layout,
  body.is-auth .main-content,
  body.is-auth .section,
  body.is-auth .section-header,
  body.is-auth .card,
  body.is-auth .campaign-form {
    max-width: 100vw;
  }

  body.is-auth .section-header p {
    max-width: calc(100vw - 3.2rem);
  }
}

/* ════════════════════════════════════════════════════════════
   Dark mode polish for dashboard / guest dashboard
   ════════════════════════════════════════════════════════════ */
html[data-theme="dark"] body {
  background: linear-gradient(145deg, #071113 0%, #0f172a 52%, #0d2b2b 100%);
  color: #e5e7eb;
}

html[data-theme="dark"] .site-header,
html[data-theme="dark"] .sidebar,
html[data-theme="dark"] .guest-drawer,
html[data-theme="dark"] .modal {
  background: rgba(15, 23, 42, 0.94);
  border-color: rgba(148, 163, 184, 0.22);
  box-shadow: 0 20px 56px rgba(0, 0, 0, 0.34);
}

html[data-theme="dark"] .sidebar-brand,
html[data-theme="dark"] .sidebar-auth-section,
html[data-theme="dark"] .donors-modal-head,
html[data-theme="dark"] .donors-modal-foot {
  border-color: rgba(148, 163, 184, 0.18);
}

html[data-theme="dark"] .site-brand-mark,
html[data-theme="dark"] .sidebar-logo-circle,
html[data-theme="dark"] .guest-drawer-close,
html[data-theme="dark"] .modal-close {
  background: rgba(96, 165, 250, 0.12);
  border-color: rgba(96, 165, 250, 0.28);
  color: #bfdbfe;
}

html[data-theme="dark"] .site-brand-name,
html[data-theme="dark"] .site-nav-link,
html[data-theme="dark"] .site-header-user-text strong,
html[data-theme="dark"] .sidebar-brand span,
html[data-theme="dark"] .section-header h2,
html[data-theme="dark"] .dash-card h3,
html[data-theme="dark"] .stat-tile-value,
html[data-theme="dark"] .camp-card-title,
html[data-theme="dark"] .modal h3,
html[data-theme="dark"] .donors-modal-head h3 {
  color: #f8fafc;
}

html[data-theme="dark"] .section-header p,
html[data-theme="dark"] .dash-card p,
html[data-theme="dark"] .camp-card-desc,
html[data-theme="dark"] .camp-creator-name,
html[data-theme="dark"] .modal-sub,
html[data-theme="dark"] .modal-confirm-note,
html[data-theme="dark"] .donor-meta small,
html[data-theme="dark"] .site-footer-mission,
html[data-theme="dark"] .site-footer-meta {
  color: #cbd5e1;
}

html[data-theme="dark"] .dash-card,
html[data-theme="dark"] .stat-tile,
html[data-theme="dark"] .camp-card,
html[data-theme="dark"] .featured-camp,
html[data-theme="dark"] .trust-card,
html[data-theme="dark"] .guest-unlock,
html[data-theme="dark"] .profile-card,
html[data-theme="dark"] .wallet-card,
html[data-theme="dark"] .card,
html[data-theme="dark"] .discover-toolbar,
html[data-theme="dark"] .filter-advanced,
html[data-theme="dark"] .donors-summary {
  background: rgba(17, 24, 39, 0.88);
  border-color: rgba(148, 163, 184, 0.20);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.24);
}

html[data-theme="dark"] .camp-card,
html[data-theme="dark"] .featured-camp,
html[data-theme="dark"] .urgent-item,
html[data-theme="dark"] .activity-row,
html[data-theme="dark"] .donor-row,
html[data-theme="dark"] .recent-donation,
html[data-theme="dark"] .trust-item,
html[data-theme="dark"] .guest-unlock-list li {
  background: rgba(15, 23, 42, 0.62);
  border-color: rgba(148, 163, 184, 0.18);
}

html[data-theme="dark"] .sidebar-item,
html[data-theme="dark"] .bottom-nav-item,
html[data-theme="dark"] .guest-drawer-link,
html[data-theme="dark"] .site-auth-link {
  color: #cbd5e1;
}

html[data-theme="dark"] .sidebar-item:hover,
html[data-theme="dark"] .sidebar-item.active,
html[data-theme="dark"] .bottom-nav-item:hover,
html[data-theme="dark"] .bottom-nav-item.active,
html[data-theme="dark"] .site-nav-link:hover,
html[data-theme="dark"] .site-nav-link.is-active,
html[data-theme="dark"] .guest-drawer-link:hover,
html[data-theme="dark"] .guest-drawer-link.is-active {
  background: rgba(96, 165, 250, 0.12);
  color: #bfdbfe;
}

html[data-theme="dark"] .site-auth-btn {
  background: #60a5fa;
  color: #071113;
  box-shadow: 0 10px 24px rgba(96, 165, 250, 0.22);
}

html[data-theme="dark"] .site-auth-btn:hover {
  background: #93c5fd;
  color: #020617;
}

/* Controls and control wrappers (both search bars are focus-within shells
   around a real input, and .payment-method-option is a clickable radio
   tile), so these take the control token. Was hardcoded #334155 = 1.72:1. */
html[data-theme="dark"] input,
html[data-theme="dark"] textarea,
html[data-theme="dark"] select,
html[data-theme="dark"] .discover-search-bar,
html[data-theme="dark"] .dash-search,
html[data-theme="dark"] .payment-method-option {
  background: #0f172a;
  border-color: var(--color-border-control);
  color: #f8fafc;
}

/* Split out of the block above: the fee summary is a read-only panel, not a
   control, so 1.4.11 does not apply and it keeps the decorative border. */
html[data-theme="dark"] .donation-fee-summary {
  background: #0f172a;
  border-color: var(--color-border);
  color: #f8fafc;
}

html[data-theme="dark"] input:focus,
html[data-theme="dark"] textarea:focus,
html[data-theme="dark"] select:focus,
html[data-theme="dark"] .discover-search-bar:focus-within,
html[data-theme="dark"] .dash-search:focus-within {
  border-color: #60a5fa;
  box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.18);
}

/* Keep the dash search input dark on focus — the light-mode rule above
   forces white, which flashes against the dark dashboard.
   Also drop the wide focus ring so the pill input doesn't read as a square box. */
html[data-theme="dark"] .dash-search input,
html[data-theme="dark"] .dash-search input:focus,
html[data-theme="dark"] .dash-search input:hover {
  background: #0f172a;
  color: #f8fafc;
}
html[data-theme="dark"] .dash-search input::placeholder {
  color: #64748b;
}
.dash-search input:focus,
html[data-theme="dark"] .dash-search input:focus {
  box-shadow: none;
}
html[data-theme="dark"] .dash-search:focus-within {
  box-shadow: none;
}

/* Removed: .payment-method-option.is-recommended used to be unconditionally
   painted blue here, which made Whish stay blue forever — even after picking
   Visa. The "Recommended" ribbon (::before) is enough to signal recommendation;
   the blue selected look should ONLY come from :has(input:checked). */
html[data-theme="dark"] .cat-chip.active,
html[data-theme="dark"] .adv-pill.active,
html[data-theme="dark"] .active-filter-pill,
html[data-theme="dark"] .camp-verified-badge {
  background: rgba(37, 99, 235, 0.18);
  border-color: rgba(96, 165, 250, 0.38);
  color: #bfdbfe;
}

html[data-theme="dark"] .payment-method-icon,
html[data-theme="dark"] .trust-icon,
html[data-theme="dark"] .rd-icon,
html[data-theme="dark"] .donor-avatar,
html[data-theme="dark"] .camp-creator-avatar {
  background: linear-gradient(135deg, #2563eb 0%, #059669 100%);
  color: #ffffff;
}

html[data-theme="dark"] .progress-bar {
  background: #1e293b;
}

html[data-theme="dark"] .site-footer {
  background: rgba(2, 6, 23, 0.84);
  border-top: 1px solid rgba(148, 163, 184, 0.16);
}

html[data-theme="dark"] .guest-hero-v2 {
  background: linear-gradient(135deg, #0f172a 0%, #12383a 58%, #1e3a8a 100%);
  border: 1px solid rgba(148, 163, 184, 0.18);
}

html[data-theme="dark"] .trust-strip {
  background: rgba(17, 24, 39, 0.88);
  border-color: rgba(148, 163, 184, 0.20);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.24);
}

html[data-theme="dark"] .trust-strip-head h3,
html[data-theme="dark"] .testimonial-card figcaption strong,
html[data-theme="dark"] .guest-unlock h3,
html[data-theme="dark"] .guest-unlock-list strong,
html[data-theme="dark"] .how-steps li strong {
  color: #f8fafc;
}

html[data-theme="dark"] .trust-strip-head p,
html[data-theme="dark"] .trust-strip-head em,
html[data-theme="dark"] .testimonial-card blockquote,
html[data-theme="dark"] .testimonial-card figcaption small,
html[data-theme="dark"] .guest-unlock p,
html[data-theme="dark"] .guest-unlock-list small,
html[data-theme="dark"] .how-steps li small {
  color: #cbd5e1;
}

html[data-theme="dark"] .testimonial-card {
  background: rgba(15, 23, 42, 0.64);
  border-color: rgba(148, 163, 184, 0.18);
  box-shadow: none;
}

html[data-theme="dark"] .testimonial-card figcaption {
  border-top-color: rgba(148, 163, 184, 0.16);
}

html[data-theme="dark"] .testimonial-avatar {
  background: rgba(96, 165, 250, 0.16);
  color: #bfdbfe;
}

html[data-theme="dark"] body.is-guest #discover .discover-toolbar {
  background: rgba(15, 23, 42, 0.94);
  border-color: rgba(148, 163, 184, 0.18);
}
/* Same reason as the light-mode rule above: below 769px this element is the
   bottom-sheet, which brings its own surface colour. */
@media (min-width: 769px) {
  html[data-theme="dark"] body.is-guest #discover .discover-filters {
    background: rgba(15, 23, 42, 0.94);
    border-color: rgba(148, 163, 184, 0.18);
  }
}

/* Dark mode for the mobile filter trigger button + sheet head + bottom-sheet
   backdrop. The base styles use light colors; these tokens flip them dark. */
html[data-theme="dark"] .discover-filter-trigger {
  background: var(--color-surface);
  border-color: var(--color-border);
  color: var(--color-text);
}
html[data-theme="dark"] .discover-filter-trigger:hover {
  border-color: var(--color-primary);
}
html[data-theme="dark"] .discover-filters-sheet-head {
  border-bottom-color: var(--color-border);
}
html[data-theme="dark"] .discover-filters-sheet-close {
  background: rgba(96, 165, 250, 0.12);
  color: #bfdbfe;
}

html[data-theme="dark"] .discover-filters,
html[data-theme="dark"] .discover-sort-wrap,
html[data-theme="dark"] .discover-advanced,
html[data-theme="dark"] .discover-empty,
html[data-theme="dark"] .campaign-upload {
  background: rgba(17, 24, 39, 0.88);
  border-color: rgba(148, 163, 184, 0.22);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.20);
}

html[data-theme="dark"] .discover-search-bar input,
html[data-theme="dark"] #discover-sort,
html[data-theme="dark"] .adv-group select {
  color: #f8fafc;
}

html[data-theme="dark"] .discover-search-bar svg,
html[data-theme="dark"] .discover-sort-label,
html[data-theme="dark"] .adv-label,
html[data-theme="dark"] .discover-result-bar,
html[data-theme="dark"] .active-filter-clearall,
html[data-theme="dark"] .campaign-upload-hint,
html[data-theme="dark"] .campaign-upload-count,
html[data-theme="dark"] .label_text,
html[data-theme="dark"] .camp-donor-count {
  color: #cbd5e1;
}

html[data-theme="dark"] .cat-chip,
html[data-theme="dark"] .adv-pill,
html[data-theme="dark"] .discover-search-clear,
html[data-theme="dark"] .campaign-upload-thumb,
html[data-theme="dark"] .campaign-upload-add,
html[data-theme="dark"] .campaign-upload-slot {
  background: rgba(15, 23, 42, 0.72);
  border-color: rgba(148, 163, 184, 0.22);
  color: #e5e7eb;
}

html[data-theme="dark"] .campaign-upload-slot.is-empty {
  background:
    linear-gradient(135deg, rgba(96, 165, 250, 0.12), rgba(15, 23, 42, 0.72));
  color: #bfdbfe;
}

html[data-theme="dark"] .campaign-upload-slot.is-empty small {
  color: #94a3b8;
}

html[data-theme="dark"] .cat-chip:hover,
html[data-theme="dark"] .adv-pill:hover,
html[data-theme="dark"] .campaign-upload:hover,
html[data-theme="dark"] .campaign-upload-slot.is-empty:hover {
  background: rgba(96, 165, 250, 0.12);
  border-color: rgba(96, 165, 250, 0.38);
  color: #bfdbfe;
}

html[data-theme="dark"] .cat-chip-count {
  background: rgba(148, 163, 184, 0.18);
}

html[data-theme="dark"] .cat-chip-more.active {
  background: rgba(96, 165, 250, 0.14);
  color: #bfdbfe;
}

html[data-theme="dark"] .adv-reset {
  background: rgba(248, 113, 113, 0.08);
  border-color: rgba(248, 113, 113, 0.48);
  color: #fecaca;
}

html[data-theme="dark"] .adv-reset:hover {
  background: rgba(248, 113, 113, 0.16);
}

html[data-theme="dark"] .active-filter-clearall:hover,
html[data-theme="dark"] .discover-result-count,
html[data-theme="dark"] .discover-empty h3,
html[data-theme="dark"] .camp-raised strong {
  color: #f8fafc;
}

html[data-theme="dark"] .discover-empty p {
  color: #cbd5e1;
}

html[data-theme="dark"] .site-header--user-lead .site-header-user,
html[data-theme="dark"] .profile-role-badge {
  background: rgba(15, 23, 42, 0.72);
  border-color: rgba(148, 163, 184, 0.24);
  color: #cbd5e1;
}

html[data-theme="dark"] .site-header--user-lead .site-header-user:hover {
  background: rgba(30, 41, 59, 0.88);
  border-color: rgba(96, 165, 250, 0.36);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.24);
}

html[data-theme="dark"] .site-header-user img,
html[data-theme="dark"] .sidebar-user-avatar,
html[data-theme="dark"] .avatar-upload {
  background: #0f172a;
  border-color: rgba(96, 165, 250, 0.34);
}

html[data-theme="dark"] .profile-display-name,
html[data-theme="dark"] .profile-fields label,
html[data-theme="dark"] .donor-meta strong,
html[data-theme="dark"] .modal-confirm-breakdown li strong,
html[data-theme="dark"] .modal-confirm-to strong {
  color: #f8fafc;
}

html[data-theme="dark"] .field-hint,
html[data-theme="dark"] .modal-confirm-breakdown li,
html[data-theme="dark"] .modal-confirm-breakdown li small {
  color: #cbd5e1;
}

html[data-theme="dark"] .modal-confirm-breakdown,
html[data-theme="dark"] .modal-confirm-note,
html[data-theme="dark"] .payment-method-details,
html[data-theme="dark"] .payment-method-fee {
  background: rgba(15, 23, 42, 0.72);
  border-color: rgba(148, 163, 184, 0.20);
}

html[data-theme="dark"] .payment-method-details > strong,
html[data-theme="dark"] .pm-detail-row > span {
  color: #f8fafc;
}

html[data-theme="dark"] .pm-detail-row > small {
  color: #cbd5e1;
}

html[data-theme="dark"] .modal-required-fee {
  background: rgba(37, 99, 235, 0.14);
  border-color: rgba(96, 165, 250, 0.28);
  color: #cbd5e1;
}

html[data-theme="dark"] .modal-required-fee strong {
  color: #93c5fd;
}

html[data-theme="dark"] .payment-method-icon--whish {
  background: linear-gradient(135deg, #e91e63, #7c3aed);
}

html[data-theme="dark"] .payment-method-icon--card {
  background: linear-gradient(135deg, #1A1F71, #2563eb);
}

/* ── Bottom-nav dark mode — single consolidated block (deep glass).
   Deep navy surface, soft blue active pill, FAB ring uses dark page-bg so
   the notch effect still reads against a dark background. */
html[data-theme="dark"] .bottom-nav {
  background: rgba(15, 23, 42, 0.88);
  border-top: 1px solid rgba(148, 163, 184, 0.20);
  box-shadow:
    0 -8px 28px rgba(0, 0, 0, 0.55),
    inset 0 1px 0 rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
}
html[data-theme="dark"] .bottom-nav-item {
  color: #cbd5e1;
}
html[data-theme="dark"] .bottom-nav-item:hover {
  background: rgba(96, 165, 250, 0.10);
  color: #93c5fd;
}
html[data-theme="dark"] .bottom-nav-item.active {
  background: rgba(96, 165, 250, 0.18);
  color: #bfdbfe;
  box-shadow: inset 0 0 0 1px rgba(96, 165, 250, 0.22);
}
html[data-theme="dark"] .bottom-nav-fab {
  background: #60a5fa;
  color: #051022;
  /* Notch ring uses the dark page bg so the cutout reads on dark mode too. */
  box-shadow:
    0 0 0 0.6rem var(--color-bg),
    0 12px 28px rgba(96, 165, 250, 0.42);
}
html[data-theme="dark"] .bottom-nav-fab:hover,
html[data-theme="dark"] .bottom-nav-fab.active {
  background: #93c5fd;
  color: #020617;
}
html[data-theme="dark"] .bottom-nav-fab::before {
  background: #60a5fa;
}

/* Compact donation checkout */
#donate-modal .modal {
  max-width: 52rem;
  padding: 2rem;
}

#modal-step-payment .modal-sub {
  margin-bottom: 0.8rem;
}

#donate-modal .payment-method-list {
  gap: 0.65rem;
  margin-top: 1rem;
}

/* Older horizontal `#donate-modal .payment-method-option` overrides removed.
   They were silently clobbering the vertical-layout block (lines ~1810)
   on every viewport >=720px — that's why icon→title spacing wouldn't budge.
   Single source of truth now lives in the vertical-layout @media block. */

#donate-modal .payment-method-details {
  margin-top: 0.8rem;
  padding: 1rem 1.1rem;
  gap: 0.55rem 1rem;
}

#donate-modal .payment-method-details > strong {
  font-size: 1.18rem;
}

#donate-modal .pm-detail-row > span {
  font-size: 0.96rem;
}

#donate-modal .pm-detail-row > small {
  font-size: 1.05rem;
  line-height: 1.32;
}

#donate-modal .modal-required-fee,
#donate-modal .payment-trust {
  margin-top: 0.8rem;
  padding: 0.85rem 1rem;
  font-size: 1.08rem;
}

#donate-modal .modal-actions {
  margin-top: 1.1rem;
}

#donate-modal .modal-confirm-icon {
  width: 5.2rem;
  height: 5.2rem;
  margin-bottom: 1rem;
}

#donate-modal .modal-confirm-amount {
  font-size: 3.8rem;
}

#donate-modal .modal-confirm-to {
  margin-bottom: 1.1rem;
}

#donate-modal .modal-confirm-breakdown {
  margin-bottom: 1rem;
  padding: 1rem 1.2rem;
}

#donate-modal .modal-confirm-method-chip {
  margin-bottom: 0.9rem;
}

#donate-modal .modal-confirm-note {
  margin-bottom: 1rem;
}

/* Duplicate @media (min-width: 720px) block removed — was overriding the
   single source of truth at line ~1797. */

@media (max-width: 520px) {
  #donate-modal .modal {
    width: min(100% - 2rem, 38rem);
    max-height: calc(100dvh - 2rem);
    padding: 1.55rem;
    border-radius: 1.6rem;
  }

  #donate-modal .modal-close {
    top: 0.9rem;
    right: 0.9rem;
  }

  #donate-modal .modal h3 {
    font-size: 1.7rem;
    margin-right: 3.8rem;
  }

  #modal-step-payment .modal-sub {
    font-size: 1.08rem;
    line-height: 1.35;
    max-width: 28rem;
  }

  #donate-modal .payment-method-list legend {
    margin-bottom: 0.25rem;
  }

  #donate-modal .payment-method-option {
    min-height: auto;
    grid-template-columns: 3.8rem minmax(0, 1fr);
    gap: 1.25rem;
    padding: 0.9rem 3.5rem 0.9rem 1.05rem;
  }

  #donate-modal .payment-method-icon {
    width: 3.8rem;
    height: 3.8rem;
  }

  #donate-modal .payment-method-option strong {
    font-size: 1.2rem;
  }

  #donate-modal .payment-method-option small {
    font-size: 1rem;
    line-height: 1.28;
  }

  #donate-modal .payment-method-fee {
    font-size: 0.92rem;
  }

  #donate-modal .payment-method-option.is-recommended::before,
  #donate-modal .payment-method-option.is-best::before {
    font-size: 0.72rem;
    padding: 0.16rem 0.48rem;
  }

  #donate-modal .payment-method-details {
    display: grid;
    grid-template-columns: 1fr;
    padding: 0.9rem 1rem;
  }

  #donate-modal .payment-method-details .pm-detail-row:nth-of-type(n+3) {
    display: none;
  }

  #donate-modal .modal-required-fee {
    align-items: flex-start;
  }

  #donate-modal .payment-trust {
    display: none;
  }

  #donate-modal .modal-actions {
    flex-direction: row;
  }

  #donate-modal .modal-actions .btn {
    width: auto;
    flex: 1 1 0;
    min-height: 4.4rem;
  }

  #donate-modal .modal-confirm-icon {
    width: 4.8rem;
    height: 4.8rem;
  }

  #donate-modal .modal-confirm-amount {
    font-size: 3.4rem;
  }

  #donate-modal .modal-confirm-breakdown li {
    font-size: 1.18rem;
  }

  #donate-modal .modal-confirm-note {
    padding: 0;
    background: transparent;
  }
}

/* Activity & Bills */
.activity-bills-summary {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.2rem;
  margin-bottom: 2.4rem;
}

.activity-total-card {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 1.4rem;
  padding: 1.6rem;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.activity-total-card span {
  color: #64748b;
  font-size: 1.15rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.activity-total-card strong {
  color: #0f172a;
  font-size: 2.5rem;
  line-height: 1.1;
}

.activity-total-card small {
  color: #64748b;
  font-size: 1.15rem;
  line-height: 1.35;
}

.activity-bills-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(34rem, 0.92fr);
  gap: 2rem;
  align-items: start;
}

.activity-ledger,
.bill-preview {
  min-width: 0;
}

.activity-ledger-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.activity-ledger-head h3 {
  margin: 0;
  color: #0f172a;
  font-size: 1.8rem;
}

.activity-filter-tabs {
  display: inline-flex;
  gap: 0.35rem;
  padding: 0.35rem;
  background: #f1f5f9;
  border-radius: 999px;
}

.activity-filter-tabs button {
  border: 0;
  background: transparent;
  color: #64748b;
  border-radius: 999px;
  padding: 0.45rem 0.9rem;
  font-family: inherit;
  font-size: 1.1rem;
  font-weight: 700;
  cursor: pointer;
}

/* Active tab: bold blue pill. Hover: subtle background only so it never
   looks selected. Previously hover === active, which made any hovered tab
   look like a second active item (the bug in the screenshot). */
.activity-filter-tabs button.active {
  background: #fff;
  color: var(--color-primary);
  box-shadow: 0 1px 4px rgba(15, 23, 42, 0.08);
}
.activity-filter-tabs button:hover:not(.active) {
  color: var(--color-text);
  background: rgba(15, 23, 42, 0.04);
}

.activity-ledger-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.activity-ledger-row {
  width: 100%;
  display: grid;
  grid-template-columns: 4.4rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 1.2rem;
  padding: 1rem;
  border: 1px solid #e2e8f0;
  border-radius: 1.2rem;
  background: #f8fafc;
  color: inherit;
  text-align: left;
  font-family: inherit;
  cursor: pointer;
  transition: border-color 0.16s ease, background 0.16s ease, box-shadow 0.16s ease;
}

.activity-ledger-row:hover,
.activity-ledger-row.active {
  border-color: rgba(37, 99, 235, 0.42);
  background: #fff;
  box-shadow: 0 8px 20px rgba(37, 99, 235, 0.10);
}

.activity-ledger-icon {
  width: 4.4rem;
  height: 4.4rem;
  border-radius: 1.1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
}

.activity-ledger-icon svg {
  width: 2rem;
  height: 2rem;
}

.activity-ledger-icon.paid { background: linear-gradient(135deg, #16a34a, #22c55e); }
.activity-ledger-icon.wallet { background: linear-gradient(135deg, #0891b2, #2563eb); }
.activity-ledger-icon.card-pay { background: linear-gradient(135deg, #1A1F71, #2563eb); }
.activity-ledger-icon.topup { background: linear-gradient(135deg, #7c3aed, #2563eb); }

.activity-ledger-main,
.activity-ledger-side {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.activity-ledger-main strong {
  color: #0f172a;
  font-size: 1.35rem;
}

.activity-ledger-main small,
.activity-ledger-side small {
  color: #64748b;
  font-size: 1.12rem;
}

.activity-ledger-side {
  align-items: flex-end;
}

.activity-ledger-side strong {
  color: #0f172a;
  font-size: 1.35rem;
  font-variant-numeric: tabular-nums;
}

.bill-preview {
  position: sticky;
  top: 8rem;
}

.bill-paper {
  background:
    linear-gradient(#fff, #fff) padding-box,
    linear-gradient(135deg, rgba(37, 99, 235, 0.45), rgba(20, 184, 166, 0.24)) border-box;
  border: 1px solid transparent;
  border-radius: 1.4rem;
  padding: 1.8rem;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
}

.bill-brand-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding-bottom: 1.4rem;
  border-bottom: 1px dashed #cbd5e1;
}

.bill-logo-mark {
  width: 4.4rem;
  height: 4.4rem;
  border-radius: 1.2rem;
  background: #0f172a;
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  font-weight: 800;
}

.bill-brand-row strong {
  display: block;
  color: #0f172a;
  font-size: 1.7rem;
}

.bill-brand-row small {
  color: #64748b;
  font-size: 1.15rem;
}

.bill-meta-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  padding: 1.4rem 0;
  border-bottom: 1px dashed #cbd5e1;
}

.bill-meta-grid span,
.bill-lines div {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.bill-meta-grid small {
  color: #64748b;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.bill-meta-grid strong {
  color: #0f172a;
  font-size: 1.15rem;
}

.bill-status-paid {
  color: #16a34a !important;
}
.bill-status-pending {
  color: #d97706 !important;
}

/* Empty state: shown until a donation row is clicked. .is-empty on the panel
   hides the receipt paper and its actions and reveals this placeholder. */
.bill-empty {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  text-align: center;
  padding: 3rem 2rem;
  color: var(--text-muted);
}
.bill-empty svg { width: 2.4rem; height: 2.4rem; opacity: 0.45; }
.bill-empty strong { font-size: 1.45rem; color: var(--text); }
.bill-empty span { font-size: 1.25rem; max-width: 26rem; }
.bill-preview.is-empty .bill-empty { display: flex; }
.bill-preview.is-empty .bill-paper,
.bill-preview.is-empty .bill-actions { display: none; }

.bill-lines {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  padding: 1.4rem 0;
}

.bill-lines div {
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  color: #64748b;
  font-size: 1.25rem;
}

.bill-lines strong {
  color: #0f172a;
  font-variant-numeric: tabular-nums;
}

.bill-total-line {
  border-top: 1px solid #e2e8f0;
  margin-top: 0.4rem;
  padding-top: 1rem;
  color: #0f172a !important;
  font-weight: 800;
}

.bill-total-line strong {
  color: var(--color-primary);
  font-size: 1.8rem;
}

.bill-foot-note {
  padding: 1rem;
  background: #eff6ff;
  border-radius: 1rem;
  color: #475569;
  font-size: 1.1rem;
  line-height: 1.45;
}

.bill-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.8rem;
  margin-top: 1rem;
}

/* Notification panel dark-mode and polish */
.dash-notif-panel {
  backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
}

html[data-theme="dark"] .dash-notif-panel {
  background: rgba(15, 23, 42, 0.96);
  border-color: rgba(96, 165, 250, 0.22);
  box-shadow: 0 24px 54px rgba(0, 0, 0, 0.42);
}

html[data-theme="dark"] .dash-notif-head {
  border-color: rgba(148, 163, 184, 0.16);
}

html[data-theme="dark"] .dash-notif-head strong,
html[data-theme="dark"] .dash-notif-text strong,
html[data-theme="dark"] .activity-ledger-head h3,
html[data-theme="dark"] .activity-total-card strong,
html[data-theme="dark"] .activity-ledger-main strong,
html[data-theme="dark"] .activity-ledger-side strong,
html[data-theme="dark"] .bill-brand-row strong,
html[data-theme="dark"] .bill-meta-grid strong,
html[data-theme="dark"] .bill-lines strong {
  color: #e5e7eb;
}

html[data-theme="dark"] .dash-notif-row {
  border-color: rgba(148, 163, 184, 0.14);
}

html[data-theme="dark"] .dash-notif-row:hover {
  background: rgba(96, 165, 250, 0.08);
}

html[data-theme="dark"] .dash-notif-row.unread::before {
  background: #60a5fa;
}

html[data-theme="dark"] .dash-notif-text small,
html[data-theme="dark"] .activity-total-card span,
html[data-theme="dark"] .activity-total-card small,
html[data-theme="dark"] .activity-ledger-main small,
html[data-theme="dark"] .activity-ledger-side small,
html[data-theme="dark"] .bill-brand-row small,
html[data-theme="dark"] .bill-meta-grid small,
html[data-theme="dark"] .bill-lines div,
html[data-theme="dark"] .bill-foot-note {
  color: #94a3b8;
}

html[data-theme="dark"] .dash-notif-foot {
  border-color: rgba(148, 163, 184, 0.16);
  background: rgba(15, 23, 42, 0.82);
}

html[data-theme="dark"] .dash-notif-foot:hover {
  background: rgba(96, 165, 250, 0.12);
}

html[data-theme="dark"] .activity-total-card,
html[data-theme="dark"] .activity-ledger,
html[data-theme="dark"] .bill-preview {
  background: rgba(15, 23, 42, 0.88);
  border-color: rgba(148, 163, 184, 0.18);
}

html[data-theme="dark"] .activity-filter-tabs {
  background: rgba(2, 6, 23, 0.56);
}

html[data-theme="dark"] .activity-filter-tabs button {
  color: #94a3b8;
}

html[data-theme="dark"] .activity-filter-tabs button.active,
html[data-theme="dark"] .activity-filter-tabs button:hover {
  background: rgba(96, 165, 250, 0.14);
  color: #bfdbfe;
  box-shadow: none;
}

html[data-theme="dark"] .activity-ledger-row {
  background: rgba(15, 23, 42, 0.76);
  border-color: rgba(148, 163, 184, 0.16);
}

html[data-theme="dark"] .activity-ledger-row:hover,
html[data-theme="dark"] .activity-ledger-row.active {
  background: rgba(37, 99, 235, 0.12);
  border-color: rgba(96, 165, 250, 0.34);
  box-shadow: none;
}

html[data-theme="dark"] .bill-paper {
  background:
    linear-gradient(rgba(15, 23, 42, 0.96), rgba(15, 23, 42, 0.96)) padding-box,
    linear-gradient(135deg, rgba(96, 165, 250, 0.44), rgba(20, 184, 166, 0.24)) border-box;
}

html[data-theme="dark"] .bill-brand-row,
html[data-theme="dark"] .bill-meta-grid,
html[data-theme="dark"] .bill-total-line {
  border-color: rgba(148, 163, 184, 0.24);
}

html[data-theme="dark"] .bill-total-line span {
  color: #cbd5e1;
}

html[data-theme="dark"] .bill-foot-note {
  background: rgba(37, 99, 235, 0.12);
}

@media (max-width: 900px) {
  .activity-bills-summary,
  .activity-bills-layout {
    grid-template-columns: 1fr;
  }

  .bill-preview {
    position: static;
  }
}

@media (max-width: 520px) {
  .activity-bills-summary {
    display: none;
  }

  .activity-total-card {
    padding: 1rem;
    border-radius: 1.1rem;
  }

  .activity-total-card span {
    font-size: 0.9rem;
    letter-spacing: 0.03em;
  }

  .activity-total-card strong {
    font-size: 1.55rem;
  }

  .activity-total-card small {
    display: none;
  }

  .bill-preview {
    order: -1;
  }

  .activity-ledger {
    order: 0;
  }

  .activity-ledger-head {
    align-items: flex-start;
    flex-direction: column;
  }

  .activity-filter-tabs {
    width: 100%;
  }

  .activity-filter-tabs button {
    flex: 1;
  }

  .activity-ledger-row {
    grid-template-columns: 3.8rem minmax(0, 1fr);
  }

  .activity-ledger-icon {
    width: 3.8rem;
    height: 3.8rem;
  }

  .activity-ledger-side {
    grid-column: 2;
    align-items: flex-start;
    flex-direction: row;
    gap: 0.6rem;
  }

  .bill-paper {
    padding: 1.2rem;
  }

  .bill-meta-grid {
    grid-template-columns: 1fr 1fr;
    gap: 0.8rem;
    padding: 1rem 0;
  }

  .bill-actions {
    grid-template-columns: 1fr 1fr;
  }

  .bill-brand-row {
    padding-bottom: 1rem;
  }

  .bill-lines {
    padding: 1rem 0;
  }

  .bill-foot-note {
    display: none;
  }

  .bill-verification {
    display: none;
  }
}

/* Messages */
.messages-shell {
  display: grid;
  grid-template-columns: minmax(26rem, 0.78fr) minmax(0, 1.22fr);
  gap: 0;
  padding: 0;
  overflow: hidden;
}

.messages-list {
  border-right: 1px solid #e2e8f0;
  background: #f8fafc;
  padding: 1.4rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 0;
}

.messages-list-head,
.chat-head {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.messages-list-head {
  justify-content: space-between;
}

.messages-list-head h3 {
  margin: 0;
  color: #0f172a;
  font-size: 1.7rem;
}

.messages-new-btn,
.chat-icon-btn {
  width: 3.8rem;
  height: 3.8rem;
  border-radius: 1rem;
  border: 1px solid #dbeafe;
  background: #eff6ff;
  color: var(--color-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.messages-new-btn svg,
.chat-icon-btn svg {
  width: 1.8rem;
  height: 1.8rem;
}

.messages-search {
  min-height: 4.2rem;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  border: 1px solid #e2e8f0;
  background: #fff;
  border-radius: 1.2rem;
  padding: 0 1rem;
}

.messages-search svg {
  width: 1.7rem;
  height: 1.7rem;
  color: #94a3b8;
}

.messages-search input {
  border: 0;
  outline: 0;
  background: transparent;
  width: 100%;
  min-width: 0;
  font-family: inherit;
}

.message-thread {
  display: grid;
  grid-template-columns: 4.4rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 1rem;
  width: 100%;
  border: 1px solid transparent;
  background: transparent;
  border-radius: 1.2rem;
  padding: 0.9rem;
  text-align: left;
  font-family: inherit;
  cursor: pointer;
}

.message-thread:hover,
.message-thread.active {
  background: #fff;
  border-color: #dbeafe;
  box-shadow: 0 8px 18px rgba(37, 99, 235, 0.08);
}

.message-avatar {
  width: 4.4rem;
  height: 4.4rem;
  border-radius: 1.3rem;
  background: linear-gradient(135deg, #2563eb, #14b8a6);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  font-weight: 900;
  flex-shrink: 0;
}

.message-avatar.donor { background: linear-gradient(135deg, #7c3aed, #2563eb); }
.message-avatar.recipient { background: linear-gradient(135deg, #16a34a, #0891b2); }

.message-thread-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.message-thread-body strong {
  color: #0f172a;
  font-size: 1.25rem;
}

.message-thread-body small,
.message-time,
.chat-head small {
  color: #64748b;
  font-size: 1.08rem;
}

.message-thread-body small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat-panel {
  min-width: 0;
  display: flex;
  flex-direction: column;
  min-height: 58rem;
  background: #fff;
}

.chat-head {
  padding: 1.4rem 1.6rem;
  border-bottom: 1px solid #e2e8f0;
}

.chat-head span:nth-child(2) {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}

.chat-head strong {
  color: #0f172a;
  font-size: 1.35rem;
}

.chat-head-link {
  color: var(--color-primary);
  font-size: 1.15rem;
  font-weight: 800;
  text-decoration: none;
}

.chat-body {
  flex: 1;
  min-height: 0;
  padding: 1.6rem;
  background:
    radial-gradient(circle at 12% 10%, rgba(96, 165, 250, 0.08), transparent 26%),
    linear-gradient(180deg, #f8fafc, #eef2ff);
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.chat-bubble {
  max-width: min(78%, 42rem);
  padding: 1rem 1.1rem;
  border-radius: 1.35rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.chat-bubble p {
  margin: 0;
  font-size: 1.25rem;
  line-height: 1.45;
}

.chat-bubble time {
  font-size: 0.98rem;
  opacity: 0.72;
}

.chat-bubble.incoming {
  align-self: flex-start;
  background: #fff;
  color: #0f172a;
  border-bottom-left-radius: 0.4rem;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.08);
}

.chat-bubble.outgoing {
  align-self: flex-end;
  background: var(--color-primary);
  color: #fff;
  border-bottom-right-radius: 0.4rem;
}

.chat-compose {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 0.8rem;
  padding: 1.2rem;
  border-top: 1px solid #e2e8f0;
  align-items: center;
}

.chat-compose input {
  width: 100%;
  min-height: 4.4rem;
  border: 1px solid #e2e8f0;
  border-radius: 999px;
  padding: 0 1.4rem;
  font-family: inherit;
  background: #f8fafc;
}

.chat-send-btn {
  min-height: 4.4rem;
}

/* Worldwide-style bill details */
.bill-standard-badge {
  margin-left: auto;
  padding: 0.35rem 0.7rem;
  border-radius: 999px;
  background: #eff6ff;
  color: var(--color-primary);
  font-size: 0.95rem;
  font-weight: 900;
  white-space: nowrap;
}

.bill-parties,
.bill-verification {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
  padding: 1.2rem 0;
  border-bottom: 1px dashed #cbd5e1;
}

.bill-parties span,
.bill-verification span {
  display: flex;
  flex-direction: column;
  gap: 0.18rem;
}

.bill-parties small,
.bill-verification small {
  color: #64748b;
  font-size: 0.95rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.bill-parties strong,
.bill-verification strong {
  color: #0f172a;
  font-size: 1.12rem;
}

.bill-parties em {
  color: #64748b;
  font-size: 1.02rem;
  font-style: normal;
}

.bill-verification {
  border-top: 1px dashed #cbd5e1;
}

/* `.sidebar { padding: 1.2rem 0.9rem 1.4rem }` lived here and silently
   overrode the drawer's safe-area padding via the shorthand. Folded into the
   consolidated `.sidebar` rule at the top of this file. */

.sidebar-brand {
  padding: 0.2rem 0.2rem 1rem;
}

.sidebar-user {
  width: 100%;
  margin: 0 0 1rem;
  padding: 0.95rem 1rem;
  border-radius: 1.25rem;
}

.sidebar-item {
  min-height: 4.6rem;
  width: 100%;
  border-radius: 1.15rem;
  padding: 1rem 1.4rem;
  gap: 1.2rem;
}

.sidebar-item.active::before {
  display: none;
}

.sidebar-item svg {
  width: 2rem;
  height: 2rem;
}

/* Pin every sidebar item to the same left edge so icons + labels line up
   vertically across Dashboard / Campaigns / Profile / etc.
   Higher specificity than the bare .sidebar-item rules so it wins without
   needing !important. */
.sidebar .sidebar-item,
.sidebar .sidebar-user {
  justify-content: flex-start;
  text-align: left;
}

/* Align the avatar circle with where icons sit below it so the user card
   reads as part of the same column. */
.sidebar .sidebar-user {
  padding-left: 1.4rem;
  padding-right: 1.4rem;
  gap: 1rem;
}

.sidebar-auth-section {
  padding-top: 1rem;
  gap: 0.35rem;
}


/* People directory + profile quick view */
.people-panel {
  display: grid;
  gap: 1.2rem;
}

.people-toolbar {
  display: grid;
  grid-template-columns: minmax(18rem, 1fr) auto;
  gap: 1rem;
  align-items: center;
}

.people-search {
  min-height: 4.6rem;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0 1rem;
  border: 1px solid #e2e8f0;
  border-radius: 1.2rem;
  background: #f8fafc;
}

.people-search svg {
  width: 1.8rem;
  height: 1.8rem;
  color: #64748b;
  flex-shrink: 0;
}

.people-search input {
  width: 100%;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: #0f172a;
  font-family: inherit;
  font-size: 1.25rem;
}

.people-filter-tabs {
  display: flex;
  gap: 0.45rem;
  padding: 0.35rem;
  border-radius: 999px;
  background: #f1f5f9;
  overflow-x: auto;
  scrollbar-width: none;
}

.people-filter-tabs::-webkit-scrollbar {
  display: none;
}

.people-filter-tabs button {
  border: 0;
  background: transparent;
  color: #64748b;
  border-radius: 999px;
  padding: 0.65rem 1rem;
  font-family: inherit;
  font-size: 1.05rem;
  font-weight: 800;
  cursor: pointer;
  white-space: nowrap;
}

.people-filter-tabs button.active,
.people-filter-tabs button:hover {
  background: #fff;
  color: var(--color-primary);
  box-shadow: 0 1px 5px rgba(15, 23, 42, 0.08);
}

.people-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}

.people-card {
  min-width: 0;
  display: grid;
  gap: 0.85rem;
  padding: 1rem;
  border: 1px solid #e2e8f0;
  border-radius: 1.35rem;
  background: #f8fafc;
}

.people-card-main {
  width: 100%;
  display: grid;
  grid-template-columns: 4.4rem minmax(0, 1fr);
  align-items: center;
  gap: 0.9rem;
  border: 0;
  background: transparent;
  color: inherit;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  border-radius: 1rem;
}

.people-avatar,
.person-profile-avatar {
  width: 4.4rem;
  height: 4.4rem;
  border-radius: 1.25rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #2563eb, #14b8a6);
  color: #fff;
  font-size: 1.28rem;
  font-weight: 900;
  flex-shrink: 0;
}

.people-card-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.people-card-text strong {
  color: #0f172a;
  font-size: 1.22rem;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.people-card-text small {
  color: #64748b;
  font-size: 1.02rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.people-card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
}

.people-card-tags span {
  display: inline-flex;
  align-items: center;
  min-height: 2.2rem;
  padding: 0.25rem 0.65rem;
  border-radius: 999px;
  background: #eef2ff;
  color: #475569;
  font-size: 0.95rem;
  font-weight: 800;
}

.people-card-message {
  min-height: 3.8rem;
  border: 1px solid rgba(37, 99, 235, 0.20);
  border-radius: 1rem;
  background: #eff6ff;
  color: var(--color-primary);
  font-family: inherit;
  font-size: 1.08rem;
  font-weight: 900;
  cursor: pointer;
}

.people-card:hover,
.people-card:has(:focus-visible) {
  border-color: rgba(37, 99, 235, 0.35);
  background: #fff;
  box-shadow: 0 12px 26px rgba(37, 99, 235, 0.10);
}

.people-empty {
  padding: 2rem 1rem;
  text-align: center;
  color: #64748b;
}

.person-modal {
  max-width: 48rem;
}

.person-profile-head {
  display: grid;
  grid-template-columns: 5.2rem minmax(0, 1fr);
  gap: 1rem;
  align-items: center;
  margin-bottom: 1.2rem;
}

.person-profile-avatar {
  width: 5.2rem;
  height: 5.2rem;
  border-radius: 1.45rem;
  font-size: 1.45rem;
}

.person-profile-title {
  min-width: 0;
}

.person-profile-title small {
  display: block;
  color: var(--color-primary);
  font-size: 1.02rem;
  font-weight: 900;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.person-profile-title h3 {
  margin: 0.15rem 0 0;
  color: #0f172a;
  font-size: 1.75rem;
  line-height: 1.2;
}

.person-profile-title span,
.person-profile-bio {
  color: #64748b;
  font-size: 1.15rem;
}

.person-profile-bio {
  margin: 0 0 1.2rem;
  line-height: 1.55;
}

.person-profile-facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.75rem;
  margin-bottom: 1.2rem;
}

.person-profile-facts span {
  min-width: 0;
  padding: 0.85rem;
  border-radius: 1rem;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
}

.person-profile-facts small {
  display: block;
  color: #64748b;
  font-size: 0.92rem;
  font-weight: 900;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.person-profile-facts strong {
  display: block;
  color: #0f172a;
  font-size: 1.08rem;
  overflow-wrap: anywhere;
}

.person-profile-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}

.person-linked-row {
  cursor: pointer;
  transition: border-color 0.16s, background 0.16s, box-shadow 0.16s;
}

.person-linked-row:hover,
.person-linked-row:focus-visible {
  background: #f8fafc;
  border-color: rgba(37, 99, 235, 0.26);
  box-shadow: 0 8px 20px rgba(37, 99, 235, 0.08);
  outline: none;
}

html[data-theme="dark"] .people-panel,
html[data-theme="dark"] .person-modal {
  background: rgba(15, 23, 42, 0.94);
  border-color: rgba(148, 163, 184, 0.18);
}

html[data-theme="dark"] .people-search,
html[data-theme="dark"] .people-card,
html[data-theme="dark"] .person-profile-facts span,
html[data-theme="dark"] .people-filter-tabs {
  background: rgba(15, 23, 42, 0.72);
  border-color: rgba(148, 163, 184, 0.16);
}

html[data-theme="dark"] .people-search input,
html[data-theme="dark"] .people-card-text strong,
html[data-theme="dark"] .person-profile-title h3,
html[data-theme="dark"] .person-profile-facts strong {
  color: #e5e7eb;
}

html[data-theme="dark"] .people-search svg,
html[data-theme="dark"] .people-card-text small,
html[data-theme="dark"] .person-profile-title span,
html[data-theme="dark"] .person-profile-bio,
html[data-theme="dark"] .person-profile-facts small,
html[data-theme="dark"] .people-empty {
  color: #94a3b8;
}

html[data-theme="dark"] .people-filter-tabs button {
  color: #94a3b8;
}

html[data-theme="dark"] .people-filter-tabs button.active,
html[data-theme="dark"] .people-filter-tabs button:hover,
html[data-theme="dark"] .people-card:hover,
html[data-theme="dark"] .people-card:has(:focus-visible) {
  background: rgba(96, 165, 250, 0.12);
  color: #bfdbfe;
  box-shadow: none;
}

html[data-theme="dark"] .people-card-tags span {
  background: rgba(96, 165, 250, 0.13);
  color: #bfdbfe;
}

html[data-theme="dark"] .people-card-message {
  background: rgba(37, 99, 235, 0.16);
  border-color: rgba(96, 165, 250, 0.28);
  color: #bfdbfe;
}

html[data-theme="dark"] .person-linked-row:hover,
html[data-theme="dark"] .person-linked-row:focus-visible {
  background: rgba(96, 165, 250, 0.10);
  border-color: rgba(96, 165, 250, 0.24);
  box-shadow: none;
}

@media (max-width: 760px) {
  .people-toolbar {
    grid-template-columns: 1fr;
  }

  .people-filter-tabs {
    border-radius: 1rem;
  }

  .people-grid {
    grid-template-columns: 1fr;
  }

  .people-card {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.65rem;
    padding: 0.85rem;
  }

  .people-card-main {
    grid-column: 1 / -1;
  }

  .people-card-tags {
    display: none;
  }

  .people-card-message {
    grid-column: 1 / -1;
    min-height: 3.6rem;
  }

  .person-profile-facts {
    grid-template-columns: 1fr;
  }

  .person-profile-actions {
    grid-template-columns: 1fr;
  }
}

/* Final alignment pass for buttons */
button,
.btn,
.site-auth-btn,
.hero-primary-btn,
.guest-unlock-cta,
.how-cta-btn,
.camp-donate,
.urgent-donate,
.featured-camp-donate,
.modal-next-btn,
.modal-back-btn,
.chat-send-btn {
  align-items: center;
  justify-content: center;
  text-align: center;
}

html[data-theme="dark"] .messages-shell,
html[data-theme="dark"] .chat-panel {
  background: rgba(15, 23, 42, 0.88);
}

html[data-theme="dark"] .messages-list {
  background: rgba(2, 6, 23, 0.36);
  border-color: rgba(148, 163, 184, 0.16);
}

html[data-theme="dark"] .messages-list-head h3,
html[data-theme="dark"] .message-thread-body strong,
html[data-theme="dark"] .chat-head strong,
html[data-theme="dark"] .bill-parties strong,
html[data-theme="dark"] .bill-verification strong {
  color: #e5e7eb;
}

/* .messages-search and .chat-compose input used to be in this list too, but
   both declarations were dead — the control rule further down the file has
   equal specificity and wins on source order. Removed so the file states the
   border once instead of contradicting itself. */
html[data-theme="dark"] .message-thread:hover,
html[data-theme="dark"] .message-thread.active {
  background: rgba(15, 23, 42, 0.76);
  border-color: rgba(148, 163, 184, 0.18);
}

html[data-theme="dark"] .messages-search input,
html[data-theme="dark"] .chat-compose input {
  color: #e5e7eb;
}

html[data-theme="dark"] .message-thread-body small,
html[data-theme="dark"] .message-time,
html[data-theme="dark"] .chat-head small,
html[data-theme="dark"] .bill-parties small,
html[data-theme="dark"] .bill-verification small,
html[data-theme="dark"] .bill-parties em {
  color: #94a3b8;
}

html[data-theme="dark"] .chat-head,
html[data-theme="dark"] .chat-compose {
  border-color: rgba(148, 163, 184, 0.16);
}

html[data-theme="dark"] .chat-body {
  background:
    radial-gradient(circle at 12% 10%, rgba(96, 165, 250, 0.08), transparent 26%),
    linear-gradient(180deg, rgba(2, 6, 23, 0.28), rgba(15, 23, 42, 0.82));
}

html[data-theme="dark"] .chat-bubble.incoming {
  background: rgba(30, 41, 59, 0.92);
  color: #e5e7eb;
}

html[data-theme="dark"] .bill-standard-badge {
  background: rgba(37, 99, 235, 0.16);
  color: #bfdbfe;
}

html[data-theme="dark"] .bill-parties,
html[data-theme="dark"] .bill-verification {
  border-color: rgba(148, 163, 184, 0.24);
}

@media (max-width: 900px) {
  .messages-shell {
    grid-template-columns: 1fr;
  }

  .messages-list {
    border-right: 0;
    border-bottom: 1px solid #e2e8f0;
  }

  .chat-panel {
    min-height: 48rem;
  }
}

@media (max-width: 520px) {
  .messages-list {
    max-height: none;
    overflow-y: auto;
    padding: 1rem;
  }

  .messages-list .message-thread:not(.active) {
    display: none;
  }

  .messages-search {
    display: none;
  }

  .chat-head-link {
    display: none;
  }

  .chat-body {
    min-height: 0;
    max-height: 22rem;
    overflow-y: auto;
    padding: 1.2rem;
  }

  .chat-bubble {
    max-width: 88%;
  }

  .chat-compose {
    grid-template-columns: auto minmax(0, 1fr) auto;
  }

  .chat-send-btn {
    grid-column: auto;
    width: auto;
    min-width: 7rem;
  }

  .bill-standard-badge {
    display: none;
  }

  .bill-parties,
  .bill-verification {
    grid-template-columns: 1fr 1fr;
    padding: 0.9rem 0;
  }

  .bill-verification {
    display: none;
  }
}

@media (max-width: 480px) {
}

@media (max-width: 768px) {
  html,
  body {
    max-width: 100%;
    overflow-x: hidden;
  }

  body.is-auth .layout {
    width: 100%;
    max-width: 100%;
    overflow-x: hidden;
  }

  body.is-auth .main-content,
  body.is-auth .section,
  body.is-auth .card,
  body.is-auth .people-panel,
  body.is-auth .messages-shell,
  body.is-auth .campaign-form {
    width: 100%;
    max-width: 100%;
    min-width: 0;
  }

  body.is-auth .main-content {
    box-sizing: border-box;
    width: 100%;
    max-width: 100vw;
    padding-left: 1.2rem;
    padding-right: 1.2rem;
    overflow-x: hidden;
  }

  body.is-auth .card {
    box-sizing: border-box;
    width: 100%;
  }

  /* Removed: body.is-auth .card-row + .flex-1 + .flex-2 — those classes
     no longer exist in any HTML. */
  .people-search input {
    min-width: 0;
    font-size: 1.08rem;
  }

}

/* ════════════════════════════════════════════════════════════════════════
   Stage 2 — Dashboard "How Sawa works" guide + Profile summary cards
   Scoped to new classes so they don't fight any older selectors.
   ════════════════════════════════════════════════════════════════════════ */

/* How Sawa works styles moved to css/guide.css (their dedicated page). */

/* ── Profile summary + extras ── */
.profile-summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 1.2rem;
  /* Top margin gives the banner card room to breathe before the stat cards —
     they sat flush against it (0px gap) before. Bottom keeps the same rhythm
     down to the Quick actions / security grid. */
  margin: 2.4rem 0;
}
.profile-summary-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--r-lg);
  padding: 1.4rem 1.6rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.profile-summary-label {
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.profile-summary-value {
  font-size: 2.2rem;
  font-weight: 800;
  color: var(--color-text);
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}
.profile-summary-card small {
  font-size: 1.15rem;
  color: var(--color-text-light);
}
.profile-summary-status {
  font-size: 1.6rem;
}
.profile-status-dot {
  width: 1rem;
  height: 1rem;
  border-radius: 50%;
  background: var(--color-success);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-success) 25%, transparent);
}

.profile-extra-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.6rem;
  margin-top: 2rem;
}
@media (max-width: 720px) {
  .profile-extra-grid {
    grid-template-columns: 1fr;
  }
}
.profile-extra-card h4 {
  font-size: 1.5rem;
  font-weight: 700;
  margin: 0 0 1.2rem;
  color: var(--color-text);
}
.profile-extra-card-wide {
  grid-column: 1 / -1;
}
.profile-extra-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
}
.profile-extra-actions .btn {
  flex: 1 1 auto;
  min-width: 14rem;
}
.profile-security-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
}
.profile-security-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  font-size: 1.3rem;
  color: var(--color-text);
  padding: 0.4rem 0;
  border-bottom: 1px dashed var(--color-border);
}
.profile-security-list li:last-child {
  border-bottom: none;
}
.profile-pill {
  font-size: 1.1rem;
  font-weight: 700;
  padding: 0.3rem 0.9rem;
  border-radius: 9999px;
  letter-spacing: 0.02em;
}
.profile-pill-ok {
  background: var(--color-success-light);
  color: var(--color-success-dark);
}
.profile-pill-soon {
  background: var(--color-warning-light);
  color: var(--color-warning);
}
.profile-extra-note {
  font-size: 1.15rem;
  color: var(--color-text-light);
  margin: 1rem 0 0;
}
.profile-empty {
  font-size: 1.3rem;
  color: var(--color-text-muted);
  margin: 0;
}
.profile-activity-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.profile-activity-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 0;
  border-bottom: 1px dashed var(--color-border);
  font-size: 1.3rem;
  color: var(--color-text);
}
.profile-activity-list li:last-child {
  border-bottom: none;
}
.profile-activity-list li span {
  font-weight: 700;
  color: var(--color-primary);
}

/* ════════════════════════════════════════════════════════════════════════
   Stage 3a — Report Campaign button + modal (frontend only)
   ════════════════════════════════════════════════════════════════════════ */

/* Report flag button injected onto every .camp-card by JS.
   Bottom-right of the card image — keeps clear of the Urgent badge (top-right)
   and the category tag (top-left). */
.camp-card-media { position: relative; }
.camp-report-btn {
  position: absolute;
  bottom: 0.8rem;
  right: 0.8rem;
  width: 3.2rem;
  height: 3.2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 50%;
  background: rgba(15, 23, 42, 0.45);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
  cursor: pointer;
  opacity: 0.85;
  transition: background 0.18s ease, color 0.18s ease, opacity 0.18s ease, transform 0.18s ease;
  z-index: 2;
}
.camp-report-btn svg {
  width: 1.6rem;
  height: 1.6rem;
}
.camp-report-btn:hover,
.camp-report-btn:focus-visible {
  background: var(--color-danger);
  color: #fff;
  opacity: 1;
  transform: scale(1.06);
  outline: none;
}

/* Modal */
.report-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.55);
  z-index: 400;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.6rem;
}
/* Critical: HTML's [hidden] would normally set display:none, but the
   display:flex above overrides it. Re-assert display:none for [hidden]
   so the overlay doesn't sit invisibly on top of the page blocking clicks. */
.report-overlay[hidden] {
  display: none;
}
.report-modal {
  position: relative;
  width: min(46rem, 100%);
  max-height: 90vh;
  overflow-y: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--r-lg);
  padding: 2.4rem 2.4rem 2rem;
  box-shadow: var(--shadow-xl);
}
.report-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 3.2rem;
  height: 3.2rem;
  border: none;
  background: transparent;
  border-radius: 50%;
  font-size: 2.4rem;
  line-height: 1;
  color: var(--color-text-muted);
  cursor: pointer;
  transition: background 0.18s ease;
}
.report-close:hover {
  background: var(--color-bg-deep);
  color: var(--color-text);
}
.report-modal h3 {
  font-size: 1.8rem;
  font-weight: 700;
  margin: 0 0 0.6rem;
  color: var(--color-text);
}
.report-sub {
  font-size: 1.3rem;
  color: var(--color-text-muted);
  margin: 0 0 1.6rem;
  line-height: 1.5;
}
.report-sub strong {
  display: block;
  margin-top: 0.4rem;
  color: var(--color-text);
  font-weight: 700;
}

/* Segmented control: Campaign / User toggle inside the report modal */
.report-segmented {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.4rem;
  padding: 0.4rem;
  background: var(--color-bg-deep);
  border-radius: var(--r);
  margin-bottom: 1.6rem;
}
.report-seg-btn {
  border: none;
  background: transparent;
  padding: 0.8rem 1rem;
  font-family: inherit;
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--color-text-muted);
  border-radius: calc(var(--r) - 0.4rem);
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease;
}
.report-seg-btn:hover {
  color: var(--color-text);
}
.report-seg-btn.is-active {
  background: var(--color-surface);
  color: var(--color-primary);
  box-shadow: var(--shadow-sm);
}
.report-form label {
  display: block;
  font-size: 1.2rem;
  font-weight: 600;
  margin: 1.2rem 0 0.5rem;
  color: var(--color-text);
}
.report-form label small {
  color: var(--color-text-light);
  font-weight: 500;
}
.report-form select,
.report-form textarea {
  width: 100%;
  padding: 1rem 1.2rem;
  border: 1.5px solid var(--color-border);
  border-radius: var(--r);
  background: var(--color-surface);
  color: var(--color-text);
  font-family: inherit;
  font-size: 1.4rem;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.report-form select:focus,
.report-form textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-glow);
}
.report-form textarea {
  resize: vertical;
  min-height: 9rem;
}
.report-actions {
  display: flex;
  gap: 1rem;
  justify-content: flex-end;
  margin-top: 2rem;
}
.report-success {
  margin-top: 1.6rem;
  padding: 1rem 1.2rem;
  background: var(--color-success-light);
  color: var(--color-success-dark);
  border: 1px solid var(--color-success-border);
  border-radius: var(--r);
  font-size: 1.3rem;
  font-weight: 600;
}
@media (max-width: 520px) {
  .report-modal {
    padding: 2rem 1.6rem 1.6rem;
  }
  .report-actions {
    flex-direction: column-reverse;
  }
  .report-actions .btn {
    width: 100%;
  }
}

/* ════════════════════════════════════════════════════════════════════════
   X / Twitter-style Profile  (banner + view mode + in-place edit toggle)
   Lives at the end so it cleanly overrides legacy .profile-card layout
   without needing !important. Deletes that the old .profile-header
   flex-wrap and .profile-display-name placeholder italic — both replaced
   by the view-mode identity stack below.
   ════════════════════════════════════════════════════════════════════════ */

#profile.section { padding-top: 0; }

/* X-style profile hero — rebuilt with natural flow + negative-margin avatar
   instead of absolute positioning. The old absolute approach pushed the
   avatar off-screen on narrow viewports because the containing block math
   broke when the section width changed. Now everything is in normal flow:
     banner image → identity column → avatar lifted up with margin-top: -6rem
   so it overlaps the banner cleanly at every width. */
.profile-hero {
  position: relative;
  padding: 0;
  overflow: hidden;
}
.profile-banner-image {
  height: 16rem;
  /* The gradient is the fallback when no banner has been uploaded. PHP injects
     an inline background-image over it once user_profiles.banner_path is set,
     and the picker previews one the same way before saving — so the sizing
     below has to be here rather than inline at either call site. */
  background: linear-gradient(135deg, #1e3a8a 0%, var(--color-primary) 55%, #60a5fa 100%);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.profile-edit-toggle {
  position: absolute;
  top: 1.4rem;
  right: 1.4rem;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1.4rem;
  border: 1.5px solid rgba(255, 255, 255, 0.65);
  border-radius: 9999px;
  background: rgba(15, 23, 42, 0.4);
  color: #fff;
  font-family: inherit;
  font-size: 1.25rem;
  font-weight: 700;
  cursor: pointer;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: background 0.18s, transform 0.15s;
}
.profile-edit-toggle:hover { background: rgba(15, 23, 42, 0.6); transform: translateY(-1px); }
.profile-edit-toggle svg   { width: 1.5rem; height: 1.5rem; }

.profile-identity {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 0 2.4rem 2rem;
}
.profile-avatar-frame {
  width: 11rem;
  height: 11rem;
  margin-top: -5.5rem;   /* lift half the avatar over the banner */
  border-radius: 50%;
  background: var(--color-surface);
  padding: 0.4rem;
  box-shadow: 0 4px 14px rgba(15, 23, 42, 0.18);
  align-self: flex-start;
  box-sizing: border-box;
}
.profile-avatar-frame img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}
.profile-view-name {
  margin: 0.6rem 0 0;
  font-size: 2.2rem;
  font-weight: 800;
  color: var(--color-text);
  letter-spacing: -0.01em;
}
.profile-identity .profile-role-badge {
  align-self: flex-start;
  margin: 0;
}
.profile-view-bio {
  font-size: 1.4rem;
  line-height: 1.55;
  color: var(--color-text);
  margin: 0.4rem 0 0;
  white-space: pre-wrap;
}
.profile-view-bio-empty {
  color: var(--color-text-muted);
  font-style: italic;
}

/* Edit form lives in its own #profile-edit section now (X-style sub-page).
   The old in-place .is-editing toggle CSS was deleted. */
.profile-edit-card {
  padding: 2.4rem;
}
.profile-edit-form {
  display: block;
}
/* X/Twitter-style header: a full-bleed banner strip with the avatar overlapping
   its lower-left, so the picker previews both right where they will appear. The
   negative margins bleed the strip to the card's padding edges (the card pads
   2.4rem) so it reads as the profile header, not a form field. */
.profile-edit-media {
  margin: -2.4rem -2.4rem 2rem;
}
.profile-edit-banner {
  position: relative;
  border-top-left-radius: var(--radius);
  border-top-right-radius: var(--radius);
}
.profile-edit-avatar {
  display: flex;
  align-items: flex-end;
  gap: 1.2rem;
  padding: 0 2.4rem;
  margin-top: -5rem;   /* lift half the 11rem avatar over the banner */
}
.profile-edit-avatar .profile-role-badge {
  margin-bottom: 0.8rem;
}
.profile-edit-fields {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.profile-edit-fields label {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--color-text);
}
.profile-edit-fields input,
.profile-edit-fields textarea {
  width: 100%;
  padding: 1.1rem 1.4rem;
  border: 1.5px solid var(--color-border);
  border-radius: 1.2rem;
  font-family: inherit;
  font-size: 1.4rem;
  color: var(--color-text);
  background: var(--color-surface);
}
.profile-edit-fields textarea { min-height: 12rem; resize: vertical; }
.profile-edit-fields input:focus,
.profile-edit-fields textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.14);
}
.profile-edit-actions {
  display: flex;
  gap: 1rem;
  margin-top: 1.4rem;
}
.profile-edit-actions .btn { flex: 1; }
@media (max-width: 720px) {
  .profile-edit-form { grid-template-columns: 1fr; gap: 1.6rem; }
  .profile-edit-actions { flex-direction: column-reverse; }
}

.profile-banner-edit-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1.2rem;
  border: 1px dashed var(--color-border);
  border-radius: 9999px;
  background: var(--color-bg-deep);
  color: var(--color-text-muted);
  font-family: inherit;
  font-size: 1.15rem;
  font-weight: 600;
  /* Was cursor:not-allowed + opacity:.7 from when this was a disabled
     "Coming soon" button. It is a working <label> driving a file input now, so
     it has to look and behave like one. */
  cursor: pointer;
  transition: background var(--t), border-color var(--t), color var(--t);
}
.profile-banner-edit-btn:hover {
  background: var(--color-primary-light);
  border-color: var(--color-primary);
  color: var(--color-primary);
}
.profile-banner-edit-btn svg { width: 1.4rem; height: 1.4rem; }

/* Overlay variant, sitting on top of the banner image in the editor. Glass pill
   over the photo rather than the dashed grey chip, which was designed to sit on
   the card background. */
.profile-banner-edit-btn--overlay {
  position: absolute;
  top: 1.2rem;
  right: 1.2rem;
  z-index: 2;
  border: 1.5px solid rgba(255, 255, 255, 0.65);
  background: rgba(15, 23, 42, 0.42);
  color: #fff;
  font-weight: 700;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.profile-banner-edit-btn--overlay:hover {
  background: rgba(15, 23, 42, 0.62);
  border-color: rgba(255, 255, 255, 0.85);
  color: #fff;
}

@media (max-width: 600px) {
  .profile-banner-image { height: 13rem; }
  .profile-avatar-frame {
    width: 9rem;
    height: 9rem;
    margin-top: -4.5rem;
  }
  .profile-view-name { font-size: 1.8rem; }
  .profile-identity { padding: 0 1.6rem 1.6rem; }
  .profile-edit-toggle { top: 1rem; right: 1rem; padding: 0.55rem 1.1rem; font-size: 1.15rem; }
  .profile-edit-actions { flex-direction: column-reverse; }
}

html[data-theme="dark"] .profile-avatar-frame { background: var(--color-surface); }
html[data-theme="dark"] .profile-edit-toggle { background: rgba(2, 6, 23, 0.55); }

/* ════════════════════════════════════════════════════════════════════════
   Full-screen sub-page mode (Twitter / X / Instagram pattern)
   When `body.in-subpage` is set (by switchSection on any data-back section)
   the dashboard chrome — top header + bottom bar — hides. The active
   section fills the viewport, scrolls internally, and the sticky back bar
   below is the only top control.
   ════════════════════════════════════════════════════════════════════════ */
body.in-subpage .site-header.auth-only,
body.in-subpage .bottom-nav {
  display: none !important;          /* Required: these have higher-specificity
                                        @media display rules elsewhere. Single
                                        case where !important is genuinely
                                        unavoidable without restructuring all
                                        the show/hide media queries. */
}
body.in-subpage .main-content {
  padding-top: 0;
  padding-bottom: 0;                  /* no bottom-bar to clear */
}
body.in-subpage .section.active {
  min-height: 100dvh;
}

/* ════════════════════════════════════════════════════════════════════════
   Sub-section back bar (Twitter/X pattern)
   Injected by JS into every <section data-back="…"> on load. Sticky at the
   top of the section so it follows the user as they scroll inside it.
   ════════════════════════════════════════════════════════════════════════ */
.section-back-bar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 1.2rem;
  /* Full-bleed like X's sticky header: the negative side margins cancel
     .main-content's 2.4rem padding so the bar spans edge to edge, and the
     matching horizontal padding keeps its contents lined up with the section
     below. Mobile mirrors this against the 1.6rem padding at <=768px. */
  padding: 1.2rem 2.4rem;
  /* Painted in the page colour, not a white card, so the bar reads as part of
     the page rather than a container sitting on it — while still hiding content
     that scrolls up underneath it. A hairline rule is the only structure. */
  background: var(--bg);
  border-bottom: 1px solid var(--color-border);
  /* Bottom margin gives the first card room to breathe — it sat flush against
     the bar before. */
  margin: -2.4rem -2.4rem 3.6rem;
}
@media (max-width: 768px) {
  .section-back-bar {
    padding: 1.1rem 1.6rem;
    margin: -1.6rem -1.6rem 3rem;
  }
}
.section-back-heading {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}
.section-back-subtitle {
  font-size: 1.25rem;
  color: var(--color-text-muted);
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.section-back-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 4rem;
  height: 4rem;
  margin-left: -0.4rem;   /* let the round hover-disc sit near the edge like X */
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--color-text);
  cursor: pointer;
  transition: background 0.15s, transform 0.1s;
}
/* A soft neutral disc that appears on hover, not a filled chip — the X look. */
.section-back-btn:hover  { background: rgba(15, 23, 42, 0.08); }
.section-back-btn:active { background: rgba(15, 23, 42, 0.14); transform: scale(0.93); }
.section-back-btn svg    { width: 2rem; height: 2rem; }
.section-back-title {
  font-size: 2rem;
  font-weight: 800;
  color: var(--color-text);
  letter-spacing: -0.02em;
  line-height: 1.1;
}

/* The bar background is var(--bg), which already inverts for dark mode, so only
   the divider needs softening there. */
html[data-theme="dark"] .section-back-bar {
  border-bottom-color: rgba(148, 163, 184, 0.18);
}
html[data-theme="dark"] .section-back-btn:hover  { background: rgba(255, 255, 255, 0.1); }
html[data-theme="dark"] .section-back-btn:active { background: rgba(255, 255, 255, 0.16); }

/* ════════════════════════════════════════════════════════════════════════
   Settings sub-page (Phase 6.0.a)
   Single source of truth. Row list with icon + body + state/chevron.
   ════════════════════════════════════════════════════════════════════════ */
.settings-list {
  max-width: 64rem;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.settings-row {
  display: flex;
  align-items: center;
  gap: 1.4rem;
  padding: 1.6rem 1.8rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 1.4rem;
  text-align: left;
  font-family: inherit;
  color: var(--color-text);
  cursor: pointer;
  transition: border-color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
  width: 100%;
}
.settings-row:hover:not(.is-disabled) {
  border-color: var(--color-primary);
  transform: translateY(-1px);
  box-shadow: 0 8px 22px rgba(15, 23, 42, 0.06);
}
.settings-row.is-disabled {
  cursor: not-allowed;
  opacity: 0.7;
}
.settings-row-icon {
  width: 4.4rem;
  height: 4.4rem;
  border-radius: 1.2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-primary-light);
  color: var(--color-primary);
  flex-shrink: 0;
}
.settings-row-icon svg { width: 2rem; height: 2rem; }
.settings-row-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}
.settings-row-body strong {
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--color-text);
}
.settings-row-body small {
  font-size: 1.2rem;
  color: var(--color-text-muted);
  line-height: 1.4;
}
.settings-row-state {
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--color-primary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.settings-row-soon {
  font-size: 1.1rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  background: var(--color-warning-light);
  color: var(--color-warning);
  padding: 0.4rem 0.9rem;
  border-radius: 9999px;
}
.settings-row-chevron {
  width: 1.6rem;
  height: 1.6rem;
  color: var(--color-text-muted);
  flex-shrink: 0;
}

/* Sun/moon icon swap (replaces deleted .sidebar-theme-toggle rules). */
[data-theme-toggle] .theme-sun { display: none; }
html[data-theme="dark"] [data-theme-toggle] .theme-moon { display: none; }
html[data-theme="dark"] [data-theme-toggle] .theme-sun { display: block; }

html[data-theme="dark"] .settings-row {
  background: var(--color-surface);
  border-color: var(--color-border);
}
html[data-theme="dark"] .settings-row-icon {
  background: rgba(96, 165, 250, 0.14);
}

/* ════════════════════════════════════════════════════════════════════════
   Sidebar account switcher (Phase 6.0.a extension)
   Tiny caret on the user card opens a panel listing the current account
   plus an "Add an account" link. Multi-account list rows are rendered by
   PHP once /php/auth/sessions.php exists — no fake rows in the meantime.
   ════════════════════════════════════════════════════════════════════════ */
.sidebar-user-wrap {
  position: relative;
}
.sidebar-account-toggle {
  position: absolute;
  top: 1.4rem;
  right: 1rem;
  width: 2.8rem;
  height: 2.8rem;
  border-radius: 50%;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, transform 0.18s;
  padding: 0;
}
.sidebar-account-toggle:hover {
  background: var(--color-bg-deep);
  border-color: var(--color-primary);
  color: var(--color-primary);
}
.sidebar-account-toggle svg { width: 1.4rem; height: 1.4rem; transition: transform 0.2s ease; }
.sidebar-account-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }

.sidebar-account-panel {
  margin: 0.6rem 0.8rem 0.8rem;
  padding: 0.6rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 1.2rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.06);
}
.sidebar-account-panel[hidden] { display: none; }

.sidebar-account-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.8rem 1rem;
  border-radius: 0.9rem;
}
.sidebar-account-row.is-current {
  background: var(--color-primary-light);
}
/* Switch-account rows are submit buttons styled to match the account rows. */
.sidebar-account-switch-form { margin: 0; }
button.sidebar-account-row {
  width: 100%;
  border: 1px solid var(--color-border);
  background: transparent;
  cursor: pointer;
  text-align: left;
  font: inherit;
  transition: background 0.15s, border-color 0.15s;
}
button.sidebar-account-row:hover {
  background: var(--color-primary-light);
  border-color: var(--color-primary);
}
html[data-theme="dark"] button.sidebar-account-row:hover {
  background: rgba(96, 165, 250, 0.12);
}
.sidebar-account-avatar {
  width: 3.2rem;
  height: 3.2rem;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}
.sidebar-account-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.sidebar-account-info strong {
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sidebar-account-info small {
  font-size: 1.05rem;
  color: var(--color-text-muted);
}
.sidebar-account-check {
  width: 1.6rem;
  height: 1.6rem;
  color: var(--color-primary);
  flex-shrink: 0;
}

.sidebar-account-add {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.9rem 1rem;
  border-radius: 0.9rem;
  text-decoration: none;
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--color-primary);
  background: transparent;
  border: 1px dashed var(--color-border);
  transition: background 0.15s, border-color 0.15s;
}
.sidebar-account-add:hover {
  background: var(--color-primary-light);
  border-color: var(--color-primary);
}
.sidebar-account-add-icon {
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.sidebar-account-add-icon svg { width: 1.2rem; height: 1.2rem; }

html[data-theme="dark"] .sidebar-account-row.is-current {
  background: rgba(96, 165, 250, 0.14);
}
html[data-theme="dark"] .sidebar-account-add:hover {
  background: rgba(96, 165, 250, 0.12);
}

/* Final dark-mode sweep.
   This stays at the end because newer profile, activity, people, messages, and
   settings blocks define light backgrounds after the first dark-mode section. */
html[data-theme="dark"] body,
html[data-theme="dark"] .layout,
html[data-theme="dark"] .main-content,
html[data-theme="dark"] .section,
html[data-theme="dark"] .dashboard-section {
  background: var(--color-bg);
  color: var(--color-text);
}

html[data-theme="dark"] .card,
html[data-theme="dark"] .dash-card,
html[data-theme="dark"] .profile-card,
html[data-theme="dark"] .profile-summary-card,
html[data-theme="dark"] .profile-extra-card,
html[data-theme="dark"] .wallet-card,
html[data-theme="dark"] .campaign-form,
html[data-theme="dark"] .people-panel,
html[data-theme="dark"] .person-modal,
html[data-theme="dark"] .messages-shell,
html[data-theme="dark"] .chat-panel,
html[data-theme="dark"] .activity-total-card,
html[data-theme="dark"] .activity-ledger,
html[data-theme="dark"] .bill-preview,
html[data-theme="dark"] .bill-paper,
html[data-theme="dark"] .settings-card,
html[data-theme="dark"] .settings-row,
html[data-theme="dark"] .sidebar-account-panel,
html[data-theme="dark"] .dash-notif-panel,
html[data-theme="dark"] .guest-action-card,
html[data-theme="dark"] .discover-toolbar,
html[data-theme="dark"] .discover-filters,
html[data-theme="dark"] .discover-advanced,
html[data-theme="dark"] .discover-empty,
html[data-theme="dark"] .modal {
  background: rgba(15, 23, 42, 0.92);
  border-color: rgba(148, 163, 184, 0.22);
  color: var(--color-text);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.24);
}

html[data-theme="dark"] .activity-ledger-row,
html[data-theme="dark"] .activity-filter-tabs,
html[data-theme="dark"] .activity-filter-tabs button.active,
html[data-theme="dark"] .recent-donation,
html[data-theme="dark"] .urgent-item,
html[data-theme="dark"] .featured-camp,
html[data-theme="dark"] .camp-card,
html[data-theme="dark"] .people-card,
html[data-theme="dark"] .people-search,
html[data-theme="dark"] .people-filter-tabs,
html[data-theme="dark"] .person-profile-facts span,
html[data-theme="dark"] .message-thread,
html[data-theme="dark"] .messages-list,
html[data-theme="dark"] .payment-method-details,
html[data-theme="dark"] .payment-method-fee,
html[data-theme="dark"] .modal-confirm-breakdown,
html[data-theme="dark"] .modal-confirm-note,
html[data-theme="dark"] .sidebar-account-row.is-current {
  background: rgba(2, 6, 23, 0.52);
  border-color: rgba(148, 163, 184, 0.18);
  color: var(--color-text);
}

/* Split out of the panel block above: the compose field and the message
   search are real controls. They inherited the panels' rgba(148,163,184,.18)
   edge, which lands at 1.32:1 once blended over this fill. Same fill and
   text as the panels — only the border changes. */
html[data-theme="dark"] .messages-search,
html[data-theme="dark"] .chat-compose input {
  background: rgba(2, 6, 23, 0.52);
  border-color: var(--color-border-control);
  color: var(--color-text);
}

html[data-theme="dark"] .activity-ledger-row:hover,
html[data-theme="dark"] .activity-ledger-row.active,
html[data-theme="dark"] .recent-donation:hover,
html[data-theme="dark"] .featured-camp:hover,
html[data-theme="dark"] .people-card:hover,
html[data-theme="dark"] .message-thread:hover,
html[data-theme="dark"] .message-thread.active,
html[data-theme="dark"] .settings-row:hover,
html[data-theme="dark"] .sidebar-account-add:hover,
html[data-theme="dark"] button.sidebar-account-row:hover {
  background: rgba(96, 165, 250, 0.12);
  border-color: rgba(96, 165, 250, 0.34);
}

html[data-theme="dark"] .activity-ledger-head h3,
html[data-theme="dark"] .activity-total-card strong,
html[data-theme="dark"] .activity-ledger-main strong,
html[data-theme="dark"] .activity-ledger-side strong,
html[data-theme="dark"] .bill-brand-row strong,
html[data-theme="dark"] .bill-meta-grid strong,
html[data-theme="dark"] .bill-lines strong,
html[data-theme="dark"] .camp-card-title,
html[data-theme="dark"] .urgent-meta strong,
html[data-theme="dark"] .urgent-progress-row strong,
html[data-theme="dark"] .featured-camp-body strong,
html[data-theme="dark"] .featured-camp-meta strong,
html[data-theme="dark"] .how-steps li strong,
html[data-theme="dark"] .trust-strip-head h3,
html[data-theme="dark"] .trust-item strong,
html[data-theme="dark"] .guest-unlock-list strong,
html[data-theme="dark"] .rd-meta strong,
html[data-theme="dark"] .rd-amount,
html[data-theme="dark"] .donor-meta strong,
html[data-theme="dark"] .profile-summary-value,
html[data-theme="dark"] .profile-extra-card h4,
html[data-theme="dark"] .profile-security-list li,
html[data-theme="dark"] .profile-activity-list li,
html[data-theme="dark"] .settings-row-title,
html[data-theme="dark"] .settings-row-body strong,
html[data-theme="dark"] .people-card-text strong,
html[data-theme="dark"] .person-profile-title h3,
html[data-theme="dark"] .message-thread-body strong,
html[data-theme="dark"] .chat-head strong {
  color: #f8fafc;
}

html[data-theme="dark"] .activity-total-card span,
html[data-theme="dark"] .activity-total-card small,
html[data-theme="dark"] .activity-ledger-main small,
html[data-theme="dark"] .activity-ledger-side small,
html[data-theme="dark"] .bill-brand-row small,
html[data-theme="dark"] .bill-meta-grid small,
html[data-theme="dark"] .bill-lines div,
html[data-theme="dark"] .bill-foot-note,
html[data-theme="dark"] .camp-card-desc,
html[data-theme="dark"] .camp-creator-name,
html[data-theme="dark"] .urgent-meta small,
html[data-theme="dark"] .urgent-progress-row span,
html[data-theme="dark"] .featured-camp-body small,
html[data-theme="dark"] .featured-camp-meta,
html[data-theme="dark"] .trust-item p,
html[data-theme="dark"] .guest-unlock-list small,
html[data-theme="dark"] .rd-meta small,
html[data-theme="dark"] .profile-summary-label,
html[data-theme="dark"] .profile-summary-card small,
html[data-theme="dark"] .profile-extra-note,
html[data-theme="dark"] .profile-empty,
html[data-theme="dark"] .settings-row-body span,
html[data-theme="dark"] .people-card-text small,
html[data-theme="dark"] .person-profile-title span,
html[data-theme="dark"] .person-profile-bio,
html[data-theme="dark"] .message-thread-body small,
html[data-theme="dark"] .message-time,
html[data-theme="dark"] .chat-head small {
  color: #cbd5e1;
}

html[data-theme="dark"] .bill-brand-row,
html[data-theme="dark"] .bill-meta-grid,
html[data-theme="dark"] .bill-total-line,
html[data-theme="dark"] .profile-security-list li,
html[data-theme="dark"] .profile-activity-list li,
html[data-theme="dark"] .chat-head,
html[data-theme="dark"] .chat-compose {
  border-color: rgba(148, 163, 184, 0.18);
}

/* --- Batch 4 additions (a11y + mobile clearance + tap targets) --- */

/* Bottom nav sits fixed on mobile — every donor section needs bottom padding
   so the FAB doesn't overlap the last card while scrolling. */
@media (max-width: 768px) {
  body.is-auth .section.active {
    padding-bottom: calc(9.6rem + env(safe-area-inset-bottom, 0));
  }
}

/* --- Batch 3 additions --- */

/* Recent-donations empty state: replaces the single grey sentence with a
   real onboarding block (3-step how-it-works + primary CTA). */
.recent-donation-empty {
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
  padding: 2rem 1.6rem;
  text-align: left;
  list-style: none;
}
.recent-donation-empty > strong {
  font-size: 1.6rem;
  color: var(--color-text-navy, #0f172a);
}
.recent-donation-empty > p {
  color: var(--color-text-muted, #64748b);
  font-size: 1.35rem;
  line-height: 1.5;
  margin: 0;
}
.how-mini {
  list-style: none;
  margin: 0.4rem 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}
.how-mini li {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.2rem;
  border-radius: 0.9rem;
  background: rgba(37, 99, 235, 0.05);
  color: var(--color-text-navy, #0f172a);
  font-size: 1.3rem;
}
.how-mini li span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 999px;
  background: var(--color-primary, #2563eb);
  color: #fff;
  font-weight: 800;
  font-size: 1.2rem;
  flex: 0 0 auto;
}
.recent-donation-empty .btn { align-self: flex-start; margin-top: 0.4rem; }

html[data-theme="dark"] .how-mini li {
  background: rgba(96, 165, 250, 0.12);
  color: #e2e8f0;
}
html[data-theme="dark"] .recent-donation-empty > strong { color: #f1f5f9; }
html[data-theme="dark"] .recent-donation-empty > p { color: #cbd5e1; }

/* Logout is a POST form so it can carry a CSRF token (see php/auth/logout.php).
   display:contents removes the form from the box tree entirely, so the button
   inside stays a direct flex child of .sidebar-nav and the sidebar lays out
   exactly as it did when this was a bare <button>. */
.logout-form {
  display: contents;
}

/* ── Account rows in Settings ──────────────────────────────────────────────
   Account switching moved out of the sidebar drawer panel and into Settings.
   These reuse .settings-row, so they only need the avatar and the wrapper that
   makes a <form>-wrapped row lay out like the plain <a> rows beside it. */
.settings-account-form {
  display: contents;
}
.settings-account-avatar {
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  border: 1px solid var(--color-border);
}
.settings-row.is-current-account {
  cursor: default;
}
.settings-row.is-current-account .settings-row-chevron {
  color: var(--color-success);
}

/* ── Owner controls on a campaign card ────────────────────────────────────
   A creator can withdraw their own campaign. Styled as a quiet destructive
   action, not a primary one: it sits where Donate sits on other people's
   cards, so it must not read as the main thing to press. */
.camp-delete-form { display: contents; }
.camp-delete {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1.4rem;
  border: 1px solid var(--color-danger);
  border-radius: 9999px;
  background: transparent;
  color: var(--color-danger);
  font-family: inherit;
  font-size: 1.3rem;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--t), color var(--t);
}
.camp-delete svg { width: 1.5rem; height: 1.5rem; }
.camp-delete:hover { background: var(--color-danger); color: #fff; }

/* ── Comment feed in the campaign modal ── */
.cm-comment-row {
  display: flex;
  gap: 1rem;
  padding: 1.2rem 0;
  border-bottom: 1px solid var(--color-border);
}
.cm-comment-row:last-child { border-bottom: 0; }
.cm-comment-avatar {
  width: 3.6rem;
  height: 3.6rem;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}
.cm-comment-body { min-width: 0; flex: 1; }
.cm-comment-head {
  display: flex;
  align-items: baseline;
  gap: 0.8rem;
  margin-bottom: 0.3rem;
}
.cm-comment-head strong { font-size: 1.4rem; color: var(--color-text); }
.cm-comment-head small { font-size: 1.2rem; color: var(--color-text-muted); }
.cm-comment-body p {
  margin: 0;
  font-size: 1.4rem;
  line-height: 1.5;
  color: var(--color-text);
  overflow-wrap: anywhere;
}

/* ── Notifications section ────────────────────────────────────────────────
   The full history, reached from "View all notifications". Rows are the same
   partial the bell dropdown uses, so the two never drift apart. */
.notif-group-label {
  font-size: 1.3rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin: 2rem 0 0.8rem;
}
.notif-group-label:first-of-type { margin-top: 0.8rem; }
.notif-full-list {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.notif-mark-all { display: flex; justify-content: flex-end; margin-bottom: 0.4rem; }

/* ── Donors list in the campaign modal ── */
.cm-donor-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 0;
  border-bottom: 1px solid var(--color-border);
}
.cm-donor-row:last-child { border-bottom: 0; }
.cm-donor-avatar {
  width: 3.4rem; height: 3.4rem; border-radius: 50%;
  object-fit: cover; flex-shrink: 0;
}
.cm-donor-body { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.cm-donor-body strong { font-size: 1.4rem; color: var(--color-text); }
.cm-donor-body small { font-size: 1.2rem; color: var(--color-text-muted); }
.cm-donor-amount { font-size: 1.4rem; font-weight: 700; color: var(--color-primary); flex-shrink: 0; }
/* The viewer's own contribution, so it is findable in a long list. */
.cm-donor-row.is-you { background: var(--color-primary-light); border-radius: var(--r); padding-inline: 1rem; }

/* ── Bell in the top nav ───────────────────────────────────────────────────
   Moved out of the dashboard header so it is reachable from every section,
   not just the dashboard, and so it stops being cropped on narrow screens.
   The wrap must stay positioned: the dropdown is absolute against it. */
.site-header-inner .dash-bell-wrap {
  position: relative;
  margin-left: auto;
  flex-shrink: 0;
}
.site-header-inner .dash-bell-wrap + .theme-toggle { margin-left: 0.4rem; }

/* Breathing room for the nav row and its links — items were sitting shoulder
   to shoulder with no space to read them apart. */
.site-header-inner {
  gap: 1.2rem;
  padding-inline: 2rem;
}
.site-header-nav {
  gap: 0.6rem;
}
.site-header-nav .site-nav-link {
  padding: 0.7rem 1.2rem;
  border-radius: 9999px;
}
.site-header-nav .site-nav-link:hover {
  background: var(--color-primary-light);
}

/* Centred under the bell, not pinned to one of its edges.

   The bell used to live at the far right of the dashboard header, so the panel
   was right-anchored; a later rule left-anchored it under 900px to stop it
   running off screen. Now the bell sits beside the user chip near the LEFT, and
   both of those look wrong — the card hangs off to one side of the button that
   opened it. Centring keeps the panel visually attached to the bell at every
   width above the phone sheet.

   translateX(-50%) does the centring, so it has to be repeated in the open
   state or the entrance transition would drop it and the panel would jump. */
@media (min-width: 521px) {
  .site-header-inner .dash-notif-panel {
    left: 50%;
    right: auto;
    transform: translateX(-50%) translateY(-6px) scale(0.98);
  }
  .site-header-inner .dash-bell-wrap.open .dash-notif-panel {
    transform: translateX(-50%) translateY(0) scale(1);
  }
  /* Room to breathe: the rows sat tight against the card edges and against
     each other, which made a three-line notification hard to read. */
  .site-header-inner .dash-notif-panel .dash-notif-hit {
    padding: 1.6rem 2rem;
    gap: 1.4rem;
  }
  .site-header-inner .dash-notif-panel .dash-notif-head,
  .site-header-inner .dash-notif-panel .dash-notif-foot {
    padding-inline: 2rem;
  }
  .site-header-inner .dash-notif-panel .dash-notif-head {
    padding-block: 1.6rem;
  }
}

/* Bell sits next to the user chip, with room around it rather than jammed
   against the name.

   The chip carries `margin-right: auto` (the --user-lead variant uses it to
   push the nav to the far right). That auto margin absorbs all the free space
   in the flex row, so the bell was landing 237px away from the name instead of
   beside it. The auto margin moves onto the bell: chip and bell stay together
   on the left, everything after them still gets pushed right. Matching the
   Three separate rules set that auto margin, the strongest being
   `body.is-auth .site-header.auth-only .site-header-user` — so the override
   has to carry the same `body.is-auth` prefix to outrank it. */
body.is-auth .site-header.auth-only .site-header-user,
.site-header.site-header--user-lead.auth-only .site-header-user,
.site-header--user-lead .site-header-user { margin-right: 0; }
.site-header-inner .dash-bell-wrap {
  margin-left: 0.8rem;
  margin-right: auto;
}

/* Why the two provider options are disabled, said once, under them. */
.payment-method-note {
  display: flex;
  align-items: flex-start;
  gap: 0.8rem;
  margin: 0 0 1.2rem;
  padding: 1rem 1.2rem;
  background: var(--color-warning-light);
  border: 1px solid var(--color-warning);
  border-radius: var(--r);
  font-size: 1.3rem;
  line-height: 1.5;
  color: var(--color-text);
}
.payment-method-note svg { width: 1.8rem; height: 1.8rem; flex-shrink: 0; color: var(--color-warning); }
.payment-method-note a { color: var(--color-primary); font-weight: 600; }

/* The theme toggle is a settings row control now, not a floating header button. */
.settings-row .theme-toggle { flex-shrink: 0; margin-left: auto; }

/* ── Printing ──────────────────────────────────────────────────────────────
   The Print button beside a receipt used to hand the entire dashboard to the
   printer. js/userhome.js clones the receipt into #print-root at <body> level
   first; these rules blank out everything else so only that clone reaches the
   page. `display: none` on the siblings rather than `visibility: hidden` — a
   hidden element still reserves its box, which produced pages of blank paper
   before the receipt appeared. */
@media print {
  @page { margin: 14mm; }

  body.is-printing > *:not(#print-root) { display: none !important; }

  body.is-printing {
    background: #fff;
    display: block;
    min-height: 0;
  }

  #print-root {
    display: block;
    width: 100%;
    padding: 0;
    margin: 0;
  }

  /* Backgrounds and tints are dropped by default when printing; the receipt
     reads fine without them, so rather than forcing colour adjustment we make
     sure the borders that carry the structure stay visible. */
  #print-root .bill-paper {
    width: 100%;
    max-width: none;
    margin: 0;
    border: 1px solid #94a3b8;
    border-radius: 0;
    box-shadow: none;
    background: #fff;
    color: #000;
    page-break-inside: avoid;
  }

  /* Nothing interactive belongs on paper. */
  #print-root .bill-actions,
  #print-root button { display: none !important; }
}

/* Dark mode must not follow the receipt onto white paper. */
@media print {
  html[data-theme="dark"] #print-root .bill-paper,
  html[data-theme="dark"] #print-root .bill-paper * {
    background: #fff !important;
    color: #000 !important;
    border-color: #94a3b8 !important;
  }
}

/* Empty state in the notifications dropdown.
   A populated row draws its padding from .dash-notif-hit (the <a>/<button>
   inside it). The "No notifications" row has no hit target, so it had none at
   all and its text started at the very edge of the card while every real row —
   and the "Notifications" heading — started 2rem in. Same padding here so the
   left edge lines up whichever state the panel is in. */
.dash-notif-empty .dash-notif-text {
  padding: 1.6rem 2rem;
}

/* ── Receipt gets the full width of the section ────────────────────────────
   Activity & Bills was a two-column grid: the ledger on the left and the
   receipt squeezed into a 34rem sticky column on the right. A receipt is a
   document — its parties sit side by side, its facts are a two-column grid and
   its money column is right-aligned — and none of that survives at 34rem. On a
   desktop window the receipt was narrower than the printed page it represents.

   One column at every width: the ledger, then the receipt full width beneath
   it. Non-sticky, because a full-width panel that follows the scroll would
   cover the list it belongs to. */
.activity-bills-layout {
  grid-template-columns: minmax(0, 1fr);
}
.bill-preview {
  position: static;
  width: 100%;
}
/* The 900px override that flattened the grid on small screens is now what the
   base rule already does, and the 520px reorder would put the receipt above
   the ledger it is selected from. Both are redundant. */
@media (max-width: 520px) {
  .bill-preview { order: 0; }
}

/* ── Sort dropdown ─────────────────────────────────────────────────────────
   js/userhome.js replaces the native <select> with a button + listbox: an
   <option> list is drawn by the operating system and no CSS reaches it, so the
   toolbar's pill controls sat above a square grey Windows menu set in a
   different font. The <select> remains the source of truth, so it is hidden
   rather than removed. */
#discover-sort.is-enhanced {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.sort-select-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.8rem;
  background: none;
  border: 0;
  padding: 0 1.2rem 0 0;
  min-height: 4.4rem;
  font-family: inherit;
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--color-text);
  cursor: pointer;
}
.sort-select-btn:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 3px;
  border-radius: 0.8rem;
}
.sort-select-chev {
  width: 1.5rem;
  height: 1.5rem;
  flex-shrink: 0;
  color: var(--color-text-muted);
  transition: transform 0.18s ease;
}
.discover-sort-wrap.is-open .sort-select-chev { transform: rotate(180deg); }
.discover-sort-wrap.is-open { border-color: var(--color-primary); }

.sort-select-menu {
  position: absolute;
  top: calc(100% + 0.8rem);
  right: 0;
  min-width: 22rem;
  list-style: none;
  margin: 0;
  padding: 0.6rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 1.4rem;
  box-shadow: 0 20px 44px rgba(15, 23, 42, 0.16);
  /* Above the campaign grid and the sticky toolbar it hangs from. */
  z-index: 40;
}
.sort-select-option {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 1rem 1.2rem;
  border-radius: 1rem;
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--color-text);
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease;
}
.sort-select-option:hover,
.sort-select-option:focus-visible {
  background: var(--color-primary-light);
  color: var(--color-primary);
  outline: none;
}
.sort-select-tick {
  width: 1.6rem;
  height: 1.6rem;
  flex-shrink: 0;
  /* Holds its own column so every label starts on the same left edge whether
     or not that row is the selected one. */
  opacity: 0;
  color: var(--color-primary);
}
.sort-select-option[aria-selected="true"] {
  color: var(--color-primary);
  font-weight: 700;
}
.sort-select-option[aria-selected="true"] .sort-select-tick { opacity: 1; }

/* On a phone the toolbar is a narrow stacked grid, so the menu takes the full
   width of its control instead of hanging off the right edge. */
@media (max-width: 768px) {
  .sort-select-menu { left: 0; right: 0; min-width: 0; }
}

/* ── Receipt fills the section ─────────────────────────────────────────────
   Full width was only half of it: the receipt still ended wherever its content
   ran out, so a short donation left a shallow strip of paper floating in a tall
   empty section. It now stands at least a screen tall, which is what a page you
   are about to print should look like. */
.bill-preview .bill-paper {
  min-height: calc(100svh - 16rem);
  display: flex;
  flex-direction: column;
}
/* The footnote sinks to the bottom of the sheet so the extra height opens up
   between the totals and the small print, not as a gap after the last line. */
.bill-preview .bill-foot-note {
  margin-top: auto;
}

/* ── Guest header: keep the auth pair with the burger ──────────────────────
   Both .site-header-auth and .site-header-burger carried `margin-left: auto`.
   Two auto margins in one flex row split the free space between them, so
   Log In / Sign Up Free floated in the middle of the header with a ~180px
   trench between them and the burger they belong beside. Only the first group
   pushes; the burger then sits directly after it at the right-hand edge. */
.site-header.guest-only .site-header-burger,
.site-header-burger { margin-left: 0; }
.site-header.guest-only .site-header-auth { margin-left: auto; }

/* ── Urgent badge on a featured campaign thumb ─────────────────────────────
   The thumb is 7.2rem square. A pill floated into its top-right corner had
   nowhere to go: at any legible size the word "Urgent" is wider than the space
   left beside the corner radius, so it hung over the edge of the image.

   As a band across the top of the thumb it cannot overflow at any text size,
   it reads as a label ON the image rather than a sticker beside it, and it
   follows the thumb's own top corner radii. */
.featured-camp-thumb .camp-urgent-badge {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  padding: 0.25rem 0.3rem;
  background: rgba(185, 28, 28, 0.94);
  color: #fff;
  font-size: 0.95rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border-radius: 1rem 1rem 0 0;
  box-shadow: none;
}
/* The pulsing dot is for the full-size card; at this scale it costs more width
   than it earns. */
.featured-camp-thumb .camp-urgent-badge::before {
  display: none;
}

/* ── Guest menu: a dropdown from the header, not a side drawer ─────────────
   The menu used to fly in from the right edge as a full-height panel, which
   reads as a separate screen and gives no sense of having come from the button
   that opened it. It now drops straight down from the header bar the burger
   sits in, anchored to the same edges, so the connection is obvious.

   Log In and Sign Up Free move inside it on narrow screens. They were being
   drawn twice — once in the header and again in the menu — which is why the
   header felt crowded next to the burger. Above 768px the header has room for
   them and the burger is hidden, so the pair stays inline there. */
.guest-drawer {
  position: fixed;
  top: 5.8rem;                 /* directly under the mobile header */
  left: 0;
  right: 0;
  bottom: auto;
  width: auto;
  max-height: calc(100svh - 5.8rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 1.2rem 1.6rem 2rem;
  border-radius: 0 0 1.8rem 1.8rem;
  border-bottom: 1px solid var(--color-border);
  /* Slides down from behind the header rather than in from the side. The
     header sits above it so the panel appears to emerge from underneath. */
  transform: translateY(-102%);
  transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1);
  box-shadow: 0 18px 40px rgba(15, 23, 42, 0.18);
  z-index: 90;
}
.guest-drawer.is-open {
  transform: translateY(0);
}
/* The header must paint over the panel as it slides out from under it. */
.site-header.guest-only {
  z-index: 95;
}
.guest-drawer-backdrop {
  /* Starts below the panel so a tap outside still closes it, but the dim never
     covers the header the menu belongs to. */
  top: 5.8rem;
  z-index: 85;
}

/* The panel has the header immediately above it — repeating the logo and a
   close button inside it is just clutter. */
.guest-drawer-head { display: none; }
.guest-drawer-nav { margin-top: 0; flex: 0 0 auto; }

@media (min-width: 769px) {
  /* Desktop keeps the inline pair; the burger is hidden at this width. */
  .guest-drawer { display: none; }
}

@media (max-width: 768px) {
  /* One home for Log In / Sign Up Free on narrow screens: the menu. */
  .site-header.guest-only .site-header-auth { display: none; }
  .site-header.guest-only .site-header-burger { margin-left: auto; }
}

/* The whole Sort pill opens the menu, not just the words in it.

   The button only wrapped the current value and the chevron, so the sort icon,
   the "SORT" label and every bit of padding around them were dead — the
   control looked like one pill and behaved like a small target inside it.
   Pressing the label was worse than dead: it is a <label for="discover-sort">,
   so it moved focus to a select that is now visually hidden.

   An overlay pinned to the wrapper makes the entire pill the hit area without
   reordering anything. It stops at the wrapper's edges, so it cannot sit over
   the menu, which is positioned below it. */
.sort-select-btn::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 9999px;
}

/* The panel was built as a full-height column: .guest-drawer is a flex column
   and .guest-drawer-nav took `flex: 1` to push the auth block to the bottom of
   the screen. As a dropdown it is only as tall as its contents, so that column
   had nothing to distribute — the auth block was shrunk by flex and its
   buttons spilled back over the links above them.

   Normal flow instead: each block is as tall as it needs to be and they stack
   in order. */
.guest-drawer {
  display: block;
}
.guest-drawer-nav {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.4rem;
}
.guest-drawer-auth {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  margin-top: 1.2rem;
  padding-top: 1.2rem;
}
.guest-drawer-link {
  justify-content: flex-start;
  width: 100%;
}

/* ── Full-page receipt view ────────────────────────────────────────────────
   Print used to go straight to the browser's print dialog, so the last look
   you got at the receipt was the panel inside the dashboard — and a print
   preview is the wrong place to find out you selected the wrong bill. The
   receipt opens at full size first, with Print and Close on a bar above it. */
.bill-fullpage {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
}
.bill-fullpage-bar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1.2rem 2rem;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}
.bill-fullpage-bar strong {
  font-size: 1.6rem;
  margin-right: auto;
}
.bill-fullpage-sheet {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 2.4rem;
  display: flex;
  justify-content: center;
  align-items: stretch;   /* let the receipt fill the height like a real page */
}
.bill-fullpage-sheet .bill-paper {
  width: 100%;
  max-width: 82rem;
  /* Fill the preview area so the receipt reads as a full sheet with its content
     at the top, instead of a short card floating in empty space. */
  min-height: 100%;
  height: fit-content;
  margin: 0 auto;
}

@media (max-width: 640px) {
  .bill-fullpage-bar { padding: 1rem 1.4rem; }
  .bill-fullpage-bar strong { font-size: 1.4rem; }
  .bill-fullpage-sheet { padding: 1.2rem; }
}

/* The bar belongs on screen, never on paper. */
@media print {
  .bill-fullpage-bar { display: none !important; }
}
/* The public build is a portfolio prototype, so sample activity must never be
   mistaken for live fundraising. This notice stays visible above every role's
   first section without competing with the primary navigation. */
.portfolio-preview-note {
  width: 100%;
  min-width: 0;
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  margin: 0 0 1.6rem;
  padding: 1.1rem 1.4rem;
  border: 1px solid #bfdbfe;
  border-radius: 1.2rem;
  color: #1e3a5f;
  background: #eff6ff;
  font-size: 1.2rem;
  line-height: 1.55;
}

.portfolio-preview-note strong {
  flex: 0 0 auto;
  color: #1d4ed8;
}

html[data-theme="dark"] .portfolio-preview-note {
  color: #bfdbfe;
  background: rgba(37, 99, 235, 0.14);
  border-color: rgba(96, 165, 250, 0.34);
}

@media (max-width: 640px) {
  .portfolio-preview-note {
    flex-direction: column;
    gap: 0.25rem;
  }
}
