/* ------------------------------------------------------------------ */
/* Reno Improv — styles. Mobile-first with a clean, airy, "card" feel. */
/* ------------------------------------------------------------------ */

:root {
  --bg: #f6f7fb;
  --surface: #ffffff;
  --surface-2: #f0f2f8;
  --ink: #1f2937;
  --ink-soft: #4b5563;
  --muted: #8a93a6;
  --line: #e3e6ef;
  --brand: #d63384;          /* improv pink */
  --brand-ink: #a5276a;
  --accent: #3b82f6;
  --success: #16a34a;
  --warning: #d97706;
  --danger: #dc2626;
  --radius: 12px;
  --tap: 48px;               /* minimum touch target */
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 16px;
  line-height: 1.4;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* -------- top bar -------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--ink);
  color: #fff;
  padding: 0.65rem 1rem;
  flex-wrap: wrap;
}
/* White brand pill on the left edge. To revert: delete the .topbar .brand
   background / margin / padding block below and change the `a` color
   back to #fff. */
.topbar .brand {
  background: #fff;
  /* Negative top/bottom/left margins cancel the topbar's padding so the
     white reaches the screen edge and fills the full bar height flush. */
  margin: -0.65rem 0 -0.65rem -1rem;
  /* No vertical padding → no black strip above/below the pill.
     Logo height alone determines the pill's height. */
  padding: 0;
  /* Pill width extends from the viewport's left edge to line up with the
     left edge of the page title. The page title sits inside <main>, which
     is max-width:1100px centered with 1rem padding; so the title's left
     edge is at calc((100vw - 1100px)/2 + 1rem) on wide screens, or 1rem
     on narrow screens. The max() with 220px keeps the pill wide enough
     to comfortably hold logo + name on smaller viewports. */
  width: max(220px, calc((100vw - 1100px) / 2 + 1rem));
  display: flex;
  align-items: center;
  align-self: flex-start;    /* don't stretch into wrapped nav rows */
  justify-content: center;   /* center logo + name inside the pill */
  /* Fill the topbar's first row top-to-bottom via explicit margin cancellation */
  min-height: calc(56px + 1.3rem);
}
.topbar .brand a {
  color: #111827;           /* black name on white bg */
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: 0.02em;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}
.topbar .brand a:hover { text-decoration: none; }
.topbar .brand .brand-logo {
  /* Bigger logo — fills the nav-bar vertical space */
  height: 56px;
  width: auto;
  display: block;
}
.topbar .brand .brand-name { line-height: 1; }
@media (max-width: 480px) {
  .topbar .brand { width: max(180px, calc((100vw - 1100px) / 2 + 1rem)); }
  .topbar .brand .brand-logo { height: 44px; }
  .topbar .brand .brand-name { font-size: 1rem; }
}
.topbar nav {
  display: flex;
  gap: 0.25rem;
  flex-wrap: wrap;
  width: 100%;
  order: 3;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
  margin-top: 0;
}
.topbar nav.open {
  max-height: 600px;
  margin-top: 0.5rem;
}
.topbar nav a {
  color: #e5e7eb;
  padding: 0.75rem 0.75rem;
  border-radius: 8px;
  font-size: 0.95rem;
  flex: 1 1 40%;
  text-align: center;
  min-height: var(--tap);
  display: flex;
  align-items: center;
  justify-content: center;
}
.topbar nav a:hover { background: #334155; text-decoration: none; }
.topbar nav a.active { background: var(--brand); color: #fff; }

/* -------- Admin dropdown -------- */
.nav-dropdown {
  position: relative;
  display: flex;
  flex: 1 1 40%;
}
.nav-dropdown-toggle {
  background: transparent;
  color: #e5e7eb;
  border: 0;
  padding: 0.75rem 0.75rem;
  border-radius: 8px;
  font: inherit;
  font-size: 0.95rem;
  cursor: pointer;
  flex: 1 1 auto;
  min-height: var(--tap);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
}
.nav-dropdown-toggle:hover { background: #334155; }
.nav-dropdown-toggle.active { background: var(--brand); color: #fff; }
.nav-dropdown-toggle .caret { font-size: 0.8rem; opacity: 0.8; }
.nav-dropdown-menu {
  display: none !important;
  flex-direction: column;
}
.nav-dropdown.open > .nav-dropdown-menu { display: flex !important; }
.nav-dropdown-toggle[aria-expanded="true"] + .nav-dropdown-menu { display: flex !important; }
.nav-dropdown-menu a {
  color: #e5e7eb;
  padding: 0.75rem 0.75rem;
  border-radius: 8px;
  font-size: 0.95rem;
  min-height: var(--tap);
  display: flex;
  align-items: center;
}
.nav-dropdown-menu a:hover { background: #334155; text-decoration: none; }
.nav-dropdown-menu a.active { background: var(--brand); color: #fff; }

/* The "Sign out" dropdown item is a <form><button> (POST), but should
   visually match the <a> items above it. */
.nav-dropdown-menu .nav-logout-btn {
  background: transparent;
  border: 0;
  color: #e5e7eb;
  padding: 0.75rem 0.75rem;
  border-radius: 8px;
  font-size: 0.95rem;
  min-height: var(--tap);
  width: 100%;
  text-align: left;
  cursor: pointer;
  font: inherit;
}
.nav-dropdown-menu .nav-logout-btn:hover { background: #334155; }

.nav-toggle {
  background: transparent;
  border: 0;
  width: var(--tap);
  height: var(--tap);
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  cursor: pointer;
  padding: 0.5rem 0.25rem;
}
.nav-toggle span {
  display: block;
  width: 100%;
  height: 3px;
  background: #fff;
  border-radius: 2px;
}

/* Inline nav only on non-touch devices (mouse/trackpad).
   Touch screens (iPads, phones) always use the hamburger regardless of width,
   which prevents the brand pill from overlapping wrapped nav rows. */
@media (min-width: 760px) and (pointer: fine) {
  .nav-toggle { display: none; }
  .topbar nav {
    max-height: none;
    width: auto;
    margin-top: 0;
    order: 2;
    overflow: visible;
  }
  .topbar nav a { flex: 0 0 auto; }
  .nav-dropdown { flex: 0 0 auto; }
  .nav-dropdown-toggle { flex: 0 0 auto; }
  .nav-dropdown-menu {
    position: absolute;
    top: 100%;
    right: 0;
    background: var(--ink);
    border: 1px solid #334155;
    border-radius: 8px;
    padding: 0.25rem;
    min-width: 200px;
    z-index: 30;
    box-shadow: 0 10px 25px rgba(0,0,0,0.35);
  }
  .nav-dropdown-menu a {
    justify-content: flex-start;
    white-space: nowrap;
  }
  /* Desktop: open on hover as well as click. */
  .nav-dropdown:hover > .nav-dropdown-menu,
  .nav-dropdown:focus-within > .nav-dropdown-menu { display: flex !important; }
  .nav-dropdown-menu::before {
    content: "";
    position: absolute;
    top: -6px; left: 0; right: 0; height: 6px;
  }
}

/* -------- main layout -------- */
main {
  max-width: 1100px;
  margin: 0 auto;
  padding: 1rem;
}

h1, h2, h3 { color: var(--ink); line-height: 1.2; margin: 0 0 0.5rem; }
h1 { font-size: 1.6rem; }
h2 { font-size: 1.25rem; margin-top: 1.5rem; }
h3 { font-size: 1.05rem; color: var(--ink-soft); }

.page-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.page-head .subtle { color: var(--muted); margin-top: 0.1rem; }

/* Company Setup — stacked contact rows. Each row is a mini grid of fields
   with a Remove button on the right. A single header row sits above the
   list (see `.contact-header`) — per-row labels are not used anymore. */
.contact-row {
  display: grid;
  grid-template-columns: 1.25rem 1.3fr 1.2fr 1.5fr 1fr auto;
  gap: 0.6rem;
  align-items: center;      /* aligns hyperlink cell with input cells */
  padding: 0.3rem 0;        /* halved from 0.6rem per Dean's request */
  border-bottom: 1px dashed var(--line);
  transition: opacity 0.15s;
}
.contact-row:last-of-type { border-bottom: none; }
.contact-row .form-field { margin: 0; }

/* Header row sitting above the list of contacts. Same grid as the data
   rows so the column labels line up perfectly with the inputs below. */
.contact-row.contact-header {
  padding: 0.25rem 0 0.35rem;
  border-bottom: 1px solid var(--line);
}

/* Drag handle — CSS dot-grid, no font dependency */
.drag-handle {
  cursor: grab;
  user-select: none;
  display: flex;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  min-width: 1.25rem;
  padding: 0 2px;
  border-radius: 3px;
  transition: opacity 0.15s;
  /* 2×3 grid of dots via SVG data-URI */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='14'%3E%3Ccircle cx='2' cy='2'  r='1.5' fill='%238a93a6'/%3E%3Ccircle cx='6' cy='2'  r='1.5' fill='%238a93a6'/%3E%3Ccircle cx='2' cy='7'  r='1.5' fill='%238a93a6'/%3E%3Ccircle cx='6' cy='7'  r='1.5' fill='%238a93a6'/%3E%3Ccircle cx='2' cy='12' r='1.5' fill='%238a93a6'/%3E%3Ccircle cx='6' cy='12' r='1.5' fill='%238a93a6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 8px 14px;
  opacity: 0.7;
}
.drag-handle:hover { opacity: 1; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='14'%3E%3Ccircle cx='2' cy='2'  r='1.5' fill='%23d63384'/%3E%3Ccircle cx='6' cy='2'  r='1.5' fill='%23d63384'/%3E%3Ccircle cx='2' cy='7'  r='1.5' fill='%23d63384'/%3E%3Ccircle cx='6' cy='7'  r='1.5' fill='%23d63384'/%3E%3Ccircle cx='2' cy='12' r='1.5' fill='%23d63384'/%3E%3Ccircle cx='6' cy='12' r='1.5' fill='%23d63384'/%3E%3C/svg%3E"); }
.contact-row.dragging  { opacity: 0.35; }
.contact-row.drag-over-top    { border-top: 2px solid var(--brand); }
.contact-row.drag-over-bottom { border-bottom: 2px solid var(--brand); }
.contact-col-label {
  font-weight: 600;
  color: var(--ink-soft);
  font-size: 0.9rem;
  /* Inputs have 0.75rem of left padding, so the heading matches the
     start of the text inside the input directly below. */
  padding-left: 0.75rem;
}

/* View-mode cells inside a contact row: plain text displayed as non-
   editable content (the real values live in hidden inputs). The Edit
   button opens a modal that modifies the hidden inputs and re-renders
   these cells. */
.contact-row .contact-cell {
  padding-left: 0.75rem;        /* line up with column header labels */
  line-height: 1.3;
  word-break: break-word;
  min-width: 0;
  align-self: center;
}
.contact-row .contact-cell .email-link {
  text-decoration: underline;
  word-break: break-all;
}

.contact-row .contact-row-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  /* Vertically center the Remove button next to the input row. */
  align-self: center;
}
@media (max-width: 700px) {
  /* On narrow screens the header row would be cramped, so we hide it and
     let the per-input `placeholder` values serve as the labels. */
  .contact-row.contact-header { display: none !important; }
  .contact-row {
    grid-template-columns: 1.25rem 1fr 1fr;
    gap: 0.5rem;
  }
  .contact-row .contact-row-actions {
    grid-column: 2 / -1;
    justify-content: flex-start;
  }
  .drag-handle { grid-row: 1 / 3; align-self: center; }
}
.btn.small { padding: 0.35rem 0.6rem; font-size: 0.85rem; }

/* Label row: label on the left, inline helper link (e.g. ✉ Send) on the right. */
.label-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}
/* Inline email hyperlink next to the "Email" label. Matches standard site
   link styling (blue + underlined on hover) so it's visually consistent
   with the email links on People / Instructor detail pages. */
.mailto-link {
  font-weight: 400;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Instructor photo — centered between the page-head and the next card.
   Rounded, bordered, max 220px so it sits comfortably on the detail page. */
.instructor-photo-wrap {
  display: flex;
  justify-content: center;
  margin: 0.25rem 0 1rem;
}
.instructor-photo {
  max-width: 220px;
  max-height: 220px;
  width: auto;
  height: auto;
  border-radius: 12px;
  border: 1px solid var(--line);
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
  object-fit: cover;
}

/* -------- cards -------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1rem;
  margin-bottom: 1rem;
}

.grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
}
@media (min-width: 640px)  { .grid.cols-2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px)  { .grid.cols-3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 900px)  { .grid.cols-4 { grid-template-columns: repeat(4, 1fr); } }

.stat {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1rem;
}
.stat .label { color: var(--muted); font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.05em; }
.stat .value { font-size: 1.8rem; font-weight: 700; margin-top: 0.25rem; }

/* -------- tables -------- */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
  background: var(--surface);
}
th, td {
  padding: 0.65rem 0.75rem;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}
th {
  background: var(--surface-2);
  font-weight: 600;
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}
tr:last-child td { border-bottom: 0; }
tr:hover td { background: #f9fafb; }

/* --- "stack-on-mobile" tables --- */
.responsive-table th { display: none; }
.responsive-table td {
  display: block;
  border: none;
  padding: 0.35rem 0.75rem;
}
.responsive-table td::before {
  content: attr(data-label);
  display: block;
  font-size: 0.75rem;
  text-transform: uppercase;
  color: var(--muted);
  letter-spacing: 0.05em;
}
.responsive-table tr {
  display: block;
  border-bottom: 1px solid var(--line);
  padding: 0.5rem 0;
}
@media (min-width: 700px) {
  .responsive-table th { display: table-cell; vertical-align: middle; }
  .responsive-table tr { display: table-row; border-bottom: none; padding: 0; }
  .responsive-table td { display: table-cell; border-bottom: 1px solid var(--line); padding: 0.65rem 0.75rem; vertical-align: middle; }
  .responsive-table td::before { display: none; }
}

/* Hide .mobile-hide cells below the 700px responsive-table breakpoint. */
@media (max-width: 699px) {
  .responsive-table .mobile-hide { display: none !important; }
}

/* Keep phone numbers on one line in tables — "(775) 555-1234" shouldn't
   break at the space between area code and the rest. */
.responsive-table td[data-label="Phone"] { white-space: nowrap; }

/* Name link inside a table — inherit color, no underline until hover. */
.name-link { color: inherit; text-decoration: none; }
.name-link:hover { text-decoration: underline; }

/* -------- buttons/forms -------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  min-height: 36px;            /* 25% shorter than --tap (48px) */
  padding: 0.45rem 1rem;       /* vertical padding reduced 25% */
  background: var(--brand);
  color: #fff;
  border: 0;
  border-radius: 10px;
  cursor: pointer;
  font-weight: 600;
  font-size: 0.95rem;
}
.btn:hover { background: var(--brand-ink); text-decoration: none; }
.btn.secondary { background: #e5e7eb; color: var(--ink); }
.btn.secondary:hover { background: #d1d5db; }
.btn.danger { background: var(--danger); }
.btn.ghost {
  background: transparent; color: var(--ink);
  border: 1px solid var(--line);
}
.btn-row { display: flex; gap: 0.5rem; flex-wrap: wrap; }

/* Segmented-control style group. The buttons sit flush and the active one
   is visually "pressed" so the current sort order is obvious at a glance. */
.btn-group { display: inline-flex; gap: 0; }
.btn-group .btn { border-radius: 0; border-right-width: 0; }
.btn-group .btn:first-child { border-top-left-radius: 8px; border-bottom-left-radius: 8px; }
.btn-group .btn:last-child  { border-top-right-radius: 8px; border-bottom-right-radius: 8px; border-right-width: 1px; }
.btn.ghost.active {
  background: var(--ink); color: #fff; border-color: var(--ink);
}
.btn.ghost.active:hover { background: var(--ink); }

/* A <details class="card collapsible-card"> that looks like a regular card
   but whose body hides until the user clicks the header. The summary hosts
   the section h2 and a parenthesized count so the user can decide whether
   it's worth expanding. */
.collapsible-card > summary {
  cursor: pointer;
  list-style: none;          /* hide the default marker… */
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0;                /* h2 already has its own spacing */
}
.collapsible-card > summary::-webkit-details-marker { display: none; }
.collapsible-card > summary::before {
  content: "▸";
  color: var(--ink);
  font-size: 1.8rem;
  line-height: 1;
  display: inline-block;
  width: 1.6rem;
  transition: transform 120ms ease;
}
.collapsible-card[open] > summary::before { transform: rotate(90deg); }
.collapsible-card > summary h2 { margin: 0; flex: 1; }
.collapsible-card > summary .sec-count {
  color: var(--ink-soft);
  font-weight: 500;
  font-size: 0.9rem;
  margin-left: 0.4rem;
}
.collapsible-card > summary:hover h2 { color: var(--brand); }
.collapsible-card[open] > * + * { margin-top: 0.75rem; }

/* Peek-card: a regular card whose Active rows are always visible, and whose
   Past rows hide until the user clicks the header arrow. Unlike
   collapsible-card (which uses <details>/<summary> and hides its whole body
   when closed), peek-card keeps the Active content on screen at all times.
   Mark the card with `has-peek` only if there is something to reveal. */
.peek-card > .peek-head {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0;
}
.peek-card > .peek-head h2 { margin: 0; flex: 1; }
.peek-card > .peek-head .sec-count {
  color: var(--ink-soft);
  font-weight: 500;
  font-size: 0.9rem;
  margin-left: 0.4rem;
}
.peek-card.has-peek > .peek-head { cursor: pointer; list-style: none; }
.peek-card.has-peek > .peek-head::before {
  content: "▸";
  color: var(--ink);
  font-size: 1.8rem;
  line-height: 1;
  display: inline-block;
  width: 1.6rem;
  transition: transform 120ms ease;
}
.peek-card.has-peek.peek-open > .peek-head::before { transform: rotate(90deg); }
.peek-card.has-peek > .peek-head:hover h2 { color: var(--brand); }

/* Past rows are hidden by default in a has-peek card, revealed when
   peek-open is set. Support both table rows and list items. */
.peek-card.has-peek tr.past-row,
.peek-card.has-peek li.past-row { display: none; }
.peek-card.has-peek.peek-open tr.past-row { display: table-row; }
.peek-card.has-peek.peek-open li.past-row { display: list-item; }

.form-field { margin-bottom: 1rem; }
.form-field label {
  display: block;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 0.25rem;
  font-size: 0.9rem;
}
input[type="text"], input[type="email"], input[type="number"], input[type="date"],
input[type="url"], input[type="password"], input[type="search"], select, textarea {
  width: 100%;
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  font-size: 1rem;
  font-family: inherit;
  min-height: var(--tap);
}
textarea { min-height: 100px; resize: vertical; }

/* -------- flashes -------- */
.flash {
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: #e0f2fe;
}
.flash-success { background: #dcfce7; border-color: #86efac; color: #14532d; }

/* -------- pills & chips -------- */
.pill {
  display: inline-block;
  background: var(--surface-2);
  border: 1px solid var(--line);
  color: var(--ink-soft);
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.78rem;
  margin-right: 0.25rem;
}
.pill.good { background: #dcfce7; border-color: #86efac; color: #14532d; }
.pill.warn { background: #fef3c7; border-color: #fcd34d; color: #7c2d12; }
.pill.bad  { background: #fee2e2; border-color: #fca5a5; color: #7f1d1d; }
.pill.brand { background: #fce7f3; border-color: #f9a8d4; color: var(--brand-ink); }

/* -------- attendance specific -------- */
.attendance-list { list-style: none; padding: 0; margin: 0; }
.attendance-list li {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.9rem 0.75rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  margin-bottom: 0.5rem;
  transition: background 0.15s;
}
.attendance-list li.absent {
  background: #fff1f2;
  border-color: #fecdd3;
}
.attendance-list .name {
  flex: 1;
  font-size: 1.05rem;
  font-weight: 500;
}
/* Performers list on the Show detail page: keep Remove button snug to name. */
.attendance-list.performers-list .name { flex: 0 0 auto; }
.attendance-list.performers-list li { justify-content: flex-start; gap: 0.6rem; }
/* Compact variant: tighter rows so the volunteer section has room below. */
.attendance-list.perf-compact li {
  padding: 0.35rem 0.6rem;
  margin-bottom: 0.25rem;
  border-radius: 8px;
}
.attendance-list.perf-compact .name { font-size: 0.95rem; font-weight: 500; }

/* Compact variant for the Groups list on the People detail page: group
   labels are short, so tighten vertical rhythm instead of using the full
   attendance-row spacing. */
.attendance-list.groups-list li {
  padding: 0.3rem 0.6rem;
  margin-bottom: 0.2rem;
  border-radius: 8px;
}
.attendance-list.groups-list .name { font-size: 0.95rem; font-weight: 500; }
/* Remove buttons live to the LEFT of the name and are hidden until edit mode. */
.attendance-list.performers-list .perf-remove-form { display: none; }
.attendance-list.performers-list.edit-mode .perf-remove-form { display: inline-block; }
.attendance-list .state {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
/* Big, tappable switch. Acts like a toggle between Present/Absent. */
.toggle {
  position: relative;
  width: 72px;
  height: 40px;
  flex-shrink: 0;
}
.toggle input { position: absolute; opacity: 0; inset: 0; cursor: pointer; width: 100%; height: 100%; margin: 0; }
.toggle .track {
  display: block;
  width: 100%; height: 100%;
  background: #d1fae5;
  border: 1px solid #6ee7b7;
  border-radius: 999px;
  position: relative;
  transition: all 0.15s;
}
.toggle .track::after {
  content: "Here";
  position: absolute;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  color: #065f46;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
}
.toggle .thumb {
  position: absolute;
  top: 4px; left: 4px;
  width: 30px; height: 30px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0,0,0,0.3);
  transition: left 0.15s;
}
.toggle input:checked + .track {
  background: #fee2e2;
  border-color: #fca5a5;
}
.toggle input:checked + .track::after {
  content: "Out";
  right: auto;
  left: 12px;
  color: #991b1b;
}
.toggle input:checked + .track + .thumb { left: 38px; }

.sticky-save {
  position: sticky;
  bottom: 0;
  background: var(--bg);            /* fully opaque — no see-through names */
  padding: 0.75rem 1rem;
  display: flex;
  gap: 0.5rem;
  margin: 1rem -1rem 0;              /* bleed to the container edges */
  border-top: 1px solid var(--line);
  box-shadow: 0 -6px 12px rgba(0,0,0,0.06);
  z-index: 10;
}
.sticky-save .btn { flex: 1; }
/* Give the attendance list enough bottom room so the last row never sits
   underneath the sticky Save bar when scrolled to the bottom. */
.attendance-list { padding-bottom: 1rem; }

/* -------- misc -------- */
.pagefoot {
  max-width: 1100px;
  margin: 2rem auto 1rem;
  padding: 1rem;
  color: var(--muted);
  font-size: 0.85rem;
  text-align: center;
}

.empty {
  padding: 2rem 1rem;
  text-align: center;
  color: var(--muted);
  font-style: italic;
}

hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 1.25rem 0;
}

.kv { display: grid; grid-template-columns: 1fr 2fr; gap: 0.5rem 1rem; font-size: 0.95rem; }
.kv dt { color: var(--muted); }
.kv dd { margin: 0; }

@media (min-width: 640px) {
  .kv { grid-template-columns: 160px 1fr; }
}

/* -------- buttons (extras) -------- */
.btn.primary { background: var(--brand); }     /* alias for default */
.btn.primary:hover { background: var(--brand-ink); }
.btn.small { min-height: 27px; padding: 0.26rem 0.7rem; font-size: 0.85rem; }
.btn.big { font-size: 1.05rem; padding: 0.675rem 1.5rem; }

/* -------- "Open" button — universal detail-page link style -------- */
/* Used on the leftmost column of every list page with a detail view. */
/* Same size & color everywhere for visual consistency. */
.btn.open-detail {
  background: #1e3a8a;       /* navy */
  color: #fff;
  min-height: 27px;
  padding: 0.3rem 0.9rem;
  font-size: 0.9rem;
  font-weight: 600;
  border-radius: 8px;
  white-space: nowrap;
}
.btn.open-detail:hover { background: #172554; text-decoration: none; }
/* Wider variant for multi-character labels like "Sessions". */
.btn.open-detail.open-wide { padding: 0.41rem 1.4rem; font-size: 0.95rem; min-height: 32px; }

/* -------- modal dialog (shared) -------- */
.modal-backdrop {
  display: none;
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, 0.55);
  z-index: 100;
  align-items: flex-start;
  justify-content: center;
  padding: 4vh 1rem 1rem;
  overflow-y: auto;
}
.modal-backdrop.open { display: flex; }
.modal {
  background: var(--surface);
  border-radius: var(--radius);
  padding: 1.25rem 1.25rem 1rem;
  width: 100%;
  max-width: 560px;
  box-shadow: 0 18px 40px rgba(15, 23, 42, 0.25);
}
.modal h2 { margin: 0 0 0.75rem; }
.modal .modal-close {
  float: right;
  background: transparent;
  border: 0;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  color: var(--muted);
  padding: 0.25rem 0.5rem;
}
.modal .modal-close:hover { color: var(--ink); }

/* Category checkbox group */
.cat-checks { display: flex; gap: 1rem; flex-wrap: wrap; }
.cat-checks label { font-weight: 500; display: inline-flex; align-items: center; gap: 0.35rem; }

/* People page: collapsible category filter */
.people-filter {
  border: 1px solid var(--border, #d1d5db);
  border-radius: 0.4rem;
  background: #f9fafb;
  padding: 0.5rem 0.75rem;
}
.people-filter > summary {
  cursor: pointer;
  font-weight: 600;
  list-style: none;
  user-select: none;
}
.people-filter > summary::-webkit-details-marker { display: none; }
.people-filter > summary::before {
  content: "▸";
  display: inline-block;
  width: 1rem;
  transition: transform 0.15s;
}
.people-filter[open] > summary::before { transform: rotate(90deg); }
.people-filter .filter-body {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  align-items: center;
  padding-top: 0.6rem;
  margin-top: 0.4rem;
  border-top: 1px solid var(--border, #e5e7eb);
}
.people-filter .filter-body label {
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

/* Group picker: two side-by-side boxes — skill groups on the left, every
   other group on the right in two alpha-ordered columns. Widens the modal
   on desktop so no label needs to wrap; collapses to stacked boxes on
   narrow screens. */
.group-picker {
  display: grid;
  grid-template-columns: minmax(180px, auto) 1fr;
  gap: 0.5rem;
}
@media (max-width: 640px) {
  .group-picker { grid-template-columns: 1fr; }
}

.group-check-list {
  display: grid;
  gap: 0.35rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.5rem 0.75rem;
  background: #fff;
}
/* One column for the skills box … */
.group-check-list.group-skills  { grid-template-columns: 1fr; }
/* … two for the "everything else" box. */
.group-check-list.group-others  {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 640px) {
  .group-check-list.group-others { grid-template-columns: 1fr; }
}

.group-check-list label {
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  /* Keep each label on a single line — let the box widen instead. */
  white-space: nowrap;
}
.group-check-list label > span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* When the group picker appears inside the Edit Person modal, make the
   modal wider than its normal 560px so all the groups fit on one line
   each. Only applies to that modal — other modals keep their default. */
#edit-person-modal .modal { max-width: 880px; }

/* Category pills on detail pages */
.cat-pills { display: flex; gap: 0.35rem; flex-wrap: wrap; margin-top: 0.35rem; }
.cat-pills .pill.on  { background: #1e3a8a; color: #fff; }
.cat-pills .pill.off { background: #e5e7eb; color: var(--muted); }

/* Compact search input (People list) — sized to fit ~30 characters. Height is
   ~47px (was 72px, reduced 35%); width is capped so the box doesn't span the
   full container. */
input[type="search"].search-big {
  font-size: 1.15rem;      /* fits "Search by name or email" without clipping */
  padding: 0.6rem 1rem;
  min-height: 47px;        /* 72px * 0.65 */
  border-radius: 12px;
  width: 30ch;             /* ~30 characters wide */
  max-width: 100%;         /* stay responsive on narrow screens */
}

/* Alias list on person detail */
.alias-list {
  list-style: none; padding: 0; margin: 0 0 0.75rem;
  display: flex; flex-wrap: wrap; gap: 0.5rem;
}
.alias-list li {
  display: inline-flex; align-items: center; gap: 0.25rem;
}
.alias-list .btn.small.ghost {
  min-height: 28px; padding: 0 0.5rem; font-size: 1rem; line-height: 1;
}
.alias-add-form {
  display: flex; gap: 0.5rem; align-items: stretch; flex-wrap: wrap;
}
.alias-add-form input[type="text"] { flex: 1 1 220px; min-width: 0; }

/* Center-aligned category checkbox cells on list */
td.cat-cell, th.cat-cell {
  text-align: center;
  width: 64px;
}
/* Generic numeric column — center-justified under heading (per style guide) */
th.col-num, td.col-num { text-align: center; }
/* Narrow Time column on the Shows list. */
th.col-time, td.col-time {
  width: 10ch;
  min-width: 10ch;
  max-width: 10ch;
  white-space: nowrap;
}
/* Center-align Performer counts on the Shows list. */
th.col-performers, td.col-performers { text-align: center; }
/* Center-align Tickets and Revenue on the Shows list. */
th.col-tickets, td.col-tickets { text-align: center; }
th.col-revenue, td.col-revenue { text-align: center; white-space: nowrap; }

/* Category flag: bold black checkmark (no box) when set; blank otherwise. */
td.cat-cell .cat-mark {
  color: #000;
  font-weight: 700;
  font-size: 1.25rem;
  line-height: 1;
}

.form-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 1rem;
}

/* -------- import review UI -------- */
.review-row {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 1rem;
  margin-bottom: 1rem;
  background: #fff;
}
.review-incoming {
  padding-bottom: 0.5rem;
  margin-bottom: 0.75rem;
  border-bottom: 1px dashed var(--line);
  font-size: 1.05rem;
}
.review-options {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.review-choice {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem;
  border-radius: 8px;
  cursor: pointer;
  min-height: 44px;
}
.review-choice:hover { background: var(--surface-2); }
.review-choice input[type="radio"] {
  transform: scale(1.2);
  margin-right: 0.35rem;
}
.review-remember {
  margin-left: 2rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0.5rem;
  font-size: 0.9rem;
  color: var(--ink-soft);
  background: #fef3c7;
  border-radius: 6px;
}
.review-remember input[type="checkbox"] { transform: scale(1.1); }
.review-series {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px dashed var(--line);
}
.review-series label {
  display: block;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 0.25rem;
  font-size: 0.85rem;
}
.review-series-static {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px dashed var(--line);
}

.sticky-actions {
  position: sticky;
  bottom: 0;
  background: var(--surface);
  border-top: 1px solid var(--line);
  padding: 0.75rem 1rem;
  margin: 1rem -1rem 0;
  display: flex;
  gap: 0.5rem;
  z-index: 10;
}
.sticky-actions .btn { flex: 1; }

/* ---------------------------------------------------------------------------
   Email templates + compose
   --------------------------------------------------------------------------- */

/* "Sent" pills on the series list */
.sent-pills {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}
.pill.faint {
  background: transparent;
  color: var(--muted, #6b7280);
  border: 1px dashed var(--line);
}

/* Per-row compose picker on the series list */
.compose-picker {
  display: flex;
  gap: 0.35rem;
  align-items: center;
  margin: 0;
}
.compose-picker select {
  min-width: 10rem;
  padding: 0.3rem 0.5rem;
  font-size: 0.9rem;
}

/* Rich-text editor used in templates_form + email_compose */
.editor-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  padding: 0.35rem;
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: 8px 8px 0 0;
  background: var(--surface-alt, #f9fafb);
}
.editor-toolbar button {
  background: white;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 0.25rem 0.55rem;
  cursor: pointer;
  font-size: 0.9rem;
  line-height: 1;
}
.editor-toolbar button:hover { background: #eef2ff; }
.rich-editor {
  min-height: 14rem;
  padding: 0.9rem 1rem;
  border: 1px solid var(--line);
  border-radius: 0 0 8px 8px;
  background: white;
  font-size: 1rem;
  line-height: 1.5;
  outline: none;
}
.rich-editor:focus { border-color: #6366f1; }
.rich-editor p { margin: 0 0 0.75em; }
.rich-editor p:last-child { margin-bottom: 0; }
.rich-editor a { color: #4f46e5; text-decoration: underline; }

/* Variable chip list */
.var-list { margin-top: 0.25rem; }
.var-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.4rem; }
.var-chip {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.82rem;
  background: #eef2ff;
  color: #3730a3;
  border: 1px solid #c7d2fe;
  border-radius: 999px;
  padding: 0.15rem 0.6rem;
  cursor: pointer;
}
.var-chip:hover { background: #dbeafe; }

/* Form shell */
.tpl-form .form-row { margin-bottom: 1rem; }
.tpl-form label { display: block; font-weight: 600; margin-bottom: 0.25rem; }
.tpl-form input[type=text], .tpl-form select {
  width: 100%;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 1rem;
}
.form-actions { display: flex; gap: 0.5rem; }

/* Compose page two-column layout */
.compose-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 22rem;
  gap: 1rem;
  align-items: start;
}
@media (max-width: 900px) {
  .compose-grid { grid-template-columns: 1fr; }
}
.compose-side { position: sticky; top: 1rem; }
.compose-field { margin-bottom: 1rem; }
.compose-field label { display: block; font-weight: 600; margin-bottom: 0.3rem; }
.compose-field input[type=text] {
  width: 100%;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 1rem;
}

/* Recipient list */
.recipient-list {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.5rem 0.75rem;
  background: var(--surface-alt, #f9fafb);
}
.recipient-list.scroll { max-height: 18rem; overflow-y: auto; }
.recipient-line { padding: 0.15rem 0; font-size: 0.92rem; }

/* Step-by-step send panel */
.compose-steps { margin-top: 1rem; border-top: 1px solid var(--line); padding-top: 0.75rem; }
.compose-steps h3 { margin: 0 0 0.6rem; }
.compose-steps ol { list-style: none; padding: 0; margin: 0; }
.compose-steps .btn.big { width: 100%; }

/* Warn flash */
.flash-warn {
  background: #fef3c7;
  color: #92400e;
  border: 1px solid #fcd34d;
  padding: 0.6rem 0.8rem;
  border-radius: 8px;
  margin-bottom: 0.75rem;
}

/* ---------------------------------------------------------------------------
   Staff reminders
   --------------------------------------------------------------------------- */
.nav-badge {
  background: #dc2626;
  color: white;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  padding: 0.08rem 0.45rem;
  margin-left: 0.25rem;
  display: inline-block;
  vertical-align: middle;
}

.trigger-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
}
.trigger-row input[type=number] {
  width: 6rem;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 8px;
}
.trigger-row select {
  flex: 1; min-width: 12rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 8px;
}

.tpl-form textarea {
  width: 100%;
  padding: 0.7rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.95rem;
  line-height: 1.5;
}
.var-chip.copied { background: #bbf7d0; border-color: #86efac; }

.reminder-row {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.8rem 1rem;
  margin-bottom: 0.6rem;
  background: var(--surface, #fff);
}
.reminder-row.overdue { border-left: 4px solid #dc2626; background: #fef2f2; }
.reminder-row.today   { border-left: 4px solid #16a34a; background: #f0fdf4; }
.reminder-row.upcoming{ border-left: 4px solid #6366f1; background: #eef2ff; }
.reminder-row.sent    { border-left: 4px solid #9ca3af; opacity: 0.85; }

.reminder-head {
  display: flex; justify-content: space-between; align-items: center; gap: 0.5rem;
  margin-bottom: 0.35rem;
}
.reminder-title { flex: 1; }
.reminder-body { margin: 0.25rem 0 0.6rem; }
.reminder-preview {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
  margin-top: 0.5rem;
  font-size: 0.92rem;
}
.reminder-bodytext {
  margin: 0.4rem 0 0;
  white-space: pre-wrap;
  font-family: inherit;
  font-size: 0.92rem;
  line-height: 1.45;
}
.reminder-actions { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.btn.disabled { opacity: 0.5; pointer-events: none; cursor: not-allowed; }

/* -------- Link-copy button on Shows list --------
   Dark green when the show has a showcase_link; very light green when it
   does not, so the contrast is obvious at a glance. */
.link-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 27px;
  padding: 0.26rem 0.7rem;
  font-size: 0.85rem;
  font-weight: 600;
  border: 0;
  border-radius: 10px;
  cursor: pointer;
  background: #15803d;      /* dark green */
  color: #fff;
}
.link-btn:hover { background: #166534; }
.link-btn.empty {
  background: #dcfce7;      /* very light green */
  color: #86efac;           /* faded green text so "Link" reads but is muted */
  cursor: not-allowed;
}
.link-btn.empty:hover { background: #dcfce7; }

/* Money input with $ prefix (used on Show form for ticket price) */
.money-input {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface);
}
.money-input .money-prefix {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.7rem;
  background: #f3f4f6;
  color: #6b7280;
  font-weight: 600;
  border-right: 1px solid var(--line);
  user-select: none;
}
.money-input input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  padding: 0.55rem 0.75rem;
  font-size: 1rem;
  outline: none;
}
.money-input:focus-within {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(214, 51, 132, 0.15);
}

/* Archived show-type rows: softer background + muted text */
tr.row-archived { background: #f3f4f6; }
tr.row-archived td { color: #6b7280; }
tr.row-archived td strong { color: #4b5563; }

/* --------------------------------------------------------------------------
   Attendance-take page: toggle on the LEFT, ~4-5 characters of space, then
   the person's name. Uses a segmented Present/Absent pill so both labels
   are always readable.
   --------------------------------------------------------------------------*/
.attendance-list.attendance-take-list li {
  gap: 2.5rem;                /* roughly 4-5 character widths */
  justify-content: flex-start;
}
.attendance-list.attendance-take-list .name {
  flex: 1;
  min-width: 0;
}

/* Segmented Present / Absent toggle */
.att-toggle {
  position: relative;
  display: inline-block;
  flex-shrink: 0;
  width: 172px;
  height: 38px;
  cursor: pointer;
}
.att-toggle input {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  opacity: 0; cursor: pointer; margin: 0;
  z-index: 2;
}
.att-toggle-track {
  position: absolute; inset: 0;
  display: flex;
  border-radius: 999px;
  border: 1px solid #d1d5db;
  background: #f3f4f6;
  overflow: hidden;
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  user-select: none;
  z-index: 1;
}
.att-label {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, color 0.15s;
  color: #9ca3af;             /* muted when inactive */
}
/* Default state (unchecked = Present): left side highlighted green */
.att-toggle .att-present { background: #15803d; color: #fff; }
/* Checked state (= Absent): right side highlighted red */
.att-toggle input:checked + .att-toggle-track .att-present {
  background: transparent; color: #9ca3af;
}
.att-toggle input:checked + .att-toggle-track .att-absent {
  background: #b91c1c; color: #fff;
}

/* -----------------------------------------------------------------------
   Calendar (month / week / day views + event chips)
   ----------------------------------------------------------------------- */
.cal-wrap {
  /* Give the calendar as much horizontal room as we have.
     `main` normally has a max-width; break out of it here. */
  max-width: min(100%, 1400px);
  margin: 0 auto;
}
.cal-head {
  display: flex; flex-wrap: wrap; gap: 0.75rem 1.5rem;
  align-items: flex-end; justify-content: space-between;
  margin-bottom: 0.75rem;
}
.cal-head h1 { margin: 0; line-height: 1.1; }
.cal-head-controls {
  display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center;
}
/* Push the Prev/Today/Next nav group visually apart from the
   view-toggle + Add Event buttons to its right. */
.cal-head-controls .cal-nav { margin-right: 1in; }
@media (max-width: 720px) {
  /* On narrow screens the groups wrap to their own rows; drop the
     horizontal spacer so it doesn't add dead space at the end of a row. */
  .cal-head-controls .cal-nav { margin-right: 0; }
}

.cal-legend {
  display: flex; flex-wrap: wrap; gap: 0.35rem;
  margin: 0 0 0.75rem 0;
  font-size: 0.85rem;
}

/* Event chips -- palette for the five kinds.
   Keep backgrounds light, left-border strong, text dark for contrast.
   Chips render as inline-flow text so the time sits on line 1 alongside
   the title. If the title is long, it wraps to the next line on its own
   (time stays anchored at the start). Both month and week use this layout. */
.cal-chip {
  display: block;
  padding: 0.18rem 0.5rem;
  border-radius: 6px;
  border-left: 4px solid transparent;
  font-size: 0.8rem; line-height: 1.3;
  text-decoration: none; color: #1f2937;
  max-width: 100%;
  white-space: normal;
  overflow-wrap: anywhere;
}
.cal-chip .cal-chip-time  {
  display: inline;
  font-variant-numeric: tabular-nums;
  font-weight: 600; opacity: 0.85;
}
.cal-chip .cal-chip-title { display: inline; font-weight: 500; }
.cal-chip .cal-chip-time + .cal-chip-title::before {
  content: " · "; opacity: 0.5;
}
.cal-chip .cal-chip-sub   { margin-left: auto; font-size: 0.75rem; opacity: 0.7; }
.cal-chip:hover { filter: brightness(0.96); }

.cal-chip.class      { background: #dbeafe; border-left-color: #2563eb; }  /* blue */
.cal-chip.show       { background: #fce7f3; border-left-color: #d63384; }  /* brand pink */
.cal-chip.rehearsal  { background: #fef3c7; border-left-color: #d97706; }  /* amber/gold */
.cal-chip.meeting    { background: #f1f5f9; border-left-color: #64748b; }  /* slate gray — clearly distinct from playground */
.cal-chip.misc       { background: #ede9fe; border-left-color: #7c3aed; }  /* violet */
.cal-chip.playground { background: #fff7ed; border-left-color: #c2410c; }  /* burnt orange — clearly distinct from meeting */
/* Playground chips are synthesized (no detail page). Render them as plain
   spans so they don't look or behave like clickable links. */
.cal-chip.playground,
span.cal-chip { cursor: default; text-decoration: none; }

/* -------- Month view -------- */
.cal-month { padding: 0; overflow: hidden; }
.cal-month-grid {
  display: grid;
  /* minmax(0, 1fr) — not 1fr — otherwise a long event chip can force a
     column wider than 1fr's implicit `auto` minimum, which then shoves
     later days off the edge of the page. */
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
}
.cal-dow-head {
  background: #f9fafb;
  padding: 0.4rem 0.5rem;
  font-weight: 600; font-size: 0.8rem; color: var(--ink-soft);
  text-align: center; text-transform: uppercase; letter-spacing: 0.03em;
}
.cal-cell {
  background: #fff;
  min-height: 7.5rem;
  padding: 0.25rem 0.35rem 0.4rem;
  display: flex; flex-direction: column;
}
.cal-cell.out-of-month { background: #f8fafc; }
.cal-cell.out-of-month .cal-cell-num { color: var(--muted); }
.cal-cell.today { box-shadow: inset 0 0 0 2px var(--brand); }
.cal-cell-num {
  align-self: flex-start;
  font-weight: 600;
  font-size: 0.85rem;
  padding: 0.1rem 0.35rem;
  border-radius: 999px;
  color: var(--ink);
  text-decoration: none;
}
.cal-cell-num:hover { background: #eef2ff; }
.cal-cell.today .cal-cell-num {
  background: var(--brand); color: #fff;
}
.cal-cell-events {
  margin-top: 0.2rem;
  display: flex; flex-direction: column; gap: 2px;
  /* overflow: visible so long chip titles can wrap below their time
     without being clipped — matches the week view layout. */
  overflow: visible;
}

/* -------- Week view -------- */
.cal-week { padding: 0; overflow: hidden; }
.cal-week-grid {
  display: grid;
  /* See note on .cal-month-grid — minmax(0,1fr) keeps chips from
     overflowing their column width. */
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
}
.cal-week-col {
  background: #fff;
  min-height: 22rem;
  display: flex; flex-direction: column;
}
.cal-week-col.today { box-shadow: inset 0 0 0 2px var(--brand); }
.cal-week-col-head {
  display: flex; flex-direction: column; align-items: center;
  padding: 0.5rem;
  text-decoration: none; color: inherit;
  border-bottom: 1px solid var(--line);
  background: #f9fafb;
}
.cal-week-col-head:hover { background: #eef2ff; }
.cal-week-dow { font-size: 0.75rem; text-transform: uppercase;
                letter-spacing: 0.05em; color: var(--ink-soft); }
.cal-week-num { font-size: 1.3rem; font-weight: 600; margin-top: 0.1rem; }
.cal-week-events {
  flex: 1; padding: 0.4rem;
  display: flex; flex-direction: column; gap: 0.3rem;
}
.cal-week-empty { color: var(--muted); font-size: 0.85rem; text-align: center; padding: 0.5rem 0; }

/* -------- Day view -------- */
.cal-day-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.cal-day-item { margin: 0; }
.cal-day-chip {
  display: grid;
  grid-template-columns: 8rem 1fr auto;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.6rem 0.85rem;
  font-size: 0.95rem;
  white-space: normal;
}
.cal-day-chip .cal-chip-title { font-weight: 600; font-size: 1rem; }

/* -------- kv block for event detail page -------- */
.kv {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.4rem 1rem;
}
.kv .k { color: var(--ink-soft); font-weight: 500; }
.kv .v { color: var(--ink); }

/* -------- Small-screen: stack week into single column, shrink month cells -------- */
@media (max-width: 720px) {
  .cal-cell { min-height: 5rem; }
  .cal-chip { font-size: 0.7rem; padding: 0.15rem 0.35rem; }
  .cal-week-grid { grid-template-columns: 1fr; }
  .cal-week-col { min-height: auto; }
  .cal-day-chip { grid-template-columns: 1fr; gap: 0.25rem; }
  .cal-head-controls { width: 100%; }
}

/* ============================================================
   Volunteer roles on the Show detail page.
   Five compact blocks, one per skill group. Grid on wide screens,
   single-column on mobile.
   ============================================================ */
.vol-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 0.75rem;
  margin-top: 0.6rem;
}
.vol-block {
  border: 2px solid var(--line);
  border-radius: 10px;
  padding: 0.6rem 0.75rem;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.vol-block.filled { background: #f0fdf4; border-color: #16a34a; }

/* -- Per-skill color tints so each box is visually distinct.
      Border uses the same color as the Skill Title (dark shade) so the
      outline reads as a label. Background is a lighter shade of that
      same color family. Filled state above still wins (green). -- */
.vol-block[data-skill="Open/Close"]         { background: #fef3c7; border-color: #b45309; }
.vol-block[data-skill="Tech"]               { background: #dbeafe; border-color: #1d4ed8; }
.vol-block[data-skill="Box Office"]         { background: #ffedd5; border-color: #c2410c; }
.vol-block[data-skill="Playground Lead"]    { background: #ede9fe; border-color: #6d28d9; }
.vol-block[data-skill="Playground Shadow"] { background: #ccfbf1; border-color: #0f766e; }

.vol-block[data-skill="Open/Close"]         .vol-title { color: #b45309; }
.vol-block[data-skill="Tech"]               .vol-title { color: #1d4ed8; }
.vol-block[data-skill="Box Office"]         .vol-title { color: #c2410c; }
.vol-block[data-skill="Playground Lead"]    .vol-title { color: #6d28d9; }
.vol-block[data-skill="Playground Shadow"] .vol-title { color: #0f766e; }

.vol-block-head {
  display: flex; justify-content: space-between; align-items: center;
  gap: 0.5rem; flex-wrap: wrap;
}
.vol-title { font-weight: 700; font-size: 1.05rem; letter-spacing: 0.01em; }
.vol-count {
  font-size: 0.8rem; color: var(--ink-soft); font-weight: 500;
  margin-left: 0.25rem;
}
.vol-pill.filled {
  display: inline-block; margin-left: 0.35rem;
  background: #dcfce7; color: #166534;
  font-size: 0.7rem; font-weight: 600;
  padding: 0.1rem 0.45rem; border-radius: 999px;
  text-transform: uppercase; letter-spacing: 0.05em;
}
.vol-target-form { display: flex; align-items: center; gap: 0.35rem; }
.vol-target-input {
  width: 3.5rem; padding: 0.2rem 0.35rem;
  font-size: 0.85rem; border: 1px solid var(--line);
  border-radius: 6px;
}
.vol-list { list-style: none; padding: 0; margin: 0; }
.vol-list li {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem;
  padding: 0.08rem 0.2rem;
  border-bottom: 1px dashed rgba(0,0,0,0.06);
  font-size: 0.9rem;
  line-height: 1.25;
}
.vol-list li:last-child { border-bottom: none; }
.vol-list a { color: var(--ink); text-decoration: none; }
.vol-list a:hover { text-decoration: underline; }
.vol-check { color: #16a34a; font-weight: 700; }
.vol-dot { color: var(--ink-soft); }
.vol-note { color: var(--ink-soft); font-style: italic; font-size: 0.85rem; }
.vol-row-actions { margin-left: auto; display: flex; gap: 0.25rem; }
/* Compact confirm/remove buttons inline with a tentative/confirmed row */
.vol-row-actions .btn.small {
  padding: 0.12rem 0.55rem;
  min-height: 0;
  line-height: 1.25;
  font-size: 0.8rem;
}
.vol-sub {
  font-size: 0.75rem; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--ink-soft);
  margin-top: 0.25rem;
}
.vol-add-form {
  display: flex; gap: 0.35rem; flex-wrap: wrap; margin-top: 0.4rem;
  align-items: center;
  padding-top: 0.5rem;
  border-top: 1px dashed rgba(0,0,0,0.08);
}
.vol-add-form select, .vol-add-form input[type="text"] {
  padding: 0.3rem 0.4rem; font-size: 0.85rem;
  border: 1px solid var(--line); border-radius: 6px;
  background: #fff;
}
.vol-add-form select[name="student_id"] { flex: 1 1 100%; min-width: 0; }
.vol-add-form input[name="note"] { flex: 1 1 100%; min-width: 0; }
.vol-add-actions {
  display: flex; gap: 0.35rem; flex-wrap: wrap;
  width: 100%; margin-top: 0.15rem;
}
.vol-add-actions button { flex: 1 1 auto; min-width: 130px; }

/* ============================================================
   Volunteer blast composer + public invite page.
   ============================================================ */
.vol-blast-skills {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0.35rem; margin: 0.5rem 0;
}
.vol-blast-skills label {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.35rem 0.5rem; border: 1px solid var(--line);
  border-radius: 6px; cursor: pointer;
}
.vol-blast-skills input[type="checkbox"] { margin: 0; }
.vol-preview {
  margin-top: 0.75rem; padding: 0.5rem 0.75rem;
  background: #f8fafc; border: 1px dashed var(--line); border-radius: 8px;
  font-size: 0.9rem;
}
.vol-invite-shows { list-style: none; padding: 0; margin: 0; }
.vol-invite-shows li {
  display: flex; align-items: flex-start; gap: 0.5rem;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--line); border-radius: 8px;
  margin-bottom: 0.4rem; background: var(--surface);
}
.vol-invite-shows li.already { background: #f0fdf4; border-color: #bbf7d0; }
.vol-invite-shows input[type="checkbox"] {
  margin-top: 0.2rem; transform: scale(1.15);
}
.vol-invite-shows .show-info { flex: 1; }
.vol-invite-shows .show-when { font-weight: 600; }
.vol-invite-shows .show-skill {
  display: inline-block; margin-left: 0.35rem;
  background: #dbeafe; color: #1d4ed8;
  font-size: 0.75rem; font-weight: 600;
  padding: 0.1rem 0.45rem; border-radius: 999px;
}
.vol-invite-shows .show-already {
  margin-left: 0.35rem; color: #16a34a; font-size: 0.8rem; font-weight: 600;
}

@media (max-width: 720px) {
  .vol-grid { grid-template-columns: 1fr; }
  .vol-row-actions { margin-left: 0; width: 100%; }
}

/* ================================================================== */
/* Dark mode                                                           */
/* Toggled by adding/removing .dark on <html>; persisted in           */
/* localStorage as "darkMode" = "1" / "0".                            */
/* ================================================================== */
html.dark {
  --bg:        #0f172a;
  --surface:   #1e293b;
  --surface-2: #334155;
  --ink:       #f1f5f9;
  --ink-soft:  #94a3b8;
  --muted:     #64748b;
  --line:      #334155;
}

/* Topbar: var(--ink) is used as its background in light mode (dark navy).
   In dark mode --ink becomes near-white, so we pin the topbar to a fixed
   very-dark value so it keeps its dark look either way.              */
html.dark .topbar {
  background: #020617;
}

/* Desktop dropdown menu — override background & border for dark bg   */
@media (min-width: 760px) {
  html.dark .nav-dropdown-menu {
    background: #1e293b;
    border-color: #334155;
  }
}

/* Form controls: give them a surface-2 bg and a visible border       */
html.dark input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]),
html.dark select,
html.dark textarea {
  background: var(--surface-2);
  color: var(--ink);
  border-color: #475569;
}

html.dark input::placeholder,
html.dark textarea::placeholder {
  color: var(--muted);
}

/* Tables: keep zebra stripe readable in dark mode                    */
html.dark .responsive-table tbody tr:nth-child(even) {
  background: #1e2d3f;
}

/* Calendar chips that use hardcoded light bg colours                 */
html.dark .cal-chip {
  opacity: 0.9;
}

/* "Already" highlight row in vol-invite (was #f0fdf4 light green)    */
html.dark .vol-invite-shows li.already {
  background: #052e16;
  border-color: #166534;
}

/* Blue skill pill inside volunteer blast (was #dbeafe / #1d4ed8)     */
html.dark .vol-invite-shows .show-skill {
  background: #1e3a5f;
  color: #93c5fd;
}

/* Dark mode toggle button in the topbar                              */
.dark-toggle {
  background: transparent;
  border: 1.5px solid rgba(255,255,255,0.25);
  color: #e5e7eb;
  border-radius: 999px;
  padding: 0.3rem 0.7rem;
  font-size: 1rem;
  cursor: pointer;
  line-height: 1;
  display: flex;
  align-items: center;
  gap: 0.3rem;
  transition: background 0.15s, border-color 0.15s;
  white-space: nowrap;
  order: 1;       /* sits just before the hamburger on mobile */
}
.dark-toggle:hover {
  background: rgba(255,255,255,0.12);
  border-color: rgba(255,255,255,0.45);
}
@media (min-width: 760px) {
  .dark-toggle { order: unset; }
}

/* Help button */
.help-btn {
  background: transparent;
  border: 1.5px solid rgba(255,255,255,0.25);
  color: #e5e7eb;
  border-radius: 999px;
  padding: 0.3rem 0.65rem;
  font-size: 0.95rem;
  font-weight: 700;
  cursor: pointer;
  line-height: 1;
  display: flex;
  align-items: center;
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
  white-space: nowrap;
  order: 1;
}
.help-btn:hover {
  background: rgba(255,255,255,0.12);
  border-color: rgba(255,255,255,0.45);
  color: #fff;
  text-decoration: none;
}
@media (min-width: 760px) {
  .help-btn { order: unset; }
}

/* ================================================================== */
/* Read-only mode                                                       */
/* Applied via body.ro-mode when current user has is_read_only flag.   */
/* Navigation buttons (Open, Back/Forward) are always preserved.       */
/* ================================================================== */

/* Topbar badge shown in read-only sessions */
.ro-badge {
  background: #fef3c7;
  border: 1.5px solid #fcd34d;
  color: #7c2d12;
  border-radius: 999px;
  padding: 0.25rem 0.7rem;
  font-size: 0.8rem;
  font-weight: 600;
  white-space: nowrap;
  order: 1;
}
@media (min-width: 760px) {
  .ro-badge { order: unset; }
}
html.dark .ro-badge {
  background: #451a03;
  border-color: #92400e;
  color: #fcd34d;
}

/* 1. Always hide: Delete / Remove buttons (red danger style) */
body.ro-mode .btn.danger { display: none !important; }

/* 2. Hide: Add / New / Create buttons that live in page-head btn-row areas.
      These are typically <a class="btn [primary]"> or <button class="btn [primary]">
      sitting at the top of list pages. We keep .open-detail (blue nav) visible. */
body.ro-mode .page-head > .btn:not(.open-detail),
body.ro-mode .page-head .btn-row .btn:not(.open-detail),
body.ro-mode .page-head > button.btn:not(.open-detail) { display: none !important; }

/* 3. Hide: Submit / Save buttons inside data-mutation forms (POST).
      The data-ro-keep attribute opts a form out of this rule so that
      the account password-change form stays usable for read-only users. */
body.ro-mode form:not([data-ro-keep]) button[type="submit"],
body.ro-mode form:not([data-ro-keep]) input[type="submit"] { display: none !important; }

/* 4. Hide: Sticky save bars that float above the bottom of edit pages */
body.ro-mode .sticky-save,
body.ro-mode .sticky-actions { display: none !important; }

/* 5. Hide: any element explicitly tagged as a write action */
body.ro-mode [data-write] { display: none !important; }
