/* ==========================================================================
   RaqGiveback — app chrome (auth pages, member dashboard, admin dashboard)
   Shares its design tokens with the public marketing site via this import
   rather than duplicating them, so both stay visually cohesive from one
   source of truth. Every selector below is a class already referenced by
   signup.html, signin.html, dashboard.html, admin.html, auth.js, or
   admin.js's generated markup — nothing here has been renamed, only
   restyled, so no HTML/JS changes were needed to land this reskin.
   ========================================================================== */

@import url("raqgiveback-public.css");

body {
  background: var(--cream);
  color: var(--ink);
  font-size: 16px;
}

h1, h2, h3, h4 {
  letter-spacing: -0.02em;
  margin: 0 0 0.5em;
}

a {
  /* --dominant-fill, not --dominant: this sets link colour at body text
     size directly on cream/white, which needs the 4.5:1 AA minimum that
     only the deepened fill variant clears (see token comment). */
  color: var(--dominant-fill);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

.wrap {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 24px;
}

/* ---------- Header ---------- */

.site-header {
  background: var(--ink);
  color: var(--cream);
  position: sticky;
  top: 0;
  z-index: 50;
  border-bottom: 1px solid rgba(246, 241, 232, 0.12);
}

.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 68px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-weight: 900;
  font-size: 1.1rem;
  color: var(--cream);
  text-decoration: none;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.brand:hover { text-decoration: none; }
.brand img { height: 28px; width: auto; display: block; flex: none; }
/* The second word of "RaqGiveback" carries the accent, matching the public
   site's wordmark — same visual system, just built from a plain <span>
   here instead of a <b>. The whole text run ("RAQ" + accent span + mark)
   sits in one wrapping <span> so .brand's flex gap only separates the logo
   image from the wordmark, not the letters within it — an earlier version
   without this wrapper let the gap land between "RAQ" and "Giveback". */
.brand .brand-accent {
  color: var(--dominant-text);
}
/* Same small solid gold mark as the public site's .wordmark i — one
   recurring motif instead of two different treatments of the same idea. */
.brand i {
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-left: 3px;
  margin-bottom: 2px;
  background: var(--spark);
  font-size: 0;
  line-height: 0;
  flex: none;
}

.site-header nav {
  display: flex;
  align-items: center;
  gap: 22px;
}

.site-header nav a {
  color: var(--muted-dark);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.site-header nav a:hover {
  color: var(--dominant-text);
  text-decoration: none;
}

/* signin.html/signup.html's plain nav has no hamburger/drawer to fall back
   on (unlike dashboard/admin, see the :has(.nav-toggle) rule below) — on a
   narrow phone, Home + Donate + the third link wrapped and looked jumbled.
   Collapse to just the primary action, always the last link in that nav. */
@media (max-width: 700px) {
  .site-header nav:not(:has(.nav-toggle)) a:not(:last-child) {
    display: none;
  }
}

/* ---------- Buttons ----------
   Class names (btn-gold, btn-dark, etc.) predate the colour swap and are
   left as-is — renaming them would mean touching every template string in
   admin.js that builds these dynamically. Only the rendered colours follow
   the new dominant(red)/spark(gold) system. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 26px;
  border-radius: var(--radius);
  font-weight: 800;
  font-size: 0.84rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border: 2px solid transparent;
  cursor: pointer;
  text-align: center;
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease),
              border-color 0.2s var(--ease), transform 0.2s var(--ease);
}
.btn:hover {
  text-decoration: none;
  transform: translateY(-1px);
}

.btn-gold {
  background: var(--dominant-fill);
  border-color: var(--dominant-fill);
  color: var(--cream);
}
.btn-gold:hover {
  background: var(--dominant-hi);
  border-color: var(--dominant-hi);
}

.btn-outline {
  background: transparent;
  border-color: rgba(246, 241, 232, 0.5);
  color: var(--cream);
}
.btn-outline:hover {
  border-color: var(--cream);
  color: var(--cream);
}

.btn-dark {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--cream);
}
.btn-dark:hover {
  background: var(--charcoal);
  border-color: var(--charcoal);
}

.btn-small {
  /* .btn's min-height: 54px (from the imported public stylesheet's own
     .btn, sized for the marketing site's big CTAs) was never overridden
     here, so every "small" admin button was silently forced to the same
     54px height as a full-size one regardless of its actual padding. */
  min-height: 38px;
  padding: 7px 14px;
  font-size: 0.72rem;
}

/* Quiet utility actions (Edit/Delete/+ Service on admin data rows) — a
   plain small outline instead of the same solid block treatment as a
   primary action, so a row of 2-3 of these doesn't read as heavy as
   Save/Approve/Add. */
.btn-quiet, .btn-quiet-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  background: transparent;
  border: 1px solid var(--line);
  padding: 3px 9px;
  border-radius: var(--radius);
  font-weight: 700;
  font-size: 0.62rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  cursor: pointer;
  font-family: inherit;
  transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease);
}
.btn-quiet { color: var(--ink); }
.btn-quiet:hover { background: var(--cream-2); border-color: var(--muted); }
.btn-quiet-danger { color: var(--dominant-fill); border-color: rgba(213, 43, 32, 0.35); }
.btn-quiet-danger:hover { background: rgba(213, 43, 32, 0.08); border-color: var(--dominant-fill); }

/* Small inline icon before a button's label (e.g. the trash can on Revoke
   Approval) — sized to the button's own small text, not a fixed px value,
   so it scales sensibly wherever .btn-icon is reused. */
.btn-icon {
  display: inline-flex;
  flex: none;
  width: 1.1em;
  height: 1.1em;
}
.btn-icon svg { width: 100%; height: 100%; display: block; }

.btn-danger {
  background: var(--dominant-fill);
  border-color: var(--dominant-fill);
  color: var(--cream);
}
.btn-danger:hover {
  background: var(--dominant-hi);
  border-color: var(--dominant-hi);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}
/* Same fix as .app-sidebar a[hidden] above: .btn-row's own `display: flex`
   outranks the browser's default [hidden] { display: none }, so a hidden
   .btn-row (e.g. the Profile page's view/edit action rows toggling) would
   otherwise still render. */
.btn-row[hidden] {
  display: none;
}

/* ---------- Cards (admin overview stat tiles) ---------- */

.card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px;
}

.card h3 {
  font-size: 1.1rem;
}

.card p {
  color: var(--muted);
  font-size: 0.95rem;
}

footer.site-footer {
  background: var(--ink);
  color: var(--muted-dark);
  padding: 40px 0;
  font-size: 0.88rem;
}

footer.site-footer a {
  color: var(--cream);
}

/* ---------- Forms ---------- */

.form-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 34px;
  max-width: 640px;
  margin: 0 auto;
}

.field {
  margin-bottom: 18px;
}

.field label {
  display: block;
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  margin-bottom: 6px;
}

.field .hint {
  font-weight: 400;
  color: var(--muted);
  font-size: 0.8rem;
  text-transform: none;
  letter-spacing: normal;
}

.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field input[type="password"],
.field input[type="date"],
.field input[type="number"],
.field input[type="file"],
.field select,
.field textarea {
  width: 100%;
  padding: 12px 13px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 0.96rem;
  font-family: inherit;
  background: #fff;
  color: var(--ink);
}
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
}

.field textarea {
  min-height: 90px;
  resize: vertical;
}

.checkbox-field {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.checkbox-field input {
  margin-top: 4px;
}
.checkbox-field label {
  font-weight: 500;
  font-size: 0.9rem;
}

.role-picker {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 10px;
  margin-bottom: 26px;
}

.role-picker input {
  display: none;
}

.role-picker span {
  display: block;
  text-align: center;
  padding: 14px 8px;
  border: 2px solid var(--line);
  border-radius: var(--radius);
  font-weight: 800;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
}

.role-picker input:checked + span {
  border-color: var(--dominant-fill);
  background: var(--cream-2);
  color: var(--dominant-fill);
}

.role-section {
  border-top: 1px dashed var(--line);
  padding-top: 18px;
  margin-top: 6px;
}

.role-section h4 {
  font-size: 0.78rem;
  font-weight: 800;
  color: var(--spark-text);
  text-transform: uppercase;
  letter-spacing: 0.14em;
}

.legal-note {
  background: var(--cream-2);
  border-left: 3px solid var(--spark);
  padding: 12px 16px;
  font-size: 0.85rem;
  color: var(--muted);
  border-radius: 0 var(--radius) var(--radius) 0;
  margin-bottom: 18px;
}

/* .form-msg's actual rules live below with .banner (the shared status-panel
   component) — kept together as one system rather than duplicated here. */

/* ---------- Auth pages ---------- */

.auth-page {
  padding: 70px 0;
  min-height: 60vh;
}
.auth-page h1 {
  text-align: center;
  margin-bottom: 6px;
  text-transform: uppercase;
  letter-spacing: -0.02em;
}
.auth-page .subtitle {
  text-align: center;
  color: var(--muted);
  margin-bottom: 34px;
}
.auth-switch {
  text-align: center;
  margin-top: 18px;
  font-size: 0.9rem;
  color: var(--muted);
}

/* ---------- App shell (dashboard / admin) ---------- */

.app-shell {
  display: grid;
  grid-template-columns: 220px 1fr;
  min-height: calc(100vh - 68px);
}

.app-sidebar {
  background: var(--ink);
  color: var(--cream);
  padding: 26px 16px;
}

.app-sidebar .who {
  padding: 0 8px 18px;
  border-bottom: 1px solid rgba(246, 241, 232, 0.12);
  margin-bottom: 16px;
}
.app-sidebar .who .name {
  font-weight: 700;
}
.app-sidebar .who .role-badge {
  margin-top: 6px;
}

.app-sidebar a, .app-sidebar button.sidebar-link {
  display: block;
  padding: 10px 10px;
  border-radius: var(--radius);
  color: var(--muted-dark);
  font-size: 0.88rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  margin-bottom: 2px;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  cursor: pointer;
  font-family: inherit;
}
.app-sidebar a:hover, .app-sidebar button.sidebar-link:hover {
  background: rgba(246, 241, 232, 0.08);
  color: var(--cream);
  text-decoration: none;
}
.app-sidebar a.active, .app-sidebar button.sidebar-link.active {
  background: rgba(168, 111, 12, 0.22);
  color: var(--spark);
}

/* .app-sidebar a's `display: block` above outranks the browser's default
   [hidden] { display: none } (one more class in the selector), so a hidden
   sidebar link would otherwise still render. Restore the hide. */
.app-sidebar a[hidden], .app-sidebar button[hidden] {
  display: none;
}

.app-main {
  padding: 36px 40px;
  max-width: 1080px;
  /* A CSS Grid item defaults to min-width: auto, so a non-wrapping child
     (the scrollable filter-tabs strip) would otherwise force this whole
     column — and the page — wider instead of just scrolling internally. */
  min-width: 0;
}

.app-main h1 {
  margin-bottom: 4px;
  text-transform: uppercase;
  letter-spacing: -0.02em;
}

.app-main .page-subtitle {
  color: var(--muted);
  margin-bottom: 30px;
}

.role-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  background: var(--dominant-fill);
  color: var(--cream);
}

/* Admin access is now independent of role (see is_admin), so a member can
   wear both a role badge and this one — gold, not red, so it reads as an
   added capability rather than a second, competing primary role. */
.role-badge--admin {
  margin-left: 6px;
  background: var(--spark);
  color: var(--ink);
}

/* Status colours are a fixed semantic convention (amber = pending,
   green = approved/completed, red = rejected) independent of the brand's
   dominant/spark accent choice — swapping them with the brand would make a
   "rejected" badge look identical to an "approved" one. Left untouched. */
.status-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.status-badge.pending { background: #fbe9c8; color: #8a5a00; }
.status-badge.approved { background: #d9f0dd; color: #1f6b2e; }
.status-badge.rejected { background: #f6d3d0; color: #8a281e; }
.status-badge.completed { background: #d9f0dd; color: #1f6b2e; }
.status-badge.ongoing, .status-badge.inprogress { background: #fbe9c8; color: #8a5a00; }

/* ---------- Status panel ----------
   One reusable "premium alert" component shared by the dashboard's pending
   banner (.banner, static markup) and the signup/signin form feedback
   (.form-msg, populated by showMsg() in signup.html/signin.html — that JS
   only ever does msg.textContent = text; msg.className = `form-msg ${type}`,
   so the uppercase label above the message is generated here in CSS via
   ::before rather than requiring any JS/HTML change). Neutral bone surface
   for every variant per design direction — color differentiates but never
   carries the meaning alone, since each variant also gets its own label
   text, so it doesn't rely on hue perception to be understood. */
.banner, .form-msg {
  position: relative;
  background: var(--cream);
  border: 1px solid var(--line);
  border-left: 3px solid var(--spark);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 14px 20px 15px;
  margin-bottom: 22px;
  font-size: 0.92rem;
  color: var(--ink);
}
.banner::before, .form-msg::before {
  content: "Notice";
  display: block;
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--spark-text);
  margin-bottom: 6px;
}
.form-msg.hidden { display: none; }

.banner.pending, .form-msg.pending { border-left-color: var(--spark); }
.banner.pending::before, .form-msg.pending::before { content: "Application Pending"; }

.banner.info, .form-msg.info { border-left-color: var(--spark); }
.banner.info::before, .form-msg.info::before { content: "Info"; }

.banner.approved, .form-msg.approved,
.banner.success, .form-msg.success { border-left-color: #2f6b3a; }
.banner.approved::before, .form-msg.approved::before { content: "Approved"; color: #2f6b3a; }
.banner.success::before, .form-msg.success::before { content: "Success"; color: #2f6b3a; }

.banner.error, .form-msg.error { border-left-color: var(--dominant-fill); }
.banner.error::before, .form-msg.error::before { content: "Error"; color: var(--dominant-fill); }

/* "What happens next" step list inside the pending-status banner. A hollow
   ring marks a step that hasn't happened yet; filled gold marks the step in
   progress; filled green marks one already done — so the state doesn't
   depend on reading the ring colour alone, the row's own weight/colour
   changes too. */
.status-steps {
  list-style: none;
  margin: 18px 0 0;
  padding: 0;
  display: grid;
  gap: 11px;
}
.status-steps li {
  position: relative;
  padding-left: 26px;
  font-size: 0.86rem;
  color: var(--muted);
}
.status-steps li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 4px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  border: 2px solid var(--line);
  background: var(--cream);
}
.status-steps li.is-done,
.status-steps li.is-active {
  color: var(--ink);
  font-weight: 700;
}
.status-steps li.is-done::before { background: #2f6b3a; border-color: #2f6b3a; }
.status-steps li.is-active::before { background: var(--spark); border-color: var(--spark); }
.status-steps__date {
  display: block;
  font-weight: 400;
  font-size: 0.76rem;
  color: var(--muted);
  margin-top: 2px;
}
.banner .tlink { margin-top: 20px; }

/* ---------- Events: editorial cards on phones, table everywhere else ----------
   The dashboard's Events tab renders the same data twice — .events-table-wrap
   (the ordinary table.data-table) and .event-cards (below) — and CSS picks
   one per breakpoint, rather than reusing the generic data-table mobile-card
   treatment other tables get. Events specifically wanted a date/title/
   location/CTA card, not a generic label/value list. */
/* The full Events & Announcements tab reuses the same picture-forward
   .home-event-card component as the Home preview (see further below) —
   one card design everywhere an event shows up, not a separate
   table+plain-card pair. .event-cards is just its responsive grid. */
.event-cards {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
}
@media (min-width: 701px) {
  .event-cards { grid-template-columns: 1fr 1fr; }
}
.event-card__toggle {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font: inherit;
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dominant-fill);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.event-card__toggle:hover { color: var(--dominant-hi); }

/* ---------- Empty state ----------
   Used where an empty data set deserves more than an italic "nothing here"
   row inside an otherwise-empty table (currently just Events — a table with
   a 640px min-width and one row of text reads as a broken page, not an
   intentional design, especially on a phone). */
.empty-state {
  padding: clamp(36px, 6vw, 56px) 20px;
  text-align: center;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
}
.empty-state__note {
  font-size: 1.1rem;
  font-weight: 800;
  text-transform: uppercase;
  margin-bottom: 10px;
}
.empty-state .lede { margin: 0 auto 22px; }
.empty-state .tlink { justify-content: center; }

/* ---------- Dashboard Home (community home for every role) ----------
   Mobile-first: everything below is a single column by default, widened at
   the two min-width breakpoints further down. Reuses .tlink, .banner, and
   .status-steps from elsewhere in this file rather than inventing parallel
   components. Cards are soft (16px radius, shadow, no hard border) rather
   than the sharp/bordered treatment the rest of the app uses, and every
   section carries a small gold-dot + coral accent so the Home tab doesn't
   read as a bare default-form-component page next to the branded logo. */

.home-welcome {
  text-transform: none;
  font-size: 1.5rem;
  letter-spacing: -0.01em;
  margin-bottom: 4px;
}
.home-subtitle {
  color: var(--muted);
  font-size: 0.95rem;
  margin-bottom: 18px;
}
.home-status-title {
  margin: 0 0 2px;
  font-size: 0.98rem;
}
.home-next-note {
  margin: 18px 0 0;
  font-size: 0.86rem;
  color: var(--muted);
  line-height: 1.55;
}
.home-next-note strong { color: var(--ink); }

.home-section { margin-top: 18px; }
.home-section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.home-section__head h2 {
  font-size: 0.86rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}
.home-section__head h2::before,
.home-card__label::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--spark);
  flex: none;
}
.home-section__head .tlink {
  font-size: 0.68rem;
  background: none;
  border: none;
  border-bottom: 2px solid var(--dominant);
  padding: 0 0 3px;
  cursor: pointer;
  font-family: inherit;
  flex: none;
}

/* Soft card base, shared by the role card / event cards / announcement list */
.home-card,
.home-event-card,
.home-announcements {
  background: #fff;
  border: none;
  border-radius: 16px;
  box-shadow: 0 1px 2px rgba(13, 13, 12, 0.04), 0 6px 18px rgba(13, 13, 12, 0.05);
}

/* Role-specific "at a glance" card */
.home-card { padding: 16px 18px; }
.home-card__label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}
.home-card__primary { font-size: 1.1rem; font-weight: 800; margin-bottom: 2px; }
.home-card__meta { font-size: 0.86rem; color: var(--muted); margin-bottom: 2px; }
.home-card .tlink {
  margin-top: 12px;
  background: none;
  border: none;
  border-bottom: 2px solid var(--dominant);
  padding: 0 0 3px;
  cursor: pointer;
  font-family: inherit;
  font-size: 0.72rem;
}

/* A person (mentee/mentor) row: avatar + name/status + a filled CTA pill,
   compact enough that a card with one person in it doesn't look empty. */
.person-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 12px;
}
.person-card + .person-card {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid rgba(13, 13, 12, 0.07);
}
.person-card__avatar {
  flex: none;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: var(--dominant-fill);
  color: var(--cream);
  display: grid;
  place-items: center;
  font-weight: 800;
  font-size: 0.86rem;
  letter-spacing: 0.02em;
}
.person-card__info { flex: 1; min-width: 0; }
.person-card__name {
  font-weight: 800;
  font-size: 0.95rem;
  margin: 0 0 3px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.person-card__status {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.74rem;
  color: var(--muted);
  margin: 0;
}
.person-card__status::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--spark);
  flex: none;
}
.person-card__cta {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 8px 13px;
  border-radius: 999px;
  background: var(--dominant-fill);
  color: var(--cream);
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border: none;
  cursor: pointer;
  font-family: inherit;
  transition: background-color 0.2s var(--ease);
}
.person-card__cta:hover { background: var(--dominant-hi); }

.home-list {
  list-style: none;
  margin: 0 0 4px;
  padding: 0;
  display: grid;
  gap: 6px;
  font-size: 0.92rem;
}

/* Compact icon + title + sub-line empty state — used for Events,
   Announcements, and every role-card "nothing here yet" message, instead
   of a large dashed placeholder box. */
.home-empty {
  display: flex;
  align-items: center;
  gap: 12px;
}
.home-empty__icon {
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(213, 43, 32, 0.08);
  color: var(--dominant-fill);
  display: grid;
  place-items: center;
}
/* "All caught up" reads as a positive state, not a neutral one — reuse the
   same green the app's status-badge.approved already uses, rather than
   coral (which elsewhere in the app signals action-needed/error). */
.home-empty__icon--good { background: rgba(31, 107, 46, 0.1); color: #1f6b2e; }
.home-empty__icon svg { width: 18px; height: 18px; }
.home-empty__title { font-weight: 800; font-size: 0.86rem; margin: 0; }
.home-empty__sub { font-size: 0.78rem; color: var(--muted); margin: 2px 0 0; }
.home-events > .home-empty,
.home-announcements > .home-empty { padding: 16px 18px; }

.home-mini-stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin: 14px 0;
}
.home-mini-stats > div {
  background: var(--cream-2);
  border-radius: 10px;
  padding: 10px 12px;
}
.home-mini-stats strong { display: block; font-size: 1.2rem; font-weight: 900; }
.home-mini-stats span {
  display: block;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Upcoming Events preview — picture-forward cards */
.home-events { display: grid; gap: 14px; }
.home-event-card { overflow: hidden; }
.home-event-card__media {
  position: relative;
  aspect-ratio: 16 / 9;
  background-color: var(--charcoal);
  background-image: repeating-linear-gradient(-45deg, rgba(246, 241, 232, 0.06) 0 2px, transparent 2px 11px);
}
.home-event-card__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.home-event-card__placeholder-note {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
.home-event-card__datebadge {
  position: absolute;
  top: 10px;
  left: 10px;
  background: var(--ink);
  color: var(--cream);
  border-radius: 10px;
  padding: 6px 10px;
  text-align: center;
  line-height: 1;
}
.home-event-card__datebadge b { display: block; font-size: 1.05rem; font-weight: 900; }
.home-event-card__datebadge span {
  display: block;
  font-size: 0.55rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--spark);
  margin-top: 3px;
}
.home-event-card__body { padding: 14px 16px 16px; }
.home-event-card__title { font-size: 1rem; text-transform: uppercase; margin-bottom: 4px; }
.home-event-card__meta { font-size: 0.82rem; color: var(--muted); margin-bottom: 8px; }
.home-event-card__desc { font-size: 0.88rem; color: var(--muted); line-height: 1.5; margin: 0 0 10px; }

/* Recent Announcements preview */
.home-announcements {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
.home-announcement {
  display: flex;
  gap: 14px;
  padding: 13px 16px;
  border-bottom: 1px solid rgba(13, 13, 12, 0.06);
}
.home-announcement:last-child { border-bottom: none; }
.home-announcement__date {
  flex: none;
  width: 52px;
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  padding-top: 2px;
}
.home-announcement__title { font-weight: 800; margin: 0 0 2px; }
.home-announcement__body { font-size: 0.88rem; color: var(--muted); line-height: 1.5; margin: 0; }

@media (min-width: 640px) {
  .home-events { grid-template-columns: repeat(2, 1fr); }
  .home-mini-stats { grid-template-columns: repeat(4, 1fr); }
}
@media (min-width: 1000px) {
  .home-events { grid-template-columns: repeat(3, 1fr); }
}

.stat-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  margin-bottom: 36px;
}
.stat-cards .card {
  padding: 18px 20px;
  border: none;
  border-radius: 0;
}
.stat-cards .stat-num {
  color: var(--ink);
  font-size: 1.7rem;
  font-weight: 900;
}
.stat-cards .stat-label {
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.admin-section {
  margin-bottom: 46px;
}

.admin-section .section-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
  flex-wrap: wrap;
  gap: 10px;
}

.admin-section h2 {
  font-size: 1.2rem;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}

.totals-row {
  display: flex;
  gap: 22px;
  flex-wrap: wrap;
  margin-bottom: 18px;
  font-size: 0.85rem;
  color: var(--muted);
}
.totals-row strong {
  display: block;
  font-size: 1.15rem;
  color: var(--ink);
}

/* Wraps every table.data-table (see admin.html/dashboard.html) so a table
   wider than the screen scrolls within its own box on mobile instead of
   forcing the whole page to scroll sideways or crushing every column
   illegibly thin. Hidden tab panels don't contribute to page scrollWidth,
   so this only actually matters once a panel is switched into view. */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--radius);
}

table.data-table {
  width: 100%;
  min-width: 640px;
  border-collapse: collapse;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  font-size: 0.86rem;
}
.table-scroll table.data-table {
  border-radius: 0;
}

/* Member/assignment row actions (Approve / Reject / Make Admin, etc.) —
   these render as several bare buttons with nothing to space them, which
   is what was colliding into each other. */
.row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

table.data-table th, table.data-table td {
  text-align: left;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

table.data-table th {
  background: var(--cream-2);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 800;
  color: var(--muted);
}

table.data-table tr:last-child td {
  border-bottom: none;
}

table.data-table .empty-row td {
  color: var(--muted);
  font-style: italic;
  text-align: center;
  padding: 22px;
}

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(14, 13, 11, 0.55);
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding: 40px 16px;
  overflow-y: auto;
  z-index: 100;
}
.modal-backdrop.open {
  display: flex;
}
.modal {
  background: #fff;
  border-radius: var(--radius);
  padding: 28px;
  max-width: 560px;
  width: 100%;
}
.modal--wide { max-width: 720px; }
.modal .modal-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}
.modal .modal-head h3 {
  text-transform: uppercase;
  font-size: 1.05rem;
}
.modal .modal-close {
  background: none;
  border: none;
  font-size: 1.3rem;
  cursor: pointer;
  color: var(--muted);
}
.two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 16px;
}

.tabs-row {
  display: flex;
  gap: 8px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}
.tabs-row button {
  display: inline-flex;
  align-items: center;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 7px 14px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
  /* <button> doesn't inherit body's text color the way other elements do —
     it falls back to the browser's own default, which isn't reliably
     black. Set it explicitly instead of leaving it to chance. */
  color: var(--ink);
}
.tabs-row button.active {
  background: var(--ink);
  color: var(--cream);
  border-color: var(--ink);
}

/* On phones, a compact horizontally-scrolling strip reads cleaner than
   letting 8 filter pills wrap onto three or four lines above the table. */
@media (max-width: 700px) {
  .tabs-row--scroll {
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: 4px;
    -webkit-overflow-scrolling: touch;
  }
  .tabs-row--scroll button { flex: none; }
}

/* Pending-count badge: a small red flag so an admin can tell at a glance,
   without opening the tab, that applications are waiting on them. */
.tab-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  margin-left: 6px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--dominant-fill);
  color: var(--cream);
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0;
  text-transform: none;
  vertical-align: middle;
}

/* ---------- Members: search bar ---------- */
.member-search {
  position: relative;
  margin-bottom: 20px;
}
.member-search svg {
  position: absolute;
  left: 15px;
  top: 50%;
  transform: translateY(-50%);
  width: 17px;
  height: 17px;
  color: var(--muted);
  pointer-events: none;
}
.member-search input {
  width: 100%;
  height: 46px;
  padding: 0 16px 0 42px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 0.88rem;
  font-family: inherit;
  color: var(--ink);
}
.member-search input::placeholder { color: var(--muted); }
.member-search input:focus {
  outline: none;
  border-color: var(--dominant-fill);
}

/* ---------- Members: compact select variants for the card's Role/
   Background Check rows. ---------- */
.member-select {
  cursor: pointer;
  font-family: inherit;
  color: var(--ink);
}
.member-select--plain {
  padding: 3px 8px;
  font-size: 0.72rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
}
.member-select--chip {
  appearance: none;
  -webkit-appearance: none;
  padding: 4px 22px 4px 10px;
  font-size: 0.68rem;
  font-weight: 700;
  border: 1px solid var(--line);
  border-radius: 999px;
  background-color: var(--cream-2);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23655e54' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 8px center;
  background-size: 12px;
}

/* ---------- Members: one compact card component at every width — single
   column on phones, a 2-column grid from tablet up. No separate table. ---------- */
.member-cards {
  display: grid;
  gap: 14px;
  grid-template-columns: 1fr;
}
@media (min-width: 701px) {
  .member-cards {
    grid-template-columns: 1fr 1fr;
    gap: 16px;
  }
}
/* The Role select blends in as bold text with a small chevron, like a
   plain "Mentor" line, rather than looking like a browser-default select
   box sitting inside an otherwise icon-led row. */
.member-card .member-select--plain {
  border: none;
  background: transparent;
  padding: 0 16px 0 0;
  font-size: 0.9rem;
  font-weight: 700;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23655e54' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right center;
  background-size: 14px;
}
.member-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 1px 3px rgba(13, 13, 12, 0.06);
  padding: 18px;
}
.member-card__head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}
.member-card__name {
  flex: 1;
  min-width: 0;
  font-size: 1.05rem;
  font-weight: 800;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.member-card__more-wrap { position: relative; flex: none; }
.member-card__more {
  flex: none;
  display: inline-flex;
  background: none;
  border: none;
  padding: 4px;
  color: var(--muted);
  cursor: pointer;
}
.member-card__more svg { width: 18px; height: 18px; }
.member-card__menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 130px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 6px 18px rgba(13, 13, 12, 0.14);
  overflow: hidden;
  z-index: 5;
}
.member-card__menu-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 10px 14px;
  background: none;
  border: none;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
}
.member-card__menu-item:hover { background: var(--cream-2); }
.member-card__menu-item .member-card__icon { width: 15px; height: 15px; }
.member-card__edit-input {
  flex: 1;
  min-width: 0;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  font-size: 0.85rem;
  font-family: inherit;
  color: var(--ink);
  background: #fff;
}
.member-card__edit-input:focus {
  outline: none;
  border-color: var(--dominant-fill);
}
.member-card__row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  font-size: 0.86rem;
}
.member-card__row--between { justify-content: space-between; }
.member-card__label {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--muted);
}
.member-card__icon {
  flex: none;
  width: 16px;
  height: 16px;
  color: var(--muted);
}
.member-card__icon svg { width: 100%; height: 100%; display: block; }
.member-card__divider {
  height: 1px;
  background: var(--line);
  margin: 4px 0;
}
.member-card__actions-row {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}
.member-card__actions-row > * {
  flex: 1;
  min-width: 0;
  padding: 13px 10px;
  font-size: 0.74rem;
}

/* Below this, the sidebar stops being a column next to the content (or, as
   it briefly was, a cluster of wrapped buttons stacked above it pushing
   everything else down) and becomes a full-screen drawer instead — opened
   by the header hamburger, matching the public site's mobile nav pattern.
   Same 1024px breakpoint as that hamburger's own appearance (imported from
   raqgiveback-public.css), so the toggle is never visible without the
   drawer behaviour actually being active, or vice versa. */
@media (max-width: 1024px) {
  /* "My Dashboard"/"Home" and "Sign Out" are also the first and last links
     in the drawer below, and at 390px wide the two text links plus the
     hamburger didn't fit anyway (11px overflow) — drop the duplicates and
     let the drawer be the one source of navigation on mobile. Scoped to
     :has(.nav-toggle) so this never touches signup.html/signin.html, whose
     header nav has no toggle or drawer to fall back on. */
  .site-header nav:has(.nav-toggle) a {
    display: none;
  }
  .app-shell {
    grid-template-columns: 1fr;
  }
  .app-sidebar {
    position: fixed;
    inset: 68px 0 0 0;
    z-index: 90;
    overflow-y: auto;
    padding: 10px 20px 40px;
    display: none;
  }
  .app-sidebar[data-open="true"] {
    display: block;
  }
  .app-sidebar .who {
    width: 100%;
    border-bottom: 1px solid rgba(246, 241, 232, 0.12);
    padding: 18px 8px;
    margin-bottom: 8px;
  }
  .app-sidebar a, .app-sidebar button.sidebar-link {
    font-size: 1.05rem;
    padding: 16px 8px;
    border-bottom: 1px solid rgba(246, 241, 232, 0.08);
    border-radius: 0;
  }
  .app-main {
    padding: 26px 18px;
  }
  .two-col {
    grid-template-columns: 1fr;
  }
}

/* Every data table has a 640px min-width so its columns stay legible, which
   is wider than any phone — so on a phone the horizontal-scroll fallback
   above was the *only* way to read anything past column two. Below phone
   width, drop the table layout entirely and render each row as a stacked
   card instead: no scrolling needed, one field per line, label pulled from
   each cell's data-label attribute (set in admin.js / dashboard.html). */
@media (max-width: 700px) {
  .table-scroll {
    overflow-x: visible;
  }
  table.data-table {
    min-width: 0;
    border: none;
    background: none;
  }
  table.data-table thead {
    display: none;
  }
  table.data-table tbody {
    display: block;
  }
  table.data-table tr {
    display: block;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    margin-bottom: 12px;
  }
  table.data-table tr:last-child {
    margin-bottom: 0;
  }
  table.data-table td {
    display: block;
    padding: 10px 14px;
  }
  /* The desktop rule strips td's bottom border only on the table's last
     row (so the card box doesn't get a stray line below its last field) —
     but every "row" is now its own card, so re-apply it card-by-card and
     only drop the divider after each card's actual last field. */
  table.data-table tr:last-child td {
    border-bottom: 1px solid var(--line);
  }
  table.data-table td:last-child {
    border-bottom: none;
  }
  table.data-table td::before {
    content: attr(data-label);
    display: block;
    font-size: 0.65rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    margin-bottom: 4px;
  }
  table.data-table td:not([data-label])::before,
  table.data-table td[data-label=""]::before {
    content: none;
    display: none;
    margin: 0;
  }
}

/* ==========================================================================
   Profile (dashboard "My Profile" tab) — large cover/hero, circular avatar
   overlapping it, name + role badge, About card, info-card grid, and an
   inline Edit mode that mirrors the Members card's Edit interaction
   (fields swap to inputs with Save/Cancel) rather than a separate modal,
   so the whole app shares one editing pattern.
   ========================================================================== */

.profile-hero {
  position: relative;
  margin-bottom: 52px;
}
.profile-hero__cover {
  position: relative;
  height: 140px;
}
/* Separate from .profile-hero__cover itself (which stays un-clipped) so
   its own overflow: hidden — needed for the rounded corners — doesn't
   also clip the Change/Remove popover positioned within it, the same
   clipping bug the avatar's edit button hit earlier. */
.profile-hero__cover-bg {
  position: absolute;
  inset: 0;
  border-radius: 16px;
  overflow: hidden;
  background: linear-gradient(135deg, var(--ink) 0%, var(--charcoal) 60%, var(--dominant-hi) 130%);
  background-size: cover;
  background-position: center;
  box-shadow: 0 1px 2px rgba(13, 13, 12, 0.04), 0 6px 18px rgba(13, 13, 12, 0.05);
}
.profile-hero__cover .profile-photo-menu-wrap {
  position: absolute;
  right: 14px;
  bottom: 14px;
}
.profile-hero__cover-edit {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border-radius: 999px;
  background: rgba(13, 13, 12, 0.55);
  color: #fff;
  border: 1px solid rgba(246, 241, 232, 0.4);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  cursor: pointer;
  backdrop-filter: blur(2px);
}
.profile-hero__cover-edit:hover { background: rgba(13, 13, 12, 0.75); }
.profile-hero__cover-edit svg { width: 14px; height: 14px; flex: none; }
.profile-hero__cover-edit:disabled { opacity: 0.6; cursor: default; }
@media (max-width: 480px) {
  .profile-hero__cover-edit span { display: none; }
  .profile-hero__cover-edit { padding: 8px; }
}
.profile-hero__avatar-wrap {
  position: absolute;
  left: 24px;
  bottom: -44px;
}
.profile-hero__avatar {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  border: 4px solid #fff;
  background: var(--dominant-fill);
  color: var(--cream);
  display: grid;
  place-items: center;
  font-weight: 900;
  font-size: 1.7rem;
  letter-spacing: 0.02em;
  overflow: hidden;
}
.profile-hero__avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.profile-hero__avatar-wrap .profile-photo-menu-wrap {
  position: absolute;
  right: -2px;
  bottom: -2px;
}
.profile-hero__avatar-edit {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--ink);
  color: #fff;
  border: 3px solid #fff;
  display: grid;
  place-items: center;
  cursor: pointer;
}
.profile-hero__avatar-edit svg { width: 15px; height: 15px; }
.profile-hero__avatar-edit:disabled { opacity: 0.5; cursor: default; }

/* Change/Remove popover shared by the avatar and cover photo buttons —
   same dropdown-menu treatment the Members card's 3-dot menu uses. */
.profile-photo-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 150px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 6px 18px rgba(13, 13, 12, 0.14);
  overflow: hidden;
  z-index: 6;
}
.profile-photo-menu button {
  display: block;
  width: 100%;
  padding: 10px 14px;
  background: none;
  border: none;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
}
.profile-photo-menu button:hover { background: var(--cream-2); }
.profile-photo-menu__danger { color: var(--dominant-fill); }
.profile-photo-menu__danger:hover { background: rgba(213, 43, 32, 0.08); }
/* Same fix as .app-sidebar a[hidden] / .btn-row[hidden] elsewhere in this
   file: the button's own `display: block` outranks the browser's default
   [hidden] { display: none }, so the Remove item (hidden when there's no
   photo to remove) would otherwise still render. */
.profile-photo-menu button[hidden] {
  display: none;
}

.profile-identity {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 52px 0 26px;
  padding: 0 4px;
}
.profile-identity h1 { margin: 0; }
.profile-identity .field { flex-basis: 100%; margin: 6px 0 0; }
/* Small, quiet outline button — not the big solid-fill treatment — sits at
   the end of the name/badges row instead of on its own line below all the
   info cards. Same .btn-quiet other small actions (Make Admin, etc.) use
   elsewhere in the app. */
.profile-edit-btn {
  margin-left: auto;
}
.profile-edit-btn[hidden] {
  display: none;
}

.profile-section-title {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 10px;
}
.profile-about {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 20px;
  margin-bottom: 22px;
}
.profile-about p { margin: 0; color: var(--muted); line-height: 1.6; }
.profile-about textarea {
  width: 100%;
  min-height: 90px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-family: inherit;
  font-size: 0.9rem;
  color: var(--ink);
}

.profile-info-grid {
  display: grid;
  gap: 14px;
  grid-template-columns: 1fr;
  margin-bottom: 26px;
}
@media (min-width: 701px) {
  .profile-info-grid { grid-template-columns: 1fr 1fr; }
}
.profile-info-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 16px 18px;
}
.profile-info-card__label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
}
.profile-info-card__label .member-card__icon { width: 14px; height: 14px; }
.profile-info-card__value { font-size: 0.92rem; font-weight: 600; }
.profile-info-card input,
.profile-info-card textarea {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-family: inherit;
  font-size: 0.88rem;
  color: var(--ink);
}

/* ==========================================================================
   Events & Announcements (dashboard member-facing tab). Events reuse the
   picture-forward .home-event-card component built for the Home preview —
   see that block above — inside the .event-cards grid; Announcements get
   their own plain white card in the same responsive 2-column grid the
   Members page established.
   ========================================================================== */

.events-subtabs { margin-bottom: 14px; }

.events-toolbar {
  display: flex;
  gap: 10px;
  margin-bottom: 22px;
}
.events-toolbar .member-search { flex: 1; margin-bottom: 0; }
.events-filter-wrap { position: relative; flex: none; }
.events-filter-btn {
  position: relative;
  height: 46px;
  width: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  cursor: pointer;
}
.events-filter-btn svg { width: 18px; height: 18px; }
.events-filter-btn.is-active {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--cream);
}
/* Small dot flagging that one or more of the Filters popover's fields is
   currently narrowing the view, visible whether or not the popover itself
   is open. */
.events-filter-btn__dot {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--dominant-fill);
  border: 2px solid #fff;
}
.events-filter-btn.is-active .events-filter-btn__dot { border-color: var(--ink); }
.filter-popover {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 190px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 6px 18px rgba(13, 13, 12, 0.14);
  padding: 12px 14px;
  z-index: 6;
}
.filter-popover__label {
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 8px;
}
.filter-popover select {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-family: inherit;
  font-size: 0.85rem;
  color: var(--ink);
}

/* Small badges layered onto an event/announcement card body — audience
   targeting and, admin-only in practice (RLS hides drafts from everyone
   else), a Draft flag so an admin previewing their own Home dashboard
   doesn't mistake an unpublished item for a live one. */
.content-card__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 6px;
}
.audience-badge {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  background: var(--cream-2);
  color: var(--muted);
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.draft-badge {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  background: #fbe9c8;
  color: #8a5a00;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.home-event-card__registered {
  font-size: 0.78rem;
  color: var(--muted);
  margin: 0 0 8px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.home-event-card__registered svg { width: 14px; height: 14px; flex: none; }

.announcement-cards {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
}
@media (min-width: 701px) {
  .announcement-cards { grid-template-columns: 1fr 1fr; }
}
.announcement-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 18px 20px;
}
.announcement-card__date {
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 8px;
}
.announcement-card__title { font-size: 1rem; margin: 0 0 6px; }
.announcement-card__body {
  font-size: 0.88rem;
  color: var(--muted);
  line-height: 1.55;
  margin: 0;
}

/* ==========================================================================
   Admin Events & Announcements — same compact icon-led card the Members
   page uses, in place of the old plain data tables, so admin and member
   views of the same content read as one design system.
   ========================================================================== */

.admin-content-cards {
  display: grid;
  gap: 14px;
  grid-template-columns: 1fr;
  margin-bottom: 8px;
}
@media (min-width: 701px) {
  .admin-content-cards { grid-template-columns: 1fr 1fr; }
}
.admin-content-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 16px 18px;
}
.admin-content-card__head {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 8px;
}
.admin-content-card__title { flex: 1; min-width: 0; font-size: 1rem; margin: 0; }
.admin-content-card__meta {
  font-size: 0.82rem;
  color: var(--muted);
  margin: 0 0 10px;
  line-height: 1.5;
}
.admin-content-card__actions {
  display: flex;
  gap: 8px;
  margin-top: 10px;
}

/* ---------- Avatar crop/zoom modal ---------- */
.avatar-crop {
  display: flex;
  justify-content: center;
  margin: 4px 0 20px;
}
.avatar-crop__frame {
  position: relative;
  width: 240px;
  height: 240px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--cream-2);
  border: 1px solid var(--line);
  cursor: grab;
  touch-action: none;
}
.avatar-crop__frame:active { cursor: grabbing; }
.avatar-crop__frame img {
  position: absolute;
  top: 0;
  left: 0;
  max-width: none;
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none;
}

/* ==========================================================================
   Community Assistance — GiveBack Log. Replaces the two plain data-tables
   with the same compact-card + filter-toolbar language established for
   Members and Events & Announcements: a search+filter toolbar, quick chips,
   primary tabs, then a responsive card grid. Mobile-first per priority —
   short cards, no dead space, chips scroll horizontally on narrow screens.
   ========================================================================== */

.impact-summary {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 18px;
}
.impact-stat {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px 14px;
  text-align: center;
}
.impact-stat strong {
  display: block;
  font-size: 1.3rem;
  font-weight: 900;
  line-height: 1.1;
}
.impact-stat span {
  display: block;
  margin-top: 3px;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.impact-stat--warn strong { color: var(--dominant-fill); }
@media (max-width: 480px) {
  .impact-stat { padding: 10px 6px; }
  .impact-stat strong { font-size: 1.1rem; }
  .impact-stat span { font-size: 0.56rem; }
}

/* Quick community-group chips — a step below the People/Assistance Records
   tabs in visual weight, so the hierarchy reads tabs first, chips second. */
.tabs-row--chips button {
  padding: 6px 12px;
  font-size: 0.66rem;
}

.assist-toolbar {
  display: flex;
  gap: 10px;
  margin: 14px 0;
}
.assist-toolbar .member-search { flex: 1; margin-bottom: 0; }

.filter-popover--wide {
  min-width: 260px;
}
.filter-popover--wide .filter-popover__label:not(:first-child) { margin-top: 14px; }
.filter-popover--wide select,
.filter-popover--wide input {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-family: inherit;
  font-size: 0.85rem;
  color: var(--ink);
}
.filter-popover__actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
}
.filter-popover__sheet-head { display: none; }
.filter-sheet-backdrop { display: none; }

/* On a phone, a floating popover ends up covering the very cards it's
   filtering. Below tablet width the same panel (same fields, same ids —
   nothing about the filtering logic changes) is repositioned into a
   bottom sheet with a backdrop instead, a more standard mobile pattern. */
@media (max-width: 700px) {
  .filter-sheet-backdrop.is-open {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(13, 13, 12, 0.5);
    z-index: 100;
  }
  .filter-popover--wide {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    top: auto;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    border-radius: 16px 16px 0 0;
    max-height: 82vh;
    overflow-y: auto;
    z-index: 101;
    padding: 10px 18px 24px;
    box-shadow: 0 -8px 24px rgba(13, 13, 12, 0.18);
  }
  .filter-popover__sheet-head {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 8px;
  }
  .filter-popover__sheet-handle {
    width: 40px;
    height: 4px;
    border-radius: 999px;
    background: var(--line);
    margin-bottom: 10px;
  }
  .filter-popover__sheet-head h3 {
    font-size: 0.9rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    margin: 0;
  }
  .filter-popover--wide .filter-popover__actions {
    flex-direction: column-reverse;
  }
  .filter-popover--wide .filter-popover__actions .btn,
  .filter-popover--wide .filter-popover__actions .btn-quiet {
    width: 100%;
  }
}

/* Shared 3-dot secondary-actions menu — same pattern as the Members card
   and the Profile photo buttons, kept scoped to this section's own class
   names since each part of the app owns its own copy of this interaction. */
.assist-menu-wrap { position: relative; flex: none; }
.assist-menu-btn {
  display: inline-flex;
  background: none;
  border: none;
  padding: 4px;
  color: var(--muted);
  cursor: pointer;
}
.assist-menu-btn svg { width: 18px; height: 18px; }
.assist-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 130px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 6px 18px rgba(13, 13, 12, 0.14);
  overflow: hidden;
  z-index: 6;
}
.assist-menu button {
  display: block;
  width: 100%;
  padding: 10px 14px;
  background: none;
  border: none;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
}
.assist-menu button:hover { background: var(--cream-2); }
.assist-menu button.assist-menu__danger { color: var(--dominant-fill); }
.assist-menu button.assist-menu__danger:hover { background: rgba(213, 43, 32, 0.08); }
/* Same [hidden] fix needed everywhere a menu item's own `display: block`
   would otherwise outrank the browser's default [hidden] { display: none }. */
.assist-menu button[hidden] {
  display: none;
}

.followup-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(213, 43, 32, 0.1);
  color: var(--dominant-fill);
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.person-cards,
.record-cards {
  display: grid;
  gap: 12px;
  grid-template-columns: 1fr;
}
@media (min-width: 701px) {
  .person-cards, .record-cards { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 1180px) {
  .person-cards, .record-cards { grid-template-columns: 1fr 1fr 1fr; }
}
/* Same [hidden] fix as .btn-row/.app-sidebar a elsewhere: the grid's own
   `display: grid` outranks the browser's default [hidden] { display: none
   }, so switching People/Assistance Records tabs would otherwise leave
   the inactive one visibly rendered underneath. */
.person-cards[hidden],
.record-cards[hidden] {
  display: none;
}

.person-card, .record-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px 16px;
}
.person-card__head, .record-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}
.person-card__name, .record-card__person {
  font-size: 0.98rem;
  font-weight: 800;
  margin: 0 0 4px;
}
.card-group-tag {
  font-weight: 600;
  font-size: 0.86em;
  color: var(--muted);
}
.person-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  font-size: 0.76rem;
  color: var(--muted);
  margin-bottom: 8px;
}
.person-card__latest {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 0.8rem;
  color: var(--muted);
  padding: 8px 0;
  border-top: 1px solid var(--line);
  margin-bottom: 10px;
}
.person-card__empty {
  font-style: italic;
}
.person-card__actions, .record-card__actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.record-card__right {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: none;
}
.record-card__type {
  font-size: 0.8rem;
  color: var(--muted);
  margin: 0 0 8px;
}
.record-card__line {
  font-size: 0.82rem;
  color: var(--ink);
  margin: 0 0 4px;
  line-height: 1.4;
}
.record-card__line b { font-weight: 700; }
.record-card__badges {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin: 8px 0 10px;
}

/* ---------- Person Profile modal (View Profile) ---------- */
.person-profile__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
}
.person-profile__name { font-size: 1.15rem; margin: 0 0 4px; }
.person-profile__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  font-size: 0.82rem;
  color: var(--muted);
}
.person-profile__info-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin: 16px 0 8px;
}
@media (max-width: 520px) {
  .person-profile__info-grid { grid-template-columns: 1fr; }
}
.person-profile__info-card {
  background: var(--cream-2);
  border-radius: 10px;
  padding: 10px 12px;
}
.person-profile__info-card .label {
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 2px;
}
.person-profile__info-card .value { font-size: 0.88rem; font-weight: 600; margin: 0; }
.person-profile__section-title {
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 20px 0 10px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.person-profile__history {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 360px;
  overflow-y: auto;
  padding-right: 2px;
}

/* Category chips (a filter) vs. People/Assistance Records (real navigation)
   need to read as different kinds of control, not two rows of the same
   pill button. Chips stay light — an outline that turns red, not black,
   when active — reserving the bold solid-fill treatment .tabs-row uses
   everywhere else for actual tab navigation. */
.tabs-row--chips button.active {
  background: #fff;
  color: var(--dominant-fill);
  border-color: var(--dominant-fill);
}

/* Underline nav tabs — visually distinct from the pill-shaped chips above:
   no fill, no border-radius, just a bottom rule that lands on the active
   one. Reads as "you are here", not "this filter is on". */
.section-tabs {
  display: flex;
  gap: 22px;
  border-bottom: 2px solid var(--line);
  margin-bottom: 18px;
}
.section-tabs button {
  background: none;
  border: none;
  padding: 10px 2px 12px;
  margin-bottom: -2px;
  font-weight: 800;
  font-size: 0.82rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 3px solid transparent;
  font-family: inherit;
}
.section-tabs button.active {
  color: var(--ink);
  border-bottom-color: var(--dominant-fill);
}
@media (max-width: 480px) {
  .section-tabs { gap: 16px; }
  .section-tabs button { font-size: 0.74rem; }
}

/* A very wide desktop window gets a 4th column instead of 3 wide cards
   stretching to fill the space. */
@media (min-width: 1500px) {
  .person-cards, .record-cards { grid-template-columns: repeat(4, 1fr); }
}
