:root {
  --ink: #1c2942;
  --muted: #576480;
  --line: #dde5f0;
  --bg: #f3f6fb;
  --card: #ffffff;
  /* Brand palette: the logo's periwinkle blue, deepened for contrast, is the
     primary; the logo's coral is the warm secondary accent. */
  --brand-blue: #7ea6e4;
  --accent: #3b6fc9;
  --accent-dark: #2c56a4;
  --accent-soft: #e9f0fb;
  --coral: #f4695c;
  --coral-dark: #c93f30;
  --coral-soft: #fdeeec;
  --ok: #2b8a3e;
  --warn: #b54708;
  --danger: #c92a2a;
}
@font-face {
  font-family: "Fredoka";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/fredoka-600-latin.woff2") format("woff2");
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
body {
  margin: 0; color: var(--ink);
  /* Soft sky wash at the top of every page that settles into the page gray. */
  background: linear-gradient(180deg, #e8f0fb 0%, var(--bg) 340px) no-repeat var(--bg);
  font: 16px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
main { max-width: 1200px; margin: 0 auto; padding: 24px 24px 64px; }
@media (max-width: 640px) { main { padding-left: 16px; padding-right: 16px; } }
a { color: var(--accent-dark); }

.site-header {
  position: relative;
  display: flex; justify-content: space-between; align-items: center;
  padding: 14px 24px; background: var(--card); border-bottom: 1px solid var(--line);
}
/* Thin brand ribbon under the header — the logo's blue melting into its coral. */
.site-header::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 3px;
  background: linear-gradient(90deg, var(--brand-blue), var(--accent) 45%, var(--coral));
}
.site-header .brand {
  display: inline-flex; flex-direction: column; align-items: flex-start;
  font-family: "Fredoka", "Trebuchet MS", "Segoe UI", Roboto, sans-serif;
  font-weight: 600; font-size: 1.3rem; line-height: 1.02; letter-spacing: .4px;
  color: #7ea6e4; text-decoration: none;
}
.brand .brand-coral { color: #f4695c; }
.brand .brand-molecule {
  overflow: visible; width: .66em; height: .66em;
  vertical-align: -0.02em; margin: 0 .04em;
}
/* Admin + family account pages keep the header pinned while scrolling long
   tables. (The 720px "position: relative" below loses to these on specificity,
   so the header stays sticky on mobile too.) */
body.admin .site-header, body.account .site-header {
  position: sticky; top: 0; z-index: 40;
}
/* Red "Development Mode" flag, dead-center in the header on every viewport —
   rendered only outside published deployments (devMode in app.js). */
.dev-mode-banner {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  color: #d11a2a; font-weight: 800; font-size: 1.35rem; letter-spacing: .05em;
  text-transform: uppercase; white-space: nowrap; pointer-events: none;
}
/* Small screens: no room between the brand and the nav/year controls, so the
   banner becomes its own centered strip along the bottom of the header. */
@media (max-width: 720px) {
  .dev-mode-banner {
    font-size: .85rem; letter-spacing: .02em;
    top: auto; bottom: 5px; transform: translateX(-50%);
  }
  .site-header:has(.dev-mode-banner) { padding-bottom: 28px; }
}
.site-header nav a { margin-left: 18px; text-decoration: none; color: var(--ink); font-weight: 600; }
/* Account dropdown: a <details> styled as a nav item, menu floats below */
.nav-account { display: inline-block; position: relative; margin-left: 18px; }
.nav-account summary {
  list-style: none; cursor: pointer; color: var(--ink); font-weight: 600;
}
.nav-account summary::-webkit-details-marker { display: none; }
.nav-account summary::after { content: " ▾"; color: var(--muted); }
.nav-account-menu {
  position: absolute; right: 0; top: calc(100% + 10px); z-index: 40;
  min-width: 170px; padding: 6px;
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 10px 20px rgba(26, 34, 51, .12);
}
.nav-account-menu form { margin: 0; border-top: 1px solid var(--line); margin-top: 6px; padding-top: 6px; }
.site-header .nav-account-menu a,
.site-header .nav-account-menu button {
  display: block; width: 100%; margin: 0; padding: 8px 10px; border: 0;
  border-radius: 8px; background: none; text-align: left; cursor: pointer;
  color: var(--ink); font: inherit; font-weight: 600; text-decoration: none;
}
.site-header .nav-account-menu a:hover,
.site-header .nav-account-menu button:hover { background: var(--bg); }
/* Admin header controls: year picker sits left of the account menu */
.admin-header-controls { display: flex; align-items: center; gap: 18px; }
.admin-header-controls .nav-account { margin-left: 0; }
.admin-year { display: flex; align-items: center; gap: 8px; }
.admin-year label { margin: 0; color: var(--muted); font-size: .9rem; }
.admin-year select {
  width: auto; min-height: 0; padding: 6px 32px 6px 10px; font-size: .9rem;
  background-position: right 10px center;
}
.cart-count { color: var(--coral-dark); }
.nav-toggle { display: none; }
@media (max-width: 720px) {
  .site-header { position: relative; }
  .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    position: relative; width: 42px; height: 42px; margin: -6px -10px -6px 0;
    border: 0; border-radius: 8px; background: none; color: var(--ink); cursor: pointer;
  }
  .nav-toggle-count {
    position: absolute; top: 3px; right: 1px; min-width: 16px; height: 16px;
    border-radius: 8px; padding: 0 4px; background: var(--coral-dark); color: #fff;
    font-size: .68rem; font-weight: 700; line-height: 16px; text-align: center;
  }
  .site-header nav {
    display: none;
    position: absolute; top: 100%; left: 0; right: 0; z-index: 30;
    background: var(--card); border-bottom: 1px solid var(--line);
    box-shadow: 0 10px 20px rgba(26, 34, 51, .08);
    padding: 6px 12px 10px;
  }
  .site-header.nav-open nav { display: block; }
  .site-header nav a { display: block; margin: 0; padding: 10px 12px; border-radius: 8px; }
  .site-header nav a:active { background: var(--bg); }
  /* In the collapsed panel the dropdown expands in place instead of floating.
     (Scoped to the nav so the admin header's account menu keeps floating.) */
  .site-header nav .nav-account { display: block; margin: 0; }
  .site-header nav .nav-account summary { padding: 10px 12px; border-radius: 8px; }
  .site-header nav .nav-account-menu {
    position: static; min-width: 0; padding: 0 0 0 14px;
    border: 0; border-radius: 0; box-shadow: none;
  }
}
.site-footer { text-align: center; color: var(--muted); padding: 24px; font-size: .85rem; }

h1 {
  font-family: "Fredoka", "Trebuchet MS", "Segoe UI", Roboto, sans-serif;
  font-weight: 600; letter-spacing: .01em;
  font-size: 1.7rem; margin: 8px 0 20px;
}
h2 { font-size: 1.15rem; margin: 24px 0 10px; }

.card {
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 18px 20px; margin-bottom: 14px;
  box-shadow: 0 1px 3px rgba(28, 41, 66, .05);
}
.session-card { display: flex; justify-content: space-between; gap: 16px; align-items: center; flex-wrap: wrap; }
.session-meta {
  color: var(--muted); font-size: .92rem;
  display: flex; flex-wrap: wrap; align-items: center;
  column-gap: 18px; row-gap: 4px; margin-top: 2px;
}
.meta-item { display: inline-flex; align-items: center; gap: 6px; }
.meta-icon { flex: none; }
.spots-low { color: var(--warn); font-weight: 700; }
.spots-ok { color: var(--ok); }
.sold-out { color: var(--danger); font-weight: 700; }
.early-bird-tag {
  display: inline-block; padding: 1px 8px; border-radius: 99px;
  background: var(--ok); color: #fff; font-size: .72rem; font-weight: 700;
  vertical-align: 1px;
}

.btn {
  display: inline-block; border: 0; border-radius: 9px; cursor: pointer;
  background: var(--accent); color: #fff; font-weight: 700; font-size: .95rem;
  padding: 10px 18px; text-decoration: none; text-align: center;
  box-shadow: 0 1px 2px rgba(44, 86, 164, .28);
  transition: background-color .12s ease, box-shadow .12s ease;
}
.btn:hover { background: var(--accent-dark); box-shadow: 0 2px 6px rgba(44, 86, 164, .3); }
.btn.secondary { background: var(--accent-soft); color: var(--accent-dark); box-shadow: none; }
.btn.secondary:hover { background: #dbe7f8; }
.btn.small { padding: 6px 12px; font-size: .85rem; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

/* ---------- "Add to Calendar" dropdown (confirmation + /my) ---------- */
.cal-menu { position: relative; display: inline-block; }
.cal-menu summary { list-style: none; white-space: nowrap; user-select: none; }
.cal-menu summary::-webkit-details-marker { display: none; }
.cal-menu-list {
  position: absolute; right: 0; top: calc(100% + 4px); z-index: 30;
  min-width: 185px; padding: 6px; background: var(--card);
  border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 10px 20px rgba(26, 34, 51, .12);
}
.cal-menu-list a {
  display: block; padding: 8px 10px; border-radius: 6px; white-space: nowrap;
  color: var(--ink); font-size: .9rem; text-decoration: none;
}
.cal-menu-list a:hover { background: var(--accent-soft); }

/* ---------- instant tooltip (replaces the sluggish browser-native title bubble) ---------- */
[data-tip] { position: relative; }
[data-tip]::after {
  content: attr(data-tip);
  position: absolute; right: 0; bottom: calc(100% + 9px);
  /* --tip-dx: horizontal shift set by the viewport clamp in session-browser.js
     so the bubble never hangs off the screen edge on narrow viewports. */
  width: max-content; max-width: min(280px, calc(100vw - 32px));
  background: var(--ink); color: #fff;
  font-size: .8rem; font-weight: 500; line-height: 1.45; text-align: left;
  white-space: normal; padding: 8px 11px; border-radius: 8px;
  box-shadow: 0 6px 18px rgba(26, 34, 51, .22);
  opacity: 0; transform: translate(var(--tip-dx, 0px), 3px);
  transition: opacity .12s ease, transform .12s ease;
  pointer-events: none; z-index: 40;
}
[data-tip]::before {
  content: ""; position: absolute; right: 20px; bottom: calc(100% + 3px);
  border: 6px solid transparent; border-top-color: var(--ink);
  opacity: 0; transform: translateY(3px);
  transition: opacity .12s ease, transform .12s ease;
  pointer-events: none; z-index: 40;
}
[data-tip]:hover::after, [data-tip]:focus::after {
  opacity: 1; transform: translateX(var(--tip-dx, 0px));
}
[data-tip]:hover::before, [data-tip]:focus::before {
  opacity: 1; transform: none;
}

/* ---------- form controls ---------- */
label { display: block; font-weight: 600; font-size: .875rem; margin: 12px 0 6px; letter-spacing: .01em; }
input:where(:not([type=checkbox], [type=radio], [type=range], [type=file], [type=color], [type=submit], [type=button])),
textarea, select {
  width: 100%; min-height: 44px; padding: 10px 14px;
  border: 1px solid var(--line); border-radius: 10px;
  font: inherit; color: var(--ink); background-color: #fff;
  transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}
input:where(:not([type=checkbox], [type=radio], [type=range], [type=file], [type=color], [type=submit], [type=button])):hover:not(:focus),
textarea:hover:not(:focus), select:hover:not(:focus) { border-color: #c3cbd8; }
input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(59, 111, 201, .18);
}
::placeholder { color: #9aa3b4; opacity: 1; }
input[readonly] { background-color: #f2f4f8; color: var(--muted); cursor: default; }
input[readonly]:hover, input[readonly]:focus-visible { border-color: var(--line); box-shadow: none; }
input:-webkit-autofill, input:-webkit-autofill:hover, input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--ink); caret-color: var(--ink);
  -webkit-box-shadow: 0 0 0 1000px #fff inset;
}
input[readonly]:-webkit-autofill { -webkit-box-shadow: 0 0 0 1000px #f2f4f8 inset; }
select {
  appearance: none; cursor: pointer; padding-right: 38px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 6l4 4 4-4' stroke='%235b6474' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; background-size: 16px;
}
input.is-invalid, textarea.is-invalid, select.is-invalid {
  border-color: var(--danger); background-color: #fff6f6;
  box-shadow: 0 0 0 3px rgba(201, 42, 42, .18);
}
input.is-invalid:focus-visible, textarea.is-invalid:focus-visible, select.is-invalid:focus-visible {
  border-color: var(--danger); box-shadow: 0 0 0 3px rgba(201, 42, 42, .28);
}
input[type=checkbox], input[type=radio] { accent-color: var(--accent); width: 16px; height: 16px; }
textarea { min-height: 88px; resize: vertical; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 20px; align-items: start; }
@media (max-width: 640px) { .field-row { grid-template-columns: 1fr; gap: 0; } }
.optional-details { margin-top: 18px; border: 1px dashed #d4dae4; border-radius: 10px; padding: 2px 16px 14px; }
.optional-details summary {
  cursor: pointer; user-select: none; list-style-position: inside;
  font-weight: 600; font-size: .9rem; color: var(--muted); padding: 10px 0;
}
.optional-details summary:hover { color: var(--ink); }
.optional-details[open] summary { color: var(--ink); }

/* Inline info chip inside an .optional-details summary ("Will also receive
   camp emails") — sized to sit on the summary's own text line. */
.summary-note {
  display: inline-block; margin-left: 8px; padding: 1px 9px; border-radius: 999px;
  background: #e7f0fb; border: 1px solid #c9ddf3; color: #31537d;
  font-size: .76rem; font-weight: 600; line-height: 1.5; vertical-align: 1px;
}

.checkbox-row { display: flex; align-items: center; gap: 8px; margin: 6px 0; font-weight: 400; }
.checkbox-row input { width: auto; }

/* ---------- address autocomplete (checkout family step) ---------- */
.addr-anchor { position: relative; }
.addr-suggestions {
  position: absolute; z-index: 30; left: 0; right: 0; margin-top: 4px;
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 8px 24px rgba(26, 34, 51, .12); overflow: hidden;
}
.addr-option {
  display: block; width: 100%; padding: 8px 12px; border: 0; background: none;
  text-align: left; cursor: pointer; font: inherit; color: var(--ink);
}
.addr-option:hover, .addr-option.is-active { background: var(--bg); }
.addr-main { font-weight: 600; font-size: .92rem; }
.addr-sub { display: block; color: var(--muted); font-size: .8rem; }
.addr-attribution {
  padding: 4px 12px 6px; text-align: right; color: var(--muted);
  font-size: .7rem; border-top: 1px solid var(--line);
}

table.data { width: 100%; border-collapse: collapse; background: var(--card); border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
table.data th, table.data td { text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--line); font-size: .92rem; }
table.data th { background: #edf2fa; font-size: .8rem; text-transform: uppercase; letter-spacing: .4px; color: #47598a; }
table.data tr:last-child td { border-bottom: 0; }

.summary-line { display: flex; justify-content: space-between; gap: 12px; padding: 4px 0; }
.summary-line .line-label { display: flex; flex-direction: column; gap: 1px; }
.summary-line .line-sub { line-height: 1.25; }
.summary-line .line-loc { display: inline-flex; align-items: center; gap: 5px; }
.summary-line.total { font-weight: 800; font-size: 1.1rem; border-top: 2px solid var(--ink); margin-top: 8px; padding-top: 10px; }
.summary-line .neg { color: var(--ok); }

.badge { display: inline-block; padding: 2px 9px; border-radius: 99px; font-size: .75rem; font-weight: 700; }
.badge.paid, .badge.confirmed { background: #e6f4ea; color: var(--ok); }
.badge.pending { background: #fff4e5; color: var(--warn); }
.badge.cancelled, .badge.refunded, .badge.partial_refund { background: #fdecec; color: var(--danger); }
.badge.abandoned { background: #eceef1; color: var(--muted); }
.badge.withdrawn { background: #f3e8fd; color: #7c3aed; }
.badge.refund_pending { background: #fff4e5; color: var(--warn); }
.badge.refund_complete { background: #e6f4ea; color: var(--ok); }
.badge.refund_failed { background: #fdecec; color: var(--danger); }
.badge.waitlist { background: #e7f0fe; color: #1a56db; }
.badge.self-checkout { background: #e7f0fe; color: #1a56db; }

.error-box { background: #fdecec; border: 1px solid #f5c2c7; color: var(--danger); border-radius: 8px; padding: 12px 16px; margin: 12px 0; }
.ok-box { background: #e6f4ea; border: 1px solid #bbdfc4; color: var(--ok); border-radius: 8px; padding: 12px 16px; margin: 12px 0; }
.notice { background: #e7f0fe; border: 1px solid #c6dafc; border-radius: 8px; padding: 12px 16px; margin: 12px 0; }
.muted { color: var(--muted); }
/* /my header: greeting on the left, sign-out on the same line at the right */
.account-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 18px 0; }
.account-head h1 { margin: 0; }
/* extended-care ✓/✗ on the account registrations table */
/* Extended-care / self-checkout marks: filled circles (green check / red X)
   so yes and no read apart at a glance, not just by glyph shape. */
.care-mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 50%; flex: none;
  font-size: .72rem; font-weight: 800; line-height: 1; color: #fff;
  vertical-align: text-bottom;
}
.care-mark.yes { background: var(--ok); }
/* Softer than --danger: "no care" is normal state on most rows, not an alarm. */
.care-mark.no  { background: #e29d9d; }
/* On phones the /my tables (7 columns at their widest) collapse into stacked
   row-cards: header rows disappear, the first cell becomes the card title,
   cells with a data-label render as label/value lines, and unlabeled cells
   (session details, action buttons) flow as plain blocks. */
@media (max-width: 640px) {
  table.data.responsive, table.data.responsive tbody,
  table.data.responsive tr, table.data.responsive td { display: block; }
  table.data.responsive { border: 0; background: none; overflow: visible; }
  table.data.responsive tr:has(th), table.data.responsive th { display: none; }
  table.data.responsive tr {
    background: var(--card); border: 1px solid var(--line); border-radius: 10px;
    padding: 7px 0 9px; margin-bottom: 10px;
  }
  table.data.responsive tr:last-child { margin-bottom: 0; }
  table.data.responsive td { border: 0; padding: 3px 14px; }
  table.data.responsive td:first-child {
    padding-top: 8px; font-weight: 700; font-size: .98rem; color: var(--ink);
  }
  table.data.responsive td:empty { display: none; }
  table.data.responsive td[data-label] {
    display: flex; justify-content: space-between; align-items: baseline; gap: 14px;
  }
  table.data.responsive td[data-label]::before {
    content: attr(data-label); flex: none;
    color: #47598a; font-size: .72rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .4px;
  }
}
.right { text-align: right; }
.mt { margin-top: 18px; }

/* ---------- admin sidebar layout ---------- */
body.admin main { max-width: 1500px; }
.admin-layout { display: flex; gap: 28px; align-items: flex-start; }
.admin-sidebar {
  /* Sits below the (sticky) site header; --header-h is measured in head.ejs. */
  flex: 0 0 190px; position: sticky; top: calc(var(--header-h, 72px) + 20px);
  display: flex; flex-direction: column; gap: 20px;
}
.admin-nav-title {
  font-size: .72rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 4px; padding-left: 10px;
}
.admin-nav-group a {
  display: block; padding: 7px 10px; border-radius: 7px;
  text-decoration: none; font-weight: 600; color: var(--ink);
}
.admin-nav-group a:hover { background: var(--accent-soft); }
.admin-nav-group a.is-active { background: var(--accent); color: #fff; }
.admin-content { flex: 1; min-width: 0; }
.admin-content > h1:first-of-type { margin-top: 0; }
.admin-logout { padding-left: 10px; }
@media (max-width: 900px) {
  .admin-layout { display: block; }
  .admin-sidebar {
    position: static; flex-direction: row; flex-wrap: wrap; align-items: center;
    gap: 8px 18px; margin-bottom: 18px;
  }
  .admin-nav-group { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; }
  .admin-nav-title { margin: 0; padding: 0 6px 0 0; }
}

/* ---------- guided checkout ---------- */
.stepper {
  display: flex; gap: 8px; margin-bottom: 22px; flex-wrap: wrap;
}
.step {
  display: flex; align-items: center; gap: 8px; border: 0; cursor: default;
  background: #e9edf5; color: var(--muted); font: inherit; font-weight: 600; font-size: .9rem;
  padding: 8px 16px; border-radius: 99px;
}
.step.is-done { cursor: pointer; color: var(--ink); background: #e3f2e7; }
.step.is-done .step-num { background: var(--ok); color: #fff; }
.step.is-done .step-num::before { content: "✓"; }
.step.is-done .step-num { font-size: 0; }
.step.is-done .step-num::before { font-size: .75rem; }
.step.is-active { background: var(--accent); color: #fff; box-shadow: 0 2px 8px rgba(44, 86, 164, .3); }
.step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%; background: #fff; color: var(--ink);
  font-size: .8rem; font-weight: 800;
}
.step.is-active .step-num { background: var(--coral); color: #fff; }

.checkout-grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 24px; align-items: start; }
/* Before sessions are picked there is nothing to total, so the wizard runs full width. */
.checkout-grid.no-summary { grid-template-columns: minmax(0, 1fr); }
.summary-col { position: sticky; top: 16px; }
.summary-col[hidden] { display: none; }
/* Order summary: an accordion like the discounts card — collapsed on mobile it
   shows just the title and the running total; desktop keeps it pinned open. */
.summary-card { padding: 0; border-top: 3px solid var(--brand-blue); }
.summary-card details { padding: 14px 20px 16px; }
.summary-card summary {
  display: flex; align-items: center; gap: 10px; cursor: pointer; list-style: none;
  font-weight: 700; padding: 4px 0;
}
.summary-card summary::-webkit-details-marker { display: none; }
.summary-title { font-size: 1.05rem; }
.summary-mini { margin-left: auto; font-weight: 800; }
.summary-card details[open] .disc-caret { transform: rotate(180deg); }
.summary-card details[open] summary { margin-bottom: 8px; }
@media (min-width: 861px) {
  .summary-card summary { pointer-events: none; }
  .summary-card .disc-caret, .summary-card .summary-mini { display: none; }
}
@media (max-width: 860px) {
  .checkout-grid { grid-template-columns: 1fr; }
  .summary-col { position: static; order: -1; }
  main { padding-bottom: 110px; }
}

.session-chip {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  background: var(--accent-soft); border: 1px solid #cfdef5; border-radius: 8px;
  padding: 9px 12px; margin-bottom: 8px;
}
.chip-x {
  border: 0; background: transparent; color: var(--muted); font-size: 1.2rem;
  cursor: pointer; line-height: 1; padding: 2px 6px; border-radius: 6px;
}
.chip-x:hover { background: #fdecec; color: var(--danger); }
.link-add { display: inline-block; margin-top: 4px; font-weight: 600; text-decoration: none; }

.camper-card .camper-head { display: flex; justify-content: space-between; align-items: center; }
.camper-card .camper-head h2 { margin: 0 0 4px; }
.camper-remove {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid #f5c2c7; background: #fff; color: var(--danger);
  font-weight: 600; font-size: .85rem; padding: 6px 12px; border-radius: 8px; cursor: pointer;
}
.camper-remove:hover { background: #fdecec; }
/* Helper text between a field's label and its input (e.g. medical notes). */
.field-hint { margin: -2px 0 6px; }
.add-camper-btn { width: 100%; text-align: left; margin-bottom: 6px; }
.save-hint { color: var(--ok); font-weight: 600; font-size: .88rem; }
.req { color: var(--coral-dark); }
.eyebrow { color: var(--coral-dark); text-transform: uppercase; letter-spacing: .12em; font-size: .72rem; font-weight: 800; margin: 0 0 6px; }
/* Steppers render above the title, so the intro only needs bottom spacing. */
.wizard-intro { margin: 0 0 22px; }
.wizard-intro h1 { font-size: clamp(1.8rem, 4vw, 2.8rem); margin: 0 0 4px; }
/* Desktop: chips wrap onto extra rows instead of scrolling sideways. */
.wizard-steps { flex-wrap: wrap; padding-bottom: 4px; margin-top: 14px; }
.wizard-steps .step { white-space: nowrap; flex: 0 0 auto; }
.wizard-steps .step:not(.is-active):not(.is-done) { background: #e6edf9; }

/* Mobile: the chip row is replaced by a compact "Step X of Y" progress bar —
   the idiomatic small-screen pattern instead of a horizontally scrolling list. */
.stepper-compact { display: none; margin: 14px 0 20px; }
.stepper-compact-info { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 7px; }
.progress-track { height: 8px; border-radius: 99px; background: #dbe4f2; overflow: hidden; }
.progress-fill {
  height: 100%; border-radius: 99px;
  background: linear-gradient(90deg, var(--brand-blue), var(--accent));
  transition: width .25s ease;
}
@media (max-width: 700px) {
  .wizard-steps { display: none; }
  .stepper-compact { display: block; }
}
.session-tabs, .availability-tabs { display: flex; gap: 8px; flex-wrap: wrap; margin: 12px 0; }
.session-option { display: flex; justify-content: space-between; gap: 12px; padding: 14px; border: 1px solid var(--line); border-radius: 9px; margin: 8px 0; }
.session-option.is-waitlist { background: #fff8ed; border-color: #f2d6ab; }
.session-option label { margin: 0; flex: 1; display: flex; gap: 10px; align-items: flex-start; }
.session-option input { width: auto; margin-right: 8px; margin-top: 3px; }
.session-opt-main { display: flex; flex-direction: column; gap: 2px; }
.session-opt-side { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; white-space: nowrap; }

/* Per-camper session step: selection-count callout above the picker. */
.step-3-title { margin-top: 0; }

/* Session browser (shared by /sessions and checkout step 3) */
.session-card.is-outside { opacity: .8; background: #fbfbfd; }
.session-card.is-conflict { background: #fbfbfd; }
.session-card.is-selected { border-color: var(--ok); box-shadow: 0 0 0 1px var(--ok); }
.outside-reason { margin-top: 6px; color: var(--warn); }
/* Dimmed via colors, not opacity — element opacity would fade the [data-tip]
   tooltip rendered from this button's pseudo-elements. */
.btn.sb-conflict { background: #f0f2f6; color: #a2abbc; cursor: not-allowed; }
.btn.sb-conflict:hover { background: #f0f2f6; }
.dm-conflict { flex-basis: 100%; margin: 0 0 4px; color: var(--warn); font-weight: 600; }
.btn.added { background: var(--ok); }
.btn.added:hover { background: #237033; }
.dm-outside { flex-basis: 100%; margin: 0 0 4px; color: var(--warn); }

/* "Available discounts" card: always open on desktop, tap-to-expand on mobile. */
.discounts-card { padding: 0; border-top: 3px solid var(--coral); }
.discounts-card details { padding: 14px 20px 16px; }
.discounts-card summary {
  display: flex; align-items: center; gap: 10px; cursor: pointer; list-style: none;
  font-weight: 700; padding: 4px 0;
}
.discounts-card summary::-webkit-details-marker { display: none; }
.discounts-title { font-size: 1.05rem; }
.disc-hint { margin-left: auto; color: var(--ok); font-size: .82rem; font-weight: 700; }
.disc-caret { color: var(--muted); transition: transform .15s ease; }
.discounts-card details[open] .disc-caret { transform: rotate(180deg); }
.disc-tier { display: flex; align-items: flex-start; gap: 12px; padding: 10px 0; border-top: 1px solid var(--line); }
.discounts-card details[open] .disc-tier:first-of-type { margin-top: 8px; }
.disc-tier.is-active { border-left: 3px solid var(--ok); padding-left: 10px; margin-left: -13px; }
.disc-main { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.disc-state { font-size: .8rem; font-weight: 700; color: var(--muted); white-space: nowrap; }
.disc-state.on { color: var(--ok); }
@media (min-width: 861px) {
  .discounts-card summary { pointer-events: none; }
  .discounts-card .disc-caret { display: none; }
}

/* Wizard step chips are all clickable; sticky footer holds back/continue. */
.wizard-steps .step { cursor: pointer; }
.wizard-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  background: var(--card); border-top: 1px solid var(--line);
  box-shadow: 0 -4px 16px rgba(20, 30, 50, .08);
  padding: 12px 24px; display: flex; align-items: center; gap: 12px;
}
.wizard-bar[hidden] { display: none; }
.wizard-bar .btn[hidden] { display: none; }
.wizard-bar .btn { min-width: 130px; }
.wizard-bar-spacer { flex: 1; }
.has-wizard-bar { padding-bottom: 84px; }
.pickup-row { display: grid; grid-template-columns: 1fr 1fr auto; gap: 8px; margin: 8px 0; align-items: center; }
.pickup-row input { min-width: 0; }
.pickup-prompt { background: #fff8ed; border: 1px solid #f2d6ab; border-radius: 9px; padding: 16px; margin-bottom: 18px; }
@media (max-width:640px){.pickup-row{grid-template-columns:1fr 1fr auto}.pickup-row input{font-size:.9rem}.step-actions .btn{width:100%}}
.small { font-size: .85rem; }

.health-details { margin-top: 10px; }
.health-details summary { cursor: pointer; font-weight: 600; font-size: .9rem; color: var(--muted); }

.checkbox-row { display: flex; justify-content: space-between; border: 1px solid var(--line); border-radius: 7px; padding: 8px 10px; }
.checkbox-row:hover { border-color: var(--accent); }
.cb-name { flex: 1; }
.cb-price { font-weight: 600; white-space: nowrap; }

.step-actions { display: flex; gap: 10px; margin-top: 16px; }
.btn-continue, .btn-pay { flex: 1; max-width: 320px; }

.promo-row { display: flex; gap: 8px; align-items: center; margin-top: 14px; flex-wrap: wrap; }
.promo-row input { max-width: 200px; }
.promo-ok { color: var(--ok); font-weight: 600; font-size: .9rem; }
.promo-bad { color: var(--danger); font-weight: 600; font-size: .9rem; }

/* Cancellation policy: read it, then sign by typing the guardian's own name. */
.policy-card p, .policy-card li { color: var(--muted); font-size: .9rem; line-height: 1.5; }
.policy-title { margin-top: 0; }
.policy-list { margin: 0 0 12px; padding-left: 22px; }
.policy-list li { margin-bottom: 4px; }
.policy-sign { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.policy-sign input { max-width: 360px; }
.policy-hint { margin: 6px 0 0; color: var(--muted); font-size: .85rem; }
.policy-hint strong { color: var(--ink); }

/* Payment method toggle: credit card vs ACH bank transfer on the review step. */
.pay-method-toggle { display: flex; gap: 14px; }
.pay-method {
  position: relative; flex: 1; display: flex; flex-direction: column; gap: 3px;
  padding: 18px 16px; border: 2px solid var(--line); border-radius: 12px;
  background: var(--card); color: var(--ink); font: inherit; text-align: left; cursor: pointer;
}
.pay-method:hover { border-color: var(--accent); }
.pay-method.is-selected { border-color: var(--accent); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent); }
.pay-method .pm-name { font-weight: 800; font-size: 1.05rem; }
@media (max-width: 640px) { .pay-method-toggle { flex-direction: column; } }

.hold-note { background: #fffaf0; border-color: #fde9c8; }
.trust-row { color: var(--muted); font-size: .85rem; }

.review-table .review-camper td { background: #edf2fa; font-weight: 700; }
.review-table .discount-row td { color: var(--ok); font-size: .88rem; border-top: 0; padding-top: 0; }
.review-table .review-subtotal td { font-weight: 600; color: var(--muted); }
.review-table .review-total td { font-weight: 800; font-size: 1.05rem; border-top: 2px solid var(--ink); }
.neg { color: var(--ok); }

.mobile-paybar {
  display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  background: var(--card); border-top: 1px solid var(--line);
  padding: 10px 16px; justify-content: space-between; align-items: center; gap: 16px;
  box-shadow: 0 -4px 16px rgba(20, 30, 50, .08);
}
@media (max-width: 860px) { .mobile-paybar:not([hidden]) { display: flex; } }

.empty-state { text-align: center; padding: 44px 20px; }

/* ---------- sessions page ---------- */
.filter-bar {
  /* Top-aligned so a field carrying a hint under its control (the locked grade
     filter) doesn't push its label out of line with the rest. */
  display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap;
  margin-bottom: 18px; padding: 14px;
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
}
.filter-field { flex: 0 1 160px; min-width: 130px; margin: 0; padding: 0; border: 0; }
.filter-field-location { flex-basis: 260px; min-width: 220px; }
.filter-field-search { flex: 1 1 200px; min-width: 170px; }
.filter-input {
  border: 1px solid var(--line); background-color: var(--card); color: var(--ink);
  font: inherit; font-size: .85rem; font-weight: 600;
  width: 100%; min-height: 38px; padding: 7px 11px; border-radius: 7px;
}
.filter-label {
  display: block; margin: 0 0 5px; color: var(--muted);
  font-size: .76rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
}
.filter-chip {
  border: 1px solid var(--line); background: var(--card); color: var(--ink);
  font: inherit; font-size: .85rem; font-weight: 600;
  padding: 6px 14px; border-radius: 99px; cursor: pointer;
}
.filter-chip.is-active { background: var(--accent); color: #fff; border-color: var(--accent); }
.filter-select {
  border: 1px solid var(--line); background-color: var(--card); color: var(--ink);
  font: inherit; font-size: .85rem; font-weight: 600;
  width: 100%; min-height: 38px; padding: 7px 34px 7px 11px; border-radius: 7px; cursor: pointer;
}
/* A filter pinned by the wizard (grade on the per-camper step) reads as fixed. */
.filter-select:disabled { background-color: #f2f4f8; color: var(--muted); cursor: not-allowed; opacity: 1; }
.location-filter { position: relative; }
.location-filter-button {
  width: 100%; min-height: 38px; display: flex; justify-content: space-between; align-items: center; gap: 10px;
  border: 1px solid var(--line); border-radius: 7px; padding: 7px 11px;
  background: var(--card); color: var(--ink); font: inherit; font-size: .85rem; font-weight: 600;
  cursor: pointer; text-align: left;
}
.location-filter-button.has-selection { border-color: var(--accent); }
.location-filter-button:focus-visible, .filter-select:focus-visible, .filter-input:focus-visible {
  outline: 3px solid rgba(59, 111, 201, .22); outline-offset: 1px; border-color: var(--accent);
}
.location-filter-menu {
  position: absolute; z-index: 40; top: calc(100% + 6px); left: 0;
  width: min(360px, calc(100vw - 48px)); max-height: 280px; overflow-y: auto;
  background: var(--card); border: 1px solid var(--line); border-radius: 9px;
  padding: 6px; box-shadow: 0 12px 30px rgba(20, 30, 50, .16);
}
.location-option { display: flex; align-items: center; gap: 8px; border-radius: 6px; }
.location-option:hover, .location-option:focus-within { background: var(--accent-soft); }
.location-check {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 9px;
  margin: 0; padding: 8px; cursor: pointer; font-size: .85rem; font-weight: 500;
}
.location-check input { flex: 0 0 auto; width: auto; }
.location-check span { overflow-wrap: anywhere; }
.location-only {
  border: 0; background: transparent; color: var(--accent-dark); cursor: pointer;
  padding: 7px 8px; border-radius: 5px; font: inherit; font-size: .78rem; font-weight: 700;
}
.location-only:hover, .location-only:focus-visible { background: var(--accent-soft); outline: none; }
@media (max-width: 640px) {
  .filter-bar { align-items: stretch; gap: 10px; }
  .filter-field, .filter-field-location { flex: 1 1 calc(50% - 5px); min-width: 140px; }
  .filter-field-search { flex: 1 1 100%; }
}

/* Small start–end date headings the cards group under in the scroll. */
.session-group-head {
  display: flex; align-items: center; gap: 10px; margin: 22px 0 10px;
  color: var(--accent-dark); font-size: .8rem; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase;
}
.session-group-head::after { content: ''; flex: 1; height: 1px; background: #c9d7ec; }
.session-group:first-child .session-group-head { margin-top: 0; }

.session-info { flex: 1; min-width: 240px; }
.session-cta { display: flex; flex-direction: column; gap: 8px; min-width: 150px; }
.session-cta .btn { width: 100%; }
@media (max-width: 640px) {
  .session-cta { flex-direction: row; width: 100%; }
  .session-cta .btn { flex: 1; width: auto; }
}
.capacity-row { display: flex; align-items: center; gap: 10px; margin-top: 6px; }
.capacity-meter {
  width: 120px; height: 8px; border-radius: 99px; background: #e0e8f4; overflow: hidden;
}
.capacity-fill { height: 100%; border-radius: 99px; background: var(--ok); }
.capacity-fill.hot { background: var(--warn); }


.next-steps { list-style: none; padding: 0; margin: 0; }
.next-steps li { padding: 7px 0; border-bottom: 1px solid var(--line); }
.next-steps li:last-child { border-bottom: 0; }

/* Referral placeholder card (confirmation page) */
.referral-card h2 { margin: 0 0 6px; }
.referral-card p { margin-top: 0; }
.referral-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.referral-code-input {
  flex: 0 1 210px; min-width: 160px; text-align: center; cursor: text;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-weight: 700; font-size: 1rem; letter-spacing: .12em;
}
input[readonly].referral-code-input { color: var(--ink); }
.referral-card p.share-lead { margin: 18px 0 0; padding-top: 14px; border-top: 1px solid var(--line); }
.share-actions { margin-top: 10px; }
@media (max-width: 640px) {
  .referral-actions .btn, .referral-code-input { flex: 1 1 100%; }
}

/* ---------- dialogs (session details + "who's coming?" picker) ---------- */
dialog.modal {
  border: 0; border-radius: 12px; padding: 0;
  width: min(480px, calc(100vw - 32px));
  box-shadow: 0 12px 40px rgba(20, 30, 50, .25);
}
dialog.modal::backdrop { background: rgba(20, 30, 50, .45); }
.modal-body { padding: 20px 22px 22px; }
.modal-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.modal-head h2 { margin: 0 0 6px; }
.modal-desc { white-space: pre-line; margin: 8px 0 14px; }
.details-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; margin-bottom: 6px; }
.details-fact span { display: block; }
.modal-actions { display: flex; gap: 10px; margin-top: 16px; }
.modal-actions .btn { flex: 1; }
/* /my camper add/edit dialog: wider than the info modals, and scrolls when
   the form outgrows the viewport. */
dialog.modal.camper-modal { width: min(620px, calc(100vw - 32px)); max-height: calc(100vh - 48px); overflow-y: auto; }
dialog.modal.age-grade-modal { width: min(460px, calc(100vw - 32px)); }
.new-child-row { gap: 8px; }
.new-child-row input[type=text] { flex: 1; min-width: 0; padding: 6px 9px; }
#cm-add-child { margin-top: 8px; }

/* ---------- sign in / create account tabs ---------- */
.auth-tabs { display: flex; gap: 8px; margin-bottom: 14px; }
.auth-tab {
  flex: 1; border: 1px solid var(--line); background: #eef0f4; color: var(--muted);
  font: inherit; font-weight: 700; font-size: .9rem; padding: 8px 12px;
  border-radius: 8px; cursor: pointer;
}
.auth-tab.is-active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ---------- admin data tables ---------- */
.tbl-toolbar { display: flex; align-items: center; gap: 12px; margin: 14px 0 10px; flex-wrap: wrap; }
.tbl-search { flex: 1; min-width: 220px; max-width: 400px; }
.tbl-spacer { flex: 1; }
.tbl-scroll { overflow-x: auto; }
table.data th a.tbl-sort { color: inherit; text-decoration: none; }
table.data th a.tbl-sort:hover { color: var(--ink); }
.tbl-dir { font-size: .65rem; margin-left: 3px; }
.tbl-filters th { background: #f7f8fa; padding: 5px 8px; font-weight: 400; text-transform: none; letter-spacing: 0; }
.tbl-filters input, .tbl-filters select { width: 100%; min-width: 64px; min-height: 0; padding: 5px 7px; font-size: .82rem; border: 1px solid var(--line); border-radius: 6px; font-family: inherit; background-color: #fff; }
.tbl-filters select { padding-right: 26px; background-position: right 6px center; background-size: 13px; }
.tbl-range { display: flex; flex-direction: column; gap: 4px; }
.tbl-range input { min-width: 0; }
.tbl-multi { position: relative; }
.tbl-multi summary { cursor: pointer; list-style: none; padding: 5px 7px; font-size: .82rem; border: 1px solid var(--line); border-radius: 6px; background: #fff; white-space: nowrap; }
.tbl-multi summary::after { content: ' ▾'; font-size: .65rem; color: var(--muted); }
.tbl-multi-list { position: absolute; z-index: 5; margin-top: 3px; padding: 7px 10px; background: #fff; border: 1px solid var(--line); border-radius: 6px; box-shadow: 0 4px 14px rgba(0,0,0,.1); display: flex; flex-direction: column; gap: 4px; }
.tbl-multi-list label { display: flex; align-items: center; gap: 6px; font-size: .82rem; white-space: nowrap; font-weight: 400; }
.tbl-multi-list input[type="checkbox"] { width: auto; min-width: 0; }
.tbl-apply { white-space: nowrap; }
.tbl-clear { margin-left: 6px; font-size: .85rem; }
.tbl-actions { white-space: nowrap; }
.tbl-actions a { margin-right: 8px; }
.tbl-pager { display: flex; align-items: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.tbl-per { font-size: .88rem; }
.tbl-per.current { font-weight: 700; }
.field-help { font-size: .82rem; margin: 2px 0 0; }
.req { color: var(--danger); }

/* ---------- admin reporting (sales history) ---------- */
/* Emphasis palette: current year in the accent, prior years recede to grays.
   The light gray sits under 3:1 on white, so the legend, per-band tooltip,
   and "Monthly detail" table carry the values — never color alone. */
.rpt-title { margin-bottom: 10px; }
.sales-chart { position: relative; padding: 18px 18px 10px; }
.sales-chart svg { display: block; width: 100%; height: auto; }
.rpt-grid { stroke: var(--line); stroke-width: 1; }
.rpt-axis { stroke: #c6ccd7; stroke-width: 1; }
.rpt-tick { fill: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }
.rpt-bar.cur { fill: var(--accent); }
.rpt-bar.p1 { fill: #7c8698; }
.rpt-bar.p2 { fill: #c3cad5; }
.rpt-hit { fill: transparent; }
.rpt-band:hover .rpt-hit, .rpt-band:focus .rpt-hit { fill: rgba(26, 34, 51, .05); }
.rpt-band:focus { outline: none; }
.rpt-band:focus-visible .rpt-hit { fill: rgba(26, 34, 51, .09); }
.rpt-legend { display: flex; justify-content: center; gap: 18px; padding: 8px 0 4px; font-size: .88rem; color: var(--muted); }
.rpt-legend span { display: inline-flex; align-items: center; gap: 6px; }
.rpt-swatch { display: inline-block; width: 12px; height: 12px; border-radius: 3px; }
.rpt-swatch.cur { background: var(--accent); }
.rpt-swatch.p1 { background: #7c8698; }
.rpt-swatch.p2 { background: #c3cad5; }
.rpt-tip {
  position: absolute; z-index: 5; pointer-events: none; min-width: 130px;
  background: #fff; border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 6px 18px rgba(26, 34, 51, .12); padding: 8px 10px; font-size: .85rem;
}
.rpt-tip-head { font-weight: 700; margin-bottom: 4px; }
.rpt-tip-row { display: flex; align-items: center; gap: 7px; margin: 2px 0; }
.rpt-tip-row .rpt-swatch { width: 10px; height: 4px; border-radius: 2px; }
.rpt-tip-row strong { font-variant-numeric: tabular-nums; }
.rpt-tip-row span { color: var(--muted); }
.rpt-monthly { margin: 14px 0 22px; }
.rpt-monthly summary { cursor: pointer; font-weight: 600; font-size: .9rem; color: var(--muted); padding: 4px 0; }
.rpt-monthly summary:hover, .rpt-monthly[open] summary { color: var(--ink); }
.rpt-monthly table.data td { font-variant-numeric: tabular-nums; }
.rpt-table td { font-variant-numeric: tabular-nums; }
.rpt-neg { color: var(--danger); }

/* Checkout add-ons step: one row per offered add-on, session-picker style */
.addon-group h2 { margin-top: 0; }
.addon-group-sub { margin-top: -6px; }
.addon-row { display: flex; align-items: center; gap: 12px; border: 1px solid var(--line); border-radius: 9px; padding: 10px 12px; margin: 8px 0; }
.addon-info { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.addon-qty-label { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.addon-qty { width: auto; }
.addon-row .sb-toggle { white-space: nowrap; }
@media (max-width: 640px) { .addon-row { flex-wrap: wrap; } .addon-info { flex-basis: 100%; } }

/* Add-on editor: "Available on" scope control */
.radio-line { display: flex; align-items: center; gap: 8px; font-weight: 400; margin: 4px 0; }
.radio-line input { width: auto; }
.session-picker { max-height: 280px; overflow-y: auto; display: grid; gap: 6px; margin-top: 8px; }
.session-picker .checkbox-row { margin: 0; font-weight: 400; }
.session-picker .checkbox-row input { width: auto; margin-right: 6px; }

/* Pull-to-refresh disc for the installed app (see /pull-to-refresh.js): rides
   just above the viewport and follows the finger down, arrow winding up as it
   goes; coral means "release to refresh", then it spins while reloading. */
.ptr-disc {
  position: fixed; top: -52px; left: 50%; margin-left: -22px; z-index: 60;
  width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--card); border: 1px solid var(--line);
  box-shadow: 0 6px 16px rgba(28, 41, 66, .18);
  will-change: transform; pointer-events: none;
}
.ptr-disc svg { width: 22px; height: 22px; color: var(--muted); transition: color .15s; }
.ptr-disc.ready svg { color: var(--coral); }
.ptr-disc.settling { transition: transform .25s ease-out; }
.ptr-disc.refreshing { transition: transform .15s ease-out; }
.ptr-disc.refreshing svg { color: var(--coral); animation: ptr-spin .8s linear infinite; }
@keyframes ptr-spin { to { transform: rotate(360deg); } }
/* Installed app: our gesture replaces the browser's top-edge behaviors, so
   turn off native overscroll effects that would fight it. */
@media (display-mode: standalone) {
  html, body { overscroll-behavior-y: none; }
}

@media print {
  .site-header, .site-footer, .no-print, .admin-sidebar { display: none !important; }
  body { background: #fff; }
  .card, table.data { border: 1px solid #999; }
}

/* ------------------------------------------------------------------ */
/* Staff check-in/checkout app (/desk) */

/* Staff tabs live in the site header (same hamburger collapse as the family
   nav); the current tab reads as a filled pill. */
.site-header nav a.current { background: var(--accent); color: #fff; padding: 7px 14px; border-radius: 99px; }
@media (max-width: 720px) {
  .site-header nav a.current { display: block; border-radius: 8px; }
}

.mode-banner { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; border-radius: 10px; padding: 12px 16px; margin: 0 0 14px; }
.mode-banner.mode-am { background: #e7f0fe; border: 1px solid #b7cff5; }
.mode-banner.mode-pm { background: #fff4e5; border: 1px solid #f2d3a2; }
.mode-banner .mode-title { display: flex; flex-direction: column; }
.mode-banner strong { font-size: 1.05rem; }

.staff-filters { display: flex; gap: 14px; flex-wrap: wrap; align-items: end; margin: 0 0 14px; }
.staff-filters label { display: flex; flex-direction: column; gap: 4px; font-weight: 600; font-size: .85rem; }
.staff-filters select { min-width: 180px; }

.stat-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; margin: 0 0 16px; }
.stat-card { display: flex; flex-direction: column; align-items: center; gap: 2px; border: 1px solid var(--line); border-radius: 10px; background: var(--card); padding: 12px 8px; text-decoration: none; color: var(--ink); }
.stat-card:hover { border-color: var(--accent); }
.stat-card.active { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.stat-card .stat-num { font-size: 1.7rem; font-weight: 800; line-height: 1.1; }
.stat-card .stat-label { font-size: .8rem; color: var(--muted); text-align: center; }

/* 2-tap attendance dropdown and its read-only twin (.status-chip, used by
   the history / registrations tables) — one chip language everywhere. */
.status-select, .status-chip { border-radius: 99px; font-size: .85rem; font-weight: 600; border: 1px solid var(--line); max-width: 100%; }
/* Size to the label (the base select rule is width:100%, which the narrow
   status column would squeeze into truncation), and clear the base chevron. */
.status-select { width: auto; min-height: 0; padding: 4px 28px 4px 12px; background-position: right 9px center; background-size: 14px; }
.status-chip { display: inline-block; padding: 3px 10px; }
/* background-color (not the background shorthand) — the shorthand would wipe
   the select's chevron background-image. */
.status-select.status-checked_in, .status-select.status-checked_out,
.status-chip.status-checked_in, .status-chip.status-checked_out { background-color: #e6f4ea; color: var(--ok); }
.status-select.status-absent, .status-chip.status-absent { background-color: #fdecec; color: var(--danger); }
.status-select.status-parent_arrived, .status-select.status-left_classroom,
.status-chip.status-parent_arrived, .status-chip.status-left_classroom { background-color: #fff4e5; color: var(--warn); }
.status-select.status-waiting_for_pickup, .status-chip.status-waiting_for_pickup { background-color: #e7f0fe; color: #1a56db; }
.status-chip.status-expected { background-color: #eceef1; color: var(--muted); }

/* Mark-absent confirm dialog (AM → PM switch) */
.absent-list { max-height: 40vh; overflow-y: auto; padding-left: 20px; }

/* First-visit-of-the-day location pick — styled like the banner's switch
   dialog: one white panel, dialog-weight heading, the same location cards. */
.welcome-screen {
  max-width: 560px; margin: 8vh auto 0;
  background: var(--card); border: 1px solid var(--line); border-radius: 16px;
  padding: 26px 30px 30px;
  box-shadow: 0 18px 44px rgba(26, 34, 51, .16);
}
.welcome-screen h1 { margin: 0 0 2px; font-size: 1.5rem; }
.welcome-date { color: var(--muted); font-size: 1.02rem; margin: 0 0 20px; }
.welcome-screen h2 { margin: 0 0 12px; font-size: 1.2rem; }
.welcome-locations { display: grid; gap: 10px; margin-top: 14px; }
.welcome-locations form { margin: 0; }
.welcome-location {
  /* appearance reset: without it Safari/iOS render native button chrome. */
  appearance: none; -webkit-appearance: none;
  width: 100%; padding: 14px 16px; font: inherit; font-weight: 700; cursor: pointer;
  border: 1px solid var(--line); border-radius: 12px; background: var(--card); color: var(--ink);
}
.welcome-location:hover { border-color: var(--accent); color: var(--accent); }
.welcome-location.secondary { font-weight: 600; color: var(--muted); }
.welcome-location.current { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
/* Step-2 role cards: title + subtitle, left-aligned (also used as an <a>). */
.welcome-role { display: block; text-align: left; text-decoration: none; box-sizing: border-box; }
.welcome-role .role-sub { display: block; font-weight: 400; color: var(--muted); font-size: 0.92rem; line-height: 1.4; margin-top: 4px; }
.mode-banner .location-link { color: inherit; text-decoration: underline; text-underline-offset: 3px; }

/* Bulk status change: row checkboxes + floating selection bar */
.bulk-check, .bulk-select-all-box { width: 18px; height: 18px; accent-color: var(--accent); cursor: pointer; }
.tbl-filters .bulk-select-all-box { min-height: 0; }
.bulk-select-all { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: .85rem; margin: 0 0 6px; }
/* Desktop keeps Select all at the top of the table's checkbox column; the
   filter-row copy is for the phone card layout, where the table is hidden. */
@media (min-width: 721px) { .staff-filters .bulk-select-all { display: none; } }
.roster-card-pick { flex: none; }
.bulk-bar {
  position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 50;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap; justify-content: center;
  background: var(--ink); color: #fff; border-radius: 14px; padding: 12px 18px;
  box-shadow: 0 12px 28px rgba(26, 34, 51, .35); max-width: calc(100vw - 24px);
}
.bulk-bar select { width: auto; min-height: 0; padding: 8px 34px 8px 12px; font-size: .9rem; border-radius: 8px; }
.bulk-bar .btn.secondary { background: transparent; color: #fff; border-color: rgba(255, 255, 255, .4); }

/* Today roster, phone layout: the table's horizontal scroll would hide the
   status control, so narrow screens swap it for stacked camper cards with
   the status chip prominent on the right. */
.roster-cards { display: none; }
.roster-card {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 12px 14px; box-shadow: 0 1px 3px rgba(28, 41, 66, .05);
}
.roster-card-info { min-width: 0; display: grid; gap: 2px; }
.roster-card-info .small { display: flex; align-items: center; gap: 6px; }
.roster-card-name { font-weight: 700; color: var(--ink); text-decoration: none; font-size: 1.02rem; }
.roster-card-status { margin: 0; flex: none; }
.roster-card .status-select { font-size: .95rem; padding: 8px 30px 8px 14px; }
@media (max-width: 720px) {
  .roster-desktop { display: none; }
  .roster-cards { display: grid; gap: 10px; }
}

/* Check-in / check-out flow pages */
.flow-camper { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.avatar { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 50%; background: var(--accent-soft); color: var(--accent-dark); font-weight: 800; flex: none; text-transform: uppercase; }
.avatar-lg { width: 60px; height: 60px; font-size: 1.3rem; }
.signature-input { font-style: italic; }
/* Checkout pickup picker: session-card-style tappable cards — the selected
   one gets a bold accent outline and a checked box. */
.pickup-cards { display: grid; gap: 10px; margin: 4px 0 14px; }
.pickup-card {
  display: flex; align-items: center; gap: 12px; margin: 0;
  border: 1px solid var(--line); border-radius: 10px; background: var(--card);
  padding: 12px 14px; cursor: pointer; font-weight: 400;
}
.pickup-card input { position: absolute; opacity: 0; pointer-events: none; }
.pickup-card-check {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border: 1px solid var(--line); border-radius: 6px;
  color: transparent; font-weight: 800; font-size: .8rem; flex: none; background: #fff;
}
.pickup-card-body { display: grid; gap: 1px; min-width: 0; }
.pickup-card.is-selected, .pickup-card:has(input:checked) {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft), inset 0 0 0 1px var(--accent);
}
.pickup-card.is-selected .pickup-card-check, .pickup-card:has(input:checked) .pickup-card-check {
  background: var(--accent); border-color: var(--accent); color: #fff;
}

/* Non-dismissable extended-care fee decision */
.care-dialog { max-width: 560px; margin: 40px auto; border: 2px solid var(--coral); }
.care-dialog h1 { margin-top: 0; font-size: 1.3rem; }
.care-dialog-actions { display: flex; gap: 10px; flex-wrap: wrap; margin: 16px 0; }

/* Saved filters (staff registrations). The selected chip — current table
   state exactly matches the saved query — shows a checked box + accent
   border; any filter change breaks the match and deselects it. */
.saved-filters { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 12px; }
.saved-filter-chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 99px; border: 1px solid var(--line); background: var(--card); color: var(--ink); text-decoration: none; font-size: .85rem; font-weight: 600; }
.saved-filter-chip:hover { border-color: var(--accent); color: var(--accent); }
.saved-filter-chip .chip-box { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; border: 1px solid var(--line); border-radius: 4px; font-size: .7rem; line-height: 1; background: #fff; color: #fff; flex: none; }
.saved-filter-chip.selected { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); color: var(--accent-dark); }
.saved-filter-chip.selected .chip-box { background: var(--accent); border-color: var(--accent); }
/* Manage-filters dialog: one wrapping flex row per saved filter (a table here
   forces horizontal scrolling in the dialog), sized like the camper modal. */
#manage-filters-dialog { width: min(560px, calc(100vw - 32px)); max-height: calc(100vh - 48px); overflow-y: auto; }
#manage-filters-dialog form { margin: 0; }
.manage-filter-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.manage-filter-row:last-of-type { border-bottom: 0; padding-bottom: 0; }
.saved-filter-rename { display: flex; gap: 6px; align-items: center; flex: 1 1 220px; }
.saved-filter-rename input { min-height: 0; padding: 8px 10px; }

/* Notes on the staff camper page */
.note-list { list-style: none; padding: 0; margin: 12px 0 0; display: grid; gap: 10px; }
.note-list li { border: 1px solid var(--line); border-radius: 9px; padding: 10px 12px; }
.badge.note-general { background: #eceef1; color: var(--muted); }
.badge.note-parent_message { background: #e7f0fe; color: #1a56db; }
.badge.note-behavior { background: #fff4e5; color: var(--warn); }
.badge.note-late_pickup { background: #fdecec; color: var(--danger); }
.badge.note-special_instructions { background: #e6f4ea; color: var(--ok); }

@media (max-width: 640px) {
  .stat-cards { grid-template-columns: repeat(auto-fit, minmax(104px, 1fr)); }
  .staff-filters select { min-width: 140px; }
  .mode-banner { flex-direction: column; align-items: flex-start; }
}
