/* ============================================================
   Hearts to Hands CLT — Volunteer Portal Stylesheet
   styles-portal.css
   ────────────────────────────────────────────────────────────
   Phase 1 (2026-07-10) of the portal/admin editorial migration:
   the shared component + Bootstrap-replacement UTILITY layer that
   used to live here has moved into styles-base.css (the single
   source of truth loaded on every surface). styles-base.css was
   ALREADY a superset of the portal skin — .glass, .portal-header,
   .path-card, .seg-ctrl, .stat-card, .event-*, .faq-*, .btn-gold,
   the notched .form-floating system, OTP boxes, bubbles, etc. —
   so those duplicates were removed here to end the base⇄portal
   divergence (a stale copy of several was quietly overriding the
   newer base version because this sheet loads last).

   What remains below is ONLY what is specific to the guest LOGIN
   page and not appropriate to load site-wide:
     • the login sticky top-bar + richer login background (scoped)
     • the animated ambient overlay (body::before)
     • the cursor spotlight
     • the path-card 3-D tilt perspective
   ============================================================ */

/* ── Login-page nav: adopt the main-site header treatment ─────
   The guest login page is body.section-main and loads styles-main.css +
   scripts-main.js, so `.section-main .portal-header` already gives it the exact
   homepage nav: sticky, transparent over the hero, frosted-glass backing on
   scroll (via the .header-scrolled body class the main JS toggles, plus the
   full-width ::before bar). The old override here forced a permanent frosted
   PILL inset at 1100px — that's what diverged from the main site and caused the
   boxed-in side gutters. We now inherit the main treatment and match the nav to
   the main site's --container spine (wider than the content column, exactly like
   the homepage: wide nav, narrower editorial content beneath). */
body.page-portal-login .portal-header { max-width: var(--container); }

/* Guest content shell — mirrors the main site's .h2h-shell header band: full
   width with the shared --gutter padding, and the nav caps itself at --container
   and centers (like .section-main .portal-header). So the portal nav runs to the
   exact same width + gutters as the homepage nav. Content sections inside stay
   at the ~1000px editorial column (.pv, below). */
body.page-portal-login .container.pv-shell {
  max-width: none;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}
@media (max-width: 560px) {
  body.page-portal-login .container.pv-shell { padding-left: 20px; padding-right: 20px; }
}

/* ── Login-page background: the richer red/blue/gold glow ──────
   base's body background is the subtle sitewide two-radial. The
   login page uses a warmer multi-radial; scope it so only the
   guest landing gets it (logged-in pages keep the base wash). */
body.page-portal-login {
  background:
    radial-gradient(1200px circle at 12% 10%, rgba(13,110,253,.26), transparent 48%),
    radial-gradient(900px  circle at 92% 18%, rgba(32,201,151,.16), transparent 48%),
    radial-gradient(1000px circle at 60% 95%, rgba(255,193,7,.16),  transparent 55%),
    linear-gradient(180deg, var(--bg-0), var(--bg-1));
}

/* Animated ambient overlay using brand colors */
body::before {
  content: '';
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(ellipse at 15% 15%, rgba(206,17,38,.10)  0%, transparent 55%),
    radial-gradient(ellipse at 85% 85%, rgba(31,166,222,.10) 0%, transparent 55%),
    radial-gradient(ellipse at 50% 100%,rgba(216,168,90,.05)0%, transparent 60%);
  animation: ambientPulse 9s ease-in-out infinite alternate;
}
@keyframes ambientPulse { from { opacity: .5; } to { opacity: 1; } }

/* ── Cursor spotlight ─────────────────────────────────────── */
#cursor-spotlight {
  position: fixed;
  top: 0; left: 0;
  width: 500px; height: 500px;
  border-radius: 50%;
  background: radial-gradient(circle at center,
    rgba(206,17,38,.05)   0%,
    rgba(31,166,222,.03) 38%,
    transparent          65%
  );
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 0;
  opacity: 0;
  transition: opacity .4s ease;
  will-change: left, top;
}

/* ── 3-D tilt — give cards a perspective context ─────────── */
.path-grid { perspective: 1000px; }
.path-card {
  transform-style: preserve-3d;
  will-change: transform;
  transition: transform .12s ease, box-shadow .22s ease, border-color .22s ease;
}

/* Everything else that used to live here (typewriter, animations, auth
   transitions, segmented control, back-link, responsive tweaks, the shared
   event panel + shift-fill bar) now lives in styles-base.css — see the
   "EDITORIAL LAYOUT + UTILITY LAYER" block and the component sections above
   it. This sheet is intentionally tiny: login-page-only additions. */

/* ── Event hero thumb (real art OR branded placeholder) ─────────────
   Mirrors the main site's index.php event poster treatment, sized to the
   portal's compact 100px thumbnail. Built by window.h2hEventHero() in
   scripts-portal.js. Real art + placeholder BOTH get a staggered sheen
   sweep (--sweep-delay set inline per event) so the row feels alive. */
.evt-thumb {
  position: relative;
  flex: 0 0 100px;
  width: 100px; height: 100px;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 4px 16px rgba(0,0,0,.35);
}
.evt-thumb-img {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
}
/* Once real art loads, h2hHeroSwap drops the --ph class — hide the branded
   placeholder so the poster shows instead of painting behind it. */
.evt-thumb:not(.evt-thumb--ph) .evt-thumb-ph { display: none; }
/* Real-art sweep: soft white diagonal pass. */
.evt-thumb:not(.evt-thumb--ph)::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(115deg, transparent 42%, rgba(255,255,255,.16) 50%, transparent 58%);
  background-size: 260% 100%;
  animation: evtThumbSweep 6.5s ease-in-out infinite;
  animation-delay: var(--sweep-delay, 0s);
}

/* Branded placeholder — navy tile, gold top-edge + dot-grid, centered logo. */
.evt-thumb--ph { background: #0b1120; box-shadow: 0 4px 16px rgba(0,0,0,.35); }
.evt-thumb-ph {
  position: relative; width: 100%; height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .3rem;
  background: linear-gradient(158deg, #17233f 0%, #0b1120 100%);
  overflow: hidden;
}
.evt-thumb-ph > * { position: relative; z-index: 1; }
.evt-thumb-ph::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background:
    radial-gradient(rgba(216,168,90,.10) 1px, transparent 1.5px) 0 0 / 9px 9px,
    linear-gradient(115deg, transparent 42%, rgba(233,238,247,.07) 50%, transparent 58%);
  background-size: 9px 9px, 260% 100%;
  animation: evtPhSheen 6.5s ease-in-out infinite;
  animation-delay: var(--sweep-delay, 0s);
}
.evt-thumb-ph::after {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px; z-index: 2;
  background: linear-gradient(90deg, #CE1126 0%, #D8A85A 50%, #1FA6DE 100%);
}
.evt-thumb-ph-logo {
  width: 58%; max-width: 60px; height: auto;
  filter: drop-shadow(0 2px 8px rgba(0,0,0,.35));
}
.evt-thumb-ph-cat {
  display: inline-flex; align-items: center; gap: .25rem;
  font-family: 'Oswald', sans-serif; font-size: .5rem; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: rgba(216,168,90,.92);
}
.evt-thumb-ph-cat i { font-size: .72rem; }
/* Placeholder sweep: brighter (navy tile eats a white pass) + warm gold trail. */
.evt-thumb--ph::after {
  content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: linear-gradient(115deg, transparent 40%, rgba(255,255,255,.28) 49%, rgba(216,168,90,.22) 51%, transparent 60%);
  background-size: 260% 100%;
  animation: evtThumbSweep 6.5s ease-in-out infinite;
  animation-delay: var(--sweep-delay, 0s);
}
@keyframes evtThumbSweep { 0%, 100% { background-position: 130% 0; } 50% { background-position: -30% 0; } }
@keyframes evtPhSheen   { 0%, 100% { background-position: 0 0, 130% 0; } 50% { background-position: 0 0, -30% 0; } }
@media (prefers-reduced-motion: reduce) {
  .evt-thumb::after, .evt-thumb--ph::after, .evt-thumb-ph::before { animation: none; }
}

/* ════════════════════════════════════════════════════════════════════
   PORTAL LOGIN — editorial rewrite (.pv-* system)
   Single centered column, hairlines + type, no card-in-card. Scoped to
   the guest login page (body.page-portal-login). Form fields use the shared
   .cf-* system (styles-base.css). Replaces the old .glass/.path-card/.seg-ctrl
   two-column layout.
   ════════════════════════════════════════════════════════════════════ */
body.page-portal-login .pv {
  /* Editorial content width — matches the homepage's ~1000px section width so
     the shared .main-section-header--editorial heads (Why / Events / FAQ) and
     the event list fill the column edge-to-edge like the main site, instead of
     being pinched into a narrow 640px block under the wide hero. The auth block
     and lede re-clamp themselves narrower below (forms read better narrow). */
  max-width: 1000px;
  margin: 0 auto;
  padding: 1rem 0 2rem;
}

/* Auth block — stays narrow & centered (login/register forms read better at a
   comfortable measure) even though the surrounding .pv column is now 1000px. */
body.page-portal-login .pv-auth { max-width: 560px; margin: 0 auto 3.5rem; scroll-margin-top: 6rem; }

/* Chooser — two editorial choices divided by a hairline, no card boxes */
body.page-portal-login .pv-chooser {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 0;
}
body.page-portal-login .pv-path {
  display: flex; flex-direction: column; align-items: flex-start;
  text-align: left; gap: .5rem;
  background: none; border: 0; cursor: pointer;
  padding: 1.5rem;
  color: rgba(233,238,247,.96);
  border-radius: 14px;
  transition: background .2s ease;
}
body.page-portal-login .pv-path:hover { background: rgba(255,255,255,.03); }
body.page-portal-login .pv-path + .pv-path { border-left: 1px solid rgba(255,255,255,.09); }
body.page-portal-login .pv-path-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 11px; font-size: 1.2rem; margin-bottom: .3rem;
}
body.page-portal-login .pv-path--login .pv-path-icon { background: rgba(206,17,38,.14); color: var(--h2h-red); }
body.page-portal-login .pv-path--reg   .pv-path-icon { background: rgba(31,166,222,.14); color: var(--h2h-blue); }
body.page-portal-login .pv-path-title { font-size: 1.05rem; font-weight: 700; color: #fff; }
body.page-portal-login .pv-path-desc { font-size: .82rem; line-height: 1.5; color: rgba(233,238,247,.52); }
body.page-portal-login .pv-path-cta {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: .8rem; font-weight: 700; letter-spacing: .02em; margin-top: .35rem;
  transition: gap .2s ease;
}
body.page-portal-login .pv-path--login .pv-path-cta { color: var(--h2h-red); }
body.page-portal-login .pv-path--reg   .pv-path-cta { color: var(--h2h-blue); }
body.page-portal-login .pv-path:hover .pv-path-cta { gap: .6rem; }
@media (max-width: 560px) {
  body.page-portal-login .pv-chooser { grid-template-columns: 1fr; }
  body.page-portal-login .pv-path + .pv-path { border-left: 0; border-top: 1px solid rgba(255,255,255,.09); }
}

/* Auth view */
body.page-portal-login .pv-authview { margin-top: .5rem; scroll-margin-top: 6rem; }

/* Segmented control — hairline underline style, not a filled pill box */
body.page-portal-login .pv-seg {
  position: relative; display: flex;
  border-bottom: 1px solid rgba(255,255,255,.12);
  margin-bottom: 1.25rem;
}
body.page-portal-login .pv-seg-btn {
  flex: 1; background: none; border: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  padding: .7rem 1rem; font-size: .95rem; font-weight: 700; letter-spacing: .02em;
  color: rgba(255,255,255,.55); transition: color .18s ease;
}
body.page-portal-login .pv-seg-btn:hover { color: rgba(255,255,255,.85); }
body.page-portal-login .pv-seg-indicator {
  position: absolute; bottom: -1px; left: 0;
  width: 50%; height: 2px; background: var(--h2h-gold);
  transition: transform .28s cubic-bezier(.22,1,.36,1), background .2s ease;
}
body.page-portal-login #authSegCtrl[data-active="login"]    .pv-seg-indicator { transform: translateX(0);    background: var(--h2h-red); }
body.page-portal-login #authSegCtrl[data-active="register"] .pv-seg-indicator { transform: translateX(100%); background: var(--h2h-blue); }
body.page-portal-login #authSegCtrl[data-active="login"]    #segLogin,
body.page-portal-login #authSegCtrl[data-active="register"] #segRegister { color: #fff; }

/* Back link */
body.page-portal-login .pv-back {
  background: none; border: 0; cursor: pointer; padding: 0;
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .8rem; color: rgba(255,255,255,.45); margin-bottom: 1.25rem;
  transition: color .15s ease;
}
body.page-portal-login .pv-back:hover { color: rgba(255,255,255,.8); }

/* Registration step bar */
body.page-portal-login .pv-stepbar { margin-bottom: 1.5rem; }
body.page-portal-login .pv-stepbar-track { display: flex; align-items: flex-start; justify-content: center; }
body.page-portal-login .reg-step { display: flex; flex-direction: column; align-items: center; gap: .3rem; flex-shrink: 0; }
body.page-portal-login .pv-step-dot {
  width: 28px; height: 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: .75rem; font-weight: 700; transition: .2s ease;
}
body.page-portal-login .reg-step.todo   .pv-step-dot { background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.18); color: rgba(233,238,247,.4); }
body.page-portal-login .reg-step.active  .pv-step-dot { background: rgba(31,166,222,.22); border: 2px solid var(--h2h-blue); color: rgba(31,166,222,.95); }
body.page-portal-login .reg-step.done    .pv-step-dot { background: rgba(16,185,129,.25); border: 1px solid rgba(16,185,129,.55); color: rgba(110,231,183,.95); }
body.page-portal-login .pv-step-label { font-size: .62rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; white-space: nowrap; }
body.page-portal-login .reg-step.todo   .pv-step-label { color: rgba(233,238,247,.3); }
body.page-portal-login .reg-step.active  .pv-step-label { color: rgba(31,166,222,.8); }
body.page-portal-login .reg-step.done    .pv-step-label { color: rgba(110,231,183,.7); }
body.page-portal-login .reg-step-line { flex: 1; height: 1px; min-width: 18px; max-width: 55px; background: rgba(255,255,255,.14); margin: 14px 4px 0; transition: background .2s; }
body.page-portal-login .reg-step-line.done { background: rgba(16,185,129,.45); }

/* Pane heads */
body.page-portal-login .pv-pane-head { margin-bottom: 1.25rem; }
body.page-portal-login .pv-pane-title { font-size: 1.05rem; font-weight: 700; color: #fff; margin-bottom: .2rem; }
body.page-portal-login .pv-pane-sub { font-size: .85rem; color: rgba(233,238,247,.55); line-height: 1.5; }

/* Field grids */
body.page-portal-login .pv-field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1rem; }
body.page-portal-login .pv-field-grid--csz { grid-template-columns: 2fr 1.3fr 1fr; }
@media (max-width: 560px) {
  body.page-portal-login .pv-field-grid,
  body.page-portal-login .pv-field-grid--csz { grid-template-columns: 1fr; }
}
body.page-portal-login .pv-field-note { font-size: .74rem; color: rgba(233,238,247,.45); line-height: 1.5; margin: -.4rem 0 1rem; }

/* Select styled as cf-input */
body.page-portal-login .cf-select { appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23D8A85A'%3E%3Cpath d='M8 11L3 6h10z'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 1rem center; background-size: 14px; padding-right: 2.5rem; }
body.page-portal-login .cf-select option { background: #0b1220; color: #e9eef7; }

/* Form action rows */
body.page-portal-login .pv-form-actions { display: flex; justify-content: flex-end; margin-top: .5rem; }
body.page-portal-login .pv-form-actions--split { justify-content: space-between; }
body.page-portal-login .pv-btn-block { width: 100%; justify-content: center; }

/* Ghost (secondary) button */
body.page-portal-login .pv-btn-ghost {
  display: inline-flex; align-items: center; gap: .35rem;
  background: none; border: 1px solid rgba(255,255,255,.2);
  color: rgba(233,238,247,.8); border-radius: 8px;
  padding: .5rem 1.1rem; font-size: .85rem; font-weight: 600; cursor: pointer;
  transition: background .18s, border-color .18s, color .18s;
}
body.page-portal-login .pv-btn-ghost:hover { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.4); color: #fff; }
body.page-portal-login .pv-btn-sm { padding: .3rem .7rem; font-size: .78rem; }

/* Checkbox row */
body.page-portal-login .pv-check {
  display: flex; align-items: center; gap: .5rem;
  font-size: .85rem; color: rgba(233,238,247,.75);
  cursor: pointer; margin: .25rem 0 1.1rem;
}
body.page-portal-login .pv-check--end { justify-content: flex-end; }
body.page-portal-login .pv-check .invalid-feedback { flex-basis: 100%; }

/* Forgot link + row */
body.page-portal-login .pv-forgot-row { text-align: center; margin-top: .85rem; }
body.page-portal-login .pv-forgot-link {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: .82rem; color: rgba(255,255,255,.5); text-decoration: none;
  transition: color .18s ease;
}
body.page-portal-login .pv-forgot-link:hover { color: var(--h2h-gold); }

/* Forgot panel */
body.page-portal-login .pv-forgot { margin-top: 1rem; }
body.page-portal-login .pv-forgot-inner {
  border-top: 1px solid rgba(255,255,255,.1);
  padding-top: 1.25rem;
}

/* Verified confirmation */
body.page-portal-login .pv-verified {
  display: flex; align-items: center; gap: .5rem;
  font-size: .88rem; color: rgba(110,231,183,.95);
  background: rgba(16,185,129,.1); border: 1px solid rgba(16,185,129,.3);
  border-radius: 12px; padding: .6rem .85rem; margin: 1rem 0;
}

/* OTP */
body.page-portal-login .pv-otp-deliver { display: flex; gap: .75rem; align-items: flex-start; margin-bottom: 1rem; }
body.page-portal-login .pv-otp-deliver .cf-float { flex: 1; margin-bottom: 0; }
body.page-portal-login .pv-otp-deliver .cf-submit,
body.page-portal-login .pv-otp-deliver .pv-btn-ghost { height: 54px; flex-shrink: 0; }
body.page-portal-login .pv-otp-area { margin: 1rem 0; }
body.page-portal-login .pv-otp-boxes { display: flex; gap: .5rem; flex-wrap: wrap; margin: .5rem 0; }
body.page-portal-login .pv-otp-box {
  width: 48px; height: 56px; text-align: center; font-size: 1.3rem;
  background: rgba(255,255,255,.05); border: 1.5px solid rgba(255,255,255,.16);
  border-radius: 12px; color: #fff; transition: border-color .18s, box-shadow .18s;
}
body.page-portal-login .pv-otp-box:focus {
  outline: none; border-color: var(--h2h-gold); box-shadow: 0 0 0 4px rgba(216,168,90,.14);
}
body.page-portal-login .pv-otp-timers { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; margin-top: .75rem; }

/* Password strength */
body.page-portal-login .pv-strength { margin: .5rem 0 1rem; }
body.page-portal-login .pv-strength-label { font-size: .78rem; color: rgba(233,238,247,.55); margin-bottom: .35rem; }

/* Waiver */
body.page-portal-login .pv-waiver { margin-top: 1rem; }
body.page-portal-login .pv-waiver-body {
  border: 1px solid rgba(255,255,255,.12); border-radius: 14px;
  background: rgba(255,255,255,.03); padding: 1rem;
}
body.page-portal-login .pv-waiver-title { font-weight: 700; color: #fff; margin-bottom: .5rem; }
body.page-portal-login .pv-waiver-copy { font-size: .82rem; line-height: 1.5; color: rgba(233,238,247,.62); margin-bottom: .5rem; }
body.page-portal-login .pv-waiver-actions { margin: .5rem 0; }
body.page-portal-login .pv-waiver-full {
  white-space: pre-wrap; font-family: inherit; font-size: .9rem; line-height: 1.4;
  max-height: 280px; overflow: auto; padding: .75rem; border-radius: 12px;
  border: 1px solid rgba(255,255,255,.12); background: rgba(0,0,0,.18); margin: .5rem 0 0;
}

/* ── Closing sections: why / events / faq ── */
body.page-portal-login .pv-why {
  display: grid; grid-template-columns: repeat(3,1fr); gap: 1.5rem;
  padding: 2rem 0; border-top: 1px solid rgba(255,255,255,.08);
  border-bottom: 1px solid rgba(255,255,255,.08); margin-bottom: 2.5rem;
}
@media (max-width: 560px) { body.page-portal-login .pv-why { grid-template-columns: 1fr; gap: 1.25rem; } }
body.page-portal-login .pv-why-icon { font-size: 1.4rem; color: var(--h2h-blue); display: block; margin-bottom: .5rem; }
body.page-portal-login .pv-why-item--blue .pv-why-icon { color: var(--h2h-blue); }
body.page-portal-login .pv-why-item--gold .pv-why-icon { color: var(--h2h-gold); }
body.page-portal-login .pv-why-item--red  .pv-why-icon { color: var(--h2h-red); }
body.page-portal-login .pv-why-title { font-size: .9rem; font-weight: 700; color: #fff; margin-bottom: .25rem; }
body.page-portal-login .pv-why-text { font-size: .8rem; line-height: 1.5; color: rgba(233,238,247,.55); }

body.page-portal-login .pv-events, body.page-portal-login .pv-faq { margin-bottom: 2.5rem; }
body.page-portal-login .pv-events-note {
  display: flex; align-items: center; justify-content: center; gap: .35rem;
  font-size: .8rem; color: rgba(233,238,247,.5); margin-top: 1rem;
}

/* ── Editorial event list (.pv-evt-*) ────────────────────────────────
   Login-page-only rebuild of the old .event-item-card "card-in-card".
   Progressive disclosure: each event is a scannable summary row — poster
   thumb + kicker + title + date + a single rolled-up meta line ("3 shifts ·
   41 spots open"). Individual shifts are NOT shown here; a logged-out visitor
   can't register anyway, so the per-shift breakdown + signup lives on the
   logged-in events page. Events are separated by hairlines, not boxes. The
   shared base classes (.event-item-card, .event-shift-block, .shift-fill-*)
   are left untouched so the logged-in pages that use them don't regress. The
   poster thumb itself (.evt-thumb*) is reused as-is. */
body.page-portal-login .pv-evt {
  display: flex; align-items: center; gap: 1.15rem;
  padding: 1.35rem 0;
  border-top: 1px solid rgba(255,255,255,.09);
}
body.page-portal-login .pv-evt:first-child { border-top: 0; padding-top: .25rem; }
body.page-portal-login .pv-evt:last-child  { padding-bottom: .25rem; }

body.page-portal-login .pv-evt-headtext { min-width: 0; }
body.page-portal-login .pv-evt-kicker {
  font-family: 'Oswald', sans-serif; font-weight: 600;
  font-size: .68rem; letter-spacing: .18em; text-transform: uppercase;
  color: rgba(216,168,90,.78); margin-bottom: .25rem;
}
body.page-portal-login .pv-evt-title {
  font-family: 'Barlow Condensed', sans-serif; font-weight: 600;
  font-size: clamp(1.4rem, 3.2vw, 1.85rem); line-height: 1.05;
  color: #F4EFE4; margin: 0;
}
body.page-portal-login .pv-evt-date {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .82rem; color: rgba(233,238,247,.62); margin-top: .3rem;
}
body.page-portal-login .pv-evt-date i { font-size: .85rem; color: rgba(216,168,90,.7); }

/* Rolled-up shift summary line */
body.page-portal-login .pv-evt-meta {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .8rem; color: rgba(233,238,247,.55); margin-top: .4rem;
}
body.page-portal-login .pv-evt-meta i { font-size: .85rem; color: rgba(31,166,222,.7); }
body.page-portal-login .pv-evt-meta.full { color: rgba(248,113,113,.85); font-weight: 600; }
body.page-portal-login .pv-evt-meta.full i { color: rgba(248,113,113,.75); }

/* ── Featured lead (.pv-evt-lead) — the next mission we serve, elevated above the
   hairline list with a live serve countdown. Larger poster, editorial eyebrow, and a
   D/H/M/S ticker that warms to H2H red inside 48h. ────────────────────── */
body.page-portal-login .pv-evt-lead {
  display: grid; grid-template-columns: 168px 1fr; gap: 1.5rem; align-items: center;
  padding: 1.5rem; margin-bottom: .5rem; border-radius: 18px;
  background: linear-gradient(158deg, rgba(23,35,63,.72) 0%, rgba(11,17,32,.72) 100%);
  border: 1px solid rgba(255,255,255,.08);
  box-shadow: 0 18px 44px rgba(0,0,0,.34);
  position: relative; overflow: hidden;
}
body.page-portal-login .pv-evt-lead::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, #CE1126 0%, #D8A85A 50%, #1FA6DE 100%);
}
body.page-portal-login .pv-evt-lead-media .evt-thumb { flex: none; width: 168px; height: 168px; border-radius: 14px; }
body.page-portal-login .pv-evt-lead-body { min-width: 0; }
body.page-portal-login .pv-evt-lead-eyebrow {
  font-family: 'Oswald', sans-serif; font-weight: 600;
  font-size: .82rem; letter-spacing: .2em; text-transform: uppercase;
  color: rgba(216,168,90,.85); margin-bottom: .3rem;
}
body.page-portal-login .pv-evt-lead-title {
  font-family: 'Barlow Condensed', sans-serif; font-weight: 600;
  font-size: clamp(1.9rem, 4.4vw, 2.6rem); line-height: 1.02;
  color: #F4EFE4; margin: .1rem 0 .5rem;
}
body.page-portal-login .pv-evt-lead-facts { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem 1.1rem; }
body.page-portal-login .pv-evt-lead-facts .pv-evt-date,
body.page-portal-login .pv-evt-lead-facts .pv-evt-meta { margin-top: 0; }

/* Countdown ticker */
body.page-portal-login .pv-cd { margin-top: 1.1rem; }
body.page-portal-login .pv-cd-row { display: flex; gap: .6rem; }
body.page-portal-login .pv-cd-unit {
  display: flex; flex-direction: column; align-items: center;
  min-width: 3.1rem; padding: .5rem .35rem; border-radius: 12px;
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.07);
}
body.page-portal-login .pv-cd-n {
  font-family: 'Barlow Condensed', sans-serif; font-weight: 600;
  font-size: clamp(1.5rem, 5vw, 2rem); line-height: 1;
  color: #F4EFE4; font-variant-numeric: tabular-nums;
}
body.page-portal-login .pv-cd-l {
  font-family: 'Oswald', sans-serif; font-weight: 500;
  font-size: .82rem; letter-spacing: .08em; text-transform: uppercase;
  color: rgba(233,238,247,.5); margin-top: .2rem;
}

/* Derived day-of ritual under the serve countdown. Doors/prayer read muted;
   the closing "We serve at" step is the payoff — brighter text + a deliberate
   gold heart (one of the rationed gold moments). */
body.page-portal-login .pv-call {
  display: flex; flex-wrap: wrap; align-items: center; gap: .3rem .95rem;
  margin-top: .85rem;
  font-family: 'Oswald', sans-serif; font-weight: 500;
  font-size: .82rem; letter-spacing: .04em;
  color: rgba(233,238,247,.62);
}
body.page-portal-login .pv-call-step { display: inline-flex; align-items: center; gap: .32rem; }
body.page-portal-login .pv-call-step i { font-size: 1rem; line-height: 1; color: rgba(233,238,247,.4); }
body.page-portal-login .pv-call-step:last-child { color: #F4EFE4; }
body.page-portal-login .pv-call-step:last-child i { color: #D8A85A; }

body.page-portal-login .pv-evt-lead + .pv-evt { border-top: 0; padding-top: 1.5rem; }

@media (max-width: 560px) {
  body.page-portal-login .pv-evt-lead { grid-template-columns: 1fr; gap: 1.1rem; padding: 1.25rem; text-align: center; }
  body.page-portal-login .pv-evt-lead-media { display: flex; justify-content: center; }
  body.page-portal-login .pv-evt-lead-media .evt-thumb { width: 132px; height: 132px; }
  body.page-portal-login .pv-evt-lead-facts { justify-content: center; }
  body.page-portal-login .pv-cd-row { justify-content: center; gap: .4rem; }
  body.page-portal-login .pv-cd-unit { min-width: 0; flex: 1 1 0; padding: .5rem .2rem; }
  body.page-portal-login .pv-call { justify-content: center; }
}

/* ── Serve clock band — the org's heartbeat: a standing "We serve again in"
   count under the hero. Contained in the column but given real presence — a
   clean editorial band: hairline rules, a soft glow, and big tabular numerals. Rests
   cool (brand blue) and warms to H2H red inside 48h (urgent hangs off the
   section so the cap, units, and numbers shift together); the seconds number
   pulses on each tick. Reuses the base .pv-cd unit/row styling; .pv-cd--band
   scales it up. */
body.page-portal-login .pv-serveclock {
  margin: 2.75rem 0 3.25rem;
  padding: 2.4rem 1rem 2.5rem;
  text-align: center;
  border-top: 1px solid rgba(31,166,222,.22);
  border-bottom: 1px solid rgba(31,166,222,.22);
  background: radial-gradient(78% 150% at 50% 50%, rgba(31,166,222,.10), transparent 72%);
  transition: border-color .6s ease, background .6s ease;
}
body.page-portal-login .pv-serveclock-inner {
  display: inline-flex; flex-direction: column; align-items: center; gap: 1rem;
}
body.page-portal-login .pv-serveclock-cap {
  font-family: 'Oswald', sans-serif; font-weight: 500;
  font-size: 1rem; letter-spacing: .28em; text-transform: uppercase;
  color: rgba(31,166,222,.92); margin: 0; transition: color .6s ease;
}
body.page-portal-login .pv-cd--band { margin: 0; }
body.page-portal-login .pv-cd--band .pv-cd-row { gap: 0; justify-content: center; }
/* No boxes — the units sit in open space, separated by hairline rules, so the
   clock reads as a typographic lockup rather than a row of widget chips. */
body.page-portal-login .pv-cd--band .pv-cd-unit {
  min-width: 0; padding: 0 clamp(1rem, 3vw, 2.1rem);
  border: 0; border-radius: 0; background: none;
}
body.page-portal-login .pv-cd--band .pv-cd-unit + .pv-cd-unit {
  border-left: 1px solid rgba(31,166,222,.22); transition: border-color .6s ease;
}
body.page-portal-login .pv-cd--band .pv-cd-n {
  font-size: clamp(2.7rem, 8vw, 4.4rem); color: #EAF6FF; letter-spacing: .01em; transition: color .6s ease;
}
body.page-portal-login .pv-cd--band .pv-cd-l {
  font-size: .72rem; letter-spacing: .22em; margin-top: .55rem; color: rgba(233,238,247,.42);
}

/* Seconds pulse — retriggered from JS each tick (class re-added after a reflow). */
@keyframes pv-cd-tick { 0% { transform: scale(1); } 30% { transform: scale(1.16); } 100% { transform: scale(1); } }
body.page-portal-login .pv-cd--band .pv-cd-s { display: inline-block; }
body.page-portal-login .pv-cd--band .pv-cd-s.is-tick { animation: pv-cd-tick .4s ease; }
@media (prefers-reduced-motion: reduce) {
  body.page-portal-login .pv-cd--band .pv-cd-s.is-tick { animation: none; }
}

/* Inside 48h: the whole band warms to red — the shift itself is the message. */
body.page-portal-login .pv-serveclock.is-urgent {
  border-top-color: rgba(206,17,38,.45);
  border-bottom-color: rgba(206,17,38,.45);
  background: radial-gradient(78% 150% at 50% 50%, rgba(206,17,38,.15), transparent 72%);
}
body.page-portal-login .pv-serveclock.is-urgent .pv-serveclock-cap { color: rgba(255,107,107,.95); }
body.page-portal-login .pv-serveclock.is-urgent .pv-cd-n { color: #FF6B6B; }
body.page-portal-login .pv-serveclock.is-urgent .pv-cd--band .pv-cd-unit + .pv-cd-unit { border-left-color: rgba(206,17,38,.45); }

@media (max-width: 560px) {
  body.page-portal-login .pv-serveclock { padding: 1.9rem .75rem 2rem; margin: 2rem 0 2.25rem; }
  body.page-portal-login .pv-serveclock-cap { font-size: .82rem; letter-spacing: .2em; }
  body.page-portal-login .pv-cd--band .pv-cd-row { gap: 0; }
  body.page-portal-login .pv-cd--band .pv-cd-unit { min-width: 0; flex: 1 1 0; padding: 0 clamp(.4rem, 3vw, 1rem); }
  body.page-portal-login .pv-cd--band .pv-cd-n { font-size: clamp(2rem, 12vw, 2.8rem); }
}

/* ════════════════════════════════════════════════════════════════════
   PORTAL HERO — cinematic full-bleed band (echoes the homepage skyline hero,
   people-focused image). The page content sits inside a centered
   max-width:1100px .container with 32px side padding (set inline in
   header_portal.php). This hero lives inside that container but breaks out to
   the full viewport width with a padding-aware negative margin, so it reads as
   an edge-to-edge cinematic band like the main site — without the 100vw +
   scrollbar horizontal-overflow bug (the calc negates BOTH the centering gap
   and the container's 32px padding).
   ════════════════════════════════════════════════════════════════════ */
body.page-portal-login .pv-hero {
  position: relative;
  /* Full-bleed break-out from the centered max-width:1100px .container.
     Uses (50% - 50vw) to reach each viewport edge, then adds back HALF the
     scrollbar width (--sbw, set by a tiny script in index.php; defaults to 0
     for overlay-scrollbar / mobile). This is scrollbar-gutter:stable–aware:
     100vw includes the reserved gutter while the content area excludes it, so
     without the correction the band overshoots and forces horizontal scroll. */
  margin-left:  calc(50% - 50vw + (var(--sbw, 0px) / 2));
  margin-right: calc(50% - 50vw + (var(--sbw, 0px) / 2));
  width: auto;
  margin-top: -0.5rem;          /* tuck up under the header bar */
  margin-bottom: 2.75rem;
  min-height: 460px;
  display: flex;
  align-items: flex-end;
  overflow: clip;   /* clip (not hidden) fully contains the scale(1.10) bg layer
                       without leaving a phantom few-px in scrollWidth */
  border-radius: 0;
}
body.page-portal-login .pv-hero-bg {
  position: absolute; inset: 0;
  background-size: cover;
  /* Charlotte night skyline (2000x1044, aspect 1.92) sits cleanly in the wide
     band. Anchored at 22% (not centered) so the building tops — including the
     tall Bank of America tower crown — sit fully in frame with night sky above;
     centering clipped the peaks. The drift's slight downward Y only adds sky
     headroom, so tops never clip through the animation. */
  background-position: 50% 22%;
  transform: scale(1.04);
  animation: pvHeroDrift 26s ease-in-out infinite alternate;
}
@keyframes pvHeroDrift {
  from { transform: scale(1.04) translate3d(0, 0, 0); }
  to   { transform: scale(1.10) translate3d(-1.5%, 0.5%, 0); }
}
@media (prefers-reduced-motion: reduce) {
  body.page-portal-login .pv-hero-bg { animation: none; }
}
/* Directional scrim: dark from the bottom-left where the text sits, clearing
   toward the upper-right so the faces in the photo stay visible. Mirrors the
   homepage hero's legibility scrim. */
body.page-portal-login .pv-hero-scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(to top, rgba(7,11,20,.92) 0%, rgba(7,11,20,.55) 42%, rgba(7,11,20,.12) 72%, rgba(7,11,20,.30) 100%),
    linear-gradient(to right, rgba(7,11,20,.70) 0%, rgba(7,11,20,.20) 55%, rgba(7,11,20,0) 100%);
}
/* Gold hairline seam at the base — the brand's signature accent, same as the
   main site's section rules. */
body.page-portal-login .pv-hero::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: linear-gradient(to right, transparent, rgba(216,168,90,.85) 22%, rgba(216,168,90,.85) 78%, transparent);
}
body.page-portal-login .pv-hero-inner {
  position: relative; z-index: 2;
  width: 100%;
  max-width: 1080px;   /* 1000px content + 2×40px padding → hero text lands on the same 1000 spine as the nav + sections */
  margin: 0 auto;
  padding: 2.5rem 40px 2.25rem;
  box-sizing: border-box;
}
body.page-portal-login .pv-hero-eyebrow {
  font-family: 'Oswald', sans-serif;
  font-weight: 800; font-size: .9rem;
  letter-spacing: .26em; text-transform: uppercase;
  color: var(--h2h-gold);
  margin-bottom: .5rem;
  text-shadow: 0 1px 12px rgba(0,0,0,.5);
}
body.page-portal-login .pv-hero-title {
  font-family: 'Barlow Condensed','Bebas Neue',sans-serif;
  font-weight: 600;
  font-size: clamp(2.4rem, 6.5vw, 4rem);
  line-height: 1.02; letter-spacing: .005em;
  color: #fff; margin: 0 0 .6rem;
  text-shadow: 0 2px 22px rgba(0,0,0,.55);
}
body.page-portal-login .pv-hero-title em { font-style: normal; color: var(--h2h-gold); }
body.page-portal-login .pv-hero-serif {
  font-family: 'Fraunces', Georgia, serif;
  font-weight: 300; font-style: italic;
  font-size: clamp(1.05rem, 2.4vw, 1.5rem);
  color: rgba(244,239,228,.92);
  margin: 0 0 .35rem;
  text-shadow: 0 1px 14px rgba(0,0,0,.5);
}
/* Hero call-to-action row (mirrors the left-aligned hero text) */
body.page-portal-login .pv-hero-cta {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 1rem 1.5rem; margin-top: 1.4rem;
}
body.page-portal-login .pv-hero-signin {
  font-size: 1.05rem; line-height: 1.4;
  color: rgba(244,239,228,.85); text-decoration: none;
  text-shadow: 0 1px 12px rgba(0,0,0,.5);
  transition: color .18s ease;
}
body.page-portal-login .pv-hero-signin strong { font-weight: 600; color: #F4EFE4; }
body.page-portal-login .pv-hero-signin:hover,
body.page-portal-login .pv-hero-signin:hover strong { color: var(--h2h-gold); }
@media (max-width: 560px) {
  body.page-portal-login .pv-hero { min-height: 360px; margin-bottom: 2rem; }
  body.page-portal-login .pv-hero-inner { padding: 1.75rem 20px 1.6rem; }
}

/* ════════════════════════════════════════════════════════════════════
   PORTAL SECTION HEADERS — reuse the main site's .main-section-header--editorial
   (gradient bar + Oswald kicker + Barlow italic-accent title) so section heads
   are visually identical to the homepage. Two portal-specific tweaks:
   (1) force the gradient bar's reveal open — the main site animates it via a
       scroll-reveal JS class (.is-visible) that doesn't run on this page, so we
       pin it open here; (2) support an optional right-aligned action button
       (refresh / FAQ toggle) by extending the 2-col grid to 3 cols.
   ═══════════════════════════════════════════════════════════════════ */
/* Pin the bar open regardless of scroll-reveal JS. */
body.page-portal-login .pv-mse .mse-bar { clip-path: inset(0 round 3px) !important; }
/* Tighten the bar height for these lighter section heads (main site uses 96px
   for big story headers; portal sections are more compact). */
body.page-portal-login .pv-mse { margin: 0 0 1.5rem; max-width: 100%; }
body.page-portal-login .pv-mse .mse-bar { min-height: 62px; }
body.page-portal-login .pv-mse .mse-title { font-size: clamp(1.7rem, 3.4vw, 2.4rem); }
body.page-portal-login .pv-mse .mse-kicker { font-family: 'Oswald', sans-serif; font-weight: 600; }
/* With a right-side action button: bar | head | action */
body.page-portal-login .pv-mse--withaction {
  grid-template-columns: auto minmax(0,1fr) auto;
  align-items: center;
}
body.page-portal-login .pv-mse-action { align-self: center; flex-shrink: 0; }

/* ═══════════════════════════════════════════════════════════
   PORTAL / ADMIN SECTION HEADERS (logged-in section-portal + section-admin) — the homepage
   editorial header, scoped to the portal so it never touches the main site.
   Growing brand bar + Barlow Condensed display title + optional one-line sub.
   The bar draws downward on page load via the shared h2hBarDraw keyframe (the
   portal has no scroll-reveal). Compact sizing for utility pages. Guest login
   carries the same look via styles-main's .mse-* (section-main); this is its
   section-portal + section-admin twin. Self-contained (literal sizes, no --ed-* vars). */
body.section-portal .main-section-header--editorial,
body.section-admin .main-section-header--editorial {
  text-align: left;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: clamp(1rem, 2.5vw, 1.6rem);
  align-items: stretch;
  max-width: 100%;
  margin: 0 0 1.75rem;
}
body.section-portal .main-section-header--editorial .mse-bar,
body.section-admin .main-section-header--editorial .mse-bar {
  width: 6px;
  align-self: stretch;
  min-height: 60px;
  border-radius: 3px;
  background: linear-gradient(#CE1126 0%, #D8A85A 50%, #1FA6DE 100%);
  box-shadow: 0 0 18px -3px rgba(216,168,90,.55);
  animation: h2hBarDraw .85s cubic-bezier(.22,.61,.36,1) .1s both;
}
body.section-portal .main-section-header--editorial .mse-head,
body.section-admin .main-section-header--editorial .mse-head { min-width: 0; }
body.section-portal .main-section-header--editorial .mse-title,
body.section-admin .main-section-header--editorial .mse-title {
  font-family: 'Barlow Condensed', 'Bebas Neue', sans-serif;
  font-size: clamp(1.85rem, 3.6vw, 2.5rem);
  font-weight: 600;
  line-height: 1.03;
  letter-spacing: .005em;
  color: #f4efe4;
  margin: 0;
}
body.section-portal .main-section-header--editorial .mse-title em,
body.section-admin .main-section-header--editorial .mse-title em { font-style: normal; color: var(--h2h-gold, #D8A85A); }
body.section-portal .main-section-header--editorial .mse-sub,
body.section-admin .main-section-header--editorial .mse-sub {
  font-size: 1rem;
  color: rgba(206,214,228,.80);
  max-width: 62ch;
  margin: .55rem 0 0;
  line-height: 1.6;
}
@media (prefers-reduced-motion: reduce) {
  body.section-portal .main-section-header--editorial .mse-bar,
  body.section-admin .main-section-header--editorial .mse-bar { animation: none; clip-path: none; }
}
@media (max-width: 760px) {
  body.section-portal .main-section-header--editorial,
  body.section-admin .main-section-header--editorial { column-gap: 1rem; }
  body.section-portal .main-section-header--editorial .mse-sub,
  body.section-admin .main-section-header--editorial .mse-sub { max-width: 100%; }
}

/* ═══ DASHBOARD — compact modern layout (body.page-portal-dashboard) ═══
   A glanceable cockpit, not a magazine: one hero (greeting + status), a slim
   quick-action row, then a two-column working area (events primary + guest-book
   / FAQ sidebar). Restrained flat panels, quiet labels. */
/* Portal content spine — caps at the shared --container so page content lines
   up with the nav (both centered on the main-site spine). Side gutter comes
   from the .container band, matching the homepage. */
body.section-portal .dash-wrap {
  max-width: var(--container);
  margin-inline: auto;
}

/* ── Content spine ─────────────────────────────────────────────
   Body content aligns with the heading TEXT, not the accent rail. The rail
   sits at the container edge; the title is inset by (rail + gap); so page
   content gets that same inset and shares the title's left edge, while the
   header breaks back out so its rail returns to the edge. Mirrors the homepage,
   where the bar rails the gutter and title + content share one spine. Scoped
   via :has() to editorial-header pages (the dashboard runs its own .dash-hero
   grid and is left alone). padding-top gives every page the same breathing
   room below the sticky nav. */
body.section-portal .dash-wrap:has(> .main-section-header--editorial),
body.section-admin  .dash-wrap:has(> .main-section-header--editorial) {
  padding-top: 1.5rem;
  padding-left: calc(6px + clamp(1.1rem, 3vw, 1.75rem));
}
body.section-portal .dash-wrap > .main-section-header--editorial,
body.section-admin  .dash-wrap > .main-section-header--editorial {
  max-width: 100%;
  margin: 0 0 2.75rem;
  margin-left: calc(-1 * (var(--ed-bar) + var(--ed-gap)));
}
@media (max-width: 760px) {
  body.section-portal .dash-wrap:has(> .main-section-header--editorial),
  body.section-admin  .dash-wrap:has(> .main-section-header--editorial) {
    padding-left: calc(6px + 1rem);
  }
  body.section-portal .dash-wrap > .main-section-header--editorial,
  body.section-admin  .dash-wrap > .main-section-header--editorial {
    margin-left: calc(-6px - 1rem);
  }
}
body.page-portal-dashboard .dash-wrap {
  padding: .5rem 0 4rem;
  /* LEFT-MARGIN FIX (2026-07-18): dash-wrap's children (quick actions, next-shift
     banner, the events/guest-book grid) sat flush with the hero's accent bar
     (x = rail edge) instead of the heading text (x = rail + this same gap),
     because dashboard.php uses its own .dash-hero grid instead of
     .main-section-header--editorial, so it never picked up the wrap-level
     inset that component gets elsewhere. --dash-inset expresses that same
     amount in one place; .dash-hero cancels it via negative margin (below) so
     its bar still reaches the true left edge. The mobile breakpoint redefines
     --dash-inset to match the hero's own stacked-layout padding instead of
     hardcoding a second value that could drift out of sync. */
  --dash-inset: calc(6px + clamp(1.25rem, 3vw, 2.25rem));
  padding-left: var(--dash-inset);
}
/* REGRESSION FIX (2026-07-18): this used to cap dash-wrap's children at
   max-width:1080px, left-anchored with no centering. The comment here claimed
   that matched "the main site's capped content columns," but measuring
   against index.php shows the main site's content spine runs the FULL
   --container width (1312px), right edge flush with the nav's right edge
   (GIVE button) — nothing on the main site caps narrower and left-anchors
   the way this rule did. That mismatch is what created the oversized empty
   margin on the right of every dashboard panel that index.php doesn't have.
   Dropping the cap so the dashboard uses the same full spine as every other
   portal page and the main site — .dash-grid's fluid fr-based columns and
   the flat .dash-panel cards have no fixed pixel widths, so they take the
   extra room cleanly with no layout breakage. */
/* ── Hero: greeting beside status ─────────────────────────── */
body.page-portal-dashboard .dash-hero {
  display: grid;
  grid-template-columns: 6px minmax(0,1fr) auto;
  align-items: center;
  gap: clamp(1.25rem, 3vw, 2.25rem);
  padding: 1.75rem 0 2rem;
  margin-bottom: 1.5rem;
  margin-left: calc(-1 * var(--dash-inset));   /* cancels dash-wrap's padding-left so the bar still hits the true edge */
  border-bottom: 1px solid rgba(233,238,247,.10);
}
/* Growing brand bar — the portal heading signature. Draws downward (red -> gold
   -> blue) once on page load, echoing the homepage editorial headers (which draw
   on scroll-reveal). Shared by the dashboard hero and the section heads below.
   prefers-reduced-motion: shown fully, no draw. */
@keyframes h2hBarDraw {
  from { clip-path: inset(0 0 100% 0 round 3px); }
  to   { clip-path: inset(0 0 0 0 round 3px); }
}
body.page-portal-dashboard .dash-hero-bar {
  align-self: stretch;
  min-height: 92px;
  border-radius: 3px;
  background: linear-gradient(#CE1126 0%, #D8A85A 50%, #1FA6DE 100%);
  box-shadow: 0 0 18px -3px rgba(216,168,90,.55);
  animation: h2hBarDraw .85s cubic-bezier(.22,.61,.36,1) .1s both;
}
@media (prefers-reduced-motion: reduce) {
  body.page-portal-dashboard .dash-hero-bar { animation: none; clip-path: none; }
}
body.page-portal-dashboard .dash-hero-lead { min-width: 0; }
body.page-portal-dashboard .dash-hero-kicker {
  font-family: 'Oswald', sans-serif;
  font-size: .78rem; font-weight: 500; letter-spacing: .22em; text-transform: uppercase;
  color: var(--h2h-gold, #D8A85A);
  margin-bottom: .5rem;
}
body.page-portal-dashboard .dash-hero-title {
  font-family: 'Barlow Condensed', 'Bebas Neue', sans-serif;
  font-size: clamp(1.85rem, 3.4vw, 2.6rem);
  font-weight: 600; line-height: 1.02; letter-spacing: .005em;
  color: #f4efe4; margin: 0;
}
body.page-portal-dashboard .dash-hero-since {
  font-size: .98rem; color: rgba(206,214,228,.78);
  margin: .6rem 0 0; line-height: 1.5;
}
body.page-portal-dashboard .dash-hero-since strong { color: rgba(233,238,247,.92); font-weight: 600; }

/* Streak → compact pill */
body.page-portal-dashboard .dash-streak {
  display: inline-flex; align-items: center; gap: .5rem;
  margin-top: .9rem;
  padding: .35rem .7rem;
  background: rgba(216,168,90,.10);
  border: 1px solid rgba(216,168,90,.28);
  border-radius: 999px;
}
body.page-portal-dashboard .dash-streak-flame { font-size: 1rem; line-height: 1; margin: 0; }
body.page-portal-dashboard .dash-streak-text {
  font-size: .8rem; font-weight: 600; letter-spacing: .02em;
  color: rgba(233,238,247,.9); margin: 0;
}

/* Hero status cluster: ring + milestone */
body.page-portal-dashboard .dash-hero-stat {
  display: flex; align-items: center; gap: 1.25rem;
  flex-shrink: 0;
  padding: 1.15rem 1.35rem;
  background: rgba(255,255,255,.03);
  border: 1px solid rgba(255,255,255,.09);
  border-radius: 16px;
}
body.page-portal-dashboard .dash-ring-wrap { position: relative; flex-shrink: 0; }
body.page-portal-dashboard .dash-hero-milestone { min-width: 190px; }

/* ── Next shift callout ───────────────────────────────────── */
body.page-portal-dashboard .dash-nextshift:not(.d-none) { margin-bottom: 1.5rem; }

/* ── Quick actions: slim chip row ─────────────────────────── */
body.page-portal-dashboard .dash-actions {
  margin: 0 0 2rem;
  padding: 1.1rem clamp(.5rem, 2vw, 1.25rem);
  border-top: 1px solid rgba(233,238,247,.09);
  border-bottom: 1px solid rgba(233,238,247,.09);
}
body.page-portal-dashboard .dash-action-btn {
  border: 0; background: transparent; border-radius: 0;
  padding: .3rem .25rem; gap: .5rem;
  transition: transform .15s ease, color .15s ease;
}
body.page-portal-dashboard .dash-action-btn:hover {
  background: transparent; border-color: transparent; color: #fff;
  transform: translateY(-3px);
}
body.page-portal-dashboard .dash-action-icon { width: 40px; height: 40px; font-size: 1.15rem; }

/* ── Working grid: primary + sidebar ──────────────────────── */
body.page-portal-dashboard .dash-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  gap: 1.5rem;
  align-items: start;
}
body.page-portal-dashboard .dash-side {
  display: flex; flex-direction: column; gap: 1.5rem;
  min-width: 0;
}

/* Restrained flat panel — a shared component used on dashboard.php, my_signups.php,
   and events.php, but this whole block was scoped ONLY to
   body.page-portal-dashboard. On every other portal page these five rules
   silently matched nothing: .dash-panel rendered with zero background, no
   border, no radius, no padding (confirmed live: computed background was
   transparent, border-radius 0, padding 0), and .dash-panel-head rendered as
   a plain block instead of a flex row — title and refresh button just
   stacked on top of each other instead of sitting side by side. That's the
   real reason events.php read as "weird": the section wrapper meant to give
   each panel a card boundary was never actually applying. Widening the scope
   to body.section-portal (every logged-in portal page) instead of just the
   dashboard fixes it everywhere at once, not just on events.php. */
body.section-portal .dash-panel {
  background: rgba(255,255,255,.025);
  border: 1px solid rgba(255,255,255,.08);
  border-radius: 16px;
  padding: 1.5rem 1.6rem;
  min-width: 0;
}
body.section-portal .dash-panel-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-bottom: .35rem;
}
body.section-portal .dash-panel-title {
  font-family: 'Oswald', sans-serif;
  font-size: .95rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: #f4efe4; margin: 0;
}
body.section-portal .dash-panel-note {
  font-size: .82rem; color: rgba(206,214,228,.6);
  margin: 0 0 1.25rem; line-height: 1.45;
}
body.section-portal .dash-sec-action {
  flex-shrink: 0;
  width: 32px; height: 32px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .95rem;
}
body.section-portal .dash-viewall {
  display: inline-flex; align-items: center; gap: .5rem;
  margin-top: 1.1rem;
  font-family: 'Oswald', sans-serif;
  font-size: .76rem; font-weight: 500; letter-spacing: .14em; text-transform: uppercase;
  color: var(--h2h-gold, #D8A85A); text-decoration: none;
}
body.section-portal .dash-viewall:hover { color: #e9c785; }

/* Guest Book — stacked fields, roomy list */
body.page-portal-dashboard .dash-guest-fields {
  display: flex; flex-direction: column; gap: .85rem;
}
body.page-portal-dashboard .dash-guest-fields .cf-float { margin-bottom: 0; }
body.page-portal-dashboard .dash-guest-add {
  width: 100%; justify-content: center;
  height: 46px; font-size: .9rem; border-radius: 12px;
}
body.page-portal-dashboard .dash-guest-list { margin-top: 1.5rem; }
body.page-portal-dashboard .dash-guest-list > * + * { margin-top: .6rem; }

/* Upcoming Events — clean event list (thumbnail + shift rows) */
body.page-portal-dashboard .dash-ev {
  display: flex; gap: 1rem;
  padding: 1.15rem 0;
  border-top: 1px solid rgba(233,238,247,.08);
  color: inherit; text-decoration: none;
}
body.page-portal-dashboard .dash-ev:first-child { border-top: 0; padding-top: .25rem; }
body.page-portal-dashboard .dash-ev:hover .dash-ev-title { color: #E7C98A; }
body.page-portal-dashboard .dash-ev .evt-thumb { flex: 0 0 84px; width: 84px; height: 84px; border-radius: 12px; }
body.page-portal-dashboard .dash-ev-body { min-width: 0; flex: 1; }
body.page-portal-dashboard .dash-ev-title {
  font-size: 1.05rem; font-weight: 600; color: var(--h2h-gold, #D8A85A);
  line-height: 1.25; margin-bottom: .55rem; transition: color .15s ease;
}
body.page-portal-dashboard .dash-ev-shifts { margin-top: .1rem; }
body.page-portal-dashboard .dash-ev-shift {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem;
  padding: .55rem 0;
  border-top: 1px solid rgba(233,238,247,.06);
}
body.page-portal-dashboard .dash-ev-shift:first-child { border-top: 0; padding-top: .15rem; }
body.page-portal-dashboard .dash-ev-shift-lead { min-width: 0; display: flex; flex-direction: column; gap: .15rem; }
body.page-portal-dashboard .dash-ev-shift-title { font-size: .88rem; font-weight: 600; color: rgba(233,238,247,.92); }
body.page-portal-dashboard .dash-ev-shift-when { font-size: .78rem; color: rgba(206,214,228,.7); }
body.page-portal-dashboard .dash-ev-shift-addr { display: flex; align-items: center; gap: .3rem; font-size: .74rem; color: rgba(206,214,228,.5); }
body.page-portal-dashboard .dash-ev-shift-addr i { color: rgba(206,214,228,.4); font-size: .8rem; flex-shrink: 0; }
body.page-portal-dashboard .dash-ev-shift-cap { display: flex; align-items: center; gap: .6rem; flex-shrink: 0; padding-top: .2rem; }
body.page-portal-dashboard .dash-ev-meter {
  display: block; width: 72px; height: 4px; border-radius: 999px;
  background: rgba(255,255,255,.12); overflow: hidden;
}
body.page-portal-dashboard .dash-ev-meter-fill { display: block; height: 100%; border-radius: 999px; background: #10B981; }
body.page-portal-dashboard .dash-ev-meter-fill.warn { background: var(--h2h-gold, #D8A85A); }
body.page-portal-dashboard .dash-ev-meter-fill.full { background: var(--h2h-red, #CE1126); }
body.page-portal-dashboard .dash-ev-spots { font-size: .72rem; color: rgba(206,214,228,.6); white-space: nowrap; }
body.page-portal-dashboard .dash-ev-spots.full { color: rgba(255,120,120,.9); }
@media (max-width: 560px) {
  body.page-portal-dashboard .dash-ev { gap: .8rem; }
  body.page-portal-dashboard .dash-ev .evt-thumb { flex-basis: 64px; width: 64px; height: 64px; }
  body.page-portal-dashboard .dash-ev-shift { flex-direction: column; gap: .35rem; }
  body.page-portal-dashboard .dash-ev-shift-cap { padding-top: 0; }
}


/* ── Responsive ───────────────────────────────────────────── */
@media (max-width: 900px) {
  body.page-portal-dashboard .dash-grid { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  body.page-portal-dashboard .dash-wrap {
    --dash-inset: 1.1rem;   /* matches the hero's own stacked padding-left below, so the two stay in sync */
  }
  body.page-portal-dashboard .dash-hero {
    display: block;
    position: relative;
    padding: 1.5rem 0 1.75rem 1.1rem;
  }
  /* Keep the growing brand bar as the left accent (matching the section heads),
     absolutely positioned to span the stacked hero. Replaces the old flat gold
     border so the gradient + on-load draw are consistent across the portal. */
  body.page-portal-dashboard .dash-hero-bar {
    display: block;
    position: absolute;
    left: 0; top: 1.5rem; bottom: 1.75rem;
    width: 5px; min-height: 0;
  }
  body.page-portal-dashboard .dash-hero-stat { margin-top: 1.5rem; }
  body.page-portal-dashboard .dash-hero-milestone { min-width: 0; flex: 1; }
}

/* ═══ EVENTS PAGE — "Save the Date" cards (events.php) ═══
   REBUILT (2026-07-18) to reuse index.php's own Save-the-Date card language
   (the leaner left-rail card, not a boxed panel) instead of the one-off card
   treatment from the previous pass — same values as body.page-main-home's
   .evt-up-* rules in styles-main.css, ported here since the portal doesn't
   load that stylesheet. Two additions beyond the homepage version: the event
   description (the one thing that layout doesn't show, but volunteers here
   need more actionable detail), and a real two-button action row ("Remind me
   to sign up" for the sign-up-open date, "Add event to calendar" for the
   event itself) instead of the old single combined reminder button. */
.events-group-label {
  font-family: 'Oswald', sans-serif;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(206,214,228,.55);
  margin: 0 0 .75rem;
}
body.page-portal-events .evt-upcoming-rail {
  display: flex;
  flex-wrap: wrap;
  gap: 1.1rem;
}
@media (max-width: 480px) {
  body.page-portal-events .evt-up-card { flex-basis: 100%; max-width: none; }
}
body.page-portal-events .evt-up-card {
  flex: 1 1 240px;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: .3rem;
  padding: .2rem 0 .2rem 1rem;
  border-left: 2px solid rgba(216,168,90,.35);
}
body.page-portal-events .evt-up-date { display: flex; align-items: baseline; gap: .4rem; margin-bottom: .15rem; }
body.page-portal-events .evt-up-mon {
  font-family: 'Barlow Condensed', sans-serif;
  text-transform: uppercase;
  letter-spacing: .1em;
  font-size: .8rem;
  color: var(--h2h-gold, #D8A85A);
}
body.page-portal-events .evt-up-day {
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  font-size: 1.5rem;
  color: #f4efe4;
  line-height: 1;
}
body.page-portal-events .event-eyebrow {
  font-family: 'Oswald', sans-serif;
  font-weight: 700;
  font-size: .78rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--h2h-gold, #D8A85A);
}
body.page-portal-events .evt-up-title {
  font-family: 'Barlow Condensed', sans-serif;
  font-weight: 600;
  font-size: 1.1rem;
  color: #f4efe4;
  line-height: 1.15;
}
/* Portal-only addition — index.php's version doesn't show this. Clamped to 3
   lines so a long description can't blow out the card's height. */
body.page-portal-events .evt-up-desc {
  font-size: .85rem;
  line-height: 1.5;
  color: rgba(206,214,228,.72);
  margin: .15rem 0 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
body.page-portal-events .evt-up-opens { font-size: .8rem; color: rgba(233,238,247,.55); }
body.page-portal-events .evt-up-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-top: .45rem;
}
body.page-portal-events .evt-up-pill {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .35rem .8rem;
  border: 1px solid rgba(255,255,255,.16);
  border-radius: 999px;
  background: transparent;
  color: rgba(233,238,247,.8);
  font-family: 'Barlow Condensed', sans-serif;
  text-transform: uppercase;
  letter-spacing: .05em;
  font-size: .74rem;
  cursor: pointer;
  transition: border-color .18s ease, color .18s ease, background .18s ease;
}
body.page-portal-events .evt-up-pill:hover { border-color: rgba(216,168,90,.5); color: #fff; }
body.page-portal-events .evt-up-pill i { font-size: .95em; }

/* Subhead runs full width on this page instead of the sitewide 62ch reading
   cap — the copy here is a short set of instructions, not an article lede,
   so wrapping it into a narrow 3-line column just wastes the header row's
   width. */
body.page-portal-events .main-section-header--editorial .mse-sub {
  max-width: 100%;
}

/* ═══ MY SIGNUPS — Upcoming / Impact segmented tabs ═══
   Un-merging the old combined page: only one panel is ever visible, so the
   Impact tab's confetti/lifetime-hours moment stops competing with the
   day-to-day Upcoming list for the same scroll. */
body.page-portal-my-signups .my-signups-tabs {
  display: inline-flex;
  gap: .25rem;
  padding: .3rem;
  border: 1px solid rgba(255,255,255,.10);
  border-radius: 999px;
  background: rgba(255,255,255,.03);
  margin: 1.5rem 0 1.75rem;
}
body.page-portal-my-signups .my-signups-tab {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .55rem 1.15rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: rgba(233,238,247,.65);
  font-family: 'Oswald', sans-serif;
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .18s ease, color .18s ease;
}
body.page-portal-my-signups .my-signups-tab i { font-size: 1em; }
body.page-portal-my-signups .my-signups-tab:hover { color: #fff; }
body.page-portal-my-signups .my-signups-tab.is-active {
  background: var(--h2h-gold, #D8A85A);
  color: #1a1408;
  box-shadow: 0 2px 10px rgba(216,168,90,.35);
}
@media (max-width: 480px) {
  body.page-portal-my-signups .my-signups-tabs { width: 100%; }
  body.page-portal-my-signups .my-signups-tab { flex: 1 1 0; justify-content: center; }
}

/* ═══ EVENTS PAGE — "My Signups" glance strip ═══
   Condensed status banner above the two-column row: answers "am I already
   signed up for something" at a glance, without a full list and without
   leaving the page. Full management still lives on My Signups (linked). */
body.page-portal-events .my-signups-glance {
  display: flex;
  align-items: center;
  gap: .85rem;
  padding: .85rem 1.25rem;
  border: 1px solid rgba(255,255,255,.10);
  border-radius: 14px;
  background: rgba(216,168,90,.06);
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
}
body.page-portal-events .my-signups-glance-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 10px;
  background: rgba(216,168,90,.15);
  color: var(--h2h-gold, #D8A85A);
  font-size: 1.05rem;
  flex-shrink: 0;
}
body.page-portal-events .my-signups-glance-text {
  flex: 1 1 auto;
  min-width: 0;
  font-size: .92rem;
  color: rgba(233,238,247,.88);
}
body.page-portal-events .my-signups-glance-text strong { color: #fff; font-weight: 600; }
body.page-portal-events .my-signups-glance-cta {
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: 'Oswald', sans-serif;
  font-size: .78rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
  color: var(--h2h-gold, #D8A85A);
  text-decoration: none;
  white-space: nowrap;
  transition: color .18s ease;
}
body.page-portal-events .my-signups-glance-cta:hover { color: #fff; }
body.page-portal-events .my-signups-glance-cta i { transition: transform .18s ease; }
body.page-portal-events .my-signups-glance-cta:hover i { transform: translateX(3px); }
@media (max-width: 560px) {
  body.page-portal-events .my-signups-glance { flex-direction: column; align-items: flex-start; }
  body.page-portal-events .my-signups-glance-cta { align-self: flex-start; }
}

/* ═══ EVENTS PAGE — "You're signed up" badge on open-list cards ═══
   Answers the self-vs-guest confusion at the point of browsing, before the
   volunteer ever opens the shift panel or sees the Guest Book section. */
body.page-portal-events .signedup-badge {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  margin-top: .4rem;
  font-family: 'Oswald', sans-serif;
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: #34D399;
}
body.page-portal-events .signedup-badge i { font-size: 1.05em; }
