/* Styles for the dynamic pages: performance tables, captain's area, forms */

/* The browser's own rule for the `hidden` attribute is display:none at the
   lowest possible priority, so ANY class that sets display beats it — and
   `.field { display:flex }` below does exactly that. The result is a box
   marked hidden that stays on screen, which is the sort of bug that looks
   like broken JavaScript and isn't. This puts it back where it belongs. */
[hidden] { display: none !important; }

/* ---------------------------------------------------------- Alerts */
.alert {
  padding: 14px 18px;
  border-radius: var(--radius);
  margin-bottom: 20px;
  border: 1px solid;
  font-size: 0.95rem;
}
.alert-success { background: #eaf5ee; border-color: #b6ddc4; color: #1c5330; }
.alert-error   { background: #fbeceb; border-color: #efc0bc; color: #8a2b22; }
.alert-warning { background: #fdf5e3; border-color: #e6d4a3; color: #7a5c11; }
/* Neither good news nor bad: "this is not available yet, and here is why". */
.alert-info    { background: #eef3f9; border-color: #c2d4e8; color: #23496f; }

/* ---------------------------------------------------------- Badges */
.badge {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  white-space: nowrap;
}
.badge-win     { background: #dff2e5; color: #1a5c34; }
.badge-loss    { background: #fbe4e2; color: #8a2b22; }
.badge-draw    { background: #eee9dc; color: #6b5b2c; }
.badge-due     { background: #fdecc8; color: #7a5c11; }
.badge-junior  { background: #e6edf8; color: #123c78; }
.badge-pending { background: #ece9e2; color: #5c5c56; }

/*
 * A match result in a table: score, then an outcome badge.
 *
 * Laid out rather than left to inline flow, which had three faults. The
 * badge is a different font size to the score, so sitting on a shared
 * baseline it rode about 2px low. There was no gap at all between them —
 * only collapsed whitespace. And because "1-0" is narrower than "1½-½",
 * the badges started at a different place on every row, so a column of
 * results looked ragged.
 *
 * The score gets a fixed minimum width in ems and lining figures, so the
 * badges line up down the column whatever the score.
 */
.result-cell {
  /*
   * inline-flex, not flex. A flex block fills the cell and packs its
   * contents to the left, which quietly cancelled the right-alignment of
   * the numeric Score columns and left the badges at a different
   * distance from the edge on every row. Inline-flex shrinks to its
   * contents, so the cell's own alignment still decides where the group
   * sits.
   */
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  gap: 8px;
  white-space: nowrap;
}
.result-cell .score {
  min-width: 4.2em;
  font-variant-numeric: tabular-nums;
}
/* The asterisk marking an adjusted score sits with the badge, not adrift. */
.result-cell .adjusted-mark { color: var(--ink-soft); cursor: help; }

/* ------------------------------------------------------ Stat tiles */
.stat-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
  margin-bottom: 32px;
}
.stat {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 20px;
  box-shadow: var(--shadow-sm);
}
.stat .value {
  font-family: "Merriweather", Georgia, serif;
  font-size: 2rem;
  color: var(--navy-800);
  line-height: 1.1;
}
.stat .label {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  font-weight: 700;
  margin-top: 6px;
}

/* ---------------------------------------------------------- Tables */
.table-compact tbody td, .table-compact tbody th { padding: 9px 14px; }
.num { text-align: right; font-variant-numeric: tabular-nums; }
.score-cell { font-weight: 700; font-variant-numeric: tabular-nums; }
table th.num, table td.num { text-align: right; }

.board-no {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px; height: 26px;
  border-radius: 6px;
  background: var(--navy-800);
  color: #fff;
  font-weight: 700;
  font-size: 0.8rem;
}
.colour-dot {
  display: inline-block;
  width: 13px; height: 13px;
  border-radius: 50%;
  border: 1px solid var(--navy-800);
  vertical-align: -1px;
  margin-right: 6px;
}
.colour-w { background: #fff; }
.colour-b { background: var(--navy-900); }

/* ----------------------------------------------------------- Forms */
.form-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 18px;
}
.field { display: flex; flex-direction: column; }
.field.full { grid-column: 1 / -1; }
.field label {
  font-weight: 700;
  font-size: 0.85rem;
  margin-bottom: 6px;
  color: var(--navy-900);
}
.field .hint { font-size: 0.8rem; color: var(--ink-soft); margin-top: 4px; }
/* Every input type the site uses. A type missing from this list is not
   styled at all and shows as a bare browser box half the height of the
   ones beside it — which is how the phone field on the enquiry form
   ended up looking broken. Add the type here when adding a field. */
input[type=text], input[type=email], input[type=password], input[type=date],
input[type=time], input[type=number], input[type=tel], input[type=url],
input[type=search], select, textarea {
  font: inherit;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  color: var(--ink);
  width: 100%;
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--gold);
  outline-offset: 1px;
  border-color: var(--gold);
}
textarea { min-height: 110px; resize: vertical; }
.form-actions {
  margin-top: 24px;
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}

/* --------------------------------------------------- Login screen */
.login-wrap {
  max-width: 420px;
  margin: 60px auto;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 32px;
  box-shadow: var(--shadow);
}
.login-wrap h1 { font-size: 1.5rem; }

/* ------------------------------------------------- Selection rows */
.pick-row {
  display: grid;
  grid-template-columns: 46px 1fr 130px 110px;
  gap: 12px;
  align-items: center;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  margin-bottom: 10px;
}
.pick-row .who { display: flex; flex-direction: column; gap: 3px; }
.pick-row .who small { color: var(--ink-soft); }

/*
 * Our player reads name-over-rating, matching the opponent's two stacked
 * boxes across the row. Side by side, a rating on the same line as the
 * name was easy to mistake for the box beside it.
 *
 * The measurements are the opponent inputs', not approximations of them:
 * each box is 48px tall with a 6px gap, so each line here is given the
 * same height and gap and the two columns sit on the same baselines.
 * The rating matches the boxes' 16px too — at 13px it read as a footnote
 * beside a figure of the same kind.
 */
.result-row .who { display: flex; flex-direction: column; gap: 6px; }
.result-row .who > strong,
.result-row .who > small {
  display: flex;
  align-items: center;
  min-height: 48px;
  font-size: 1rem;
}
/* Still quieter than the name: it is a reference, not the headline. */
.result-row .who > small { color: var(--ink-soft); }

/*
 * Column headings above the result rows. Shares the row's grid so the
 * labels line up with the boxes they describe rather than approximately.
 */
.result-head {
  display: grid;
  grid-template-columns: 46px minmax(150px, 0.9fr) minmax(220px, 1.3fr) 200px;
  gap: 12px;
  max-width: 1040px;
  padding: 0 12px 6px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.result-head span { font-weight: 400; text-transform: none; letter-spacing: 0; }

.result-row {
  display: grid;
  /*
   * Board, player, opponent, result.
   *
   * The player column is bounded rather than a plain fraction: a short
   * label like "Board defaulted" left a fraction-sized column mostly
   * empty, pushing the opponent fields far to the right on a wide
   * screen. The result column was a fixed 150px, which cut off "Not
   * played yet" — the one option a captain sees before they touch
   * anything. Both are sized to their content now.
   */
  grid-template-columns: 46px minmax(150px, 0.9fr) minmax(220px, 1.3fr) 200px;
  gap: 12px;
  align-items: center;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  margin-bottom: 10px;
  /* Stops the row stretching the width of a large monitor, which puts
     the result dropdown an inch from the player it belongs to. */
  max-width: 1040px;
}

.filter-bar {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  flex-wrap: wrap;
  margin-bottom: 28px;
  padding: 18px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.filter-bar .field { min-width: 190px; }

.subnav {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 28px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 12px;
}
.subnav a {
  padding: 8px 14px;
  border-radius: 8px;
  font-weight: 600;
  font-size: 0.92rem;
}
.subnav a.active { background: var(--navy-800); color: #fff; }

.empty-state {
  text-align: center;
  padding: 48px 24px;
  background: #fff;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  color: var(--ink-soft);
}

@media (max-width: 880px) {
  .stat-row { grid-template-columns: repeat(2, 1fr); }
  .form-grid { grid-template-columns: 1fr; }
  .pick-row, .result-row { grid-template-columns: 40px 1fr; row-gap: 10px; }
  .result-row select { width: 100%; }
  .result-head { display: none; }
}

/* ============================================================
   Editable page text
   ============================================================ */

/* Bar shown to signed-in admins at the top of a public page. */
.edit-bar {
  background: var(--navy-900);
  color: #fff;
  font-size: 0.88rem;
  padding: 9px 0;
}
.edit-bar .container {
  display: flex;
  gap: 14px;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}
.edit-bar a { color: var(--gold-light); font-weight: 700; }

/* An editable region, with its pencil link tucked into the corner.
   Only ever rendered for signed-in administrators, so visitors see
   no trace of it. */
.editable { position: relative; }
.editable > .editable-pin {
  position: absolute;
  top: -10px;
  right: -6px;
  z-index: 5;
  background: var(--gold);
  color: var(--navy-900);
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1;
  padding: 5px 9px;
  border-radius: 6px;
  box-shadow: var(--shadow-sm);
  opacity: 0;
  transition: opacity .12s ease-in-out;
  white-space: nowrap;
  max-width: 60%;
  overflow: hidden;
  text-overflow: ellipsis;
}
.editable:hover > .editable-pin,
.editable > .editable-pin:focus { opacity: 1; }
.editable:hover { outline: 2px dashed rgba(255, 190, 0, .75); outline-offset: 6px; }

@media (max-width: 700px) {
  /* No hover on a touchscreen, so the pin has to be permanently visible. */
  .editable > .editable-pin { opacity: 1; position: static; display: inline-block; margin-bottom: 8px; }
  .editable:hover { outline: none; }
}

/* ---------------------------------------------- the editor itself */
.editor-toolbar {
  display: flex;
  gap: 4px;
  align-items: center;
  flex-wrap: wrap;
  padding: 8px;
  background: var(--cream-dark);
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: 8px 8px 0 0;
}
.editor-toolbar button {
  font: inherit;
  font-size: 0.85rem;
  padding: 6px 11px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: pointer;
  color: var(--ink);
}
.editor-toolbar button:hover { background: var(--navy-900); color: #fff; border-color: var(--navy-900); }
.editor-toolbar .sep { width: 1px; height: 22px; background: var(--line); margin: 0 4px; }
.editor-toolbar .right { margin-left: auto; }

.editor-area {
  width: 100%;
  min-height: 260px;
  max-height: 60vh;
  overflow-y: auto;
  padding: 18px 20px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 0 0 8px 8px;
  line-height: 1.65;
}
.editor-area:focus { outline: 2px solid var(--navy-600); outline-offset: -2px; }
.editor-area h2 { font-size: 1.25rem; margin: 1.1em 0 .4em; }
.editor-area h3 { font-size: 1.05rem; margin: 1em 0 .35em; }
.editor-area p  { margin: 0 0 .8em; }
.editor-area ul, .editor-area ol { margin: 0 0 .8em 1.3em; }
.editor-area table { width: 100%; border-collapse: collapse; margin: .6em 0; }
.editor-area th, .editor-area td { border: 1px solid var(--line); padding: 6px 9px; text-align: left; }

/* ============================================================
   Social links
   ============================================================ */

.social-row { display: flex; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.social-row a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .12);
  color: #fff;
  transition: background .12s ease-in-out, color .12s ease-in-out;
}
.social-row a:hover, .social-row a:focus {
  background: var(--gold);
  color: var(--navy-900);
}

.social-list { list-style: none; margin: 0; padding: 0; }
.social-list li { margin-bottom: 8px; }
.social-list a {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-weight: 600;
  color: var(--navy-700);
}
.social-list a:hover { color: var(--navy-900); }

/* The footer grew a fourth column when resource pages were added. */
.footer-grid { grid-template-columns: 1.7fr 1fr 1fr 1fr; }
@media (max-width: 880px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 520px) {
  .footer-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   Embedded chess boards
   ============================================================ */

/* Third-party boards come with fixed pixel sizes that overflow a phone.
   The wrapper lets them scroll rather than pushing the page sideways. */
.prose iframe {
  max-width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
  display: block;
}
.prose .table-wrap {
  overflow-x: auto;
  /* Without the max-width the wrapper grows to fit its contents and
     the whole page ends up scrolling sideways on a phone, which is
     the thing the wrapper exists to prevent. */
  max-width: 100%;
}

/* ------------------------------------------------------------------
   Sizing the third-party boards.
   
   The width and height attributes on these embeds came from the old
   site and are too small for what the widgets now draw — the result
   is a board with scrollbars round it. CSS overrides those attributes,
   so the sizes can be corrected here without touching the page text.
   
   Generous rather than exact: whitespace inside the frame is invisible,
   whereas a few pixels short produces scrollbars.
   ------------------------------------------------------------------ */

/* Shredder's daily tactics. Measured rather than guessed: the board is
   eight 41px squares (328px), and the widget box round it — coordinates,
   prompt, hint, and the two rows of buttons — is 380 x 420. Add the 8px
   margin a browser puts round any page body, and a little slack so one
   stray pixel doesn't bring the scrollbars back. */
.prose iframe[src*="shredderchess"] {
  width: 400px;
  height: 440px;
  max-width: 100%;
  border: 0;
}

/* The Fritz board is drawn at 800 x 500 and does not reflow, so it is
   scaled to whatever room the column has. */
.prose iframe[src*="chessbase"] {
  width: 100%;
  max-width: 820px;
  height: 520px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

@media (max-width: 560px) {
  /* On a phone, let the wrapper scroll rather than squeezing the board
     into something unusable. */
  .prose iframe[src*="shredderchess"] { max-width: none; }
  .prose iframe[src*="chessbase"]     { height: 420px; }
}

/* A grid column sizes itself to its widest child by default, so one wide
   embed stretched the whole text column — and with it the page — beyond
   the screen. min-width:0 lets the column be narrower than its contents,
   which is what allows the wrapper above to do the scrolling instead. */
.content-columns > *,
.prose,
.sidebar { min-width: 0; }

/* ------------------------------------------- the enquiry form's wording
   These paragraphs come from editable blocks now, so the styling lives
   here rather than as inline styles the editor would strip. */
.enquiry-aside ol        { padding-left: 1.1em; margin-bottom: 18px; }
.enquiry-aside small,
.enquiry-footnote small  { color: var(--ink-soft); }
.enquiry-aside p         { font-size: 0.92rem; }
.enquiry-aside p:last-child { margin-bottom: 0; }
.enquiry-footnote        { margin-top: 14px; }
.enquiry-footnote p      { margin: 0; }

/* The QR card centres its image but not its wording. The text comes from
   an editable block now, so the alignment lives here rather than as
   inline styles the content editor would strip out. */
.side-qr          { text-align: center; }
.side-qr h3,
.side-qr p        { text-align: left; }
.side-qr small    { color: var(--ink-soft); }
.side-qr img      { margin: 0 auto; }

/* Note panels and sidebar cards whose wording is now editable: the last
   paragraph should not push the card open at the bottom. */
.note-panel > p:last-child,
.sidebar .card > p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------- form errors
 * A box the server has rejected, and the message that says why. The
 * colour is the same red as .alert-error so the summary at the top of
 * the page and the message beside the box read as one thing.
 */
.field-error {
  display: block;
  margin-top: 6px;
  color: #8a2b22;
  font-weight: 600;
}
[aria-invalid="true"] {
  border-color: #c0392b !important;
  background: #fdf6f5;
}
[aria-invalid="true"]:focus {
  outline: 2px solid #c0392b;
  outline-offset: 1px;
}

/* The running count of what is still missing, beside the Send button. */
.still-todo {
  margin-left: 14px;
  color: #8a2b22;
  font-weight: 600;
  font-size: 0.92rem;
}
.still-todo:empty { display: none; }

/* A button that has to sit inside a table cell without dominating it. */
.btn-small {
  padding: 4px 10px;
  font-size: 0.82rem;
}

/* ------------------------------------------------- Enquiry filter bar
 * A count beside each state, so "is there anything to do?" is answered
 * by looking rather than by clicking through all seven.
 *
 * TWO SIGNALS, TWO DEVICES. Weight says "something is waiting for you
 * here"; the underline says "this is what you are looking at". Using
 * bold for both would leave neither readable.
 */
.enquiry-filters a { text-decoration: none; }
.enquiry-filters a:hover { text-decoration: underline; }

/* Where you are. */
.enquiry-filters a.on {
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 2px;
}

/* Somebody at the club has to do something about these. */
.enquiry-filters a.needs { font-weight: 700; }

.enquiry-filters .tally {
  display: inline-block;
  min-width: 1.35em;
  padding: 1px 6px;
  border-radius: 10px;
  background: #e8eef6;
  color: #23496f;
  font-size: 0.82rem;
  font-weight: 600;
  text-align: center;
  line-height: 1.5;
}
/* Waiting on us: the one colour on the bar that is meant to catch you. */
.enquiry-filters .tally.waiting {
  background: #fdecc8;
  color: #7a5c11;
}
/* Nothing there: still shown, but it should not draw the eye. */
.enquiry-filters .tally.none {
  background: transparent;
  color: var(--ink-soft, #6b6b63);
  font-weight: 400;
}

/* ------------------------------------------------------- Progress bar
 * Used by the ECF update, which is the one thing on this site slow
 * enough to need telling the reader it is still alive.
 */
.ecf-bar {
  height: 10px;
  border-radius: 6px;
  background: #e8eef6;
  overflow: hidden;
}
.ecf-bar-fill {
  height: 100%;
  width: 0;
  border-radius: 6px;
  background: var(--gold, #c9a227);
  transition: width .25s ease;
}
/* Finished cleanly: the same green the site uses for a win. */
.ecf-bar-fill.is-done    { background: #2f7d4f; }
/* Finished, but something needs looking at. Not green. */
.ecf-bar-fill.is-partial { background: #b8860b; }

/* ------------------------------------------- Warning in a table header
 * "There is something in this column that needs you." Sits in the
 * heading because that is what the eye passes over on the way to
 * something else, and it is a link because a warning you cannot act on
 * is only decoration.
 */
.th-warn {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 7px;
  border-radius: 10px;
  background: #fdecc8;
  color: #7a5c11;
  font-size: 0.78rem;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.th-warn:hover { background: #f7dda0; text-decoration: none; }

/* ------------------------------------------------------------------ panes
 * A panel that folds away.
 *
 * Used for the parts of the members screen that are set up once and
 * then rarely touched — the monthly ECF schedule, the add-a-member
 * form — so that the things looked at every visit are not pushed below
 * the fold by the things looked at once a year.
 *
 * Built on <details>, so it works with JavaScript switched off, the
 * browser's own find-on-page can still reach inside it, and it prints
 * expanded.
 */
.pane > summary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 12px;
  cursor: pointer;
  list-style: none;          /* Firefox's default triangle */
  font-family: var(--font-head, inherit);
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.3;
  padding-left: 22px;
  position: relative;
}
.pane > summary::-webkit-details-marker { display: none; }

/* Our own marker, so it sits on the baseline of the title rather than
   wherever the browser feels like putting it. */
.pane > summary::before {
  content: '';
  position: absolute;
  left: 2px;
  top: 0.45em;
  width: 0;
  height: 0;
  border-left: 6px solid currentColor;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  opacity: 0.55;
  transition: transform 0.12s ease;
  transform-origin: 25% 50%;
}
.pane[open] > summary::before { transform: rotate(90deg); }

.pane > summary:hover::before { opacity: 0.9; }
.pane > summary:focus-visible {
  outline: 2px solid var(--gold, #b8860b);
  outline-offset: 3px;
  border-radius: 3px;
}

/* The state of the thing, said on the closed summary, so you can tell
   whether it is worth opening without opening it. */
.pane-note {
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 400;
  color: var(--ink-soft, #666);
}

.pane[open] > summary { margin-bottom: 14px; }

/*
 * A folded pane is a heading, not an empty card. The card's 34px of
 * padding is right for a panel with contents in it and leaves a closed
 * one looking like a box somebody forgot to fill.
 */
.pane.card:not([open]) { padding-top: 22px; padding-bottom: 22px; }

@media print {
  .pane > summary::before { display: none; }
}

/* ------------------------------------------------- register toolbar
 * The row of things you can do to the member register, and the line of
 * facts under it. Sits directly above the filter tabs and the table, so
 * the whole block reads as one thing.
 */
.register-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin: 0 0 10px;
}
.register-tools .btn {
  width: auto;
  padding: 8px 16px;
  font-size: 0.85rem;
}
.register-tools form { margin: 0; }

.register-status {
  margin: 0 0 16px;
  font-size: 0.85rem;
  color: var(--ink-soft);
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  align-items: baseline;
}
.register-status .sep { opacity: 0.4; }

/* The same triangle-and-amber as the warning on a column heading, so
   every "a person needs to look at this" marker on the screen matches. */
.register-status .warn {
  background: #fdecc8;
  color: #7a5c11;
  border-radius: 10px;
  padding: 1px 9px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.register-status .warn:hover { background: #f7dda0; text-decoration: none; }

/* --------------------------------------------- sticky table headings
 * On a register of fifty the headings scroll away after a dozen rows
 * and the columns stop meaning anything.
 *
 * TWO THINGS ARE IN THE WAY, BOTH THERE FOR GOOD REASONS
 *
 * 1. table { overflow: hidden } exists to clip the table's rounded
 *    corners. But an element with overflow:hidden is a scroll
 *    container, and a sticky heading inside one sticks to THAT rather
 *    than to the page - which is to say, it does nothing at all.
 *    overflow:clip clips the corners identically without creating one.
 *
 * 2. .table-wrap { overflow-x: auto } is what stops a wide table
 *    dragging the whole page sideways on a phone. There is no way to
 *    keep that and have a sticky heading: when one axis scrolls, the
 *    other computes to hidden whatever you ask for.
 *
 * So the heading sticks only on screens wide enough not to need the
 * sideways scroll in the first place. On a phone the table behaves
 * exactly as it did. Nothing is lost anywhere; it is simply better on
 * the screens where it can be.
 */
@media (min-width: 1024px) {
  .sticky-head .table-wrap { overflow-x: visible; }
  .sticky-head table { overflow: clip; }
  .sticky-head thead th {
    position: sticky;
    /* Clear of the site header, which is itself sticky and would
       otherwise sit on top of the headings. */
    top: var(--stick-top, 72px);
    z-index: 5;
    /* So the rows passing underneath read as passing underneath, rather
       than as a row that has gone wrong. */
    box-shadow: 0 3px 6px rgba(8, 35, 74, 0.22);
  }
}

/* ------------------------------------------------- register search
 * Sits with the filter tabs rather than the button row: it is another
 * way of choosing which members you are looking at.
 */
.register-search {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin: 0 0 14px;
}
.register-search input[type="search"] {
  flex: 1 1 320px;
  min-width: 0;
  max-width: 460px;
  margin: 0;
}
.register-search .btn {
  width: auto;
  padding: 8px 16px;
  font-size: 0.85rem;
}

/* For a label that a screen reader should read out but that would be
   clutter on screen, the search box having a placeholder already. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------- the register's filter row
 * The same pills as .subnav, but this row carries nine of them and was
 * wrapping onto a second line with a single orphaned tab on it, which
 * looked like a mistake rather than a layout.
 *
 * So: tighter, and it scrolls sideways rather than wrapping. A row that
 * runs off the edge reads as "there is more this way"; a row that wraps
 * to one lonely item reads as broken. On any normal screen all nine now
 * fit on the one line anyway.
 */
.subnav.register-filters {
  flex-wrap: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
  gap: 2px;
  margin-bottom: 18px;
  padding-bottom: 10px;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}
.subnav.register-filters a {
  padding: 7px 10px;
  font-size: 0.85rem;
  white-space: nowrap;
  flex: 0 0 auto;
}
/* A scrollbar only when there is something to scroll to. */
.subnav.register-filters::-webkit-scrollbar { height: 6px; }
.subnav.register-filters::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: 3px;
}


/* A badge for adults, to pair with the junior one.
 *
 * Brown rather than another blue, so the two read as two states of one
 * thing rather than two unrelated flags - and so the junior badge keeps
 * the only cool colour in the column, which is the one worth spotting.
 *
 * 7:1 against its background, comfortably past the 4.5:1 that text this
 * size needs, because a badge nobody can read is just a coloured box.
 */
.badge-adult { background: #eee4d5; color: #5f4522; }

/* --------------------------------------------- the dashboard activity log
 * Full width and scrolling, rather than a narrow column where every entry
 * wrapped onto four lines. The height shows about eight rows: enough to
 * see today without the dashboard turning into a log viewer.
 */
.activity-scroll {
  /* About eight entries. Enough to see today without the dashboard
     turning into a log viewer; the rest are a scroll away. */
  max-height: 360px;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 8px;
}
/* Each entry is a small block rather than a table row: what happened in
 * bold, what it was underneath in grey, and who and when set quietly to
 * the right. Hairlines between, nothing around the outside - the card
 * already provides that.
 */
.log-entry {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 18px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
}
.log-entry:last-child { border-bottom: 0; }
.log-main strong { font-size: 0.92rem; }
.log-main .detail {
  color: var(--ink-soft);
  font-size: 0.88rem;
  margin-top: 2px;
}
.log-meta {
  color: var(--ink-soft);
  font-size: 0.82rem;
  white-space: nowrap;
  text-align: right;
}

@media (max-width: 560px) {
  /* No room for two columns on a phone - let who and when drop under. */
  .log-entry { display: block; }
  .log-meta { text-align: left; margin-top: 3px; }
}

/* The scrollbar only appears when there is something to scroll to. */
.activity-scroll::-webkit-scrollbar { width: 8px; }
.activity-scroll::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: 4px;
}


/* ------------------------------------------- the foot of the dashboard
 * Enquiries and Quick links side by side under the log. Equal columns,
 * a real gap between them, and one below each other on a narrow screen.
 */
.dash-cards {
  display: grid;
  gap: 24px;
  grid-template-columns: 1fr;
  margin-top: 44px;
  align-items: start;
}
.dash-cards > .card { margin-bottom: 0; }

@media (min-width: 760px) {
  .dash-cards { grid-template-columns: 1fr 1fr; }
}

/* A count against a label - the enquiry states, and anything else that
   turns out to want the same shape. */
.dash-tally td { font-size: 0.9rem; }
.dash-tally td.n { text-align: right; width: 1%; white-space: nowrap; }
.dash-tally tr.total td { font-weight: 700; }
.dash-tally a { text-decoration: none; }
.dash-tally a:hover { text-decoration: underline; }
