/* ARCMS Setup Wizard — plain, dependency-free CSS. No framework/CDN by
   design (see arcms/webapp/__init__.py's module docstring). Kept simple
   on purpose: legible, accessible contrast, works with browser zoom and
   keyboard navigation, nothing fancy to maintain. */

:root {
  --color-bg: #f7f7f5;
  --color-surface: #ffffff;
  --color-border: #d8d5cf;
  --color-text: #23241f;
  --color-text-muted: #5c5d57;
  /* Site-wide brand accent — real Rusty request, 2026-09-27: started as
     the header-bar-only navy/blue rebrand below, then extended the same
     day to "the rest of the green on the UI" (buttons, links, focus
     rings, calendar nav, status pills, etc.) to match, once the header
     blue itself settled on this exact swatch. Was #1f5c3f/#164531
     (green) before this change. Deliberately NOT applied to
     .alert--success (see its own rule below) or the redline-diff colors
     — those are a separate green=go/red=stop semantic, not the brand
     accent, and he explicitly asked to keep that pairing as-is. */
  --color-primary: #343ad9;
  --color-primary-hover: #272ca3;
  --color-error-bg: #fdecec;
  --color-error-border: #d9534f;
  --color-error-text: #7a1f1a;
  --color-done: #343ad9;
  --focus-ring: 3px solid #8a8ee6;
  /* The header bar. Originally set to the logo's own navy ring
     (#0f0b46); updated the same day per a follow-up request to a
     brighter royal blue matching a swatch he picked (#343ad9) — which
     is also, as of the site-wide change above, identical to
     --color-primary. Kept as its own variable rather than folded into
     --color-primary: the header intentionally stays this exact blue
     even if the brand accent ever changes again independently. */
  --color-header-bg: #343ad9;
  /* Four permission-section header colors (real Rusty request,
     2026-10-03, exact swatches from his own color picker) — Member
     keeps the existing --color-header-bg blue unchanged, the other
     three are new. Applied via the .site-header--section-* modifier
     classes below, chosen per-page by admin/layout.html from the
     request path (/board/, /admin/, /installer/, else Member) — see
     that template for the section-detection logic. Not folded into
     --color-header-bg itself since Member's own color must stay
     exactly what it already was. */
  --color-board-bg: #30a1e3;
  /* Swapped 2026-10-04 at Rusty's request: Admin is now red, Installer
     orange (they were the other way around). */
  --color-admin-bg: #e33030;
  --color-installer-bg: #e8890c;
  /* Co-Director, added 2026-10-03 alongside the new /codirector/
     section — unlike the four above, Rusty didn't pick this one from a
     swatch (it wasn't part of his original four-section request), so
     this is my own pick: a teal distinct from all four existing
     section colors and from --color-primary/--color-header-bg, meant
     to read as "related to Board but its own thing" given where it
     sits in the hierarchy (member, co-director, board, admin). Flagged
     to Rusty as easily swapped — just this one variable — if he'd
     rather pick his own. */
  --color-codirector-bg: #17a398;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--color-bg);
  color: var(--color-text);
  line-height: 1.5;
}

.site-header {
  background: var(--color-header-bg);
  color: #fff;
}
.site-header__inner {
  max-width: 960px;
  margin: 0 auto;
  padding: 1rem 1.25rem;
}
.site-header__title {
  font-size: 1.1rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.site-header__logo {
  height: 2.25rem;
  width: 2.25rem;
  display: block;
}

/* Day-to-day admin screens (added 2026-09-07, alongside the first one —
   the HamClubOnline import UI) — a plain top nav rather than the
   wizard's step sidebar, since there's no fixed sequence of screens
   here the way there is in the wizard. Reuses every other class in
   this file (.field, .alert, button/.btn, etc.) as-is. */
.admin-header__inner {
  max-width: 1100px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
}
.admin-topnav {
  display: flex;
  align-items: center;
  gap: 1.25rem;
}
.admin-topnav a {
  color: #fff;
  text-decoration: none;
  font-size: 0.95rem;
}
.admin-topnav a:hover {
  text-decoration: underline;
}
/* Administrator dropdown + its nested Discord submenu (real Rusty
   request, 2026-09-27: group the admin-only screens under one menu at
   the far right of the nav, just before Log out, instead of a growing
   flat list). Plain <details>/<summary> — no JS for the toggle itself,
   see nav-dropdown.js for the "close on outside click" polish. */
.nav-dropdown {
  position: relative;
}
.nav-dropdown > summary {
  color: #fff;
  font-size: 0.95rem;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.nav-dropdown > summary::-webkit-details-marker {
  display: none;
}
.nav-dropdown > summary:hover,
.nav-dropdown[open] > summary {
  text-decoration: underline;
}
.nav-dropdown__menu {
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 0.5rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
  min-width: 190px;
  padding: 0.35rem 0;
  z-index: 60;
  /* The Admin menu has grown past the height of a laptop screen (Rusty,
     2026-10-24): cap every dropdown at what fits under the sticky
     header and scroll inside it, so the last items are always reachable. */
  max-height: calc(100vh - 11rem);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.nav-dropdown__menu a {
  display: block;
  padding: 0.5rem 1rem;
  color: var(--color-text);
  text-decoration: none;
  font-size: 0.9rem;
  white-space: nowrap;
}
.nav-dropdown__heading {
  padding: 0.55rem 1rem 0.2rem;
  margin-top: 0.25rem;
  border-top: 1px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.nav-dropdown__menu a:hover {
  background: var(--color-bg);
}
/* The Discord submenu nests a second <details> inside the first
   dropdown's menu. It opens in place (indented, under its own heading)
   rather than as a flyout: the parent menu now scrolls, and a scrolling
   box would clip a flyout. */
.nav-dropdown__menu .nav-dropdown--sub {
  position: static;
}
.nav-dropdown--sub > summary {
  padding: 0.5rem 1rem;
  color: var(--color-text);
  font-size: 0.9rem;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.nav-dropdown--sub > summary::-webkit-details-marker {
  display: none;
}
.nav-dropdown--sub > summary:hover,
.nav-dropdown--sub[open] > summary {
  background: var(--color-bg);
}
.nav-dropdown--sub > .nav-dropdown__menu {
  position: static;
  margin: 0;
  padding: 0 0 0 1rem;
  min-width: 0;
  max-height: none;
  overflow: visible;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
}

.admin-logout-form {
  margin: 0;
}
.admin-logout-form button {
  padding: 0.35rem 0.9rem;
  font-size: 0.85rem;
}
.admin-shell {
  max-width: 1100px;
  margin: 0 auto;
  padding: 1.5rem 1.25rem 4rem;
}

/* Sticky nav (real Rusty request, 2026-09-26): scoped to the admin/
   member layout's header specifically (`.site-header--admin`), not the
   bare `.site-header` the login/reset-password/setup-wizard screens
   also use — those are short, single-purpose screens with nothing long
   enough to scroll past, so there's no reason to touch them here. See
   sticky-header.js for why the offset used just below (.table-search)
   is a CSS variable rather than a hardcoded pixel value: this nav wraps
   onto more than one line already, and the exact height isn't something
   CSS alone can know ahead of time. */
.site-header--admin {
  position: sticky;
  top: 0;
  z-index: 50;
}

/* Permission-section header colors (real Rusty request, 2026-10-03) —
   applied alongside .site-header--admin above, not instead of it: that
   class is purely the sticky-nav structure now (its name predates the
   four-section split and no longer means "the Administrator section"
   specifically — admin/layout.html's shared header uses it regardless
   of which section is active). --section-member intentionally repeats
   --color-header-bg rather than being left to inherit .site-header's
   own default, so every section is one explicit, equally-overridable
   rule. */
.site-header--section-member { background: var(--color-header-bg); }
.site-header--section-codirector { background: var(--color-codirector-bg); }
.site-header--section-board { background: var(--color-board-bg); }
.site-header--section-admin { background: var(--color-admin-bg); }
.site-header--section-installer { background: var(--color-installer-bg); }

.import-report {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
  margin: 1rem 0 1.5rem;
}
.import-report th, .import-report td {
  text-align: left;
  padding: 0.4rem 0.6rem;
  border-bottom: 1px solid var(--color-border);
  vertical-align: top;
}
.import-report th {
  background: var(--color-bg);
  font-weight: 600;
}
.import-row--error {
  background: var(--color-error-bg);
}
.import-row--warning {
  background: #fdf6e3;
}

.wizard-shell {
  max-width: 960px;
  margin: 0 auto;
  padding: 1.5rem 1.25rem 4rem;
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 2rem;
}
@media (max-width: 720px) {
  .wizard-shell { grid-template-columns: 1fr; }
}

.wizard-nav ol {
  list-style: none;
  margin: 0;
  padding: 0;
  border-left: 2px solid var(--color-border);
}
.wizard-nav li {
  padding: 0.5rem 0 0.5rem 1rem;
  color: var(--color-text-muted);
  font-size: 0.9rem;
  border-left: 2px solid transparent;
  margin-left: -2px;
}
.wizard-nav li.is-done {
  color: var(--color-done);
  font-weight: 600;
}
.wizard-nav li.is-active {
  color: var(--color-text);
  font-weight: 700;
  border-left-color: var(--color-primary);
}

.wizard-content {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 2rem;
}

h1 { font-size: 1.4rem; margin-top: 0; }
h2 { font-size: 1.1rem; }
p.help { color: var(--color-text-muted); font-size: 0.92rem; }
.page-menu-label {
  color: var(--color-text-muted);
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: -0.5rem 0 1rem;
}

.alert {
  padding: 0.75rem 1rem;
  border-radius: 6px;
  margin-bottom: 1.5rem;
  font-size: 0.95rem;
}
.alert--error {
  /* Strengthened 2026-09-07 — found live: the original 1px border/pale
     background was easy to miss entirely, especially on a screen already
     showing a wall of black form text above it. A thick left accent bar,
     bold weight, and a bold "Error:" lead-in (added in layout.html, not
     here, so it's real text for screen readers rather than a ::before
     someone could miss when copy-pasting a message) make this impossible
     to skim past. */
  background: var(--color-error-bg);
  border: 1px solid var(--color-error-border);
  border-left: 6px solid var(--color-error-border);
  color: var(--color-error-text);
  font-weight: 600;
  font-size: 1rem;
}
.alert--success {
  /* Deliberately hardcoded, not var(--color-primary) — real Rusty
     request, 2026-09-27: this stays green as "Go" feedback the same way
     .alert--error stays pink/red as "Stop" feedback, even though the
     rest of the app's accent color moved to blue that same round. These
     are the exact green values --color-primary itself used before that
     change, so this bar looks identical to how it always has. */
  background: #eaf3ee;
  border: 1px solid #1f5c3f;
  color: #164531;
}
.alert--info {
  background: #eef3f7;
  border: 1px solid #6c93ab;
  color: #2c4a5c;
}
.alert--action {
  /* Added 2026-09-24 for the Notifications board (arcms/notifications/)
     — an action-required alert (accept/decline a nomination, cast a
     vote) needs to stand out from a plain heads-up without looking like
     an error. */
  background: #fdf4e3;
  border: 1px solid #c99a3b;
  color: #6b4e14;
}
.notification-board { margin-bottom: 1.5rem; }
.notification-board .alert { margin-bottom: 0.75rem; }
.notification-board .alert form { display: inline-block; margin-right: 0.5rem; }
.notification-board .alert .notification-meta {
  display: block;
  font-size: 0.8rem;
  color: var(--color-text-muted);
  margin-top: 0.35rem;
}

fieldset {
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: 1rem 1.25rem 1.25rem;
  margin: 0 0 1.5rem;
}
legend { font-weight: 600; padding: 0 0.4rem; }

/* Election ballot's radio-per-candidate rows (real Rusty request,
   2026-09-28: a single page, radio buttons per position, one "Vote
   Now!" button) — fieldset/legend above already handle the outer box,
   this just gives each option some breathing room. */
.radio-option { display: inline-flex; align-items: center; gap: 0.4rem; margin: 0.3rem 0; }

.field { margin-bottom: 1.1rem; }
.field label {
  display: block;
  font-weight: 600;
  margin-bottom: 0.3rem;
  font-size: 0.92rem;
}
.field .field-help {
  display: block;
  color: var(--color-text-muted);
  font-size: 0.85rem;
  margin-top: 0.25rem;
}
.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field input[type="password"],
.field input[type="date"],
.field input[type="time"],
.field input[type="number"],
.field input[type="url"],
.field select,
.field textarea {
  width: 100%;
  max-width: 420px;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--color-border);
  border-radius: 5px;
  font-size: 1rem;
  font-family: inherit;
  background: #fff;
  color: var(--color-text);
}
.field textarea { max-width: 100%; resize: vertical; }
.field input:focus, .field select:focus {
  outline: var(--focus-ring);
  outline-offset: 1px;
}
.field.has-error input, .field.has-error select {
  border-color: var(--color-error-border);
  border-width: 2px;
}
.field-error {
  color: var(--color-error-text);
  font-size: 0.9rem;
  font-weight: 600;
  margin-top: 0.3rem;
}

.checkbox-row {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin-bottom: 0.6rem;
}
.checkbox-row input[type="checkbox"] { margin-top: 0.25rem; }
.checkbox-row label { font-weight: 500; }

.form-row { display: flex; gap: 1rem; flex-wrap: wrap; }
.form-row .field { flex: 1 1 200px; }

.module-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.5rem 1.5rem;
}

.actions {
  margin-top: 1.75rem;
  display: flex;
  gap: 0.75rem;
}

/* Convention (2026-09-13, after a real invisible-text bug in
   .contact-search-result): this base rule sets color: #fff for the
   default green button look. Any more specific rule that overrides
   `background` away from var(--color-primary) MUST also set its own
   explicit `color` — never rely on inheriting this one. Same rule
   applies to every future button/pill/badge variant in this file. */
button, .btn {
  font-size: 1rem;
  font-weight: 600;
  padding: 0.6rem 1.4rem;
  border-radius: 6px;
  border: 1px solid var(--color-primary);
  background: var(--color-primary);
  color: #fff;
  cursor: pointer;
}
button:hover, .btn:hover { background: var(--color-primary-hover); }
button:focus { outline: var(--focus-ring); outline-offset: 2px; }

.btn-secondary {
  background: #fff;
  color: var(--color-primary);
}
.btn-secondary:hover { background: #f0f1fa; }

.btn-small {
  white-space: nowrap;
  font-size: 0.85rem;
  font-weight: 500;
  padding: 0.3rem 0.7rem;
}
.btn-danger {
  background: #fff;
  color: var(--color-error-text);
  border-color: var(--color-error-border);
}
.btn-danger:hover { background: var(--color-error-bg); }

/* Members & Access screen (added 2026-09-10) — role chips and small
   inline per-row forms, on the same .import-report table this file
   already defines for the CSV import screens' report tables. */
.role-badge {
  display: inline-block;
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  background: #eaeaf8;
  color: var(--color-primary);
  border: 1px solid #d0d3f0;
  margin: 0.1rem 0.25rem 0.1rem 0;
  white-space: nowrap;
}
.role-badge--suspended {
  background: var(--color-error-bg);
  color: var(--color-error-text);
  border-color: var(--color-error-border);
  text-decoration: line-through;
}
.role-badge form { display: inline; margin-left: 0.3rem; }
.role-badge button {
  font-size: 0.75rem;
  font-weight: 700;
  padding: 0 0.2rem;
  border: none;
  background: transparent;
  color: inherit;
  line-height: 1;
}
.role-badge button:hover { background: transparent; text-decoration: underline; }
.inline-form { display: inline-flex; gap: 0.4rem; align-items: center; }
.status-pill {
  display: inline-block;
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
}
.status-pill--active { background: #eaeaf8; color: var(--color-primary); }
.status-pill--inactive { background: #f0f0ee; color: var(--color-text-muted); }

/* /admin/committees screen (added 2026-09-12) — a dedicated table style
   rather than reusing .import-report as-is: each row's Actions column
   holds a variable-height stack of 2-4 forms depending on the
   committee's flags, and .import-report's thin 1px row divider wasn't
   enough to keep one committee's button stack from visually blending
   into the next row (found live, Rusty had to squint to tell which
   buttons belonged to which committee). Stronger row dividers,
   alternating row shading, and a bordered box around the action
   buttons together fix that without introducing this codebase's first
   line of JavaScript. */
.committees-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
  margin: 1rem 0 1.5rem;
}
.committees-table th {
  text-align: left;
  padding: 0.6rem;
  background: var(--color-bg);
  font-weight: 600;
  border-bottom: 2px solid var(--color-border);
}
.committees-table td {
  text-align: left;
  padding: 0.75rem 0.6rem;
  vertical-align: top;
  border-bottom: 2px solid var(--color-border);
}
.committees-table tbody tr:nth-child(odd) {
  background: var(--color-bg);
}
.rename-input {
  font-size: 0.9rem;
  padding: 0.25rem 0.4rem;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  width: 12rem;
  max-width: 100%;
}
.committee-actions {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  align-items: flex-start;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: 0.6rem;
  background: #fff;
}
.roster-list {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.85rem;
}
.roster-list li {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.15rem 0;
}
.roster-list form { margin: 0; }
.contact-picker { margin-top: 0.4rem; }
.contact-picker summary {
  cursor: pointer;
  display: inline-block;
  font-size: 0.85rem;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  background: var(--color-bg);
}
/* Sticks just below the (also sticky) admin nav so only the table body
   scrolls underneath it — the padding (replacing what used to be a
   plain margin-bottom) and matching background keep table rows from
   visibly showing through the gap while scrolled; --sticky-header-height
   is kept current by sticky-header.js. The 140px fallback is only ever
   seen for an instant before that script's first run, or with
   JavaScript disabled (where nothing sticks at all, since
   .site-header--admin's own sticky behavior is purely CSS and doesn't
   depend on this variable). */
.table-search {
  max-width: 20rem;
  position: sticky;
  top: var(--sticky-header-height, 140px);
  z-index: 20;
  background: var(--color-surface);
  padding: 0.6rem 0;
}
.table-search-input {
  font-size: 0.95rem;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--color-border);
  border-radius: 5px;
  width: 100%;
}
.contact-search { margin-top: 0.4rem; max-width: 16rem; }
.contact-search-input {
  font-size: 0.9rem;
  padding: 0.25rem 0.4rem;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  width: 100%;
}
.contact-search-results {
  list-style: none;
  margin: 0.3rem 0 0;
  padding: 0;
  max-height: 10rem;
  overflow-y: auto;
}
.contact-search-results li { margin: 0; }
.contact-search-result {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.3rem 0.4rem;
  border: none;
  border-bottom: 1px solid var(--color-border);
  background: #fff;
  color: var(--color-text);
  font-weight: 400;
  cursor: pointer;
  font-size: 0.85rem;
}
.contact-search-result:hover { background: var(--color-bg); }
.contact-search-hint {
  font-size: 0.8rem;
  color: var(--color-text-muted);
  margin: 0.3rem 0 0;
}

/* Nominate/add-moderator "member-picker" combobox (see
   arcms/webapp/static/js/member-picker.js) — reuses the .contact-search*
   result-list look above; only the empty state and the "you must pick
   someone from the list" validation message are new here. */
.member-picker { max-width: 20rem; }
.person-picker { max-width: 24rem; }
.member-picker-empty {
  padding: 0.3rem 0.4rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}
.contact-search-result.is-highlighted { background: var(--color-bg); }
.member-picker-error {
  font-size: 0.85rem;
  color: var(--color-error-text);
  margin: 0.3rem 0 0;
}

/* Calendar (Cal-10, added 2026-09-14) — the month grid, layer-toggle
   panel, and day/event screens. See arcms/webapp/calendar_routes.py's
   own module docstring for why layer-visibility (.calendar-layers) is
   kept visually and structurally separate from event actions
   (.calendar-event-actions) — that separation is a real product
   decision, not just a styling choice, so don't merge these back
   together even if it looks like it would tidy up the markup. */
.calendar-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 1rem;
}
.calendar-toolbar h1 { margin: 0; }
.calendar-nav { display: flex; align-items: center; gap: 0.75rem; }
.calendar-nav a { font-weight: 600; text-decoration: none; color: var(--color-primary); }
.calendar-nav a:hover { text-decoration: underline; }

.calendar-layers {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 1rem 1.25rem;
  margin-bottom: 1.25rem;
}
.calendar-layers .field-help { margin: 0.2rem 0 0.75rem; }
.calendar-layers ul { list-style: none; margin: 0 0 0.75rem; padding: 0; columns: 2; }
@media (max-width: 640px) { .calendar-layers ul { columns: 1; } }
.calendar-layers li { display: flex; align-items: center; gap: 0.45rem; margin-bottom: 0.4rem; break-inside: avoid; }
.calendar-swatch {
  display: inline-block;
  width: 0.75rem;
  height: 0.75rem;
  border-radius: 3px;
  flex-shrink: 0;
}
.calendar-layers .view-only-tag {
  color: var(--color-text-muted);
  font-size: 0.82rem;
}

.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  background: var(--color-border);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  overflow: hidden;
}
.calendar-grid-header {
  background: var(--color-primary);
  color: #fff;
  padding: 0.4rem;
  text-align: center;
  font-size: 0.8rem;
  font-weight: 600;
}
.calendar-day-cell {
  background: #fff;
  min-height: 6.5rem;
  padding: 0.35rem;
  font-size: 0.82rem;
}
.calendar-day-cell--other-month { background: #fafaf8; color: var(--color-text-muted); }
.calendar-day-cell--today { background: #eaeaf8; }
.calendar-day-number { font-weight: 600; text-decoration: none; color: inherit; }
.calendar-day-number:hover { text-decoration: underline; }
.calendar-day-events { list-style: none; margin: 0.3rem 0 0; padding: 0; }
.calendar-day-events li { margin-bottom: 0.15rem; }
.calendar-event-chip {
  display: block;
  border-radius: 3px;
  padding: 0.05rem 0.3rem;
  font-size: 0.78rem;
  text-decoration: none;
  color: #fff;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.calendar-event-chip--cancelled { text-decoration: line-through; opacity: 0.7; }
.calendar-day-more { font-size: 0.76rem; color: var(--color-text-muted); }

.calendar-event-list { list-style: none; margin: 0; padding: 0; }
.calendar-event-list li {
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--color-border);
}
.calendar-event-list li:last-child { border-bottom: none; }
.calendar-event-time { color: var(--color-text-muted); font-size: 0.88rem; }

.calendar-event-actions { margin-top: 1.25rem; display: flex; gap: 0.75rem; }

.weekday-check-row { display: flex; flex-wrap: wrap; gap: 0.75rem; margin: 0.3rem 0 0.9rem; }
.weekday-check-row label { display: flex; align-items: center; gap: 0.3rem; font-weight: 500; }

fieldset.calendar-fieldset {
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 0.9rem 1rem 0.2rem;
  margin: 0 0 1.25rem;
}
fieldset.calendar-fieldset legend { font-weight: 700; padding: 0 0.4rem; }
.radio-row { display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.4rem; }
.radio-row label { font-weight: 500; }

/* Position Descriptions (2026-09-17) */
.position-description-content ul { margin: 0.2rem 0 0.9rem 1.2rem; }
.position-description-changelog-entry {
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 0.9rem 1rem;
  margin-bottom: 1.25rem;
}
.position-description-redline p { margin: 0.15rem 0; }
.redline-added { color: #1a6b1a; text-decoration: underline; }
.redline-deleted { color: #a30000; }
.redline-unchanged { color: var(--color-text-muted, #444); }
.radio-row-inline-input { display: inline-flex; align-items: center; gap: 0.4rem; margin-left: 0.4rem; }

/* Position Description approval-discussion comments (2026-09-21) */
.position-description-comment {
  border-left: 3px solid var(--color-primary);
  padding: 0.4rem 0 0.4rem 0.8rem;
  margin-bottom: 0.9rem;
}
.position-description-comment p { margin: 0.2rem 0; }

/* Member-facing Committees directory (2026-10-04) */
.committee-card {
  border: 1px solid var(--color-border, #d8d8d2);
  border-radius: 8px;
  padding: 1rem 1.25rem;
  margin: 0 0 1.25rem;
}
.committee-card h2 { margin-top: 0; }
.committee-card h3 { font-size: 1rem; margin: 0.9rem 0 0.3rem; }

/* --- Member profile page (2026-10-05). Kept here, not inline: the nginx
   Content-Security-Policy is "default-src 'self'", which blocks <style>
   blocks, style="" attributes and inline <script> on the page itself. --- */
.profile-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr)); gap: 1.5rem; align-items: start; }
.profile-table th[scope=row] { width: 11rem; text-align: left; font-weight: 600; }
.profile-table td { vertical-align: top; }
.profile-update { display: inline-block; margin-left: .5rem; }
.profile-update > summary { display: inline-block; cursor: pointer; list-style: none; }
.profile-update > summary::-webkit-details-marker { display: none; }
.profile-update__form { margin-top: .5rem; display: grid; gap: .4rem; max-width: 26rem; }
.profile-update__form label { font-size: .9rem; }
.profile-note { color: var(--color-text-muted); font-size: .9rem; }
.donation-group { display: contents; }
.donation-group[hidden] { display: none; }

/* Members & Access: the "What each role means" reference table. */
.role-definitions { margin: 0 0 1rem; }
.role-definitions > summary { cursor: pointer; }
.role-definitions th[scope=row] { text-align: left; white-space: nowrap; vertical-align: top; }
.role-definitions td { vertical-align: top; }

/* Public pages (apply, donate): narrow, centered, no login. */
.public-main {
  max-width: 640px;
  margin: 2rem auto;
  padding: 0 1.25rem;
}

/* Spam trap field: out of sight and out of the tab order for real people. */
.visually-hidden {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Plain data tables (used by many pages; v198a gave them their spacing and row lines, as .import-report has) */
.data-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; margin: 1rem 0 1.5rem; }
.data-table th, .data-table td { text-align: left; padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--color-border); vertical-align: top; }
.data-table thead th { background: var(--color-bg); font-weight: 600; }
.data-table tbody th { font-weight: 600; width: 16rem; }

/* Treasurer budget workspace (v198) */
.data-table .money, .data-table td.money, .data-table th.money { text-align: right; white-space: nowrap; }
.data-table details.profile-update { margin: .25rem 0; }

/* Treasurer ledger (v199): the spending check shows in words, with a colour to help the eye */
.standing--over, .standing--not_in_budget, .standing--budget_not_approved { color: var(--color-error-text); font-weight: 600; }
.standing--within, .standing--approved { color: var(--color-text); }
.standing--discretionary { color: var(--color-primary); }

/* Club status page (v204): title on the left, the club's details box at the upper right */
.status-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.status-head h1 { flex: 1 1 18rem; margin: 0; }
.status-club { flex: 0 1 16rem; margin-left: auto; text-align: center; background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: 6px; padding: 0.75rem 1rem; }
.status-club p { margin: 0.25rem 0; overflow-wrap: anywhere; }
.status-club__logo { max-width: 100%; max-height: 8rem; height: auto; }
.status-club__call { font-weight: 700; font-size: 1.1rem; }
.status-main { max-width: 70rem; }
.status-committees td p.help { margin: 0.25rem 0 0; }
@media (max-width: 40rem) {
  .status-club { flex-basis: 100%; margin-left: 0; }
  .status-main { overflow-x: auto; }
}

/* ==========================================================================================================
   Responsive layout (v205, Rusty's request: "make the ARCMS work well on Desktop, Tablets and phones").
   Three tiers: desktop (above 60rem), tablet (up to 60rem, the top bar folds behind a button) and phone
   (up to 40rem, tighter spacing, tables scroll sideways, the Home page tables become cards). Everything here
   comes last so it wins over the earlier rules; none of it changes the desktop look except that the top bar now
   wraps onto extra lines instead of running off the right edge.
   ========================================================================================================== */
img, video { max-width: 100%; height: auto; }
.site-header__logo { flex: none; }

/* Desktop: wrap the top bar's links instead of letting them overflow the window. */
.admin-topnav { flex-wrap: wrap; row-gap: 0.4rem; }
.admin-topnav > a, .admin-topnav > .nav-dropdown > summary { white-space: nowrap; }

.nav-toggle {
  display: none;
  margin-left: auto;
  background: transparent;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.75);
  padding: 0.45rem 0.9rem;
  font-size: 0.95rem;
  font-weight: 500;
}
.nav-toggle:hover { background: rgba(255, 255, 255, 0.15); }
.nav-toggle:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }

@media (max-width: 60rem) {
  .admin-header__inner { gap: 0.5rem 1rem; }
  .nav-toggle:not([hidden]) { display: inline-flex; align-items: center; }
  .admin-topnav { width: 100%; flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 0; }
  .admin-topnav.nav-collapsible { display: none; }
  .admin-topnav.nav-collapsible.is-open {
    display: flex;
    max-height: calc(100vh - 5rem);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .admin-topnav > a,
  .admin-topnav > .nav-dropdown > summary {
    display: block;
    padding: 0.75rem 0.25rem;
    border-top: 1px solid rgba(255, 255, 255, 0.25);
    font-size: 1rem;
  }
  .admin-topnav .nav-dropdown { position: static; }
  /* Menus open in place under their heading, not as a floating box. */
  .nav-dropdown__menu {
    position: static;
    margin: 0 0 0.5rem;
    min-width: 0;
    max-height: none;
    overflow: visible;
    box-shadow: none;
  }
  .nav-dropdown__menu a, .nav-dropdown--sub > summary { padding: 0.7rem 1rem; font-size: 1rem; white-space: normal; }
  .admin-logout-form { padding: 0.75rem 0 0.5rem; border-top: 1px solid rgba(255, 255, 255, 0.25); }
  .admin-logout-form button { padding: 0.6rem 1.2rem; font-size: 1rem; }
  .status-head h1 { flex-basis: 100%; }
}

@media (max-width: 48rem) {
  .admin-shell { padding: 0.75rem 0.5rem 3rem; }
  .wizard-content { padding: 1rem; }
  .site-header__inner { padding: 0.65rem 1rem; }
  h1 { font-size: 1.25rem; }
  /* Wide tables scroll sideways inside the page instead of stretching the whole page. */
  table { display: block; max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  input, select, textarea { max-width: 100%; font-size: 1rem; }
  input[type="text"], input[type="email"], input[type="search"], input[type="password"], input[type="tel"],
  input[type="url"], input[type="number"], input[type="date"], input[type="time"], select, textarea { width: 100%; }
  .form-row .field { flex-basis: 100%; }
  .actions { flex-wrap: wrap; }
  .member-picker, .person-picker, .contact-search { max-width: none; }
  button, .btn { min-height: 2.75rem; }
  .btn-small { min-height: 2.25rem; }
  pre, code { overflow-x: auto; max-width: 100%; }
  .inline-form { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }
}

/* Phone: a table marked .stack-table becomes one card per row, each cell labelled by its column. */
@media (max-width: 40rem) {
  table.stack-table, table.stack-table tbody { display: block; overflow: visible; }
  table.stack-table thead { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
  table.stack-table tr {
    display: block;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 6px;
    margin: 0 0 0.75rem;
    padding: 0.4rem 0.75rem;
  }
  table.stack-table td {
    display: block;
    border: 0;
    padding: 0.3rem 0;
  }
  table.stack-table td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--color-text-muted);
  }
  table.stack-table td:empty { display: none; }
}

/* Tablet: the opened navigation lists its links in columns instead of one long column. */
@media (min-width: 40.01rem) and (max-width: 60rem) {
  .admin-topnav.nav-collapsible.is-open {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
    column-gap: 1rem;
    align-content: start;
  }
  .admin-topnav.nav-collapsible.is-open .admin-logout-form { grid-column: 1 / -1; }
}

/* Phone: the month grid keeps seven equal columns, with smaller type and shorter days. */
@media (max-width: 40rem) {
  .calendar-grid { grid-template-columns: repeat(7, minmax(0, 1fr)); }
  .calendar-grid-header { padding: 0.3rem 0.1rem; font-size: 0.7rem; }
  .calendar-day-cell { min-height: 3.75rem; padding: 0.2rem; font-size: 0.72rem; }
  .calendar-event-chip { font-size: 0.65rem; padding: 0 0.15rem; }
  .calendar-day-more { font-size: 0.65rem; }
}
