:root {
  /* Historical names — kept working exactly as before. Everything below
     is an ADDITIVE alias layer using clearer semantic names, so new/updated
     CSS can read `var(--brand-blue)` instead of the misleadingly-named
     `var(--green)` (it's actually blue). Nothing here changes any existing
     rendered pixel — see UI_UX_CLEANUP_AUDIT.md Phase 1. */
  --green: #0055a5;       /* UZES blue */
  --green-dark: #003d7a;
  --navy: #001f4d;
  --accent-gold: #d6a729; /* restrained warm accent — use sparingly */
  --bg: #eef1f4;
  --card: #ffffff;
  --line: #d8dee6;
  --text: #1a2230;
  --muted: #6a7686;
  --danger: #c0392b;
  --ok: #1e8a4c;
  --radius: 10px;
  --shadow: 0 2px 10px rgba(19,35,58,.08);
  --shadow-md: 0 8px 22px rgba(19,35,58,.10);

  /* Semantic aliases — same values, clearer names for new/edited CSS */
  --brand-blue: var(--green);
  --brand-blue-700: var(--green-dark);
  --brand-blue-900: var(--navy);
  --surface: var(--card);
  --surface-soft: #f6f8fb;
  --page-bg: var(--bg);
  --border: var(--line);
  --radius-sm: 6px;
  --radius-md: var(--radius);
  --radius-lg: 14px;
  --shadow-sm: var(--shadow);

  /* Type scale (Phase 2) — card titles normalized to --font-size-lg (16px);
     see UI_UX_CLEANUP_AUDIT.md Phase 2. Body text/uppercase-label usage was
     checked and found already reasonably consistent, so this pass only
     touches the confirmed real inconsistency: card titles ranging 14-18px
     across .hub-title/.info-box-title/.support-card h3/.act-title/.who-topic. */
  --font-size-sm: 13px;
  --font-size-md: 14px;
  --font-size-lg: 16px;
  --font-size-xl: 20px;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: system-ui, "Segoe UI", Arial, sans-serif; color: var(--text); background: var(--bg); display: flex; flex-direction: column; min-height: 100dvh; overflow-x: clip; scrollbar-gutter: stable; }
img { max-width: 100%; height: auto; }
.muted { color: var(--muted); }
.small { font-size: 12px; }
a { color: var(--green); }

/* ---------- Auth screen ---------- */
/* Campus photo behind a dark overlay so the card text stays readable.
   Same image + overlay in both themes — gradients still render even if the
   photo hasn't been added yet at img/campus-building.jpg. */
.auth-bg {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  background:
    linear-gradient(135deg, rgba(0,31,77,.58), rgba(0,61,122,.62)),
    url("../img/campus-building.jpg") center/cover no-repeat,
    linear-gradient(140deg, var(--green-dark) 0%, var(--navy) 100%);
  padding: 20px;
}
.auth-card {
  background: var(--card);
  width: 100%; max-width: 380px;
  padding: 32px 28px;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.brand { text-align: center; margin-bottom: 22px; }
.brand-mark {
  display: inline-block;
  background: var(--green); color: #fff;
  font-weight: 800; letter-spacing: 1px;
  padding: 8px 14px; border-radius: 10px; font-size: 20px;
}
.brand-mark.sm { padding: 4px 8px; font-size: 14px; border-radius: 7px; }
.brand h1 { font-size: 22px; margin-top: 12px; }

form { display: flex; flex-direction: column; gap: 6px; }
label { font-size: 13px; font-weight: 600; margin-top: 8px; }
input, select, textarea {
  padding: 11px 12px; border: 1px solid var(--line); border-radius: 9px;
  font-size: 15px; background: #fff; color: var(--text); width: 100%;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--green); border-color: var(--green); }

.btn-primary {
  margin-top: 16px; background: var(--green); color: #fff;
  border: none; padding: 12px; border-radius: 9px;
  font-size: 15px; font-weight: 700; cursor: pointer;
}
.btn-primary:hover { background: var(--green-dark); }
.btn-primary:disabled { opacity: .65; cursor: default; }
.btn-ghost {
  background: transparent; border: 1px solid var(--line); color: var(--text);
  padding: 7px 12px; border-radius: 8px; cursor: pointer; font-size: 14px;
}
.btn-ghost:hover { background: #f3f5f8; }

.error { color: var(--danger); font-size: 13px; min-height: 16px; }

/* ---------- App shell ---------- */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  background: var(--card); border-bottom: 1px solid var(--line);
  padding: 12px 22px; gap: 12px;
  position: sticky; top: 0; z-index: 200;
}
.topbar-brand { font-weight: 700; display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.topbar-logo { height: 30px; width: auto; display: block; }
.topbar-right { display: flex; align-items: center; gap: 14px; min-width: 0; }
.btn-ghost { white-space: nowrap; }
.page { max-width: 960px; width: 100%; margin: 0 auto; padding: 26px 22px 64px; flex: 1; }
.page h1 { font-size: 24px; margin-bottom: 4px; }
.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 20px; margin-top: 16px;
  box-shadow: var(--shadow);
}
/* .ui-card — canonical name for new card-style containers going forward
   (UI_UX_CLEANUP_AUDIT.md Phase 3). Same recipe as .card; .card and the
   other existing card classes (.hub-card/.info-box/.support-card/.act-card/
   .who-card/.exec-card) already share this same background/border/radius/
   shadow via their own grouped rules, so this isn't a visual change for
   any of them — it's the one name new code should reach for instead of
   picking between six existing options. */
.ui-card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 20px;
  box-shadow: var(--shadow);
}

/* ───────────────────────────────────────────────────────────────
   RESPONSIVE
   ─────────────────────────────────────────────────────────────── */

/* Tabs — scroll horizontally instead of wrapping or clipping */
.tabs {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;        /* Firefox */
}
.tabs::-webkit-scrollbar { display: none; }   /* Chrome / Safari */
.tab-btn { white-space: nowrap; flex-shrink: 0; }

/* ═══════════════════════════════════════════════════════════════════
   PUBLIC SITE — shared styles for all public-facing pages
   ═══════════════════════════════════════════════════════════════════ */

/* ── Logo chip (crisp logo on coloured backgrounds) ──────────────── */
.logo-chip {
  background: #fff; border-radius: 10px; display: inline-flex;
  align-items: center; justify-content: center; flex-shrink: 0;
}
.logo-chip.nav   { height: 40px; padding: 2px 4px; }
.logo-chip.nav img   { height: 36px; width: auto; display: block; }
.logo-chip.hero  { padding: 4px 8px; margin-bottom: 4px; box-shadow: 0 4px 14px rgba(0,0,0,.28); }
.logo-chip.hero img  { height: 44px; width: auto; display: block; }
.logo-chip.footer{ padding: 4px 8px; margin: 0 auto 6px; }
.logo-chip.footer img{ height: 32px; width: auto; display: block; }
.login-logo { height: 80px; width: auto; display: block; margin: 0 auto 6px; }

/* ── Public Nav ──────────────────────────────────────────────────── */
/* Light/white bar (UI_UX_CLEANUP_AUDIT.md Phase 1 + user decision 2026-07-12)
   — brand blue is now reserved for the active link, hover tint, and the
   sign-in button, instead of covering the whole bar. */
.pub-nav {
  background: var(--surface); color: var(--text);
  position: sticky; top: 0; z-index: 200;
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
}
.pub-nav-inner {
  max-width: 1060px; margin: 0 auto;
  padding: 0 20px;
  display: flex; align-items: center; gap: 8px; height: 56px;
}
.pub-nav-brand {
  display: flex; align-items: center; gap: 10px;
  text-decoration: none; color: var(--text); min-width: 0; flex: 0 1 auto;
}
.pub-nav-name {
  font-weight: 700; font-size: 14px; letter-spacing: .2px;
  min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pub-nav-links {
  display: flex; gap: 4px; margin-left: 20px; flex: 1;
}
.pub-nav-links a {
  padding: 6px 13px; border-radius: 8px;
  color: var(--muted); text-decoration: none;
  font-size: 14px; font-weight: 600; transition: background .15s, color .15s;
  white-space: nowrap;
}
.pub-nav-links a:hover { background: var(--surface-soft); color: var(--brand-blue); }
.pub-nav-links a.active { background: rgba(0,85,165,.10); color: var(--brand-blue); }
.pub-nav-end { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-shrink: 0; }
.pub-nav-signin {
  padding: 7px 16px; border-radius: 8px;
  background: var(--brand-blue); color: #fff;
  text-decoration: none; font-size: 13px; font-weight: 700;
  border: 1px solid var(--brand-blue); white-space: nowrap;
  transition: background .15s;
}
.pub-nav-signin:hover { background: var(--brand-blue-700); }
.pub-nav-toggle {
  display: none; background: none; border: none; color: var(--text);
  font-size: 22px; cursor: pointer; padding: 4px 6px; line-height: 1;
}

/* ── Hero (home page) ────────────────────────────────────────────── */
/* Campus photo behind a dark overlay — same treatment as .auth-bg. */
.pub-hero {
  background:
    linear-gradient(135deg, rgba(0,31,77,.58), rgba(0,61,122,.62)),
    url("../img/campus-building.jpg") center/cover no-repeat,
    linear-gradient(140deg, var(--green-dark) 0%, var(--navy) 100%);
  color: #fff; text-align: center; padding: 56px 24px;
  min-height: clamp(300px, 48vh, 480px);
  flex: 1; display: flex; align-items: center; justify-content: center;
}
.pub-hero-content { max-width: 640px; margin: 0 auto; }
.pub-hero h1 { font-size: clamp(26px, 5vw, 44px); font-weight: 800; margin: 4px 0 12px; line-height: 1.2; }
.pub-hero-sub { font-size: clamp(14px, 2vw, 17px); opacity: .9; line-height: 1.6; margin-bottom: 24px; }
.pub-hero-cta { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.pub-cta-primary {
  background: #fff; color: var(--green); border: none;
  padding: 9px 22px; border-radius: 10px; font-size: 14px; font-weight: 700;
  text-decoration: none; display: inline-block; transition: opacity .15s;
  margin-top: 0;
}
.pub-cta-primary:hover { opacity: .9; }
.pub-cta-secondary {
  padding: 9px 22px; border-radius: 10px; font-size: 14px; font-weight: 700;
  text-decoration: none; color: #fff; border: 2px solid rgba(255,255,255,.5);
  transition: border-color .15s;
}
.pub-cta-secondary:hover { border-color: #fff; }

/* ── Hero (inner pages — small) ──────────────────────────────────── */
.pub-hero-sm {
  background: linear-gradient(140deg, var(--green-dark) 0%, var(--navy) 100%);
  color: #fff; padding: 8px 24px 10px; text-align: center;
}
.pub-hero-sm h1 { font-size: clamp(14px, 3.5vw, 19px); font-weight: 800; margin-bottom: 2px; }
.pub-hero-sm p  { opacity: .8; font-size: clamp(11px, 2vw, 13px); }

/* ── Public layout ───────────────────────────────────────────────── */
.pub-main { max-width: 1040px; margin: 0 auto; padding: 32px 24px 64px; flex: 1; }
.pub-section { padding: 60px 24px; }
.pub-section-alt { background: #f5f8fb; }
.pub-container { max-width: 1040px; margin: 0 auto; }
.section-h2 {
  font-size: clamp(16px, 3.5vw, 22px); font-weight: 700; color: var(--text);
  margin-bottom: 6px; margin-top: 0;
}
.section-sub { color: var(--muted); font-size: 14px; margin-bottom: 28px; }
.section-head-row {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 24px; gap: 12px; flex-wrap: wrap;
}
.pub-link { color: var(--green); font-size: 14px; font-weight: 700; text-decoration: none; }
.pub-link:hover { text-decoration: underline; }

/* ── Home: hub cards (links out to the separate pages) ───────────── */
.hub-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); gap: 16px;
}
.hub-card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 26px 22px; box-shadow: var(--shadow); text-decoration: none;
  display: flex; flex-direction: column; gap: 8px;
  transition: transform .15s, box-shadow .15s, border-color .15s;
}
.hub-card:hover {
  transform: translateY(-3px); border-color: var(--green);
  box-shadow: 0 10px 28px rgba(0,85,165,.14);
}
.hub-icon  { font-size: 30px; }
.hub-title { font-size: var(--font-size-lg); font-weight: 700; color: var(--text); }
.hub-desc  { font-size: 13px; color: var(--muted); line-height: 1.5; }
.hub-more  { font-size: 13px; font-weight: 700; color: var(--green); margin-top: auto; }

/* ── Org chart ───────────────────────────────────────────────────── */
.org-chart { padding: 8px 0 24px; }
.org-tier { display: flex; flex-direction: column; align-items: center; }
.org-tier-label {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .8px;
  color: var(--muted); margin-bottom: 10px;
}
.tier-cards {
  display: flex; flex-wrap: wrap; gap: 14px; justify-content: center;
}
.org-connector {
  width: 2px; height: 28px; background: var(--line); margin: 4px auto;
}
.exec-card {
  width: 130px; background: var(--card); border: 2px solid var(--line);
  border-radius: 12px; padding: 14px 10px 12px; text-align: center;
  cursor: pointer; transition: border-color .15s, box-shadow .15s;
  box-shadow: var(--shadow);
}
.exec-card:hover { border-color: var(--green); box-shadow: 0 4px 16px rgba(0,85,165,.14); }
.exec-card.selected { border-color: var(--green); background: #f0f6ff; }
.exec-photo {
  width: 64px; height: 64px; border-radius: 50%; object-fit: cover;
  background: #dde3ec; margin: 0 auto 8px; display: block;
}
.exec-photo-placeholder {
  width: 64px; height: 64px; border-radius: 50%;
  background: linear-gradient(135deg, var(--green), var(--navy));
  margin: 0 auto 8px; display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 22px; font-weight: 800;
}
.exec-name { font-size: 12px; font-weight: 700; color: var(--text); line-height: 1.3; }
.exec-pos  { font-size: 10px; color: var(--muted); margin-top: 3px; line-height: 1.3; }

/* ── Profile dialog ──────────────────────────────────────────────── */
.profile-dialog {
  border: none; border-radius: 16px; padding: 0; max-width: 480px; width: 92%;
  box-shadow: 0 20px 60px rgba(0,0,0,.22);
}
.profile-dialog::backdrop { background: rgba(0,0,0,.45); }
.dialog-inner { padding: 28px; }
.dialog-close {
  position: absolute; top: 14px; right: 16px;
  background: #f0f2f5; border: none; border-radius: 50%;
  width: 32px; height: 32px; font-size: 16px; cursor: pointer; color: var(--muted);
  display: flex; align-items: center; justify-content: center;
}
.dialog-close:hover { background: #e2e6ea; color: var(--text); }
.dialog-photo {
  width: 90px; height: 90px; border-radius: 50%; object-fit: cover;
  border: 3px solid var(--green); margin-bottom: 14px;
}
.dialog-photo-placeholder {
  width: 90px; height: 90px; border-radius: 50%;
  background: linear-gradient(135deg, var(--green), var(--navy));
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 32px; font-weight: 800; margin-bottom: 14px;
}
.dialog-name { font-size: 20px; font-weight: 700; margin-bottom: 3px; }
.dialog-pos  {
  font-size: 13px; font-weight: 700; color: var(--green);
  margin-bottom: 14px; text-transform: uppercase; letter-spacing: .3px;
}
.dialog-bio  { font-size: 14px; color: var(--muted); line-height: 1.65; margin-bottom: 14px; }
.dialog-meta { display: flex; flex-direction: column; gap: 5px; font-size: 13px; }
.dialog-meta a { color: var(--green); text-decoration: none; }
.dialog-meta a:hover { text-decoration: underline; }

/* ── About: affiliations ─────────────────────────────────────────── */
.affiliations-list { list-style: none; display: flex; flex-direction: column; gap: 10px; }
.affiliations-list li {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px; background: var(--card); border: 1px solid var(--line);
  border-radius: 10px; font-size: 14px; font-weight: 600;
  box-shadow: var(--shadow);
}
.aff-dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--green); flex-shrink: 0;
}

/* ── About page ──────────────────────────────────────────────────── */
.mission-text { color: var(--muted); line-height: 1.75; font-size: 15px; max-width: 720px; }
.org-chart-loading-row { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
.sk-exec-card { width: 130px; height: 130px; border-radius: 12px; }

/* ── Contact page ────────────────────────────────────────────────── */
.info-grid {
  display: grid; grid-template-columns: 1.4fr 1fr; gap: 20px; margin-bottom: 8px;
}
.info-box {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 22px 22px; box-shadow: var(--shadow);
}
.info-box-title { font-size: var(--font-size-lg); font-weight: 700; color: var(--text); margin-bottom: 16px; }
.contact-row { display: flex; gap: 12px; align-items: flex-start; padding: 10px 0; border-bottom: 1px solid var(--line); }
.contact-row:last-child { border-bottom: none; }
.contact-icon { font-size: 18px; line-height: 1.4; flex-shrink: 0; }
.contact-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); }
.sk-icon-28 { width: 28px; height: 28px; border-radius: 6px; flex-shrink: 0; }
.sk-social-card { height: 48px; border-radius: 10px; }
/* Pulls the note up against "Reach the right office" above it — exact value
   already used inline; -20px is intentional (this section has margin-top: 40px
   from .u-mt-40, this note counters most of it to sit close to the subtitle). */
.who-grid-note { margin: -20px 0 18px; }
.contact-value { font-size: 14px; color: var(--text); line-height: 1.5; }
.contact-value a { font-weight: 600; word-break: break-word; }

.social-links { display: flex; flex-direction: column; gap: 10px; }
.social-link {
  display: flex; align-items: center; gap: 10px; text-decoration: none;
  border: 1px solid var(--line); border-radius: 10px; padding: 10px 14px;
  color: var(--text); font-weight: 600; font-size: 14px; transition: all .15s;
}
.social-link:hover { border-color: var(--green); color: var(--green); transform: translateY(-1px); }
.social-link svg { flex-shrink: 0; }

.who-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px,1fr)); gap: 14px; }
.who-card {
  background: var(--card); border: 1px solid var(--line); border-left: 4px solid var(--green);
  border-radius: 10px; padding: 16px 18px;
  width: 100%; display: block; text-align: left; font-family: inherit; cursor: pointer;
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
.who-card:hover { border-color: var(--green); box-shadow: 0 4px 14px rgba(0,85,165,.12); transform: translateY(-2px); }
.who-card:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
.who-topic { font-weight: 700; font-size: var(--font-size-lg); color: var(--text); margin-bottom: 3px; }
.who-role  { font-size: 13px; color: var(--green); font-weight: 600; }
.who-role::after { content: " ›"; font-weight: 800; }

/* ── Support page ────────────────────────────────────────────────── */
.support-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px,1fr)); gap: 18px; }
.support-card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 24px 22px; box-shadow: var(--shadow); display: flex; flex-direction: column;
}
.support-card h3 { font-size: var(--font-size-lg); font-weight: 700; color: var(--text); margin: 6px 0 10px; }
.support-icon { font-size: 30px; }
.support-text { font-size: 14px; line-height: 1.7; color: var(--muted); white-space: pre-line; }
.support-foot { font-size: 13px; line-height: 1.7; margin-top: 28px; text-align: center; }

@media (max-width: 680px) {
  .info-grid { grid-template-columns: 1fr; }
}

/* ── FAQ ─────────────────────────────────────────────────────────── */
.faq-category { font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .8px; color: var(--muted); margin: 28px 0 10px; }
.faq-item { border: 1px solid var(--line); border-radius: 10px; overflow: hidden; margin-bottom: 8px; }
.faq-question {
  width: 100%; background: var(--card); border: none; cursor: pointer;
  padding: 14px 18px; text-align: left; font-size: 14px; font-weight: 600;
  color: var(--text); display: flex; justify-content: space-between; align-items: center;
  gap: 12px;
}
.faq-question:hover { background: #f8fafc; }
.faq-chevron { font-size: 16px; color: var(--muted); flex-shrink: 0; transition: transform .2s; }
.faq-item.open .faq-chevron { transform: rotate(180deg); }
.faq-answer {
  display: none; padding: 0 18px 16px; font-size: 14px; color: var(--muted);
  line-height: 1.7; background: var(--card);
}
.faq-item.open .faq-answer { display: block; }

/* ── Activities ──────────────────────────────────────────────────── */
.act-filters {
  display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 24px;
}
.filter-pill {
  padding: 6px 14px; border: 1px solid var(--line); border-radius: 20px;
  background: #fff; font-size: 13px; font-weight: 600; cursor: pointer;
  color: var(--muted); transition: background .12s, color .12s;
}
.filter-pill:hover { background: #f0f3f7; color: var(--text); }
.filter-pill.active { background: var(--green); color: #fff; border-color: var(--green); }
.act-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(270px,1fr)); gap: 16px;
}
.act-card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; box-shadow: var(--shadow); display: flex; flex-direction: column;
}
.act-poster {
  width: 100%; height: 160px; object-fit: cover; background: linear-gradient(135deg, var(--green), var(--navy));
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 13px; font-weight: 700; letter-spacing: .5px; text-align: center;
  padding: 12px;
}
.act-poster img { width: 100%; height: 160px; object-fit: cover; display: block; }
.act-card-body { padding: 14px 16px; flex: 1; display: flex; flex-direction: column; gap: 6px; }
.act-title { font-size: var(--font-size-lg); font-weight: 700; line-height: 1.3; }
.act-meta  { font-size: 12px; color: var(--muted); }
.act-badges { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 4px; }
.act-cat-badge {
  font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 20px;
  background: #e8f0fa; color: var(--green); letter-spacing: .3px;
}
.act-status-pill {
  font-size: 10px; font-weight: 800; padding: 2px 8px; border-radius: 20px;
  color: #fff; letter-spacing: .4px;
}
.act-desc { font-size: 13px; color: var(--muted); line-height: 1.5; margin-top: 4px; }
.empty-state {
  text-align: center; padding: 60px 24px; color: var(--muted);
  grid-column: 1 / -1;
}
.empty-state-icon { font-size: 40px; margin-bottom: 12px; }
.empty-state h3    { font-size: 16px; margin-bottom: 6px; color: var(--text); }

/* ── Public footer ───────────────────────────────────────────────── */
.pub-footer {
  background: var(--navy); color: rgba(255,255,255,.75);
  padding: 5px 16px; text-align: center; font-size: 11px;
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 150;
}
.pub-footer a   { color: rgba(255,255,255,.7); text-decoration: none; }
.pub-footer a:hover { color: #fff; text-decoration: underline; }
.footer-inner   { max-width: 640px; margin: 0 auto; }
.footer-brand   { font-size: 13px; font-weight: 700; color: #fff; margin-bottom: 1px; }
.footer-tagline { margin-bottom: 0; line-height: 1.3; font-size: 11px; }
.footer-links   { display: flex; gap: 20px; justify-content: center; flex-wrap: wrap; margin-bottom: 4px; }
.footer-copy    { font-size: 10px; opacity: .6; margin-top: 1px; }

/* ── Content editor (executive dashboard additions) ──────────────── */
.editor-section { margin-bottom: 28px; }
.editor-section-head {
  font-size: 14px; font-weight: 700; color: var(--text);
  border-bottom: 2px solid var(--line); padding-bottom: 8px; margin-bottom: 14px;
}
.profile-row {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 10px 0; border-bottom: 1px solid var(--line);
}
.profile-row:last-child { border-bottom: none; }
.profile-thumb {
  width: 40px; height: 40px; border-radius: 50%; object-fit: cover;
  background: linear-gradient(135deg, var(--green), var(--navy));
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 14px; font-weight: 700; flex-shrink: 0; overflow: hidden;
}
.profile-thumb img { width: 100%; height: 100%; object-fit: cover; }
.profile-info { flex: 1; min-width: 0; }
.profile-info-name { font-size: 13px; font-weight: 700; }
.profile-info-pos  { font-size: 12px; color: var(--muted); }
.draft-badge {
  font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 20px;
  background: #fff3cd; color: #856404; border: 1px solid #ffc107;
}
.live-badge {
  font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 20px;
  background: #e8f5ee; color: var(--ok); border: 1px solid #b8dfc9;
}
.photo-upload-box {
  border: 2px dashed var(--line); border-radius: 10px; padding: 14px;
  display: flex; align-items: center; gap: 14px; cursor: pointer;
  background: #f8fafc; margin-top: 8px;
}
.photo-upload-box:hover { border-color: var(--green); }
.photo-preview { width: 56px; height: 56px; border-radius: 50%; object-fit: cover; display: none; }
.photo-placeholder { color: var(--muted); font-size: 13px; }
.form-collapse { display: none; }
.form-collapse.open { display: block; }
.toggle-form-btn {
  background: none; border: 1px dashed var(--green); color: var(--green);
  padding: 7px 16px; border-radius: 8px; cursor: pointer; font-size: 13px;
  font-weight: 600; margin-bottom: 14px;
}
.toggle-form-btn:hover { background: #f0f6ff; }
.act-editor-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
@media (max-width: 600px) { .act-editor-grid { grid-template-columns: 1fr; } }

/* ── Responsive: public site ─────────────────────────────────────── */
/* Collapse the nav to a hamburger early so the full society name has room. */
@media (max-width: 900px) {
  .pub-nav-links {
    display: none; flex-direction: column; background: var(--surface);
    position: absolute; top: 100%; left: 0; right: 0; padding: 8px 16px 12px;
    z-index: 199; border-bottom: 1px solid var(--border); box-shadow: var(--shadow-md);
  }
  .pub-nav-links.open { display: flex; }
  .pub-nav-links a   { padding: 10px 12px; border-radius: 6px; }
  .pub-nav-toggle    { display: block; }
  .pub-nav-inner     { position: relative; height: auto; min-height: 56px; padding-top: 8px; padding-bottom: 8px; }
  .pub-nav-name      { white-space: normal; font-size: 13px; line-height: 1.2; }
}
@media (max-width: 720px) {
  .pub-section { padding: 32px 16px; }
  .pub-main    { padding: 24px 16px 56px; }
}

@media (max-width: 640px) {
  /* Topbar — keep one tidy row: brand · name · sign-out */
  .topbar { padding: 10px 12px; gap: 8px; }
  .topbar-brand { font-size: 14px; gap: 6px; }
  .topbar-right { gap: 8px; flex: 1; justify-content: flex-end; }
  #who {
    flex: 1;
    min-width: 0;
    text-align: right;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .btn-ghost { padding: 7px 10px; flex-shrink: 0; }

  /* Page */
  .page { padding: 14px 12px 56px; }
  .page h1 { font-size: clamp(16px, 4vw, 20px); }

  /* Cards */
  .card { padding: 14px 12px; margin-top: 12px; }
}

/* ═══════════════════════════════════════════════════════════════════
   VERIFY RECEIPT FAB + SCANNER MODAL
   ─────────────────────────────────────────────────────────────── */
.verify-fab {
  position: fixed; bottom: 28px; right: 28px; z-index: 400;
  background: var(--green); color: #fff; border: none;
  border-radius: 50px; cursor: pointer; overflow: hidden;
  box-shadow: 0 6px 20px rgba(0,85,165,.4);
  display: flex; align-items: center; gap: 7px;
  padding: 13px 20px; font-size: 13px; font-weight: 700;
  transition: background .15s, transform .12s;
}
.verify-fab:hover { background: var(--green-dark); transform: translateY(-2px); }

.scanner-modal {
  position: fixed; inset: 0; z-index: 500;
  background: rgba(0,0,0,.65); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; padding: 16px;
}
.scanner-modal.hidden { display: none; }

.scanner-box {
  background: var(--card); border-radius: var(--radius);
  padding: 22px 20px; width: 100%; max-width: 440px;
  box-shadow: 0 24px 64px rgba(0,0,0,.35);
  max-height: 90vh; overflow-y: auto;
}
.scanner-header {
  display: flex; align-items: flex-start;
  justify-content: space-between; gap: 12px;
}
.scanner-close {
  background: none; border: none; font-size: 24px; line-height: 1;
  cursor: pointer; color: var(--muted); padding: 0; flex-shrink: 0;
}
.scanner-close:hover { color: var(--text); }

/* Scan result cards */
.scan-result { padding: 18px 16px; border-radius: 10px; text-align: center; }
.scan-result.ok   { background: #e8f5ee; border: 1.5px solid #b8dfc9; }
.scan-result.fail { background: #fdf4f4; border: 1.5px solid #f1c0bb; }
.scan-icon { font-size: 52px; line-height: 1; margin-bottom: 8px; }
.scan-result.ok   .scan-icon { color: var(--ok); }
.scan-result.fail .scan-icon { color: var(--danger); }
.scan-result strong { font-size: 16px; display: block; margin-bottom: 10px; }
.scan-result p { font-size: 13px; color: var(--muted); margin: 0; }

.scan-table {
  width: 100%; border-collapse: collapse;
  font-size: 13px; margin-top: 14px; text-align: left;
}
.scan-table td { padding: 7px 4px; border-bottom: 1px solid var(--line); }
.scan-table tr:last-child td { border-bottom: none; }
.scan-table td:first-child {
  color: var(--muted); font-size: 11px; white-space: nowrap;
  text-transform: uppercase; letter-spacing: .4px; padding-right: 14px;
}

/* ── Public verify.html page ────────────────────────────────────── */
.verify-card {
  background: var(--card); width: 100%; max-width: 460px;
  padding: 32px 28px; border-radius: var(--radius); box-shadow: var(--shadow);
}
.verify-result { text-align: center; padding: 20px 0 8px; }
.verify-big-icon { font-size: 72px; line-height: 1; margin-bottom: 12px; }
.verify-ok   .verify-big-icon { color: var(--ok); }
.verify-fail .verify-big-icon { color: var(--danger); }
.verify-title { font-size: 22px; font-weight: 800; margin-bottom: 6px; }
.verify-ok   .verify-title { color: var(--ok); }
.verify-fail .verify-title { color: var(--danger); }
.verify-subtitle { font-size: 14px; color: var(--muted); margin-bottom: 20px; }
.verify-details {
  background: #f8fafc; border: 1px solid var(--line);
  border-radius: 10px; padding: 16px; margin-top: 4px;
}
.verify-row {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 13px;
  gap: 12px;
}
.verify-row:last-child { border-bottom: none; }
.verify-row-label { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .4px; white-space: nowrap; }
.verify-row-val { font-weight: 600; text-align: right; }
.verify-badge {
  display: inline-block; background: var(--ok); color: #fff;
  font-size: 11px; font-weight: 700; padding: 3px 10px;
  border-radius: 20px; letter-spacing: .4px; margin-top: 14px;
}

@media (max-width: 640px) {
  .verify-fab { bottom: 16px; right: 16px; padding: 11px 16px; }
  .verify-card { padding: 24px 16px; }
}

/* ═══════════════════════════════════════════════════════════════════
   SUB-HERO — universal blue TAB BAR below the white topbar.
   One navigation layer per role. Each tab reveals its full panel inline.
   ═══════════════════════════════════════════════════════════════════ */
/* Universal tab-panel toggle — pages reveal one panel at a time via the sub-hero.
   Defined globally so every dashboard behaves the same (student.html relied on a
   local copy that was easy to drop). */
.tab-panel.hidden { display: none; }

.sub-hero {
  background: linear-gradient(140deg, var(--green-dark) 0%, var(--navy) 100%);
  position: sticky; top: 0; z-index: 200;
  border-bottom: 1px solid rgba(255,255,255,.1);
  box-shadow: 0 3px 14px rgba(0,0,0,.22);
}
.sh-bar {
  /* Matches .page's max-width exactly so the tab bar's edges line up with
     the content column beneath it on every dashboard page — previously
     1040px vs .page's 960px, an 80px mismatch that made every page's
     content look inset/misaligned under the bar. */
  max-width: 960px; margin: 0 auto;
  display: flex; align-items: center;
  padding: 0 20px; gap: 10px; height: 52px;
}
/* Left group: logo/sign-out + name/position — always the far-left anchor */
.sh-left { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
/* Right group: bell, theme toggle, hamburger — always the far-right anchor.
   margin-left:auto (not just relying on .sh-tabs's flex:1) so this still sits
   flush right even when .sh-tabs is display:none behind the mobile hamburger —
   same pattern as .pub-nav-end on the public nav. */
.sh-right { display: flex; align-items: center; gap: 4px; flex-shrink: 0; margin-left: auto; }
.sh-brand {
  display: flex; align-items: center; flex-shrink: 0; text-decoration: none;
  background: #fff; border-radius: 9px; padding: 4px 8px;
  border: none; cursor: pointer;
}
.sh-logo  { height: 26px; width: auto; display: block; }
.sh-nav-toggle {
  display: none; background: none; border: none; color: #fff;
  font-size: 20px; cursor: pointer; padding: 4px 8px; flex-shrink: 0;
}
.sh-tabs {
  display: flex; align-items: center; gap: 2px;
  overflow-x: auto; scrollbar-width: none; flex: 1; min-width: 0;
}
.sh-tabs::-webkit-scrollbar { display: none; }

/* Ghost/skeleton subhero — shown briefly before initSubHero() replaces it with
   the real tab bar (library.html, attachment.html). Reserves the same 52px
   height so nothing jumps when the real bar renders. */
.sh-ghost { min-height: 52px; }
.sh-ghost-tabs { gap: 4px; }
.sh-skel-tab { height: 26px; border-radius: 8px; background: rgba(255,255,255,.13); flex-shrink: 0; }
.sh-skel-tab.active { background: rgba(255,255,255,.28); }
.sh-skel-end { width: 70px; height: 28px; border-radius: 7px; background: rgba(255,255,255,.13); flex-shrink: 0; }

/* Bell */
.sh-bell {
  position: relative; background: none; border: none; color: rgba(255,255,255,.85);
  cursor: pointer; padding: 6px; border-radius: 8px; display: flex;
  align-items: center; justify-content: center; flex-shrink: 0; transition: background .12s;
}
.sh-bell:hover { background: rgba(255,255,255,.12); color: #fff; }
.sh-bell-dot {
  position: absolute; top: 4px; right: 4px; width: 8px; height: 8px;
  border-radius: 50%; background: #ff5252; border: 1.5px solid var(--green-dark);
}
.sh-bell-dot.hidden { display: none; }

.notif-panel {
  position: fixed; z-index: 999; width: min(360px, 92vw);
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 12px 36px rgba(0,0,0,.25); overflow: hidden;
}
.notif-panel-head { padding: 12px 16px; font-weight: 700; font-size: 14px; border-bottom: 1px solid var(--line); }
.notif-panel-list { max-height: 360px; overflow-y: auto; }
.notif-row { padding: 12px 16px; border-bottom: 1px solid var(--line); cursor: pointer; transition: background .12s; }
.notif-row:last-child { border-bottom: none; }
.notif-row:hover { background: rgba(0,85,165,.05); }
.notif-row.unread { background: rgba(0,85,165,.06); border-left: 3px solid var(--green); }
.notif-title { font-size: 13px; font-weight: 700; margin-bottom: 2px; }
.notif-body  { font-size: 12.5px; color: var(--muted); line-height: 1.4; }
.notif-time  { font-size: 11px; color: var(--muted); margin-top: 4px; }
.notif-panel-spinner { display: flex; justify-content: center; padding: 10px; }
.notif-panel-spinner.hidden { display: none; }
@media (max-width: 640px) {
  .notif-panel { width: auto; }
}
[data-theme="dark"] .notif-row.unread { background: rgba(88,166,255,.08); }
.sh-tab {
  background: none; border: none; color: rgba(255,255,255,.78);
  cursor: pointer; padding: 6px 13px; border-radius: 8px;
  font-size: 13px; font-weight: 600; white-space: nowrap;
  display: flex; align-items: center; gap: 6px; text-decoration: none;
  transition: background .12s, color .12s; flex-shrink: 0;
}
.sh-tab:hover { background: rgba(255,255,255,.12); color: #fff; }
.sh-tab.sh-tab-active { background: #fff; color: var(--green); }
.sh-tab.sh-tab-active svg { stroke: var(--green); }
.sh-user-pill { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.sh-user-info {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px; min-width: 0;
}
.sh-uname {
  font-size: 12.5px; font-weight: 600; color: rgba(255,255,255,.88);
  max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sh-utitle {
  font-size: 10px; color: rgba(255,255,255,.58); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 140px;
}
.sh-signout {
  padding: 5px 12px; border: 1px solid rgba(255,255,255,.3);
  border-radius: 7px; background: rgba(255,255,255,.1);
  color: rgba(255,255,255,.85); font-size: 12px; font-weight: 600;
  cursor: pointer; white-space: nowrap; flex-shrink: 0; transition: background .12s;
}
.sh-signout:hover { background: rgba(255,255,255,.22); color: #fff; }

@media (max-width: 640px) {
  .sh-bar { padding: 0 10px; height: 48px; }
  /* Name/role stay visible on mobile — tabs collapse behind the hamburger,
     which frees up enough width for the ellipsis-truncated pill to fit. */
  .sh-uname, .sh-utitle { max-width: 34vw; }
  .sh-signout { padding: 5px 9px; font-size: 11px; }

  /* Tabs collapse behind a hamburger, same pattern as the public nav */
  .sh-nav-toggle { display: block; }
  .sh-tabs {
    display: none; position: absolute; top: 48px; left: 8px; right: 8px;
    flex-direction: column; align-items: stretch; gap: 2px;
    background: var(--green-dark); padding: 8px; border-radius: 0 0 10px 10px;
    box-shadow: 0 10px 24px rgba(0,0,0,.3); z-index: 210; overflow: visible;
  }
  .sh-tabs.open { display: flex; }
  .sh-tab { padding: 9px 12px; font-size: 13px; justify-content: flex-start; }
}

/* ═══════════════════════════════════════════════════════════════════
   TAB-HERO — banded container for in-page sub-tabs (Placements, Library
   moderation, System settings, Finance, Elections, etc). Same family as
   .pub-hero-sm (a deliberate, padded section) but transparent/soft
   instead of solid-filled, and centers its tabs instead of anchoring
   them left. Centralized here — was previously four near-identical
   copies duplicated inline across student.html (.fin-tabs/.elec-postabs),
   executive.html, admin.html, and industrial-secretary.html (.ses-tabs),
   all styled as bare underlined text with no container at all.
   ═══════════════════════════════════════════════════════════════════ */
.ses-tabs, .fin-tabs, .elec-postabs {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 6px;
  margin: 0 0 20px; padding: 12px 20px;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  /* Stick just below the sub-hero (52px tall; z-200) as the panel scrolls,
     so the sub-tabs stay reachable. Solid surface-soft bg hides content
     scrolling underneath; z-index sits below the sub-hero so it tucks under. */
  position: sticky; top: 52px; z-index: 150;
}
.ses-tab, .fin-tab, .elec-postab {
  /* appearance:none from first paint — native <button> theming otherwise
     caches its own background at initial render and won't reliably repaint
     a var()-based background when the active state or dark-mode toggle
     changes it later. */
  appearance: none; -webkit-appearance: none;
  padding: 9px 18px; border: none; background: none; cursor: pointer;
  border-radius: var(--radius-sm);
  font-size: 14px; font-weight: 600; color: var(--muted);
  transition: color .15s, background .15s, box-shadow .15s;
}
.ses-tab:hover, .fin-tab:hover, .elec-postab:hover { background: rgba(0,85,165,.07); color: var(--text); }
.ses-tab.active, .fin-tab.active, .elec-postab.active {
  color: var(--green); background: var(--card); box-shadow: var(--shadow-sm);
}
.elec-postab.done::after { content: " ✓"; color: var(--ok); }
.ses-panel.hidden, .fin-panel.hidden, .elec-pospanel.hidden { display: none; }

/* Shared empty-state card — replaces bare "<p class='muted'>No … yet</p>" list
   placeholders across the dashboards so an empty list reads as an intentional
   card, not stray text. Tokens auto-adapt to dark mode. */
.empty-state {
  text-align: center; padding: 30px 20px; color: var(--muted);
  background: var(--surface-soft); border: 1px dashed var(--border);
  border-radius: var(--radius-lg); margin-top: 12px; font-size: 13.5px;
}
.empty-state-title { font-weight: 700; color: var(--text); font-size: 14px; margin-bottom: 4px; }

@media (max-width: 640px) {
  .ses-tabs, .fin-tabs, .elec-postabs { padding: 8px 10px; gap: 4px; margin-bottom: 14px; top: 48px; }
  .ses-tab, .fin-tab, .elec-postab { padding: 8px 12px; font-size: 13px; }
}

/* ═══════════════════════════════════════════════════════════════════
   STAT/REPORT WIDGETS — KPI tiles + category breakdowns. Used by
   reports.js (executive.html Reports tab) and sqms-admin.js (admin.html
   SQMS tab). Centralized here — was two near-identical copies inline in
   executive.html and admin.html's own <style> blocks.
   ═══════════════════════════════════════════════════════════════════ */
.rpt-kpi-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 10px; margin-bottom: 14px;
}
.stat-card {
  border-radius: var(--radius); padding: 16px 18px; color: #fff;
  box-shadow: var(--shadow);
}
.stat-card.green  { background: var(--ok); }
.stat-card.blue   { background: #1a6fb5; }
.stat-card.orange { background: #d97706; }
.stat-card.red    { background: var(--danger); }
.stat-val   { font-size: 22px; font-weight: 800; }
.stat-label { font-size: 11px; opacity: .85; margin-top: 2px; }
@media (max-width: 700px) { .rpt-kpi-grid { grid-template-columns: repeat(2, 1fr); } }

.breakdown-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(260px,1fr));
  gap: 12px; margin-bottom: 2px;
}
.breakdown-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 13px;
}
.breakdown-row:last-child { border-bottom: none; }
.breakdown-amt { font-weight: 700; }

/* ═══════════════════════════════════════════════════════════════════
   STUDENT DASHBOARD — welcome + details (left) + media (right)
   ═══════════════════════════════════════════════════════════════════ */
.dash-welcome {
  font-size: 22px; font-weight: 800; margin-bottom: 2px; color: var(--text);
}
.dash-welcome span { color: var(--green); }
.dash-sub { color: var(--muted); font-size: 14px; margin-bottom: 18px; }
.dash-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: start;
}
@media (max-width: 760px) { .dash-grid { grid-template-columns: 1fr; } }

.dash-info-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 14px 18px;
}
@media (max-width: 460px) { .dash-info-grid { grid-template-columns: 1fr; } }
.dash-info-item { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dash-info-label {
  font-size: 10px; font-weight: 700; letter-spacing: .6px;
  text-transform: uppercase; color: var(--muted);
}
.dash-info-val { font-size: 14.5px; color: var(--text); font-weight: 600; word-break: break-word; }

.dash-media {
  border-radius: 12px; overflow: hidden; background: #000;
  aspect-ratio: 16 / 10; display: flex; align-items: center; justify-content: center;
  position: relative;
}
.dash-media img, .dash-media video, .dash-media iframe {
  width: 100%; height: 100%; object-fit: cover; border: none; display: block;
}
.dash-media-empty {
  background: linear-gradient(135deg, var(--green), var(--navy));
  color: rgba(255,255,255,.9); text-align: center; padding: 24px; font-size: 14px;
}
.dash-media-cap { font-size: 12px; color: var(--muted); margin-top: 8px; text-align: center; }

.dash-membership {
  display: inline-flex; align-items: center; gap: 7px; margin-top: 4px;
  padding: 5px 13px; border-radius: 20px; font-size: 12px; font-weight: 700;
}
.dash-membership.paid   { background: #e6f7ee; color: #1e8a4c; border: 1px solid #a8e0c0; }
.dash-membership.unpaid { background: #fdf2f2; color: #c0392b; border: 1px solid #f0c0bb; }

/* ═══════════════════════════════════════════════════════════════════
   SKELETON LOADING
   ═══════════════════════════════════════════════════════════════════ */
@keyframes sk-wave {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
.sk {
  background: linear-gradient(90deg, #dde3ec 25%, #eef1f6 50%, #dde3ec 75%);
  background-size: 200% 100%;
  animation: sk-wave 1.4s ease-in-out infinite;
  border-radius: 5px;
  display: block;
}
.sk-line  { height: 13px; margin-bottom: 9px; }
.sk-title { height: 18px; width: 55%; margin-bottom: 12px; }
.sk-w90   { width: 90%; }
.sk-w75   { width: 75%; }
.sk-w60   { width: 60%; }
.sk-w40   { width: 40%; }
.sk-card  { height: 110px; border-radius: var(--radius); margin-bottom: 12px; }
.sk-para  { display: flex; flex-direction: column; }
.sk-avatar { width: 64px; height: 64px; border-radius: 50%; flex-shrink: 0; }
.sk-avatar-sm { width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0; }
.sk-row   { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.sk-row:last-child { border-bottom: none; }

/* ── Reports: header row (section title + filters) ───────────────── */
/* On mobile, the title and filter row should stack so filters don't
   sit to the right of the heading (awkward on narrow screens). */
@media (max-width: 600px) {
  .rpt-header-row { flex-direction: column !important; align-items: flex-start !important; }
  .rpt-header-row .rpt-filters { align-self: stretch; }
}

/* ═══════════════════════════════════════════════════════════════════
   EXTRA RESPONSIVE GUARDS
   ═══════════════════════════════════════════════════════════════════ */

/* Scrollable table wrapper (for reports etc.) */
.tbl-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* Prevent long words / emails from busting layout */
.card, .info-box, .who-card, .support-card { overflow-wrap: break-word; word-break: break-word; }

@media (max-width: 400px) {
  .pub-nav-name { font-size: 11px; }
  .logo-chip.nav { height: 34px; }
  .logo-chip.nav img { height: 30px; }
  .pub-cta-primary, .pub-cta-secondary { padding: 10px 18px; font-size: 13px; }
  .hub-card { padding: 18px 14px; }
  .sh-tab { padding: 5px 7px; font-size: 11.5px; }
  .auth-card, .reg-card { padding: 20px 14px; }
}


/* ═══════════════════════════════════════════════════════════════════
   TOAST NOTIFICATIONS
   ═══════════════════════════════════════════════════════════════════ */
.toast-container {
  position: fixed; top: 20px; right: 20px; z-index: 10000;
  display: flex; flex-direction: column; gap: 10px;
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  background: var(--card); color: var(--text);
  border: 1px solid var(--line); border-radius: 10px;
  padding: 14px 18px; min-width: 260px; max-width: 360px;
  box-shadow: 0 8px 32px rgba(0,0,0,.18);
  font-size: 14px; line-height: 1.5;
  display: flex; align-items: flex-start; gap: 10px;
  animation: toastIn .35s ease-out;
  cursor: pointer;
}
.toast.toast-out { animation: toastOut .3s ease-in forwards; }
.toast-success { border-left: 4px solid var(--ok); }
.toast-error   { border-left: 4px solid var(--danger); }
.toast-info    { border-left: 4px solid var(--green); }
.toast-warn    { border-left: 4px solid #e67e22; }
.toast-icon { font-size: 18px; flex-shrink: 0; line-height: 1; }
.toast-success .toast-icon { color: var(--ok); }
.toast-error   .toast-icon { color: var(--danger); }
.toast-info    .toast-icon { color: var(--green); }
.toast-warn    .toast-icon { color: #e67e22; }
.toast-body { flex: 1; }
.toast-title { font-weight: 700; font-size: 13px; margin-bottom: 2px; }
.toast-msg   { font-size: 13px; color: var(--muted); }
@keyframes toastIn {
  from { opacity: 0; transform: translateX(30px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes toastOut {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(30px); }
}
@media (max-width: 640px) {
  .toast-container { top: 10px; right: 10px; left: 10px; }
  .toast { max-width: none; min-width: auto; }
}

/* ═══════════════════════════════════════════════════════════════════
   SHINE & INTERACTIVE POLISH
   A restrained glossy highlight on card surfaces (a thin light line along
   the top edge, like light catching a smooth surface) plus a sweep-of-light
   hover effect on primary buttons and clickable cards/tabs.
   ═══════════════════════════════════════════════════════════════════ */
.card, .who-card, .support-card, .act-card, .exec-card, .info-box,
.auth-card, .reg-card, .verify-card, .scanner-box, .hub-card, .affiliations-list li {
  box-shadow: var(--shadow), inset 0 1px 0 rgba(255,255,255,.6);
}

/* Sweep-of-light hover: a soft diagonal highlight slides across on hover.
   Applied to primary call-to-action buttons and clickable cards/tabs.
   .verify-fab already sets its own position/overflow above (it must stay
   position:fixed to float over the page — this rule would have clobbered
   that if it also matched .verify-fab, which is why it's listed separately
   in the ::after rules below instead of here). */
.btn-primary, .pub-cta-primary,
.who-card, .exec-card, .sh-tab, .filter-pill {
  position: relative;
  overflow: hidden;
}
.btn-primary::after, .pub-cta-primary::after, .verify-fab::after,
.who-card::after, .exec-card::after, .sh-tab::after, .filter-pill::after {
  content: "";
  position: absolute; top: 0; left: -60%; width: 40%; height: 100%;
  background: linear-gradient(120deg, transparent, rgba(255,255,255,.35), transparent);
  transform: skewX(-20deg);
  transition: left .5s ease;
  pointer-events: none;
}
.btn-primary:hover::after, .pub-cta-primary:hover::after, .verify-fab:hover::after,
.who-card:hover::after, .exec-card:hover::after, .sh-tab:hover::after, .filter-pill:hover::after {
  left: 130%;
}

.btn-primary {
  background: linear-gradient(135deg, var(--green), var(--green-dark));
  transition: filter .15s, transform .12s;
}
.btn-primary:hover { background: linear-gradient(135deg, var(--green), var(--green-dark)); filter: brightness(1.08); }
.btn-primary:active { transform: scale(.98); }

.pub-cta-primary { transition: opacity .15s, transform .12s; }
.pub-cta-primary:hover { transform: translateY(-1px); }

/* ═══════════════════════════════════════════════════════════════════
   DARK MODE
   ═══════════════════════════════════════════════════════════════════ */
[data-theme="dark"] {
  --bg: #0d1117;
  --card: #161b22;
  --line: #30363d;
  --text: #c9d1d9;
  --muted: #8b949e;
  --green: #58a6ff;
  --green-dark: #1f6feb;
  --navy: #0d1117;
  --shadow: 0 2px 10px rgba(0,0,0,.35);
  --shadow-md: 0 8px 22px rgba(0,0,0,.4);
  /* --surface/--page-bg/--border/--brand-blue* all auto-adapt above since
     they're defined as var() references to these same overridden tokens.
     --surface-soft is the one alias with a flat literal value in :root
     (no original token to inherit from), so it needs its own dark value —
     reusing the same shade already used for other dark-mode :hover states
     in this file (faq-question, btn-ghost, photo-upload-box) for consistency. */
  --surface-soft: #21262d;
}
/* Glossy top-highlight, dark-mode tuned: a bright white edge reads wrong on
   dark surfaces, so this is a faint cool-toned line instead of the light
   mode's crisp white one. */
[data-theme="dark"] .card, [data-theme="dark"] .who-card, [data-theme="dark"] .support-card,
[data-theme="dark"] .act-card, [data-theme="dark"] .exec-card, [data-theme="dark"] .info-box,
[data-theme="dark"] .auth-card, [data-theme="dark"] .reg-card, [data-theme="dark"] .verify-card,
[data-theme="dark"] .scanner-box, [data-theme="dark"] .hub-card, [data-theme="dark"] .ui-card,
[data-theme="dark"] .affiliations-list li {
  box-shadow: var(--shadow), inset 0 1px 0 rgba(255,255,255,.06);
}
[data-theme="dark"] .pub-hero-sm,
[data-theme="dark"] .sub-hero {
  background: linear-gradient(140deg, #161b22 0%, #0d1117 100%);
}
[data-theme="dark"] .pub-nav { background: #161b22; }
[data-theme="dark"] .pub-nav-links { background: #0d1117; }
/* Mobile collapsed-tabs dropdown: it's the sub-hero's own overflow menu, so it
   should match the sub-hero's dark surface — not the bright --green-dark blue
   dark mode redefines for other uses (buttons, links, etc). */
[data-theme="dark"] .sh-tabs { background: #0d1117; }
/* .pub-hero and .auth-bg use the campus photo in both themes — no override needed */
[data-theme="dark"] .sk { background: linear-gradient(90deg, #21262d 25%, #30363d 50%, #21262d 75%); }
[data-theme="dark"] .dash-media-empty { background: linear-gradient(135deg, #1f6feb, #0d1117); }
[data-theme="dark"] .empty-state-icon { opacity: .6; }
[data-theme="dark"] .photo-upload-box,
[data-theme="dark"] .verify-details { background: #0d1117; }
[data-theme="dark"] .act-poster { background: linear-gradient(135deg, #1f6feb, #0d1117); }
[data-theme="dark"] .exec-photo-placeholder,
[data-theme="dark"] .profile-thumb,
[data-theme="dark"] .dialog-photo-placeholder { background: linear-gradient(135deg, #1f6feb, #0d1117); }
[data-theme="dark"] .pub-section-alt { background: #0d1117; }
[data-theme="dark"] .faq-question:hover,
[data-theme="dark"] .btn-ghost:hover,
[data-theme="dark"] .photo-upload-box:hover { background: #21262d; }
[data-theme="dark"] .filter-pill { background: #161b22; }
[data-theme="dark"] .filter-pill:hover { background: #21262d; }
[data-theme="dark"] .who-card:hover,
[data-theme="dark"] .hub-card:hover { background: #161b22; }
[data-theme="dark"] .dash-membership.paid   { background: #1a2e24; border-color: #238636; }
[data-theme="dark"] .dash-membership.unpaid { background: #2d1a1a; border-color: #f85149; }
[data-theme="dark"] .draft-badge { background: #3d2a05; color: #ffd166; border-color: #ffd166; }
[data-theme="dark"] .live-badge  { background: #1a2e24; color: #3fb950; border-color: #3fb950; }
[data-theme="dark"] .scan-result.ok   { background: #1a2e24; border-color: #238636; }
[data-theme="dark"] .scan-result.fail { background: #2d1a1a; border-color: #f85149; }
[data-theme="dark"] .verify-result { background: #161b22; }
[data-theme="dark"] .support-card { background: #161b22; }
[data-theme="dark"] .info-box { background: #161b22; }
[data-theme="dark"] .contact-row { border-color: #30363d; }
[data-theme="dark"] .social-link { border-color: #30363d; }
[data-theme="dark"] .social-link:hover { border-color: #58a6ff; color: #58a6ff; }
[data-theme="dark"] .affiliations-list li { background: #161b22; border-color: #30363d; }
[data-theme="dark"] .act-card { background: #161b22; border-color: #30363d; }
[data-theme="dark"] .act-cat-badge { background: #1f2937; color: #58a6ff; }
[data-theme="dark"] .act-status-pill { background: #1f2937; }
[data-theme="dark"] .pub-footer { background: #0d1117; color: rgba(255,255,255,.6); }
[data-theme="dark"] .pub-footer a { color: rgba(255,255,255,.5); }
[data-theme="dark"] .pub-footer a:hover { color: #fff; }
[data-theme="dark"] .verify-details,
[data-theme="dark"] .verify-card { background: #161b22; }
[data-theme="dark"] .scan-table td { border-color: #30363d; }
[data-theme="dark"] .scanner-box { background: #161b22; }
[data-theme="dark"] .pub-nav-toggle { color: #fff; }
[data-theme="dark"] .profile-dialog { background: #161b22; }
[data-theme="dark"] .dialog-close { background: #21262d; color: #8b949e; }
[data-theme="dark"] .dialog-close:hover { background: #30363d; color: #c9d1d9; }
[data-theme="dark"] .pub-cta-primary { background: #58a6ff; color: #0d1117; }
[data-theme="dark"] .pub-cta-secondary { border-color: rgba(255,255,255,.3); color: #fff; }
[data-theme="dark"] .pub-cta-secondary:hover { border-color: #fff; }
[data-theme="dark"] .auth-card { background: #161b22; }
[data-theme="dark"] .auth-card label { color: #c9d1d9; }
[data-theme="dark"] .auth-card input,
[data-theme="dark"] .auth-card select,
[data-theme="dark"] .auth-card textarea { background: #0d1117; border-color: #30363d; color: #c9d1d9; }
[data-theme="dark"] .auth-card input:focus,
[data-theme="dark"] .auth-card select:focus,
[data-theme="dark"] .auth-card textarea:focus { outline-color: #58a6ff; border-color: #58a6ff; }
[data-theme="dark"] .auth-card .btn-primary { background: #58a6ff; color: #0d1117; }
[data-theme="dark"] .auth-card .btn-primary:hover { background: #79b8ff; }
[data-theme="dark"] .btn-ghost { border-color: #30363d; color: #c9d1d9; }
[data-theme="dark"] .btn-ghost:hover { background: #21262d; }
[data-theme="dark"] .error { color: #f85149; }
[data-theme="dark"] .ok-msg { color: #3fb950; }
[data-theme="dark"] .faq-question { background: #161b22; color: #c9d1d9; }
[data-theme="dark"] .faq-answer { background: #161b22; color: #8b949e; }
[data-theme="dark"] .faq-item { border-color: #30363d; }
[data-theme="dark"] .who-card { background: #161b22; border-color: #30363d; }
[data-theme="dark"] .who-card:hover { border-color: #58a6ff; box-shadow: 0 4px 14px rgba(88,166,255,.1); }
[data-theme="dark"] .hub-card { background: #161b22; border-color: #30363d; }
[data-theme="dark"] .hub-card:hover { border-color: #58a6ff; box-shadow: 0 10px 28px rgba(88,166,255,.14); }
[data-theme="dark"] .exec-card { background: #161b22; border-color: #30363d; }
[data-theme="dark"] .exec-card:hover { border-color: #58a6ff; box-shadow: 0 4px 16px rgba(88,166,255,.14); }
[data-theme="dark"] .exec-card.selected { background: #0d1117; border-color: #58a6ff; }
[data-theme="dark"] .exec-photo { background: #21262d; }
[data-theme="dark"] .exec-name { color: #c9d1d9; }
[data-theme="dark"] .exec-pos { color: #8b949e; }
[data-theme="dark"] .org-connector { background: #30363d; }
[data-theme="dark"] .org-tier-label { color: #8b949e; }
[data-theme="dark"] .dialog-name { color: #c9d1d9; }
[data-theme="dark"] .dialog-pos { color: #58a6ff; }
[data-theme="dark"] .dialog-bio { color: #8b949e; }
[data-theme="dark"] .dialog-meta { color: #8b949e; }
[data-theme="dark"] .dialog-meta a { color: #58a6ff; }
[data-theme="dark"] .support-card { border-color: #30363d; }
[data-theme="dark"] .support-card h3 { color: #c9d1d9; }
[data-theme="dark"] .support-text { color: #8b949e; }
[data-theme="dark"] .support-foot { color: #8b949e; }
[data-theme="dark"] .section-head-row { color: #c9d1d9; }
[data-theme="dark"] .section-h2 { color: #c9d1d9; }
[data-theme="dark"] .section-sub { color: #8b949e; }
[data-theme="dark"] .pub-link { color: #58a6ff; }
[data-theme="dark"] .pub-link:hover { color: #79b8ff; }
[data-theme="dark"] .contact-icon { color: #8b949e; }
[data-theme="dark"] .contact-label { color: #8b949e; }
[data-theme="dark"] .contact-value { color: #c9d1d9; }
[data-theme="dark"] .contact-value a { color: #58a6ff; }
[data-theme="dark"] .verify-big-icon { color: #58a6ff; }
[data-theme="dark"] .verify-badge { background: #238636; }
[data-theme="dark"] .verify-ok .verify-title { color: #3fb950; }
[data-theme="dark"] .verify-fail .verify-title { color: #f85149; }
[data-theme="dark"] .verify-subtitle { color: #8b949e; }
[data-theme="dark"] .verify-details { border-color: #30363d; }
[data-theme="dark"] .verify-row { border-color: #30363d; }
[data-theme="dark"] .verify-row-label { color: #8b949e; }
[data-theme="dark"] .verify-row-val { color: #c9d1d9; }
[data-theme="dark"] .scan-result.ok .scan-icon { color: #3fb950; }
[data-theme="dark"] .scan-result.fail .scan-icon { color: #f85149; }
[data-theme="dark"] .scan-result strong { color: #c9d1d9; }
[data-theme="dark"] .scan-result p { color: #8b949e; }
[data-theme="dark"] .scan-table { color: #c9d1d9; }
[data-theme="dark"] .scan-table td:first-child { color: #8b949e; }
[data-theme="dark"] .scanner-header { color: #c9d1d9; }
[data-theme="dark"] .scanner-close { color: #8b949e; }
[data-theme="dark"] .scanner-close:hover { color: #c9d1d9; }
[data-theme="dark"] .scanner-modal { background: rgba(0,0,0,.75); }
[data-theme="dark"] .verify-fab { background: #58a6ff; color: #0d1117; }
[data-theme="dark"] .verify-fab:hover { background: #79b8ff; }
[data-theme="dark"] .verify-card .verify-result { background: #0d1117; }
[data-theme="dark"] .verify-card .verify-details { background: #0d1117; }
[data-theme="dark"] .verify-card .verify-row { border-color: #30363d; }
[data-theme="dark"] .verify-card .verify-row-label { color: #8b949e; }
[data-theme="dark"] .verify-card .verify-row-val { color: #c9d1d9; }
[data-theme="dark"] .verify-card .verify-badge { background: #238636; }
[data-theme="dark"] .verify-card .verify-ok .verify-title { color: #3fb950; }
[data-theme="dark"] .verify-card .verify-fail .verify-title { color: #f85149; }
[data-theme="dark"] .verify-card .verify-subtitle { color: #8b949e; }
[data-theme="dark"] .verify-card .verify-big-icon { color: #58a6ff; }
[data-theme="dark"] .verify-card .verify-ok .verify-big-icon { color: #3fb950; }
[data-theme="dark"] .verify-card .verify-fail .verify-big-icon { color: #f85149; }
[data-theme="dark"] .verify-card .verify-details { border-color: #30363d; }

/* ── Global form elements ── */
[data-theme="dark"] input,
[data-theme="dark"] select,
[data-theme="dark"] textarea { background: #0d1117; border-color: #30363d; color: #c9d1d9; }
[data-theme="dark"] input::placeholder,
[data-theme="dark"] textarea::placeholder { color: #6e7681; }
[data-theme="dark"] input:focus,
[data-theme="dark"] select:focus,
[data-theme="dark"] textarea:focus { outline-color: #58a6ff; border-color: #58a6ff; }
[data-theme="dark"] .file-upload-label { background: #0d1117; border-color: #30363d; color: #8b949e; }
[data-theme="dark"] .file-upload-label:hover { border-color: #58a6ff; color: #58a6ff; }
[data-theme="dark"] .drop-zone { background: #0d1117; }
[data-theme="dark"] .drop-zone:hover,
[data-theme="dark"] .drop-zone.dragover { background: rgba(88,166,255,.06); border-color: #58a6ff; }
[data-theme="dark"] .modal-overlay { background: rgba(0,0,0,.65); }
[data-theme="dark"] .modal-box { background: #161b22; }
[data-theme="dark"] .modal-title { color: #c9d1d9; }
[data-theme="dark"] .modal-sub { color: #8b949e; }
[data-theme="dark"] .readonly-field { background: #21262d !important; color: #6e7681 !important; }

/* ═══════════════════════════════════════════════════════════════════
   WHATSAPP FLOATING BUTTON
   ═══════════════════════════════════════════════════════════════════ */
.wa-float {
  position: fixed; bottom: 24px; left: 24px; z-index: 9998;
  width: 56px; height: 56px; border-radius: 50%;
  background: #25d366; color: #fff; border: none;
  box-shadow: 0 4px 16px rgba(37,211,102,.35);
  display: flex; align-items: center; justify-content: center;
  font-size: 28px; cursor: pointer; text-decoration: none;
  transition: transform .15s, box-shadow .15s;
}
.wa-float:hover { transform: scale(1.08); box-shadow: 0 6px 24px rgba(37,211,102,.5); }

/* Desktop: show a label on hover */
@media (min-width: 641px) {
  .wa-float:hover::after {
    content: "Support"; position: absolute; left: 64px; white-space: nowrap;
    background: #25d366; color: #fff; font-size: 13px; font-weight: 600;
    padding: 6px 12px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,.15);
  }
}

@media (max-width: 640px) {
  .wa-float { bottom: 16px; left: 16px; width: 48px; height: 48px; font-size: 24px; }
}

/* ═══════════════════════════════════════════════════════════════════
   THEME TOGGLE BUTTON (shared base)
   ═══════════════════════════════════════════════════════════════════ */
.theme-toggle-btn {
  background: none; border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: transform .15s, background .15s;
}
.theme-toggle-btn:hover { transform: scale(1.1); }

/* ── In public nav (index.html, about.html, etc.) ── */
/* Light-mode chip: the white-translucent treatment below was designed for
   the old solid-blue nav bar and is invisible on the new light one (see
   UI_UX_CLEANUP_AUDIT.md Phase 1 nav change) — uses the same border/surface
   tokens as the rest of the light nav instead. Dark mode's .pub-nav is still
   a dark surface, so it keeps the original white-translucent look below. */
.theme-toggle-nav {
  width: 36px; height: 36px; border-radius: 8px;
  background: var(--surface-soft); border: 1px solid var(--border);
  color: var(--text); font-size: 16px; margin-left: 8px;
}
.theme-toggle-nav:hover { background: var(--border); }
[data-theme="dark"] .theme-toggle-nav {
  background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.25);
  color: #fff;
}
[data-theme="dark"] .theme-toggle-nav:hover { background: rgba(255,255,255,.22); }

/* ── In sub-hero (logged-in pages) ── */
.theme-toggle-subhero {
  width: 32px; height: 32px; border-radius: 8px;
  background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.25);
  color: #fff; font-size: 14px; margin-right: 10px; flex-shrink: 0;
}
.theme-toggle-subhero:hover { background: rgba(255,255,255,.22); }

/* ── On login page ── */
.theme-toggle-login {
  position: absolute; top: 16px; right: 16px;
  width: 36px; height: 36px; border-radius: 8px;
  background: rgba(255,255,255,.15); border: 1px solid rgba(255,255,255,.25);
  color: #fff; font-size: 16px; z-index: 10;
}
.theme-toggle-login:hover { background: rgba(255,255,255,.25); }
@media (max-width: 400px) {
  .theme-toggle-login { top: 10px; right: 10px; width: 32px; height: 32px; font-size: 14px; }
}

/* ═══════════════════════════════════════════════════════════════════
   PAGE SKELETON — full-viewport cover shown until the correct tab has been
   restored (from the URL hash) and its data is on the way in. Prevents a
   refresh from flashing the wrong tab (e.g. Dashboard) before snapping to
   whichever tab the user was actually on. Hidden by subhero.js once ready.
   ═══════════════════════════════════════════════════════════════════ */
.page-skeleton {
  position: fixed; inset: 0; z-index: 9999; background: var(--bg);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
}
.page-skeleton.hidden { display: none; }
.page-skeleton .sk { width: min(420px, 80vw); }

/* ═══════════════════════════════════════════════════════════════════
   MOBILE PAYMENT HISTORY CARDS
   ═══════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  .pay-row {
    display: flex; flex-direction: column;
    background: var(--card); border: 1px solid var(--line);
    border-radius: 10px; padding: 14px; margin-bottom: 10px;
    box-shadow: var(--shadow);
  }
  .pay-main { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin-bottom: 6px; }
  .pay-meta { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 6px; }
  .pay-cat { font-weight: 700; font-size: 14px; }
  .pay-amt { font-weight: 800; font-size: 15px; color: var(--green); }
  .pay-method { font-size: 12px; }
  .status-pill { font-size: 10px; font-weight: 700; padding: 3px 10px; border-radius: 20px; color: #fff; letter-spacing: .4px; }
}

/* ═══════════════════════════════════════════════════════════════════
   PULL-TO-REFRESH INDICATOR
   ═══════════════════════════════════════════════════════════════════ */
.ptr-indicator {
  position: fixed; top: 0; left: 0; right: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  height: 0; overflow: hidden; transition: height .2s;
  background: var(--card); border-bottom: 1px solid var(--line);
}
.ptr-indicator.active { height: 48px; }
.ptr-spinner {
  width: 20px; height: 20px; border: 2px solid var(--line);
  border-top-color: var(--green); border-radius: 50%;
  animation: ptr-spin .8s linear infinite;
}
@keyframes ptr-spin { to { transform: rotate(360deg); } }

/* ═══════════════════════════════════════════════════════════════════
   SEARCH / FILTER INPUT
   ═══════════════════════════════════════════════════════════════════ */
.search-box {
  position: relative; margin-bottom: 14px;
}
.search-box input {
  width: 100%; padding: 10px 14px 10px 36px; border: 1px solid var(--line);
  border-radius: 9px; font-size: 14px; background: var(--card); color: var(--text);
}
.search-box input:focus { outline: 2px solid var(--green); border-color: var(--green); }
.search-box::before {
  content: "🔍"; position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  font-size: 14px; opacity: .5; pointer-events: none;
}

/* ═══════════════════════════════════════════════════════════════════
   TAB SCROLL INDICATOR (mobile)
   ═══════════════════════════════════════════════════════════════════ */
.sh-tabs { scroll-snap-type: x mandatory; }
.sh-tab { scroll-snap-align: start; }

/* ═══════════════════════════════════════════════════════════════════
   LIBRARY (shared between library.html's standalone page and student.html's
   embedded Library tab — the rest of the library-specific classes, e.g.
   .browse-grid/.btn-lib/.modal-box, stay page-local for now; only promoted
   here because these two specific classes ended up used in both places)
   ═══════════════════════════════════════════════════════════════════ */
.lib-page-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px; margin-bottom: 4px; }
.sk-browse-card { height: 100px; border-radius: var(--radius); }

/* ═══════════════════════════════════════════════════════════════════
   PLACEMENTS/VACANCIES skeleton + form patterns — shared between
   executive.html's Placements tab and industrial-secretary.html's
   equivalent (both let Sec Gen / Vice Sec Gen / IT Secretary manage
   company vacancies against the same data model).
   ═══════════════════════════════════════════════════════════════════ */
.sk-pending-block { height: 140px; margin-bottom: 12px; }
.sk-vacancy-block { height: 120px; margin-bottom: 10px; }
.sk-confirmed-block { height: 110px; margin-bottom: 12px; }
.slots-per-dept-label { font-size: 13px; font-weight: 600; margin: 14px 0 8px; }
.dept-slots-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px,1fr)); gap: 8px; margin-bottom: 16px; }

/* ═══════════════════════════════════════════════════════════════════
   PAGE SKELETON blocks — shown briefly on page load before real content
   arrives (used by student.html, admin.html, executive.html; likely more
   dashboard pages).
   ═══════════════════════════════════════════════════════════════════ */
.sk-page-header   { height: 48px; border-radius: 10px; }
.sk-page-block-lg { height: 160px; }
.sk-page-block-md { height: 80px; }
.sk-dash-block-1 { height: 80px; margin-bottom: 12px; }
.sk-dash-block-2 { height: 140px; }

/* ═══════════════════════════════════════════════════════════════════
   UTILITIES (UI_UX_CLEANUP_AUDIT.md Phase 5)
   Replace one-off inline styles with these instead of hand-writing new
   ones. Values match what was ALREADY used inline — reproduces existing
   spacing exactly, doesn't introduce a new scale (a separate Phase 4
   decision). Deliberately placed LAST in the file: every one of these is
   a single-class selector, same specificity as the component classes
   they're meant to override (e.g. `.pub-main.u-page-920`'s width vs
   `.pub-main`'s own 1040px, or `.section-h2.u-mb-4`'s spacing vs
   `.section-h2`'s own margin-bottom) — CSS breaks same-specificity ties
   by SOURCE ORDER, so a utilities block placed near the top of the file
   silently loses to any later component rule touching the same property.
   Caught this the hard way building it (u-page-920 was originally near
   the top and .pub-main's 1040px was winning) — moving the whole block
   here instead of chasing each conflict with higher specificity. Any
   future utility added to this file must go here, not near :root.
   ═══════════════════════════════════════════════════════════════════ */
.u-relative     { position: relative; }
.u-flex-1       { flex: 1; }
.u-flex-shrink-0 { flex-shrink: 0; }
.u-mt-2  { margin-top: 2px; }
.u-mt-8  { margin-top: 8px; }
.u-mt-10 { margin-top: 10px; }
.u-mt-14 { margin-top: 14px; }
.u-mt-16 { margin-top: 16px; }
.u-mt-20 { margin-top: 20px; }
.u-mt-40 { margin-top: 40px; }
.u-mb-4  { margin-bottom: 4px; }
.u-mb-6  { margin-bottom: 6px; }
.u-mb-8  { margin-bottom: 8px; }
.u-mb-10 { margin-bottom: 10px; }
.u-mb-12 { margin-bottom: 12px; }
.u-mb-14 { margin-bottom: 14px; }
.u-mb-16 { margin-bottom: 16px; }
.u-mb-48 { margin-bottom: 48px; }
.u-mb-56 { margin-bottom: 56px; }
.u-fs-11 { font-size: 11px; }
.u-fs-13 { font-size: 13px; }
.u-fs-14 { font-size: 14px; }
.u-resize-vertical { resize: vertical; }
.u-min-h-18 { min-height: 18px; }
.u-max-w-280 { max-width: 280px; }
/* Primary-button sizing override — a .btn-primary defaults to full-width
   block; several one-off submit/CTA buttons need it sized to its content
   instead, without the display:inline-block an <a> styled as a button needs
   (see .btn-inline-link above) — this variant is button-agnostic. */
.u-btn-compact { width: auto; padding: 11px 28px; }
.u-btn-compact-md { width: auto; padding: 10px 22px; }
.u-w-66  { width: 66px; }
.u-w-80  { width: 80px; }
.u-w-82  { width: 82px; }
.u-w-128 { width: 128px; }
/* CTA link that needs to look like a button (<a> doesn't get .btn-primary's
   block-level width automatically) — was repeated inline on membership-gate
   pages (library.html, attachment.html). */
.btn-inline-link { display: inline-block; text-decoration: none; width: auto; padding: 11px 28px; }
/* Two distinct narrow-container widths exist because the pages that used
   them inline already disagreed (920px vs 980px) — reproduced as-is here
   rather than silently picking one; reconciling them is a Phase 4 decision. */
.u-page-920 { max-width: 920px; }
.u-page-980 { max-width: 980px; }
.u-max-w-480 { max-width: 480px; }
.u-max-w-560 { max-width: 560px; }
.u-max-w-640 { max-width: 640px; }
.u-max-w-720 { max-width: 720px; }
.u-margin-4-0-0 { margin: 4px 0 0; }
.u-mt-0  { margin-top: 0; }
.u-mt-2  { margin-top: 2px; }
.u-mt-3  { margin-top: 3px; }
.u-mt-4  { margin-top: 4px; }
.u-mt-6  { margin-top: 6px; }
.u-mt-12 { margin-top: 12px; }
.u-m-0   { margin: 0; }
.u-mb-0  { margin-bottom: 0; }
.u-mb-5  { margin-bottom: 5px; }
.u-mb-18 { margin-bottom: 18px; }
.u-block { display: block; }
.u-flex-minw-0 { flex: 1; min-width: 0; }
.u-h-1 { height: 1px; }
.sk-h-90  { height: 90px; }
.sk-h-110 { height: 110px; }
.sk-h-120 { height: 120px; }
.sk-h-140 { height: 140px; }
.u-color-danger { color: var(--danger); }
.u-grid-col-full { grid-column: 1 / -1; }
/* Search box variant used on both admin.html's Student Accounts list and
   executive.html's read-only Student Accounts view — promoted here since a
   2nd file needed the identical rule. */
.search-input-sm { width: 100%; margin-bottom: 12px; padding: 9px 12px;
  border: 1px solid var(--line); border-radius: 8px; font-size: 13px; }
/* Generic "success text" pattern (green, small, semibold) repeated across
   many pages as its own page-local .ok-msg class — promoted here since a
   4th file (admin.html) needed the identical rule; older per-page copies
   left as-is (redundant but harmless, same values). */
.ok-msg { color: var(--ok); font-size: 13px; font-weight: 600; }
