:root {
  /* Club identity palette — pulled from the club's own Dashain/Tihar banners,
     bunting, and traditional dress: deep maroon + festival gold. */
  --color-maroon-900: #3a0d0d;
  --color-maroon-800: #551414;
  --color-maroon-700: #7a1d1d;
  --color-maroon-600: #932323;
  --color-red: #b6392f;
  --color-gold: #d9a441;
  --color-gold-dark: #c8922f;
  --color-gold-light: #f6e2b0;
  --color-cream: #fdf8f1;
  --color-ivory: #fffaf1;
  --color-tint: #fbeee0;
  --color-text: #2a1a14;
  --color-text-muted: #7a675c;
  --color-border: #ecdfca;
  --color-success: #2e7d4f;
  --color-error: #b3261e;
  --radius: 12px;
  --radius-sm: 8px;
  --shadow: 0 4px 16px rgba(58, 13, 13, 0.12);
  --shadow-lg: 0 12px 32px rgba(58, 13, 13, 0.18);
  --font-body: "Inter", "Noto Sans Devanagari", sans-serif;
  --font-display: "Poppins", "Noto Sans Devanagari", sans-serif;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--color-text);
  background: var(--color-cream);
  line-height: 1.6;
}

a {
  color: var(--color-maroon-700);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

img {
  max-width: 100%;
  display: block;
}

.container {
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 1.25rem;
}

/* Decorative bunting strip — echoes the paper-flag garlands used at real club
   events (Dashain/Tihar/Deepawali greeting programs). Pure CSS, no assets. */
.bunting {
  height: 14px;
  background-image:
    linear-gradient(135deg, var(--color-gold) 25%, transparent 25.5%),
    linear-gradient(225deg, var(--color-maroon-700) 25%, transparent 25.5%),
    linear-gradient(45deg, var(--color-gold) 25%, transparent 25.5%),
    linear-gradient(315deg, var(--color-maroon-700) 25%, transparent 25.5%);
  background-position: 0 0, 7px 0, 0 0, 7px 0;
  background-size: 14px 14px;
  background-repeat: repeat-x;
}

/* Navbar */
.navbar {
  background: var(--color-maroon-900);
  color: white;
  position: sticky;
  top: 0;
  z-index: 10;
  box-shadow: var(--shadow);
}

.navbar .container {
  max-width: none;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.6rem 1.5rem;
  gap: 1rem;
  flex-wrap: wrap;
}

.navbar-brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  color: white;
}

.navbar-brand:hover {
  text-decoration: none;
}

.navbar-brand img {
  width: 54px;
  height: 54px;
  border-radius: 50%;
  border: 2px solid var(--color-gold);
}

.navbar-brand-text {
  line-height: 1.25;
}

.navbar-brand-text .name-ne {
  display: block;
  font-weight: 700;
  font-size: 1.05rem;
}

.navbar-brand-text .name-en {
  display: block;
  font-size: 0.75rem;
  color: var(--color-gold-light);
  letter-spacing: 0.03em;
}

.navbar-links {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
}

.navbar-links a {
  color: white;
  font-weight: 500;
  font-size: 0.95rem;
}

.navbar-links a:hover {
  color: var(--color-gold-light);
  text-decoration: none;
}

.navbar-links .btn {
  color: var(--color-maroon-900);
}

.navbar-links .navbar-divider {
  width: 1px;
  height: 20px;
  background: rgba(255, 255, 255, 0.25);
}

.navbar-links form {
  display: inline;
}

/* Language switch — both options always visible, so a Nepali reader who lands on
   the English site can see their own language rather than decode a label first. */
.lang-switch {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 999px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.18);
}

.navbar-links .lang-option {
  /* "नेपाली" sits in the navbar on every page in both languages — same reason
     as .wall-tab-ne, keep it on the face that is already loaded. */
  font-family: "Poppins", sans-serif;
  display: flex;
  align-items: center;
  padding: 0.3rem 0.8rem;
  min-height: 34px;
  font-size: 0.82rem;
  font-weight: 600;
  line-height: 1;
  color: rgba(255, 255, 255, 0.75);
  transition: background 0.2s ease, color 0.2s ease;
}

.navbar-links .lang-option:hover {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  text-decoration: none;
}

.navbar-links .lang-option.is-active {
  background: var(--color-gold);
  color: var(--color-maroon-900);
}

.navbar-links .lang-option:focus-visible {
  outline: 3px solid var(--color-gold-light);
  outline-offset: -3px;
}

/* Devanagari needs more vertical room than Latin and reads better with the Noto
   face leading, so the Nepali site swaps the font stack rather than borrowing
   Inter's metrics for a script it was not drawn for.

   Display is Poppins in both languages. Poppins ships a full Devanagari — so
   putting it first here costs nothing and finally gives Nepali the two-tier
   system English already had: a display face for headings, a text face for
   prose. Noto stays behind it as the fallback, and remains the body face. */
html[lang="ne"] {
  --font-body: "Noto Sans Devanagari", "Inter", sans-serif;
  --font-display: "Poppins", "Noto Sans Devanagari", sans-serif;
}

html[lang="ne"] body {
  line-height: 1.75;
  /* Devanagari sets denser than Latin at the same pixel size — the conjuncts
     carry more detail into the same em — so it needs a nudge to read as the
     same size to the eye. Small on purpose: enough to match, not to shout. */
  font-size: 1.05rem;
}

html[lang="ne"] h1,
html[lang="ne"] h2,
html[lang="ne"] h3 {
  line-height: 1.45;
}

/* The club's own name is always shown in both scripts, so it keeps its own
   fonts regardless of the language being read. Both halves are display text,
   and Poppins covers both scripts — which also means an English visitor, whose
   only Devanagari on the page is this one line, never downloads the 118 KB
   Noto Devanagari file just to render it. */
.navbar-brand-text .name-ne {
  font-family: "Poppins", sans-serif;
}

.navbar-brand-text .name-en {
  font-family: "Poppins", sans-serif;
}

.navbar-links .link-btn {
  background: none;
  border: none;
  padding: 0;
  color: white;
  font: inherit;
  font-weight: 500;
  cursor: pointer;
}

.navbar-links .link-btn:hover {
  color: var(--color-gold-light);
  text-decoration: underline;
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  background: var(--color-gold);
  color: var(--color-maroon-900);
  font-weight: 700;
  padding: 0.65rem 1.4rem;
  border-radius: 999px;
  border: none;
  cursor: pointer;
  font-size: 1rem;
  transition: background 0.2s ease, transform 0.15s ease, box-shadow 0.2s ease;
}

.btn:hover {
  background: var(--color-gold-dark);
  text-decoration: none;
  box-shadow: var(--shadow);
}

.btn:active {
  transform: translateY(1px);
}

.btn:focus-visible {
  outline: 3px solid var(--color-maroon-700);
  outline-offset: 2px;
}

.btn-block {
  width: 100%;
}

.btn-outline {
  background: transparent;
  border: 2px solid white;
  color: white;
}

.btn-outline:hover {
  background: rgba(255, 255, 255, 0.12);
}

.btn-secondary {
  background: transparent;
  border: 2px solid var(--color-maroon-700);
  color: var(--color-maroon-700);
}

.btn-secondary:hover {
  background: var(--color-tint);
}

/* Hero */
.hero {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(circle at 15% 20%, rgba(217, 164, 65, 0.18), transparent 45%),
    linear-gradient(135deg, var(--color-maroon-700), var(--color-maroon-900));
  color: white;
  padding: 4.5rem 0 3.5rem;
  text-align: center;
}

.hero > .container {
  position: relative;
  z-index: 2;
}

.hero .eyebrow {
  display: inline-block;
  color: var(--color-maroon-900);
  background: var(--color-gold);
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  padding: 0.3rem 0.9rem;
  border-radius: 999px;
  margin-bottom: 1.25rem;
}

.hero h1 {
  font-family: var(--font-display);
  font-size: 2.4rem;
  margin: 0 0 0.5rem;
}

.hero .subtitle {
  color: var(--color-gold-light);
  font-size: 1.1rem;
  margin: 0 0 1.5rem;
  font-weight: 500;
}

.hero p.tagline {
  max-width: 640px;
  margin: 0 auto 2rem;
  color: #f2e2d6;
}

.hero-actions {
  display: flex;
  gap: 0.85rem;
  justify-content: center;
  flex-wrap: wrap;
}

.hero-stats {
  display: flex;
  gap: 2.5rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 2.75rem;
  padding-top: 2rem;
  border-top: 1px solid rgba(255, 255, 255, 0.18);
}

.hero-stats .stat-value {
  font-family: var(--font-display);
  font-size: 1.8rem;
  font-weight: 700;
  color: var(--color-gold);
}

.hero-stats .stat-label {
  font-size: 0.82rem;
  color: #e6d6c8;
}

/* Sections */
section.page-section {
  padding: 3.5rem 0;
}

section.page-section.tint {
  background: var(--color-tint);
}

.section-title {
  text-align: center;
  margin-bottom: 2.25rem;
}

.section-title h2 {
  font-family: var(--font-display);
  color: var(--color-maroon-700);
  margin: 0 0 0.25rem;
}

.section-title .en {
  color: var(--color-text-muted);
  font-size: 0.95rem;
}

/* Cards / grid */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1.5rem;
}

.card {
  background: white;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 1.5rem;
  box-shadow: var(--shadow);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
}

.card .card-icon {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  background: var(--color-tint);
  color: var(--color-maroon-700);
  margin-bottom: 0.9rem;
}

.card .card-icon svg {
  width: 24px;
  height: 24px;
}

.card h3 {
  margin: 0 0 0.25rem;
  color: var(--color-maroon-700);
}

.card .muted {
  color: var(--color-text-muted);
  font-size: 0.9rem;
}

/* Photo mosaic (home page real-event imagery) */
.photo-mosaic {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 120px;
  gap: 0.65rem;
}

.photo-mosaic .mosaic-item {
  position: relative;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--color-tint);
  border: 1px solid var(--color-border);
}

.photo-mosaic .mosaic-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.photo-mosaic .mosaic-item.wide {
  grid-column: span 2;
}

.photo-mosaic .mosaic-item.tall {
  grid-row: span 2;
}

.photo-mosaic .mosaic-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: var(--color-text-muted);
  font-size: 0.75rem;
  text-align: center;
  padding: 0.5rem;
}

@media (max-width: 720px) {
  .photo-mosaic {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Gallery */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1.5rem;
}

.gallery-item {
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  background: white;
  border: 1px solid var(--color-border);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.gallery-item:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
}

.gallery-item-thumb {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  background: var(--color-tint);
  overflow: hidden;
}

.gallery-item-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

img[data-lightbox-thumb] {
  cursor: pointer;
}

img[data-lightbox-thumb]:focus-visible {
  outline: 3px solid var(--color-maroon-700);
  outline-offset: -3px;
}

.gallery-item .caption {
  padding: 0.7rem 0.9rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--color-maroon-700);
  background: var(--color-cream);
  border-top: 1px solid var(--color-border);
}

.placeholder-badge {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: var(--color-gold);
  color: var(--color-maroon-900);
  font-size: 0.7rem;
  font-weight: 700;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
}

/* The full-screen photo viewer lives in viewer.css. */

/* Past Presidents — honor roll */
.leaders-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 2.25rem;
  margin-bottom: 3.25rem;
}

.leader-card {
  text-align: center;
  width: 170px;
}

.leader-card .leader-photo {
  width: 116px;
  height: 116px;
  border-radius: 50%;
  overflow: hidden;
  margin: 0 auto 0.85rem;
  border: 3px solid var(--color-gold);
  box-shadow: var(--shadow);
  background: var(--color-tint);
}

.leader-card .leader-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.leader-card .leader-initial {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: 700;
  color: var(--color-maroon-700);
}

.leader-card .leader-badge {
  display: inline-block;
  background: var(--color-gold);
  color: var(--color-maroon-900);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 0.15rem 0.65rem;
  border-radius: 999px;
  margin-bottom: 0.45rem;
}

.leader-card h3 {
  margin: 0 0 0.2rem;
  color: var(--color-maroon-700);
  font-family: var(--font-display);
  font-size: 1.05rem;
}

.leader-card .leader-years {
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

/* Timeline (History page) */
.timeline {
  border-left: 3px solid var(--color-maroon-600);
  margin-left: 1rem;
  padding-left: 1.5rem;
}

.timeline-item {
  position: relative;
  margin-bottom: 2rem;
}

.timeline-item::before {
  content: "";
  position: absolute;
  left: -1.95rem;
  top: 0.3rem;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--color-gold);
  border: 2px solid var(--color-maroon-900);
}

.timeline-item .year {
  font-weight: 700;
  color: var(--color-maroon-700);
}

/* Flash messages */
.flash-messages {
  max-width: 1080px;
  margin: 1rem auto 0;
  padding: 0 1.25rem;
}

.flash {
  background: var(--color-tint);
  border: 1px solid var(--color-gold-dark);
  color: var(--color-maroon-900);
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  margin-bottom: 0.75rem;
}

.flash-error,
.flash-danger {
  background: #fdecea;
  border-color: var(--color-error);
  color: var(--color-error);
}

.flash-success {
  background: #eaf6ee;
  border-color: var(--color-success);
  color: var(--color-success);
}

/* ============ Confirm dialog ============ */
.dialog-overlay {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: grid;
  place-items: center;
  padding: 1.25rem;
  background: rgba(24, 8, 8, 0.55);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity 0.2s ease;
}

.dialog-overlay.is-open {
  opacity: 1;
}

.dialog {
  width: min(420px, 100%);
  background: var(--color-ivory);
  border: 1px solid var(--color-gold);
  border-radius: var(--radius);
  padding: 1.5rem;
  box-shadow: 0 30px 60px -25px rgba(58, 13, 13, 0.7);
  transform: translateY(12px) scale(0.97);
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}

.dialog-overlay.is-open .dialog {
  transform: none;
}

.dialog-title {
  margin: 0 0 0.6rem;
  font-family: "Poppins", sans-serif;
  font-size: 1.15rem;
  color: var(--color-maroon-700);
}

.dialog-preview {
  margin: 0 0 0.9rem;
  border-radius: 3px;
  overflow: hidden;
  border: 1px solid var(--color-border);
  background: var(--color-tint);
}

.dialog-preview img {
  display: block;
  width: 100%;
  max-height: 190px;
  object-fit: cover;
}

.dialog-body {
  margin: 0 0 1.25rem;
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--color-text);
}

.dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.6rem;
}

.btn-danger {
  background: var(--color-error);
  color: #fff;
  border: 2px solid var(--color-error);
}

.btn-danger:hover {
  background: #911d17;
  border-color: #911d17;
  color: #fff;
}

/* ============ Toasts ============ */
.toast-host {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 3100;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.5rem;
  pointer-events: none;
}

.toast {
  max-width: min(360px, calc(100vw - 2rem));
  padding: 0.7rem 1rem;
  border-radius: var(--radius);
  font-size: 0.88rem;
  font-weight: 600;
  background: var(--color-maroon-800);
  color: var(--color-gold-light);
  border: 1px solid var(--color-gold-dark);
  box-shadow: 0 16px 34px -18px rgba(0, 0, 0, 0.8);
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.3s ease, transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

.toast.is-in {
  opacity: 1;
  transform: none;
}

.toast-error {
  background: #7c1c16;
  border-color: var(--color-error);
  color: #ffe6e3;
}

@media (max-width: 520px) {
  .toast-host {
    left: 1rem;
    align-items: stretch;
  }
}

/* ============ Auth pages (login / signup) ============ */
.auth-shell {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: calc(100vh - 260px);
}

.auth-visual {
  position: relative;
  background:
    linear-gradient(rgba(58, 13, 13, 0.55), rgba(58, 13, 13, 0.78)),
    linear-gradient(135deg, var(--color-maroon-700), var(--color-maroon-900));
  color: white;
  padding: 3rem 2.5rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.auth-visual::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    45deg,
    rgba(217, 164, 65, 0.06) 0,
    rgba(217, 164, 65, 0.06) 2px,
    transparent 2px,
    transparent 14px
  );
  pointer-events: none;
}

.auth-visual .auth-visual-content {
  position: relative;
  max-width: 420px;
}

.auth-visual .eyebrow {
  color: var(--color-gold);
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.05em;
  margin-bottom: 0.75rem;
  display: block;
}

.auth-visual h2 {
  font-family: var(--font-display);
  font-size: 1.9rem;
  margin: 0 0 1rem;
}

.auth-visual p {
  color: #f0ded1;
}

.auth-visual .auth-values {
  list-style: none;
  margin: 1.75rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.auth-visual .auth-values li {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  font-size: 0.92rem;
  color: #f2e6da;
}

.auth-visual .auth-values svg {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  color: var(--color-gold);
  margin-top: 0.15rem;
}

.auth-form-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem 2rem;
  background: var(--color-cream);
}

.auth-card {
  width: 100%;
  max-width: 420px;
}

.auth-card h1 {
  font-family: var(--font-display);
  color: var(--color-maroon-700);
  font-size: 1.6rem;
  margin: 0 0 0.25rem;
}

.auth-card .auth-subtitle {
  color: var(--color-text-muted);
  margin: 0 0 1.75rem;
  font-size: 0.95rem;
}

.form-group {
  margin-bottom: 1.15rem;
}

.form-group label {
  display: block;
  font-weight: 600;
  font-size: 0.88rem;
  margin-bottom: 0.35rem;
  color: var(--color-text);
}

.form-group .required {
  color: var(--color-error);
}

.form-control {
  width: 100%;
  padding: 0.7rem 0.85rem;
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: 1rem;
  font-family: var(--font-body);
  background: white;
  color: var(--color-text);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.form-control:focus {
  outline: none;
  border-color: var(--color-maroon-700);
  box-shadow: 0 0 0 3px rgba(122, 29, 29, 0.15);
}

.form-control.is-invalid {
  border-color: var(--color-error);
}

.form-help {
  font-size: 0.8rem;
  color: var(--color-text-muted);
  margin-top: 0.3rem;
}

.form-error {
  font-size: 0.82rem;
  color: var(--color-error);
  margin-top: 0.35rem;
}

.password-field {
  position: relative;
}

.password-field .form-control {
  padding-right: 2.75rem;
}

.password-toggle {
  position: absolute;
  right: 0.6rem;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text-muted);
  padding: 0.35rem;
  display: flex;
  min-width: 44px;
  min-height: 44px;
  align-items: center;
  justify-content: center;
}

.password-toggle svg {
  width: 20px;
  height: 20px;
}

.checkbox-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
  color: var(--color-text-muted);
}

.checkbox-row input {
  width: 18px;
  height: 18px;
  accent-color: var(--color-maroon-700);
}

.auth-links {
  margin-top: 1.5rem;
  text-align: center;
  font-size: 0.92rem;
  color: var(--color-text-muted);
}

.auth-links a {
  font-weight: 600;
  color: var(--color-maroon-700);
}

.auth-status {
  text-align: center;
  padding: 4rem 1.25rem;
  max-width: 520px;
  margin: 0 auto;
}

.auth-status .status-icon {
  width: 64px;
  height: 64px;
  margin: 0 auto 1.25rem;
  border-radius: 50%;
  background: var(--color-tint);
  color: var(--color-maroon-700);
  display: flex;
  align-items: center;
  justify-content: center;
}

.auth-status .status-icon svg {
  width: 32px;
  height: 32px;
}

@media (max-width: 860px) {
  .auth-shell {
    grid-template-columns: 1fr;
  }
  .auth-visual {
    padding: 2.5rem 1.5rem;
  }
}

/* Footer */
.footer {
  background: var(--color-maroon-900);
  color: #e6d3c4;
  padding: 1.75rem 0 1.25rem;
  margin-top: 2rem;
}

.footer .container {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem 2rem;
  /* Top-align the columns so the short ones (address, contact) don't stretch to
     the height of the tallest, which padded the footer out with empty space. */
  align-items: flex-start;
  justify-content: space-between;
}

.footer h4 {
  color: white;
  margin: 0 0 0.75rem;
}

.footer a {
  color: #e6d3c4;
}

.footer .copyright {
  text-align: center;
  margin-top: 1rem;
  font-size: 0.85rem;
  color: #c4a996;
}

/* Error pages */
.error-page {
  text-align: center;
  padding: 5rem 1rem;
}

.error-page h1 {
  color: var(--color-maroon-700);
}

/* ============ Motion ============ */
@media (prefers-reduced-motion: no-preference) {
  /* Scrolling garland — echoes real paper-flag bunting fluttering */
  .bunting {
    animation: bunting-scroll 5s linear infinite;
  }

  @keyframes bunting-scroll {
    from { background-position: 0 0, 7px 0, 0 0, 7px 0; }
    to   { background-position: 14px 0, 21px 0, 14px 0, 21px 0; }
  }

  /* Slow drifting glow behind the hero */
  .hero {
    background-size: 220% 220%;
    animation: hero-glow 14s ease-in-out infinite;
  }

  @keyframes hero-glow {
    0%, 100% { background-position: 0% 50%; }
    50%      { background-position: 100% 50%; }
  }

  /* Staggered hero entrance */
  .hero .eyebrow,
  .hero h1,
  .hero .subtitle,
  .hero p.tagline,
  .hero-actions,
  .hero-stats {
    opacity: 0;
    animation: fade-up 0.7s ease forwards;
  }

  .hero .eyebrow   { animation-delay: 0.05s; }
  .hero h1         { animation-delay: 0.15s; }
  .hero .subtitle  { animation-delay: 0.25s; }
  .hero p.tagline  { animation-delay: 0.35s; }
  .hero-actions    { animation-delay: 0.45s; }
  .hero-stats      { animation-delay: 0.55s; }

  @keyframes fade-up {
    from { opacity: 0; transform: translateY(18px); }
    to   { opacity: 1; transform: translateY(0); }
  }

  /* Scroll-reveal, progressively enhanced (see .js gate below) */
  .js .reveal {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity 0.6s ease, transform 0.6s ease;
    transition-delay: calc(var(--i, 0) * 70ms);
  }

  .js .reveal.is-visible {
    opacity: 1;
    transform: translateY(0);
  }

  /* Button hover shine */
  .btn {
    position: relative;
    overflow: hidden;
  }

  .btn::after {
    content: "";
    position: absolute;
    top: 0;
    left: -60%;
    width: 40%;
    height: 100%;
    background: linear-gradient(115deg, transparent, rgba(255, 255, 255, 0.55), transparent);
    transform: skewX(-20deg);
    transition: left 0.55s ease;
  }

  .btn:hover::after {
    left: 130%;
  }

  /* Card icon lift on hover */
  .card:hover .card-icon {
    transform: translateY(-2px) scale(1.08);
  }

  .card .card-icon {
    transition: transform 0.25s ease;
  }

  /* Photo mosaic hover zoom */
  .photo-mosaic .mosaic-item img,
  .gallery-item-thumb img {
    transition: transform 0.4s ease;
  }

  .photo-mosaic .mosaic-item:hover img,
  .gallery-item:hover .gallery-item-thumb img {
    transform: scale(1.06);
  }
}

/* ============ Framed photos (gallery + admin) ============
   A gilded moulding, an ivory mat, then the photograph — the way the club's
   printed and hung photos actually look. The frame supplies the border and
   shadow, so .gallery-item below is reduced to a plain wrapper. */
.gallery-item {
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
}

.gallery-item:hover {
  box-shadow: none;
}

.photo-frame {
  padding: 7px;
  border-radius: 3px;
  /* Angled gradient reads as a bevelled gilt moulding catching the light. */
  background: linear-gradient(
    145deg,
    #eccd88 0%,
    var(--color-gold) 20%,
    #a1701f 48%,
    var(--color-gold) 76%,
    #eccd88 100%
  );
  box-shadow:
    0 1px 2px rgba(58, 13, 13, 0.28),
    0 10px 22px -10px rgba(58, 13, 13, 0.45);
}

.photo-frame-mat {
  background: var(--color-ivory);
  padding: 11px;
  /* Inner shadow sits the photograph down into the mat rather than on top. */
  box-shadow: inset 0 1px 4px rgba(58, 13, 13, 0.16);
}

.photo-frame .gallery-item-thumb {
  background: var(--color-tint);
  border: 1px solid rgba(58, 13, 13, 0.18);
}

.photo-frame-sm {
  max-width: 240px;
}

.photo-frame-sm .photo-frame-mat {
  padding: 8px;
}

.gallery-item .caption {
  background: none;
  border-top: none;
  padding: 0.75rem 0.2rem 0.2rem;
  text-align: center;
}

@media (max-width: 480px) {
  .photo-frame { padding: 5px; }
  .photo-frame-mat { padding: 7px; }
}

/* ============ Admin: gallery management ============ */
.admin-bar {
  display: flex;
  justify-content: flex-end;
  margin: 0 0 1.75rem;
}

.admin-panel {
  background: white;
  border: 1px solid var(--color-border);
  border-top: 3px solid var(--color-gold);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: clamp(1.35rem, 4vw, 2rem);
  max-width: 720px;
  margin: 0 auto;
}

.admin-panel h2 {
  font-family: var(--font-display);
  color: var(--color-maroon-700);
  margin: 0 0 0.3rem;
}

.admin-panel-hint {
  color: var(--color-text-muted);
  font-size: 0.9rem;
  margin: 0 0 1.5rem;
}

.admin-form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 1.1rem;
}

@media (max-width: 620px) {
  .admin-form-row { grid-template-columns: 1fr; }
}

.file-input {
  padding: 0.6rem;
  cursor: pointer;
  background: var(--color-cream);
}

.file-input::file-selector-button {
  font: inherit;
  font-weight: 700;
  margin-right: 0.9rem;
  padding: 0.5rem 1.1rem;
  border: none;
  border-radius: 999px;
  background: var(--color-gold);
  color: var(--color-maroon-900);
  cursor: pointer;
}

.file-input::file-selector-button:hover {
  background: var(--color-gold-dark);
}

.upload-preview {
  margin-top: 1.1rem;
}

.upload-preview-name {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--color-maroon-700);
  margin: 0 0 0.6rem;
  word-break: break-all;
}

/* Contact-sheet of everything in the pending batch. */
.upload-preview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 0.6rem;
}

.photo-frame-xs .photo-frame-mat {
  padding: 4px;
}

.photo-frame-xs img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* Titles are dropped for a batch upload; dim them so that reads as deliberate. */
.is-muted {
  opacity: 0.55;
  transition: opacity 0.2s ease;
}

.admin-item-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0 0.2rem;
}

.admin-item-actions form {
  margin: 0;
}

/* Per-photo "move to another section" control in the gallery list. */
.admin-refile {
  display: flex;
  gap: 0.4rem;
  margin: 0 0.2rem 0.5rem;
  border-radius: var(--radius);
  transition: box-shadow 0.3s ease;
}

/* Brief gold ring after a successful move, so the change is visible without a
   page reload having announced it. */
.admin-refile.is-saved {
  box-shadow: 0 0 0 2px var(--color-gold);
}

.admin-refile .form-control:disabled,
.admin-refile .btn:disabled {
  opacity: 0.5;
  cursor: progress;
}

/* A deleted card shrinks away instead of the page reloading under the admin. */
.gallery-item.is-leaving {
  transform: scale(0.9);
  opacity: 0;
  transition: transform 0.26s ease-in, opacity 0.26s ease-in;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .gallery-item.is-leaving {
    transition-duration: 0.01ms;
  }
}

.admin-refile .form-control {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 0.8rem;
  padding: 0.35rem 0.5rem;
}

.admin-refile .btn {
  flex: 0 0 auto;
  font-size: 0.78rem;
  padding: 0.35rem 0.75rem;
}

.admin-meta {
  font-size: 0.78rem;
  color: var(--color-text-muted);
  display: block;
}

.btn-danger-link {
  background: none;
  border: none;
  padding: 0.35rem 0;
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-error);
  cursor: pointer;
  text-decoration: underline;
}

.btn-danger-link:hover {
  color: #7d1a14;
}

/* Fix: `.navbar-links .btn` (0,2,0) outranks `.btn-outline` (0,1,0), which left
   the outlined Donate button with maroon text on the maroon navbar — a 1:1
   contrast ratio, i.e. invisible. Restore the outline variant's white text. */
.navbar-links .btn-outline {
  color: white;
}

/* ============ Home hero: full-viewport, backed by a real photograph ============
   Replaces the illustrated greeting figures with a photo of the club's own
   venue — the same bunting, flag and hillside the CSS elsewhere imitates.
   Scoped to .hero-home so History / Alumni / Gallery keep their short banner. */
.hero-home {
  /* The sticky navbar and bunting sit in normal flow above the hero, so their
     height comes off the viewport to make the hero end exactly at the fold.
     svh (not vh) keeps mobile browser chrome from causing a jump. */
  min-height: calc(100vh - 5.5rem);
  min-height: calc(100svh - 5.5rem);
  display: flex;
  align-items: center;
  padding-block: clamp(2.5rem, 7vh, 4.5rem);
  /* Cancels the drifting gradient inherited from .hero — pointless work now
     that an opaque photograph covers that background. */
  animation: none;
}

.hero-home::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: url("../img/gallery/event-3.jpg");
  background-size: cover;
  /* Biased below centre so the club building stays in frame when a wide
     viewport crops the top and bottom off this 4:3 photo. */
  background-position: center 62%;
}

.hero-home::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  /* Maroon veil: heavy enough for white text over a bright sky, and it keeps
     the brand colour rather than washing the photo to plain grey. */
  background:
    linear-gradient(
      rgba(58, 13, 13, 0.72),
      rgba(58, 13, 13, 0.66) 45%,
      rgba(58, 13, 13, 0.86)
    );
}

@media (max-width: 900px) {
  /* The navbar wraps to a second row here (measured 138px + 14px bunting at
     768px wide), so more of the viewport has to come off. */
  .hero-home {
    min-height: calc(100vh - 9.5rem);
    min-height: calc(100svh - 9.5rem);
  }
}

/* Phones: the navbar wraps to ~3 rows here and eats ~200px of the viewport, so
   the hero's own content has to be tightened for it to still land on one
   screen. Sizes drop, vertical rhythm compresses; nothing is hidden. */
@media (max-width: 600px) {
  .hero-home {
    min-height: calc(100vh - 12.5rem);
    min-height: calc(100svh - 12.5rem);
    padding-block: 1.75rem;
  }

  .hero-home .eyebrow {
    font-size: 0.72rem;
    margin-bottom: 0.85rem;
  }

  .hero-home h1 {
    font-size: 1.85rem;
  }

  .hero-home .subtitle {
    font-size: 1rem;
    margin-bottom: 1rem;
  }

  .hero-home p.tagline {
    font-size: 0.95rem;
    margin-bottom: 1.35rem;
  }

  .hero-home .hero-actions {
    gap: 0.6rem;
  }

  .hero-home .hero-stats {
    gap: 1.35rem;
    margin-top: 1.5rem;
    padding-top: 1.15rem;
  }

  .hero-home .hero-stats .stat-value {
    font-size: 1.45rem;
  }
}

/* "What We Do" holds 5 cards. The default auto-fill grid fits 4 across on a
   desktop, stranding the fifth alone at quarter width; capping this one grid at
   3 columns gives a balanced 3 + 2 instead. Scoped so the Alumni page keeps its
   auto-fill behaviour, which suits its variable number of entries. */
@media (min-width: 860px) {
  .card-grid-programs {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* ============ Membership applications ============ */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

textarea.form-control {
  min-height: 6rem;
  resize: vertical;
  line-height: 1.6;
}

.status-pill {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.25rem 0.7rem;
  border-radius: 999px;
  margin-bottom: 0.75rem;
}

.status-pill-pending {
  background: var(--color-tint);
  color: #8a5a12;
  border: 1px solid var(--color-gold-dark);
}

.status-pill-approved {
  background: #eaf6ee;
  color: #1f4e33;
  border: 1px solid var(--color-success);
}

.status-pill-rejected {
  background: #fdecea;
  color: #7d1a14;
  border: 1px solid var(--color-error);
}

.review-note {
  border-left: 3px solid var(--color-gold);
  padding-left: 0.9rem;
  margin: 0 0 1.25rem;
  color: var(--color-text-muted);
  font-style: italic;
}

.application-recap {
  margin-top: 1.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--color-border);
}

.application-recap:empty {
  display: none;
}

.application-recap h3 {
  font-family: var(--font-display);
  color: var(--color-maroon-700);
  font-size: 1.05rem;
  margin: 0 0 0.75rem;
}

.application-card {
  background: white;
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-gold);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: clamp(1.2rem, 3vw, 1.75rem);
  margin-bottom: 1.25rem;
}

.application-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.application-head h3 {
  font-family: var(--font-display);
  color: var(--color-maroon-700);
  margin: 0 0 0.15rem;
}

.application-answers,
.application-recap dl {
  margin: 0;
}

.application-answers dt,
.application-recap dt {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: 0.2rem;
}

.application-answers dd,
.application-recap dd {
  margin: 0 0 1rem;
  white-space: pre-line;
}

.application-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--color-border);
}

/* Note, committee post, and the button. Wraps rather than squeezing three
   controls onto one line on a narrow screen. */
.application-actions form:first-child {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  flex: 1 1 22rem;
  gap: 0.6rem;
}

.application-actions form:first-child input.form-control {
  flex: 1 1 14rem;
}

.application-actions form:first-child select.form-control {
  flex: 0 1 17rem;
}

.admin-table {
  width: 100%;
  border-collapse: collapse;
  background: white;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  overflow: hidden;
}

.admin-table th,
.admin-table td {
  text-align: left;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--color-border);
  font-size: 0.92rem;
  vertical-align: middle;
}

.admin-table th {
  background: var(--color-tint);
  font-size: 0.76rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-maroon-700);
}

.admin-table tr:last-child td {
  border-bottom: none;
}

/* A wide table on a narrow phone scrolls inside its own box rather than pushing
   the whole page sideways. */
.admin-table-scroll {
  overflow-x: auto;
}

/* ---------- Admin sub-navigation ----------
   The admin area grew past the two sections the main navbar could carry, so the
   sections live here instead and the navbar keeps a single "Admin" entry. */
.admin-nav {
  background: var(--color-tint);
  border-bottom: 1px solid var(--color-border);
}

.admin-nav .container {
  display: flex;
  gap: 0.35rem;
  overflow-x: auto;
  scrollbar-width: none;
}

.admin-nav .container::-webkit-scrollbar {
  display: none;
}

.admin-nav-link {
  flex: 0 0 auto;
  padding: 0.85rem 1rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--color-maroon-700);
  border-bottom: 3px solid transparent;
  transition: color 0.2s ease, border-color 0.2s ease;
}

.admin-nav-link:hover {
  text-decoration: none;
  border-bottom-color: var(--color-gold-dark);
}

.admin-nav-link.is-active {
  border-bottom-color: var(--color-gold);
  color: var(--color-maroon-900);
}

/* ---------- Admin list rows ---------- */
.admin-person {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.admin-person-photo {
  position: relative; /* .person-initial fills its box absolutely */
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--color-tint);
}

.admin-person-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.admin-person-photo .person-initial {
  font-size: 1.05rem;
}

.status-pill-neutral {
  background: var(--color-cream);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
}

/* The photo that is live right now, shown beside the replace/remove controls so
   an admin can see what they are about to overwrite. */
.admin-current-photo {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding: 0.9rem;
  margin-bottom: 0.9rem;
  background: var(--color-cream);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

.admin-current-photo img {
  flex: 0 0 auto;
  width: 84px;
  height: 84px;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--color-border);
  background: white;
}

.admin-current-photo .form-help {
  margin-top: 0;
}

/* ---------- Checkbox rows ---------- */
.form-check {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  margin-bottom: 0.75rem;
  cursor: pointer;
}

.form-check input[type="checkbox"] {
  flex: 0 0 auto;
  width: 1.05rem;
  height: 1.05rem;
  margin-top: 0.15rem;
  accent-color: var(--color-maroon-700);
  cursor: pointer;
}

.form-check .form-help {
  margin-top: 0.15rem;
}

/* ---------- Choice grid (membership application) ----------
   Tickable cards rather than a bare checkbox list: the whole card is the label,
   so the tap target is the full row on a phone instead of a 16px box. */
.choice-group {
  border: 0;
  padding: 0;
  margin: 0 0 1.5rem;
}

.choice-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 0.6rem;
  margin-top: 0.75rem;
}

.choice {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: white;
  cursor: pointer;
  transition: border-color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}

.choice:hover {
  border-color: var(--color-gold-dark);
  background: var(--color-cream);
}

.choice input[type="checkbox"] {
  flex: 0 0 auto;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.1rem;
  accent-color: var(--color-maroon-700);
  cursor: pointer;
}

/* :has lets the whole card react to its own checkbox. Browsers without it lose
   the fill but keep the checkbox itself, which is what conveys the state. */
.choice:has(input:checked) {
  border-color: var(--color-gold);
  background: var(--color-tint);
  box-shadow: inset 0 0 0 1px var(--color-gold);
}

.choice:has(input:focus-visible) {
  outline: 3px solid var(--color-gold);
  outline-offset: 2px;
}

.choice-text {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.choice-en {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--color-maroon-700);
  line-height: 1.3;
}

.choice-ne {
  font-family: "Poppins", sans-serif;
  font-size: 0.8rem;
  color: var(--color-text-muted);
  line-height: 1.5;
}

.choice-group.is-invalid .choice {
  border-color: var(--color-error);
}

/* The same choices played back on the status and admin pages. */
.offer-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.offer-pill {
  display: flex;
  flex-direction: column;
  padding: 0.3rem 0.7rem;
  border-radius: var(--radius-sm);
  background: var(--color-tint);
  border: 1px solid var(--color-gold-dark);
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--color-maroon-700);
}

.offer-pill-ne {
  font-family: "Poppins", sans-serif;
  font-size: 0.74rem;
  font-weight: 400;
  color: var(--color-text-muted);
}

/* Heading for a group of checkboxes, which has no single field to label. */
.form-label-standalone {
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--color-maroon-700);
  margin: 0 0 0.6rem;
}

/* ============ Alumni & Committee ============
   Photo, name, and — only when there is something to read — a link through to
   that person's own page. Cards without a recorded contribution stay plain,
   so the link never leads to an empty page. */
.person-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: clamp(1.25rem, 3vw, 2rem);
}

.person-card {
  text-align: center;
}

.person-photo,
.person-detail-photo {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--color-tint);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.person-photo img,
.person-detail-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Monogram stands in until a real photo is uploaded. */
.person-initial {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 7vw, 3.25rem);
  font-weight: 700;
  color: var(--color-maroon-700);
  background: var(--color-tint);
}

.person-name {
  font-family: var(--font-display);
  font-size: 1.02rem;
  color: var(--color-maroon-700);
  margin: 0.85rem 0 0.15rem;
}

.person-role {
  font-size: 0.84rem;
  color: var(--color-text-muted);
  margin: 0;
}

.person-link {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.5rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-maroon-700);
}

.person-link svg {
  width: 14px;
  height: 14px;
  transition: transform 0.2s ease;
}

.person-link:hover svg {
  transform: translateX(3px);
}

.back-link {
  margin: 0 0 1.75rem;
}

.back-link a {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.9rem;
  font-weight: 600;
}

.back-link svg {
  width: 15px;
  height: 15px;
}

/* Detail: portrait and name on the left, the contribution text on the right. */
.person-detail {
  display: grid;
  grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);
  gap: clamp(1.75rem, 5vw, 3.5rem);
  align-items: start;
}

@media (max-width: 760px) {
  .person-detail {
    grid-template-columns: 1fr;
  }
  .person-detail-aside {
    max-width: 18rem;
    margin: 0 auto;
  }
}

.person-detail-aside {
  text-align: center;
}

.person-detail-photo {
  border: none;
  border-radius: 0;
  box-shadow: none;
}

.person-detail-name {
  font-family: var(--font-display);
  font-size: 1.3rem;
  color: var(--color-maroon-700);
  margin: 1rem 0 0.2rem;
}

.person-detail-body h2 {
  font-family: var(--font-display);
  color: var(--color-maroon-700);
  font-size: 1.5rem;
  margin: 0 0 0.4rem;
  padding-bottom: 0.6rem;
  border-bottom: 2px solid var(--color-gold);
}

.person-detail-subhead {
  font-family: var(--font-display);
  color: var(--color-maroon-700);
  font-size: 1.1rem;
  margin: 2rem 0 0.5rem;
}

/* Preserves the line breaks an admin typed, without allowing any markup. */
.prose {
  white-space: pre-line;
  max-width: 38rem;
  margin-top: 1rem;
}

/* ============ Alumni page: history column + current-committee sidebar ======
   The serving committee sits in a sticky panel on the right so "who runs the
   club now" stays visible while you scroll the history on the left. */
.alumni-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 19rem;
  gap: clamp(1.75rem, 4vw, 3rem);
  align-items: start;
}

@media (max-width: 900px) {
  .alumni-layout {
    grid-template-columns: 1fr;
  }
  /* On a narrow screen the sidebar leads, so the current committee is the
     first thing read rather than being buried under the whole archive. */
  .alumni-aside {
    order: -1;
  }
}

/* Section headings inside the two-column layout read better left-aligned than
   centred over a narrow column. */
.section-title-left {
  text-align: left;
  margin-bottom: 1.5rem;
}

.roster {
  background: white;
  border: 1px solid var(--color-border);
  border-top: 3px solid var(--color-gold);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.35rem 1.25rem;
  position: sticky;
  /* Clears the sticky navbar (73px) plus the bunting strip. */
  top: 6.5rem;
}

@media (max-width: 900px) {
  .roster {
    position: static;
  }
}

.roster-heading {
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: var(--color-maroon-700);
  margin: 0 0 0.15rem;
}

.roster-sub {
  font-size: 0.8rem;
  color: var(--color-text-muted);
  margin: 0 0 1rem;
}

.roster-empty {
  font-size: 0.86rem;
  color: var(--color-text-muted);
  margin: 0.75rem 0 0;
}

.roster-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.roster-item {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.7rem 0;
  border-top: 1px solid var(--color-border);
}

.roster-item:first-child {
  border-top: none;
}

/* The sitting president leads the panel and gets a larger portrait. */
.roster-item-lead .roster-photo {
  width: 62px;
  height: 62px;
  border: 2px solid var(--color-gold);
}

.roster-item-lead .roster-name {
  font-size: 1rem;
}

.roster-photo {
  position: relative;
  flex-shrink: 0;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--color-tint);
  border: 1px solid var(--color-border);
}

.roster-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.roster-photo .person-initial {
  font-size: 1.15rem;
}

.roster-item-lead .roster-photo .person-initial {
  font-size: 1.5rem;
}

.roster-text {
  min-width: 0;
}

.roster-name {
  font-family: var(--font-display);
  font-size: 0.92rem;
  color: var(--color-maroon-700);
  margin: 0;
  line-height: 1.35;
}

.roster-role {
  font-size: 0.78rem;
  color: var(--color-text-muted);
  margin: 0.1rem 0 0;
}

.roster-item .person-link {
  margin-top: 0.25rem;
  font-size: 0.78rem;
}

/* Status line under a card's body copy — for a programme that is announced but
   not yet running, so it reads as a notice rather than part of the description. */
.card-note {
  margin: 0.9rem 0 0;
  padding-top: 0.7rem;
  border-top: 1px solid var(--color-border);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-maroon-700);
}

/* ============ Login: the club motto ============
   The left panel carries one line and nothing else. Two animated ideas only —
   the words arrive, then the gold catches the light — per the guidance that a
   view should animate one or two things, not everything. */
.auth-visual-motto {
  align-items: center;
  text-align: center;
  padding: clamp(2.5rem, 6vw, 4rem) clamp(1.5rem, 5vw, 3rem);
}

.motto {
  position: relative;   /* sits above .auth-visual::after's stripe texture */
  z-index: 1;
  margin: 0;
  max-width: 22ch;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.85rem, 4.4vw, 3.15rem);
  line-height: 1.18;
  letter-spacing: -0.01em;
  color: white;
  text-wrap: balance;
}

.motto-line {
  display: block;
}

.motto-word {
  display: inline-block;
  /* Keeps the space between inline-block words, which would otherwise collapse. */
  margin-right: 0.24em;
}

.motto-word:last-child {
  margin-right: 0;
}

/* Solid gold is the base so the club name is legible even if the gradient
   shimmer below never paints. */
.motto-accent {
  color: var(--color-gold);
}

.motto-rule {
  display: block;
  width: 4.5rem;
  height: 2px;
  margin: clamp(1.25rem, 3vw, 1.9rem) auto 0;
  background: linear-gradient(to right, transparent, var(--color-gold), transparent);
}

@media (prefers-reduced-motion: no-preference) {
  /* 1. The words arrive: rise, sharpen, settle. Blur on the way in makes the
        landing feel weighted rather than a plain fade. */
  .motto-word {
    opacity: 0;
    transform: translateY(0.5em);
    filter: blur(8px);
    animation: motto-word-in 0.8s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
  }

  .motto-line:nth-child(1) .motto-word:nth-child(1) { animation-delay: 0.12s; }
  .motto-line:nth-child(1) .motto-word:nth-child(2) { animation-delay: 0.20s; }
  .motto-line:nth-child(1) .motto-word:nth-child(3) { animation-delay: 0.28s; }
  .motto-line:nth-child(2) .motto-word:nth-child(1) { animation-delay: 0.42s; }
  .motto-line:nth-child(2) .motto-word:nth-child(2) { animation-delay: 0.50s; }
  .motto-line:nth-child(2) .motto-word:nth-child(3) { animation-delay: 0.58s; }

  @keyframes motto-word-in {
    from { opacity: 0; transform: translateY(0.5em); filter: blur(8px); }
    to   { opacity: 1; transform: translateY(0);     filter: blur(0); }
  }

  .motto-rule {
    transform: scaleX(0);
    animation: motto-rule-in 0.7s cubic-bezier(0.22, 0.61, 0.36, 1) 0.78s forwards;
  }

  @keyframes motto-rule-in {
    to { transform: scaleX(1); }
  }

  /* 2. The gold catches the light — a slow highlight travelling across the club
        name once the words have settled. */
  .motto-accent {
    background-image: linear-gradient(
      100deg,
      var(--color-gold) 42%,
      #fff2cd 50%,
      var(--color-gold) 58%
    );
    background-size: 300% 100%;
    background-position: 100% 0;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation:
      motto-word-in 0.8s cubic-bezier(0.22, 0.61, 0.36, 1) forwards,
      motto-shine 6s ease-in-out 1.4s infinite;
  }

  @keyframes motto-shine {
    0%, 55%, 100% { background-position: 100% 0; }
    28%           { background-position: 0 0; }
  }
}

/* Browsers without background-clip: text would show nothing once text-fill is
   transparent, so restore a solid gold there. */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .motto-accent {
    -webkit-text-fill-color: var(--color-gold);
    color: var(--color-gold);
  }
}

@media (max-width: 860px) {
  .auth-visual-motto {
    min-height: 42vh;
  }
}

/* ============ Social sign-in ============
   Provider buttons stay on white with their own brand mark, which is what the
   Google and Facebook brand guidelines require and what users recognise. They
   sit above the email form, with a divider marking the alternative. */
.oauth-block {
  /* Sits below the email form, so the breathing room goes above it. */
  margin-top: 1.5rem;
}

.oauth-buttons {
  display: grid;
  gap: 0.65rem;
  /* Sized from the space the card actually gives, not the viewport: two across
     whenever there is room for both, one when there isn't. A viewport media
     query gets this wrong, because the card is a fixed 420px inside a window
     of any width. */
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
}

.oauth-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.65rem;
  min-height: 46px;
  padding: 0.65rem 1.1rem;
  background: white;
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
}

.oauth-btn:hover {
  background: var(--color-ivory);
  border-color: var(--color-maroon-700);
  box-shadow: var(--shadow);
  text-decoration: none;
  color: var(--color-text);
}

.oauth-btn:focus-visible {
  outline: 3px solid var(--color-maroon-700);
  outline-offset: 2px;
}

.oauth-btn svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.oauth-divider {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  /* Divider now introduces the buttons below it, rather than closing them off. */
  margin: 0 0 1.1rem;
  color: var(--color-text-muted);
  font-size: 0.8rem;
}

.oauth-divider::before,
.oauth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--color-border);
}

/* ===================================================================
   Events & Programs
   =================================================================== */

/* Compact upcoming-events preview on the home page. */
.home-events {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.1rem;
}

.home-event-card {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  background: white;
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-gold);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.1rem 1.25rem;
  color: inherit;
  text-decoration: none;
  transition: transform 0.15s ease, box-shadow 0.2s ease;
}

.home-event-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
  text-decoration: none;
}

.home-event-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.home-event-title {
  font-family: var(--font-display);
  color: var(--color-maroon-700);
  font-size: 1.05rem;
  font-weight: 600;
  margin: 0 0 0.25rem;
}

.event-list {
  display: grid;
  gap: 1.25rem;
}

.event-card {
  display: flex;
  gap: 1.25rem;
  background: white;
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-gold);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: clamp(1.1rem, 3vw, 1.5rem);
}

.event-card.is-past {
  border-left-color: var(--color-border);
  box-shadow: none;
  opacity: 0.85;
}

/* The calendar-chip date block. */
.event-date {
  flex: none;
  width: 62px;
  height: 62px;
  border-radius: var(--radius-sm);
  background: var(--color-tint);
  color: var(--color-maroon-700);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

.event-date-day {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 700;
}

.event-date-mon {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-top: 0.15rem;
}

.event-card.is-past .event-date {
  background: var(--color-border);
  color: var(--color-text-muted);
}

.event-body {
  flex: 1;
  min-width: 0;
}

.event-cat {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-maroon-700);
  background: var(--color-gold-light);
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  margin-bottom: 0.5rem;
}

.event-title {
  font-family: var(--font-display);
  color: var(--color-maroon-700);
  font-size: 1.2rem;
  margin: 0 0 0.3rem;
}

.event-meta {
  color: var(--color-text-muted);
  font-size: 0.9rem;
  margin: 0 0 0.6rem;
}

.event-desc {
  margin: 0 0 1rem;
  white-space: pre-line;
}

.event-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.25rem;
  border-top: 1px solid var(--color-border);
  padding-top: 0.9rem;
}

.event-count {
  margin: 0;
  font-size: 0.85rem;
  color: var(--color-text-muted);
  font-weight: 600;
}

.rsvp-group {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-left: auto;
}

.rsvp-form {
  margin: 0;
}

/* Small button variant for the RSVP row. */
.btn-small {
  padding: 0.4rem 0.9rem;
  font-size: 0.85rem;
}

/* The member's currently chosen response: a filled maroon pill. */
.rsvp-active {
  background: var(--color-maroon-700);
  color: white;
  border: 2px solid var(--color-maroon-700);
}

.rsvp-active:hover {
  background: var(--color-maroon-900, #5f1414);
}

.event-empty {
  text-align: center;
  color: var(--color-text-muted);
  padding: 2rem 0;
}

.is-past-list .event-card {
  padding-top: 1rem;
  padding-bottom: 1rem;
}

.rsvp-roster {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}

.rsvp-roster li {
  display: flex;
  flex-direction: column;
}

/* ===================================================================
   Notices
   =================================================================== */
.notice-list {
  display: grid;
  gap: 1.25rem;
  max-width: 760px;
}

.notice-card {
  background: white;
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-gold);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: clamp(1.1rem, 3vw, 1.5rem);
}

.notice-card.is-pinned {
  border-left-color: var(--color-maroon-700);
  background: var(--color-tint);
}

.notice-pin {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-maroon-700);
  margin-bottom: 0.4rem;
}

.notice-title {
  font-family: var(--font-display);
  color: var(--color-maroon-700);
  font-size: 1.2rem;
  margin: 0 0 0.2rem;
}

.notice-date {
  color: var(--color-text-muted);
  font-size: 0.85rem;
  margin: 0 0 0.75rem;
}

.notice-body {
  white-space: pre-line;
}

/* Home-page notice preview */
.home-notices {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.1rem;
}

.home-notice {
  background: white;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.2rem 1.35rem;
}

.home-notice.is-pinned {
  border-color: var(--color-gold);
}

.home-notice-title {
  font-family: var(--font-display);
  color: var(--color-maroon-700);
  font-size: 1.1rem;
  margin: 0 0 0.15rem;
}

.home-notice-body {
  margin: 0.4rem 0 0;
  color: var(--color-text-muted);
}

/* ===================================================================
   Membership card
   =================================================================== */
.card-page {
  max-width: 460px;
}

.membership-card {
  background: linear-gradient(135deg, var(--color-maroon-700), var(--color-maroon-900));
  color: white;
  border-radius: 16px;
  box-shadow: var(--shadow-lg);
  padding: 1.4rem 1.5rem;
  /* A hair over card aspect, so it prints nicely on its own. */
  border-top: 6px solid var(--color-gold);
}

.mc-top {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}

.mc-logo {
  width: 42px;
  height: 42px;
  object-fit: contain;
  background: white;
  border-radius: 50%;
  padding: 3px;
}

.mc-titles {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
}

.mc-club-ne {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
}

.mc-club-en {
  font-size: 0.78rem;
  color: var(--color-gold-light);
}

.mc-body {
  display: flex;
  gap: 1rem;
  align-items: flex-end;
  justify-content: space-between;
  padding-top: 1.1rem;
}

.mc-name {
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 700;
}

.mc-role {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-maroon-900);
  background: var(--color-gold);
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  margin: 0.35rem 0 0.85rem;
}

.mc-meta {
  margin: 0;
  display: grid;
  gap: 0.5rem;
}

.mc-meta dt {
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-gold-light);
}

.mc-meta dd {
  margin: 0;
  font-weight: 600;
  font-size: 0.95rem;
}

.mc-qr {
  flex: none;
  background: white;
  padding: 6px;
  border-radius: 8px;
  line-height: 0;
}

.mc-qr svg {
  width: 96px;
  height: 96px;
  display: block;
}

.card-actions {
  display: flex;
  gap: 1rem;
  justify-content: center;
  margin: 1.5rem 0 0.75rem;
}

.verify-meta {
  display: inline-grid;
  gap: 0.5rem;
  margin: 1rem 0 0;
  text-align: left;
}

.verify-meta dt {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-muted);
}

.verify-meta dd {
  margin: 0;
  font-weight: 600;
}

/* Print just the card, nothing else. */
@media print {
  .navbar, .footer, .bunting, .no-print, .hero {
    display: none !important;
  }
  body {
    background: white;
  }
  .membership-card {
    box-shadow: none;
    margin: 0 auto;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}

@media (max-width: 560px) {
  .event-card {
    flex-direction: column;
    gap: 0.9rem;
  }
  .rsvp-group {
    margin-left: 0;
    width: 100%;
  }
}

