/* Help Out Hub — single hand-written stylesheet, no build step.
   PTA branding is constrained to two CSS custom properties (--brand,
   --brand-2) injected by the base template; everything else stays fixed so
   customization can't break readability. */

:root {
  --brand: #3e5f8a;
  --brand-2: #e8a33d;
  --on-brand: #ffffff;
  --bg: #f5f6f8;
  --card: #ffffff;
  --text: #1c2733;
  --muted: #5b6b7c;
  --line: #e4e8ee;
  --danger: #b3362c;
  --ok: #1e7a46;
  --radius: 14px;
  --radius-small: 10px;
  --shadow: 0 1px 2px rgb(16 24 40 / 0.05), 0 1px 3px rgb(16 24 40 / 0.06);
  --focus-ring: 0 0 0 3px color-mix(in srgb, var(--brand) 35%, transparent);
}

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* Reserve the scrollbar's width whether or not it's needed. Filtering open
     needs down to one shift makes the page shorter than the window, and
     without this the scrollbar vanishes and the whole centred layout jumps
     sideways by its width. Invisible on overlay-scrollbar systems; very
     visible on Windows. */
  scrollbar-gutter: stable;
}

body {
  margin: 0;
  /* A whisper of the PTA's color warms the whole page without touching
     text contrast — all brand tints below stay at or under 8%. */
  background: color-mix(in srgb, var(--brand) 4%, #f7f8f9);
  color: var(--text);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 16px;
  line-height: 1.55;
  display: flex;
  min-height: 100vh;
  flex-direction: column;
}

.accent {
  height: 4px;
  background: linear-gradient(90deg, var(--brand), var(--brand-2));
}
/* Thicker on an organization's own pages, where the colour means something. */
body.has-pta .accent { height: 6px; }

.wrap {
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  padding: 0 20px;
}

.wrap-wide { max-width: 1060px; }
/* Between the reading column and the admin tables: wide enough that the
   landing page's three-across cards aren't a stack of two-word lines. */
.wrap-landing { max-width: 920px; }

main.wrap { flex: 1; padding-top: 8px; padding-bottom: 48px; }

/* --- Header / footer ---------------------------------------------------- */

/* The organization's colour, not a hint of it. Every tint is mixed into white
   and the text stays anchored to --text, so a PTA choosing an alarming colour
   changes the mood and never the contrast. */
.site-header {
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--brand) 13%, #ffffff),
    color-mix(in srgb, var(--brand) 7%, #ffffff)
  );
  border-bottom: 1px solid color-mix(in srgb, var(--brand) 26%, var(--line));
  margin-bottom: 24px;
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 60px;
  flex-wrap: wrap;
  padding-top: 8px;
  padding-bottom: 8px;
}

.pta-ident {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
  text-decoration: none;
  font-weight: 650;
  font-size: 1.05rem;
}

.pta-logo {
  width: 36px;
  height: 36px;
  object-fit: contain;
  border-radius: 8px;
}

.header-nav {
  display: flex;
  align-items: center;
  gap: 16px;
  font-size: 0.95rem;
}

.header-nav a { color: var(--muted); text-decoration: none; }
.header-nav a:hover { color: color-mix(in srgb, var(--brand) 30%, var(--text)); }

.site-footer {
  border-top: 1px solid color-mix(in srgb, var(--brand) 22%, var(--line));
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--brand) 6%, transparent),
    color-mix(in srgb, var(--brand-2) 7%, transparent)
  );
  padding: 20px 0 32px;
  color: var(--muted);
  font-size: 0.9rem;
}

.site-footer a { color: color-mix(in srgb, var(--brand) 25%, var(--text)); }

.footer-line { margin: 0 0 4px; }
.footer-line:last-child { margin-bottom: 0; }
.footer-admin { font-size: 0.85rem; opacity: 0.85; }

/* --- Typography / structure --------------------------------------------- */

h1 {
  font-size: clamp(1.45rem, 3.5vw, 1.85rem);
  line-height: 1.2;
  margin: 0 0 8px;
  color: color-mix(in srgb, var(--brand) 30%, var(--text));
}
h2 { font-size: 1.2rem; margin: 0 0 8px; color: color-mix(in srgb, var(--brand) 22%, var(--text)); }
h3 { font-size: 1.05rem; margin: 0; }

.page-head { margin: 8px 0 20px; }
.page-head .meta { margin: 2px 0; }

.page-head-actions {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.lede { color: var(--muted); font-size: 1.02rem; margin: 6px 0 0; }
.meta { color: var(--muted); margin: 4px 0; }


.day-heading {
  /* Reserve the badge's height whether or not there is one. A "soon" pill is
     taller than the heading's line box, so days that had one sat 3.5px lower
     than days that didn't, and the whole list below them shifted with it. */
  min-height: 1.8em;
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: color-mix(in srgb, var(--brand) 32%, var(--text));
  margin: 28px 0 10px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.section-label {
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: color-mix(in srgb, var(--brand) 32%, var(--text));
  margin: 20px 0 8px;
}

.footnote { color: var(--muted); font-size: 0.95rem; margin-top: 28px; text-align: center; }
.footnote a { color:color-mix(in srgb, var(--brand) 32%, var(--text)); }

/* --- Cards --------------------------------------------------------------- */

.card {
  background: var(--card);
  border: 1px solid color-mix(in srgb, var(--brand) 9%, var(--line));
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 18px 20px;
  margin-bottom: 14px;
}

.card-narrow { max-width: 460px; margin-left: auto; margin-right: auto; }

.card-link {
  display: block;
  color: inherit;
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.card-link:hover {
  border-color: color-mix(in srgb, var(--brand) 45%, var(--line));
}


/* The cards lose their own margin so the grid gap controls spacing between
   them — which means the grid has to carry the margin below, or whatever
   follows sits flush against it. */

.need-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.need-row .badge { flex-shrink: 0; }

/* --- Shift cards ---------------------------------------------------------- */

.shift-card.is-past { opacity: 0.65; }

.shift-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.shift-title { font-weight: 650; }
.shift-time { color: var(--muted); margin: 2px 0 0; font-variant-numeric: tabular-nums; }
.shift-notes { color: var(--muted); font-size: 0.95rem; margin: 10px 0 0; }

.meter {
  height: 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--brand) 12%, var(--bg));
  margin: 14px 0 10px;
  overflow: hidden;
}

.meter span {
  display: block;
  height: 100%;
  border-radius: inherit;
  /* Solid brand: gradients toward the secondary go muddy when a PTA picks
     complementary colors (blue→orange passes through gray). */
  background: var(--brand);
  min-width: 2px;
}

.fill-caption {
  color: var(--muted);
  font-size: 0.88rem;
  font-weight: 600;
  margin-right: 4px;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0 0 4px;
}

.chip {
  background: color-mix(in srgb, var(--brand) 10%, var(--card));
  border: 1px solid color-mix(in srgb, var(--brand) 22%, var(--card));
  color: color-mix(in srgb, var(--brand) 32%, var(--text));
  border-radius: 999px;
  padding: 3px 11px;
  font-size: 0.88rem;
  font-weight: 550;
}

.chips-empty { color: var(--muted); font-size: 0.9rem; }

/* --- Badges --------------------------------------------------------------- */

.badge {
  display: inline-block;
  border-radius: 999px;
  padding: 3px 11px;
  font-size: 0.82rem;
  font-weight: 650;
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--muted);
  white-space: nowrap;
}

.badge-open {
  background: color-mix(in srgb, var(--brand-2) 18%, var(--card));
  border-color: color-mix(in srgb, var(--brand-2) 40%, var(--card));
  color: color-mix(in srgb, var(--brand) 32%, var(--text));
}

.badge-full { background: #f1f2f4; color: var(--muted); }

.badge-confirmed {
  background: #e7f4ec;
  border-color: #c4e3d0;
  color: var(--ok);
}

.badge-cancelled { background: #faeceb; border-color: #f0cfcb; color: var(--danger); }

.badge-soon {
  background: color-mix(in srgb, var(--brand-2) 20%, var(--card));
  border-color: transparent;
  color: color-mix(in srgb, var(--brand) 32%, var(--text));
  text-transform: none;
  letter-spacing: 0;
}

/* --- Buttons -------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 44px;
  padding: 9px 18px;
  border-radius: var(--radius-small);
  border: 1px solid transparent;
  font: inherit;
  font-weight: 620;
  font-size: 0.97rem;
  text-decoration: none;
  cursor: pointer;
  transition: filter 0.12s ease, background 0.12s ease;
}

.btn-primary { background: var(--brand); color: var(--on-brand); }
.btn-primary:hover { filter: brightness(1.08); }

.btn-ghost {
  background: var(--card);
  border-color: color-mix(in srgb, var(--brand) 20%, var(--line));
  color: color-mix(in srgb, var(--brand) 32%, var(--text));
}
.btn-ghost:hover { border-color: color-mix(in srgb, var(--brand) 45%, var(--line)); }

.btn-danger { background: var(--card); border-color: #e5c0bc; color: var(--danger); }
.btn-danger:hover { background: #faeceb; }

.btn-block { width: 100%; }
.btn-small { min-height: 34px; padding: 4px 12px; font-size: 0.88rem; }

.btn-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 8px; }

.linklike {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--muted);
  cursor: pointer;
}
.linklike:hover { color: var(--text); }

.inline-form { display: inline; }

/* --- Forms ---------------------------------------------------------------- */

.field { margin: 0 0 14px; }

.field > label {
  display: block;
  font-weight: 620;
  font-size: 0.92rem;
  margin-bottom: 5px;
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="tel"],
input[type="number"],
input[type="date"],
input[type="time"],
input[type="url"],
textarea,
select {
  width: 100%;
  padding: 10px 12px;
  font: inherit;
  color: var(--text);
  background: var(--card);
  border: 1px solid #cfd6df;
  border-radius: var(--radius-small);
  min-height: 44px;
}

textarea { min-height: 0; resize: vertical; }

input[type="color"] {
  width: 100%;
  height: 44px;
  padding: 4px;
  border: 1px solid #cfd6df;
  border-radius: var(--radius-small);
  background: var(--card);
  cursor: pointer;
}

input:focus-visible,
textarea:focus-visible,
select:focus-visible,
.btn:focus-visible,
summary:focus-visible,
a:focus-visible,
button:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 12px;
}

.field-check label {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  font-weight: 500;
  font-size: 0.95rem;
  cursor: pointer;
}

.field-check input {
  width: 19px;
  height: 19px;
  margin-top: 2px;
  accent-color:color-mix(in srgb, var(--brand) 32%, var(--text));
  flex-shrink: 0;
}

.field-help { color: var(--muted); font-size: 0.88rem; margin: 6px 0 0; }

.also-box {
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
  padding: 10px 14px 12px;
  margin: 0 0 14px;
}

.also-box legend {
  /* Render as a normal block inside the box so long text wraps cleanly. */
  float: left;
  width: 100%;
  font-weight: 620;
  font-size: 0.92rem;
  padding: 0;
  margin: 2px 0 2px;
}

.also-box label {
  clear: both;
  display: flex;
  align-items: flex-start;
  gap: 9px;
  font-size: 0.93rem;
  margin: 8px 0;
  cursor: pointer;
}

.also-box input {
  width: 19px;
  height: 19px;
  margin-top: 1px;
  accent-color:color-mix(in srgb, var(--brand) 32%, var(--text));
  flex-shrink: 0;
}

.date-list {
  list-style: none;
  padding: 0;
  margin: 12px 0;
  columns: 2;
  column-gap: 24px;
}

.date-list li { margin: 8px 0; break-inside: avoid; }

.date-list label { display: flex; align-items: center; gap: 9px; cursor: pointer; }

.date-list input {
  width: 19px;
  height: 19px;
  accent-color:color-mix(in srgb, var(--brand) 32%, var(--text));
  flex-shrink: 0;
}

.plain-link { color: inherit; text-decoration: none; }
.plain-link:hover { text-decoration: underline; }

/* Site-wide "who am I" strip, shown whenever the session knows the visitor. */
.identity-bar {
  background: color-mix(in srgb, var(--brand) 10%, var(--card));
  border-bottom: 1px solid color-mix(in srgb, var(--brand) 18%, var(--line));
  margin: -24px 0 24px;
  font-size: 0.92rem;
}

.identity-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding-top: 8px;
  padding-bottom: 8px;
}

.identity-who { color: color-mix(in srgb, var(--brand) 32%, var(--text)); }

/* Organizer session, no volunteer identity. Distinct from the volunteer bar
   so "I'm holding admin rights" is never a surprise. */
.organizer-bar {
  background: color-mix(in srgb, var(--brand) 14%, var(--card));
  border-bottom-color: color-mix(in srgb, var(--brand) 30%, var(--line));
}

.organizer-bar .identity-who { color: color-mix(in srgb, var(--brand) 32%, var(--text)); }
.organizer-bar .linklike { color: color-mix(in srgb, var(--brand) 32%, var(--text)); }
.organizer-bar .linklike:hover { color: var(--text); }

/* PTA settings / Admins / Blocked emails as one area rather than three
   buttons competing with "New event" on the dashboard. */
.settings-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 18px;
  margin: 0 0 22px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
  font-size: 0.95rem;
}

.settings-nav a { color: var(--muted); text-decoration: none; }
.settings-nav a:hover { color: var(--text); }

.settings-nav a[aria-current="page"] {
  color: color-mix(in srgb, var(--brand) 32%, var(--text));
  font-weight: 650;
}

.settings-back { margin-right: auto; }

/* Read-only reports, kept apart from the buttons that change the event. */
.event-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}

/* Matches .coordinator-line below it: same size, same muted prose, same
   middot between actions. Export and roster still sit apart from Edit and
   Publish (both pull every volunteer's contact details, and both are
   audit-logged), but "apart" is now a separate line rather than a shouted
   label. */
.report-line { margin: 0; font-size: 0.88rem; color: var(--muted); }
.report-line a { color: color-mix(in srgb, var(--brand) 32%, var(--text)); }

/* Per-row removal: available, but never the loudest thing in the table. */
.row-remove { color: var(--muted); white-space: nowrap; }
.row-remove:hover { color: var(--danger); }

.coordinator-line { margin: 0; font-size: 0.88rem; color: var(--muted); }
.coordinator-line a { color: var(--muted); }

@media (max-width: 560px) {
  .event-actions { align-items: stretch; }
  .settings-back { margin-right: 0; width: 100%; }
  /* Keep the sign-out control beside the identity instead of letting it wrap
     onto a third line, which pushed the page content well below the fold. */
  .identity-inner { flex-wrap: nowrap; gap: 12px; }
  .identity-who { min-width: 0; font-size: 0.86rem; }
  .identity-inner .inline-form { flex-shrink: 0; }
}

/* Logged in as an organizer *and* remembered as a volunteer: warn, because
   acting as the wrong person is the mistake this state invites. */
.identity-bar-dual {
  background: #fffbf0;
  border-bottom-color: #e6c98a;
}

.identity-bar-dual .identity-who { color: #8a5a00; }

.known-signup { margin-top: 14px; }

.other-email { margin-top: 18px; }

.other-email summary {
  cursor: pointer;
  color: var(--muted);
  font-size: 0.92rem;
}

.known-joined {
  margin: 14px 0 0;
  font-weight: 620;
  font-size: 0.93rem;
  color: var(--ok);
}

.known-joined a { color: var(--muted); font-weight: 500; margin-left: 4px; }

/* A shift the signed-in volunteer is already on is marked by its badge
   alone — no card accent needed. */

.badge-yours {
  background: #e7f4ec;
  border-color: #c4e3d0;
  color: var(--ok);
}

.badge-stack {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: flex-end;
}

.chip-you {
  background: color-mix(in srgb, var(--brand) 22%, var(--card));
  border-color: color-mix(in srgb, var(--brand) 45%, var(--card));
  font-weight: 700;
}

/* When a name is already known, the full form is a secondary escape hatch. */
.signup-box summary .linklike {
  font-size: 0.9rem;
  color: var(--muted);
  text-decoration: underline;
}

/* Development-only link surfacing (see templates/_dev_link.html). */
.dev-link {
  margin-top: 18px;
  padding: 14px 16px;
  border: 1px dashed #b7791f;
  border-radius: var(--radius-small);
  background: #fffbf0;
  font-size: 0.92rem;
}

.dev-link p { margin: 0 0 8px; }
.dev-link p:last-child { margin-bottom: 0; }

.dev-link-label {
  font-weight: 700;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #b7791f;
}

.dev-link input { font-size: 0.82rem; }

.dev-inline-link { font-size: 0.8rem; color: #b7791f; }

.event-tag {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  color: var(--muted);
  font-size: 0.88rem;
  font-weight: 620;
  margin: 0 0 10px;
}

.emoji-picks {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: -6px 0 14px;
}

.emoji-pick {
  font-size: 1.15rem;
  line-height: 1;
  padding: 7px 9px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
  cursor: pointer;
}

.emoji-pick:hover { border-color: color-mix(in srgb, var(--brand) 45%, var(--line)); }

/* Collapsed, informational list of full shifts on the open-needs page. */
.field-error { color: var(--danger); font-size: 0.88rem; font-weight: 550; margin: 5px 0 0; }

.has-error input, .has-error textarea { border-color: var(--danger); }

/* --- Signup details/summary ----------------------------------------------- */

.signup-box { margin-top: 14px; }

.signup-box summary {
  list-style: none;
  cursor: pointer;
  display: inline-block;
}

.signup-box summary::-webkit-details-marker { display: none; }

.signup-box summary .btn { pointer-events: none; }

.signup-box[open] summary { display: none; }

.signup-form {
  border-top: 1px solid var(--line);
  margin-top: 4px;
  padding-top: 16px;
}

.danger-box { margin-top: 18px; }

.danger-box summary {
  color: var(--muted);
  font-size: 0.93rem;
  cursor: pointer;
}

.danger-box p { color: var(--muted); font-size: 0.93rem; }

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

.plain-list { color: var(--muted); font-size: 0.92rem; padding-left: 20px; margin: 8px 0 0; }

/* --- Messages -------------------------------------------------------------- */


/* Anchored to the viewport, not the document: a confirmation you scrolled
   past is a confirmation nobody read. */
.messages {
  position: fixed;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  z-index: 60;
  width: min(560px, calc(100vw - 24px));
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}
.messages .msg { pointer-events: auto; box-shadow: 0 6px 22px rgba(16, 24, 40, 0.18); }
.messages .msg.is-leaving { opacity: 0; transform: translateY(8px); }
.msg-text { flex: 1 1 auto; }
.msg-close {
  flex: 0 0 auto;
  background: none;
  border: 0;
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
  color: inherit;
  opacity: 0.55;
  padding: 0 2px;
}
.msg-close:hover { opacity: 1; }

.msg {
  transition: opacity 0.25s ease, transform 0.25s ease;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  border-radius: var(--radius-small);
  padding: 12px 16px;
  margin-bottom: 8px;
  font-size: 0.96rem;
  border: 1px solid var(--line);
  background: var(--card);
}

.msg-success { background: #e7f4ec; border-color: #c4e3d0; color: #14532d; }
.msg-info { background: color-mix(in srgb, var(--brand) 8%, var(--card)); border-color: color-mix(in srgb, var(--brand) 25%, var(--card)); }
.msg-error { background: #faeceb; border-color: #f0cfcb; color: #7f1d1d; }

/* --- Confirmation banner ---------------------------------------------------- */

.confirm-banner { text-align: center; padding: 12px 0 20px; }

.confirm-check {
  width: 56px;
  height: 56px;
  margin: 0 auto 12px;
  border-radius: 50%;
  background: #e7f4ec;
  color: var(--ok);
  font-size: 1.7rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

.confirm-banner p { color: var(--muted); margin: 4px 0 0; }

/* --- Admin tables ----------------------------------------------------------- */

.table-scroll { overflow-x: auto; margin-top: 12px; }

table { border-collapse: collapse; width: 100%; font-size: 0.93rem; }

th {
  text-align: left;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: color-mix(in srgb, var(--brand) 32%, var(--text));
  font-weight: 650;
  padding: 8px 12px 6px 0;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

td { padding: 9px 12px 9px 0; border-bottom: 1px solid var(--line); vertical-align: top; }

tr:last-child td { border-bottom: none; }

td a { color:color-mix(in srgb, var(--brand) 32%, var(--text)); }

.share-card { background: color-mix(in srgb, var(--brand) 4%, var(--card)); }

.copy-row { display: flex; gap: 8px; }

/* min-width:0 lets the URL field actually shrink inside the flex row, and
   width:auto opts the button out of the full-width mobile button rule. */
.copy-row input { flex: 1 1 auto; min-width: 0; font-size: 0.9rem; color: var(--muted); }
.copy-row .btn { flex: 0 0 auto; width: auto; }

.share-row { margin-top: 10px; }

.notify-box {
  border: 1px solid color-mix(in srgb, var(--brand) 20%, var(--line));
  border-radius: var(--radius-small);
  padding: 12px 14px;
  margin: 0 0 16px;
  background: color-mix(in srgb, var(--brand) 4%, var(--card));
}


.locked-value {
  margin: 0;
  padding: 10px 12px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-small);
  background: var(--bg);
  color: var(--muted);
}

.reminder-note {
  background: color-mix(in srgb, var(--brand) 5%, var(--card));
  border-radius: var(--radius-small);
  padding: 9px 12px;
  margin-top: 12px;
}

/* --- Roster / print --------------------------------------------------------- */

.roster h2 { margin-top: 24px; font-size: 1.05rem; }

.checkbox-square {
  display: inline-block;
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--muted);
  border-radius: 4px;
}

.col-check { width: 52px; }

@media print {
  .site-header, .site-footer, .accent, .no-print, .messages { display: none !important; }
  body { background: #fff; }
  main.wrap { max-width: none; padding: 0; }
  .card { box-shadow: none; }
  a { color: inherit; text-decoration: none; }
}

/* --- Small screens ----------------------------------------------------------- */

@media (max-width: 560px) {
  .field-row { grid-template-columns: 1fr; }
  .date-list { columns: 1; }
    .page-head-actions { flex-direction: column; align-items: stretch; }
  .page-head-actions .btn-row { justify-content: flex-start; }
  .need-row { flex-wrap: wrap; }
  .btn { width: 100%; }
  .btn-row .btn, .btn-small { width: auto; }
  .signup-box summary { display: block; }
  .signup-box summary .btn { width: 100%; }
}

/* --- Help page ---------------------------------------------------------- */
/* Collapsed by default so the page is a list of questions, not an essay. */
.help-item {
  border-top: 1px solid var(--line);
  padding: 0;
}
.help-item > summary {
  cursor: pointer;
  padding: 0.85rem 0.25rem;
  font-weight: 600;
  color: var(--text);
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
}
.help-item > summary::-webkit-details-marker { display: none; }
.help-item > summary::before {
  content: "+";
  color:color-mix(in srgb, var(--brand) 32%, var(--text));
  font-weight: 700;
  width: 0.8em;
  flex: 0 0 auto;
}
.help-item[open] > summary::before { content: "–"; }
.help-item > summary:hover { color:color-mix(in srgb, var(--brand) 32%, var(--text)); }
.help-item > p {
  margin: 0 0 0.75rem 1.4rem;
  color: var(--muted);
}
.help-item[open] > summary { color:color-mix(in srgb, var(--brand) 32%, var(--text)); }
.help-footer { margin-top: 1.5rem; }
.tight-list { margin: 0.5rem 0 0.75rem 1.2rem; padding: 0; }
.tight-list li { margin-bottom: 0.35rem; }

/* --- Landing pages ------------------------------------------------------ */

/* Product landing. Wider and more open than an in-app page: this is the one
   screen that has to explain what the thing is before anyone trusts it. */
.landing-hero {
  position: relative;
  overflow: hidden;
  text-align: center;
  padding: 58px 20px 50px;
  margin-bottom: 26px;
  background: linear-gradient(
    150deg,
    color-mix(in srgb, var(--brand) 12%, #ffffff),
    color-mix(in srgb, var(--brand-2) 10%, #ffffff) 70%
  );
  border: 1px solid color-mix(in srgb, var(--brand) 14%, var(--line));
  border-radius: var(--radius);
}
/* A soft bloom behind the name. Purely atmospheric, so it sits under the
   content and never intercepts a click. */
.landing-hero::before {
  content: "";
  position: absolute;
  top: -180px;
  left: 50%;
  width: 620px;
  height: 420px;
  transform: translateX(-50%);
  background: radial-gradient(
    ellipse at center,
    color-mix(in srgb, var(--brand) 20%, transparent),
    transparent 68%
  );
  pointer-events: none;
}
.hero-inner { position: relative; }
/* Smaller than the wordmark above it: the name identifies, the headline
   explains, and only one of the two can be the largest thing on screen. */
.landing-hero h1 {
  font-size: clamp(1.4rem, 3.4vw, 1.95rem);
  line-height: 1.2;
  font-weight: 650;
  margin: 0 auto;
  max-width: 30ch;
  color: color-mix(in srgb, var(--text) 88%, var(--brand));
}
.landing-hero .lede {
  max-width: 46ch;
  margin: 14px auto 0;
  font-size: 1.06rem;
  color: var(--muted);
}

/* Beta notice. A pill rather than a banner: it should read as a status, not
   as an error the visitor has to resolve. */
.beta-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 20px;
  padding: 6px 14px 6px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--brand-2) 22%, #ffffff);
  border: 1px solid color-mix(in srgb, var(--brand-2) 45%, var(--line));
  font-size: 0.86rem;
  font-weight: 600;
  color: color-mix(in srgb, var(--brand) 30%, var(--text));
}
.beta-pill .beta-tag {
  background: var(--brand);
  color: var(--on-brand);
  border-radius: 999px;
  padding: 2px 9px;
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.landing-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  margin-bottom: 26px;
  counter-reset: step;
}
.landing-steps .step {
  padding: 20px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.landing-steps .step h3 {
  margin: 0 0 6px;
  font-size: 1.02rem;
  display: flex;
  align-items: center;
  gap: 10px;
}
.landing-steps .step h3::before {
  counter-increment: step;
  content: counter(step);
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--brand) 14%, #ffffff);
  color:color-mix(in srgb, var(--brand) 32%, var(--text));
  font-size: 0.85rem;
  display: grid;
  place-items: center;
}
.landing-steps .step p { color: var(--muted); margin: 0; font-size: 0.95rem; }




@media (max-width: 700px) {
  /* Three across is the whole point of this row on a laptop and unreadable on
     a phone. Losing this line left "How it works" as three ~110px columns
     running off the side of the screen. */
  .landing-steps { grid-template-columns: 1fr; }
  .landing-hero { padding: 34px 16px 30px; }
}

/* Wordmark: a mark plus the name, set apart from the headline so the name
   registers before the pitch does. Sized in em throughout, so one font-size on
   an ancestor scales the whole lockup. */
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.34em;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1;
  font-size: clamp(1.5rem, 3vw, 2rem);
  color: var(--text);
}
/* Sized against the capitals of the name beside it, not the em box. Measured
   cap height in the system stack is 0.70em, and a filled tile needs a little
   more than that to carry the same visual weight as a letterform, so 0.84em
   lands it ~1.2x cap. At the original 1.08em it was 1.4x and the tile read as
   the subject with the name attached to it. */
.wordmark-mark {
  flex: 0 0 auto;
  width: 0.84em;
  height: 0.84em;
  border-radius: 28%;
  /* Monochrome, for the reason .meter gives: a gradient running to the
     secondary passes through mud whenever the two are complementary, which
     the default navy/amber pair is. Light-to-full brand keeps the dimension
     and can't go olive whatever colours a group picks. */
  background: linear-gradient(
    145deg,
    color-mix(in srgb, var(--brand) 78%, #ffffff),
    var(--brand) 62%
  );
  color: var(--on-brand);
  display: grid;
  place-items: center;
  /* A hairline of the brand at its own edge keeps the tile from dissolving
     into a pale hero panel, and the inset highlight gives it a light source
     instead of a flat fill. */
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.28),
    0 1px 1px color-mix(in srgb, var(--brand) 22%, transparent),
    0 3px 10px color-mix(in srgb, var(--brand) 22%, transparent);
}
.wordmark-mark svg {
  width: 62%;
  height: 62%;
  display: block;
  /* The tick is optically low in its own box; nudge it onto the centre. */
  transform: translateY(-2%);
}
/* Aligned on the capitals, not the line box, so the mark doesn't ride high
   over a name with no descenders. */
.wordmark { align-items: baseline; }
.wordmark-mark { align-self: center; }
.wordmark-text { padding-bottom: 0.02em; }

.hero-wordmark, .about-wordmark { margin: 0 0 14px; }
/* Display sizes want tighter tracking than body sizes: the same -0.03em that
   reads as tidy at 17px reads as loose at 50px. */
.hero-wordmark .wordmark {
  font-size: clamp(1.7rem, 5.5vw, 3.15rem);
  letter-spacing: -0.038em;
}
.hero-wordmark .wordmark-mark {
  box-shadow:
    inset 0 1.5px 0 rgb(255 255 255 / 0.3),
    0 2px 3px color-mix(in srgb, var(--brand) 20%, transparent),
    0 8px 22px color-mix(in srgb, var(--brand) 26%, transparent);
}
/* In the header it's an identifier, not a banner, so it drops back to the
   size the PTA's own name uses on every other page. */
.pta-ident .wordmark { font-size: 1.05rem; letter-spacing: -0.01em; }
.pta-ident .wordmark-mark { box-shadow: none; }

.hero-actions {
  margin: 26px 0 0;
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
}
.btn-lg { padding: 12px 26px; font-size: 1.02rem; }
.landing-footnote { text-align: center; color: var(--muted); margin: 26px 0 8px; }

.about-head { text-align: center; margin-bottom: 22px; }
.about-head h1 { margin: 0 0 6px; }
.about-head .lede { max-width: 46ch; margin-left: auto; margin-right: auto; }
.beta-card { border-color: color-mix(in srgb, var(--brand-2) 40%, var(--line)); }
.beta-card .beta-pill { margin-bottom: 12px; }
.beta-card p { margin: 0 0 8px; }

/* --- Event filter and colour coding ------------------------------------- */
/* A weekly event fills the open-needs list, so each event carries a stable
   colour and the list can be narrowed to one of them. */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 16px;
}
.filter-chip {
  --event-accent: var(--brand);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 13px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--event-accent) 35%, var(--line));
  background: var(--card);
  color: var(--text);
  text-decoration: none;
  font-size: 0.92rem;
  font-weight: 600;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.filter-chip:hover { border-color: var(--event-accent); }
.filter-chip.is-active {
  background: var(--event-accent);
  border-color: var(--event-accent);
  color: #ffffff;
}
.filter-count {
  font-size: 0.8rem;
  font-weight: 700;
  padding: 1px 7px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--event-accent) 14%, #ffffff);
  color: color-mix(in srgb, var(--event-accent) 80%, #000000);
}
.filter-chip.is-active .filter-count {
  background: rgba(255, 255, 255, 0.25);
  color: #ffffff;
}

/* Unmissable, because a filtered list that looks unfiltered is how someone
   concludes their PTA has nothing on. */
/* The badge alone carries the event's identity. A coloured edge on the card
   competed with the card itself for attention and made a mixed list look
   striped; a solid pill reads faster and stays contained. */
.event-badge {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--event-accent);
  font-weight: 700;
  font-size: 0.86rem;
  letter-spacing: 0.01em;
  text-decoration: none;
}
.event-badge:hover { filter: brightness(1.12); }
.event-where { color: var(--muted); font-size: 0.88rem; }

/* Past dates on an event page: chronologically first, visually last. */
/* Grey-on-grey made this invisible: a dashed --line border and an 18% --line
   fill sitting on a page background that is itself a pale tint. Measured, the
   panel and the page were 1.02:1 apart, so the one thing on the page you have
   to notice and click was the hardest object on it to see.

   Shut, it is now a white card with a solid edge, exactly like details.card
   .explainer elsewhere in the manage screens: white on the tinted page is how
   every other panel here separates itself, and reusing that is both more
   visible and more consistent than inventing a third treatment.

   Open, it flips to a faint tint, because the job changes. Shut it has to
   stand out from the page; open it is a container, and the white cards inside
   it need something to sit on. */
/* The control is the summary row, not the container.

   Two earlier attempts both failed on the same thing. Grey-on-grey was
   invisible (the panel and the page measured 1.02:1). Making the box a white
   card fixed that but left it changing colour on click, because a white
   container can't hold white cards: the fill was doing two incompatible jobs
   at once.

   So the box carries no fill in either state, and the summary is styled as
   the button it actually is. Nothing changes colour when you open it; the
   cards below simply appear, on the same page background they'd have
   anywhere else. */
/* "Earlier" and "Upcoming" are one pair of section labels, and they finally
   look like it.

   Three attempts got this wrong in the same way: treating the container as
   the thing to style. Faint grey on a tinted page measured 1.02:1 and was
   invisible. A white card fixed the contrast but had to change colour on open,
   because a white container can't hold white cards. And at full width with a
   card's border and shadow it read as an *empty card* with two words in it,
   sitting directly above its own partner, which was plain 1rem text.

   There is no panel now. Both labels are the same size, weight and colour;
   the only difference is that one has a chevron and toggles. The colour does
   the work the fill was failing at, and it is text colour, which is the one
   thing on the page that was never hard to see. */
.past-box {
  margin: 0;
  border: 0;
  padding: 0;
  background: none;
}
.past-box > summary,
.list-heading {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 24px 0 12px;
  /* A step above the day headings they contain, which are 1rem uppercase.
     At the same size the nesting read backwards. */
  font-size: 1.08rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  list-style: none;
}

/* Here is the colour that was missing. The two labels were identical apart
   from a chevron, which is what made the whole region read as flat: one is
   the list you came to work on and the other is an archive, and nothing said
   so. Live gets the PTA's colour, finished gets grey. */
.list-heading { color: color-mix(in srgb, var(--brand) 32%, var(--text)); }
.past-box > summary { color: var(--muted); }
.past-box > summary .list-count {
  background: color-mix(in srgb, var(--line) 55%, #ffffff);
  color: var(--muted);
}
.past-box > summary:hover,
.past-box[open] > summary {
  color: color-mix(in srgb, var(--brand) 32%, var(--text));
}
.past-box > summary {
  cursor: pointer;
  user-select: none;
}
.past-box > summary::-webkit-details-marker { display: none; }

/* Drawn from two borders rather than the "▸" character, which rendered as a
   handful of grey pixels at any size and was the one mark saying "this
   opens". */
.past-box > summary::before {
  content: "";
  flex: 0 0 auto;
  width: 0.46em;
  height: 0.46em;
  border-right: 2.5px solid currentColor;
  border-bottom: 2.5px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
}
.past-box[open] > summary::before {
  transform: rotate(45deg) translate(-0.1em, -0.1em);
}
.past-box > summary:hover .past-summary-label { text-decoration: underline; }
.past-box > summary:focus-visible {
  outline: none;
  border-radius: var(--radius-small);
  box-shadow: var(--focus-ring);
}

.list-count {
  font-size: 0.78rem;
  font-weight: 700;
  padding: 1px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--brand) 14%, #ffffff);
  color: color-mix(in srgb, var(--brand) 32%, var(--text));
}


.past-box > .field-help { margin-top: -4px; }

/* Same cards as the upcoming list, drained of colour so the eye skips them. */
.past-box .shift-card {
  filter: grayscale(1);
  opacity: 0.7;
  box-shadow: none;
}
.past-box .shift-card:hover { opacity: 0.9; }
.day-heading-past { color: var(--muted); margin-top: 16px; }

/* The number of shifts about to be created, stated before the list of them. */
.repeat-count {
  margin: 12px 0;
  padding: 12px 14px;
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--brand) 8%, #ffffff);
  border: 1px solid color-mix(in srgb, var(--brand) 22%, var(--line));
}
.repeat-count-large {
  background: color-mix(in srgb, var(--brand-2) 16%, #ffffff);
  border-color: color-mix(in srgb, var(--brand-2) 45%, var(--line));
}

/* --- Finished shifts on the manage page --------------------------------- */
/*
   Same .past-box as the volunteer-facing event page, so both sides of the app
   put earlier dates in the same place and open them the same way. What differs
   is what survives inside it.

   On the volunteer page the cards are drained to grayscale: nobody can act on
   a past date, so the eye should slide off. An organizer's can't do that. The
   roster inside a finished shift is the record of who turned up, and that is
   most of what brings them back to this page, so the table stays at full
   contrast and only the chrome recedes.
*/
/* White, like every other card in the app.
   
   Tinting these to look "recessed" put them at #f0f2f6 on a page background
   of #edf2f9: three values apart, which is no card at all. It is the same
   error the container went through twice. On a page that is itself a tint,
   white is the only thing that reads as a card, and anything mixed toward the
   background disappears into it.

   Past-ness is carried by things that cost no visibility: a dashed border,
   no shadow so they sit flatter than the upcoming ones, a muted title, a grey
   fill count, a PAST badge, and the grey "Earlier" label above them. */
.past-box .card-past {
  background: var(--card);
  border-style: dashed;
  border-color: color-mix(in srgb, var(--brand) 22%, var(--line));
  box-shadow: none;
}

/* The title, not the roster. Muting the table would defeat the point of
   keeping these open at all. */
.card-past .shift-title { color: var(--muted); font-weight: 600; }

/* Sits inline after the title, so it can't inherit the title's line-height
   without riding high. Redundant with "Earlier dates" while the box is shut,
   but a scrolled-open box of forty cards loses its own summary off the top. */
.badge-past {
  margin-left: 8px;
  vertical-align: middle;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Editing a finished shift is legitimate (fixing a typo in the record), but
   it isn't what the page is for. Deliberately not `opacity`, which was the
   first attempt: .btn-ghost's text is color-mix(--brand 32%, --text) and a
   pale brand already lands near 4.7:1, so fading it failed AA. */
.card-past .btn-ghost { border-color: var(--line); }

/* Bulk shift removal */
.bulk-select-row { margin-bottom: 12px; }
.bulk-table td, .bulk-table th { vertical-align: middle; }
.bulk-table .row-past { color: var(--muted); }
.bulk-table label { cursor: pointer; }
#bulk-delete-submit[disabled] { opacity: 0.5; cursor: not-allowed; }

/* Sits directly under a day-heading, so it needs to pull up against it. */
.section-intro { margin: -4px 0 12px; }

/* --- Organizer guidance ------------------------------------------------- */
/* Explaining what a shift is, with examples. Deliberately quieter than the
   form it sits above: it's a reference, and the form is the task. */
.explainer { border-color: color-mix(in srgb, var(--brand) 12%, var(--line)); }
.explainer > summary {
  cursor: pointer;
  font-weight: 600;
  color:color-mix(in srgb, var(--brand) 32%, var(--text));
}
.explainer > summary::marker { color: var(--muted); }
.explainer[open] > summary { margin-bottom: 12px; }
.explainer-lead { margin: 0 0 14px; }

.example-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.example {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  padding: 14px 16px;
}
.example-label {
  margin: 0 0 2px;
  font-weight: 700;
  font-size: 0.95rem;
}
.example-event { margin: 0 0 10px; color: var(--muted); font-size: 0.9rem; }

/* Reads as a sample of the real thing, so it borrows the shift list's shape:
   the job in bold, the when-and-how-many underneath. */
.example-list { list-style: none; margin: 0 0 10px; padding: 0; }
.example-list li {
  padding: 7px 0;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.example-list li:last-child { border-bottom: 1px solid var(--line); }
.example-list strong { font-size: 0.94rem; }
.example-list span { color: var(--muted); font-size: 0.86rem; }
.example-note { margin: 0; color: var(--muted); font-size: 0.88rem; }

/* The field that quietly creates thirty shifts, so it gets a box of its own. */
.repeat-box {
  border: 1px dashed color-mix(in srgb, var(--brand) 35%, var(--line));
  border-radius: var(--radius);
  padding: 14px 16px 2px;
  margin-bottom: 18px;
  background: color-mix(in srgb, var(--brand) 4%, transparent);
}
.repeat-box-title { margin: 0 0 4px; font-weight: 700; }
.repeat-box .field { margin-bottom: 10px; }

.empty-shifts h3 { margin: 0 0 6px; }
.empty-shifts .tight-list { margin: 12px 0 16px; padding-left: 1.15rem; }
.empty-shifts .btn-row { margin: 0; }

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

/* --- My shifts ----------------------------------------------------------- */
/* Two panels side by side: where you stand, and the settings behind it.
   Everything account-shaped lives in the second one, so the shift list below
   stays purely about shifts. */
.dash-top {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 14px;
  margin-bottom: 14px;
}
.dash-top .card { margin-bottom: 0; }

.summary-label {
  margin: 0 0 6px;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 700;
  color: color-mix(in srgb, var(--brand) 32%, var(--text));
}

/* The one line someone opens this page to read. */
.summary-next {
  margin: 0;
  font-size: 1.22rem;
  line-height: 1.25;
}
.summary-next strong { color: color-mix(in srgb, var(--brand) 32%, var(--text)); }
.summary-empty { color: var(--muted); font-weight: 600; }
.summary-what { margin: 4px 0 0; color: var(--muted); font-size: 0.95rem; }
/* Both panels are flex columns with their action pinned to the bottom, so the
   two cards line up along their last row however tall the other one grows. */
.dash-summary { display: flex; flex-direction: column; }
.summary-todo { margin: 14px 0 0; padding-top: 4px; }
.dash-summary .summary-todo { margin-top: auto; }
.summary-clear { color: var(--muted); font-size: 0.92rem; }

.dash-account { display: flex; flex-direction: column; }
.account-email {
  margin: 0;
  font-weight: 600;
  overflow-wrap: anywhere;
}
.dash-account .reminder-note { font-size: 0.88rem; }
.dash-account .btn-row { margin: auto 0 0; padding-top: 14px; }

/* Dates inside "Your shifts". Quieter than .day-heading, which now labels the
   section itself, so the two don't compete. */
.date-heading {
  min-height: 1.9em;   /* same reason as .day-heading */
  font-size: 0.95rem;
  font-weight: 650;
  color: var(--muted);
  margin: 18px 0 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}

@media (max-width: 700px) {
  .dash-top { grid-template-columns: 1fr; }
}

/* --- Landing pages, shared components ------------------------------------ */
/* The product page and each organization's page are built from the same
   pieces: hero panel, "How it works" steps, closing note. Only the contents
   differ, so the two feel like one site. */

/* The organization's identity in its hero, mirroring .wordmark on the product
   page: a mark, then the name, at the same weight and scale. */
/* Block, not inline-flex: the logo moved out to its own line above, so this
   holds only the name now, and the rule beneath it needs a line of its own. */
.hero-ident {
  display: block;
  margin: 0 0 14px;
  font-size: clamp(1.5rem, 4vw, 2.3rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
  color: var(--text);
}
/* A school's logo is whatever shape it is: a square crest, a wide banner, a
   portrait photo of the building. Fixing the height and letting the width
   follow suits all three; forcing a square letterboxed the tall ones inside
   white bars. No backdrop or rounded corner for the same reason, since both
   assume a shape the logo may not have. */
.hero-logo-wrap { margin: 0 0 16px; }
.ident-logo {
  height: clamp(78px, 13vw, 116px);
  width: auto;
  max-width: 62%;
  object-fit: contain;
  /* Lifts a logo off the tinted panel without boxing it in. */
  filter: drop-shadow(0 3px 10px color-mix(in srgb, var(--brand) 30%, transparent));
}
.ident-name { text-wrap: balance; }


.steps-label {
  text-align: center;
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 700;
  color: color-mix(in srgb, var(--brand) 32%, var(--text));
  margin: 0 0 12px;
}

.landing-steps .step:hover {
  border-color: color-mix(in srgb, var(--brand) 28%, var(--line));
  box-shadow: 0 3px 14px color-mix(in srgb, var(--brand) 12%, transparent);
}

/* Closing call to action. Same panel treatment as the hero so the page opens
   and closes on the same note, minus the bloom, which would compete. */
.landing-band {
  text-align: center;
  padding: 40px 20px 36px;
  margin-bottom: 8px;
  background: linear-gradient(
    150deg,
    color-mix(in srgb, var(--brand) 10%, #ffffff),
    color-mix(in srgb, var(--brand-2) 9%, #ffffff) 70%
  );
  border: 1px solid color-mix(in srgb, var(--brand) 14%, var(--line));
  border-radius: var(--radius);
}
.landing-band h2 {
  font-size: clamp(1.3rem, 3vw, 1.75rem);
  margin: 0 auto;
  max-width: 22ch;
}
.landing-band .lede { max-width: 44ch; margin: 10px auto 0; }
.band-note {
  max-width: 50ch;
  margin: 20px auto 0;
  color: var(--muted);
  font-size: 0.92rem;
}

@media (max-width: 700px) {
  .landing-band { padding: 30px 16px 28px; }
}

/* Fully-covered shifts borrow the earlier-dates treatment wholesale: same
   dashed container, same drained cards. They differ only in why they're
   quiet — nothing to do here, rather than already over. */
.covered-box { margin-top: 28px; }

/* Except for a shift you're actually on. The manage link is the one live
   control in a greyed block, and greying it makes it read as disabled. */
.past-box .shift-card:has(.known-joined) {
  filter: none;
  opacity: 1;
}

/* Offered when we deliberately didn't guess whose signup this was. Quiet: it
   is a question, and the answer only matters to the rare person it's asked of. */
.remember-prompt {
  border-style: dashed;
  border-color: color-mix(in srgb, var(--brand) 25%, var(--line));
  background: color-mix(in srgb, var(--brand) 3%, var(--card));
  box-shadow: none;
}
.remember-prompt p { margin: 0 0 10px; }
.remember-prompt .field-help { margin: 10px 0 0; }

/* --- Organizer guides ---------------------------------------------------- */
/* A worked example: the event's name, then its shifts laid out the way they'd
   really appear. Shares .example-list with the add-shift explainer so a
   sample of a shift looks the same wherever one is shown. */
.worked-example {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  padding: 14px 16px;
  margin: 0 0 14px;
}
.worked-title {
  margin: 0 0 10px;
  font-weight: 700;
  font-size: 1.02rem;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
}
.worked-tag {
  font-size: 0.76rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: color-mix(in srgb, var(--brand) 32%, var(--text));
  background: color-mix(in srgb, var(--brand) 9%, var(--card));
  border-radius: 999px;
  padding: 2px 10px;
}
.example-more { color: var(--muted); font-style: italic; }
.worked-example .example-note { margin-top: 8px; }
.worked-example .example-note + .example-note { margin-top: 6px; }

/* The two words the whole app rests on, side by side so the distinction is
   the first thing you see rather than something you infer from prose. */
.definition-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin: 14px 0;
}
.definition {
  border: 1px solid var(--line);
  border-left: 3px solid color-mix(in srgb, var(--brand) 45%, var(--line));
  border-radius: var(--radius-small);
  padding: 12px 14px;
  background: color-mix(in srgb, var(--brand) 3%, var(--card));
}
.definition-word {
  margin: 0 0 4px;
  font-weight: 700;
  color: color-mix(in srgb, var(--brand) 32%, var(--text));
}
.definition p:last-child { margin: 0; font-size: 0.95rem; }

.guide-link { margin: 16px 0 22px; }
.guide-link-title {
  margin: 0 0 4px;
  font-weight: 700;
  color:color-mix(in srgb, var(--brand) 32%, var(--text));
}
.guide-link p:last-child { margin: 0; color: var(--muted); font-size: 0.95rem; }

@media (max-width: 700px) {
  .definition-pair { grid-template-columns: 1fr; }
}

/* The "so how do I sign up as myself" answer, next to the button that does it. */
.identity-hint {
  display: block;
  font-weight: 400;
  font-size: 0.86rem;
  opacity: 0.85;
}

/* --- Contextual help ----------------------------------------------------- */
/* Every major landing point ends with the questions that page raises. One
   look everywhere, so it reads as a standing feature rather than something
   bolted onto a particular page. Tinted with the organization's colour, since
   it sits on their pages. */
.page-help {
  margin: 34px 0 8px;
  padding: 18px 20px 6px;
  border: 1px solid color-mix(in srgb, var(--brand) 12%, var(--line));
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: var(--shadow);
}
.page-help-title {
  margin: 0 0 10px;
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 700;
  color: color-mix(in srgb, var(--brand) 30%, var(--text));
}
.page-help .help-item:last-of-type { border-bottom: none; }
.page-help-more { margin: 12px 0 12px; }

/* A link at the top of a page to the help at the foot of it. Reference
   material belongs at the bottom; being findable from the top is what stops
   it being reference material nobody reaches. */
.help-jump { white-space: nowrap; }
.page-head .help-jump { margin-left: 4px; }
.help-jump a { color: color-mix(in srgb, var(--brand) 32%, var(--text)); }
.landing-hero .help-jump, .hero-inner .help-jump { margin-top: 16px; }

/* The filter's state in words, always present so switching never moves the
   list. Four coloured chips alone left people unsure a filter was even on. */
.filter-panel {
  margin: 0 0 18px;
  padding: 12px 14px 10px;
  border-radius: var(--radius);
  border: 1px solid color-mix(in srgb, var(--brand) 12%, var(--line));
  background: color-mix(in srgb, var(--brand) 4%, var(--card));
}
.filter-panel .filter-bar { margin: 0; }
.filter-status {
  margin: 10px 2px 0;
  color: var(--muted);
  font-size: 0.9rem;
}
.filter-status strong { color: var(--text); }
.filter-status a { margin-left: 6px; }

/* --- Organization landing, themed ---------------------------------------- */
.has-pta .landing-hero {
  background: linear-gradient(
    155deg,
    color-mix(in srgb, var(--brand) 26%, #ffffff),
    color-mix(in srgb, var(--brand-2) 20%, #ffffff) 72%
  );
  border-color: color-mix(in srgb, var(--brand) 34%, var(--line));
}
/* The deeper wash costs the muted lede its headroom once a brand is dark or
   saturated, so on a themed hero the supporting text goes to full --text.
   Cheaper than watering the colour back down, which was the point of it. */
.has-pta .landing-hero .lede,
.has-pta .landing-hero .help-jump a { color: var(--text); }
.has-pta .landing-hero::before {
  background: radial-gradient(
    ellipse at center,
    color-mix(in srgb, var(--brand) 34%, transparent),
    transparent 68%
  );
}
/* A rule in the organization's colour, directly under its name. */
.has-pta .hero-ident::after {
  content: "";
  display: block;
  width: 84px;
  height: 4px;
  margin: 14px auto 0;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--brand), var(--brand-2));
}
.has-pta .landing-steps .step {
  border-color: color-mix(in srgb, var(--brand) 20%, var(--line));
}
.has-pta .landing-steps .step h3::before {
  background: linear-gradient(140deg, var(--brand), var(--brand-2));
  color: var(--on-brand);
}
.has-pta .steps-label::after {
  content: "";
  display: block;
  width: 44px;
  height: 3px;
  margin: 8px auto 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--brand) 55%, transparent);
}

/* Site chrome keeps one width whatever the page's content does. Letting each
   page set it meant the header jumped between an organization's landing page
   and every other page a volunteer visits. */
.wrap-chrome { max-width: 1060px; }

.account-note { margin: 10px 0 0; color: var(--muted); font-size: 0.9rem; }

/* Build stamp. Present on every page, loud on none: findable when somebody
   asks "what version are you seeing", invisible the rest of the time. */
.footer-version {
  margin: 10px 0 0;
  font-size: 0.78rem;
  opacity: 0.6;
  font-variant-numeric: tabular-nums;
}
