/* classmates.css — the /classmates roster only.
 *
 * The page also loads /style.css, the public site's stylesheet, which is
 * where every colour token, typography, and the .chip/.facet/.search search
 * apparatus come from (this page's facet search reuses that exact markup).
 * This file adds the form controls and roster-card layout the public pages
 * have none of — modeled on admin.css, the /input editor's equivalent file,
 * but without anything week-grid-specific.
 *
 * No inline <style> anywhere — the CSP for /classmates is default-src 'self'
 * with no 'unsafe-inline', so a browser drops one silently. */

.narrow { max-width: 26rem; }

/* The search box and the Team/Staff Group dropdowns share one row instead of
   each getting its own — the thing this file exists to fix is a search
   section that grows a new block per facet. .search itself only styles the
   text input and button (shared style.css); these selects get the same look
   as .adm's form controls, scoped here so it doesn't bleed into a plain
   <select> elsewhere on the page. */
.search.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.6rem 1rem;
}

.search.toolbar .f { margin: 0; }
.search.toolbar .searchf { flex: 1 1 16rem; }
.search.toolbar .searchrow { max-width: none; }

.search.toolbar label {
  display: block;
  margin-bottom: 0.2rem;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.search.toolbar select {
  min-width: 8rem;
  padding: 0.5rem 0.6rem;
  background: var(--surface);
  border: var(--hair) solid var(--edge-2);
  border-radius: 0;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--text);
}

.search.toolbar select:focus-visible {
  outline: var(--line) solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}

/* A facet with more than COLLAPSE_THRESHOLD options (Branch, currently — see
   server.ts) renders as this instead of a plain .facet: closed by default,
   so a 29-option checkbox list doesn't sit open on every page load. Opens on
   its own when it already has a selection, so an active filter is never
   hidden behind a closed panel. */
.facetpanel {
  margin-bottom: 0.9rem;
  border: var(--hair) solid var(--edge-2);
}

.facetpanel summary {
  padding: 0.5rem 0.7rem;
  cursor: pointer;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-2);
}

.facetpanel .filters { padding: 0 0.7rem 0.7rem; }
.facetpanel[open] summary { margin-bottom: 0.4rem; }

.panelcount {
  font-weight: 500;
  text-transform: none;
  letter-spacing: normal;
  color: var(--muted);
}

.admhead {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1rem;
}

.admhead h2 {
  grid-column: 2;
  text-align: center;
  font-size: 2.4rem;
  font-weight: 800;
}

.admhead .adm.out {
  grid-column: 3;
  justify-self: end;
}

.note { margin: 0.6rem 0 0; color: var(--text); font-size: 0.9rem; font-weight: 700; }

/* The roster's one-line intro sits directly above the centered "add yourself" button and
   reads as its caption, so it is centered with it. Scoped by the second class: the other
   .note, the personal-passphrase explanation under the add form, is a paragraph of prose
   and stays left-aligned with the fields it describes. */
.note.intro { text-align: center; }

.addcta { margin: 1rem 0 0; text-align: center; }

.addcta a {
  display: inline-block;
  padding: 0.6rem 1.4rem;
  background: var(--accent);
  border: var(--hair) solid var(--accent);
  color: var(--surface);
  font-weight: 700;
  font-size: 1rem;
  text-decoration: none;
}

.addcta a:hover { background: var(--accent-2); border-color: var(--accent-2); }
.addcta a:focus-visible { outline: var(--line) solid var(--accent); outline-offset: 2px; }

/* --- FORMS -------------------------------------------------------------- */

.adm { margin: 0; }

/* Two columns of fields on a wide screen, one on a phone. Facet fieldsets and
   the submit row span both columns, so a checkbox list never gets squeezed
   into a half-width cell. */
.grid2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0.6rem 1rem;
}

.grid2 .actions,
.grid2 .facetfield { grid-column: 1 / -1; }

.f { margin: 0; }

.f label,
.adm label,
.facetfield legend {
  display: block;
  margin-bottom: 0.2rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent-2);
}

.opt {
  font-weight: 400;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--muted);
}

.adm input,
.adm select {
  width: 100%;
  box-sizing: border-box;
  padding: 0.45rem 0.6rem;
  background: var(--surface);
  border: var(--hair) solid var(--edge-2);
  border-radius: 0;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--text);
}

.adm input:focus-visible,
.adm select:focus-visible {
  outline: var(--line) solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}

.actions { display: flex; gap: 0.5rem; margin: 0.4rem 0 0; }

/* Slim on purpose — this page has a lot of buttons per row (Search, Save,
   Remove, Sign out...) and the shared site's 0.5rem vertical padding reads as
   puffy repeated that often. .search.toolbar button below matches the same
   number so the Search button doesn't stand out taller than the rest. */
.adm button {
  padding: 0.32rem 1rem;
  background: var(--accent);
  border: var(--hair) solid var(--accent);
  border-radius: 0;
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--surface);
  cursor: pointer;
}

.search.toolbar button { padding: 0.32rem 1rem; }

.adm button:hover { background: var(--accent-2); border-color: var(--accent-2); }
.adm button:focus-visible { outline: var(--line) solid var(--accent); outline-offset: 2px; }

/* Destructive, and it does not ask twice — the one control on the page
   allowed to use --alert, otherwise reserved for failure states. */
.adm button.danger {
  background: transparent;
  border-color: var(--edge-2);
  color: var(--alert);
  font-weight: 500;
}

.adm button.danger:hover { background: var(--alert); border-color: var(--alert); color: var(--surface); }

.adm.out button {
  padding: 0.2rem 0.7rem;
  font-size: 0.82rem;
  background: transparent;
  border-color: var(--edge-2);
  color: var(--text-2);
}

.adm.out button:hover { background: var(--surface); border-color: var(--accent); color: var(--accent); }

/* --- FACET FIELDS --------------------------------------------------------
 *
 * One <fieldset> per tag category on the add/edit forms — radios for the
 * four single-select facets, checkboxes for the three multi-select ones,
 * plus a free-text "add a new one" field shared by both. */

.facetfield {
  margin: 0 0 0.9rem;
  padding: 0.7rem 0.8rem;
  background: var(--surface);
  border: var(--hair) solid var(--edge-2);
}

/* A grid rather than relying on inline wrapping: several options share a row
   on purpose (Branch has 29; Sports/Leisure/Fitness are meant to grow), and a
   grid guarantees that instead of leaving it to how wide each label happens
   to be. minmax(9rem, 1fr) is the same column rule assets.123drg.com uses for
   its own long checkbox list. */
.factboxes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: 0.15rem 0.6rem;
}

.factbox {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  margin: 0;
  padding: 0.1rem 0;
  font-size: 0.88rem;
  font-weight: 400;
  color: var(--text);
  text-transform: none;
  letter-spacing: normal;
}

.factbox input { width: auto; }

.newval { margin-top: 0.4rem; }

/* --- MESSAGES ------------------------------------------------------------ */

.msg {
  max-width: 62rem;
  margin: 1.2rem auto 0;
  padding: 0.7rem 0.9rem;
  background: var(--surface);
  border-left: var(--line) solid var(--edge-2);
  font-size: 0.95rem;
}

.msg-ok  { border-left-color: var(--ok); }
.msg-bad { border-left-color: var(--alert); }

/* --- ROSTER --------------------------------------------------------------
 *
 * .rows/.row already exist on the public site's tables; .cmrows/.cmcard are
 * this page's own, since a roster entry has no counterpart there. */

.cmrows { list-style: none; margin: 0; padding: 0; }

.cmcard {
  padding: 1rem 0 1.2rem 0.9rem;
  border-top: var(--hair) solid var(--edge);
  border-left: var(--line) solid var(--edge-2);
}

.cmcard:last-child { border-bottom: var(--hair) solid var(--edge); }

.cmname { margin: 0 0 0.2rem; font-weight: 700; font-size: 1.05rem; }

.cmcontacts { margin: 0 0 0.3rem; }

.cmcontact {
  display: inline-block;
  margin-right: 0.9rem;
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--text-2);
}

.cmfacets {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 1.2rem;
  margin: 0 0 0.4rem;
}

.cmfacet { font-size: 0.82rem; color: var(--text-2); }

.cmfacet b {
  margin-right: 0.35rem;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--accent-2);
}

/* The only link on a roster card. It goes to a dedicated page (server.ts's
   editPage) rather than unfolding in place, and it is drawn as small text
   rather than a button: it repeats on every card in a long roster, where a
   bordered control per entry reads as the page's main action instead of the
   afterthought it is. The visible word is just "Edit" — the link carries an
   aria-label naming the classmate, since a screen reader listing the page's
   links would otherwise get a column of identical "Edit". */
.editlink {
  display: inline-block;
  margin-top: 0.35rem;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text-2);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.editlink:hover { color: var(--accent); }
.editlink:focus-visible { outline: var(--line) solid var(--accent); outline-offset: 2px; }
