/* ===== Community Directory — Custom Styles ===== */

:root {
  --primary:    #1e5799;
  --primary-dk: #153f72;
  --gold:       #f8a100;
  --gold-lt:    #fff3cd;
  --bg:         #f5f7fa;
  --card-bg:    #ffffff;
  --text:       #222;
  --muted:      #6c757d;
  --radius:     10px;
  --shadow:     0 2px 12px rgba(0,0,0,.09);
}

body {
  background: var(--bg);
  color: var(--text);
  font-size: 1.05rem;
  line-height: 1.65;
}

/* ── Typography ── */
h1, h2, h3, h4, h5 { font-weight: 700; color: var(--primary); }
a { color: var(--primary); }

/* ── Cards ── */
.card {
  border: none;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.card-header {
  border-radius: var(--radius) var(--radius) 0 0 !important;
  font-weight: 700;
  font-size: 1.1rem;
}
.card-header.primary-header {
  background: var(--primary);
  color: #fff;
}

/* ── Hero Banner ── */
.hero {
  background: linear-gradient(135deg, var(--primary) 0%, #2e7acc 100%);
  color: #fff;
  padding: 3.5rem 1.5rem;
  border-radius: var(--radius);
  margin-bottom: 2rem;
  text-align: center;
}
.hero h1 { color: #fff; font-size: clamp(1.8rem, 5vw, 2.8rem); margin-bottom: .5rem; }
.hero p  { color: rgba(255,255,255,.88); font-size: 1.15rem; }

/* Logo variant — white-bg PNG sits on a rounded white tile inside the hero */
.hero-logo, .hero-split { padding: 2rem 1.5rem; text-align: left; }
.hero-split { text-align: inherit; }
.hero-logo-img {
  display: block;
  margin: 0 auto;        /* centered by default (mobile) */
  max-width: 250px;      /* same footprint as the original white card */
  width: 100%;
  height: auto;
}
.hero-logo .hero-logo-img { margin: 0 auto; }
/* On md+ the .mx-md-0 utility on the <img> pulls it back to the left edge. */
.hero-logo .hero-tagline,
.hero-split .hero-tagline {
  margin-top: 1rem;
  margin-left: auto;                                /* mobile: center under centered logo */
  margin-right: auto;
  max-width: 250px;                                 /* same width as the logo tile */
  color: #ffe7a1;                                   /* warm cream — contrast against the blue */
  font-family: 'Dancing Script', cursive;
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: .01em;
  line-height: 1.2;
  text-shadow: 0 1px 2px rgba(0,0,0,.25);
}
@media (min-width: 768px) {
  /* On md+ the logo is left-aligned via mx-md-0; pin the tagline to the same
     left edge so it sits centered under the logo tile. */
  .hero-split .hero-tagline { margin-left: 0; margin-right: 0; }
}
.hero-description {
  color: rgba(255,255,255,.92);
  font-size: 1.05rem;
  line-height: 1.55;
  background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.25);
  border-radius: var(--radius);
  padding: 1.25rem 1.5rem;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.08),
              0 2px 8px rgba(0,0,0,.10);
  backdrop-filter: blur(2px);
}
.hero-description p:first-child { margin-top: 0; }
.hero-description p:last-child  { margin-bottom: 0; }
.hero-description ul, .hero-description ol { margin: .5rem 0; padding-left: 1.25rem; }
.hero-description a { color: #ffe7a1; text-decoration: underline; }

/* Tagline stays centered inside its (logo-width) box at every breakpoint, so it
   always reads as "centered under the logo". The description follows the
   container's text-utility classes: centered on mobile, left on md+. */
.hero-split .hero-tagline { text-align: center !important; }
.hero-description { text-align: center !important; }
@media (min-width: 768px) {
  .hero-description { text-align: left !important; }
}
.hero .badge-event {
  background: var(--gold);
  color: #333;
  font-size: .95rem;
  padding: .35em .8em;
  border-radius: 20px;
  font-weight: 600;
}

/* ── Stat Cards ── */
.stat-card {
  text-align: center;
  padding: 1.5rem 1rem;
  border-radius: var(--radius);
  background: #fff;
  box-shadow: var(--shadow);
}
.stat-card .stat-number {
  font-size: 2.4rem;
  font-weight: 800;
  color: var(--primary);
  line-height: 1;
}
.stat-card .stat-label {
  color: var(--muted);
  font-size: .9rem;
  margin-top: .25rem;
}
.stat-card .stat-icon {
  font-size: 2rem;
  color: var(--gold);
  margin-bottom: .5rem;
}
.stat-card-link {
  transition: transform .15s, box-shadow .15s;
  cursor: pointer;
}
.stat-card-link:hover {
  transform: translateY(-3px);
  box-shadow: 0 6px 20px rgba(0,0,0,.14);
}

/* ── Buttons ── */
.btn-primary {
  background: var(--primary);
  border-color: var(--primary);
}
.btn-primary:hover, .btn-primary:focus {
  background: var(--primary-dk);
  border-color: var(--primary-dk);
}
.btn-gold {
  background: var(--gold);
  border-color: var(--gold);
  color: #222;
  font-weight: 600;
}
.btn-gold:hover { background: #e09500; border-color: #e09500; color: #222; }

/* ── Forms ── */
.form-label { font-weight: 600; margin-bottom: .3rem; }
.form-control, .form-select {
  border-radius: 7px;
  padding: .6rem .9rem;
  font-size: 1rem;
  border-color: #c9d4e0;
}
.form-control:focus, .form-select:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 .2rem rgba(30,87,153,.18);
}
.required-star { color: #dc3545; }

/* ── Tables ── */
.table th { background: #e9eff7; color: var(--primary); font-weight: 700; }
.table td { vertical-align: middle; }

/* ── Admin Sidebar ── */
.admin-sidebar {
  min-height: calc(100vh - 120px);
  background: #fff;
  border-right: 1px solid #dee2e6;
  padding: 1.5rem 0;
}
.admin-sidebar .nav-link {
  color: var(--text);
  padding: .6rem 1.2rem;
  border-radius: 0 30px 30px 0;
  margin-right: .75rem;
  font-size: 1rem;
  transition: all .15s;
}
.admin-sidebar .nav-link:hover,
.admin-sidebar .nav-link.active {
  background: #e8f0fb;
  color: var(--primary);
  font-weight: 600;
}
.admin-sidebar .nav-link i { width: 22px; }

/* ── Status badges ── */
.badge { font-size: .82rem; }

/* ── Address autocomplete ── */
.pac-container { border-radius: 8px; font-size: 1rem; }

/* ── Member card grid ── */
.member-card {
  background: #fff;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.25rem;
  height: 100%;
  transition: transform .15s;
}
.member-card:hover { transform: translateY(-2px); }
.member-card .member-name { font-weight: 700; font-size: 1.1rem; color: var(--primary); }
.member-card .member-meta { font-size: .9rem; color: var(--muted); }

/* ── Print — Avery 5305 tent card (3" × 5", 4 per sheet)
       Top half rotated 180° so it reads from the back when folded ── */
@media print {
  body * { visibility: hidden; }
  #print-area, #print-area * { visibility: visible; }
  #print-area { position: fixed; top: 0; left: 0; width: 100%; }
  .no-print { display: none !important; }

  @page {
    size: letter portrait;
    margin: 0.5in 1.25in;
  }

  .label-sheet {
    display: grid;
    grid-template-columns: 3in 3in;
    grid-auto-rows: 5in;
    column-gap: 0;
    row-gap: 0;
  }

  .avery-label {
    width: 3in;
    height: 5in;
    box-sizing: border-box;
    border: 1px dashed #ccc;
    display: flex;
    flex-direction: column;
    page-break-inside: avoid;
    break-inside: avoid;
    overflow: hidden;
  }

  .print-excluded {
    display: none !important;
  }

  /* Each half fills exactly 2.5in */
  .label-half {
    height: 2.5in;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 0.2in 0.25in;
  }

  /* Top half flipped — reads correctly from the back when tent is folded */
  .label-top {
    transform: rotate(180deg);
  }

  /* Dashed fold guide line */
  .label-fold {
    flex-shrink: 0;
    border-top: 1pt dashed #aaa;
  }

  /* Typography — same for both halves */
  .label-half .lbl-event   { font-size: 7pt;  color: #888; text-transform: uppercase; letter-spacing: 1pt; margin-bottom: 6pt; }
  .label-half .lbl-name    { font-size: 22pt; font-weight: 900; color: #000; line-height: 1.15; margin-bottom: 0; }
  .label-half .lbl-divider { border-top: 1.5pt solid #1e5799; width: 1.4in; margin: 10pt auto; }
  .label-half .lbl-table   { font-size: 16pt; font-weight: 700; color: #1e5799; margin-bottom: 4pt; }
  .label-half .lbl-meal    { font-size: 14pt; font-weight: 700; color: #222; margin-bottom: 6pt; }
  .label-half .lbl-allergy { font-size: 11pt; color: #b22; font-weight: 600; margin-top: 6pt; line-height: 1.2; }
}

/* ── Screen preview of labels ── */
.label-preview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1rem;
}
.label-preview-card {
  position: relative;
  background: #fff;
  border: 2px dashed #bcd;
  border-radius: 8px;
  padding: 1.25rem;
  text-align: center;
  cursor: pointer;
  transition: border-color .15s, box-shadow .15s, opacity .15s;
  user-select: none;
}
.label-preview-card:hover {
  border-color: var(--primary);
}
.label-preview-card.label-selected {
  border: 2px solid var(--primary);
  box-shadow: 0 0 0 3px rgba(30,87,153,.2);
}
.label-select-cb {
  position: absolute;
  top: 8px;
  left: 8px;
  width: 18px;
  height: 18px;
  cursor: pointer;
  accent-color: var(--primary);
}
.label-preview-card .lbl-name    { font-size: 1.2rem; font-weight: 800; color: var(--primary); }
.label-preview-card .lbl-table   { font-weight: 700; color: #555; }
.label-preview-card .lbl-meal    { color: #333; font-size: .95rem; font-weight: 600; }
.label-preview-card .lbl-allergy { color: #b22; font-size: .85rem; font-weight: 600; margin-top: .25rem; }

/* ── Drag-and-drop sorting ── */
.sortable-ghost { opacity: .4; background: #d0e4f7 !important; }
.drag-handle { color: #adb5bd; }
.drag-handle:hover { color: #6c757d; }

/* ── Responsive tweaks ── */
@media (max-width: 768px) {
  .hero { padding: 2rem 1rem; }
  .admin-sidebar { min-height: auto; border-right: none; border-bottom: 1px solid #dee2e6; padding: .5rem 0; }
  /* One link per row, not a wrapped block of pills. The pills were compact, but on a phone
     this column sits above the page's own content, so they read as the menu repeating itself
     rather than as navigation. The list is behind the "Admin menu" button now, so its length
     costs nothing until it is asked for. */
  .admin-sidebar .nav-link { border-radius: 6px; margin-right: 0; display: flex; }
  /* The "Admin menu" button is now the only way into the nav on a phone, so it holds the
     same 44px minimum target as the rest of the phone navigation. */
  .admin-sidebar > .btn { min-height: 44px; }
}

/* ── Compact phone event list (home page, `home_phone_compact`) ──────────────
   Everything here is inside the phone breakpoint on purpose: computers and
   tablets must render the home page exactly as they did before the setting
   existed. The markup is ONE card, not two — index.php adds a phone-only
   summary (.evc-sum) and wraps today's card body in `.collapse .d-md-block`,
   so at md+ Bootstrap's own `display:block !important` forces the detail open
   and the summary is hidden. Do not try to hide/show these with inline
   style.display: the `.d-*` utilities are !important and will win. */
@media (max-width: 767.98px) {
  /* The hero's welcome text, collapsed behind an "Introduction" header. Styled
     to sit ON the blue hero, so it borrows the same translucent fill and border
     as .hero-description rather than looking like a button dropped on top of it.
     Its own chevron rule on purpose: .evc-chev belongs to the event cards, and a
     rule shared across two unrelated components is how the next person breaks
     one while editing the other. */
  .hero-intro-toggle {
    width: 100%; min-height: 48px; display: flex; align-items: center;
    font-size: 1.05rem; font-weight: 600; color: #fff;
    background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.25);
    border-radius: var(--radius); padding: .5rem .9rem;
  }
  .hero-intro-chev { transition: transform .2s; }
  [aria-expanded="true"] .hero-intro-chev { transform: rotate(180deg); }

  /* Bigger targets. The home page shipped 38px buttons, under the 44px
     minimum, for the audience with the least steady hands. */
  .evc-card .btn,
  .evc-next .btn { min-height: 48px; font-size: 1.05rem; }
  .evc-name { font-size: 1.3rem; font-weight: 700; color: var(--primary); line-height: 1.2; }
  .evc-when { font-size: 1.05rem; color: var(--text); margin-top: .15rem; }
  .evc-status { font-size: 1.05rem; font-weight: 600; margin-top: .4rem;
                display: flex; align-items: flex-start; gap: .4rem; }
  .evc-sub { font-size: 1rem; font-weight: 600; margin-top: .1rem; margin-left: 1.4rem; }
  /* Scarcity is a deadline, not a description, so it is the one advisory that
     survives collapsing — as a chip, never a full-width banner. Three stacked
     amber blocks would rebuild the wall-of-sameness the compact view exists to
     undo, and once everything is emphasised nothing is. It stays rare because
     it only ever appears at or under the low-seat threshold. */
  .evc-sub.evc-low {
    display: inline-block; margin-top: .55rem; margin-left: 0; font-weight: 700;
    color: #7a4a00; background: var(--gold-lt); border: 1px solid #e0ab52;
    border-radius: 20px; padding: .2rem .65rem;
  }
  .evc-yes { color: #137a3d; } .evc-no { color: #5a6472; } .evc-wl { color: #8a5b00; }
  /* Status is carried by icon + words as well as colour — the left edge is a
     reinforcement, never the only signal. */
  .evc-edge-yes { border-left: 8px solid #1a9553; }
  .evc-edge-no  { border-left: 8px solid #98a2b3; }
  .evc-edge-wl  { border-left: 8px solid var(--gold); }
  .evc-edge-past{ border-left: 8px solid #adb5bd; }
  .evc-tear { flex: 0 0 62px; background: var(--primary); color: #fff; border-radius: 8px;
              text-align: center; padding: .35rem .15rem; }
  .evc-tear .mo { font-size: .8rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
  .evc-tear .dy { font-size: 1.75rem; font-weight: 800; line-height: 1.05; }
  .evc-tear .wd { font-size: .78rem; opacity: .95; }
  /* Day-of. Red is spent sparingly and only on an event you are actually
     attending today — see the $c_going gate in index.php. Everyone gets
     "Today" in the date block; only attendees get the colour and the ticket. */
  .evc-tear-today { background: #b3271e; }
  .evc-when-today { color: #b3271e; font-weight: 700; }
  .evc-more { min-height: 48px; font-size: 1.05rem; font-weight: 600; text-decoration: none;
              display: flex; align-items: center; justify-content: center; gap: .4rem; }
  .evc-detail { border-top: 2px solid #e3e8ef; }
  .evc-chev { transition: transform .2s; }
  [aria-expanded="true"] .evc-chev { transform: rotate(180deg); }

  /* "Your next event" — the answer to when is it / where do I sit / where is
     my ticket, before any tap. */
  .evc-next { background: linear-gradient(135deg, #14532d, #1a7a44); color: #fff;
              border-radius: var(--radius); padding: .9rem; margin-bottom: 1rem; box-shadow: var(--shadow); }
  .evc-next .lbl { font-size: .85rem; letter-spacing: .08em; text-transform: uppercase; opacity: .9; font-weight: 700; }
  .evc-next .nm  { font-size: 1.35rem; font-weight: 800; line-height: 1.2; margin-top: .1rem; }
  .evc-next .mt  { font-size: 1.05rem; margin-top: .2rem; }
  .evc-next .seat{ font-size: 1.15rem; font-weight: 700; margin-top: .45rem;
                   background: rgba(255,255,255,.16); border-radius: 8px; padding: .35rem .55rem; display: inline-block; }
  .evc-count { background: var(--gold); color: #3a2600; font-weight: 800; border-radius: 20px;
               padding: .1rem .6rem; font-size: .9rem; display: inline-block; }
  /* Must come AFTER .evc-count — same specificity, so source order decides. */
  .evc-count-today { background: #b3271e; color: #fff; }
}
@media (prefers-reduced-motion: reduce) {
  .evc-chev { transition: none; }
  .collapsing { transition: none !important; }
}

/* The same sticky trap on a DESKTOP, where the menu is a floating dropdown rather than a
   collapsed list. A .dropdown-menu is absolutely positioned inside the pinned navbar, so
   anything past the bottom of the window is unreachable: the page scrolls, the pinned bar
   does not, and the menu goes with it. Collapsed the admin list just fits a tall screen;
   expanding Events adds six rows and pushes the tail off — measured at 1280x720, the menu
   came to 947px and Security's bottom edge sat at y=994, 274px below the fold.

   Scoped to min-width 992px ON PURPOSE: below that the .navbar-collapse cap further down
   already scrolls the whole menu, and capping the dropdown too would put a scroller inside
   a scroller. Offset measured, not guessed — the bar is 63px and the menu opens at y=57. */
@media (min-width: 992px) {
  .navbar.sticky-top .dropdown-menu {
    max-height: calc(100vh - 5rem);
    max-height: calc(100dvh - 5rem);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

/* A long menu in a STICKY navbar is unreachable past the fold, so let it scroll itself.
   `position: sticky; top: 0` pins the whole nav — and when the nav is taller than the
   window, everything below the fold is off-screen permanently: scrolling the page does
   not help, because the pinned element does not move. Measured on a 780px viewport with
   the admin menu open, the nav came to 991px and the last item (Security) sat at y=896,
   rendered but unreachable — which is exactly the "list stops at Mail History" report.

   The offset is measured, not guessed: the bar itself is 59px at phone width, so 3.75rem
   (60px) clears it. Too small a value and the last row clips, which is this same bug in
   miniature. Only the sticky navbar needs it (admin/header.php's is not sticky and has
   never shown this), and only below the breakpoint where the menu collapses. */
@media (max-width: 991.98px) {
  .navbar.sticky-top .navbar-collapse {
    max-height: calc(100vh - 3.75rem);
    max-height: calc(100dvh - 3.75rem);   /* dvh excludes the mobile browser's own chrome */
    overflow-y: auto;
    overscroll-behavior: contain;          /* don't scroll the page underneath it */
    padding-bottom: .5rem;                 /* the last row never sits flush against the cut */
  }
}

/* The Admin entry is a chip, not a plain nav link. It is the one item in the member navbar
   that leads somewhere with different consequences, and an admin scanning a phone menu should
   find it without reading every row.

   Amber on #3a2600 measures 8.84:1 — the most legible of the four treatments compared. Red
   LETTERING was the original request and was rejected on measurement, not taste: #dc3545 on
   this #1e5799 bar is 1.61:1, below the 4.5:1 needed for text and below even the 3:1 floor,
   so it would have made the item harder to see rather than easier. If red is ever wanted
   again it has to be the FILL (white on #a51d2a is 7.48:1), never the letters.

   The selector carries one more class than Bootstrap's `.navbar-nav .nav-link`, so it wins on
   specificity without !important. */
.navbar-nav .nav-link.nav-admin-chip {
  background: #ffc107;
  color: #3a2600;
  font-weight: 700;
  border-radius: 7px;
  /* Vertical padding keeps the chip at the 44px minimum touch target the rest of the
     phone nav holds; the plain .nav-link reaches it on its own padding. */
  padding: .6rem .75rem;
  margin: .15rem 0;
}
.navbar-nav .nav-link.nav-admin-chip:hover,
.navbar-nav .nav-link.nav-admin-chip:focus {
  background: #ffcd39;
  color: #3a2600;
}
@media (min-width: 992px) { .navbar-nav .nav-link.nav-admin-chip { margin: 0 .15rem; } }

/* A nav item that must POST — Logout — is a <button> inside a form rather than an <a>,
   so it needs the button chrome stripped to sit in the navbar. Colour and padding still
   come from .nav-link, so it matches its neighbours in both headers. */
.nav-link-btn {
  border: 0;
  background: none;
  font: inherit;
}

/* ── More visible checkboxes & radios (site-wide) ── */
.form-check-input[type="checkbox"],
.form-check-input[type="radio"] {
  width: 1.25em;
  height: 1.25em;
  margin-top: .15em;
  border-width: 2px;
  border-color: #6c757d;            /* darker, higher-contrast outline when unchecked */
  cursor: pointer;
}
.form-check-input:focus {
  border-color: #0d6efd;
  box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .35);
}
/* Keep toggle switches their normal pill width (don't shrink them). */
.form-switch .form-check-input {
  width: 2em;
}
/* Give the label a touch more room so the larger control doesn't crowd the text. */
.form-check-label { cursor: pointer; }

/* ── Registration details popup: bordered row per person ── */
.reg-person {
  border: 2px solid #9aa7b5;
  border-radius: 8px;
  padding: .35rem .75rem;
  margin-bottom: .5rem;
}

/* ── Deep-link targets ──
   The navbar is sticky-top on every page, so a link to #security (from the
   Guide, say) would otherwise land with the card header hidden underneath it. */
.card[id] { scroll-margin-top: 5rem; }
