/* RGS Guildford — Veracross Additions
 *
 * Palette and typefaces come from the school's own artwork and are not
 * design choices to revisit casually. What this file does own: layout
 * width, form controls, and focus.
 *
 * Two widths on purpose. Staff assembling a form are at a desk with a
 * keyboard and want to see the whole thing; a parent answering a medical
 * question is on a phone, and a 100-character line is harder to read, not
 * easier. .wrap stays narrow for anything a parent sees. .wrap--wide is
 * for staff screens only.
 */

:root {
  --rgs-green: #113D2A;
  --rgs-green-dark: #0B2A1D;
  --rgs-red: #C8192B;
  --rgs-gold: #D0AE6F;
  --rgs-paper: #FBF8F3;
  --rgs-paper-warm: #F2EDE0;
  --rgs-rule: #D9D2C2;
  --rgs-ink: #1A1A1A;
  --rgs-ink-soft: #4A4A4A;

  /* Added for form controls, which previously had none. */
  --rgs-field-border: #C4BCA8;
  --rgs-field-bg: #fff;
  --rgs-wash: #EFF2F0;
  --rgs-danger-wash: #FCEFF1;

  --font-heading: "Fraunces", Georgia, "Times New Roman", serif;
  --font-body: "Inter Tight", system-ui, -apple-system, "Segoe UI", sans-serif;

  --step-0: 1rem;
  --step-1: 1.125rem;
  --step-2: 1.375rem;
  --step-3: 1.75rem;
  --step-4: 2.25rem;

  --radius: 5px;
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.55;
  color: var(--rgs-ink);
  background: var(--rgs-paper);
  -webkit-text-size-adjust: 100%;
}

/* The signature tricolour stripe, matching the staff guides. */
body::before {
  content: "";
  position: fixed;
  inset: 0 0 auto 0;
  height: 5px;
  background: linear-gradient(
    90deg,
    var(--rgs-green) 0 55%,
    var(--rgs-gold) 55% 75%,
    var(--rgs-red) 75% 100%
  );
  /* Decorative only — never intercept taps, even flush to the viewport top. */
  pointer-events: none;
  /* Below any conventionally-stacked overlay or modal, so a future dialog
     doesn't render underneath the stripe. */
  z-index: 10;
}

h1, h2 {
  font-family: var(--font-heading);
  color: var(--rgs-green);
  letter-spacing: -0.01em;
  line-height: 1.15;
  margin: 0 0 0.5rem;
}
h1 { font-size: var(--step-4); font-weight: 600; }
h2 { font-size: var(--step-2); font-weight: 600; margin-top: 2.5rem; }

/* h3 deliberately in the body face: the serif stays reserved for the two
   levels that actually structure a page, so it keeps its weight. */
h3 {
  font-family: var(--font-body);
  font-size: var(--step-1);
  font-weight: 600;
  color: var(--rgs-ink);
  margin: 0 0 0.25rem;
}

p { margin: 0 0 1rem; max-width: 66ch; }

a { color: var(--rgs-green); text-underline-offset: 2px; }
a:hover { color: var(--rgs-red); }

/* Nothing in this service had a focus style. Keyboard users had to guess
   where they were. Gold because it reads on both the paper background and
   the green buttons. */
:focus-visible {
  outline: 3px solid var(--rgs-gold);
  outline-offset: 2px;
  border-radius: 2px;
}

/* ---------- Shell ---------- */

.site-header {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
  padding: 1.25rem 1rem 1rem;
  border-bottom: 1px solid var(--rgs-rule);
  background: #fff;
}
.site-header img { height: 44px; width: auto; }
.site-header .site-name {
  font-family: var(--font-heading);
  font-size: var(--step-1);
  color: var(--rgs-green);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  margin-left: auto;
  font-size: 0.95rem;
}
.site-nav .sign-out { margin: 0; }

/* A form's submit button styled to read as a nav link, not a button —
   sign-out must be a POST (see core/auth/views.py:logout) but must not
   look out of place next to the plain <a> links either side of it. */
.link-button {
  font: inherit;
  color: var(--rgs-green);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.link-button:hover { color: var(--rgs-red); }

/* Mobile first: a parent completing a consent form is on a phone. */
.wrap {
  width: 100%;
  max-width: 44rem;
  margin: 0 auto;
  padding: 1.5rem 1rem 4rem;
}
/* Staff screens only — see the note at the top of this file. */
.wrap--wide { max-width: 76rem; }
/* For the two staff pages that are a wide table and nothing else: the
   responses grid and the audit log. A table with a column per question
   is unreadable inside a measure meant for prose, and horizontal
   scrolling inside .table-scroll is what a person does instead of
   reading. Still keeps the side gutter. */
.wrap--full { max-width: none; }

.site-footer {
  padding: 1.5rem 1rem;
  border-top: 1px solid var(--rgs-rule);
  background: var(--rgs-paper-warm);
  color: var(--rgs-ink-soft);
  font-size: 0.9rem;
}

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

ul.messages { list-style: none; margin: 0 0 1.75rem; padding: 0; }
.message {
  padding: 0.9rem 1.1rem;
  margin: 0 0 0.75rem;
  background: #fff;
  border: 1px solid var(--rgs-rule);
  border-left: 4px solid var(--rgs-green);
  border-radius: var(--radius);
}
.message--error { border-left-color: var(--rgs-red); background: var(--rgs-danger-wash); }
.message--warning { border-left-color: var(--rgs-gold); background: #FCF6E9; }

/* ---------- Page heading ---------- */

.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.75rem 1.25rem;
  margin-bottom: 1.75rem;
  padding-bottom: 1rem;
  border-bottom: 2px solid var(--rgs-green);
}
.page-head h1 { margin: 0; }
.page-head .page-head__aside { margin-left: auto; }

/* A form's state, shown as a word rather than a coloured pill: there are
   three states and they are not a severity scale. */
.state {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--rgs-ink-soft);
}
.state::before {
  content: "";
  display: inline-block;
  width: 0.55rem;
  height: 0.55rem;
  margin-right: 0.45rem;
  border-radius: 50%;
  background: currentColor;
  vertical-align: 0.05em;
}
.state--published { color: var(--rgs-green); }
.state--closed { color: var(--rgs-red); }

/* ---------- Apps ---------- */

/* The platform's front door. A grid rather than a stack because this
   holds one module today and is meant to hold several. */
ul.apps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1.25rem;
}
@media (min-width: 40rem) {
  ul.apps { grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr)); }
}
ul.apps a {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  height: 100%;
  padding: 1.5rem;
  background: #fff;
  border: 1px solid var(--rgs-rule);
  border-left: 4px solid var(--rgs-green);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--rgs-ink);
}
ul.apps a:hover { background: var(--rgs-wash); color: var(--rgs-ink); }
.apps__name {
  font-family: var(--font-heading);
  font-size: var(--step-2);
  font-weight: 600;
  color: var(--rgs-green);
}
.apps__what { color: var(--rgs-ink-soft); font-size: 0.9375rem; }

/* ---------- Builder tabs ---------- */

/* The four stages of building a form. Underline rather than a pill or a
   filled block: these are pages, and an underline is the convention a
   person already reads as "you are here" without it competing with the
   green headings above. */
.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.75rem;
  margin: 0 0 2rem;
  border-bottom: 1px solid var(--rgs-rule);
}
.tabs a {
  padding: 0.65rem 0.75rem 0.7rem;
  margin-bottom: -1px;
  border-bottom: 3px solid transparent;
  /* Not semibold: the current tab is the one that carries weight, and
     when every tab is bold none of them is. */
  color: var(--rgs-ink-soft);
  text-decoration: none;
  font-weight: 400;
  white-space: nowrap;
}
.tabs a:hover { color: var(--rgs-green); border-bottom-color: var(--rgs-rule); }
.tabs a[aria-current="page"] {
  color: var(--rgs-green);
  font-weight: 600;
  border-bottom-color: var(--rgs-green);
  background: var(--rgs-wash);
  border-radius: var(--radius) var(--radius) 0 0;
}
.tabs__count {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.05rem 0.4rem;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--rgs-ink-soft);
  background: var(--rgs-paper-warm);
  border-radius: 999px;
}
.tabs__new { margin-left: 0.3rem; font-size: 0.8em; opacity: 0.7; }
.tabs a[aria-current="page"] .tabs__count {
  color: #fff;
  background: var(--rgs-green);
}

/* ---------- Two-column staff layout ---------- */

.cols { display: grid; gap: 2rem; align-items: start; }
@media (min-width: 64rem) {
  .cols { grid-template-columns: minmax(0, 2fr) minmax(16rem, 1fr); gap: 3rem; }
}

/* A wide page whose content is one column rather than two. Held to a
   readable measure so the wide wrap does not stretch a form across a
   monitor. */
.single { max-width: 52rem; }

/* A .cols whose aside is absent this time -- the questions page only has
   a right-hand column once its questions are locked. Written after the
   media query above, and with both classes, so it wins whatever the
   viewport: an empty grid track reads as a layout that has gone wrong,
   not as a page with nothing to say there. */
.cols.cols--one { grid-template-columns: minmax(0, 1fr); max-width: 52rem; }

/* ---------- Add a question ---------- */

.addq {
  margin: 2rem 0 0;
  padding: 1.5rem;
  background: #fff;
  border: 1px solid var(--rgs-rule);
  border-radius: var(--radius);
}
.addq h2 { margin-top: 0; }

/* An option group that applies only to some answer types. Hidden by the
   script in staff_field_form.html; visible without it. */
.opt[hidden] { display: none; }

/* The answer type does not need the width of a question. */
.addq .field--half { max-width: 20rem; }

/* Lowest and highest belong side by side: they are one range. */
.two-up { display: grid; gap: 0 1.25rem; }
@media (min-width: 34rem) {
  .two-up { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .two-up .field { max-width: none; }
}

/* ---------- Cards and panels ---------- */

.card {
  background: #fff;
  border: 1px solid var(--rgs-rule);
  border-left: 4px solid var(--rgs-green);
  border-radius: var(--radius);
  padding: 1rem 1.25rem;
  margin: 0 0 1rem;
}
.card > :last-child { margin-bottom: 0; }

/* Secondary information beside a form — guidance, a link to copy, the
   state of things. Distinguished from .card by having no left rule, so
   the two never read as the same kind of object. */
.panel {
  background: var(--rgs-wash);
  border: 1px solid var(--rgs-rule);
  border-radius: var(--radius);
  padding: 1.25rem;
  margin: 0 0 1.25rem;
}
.panel > :last-child { margin-bottom: 0; }
.panel h3 { margin-bottom: 0.5rem; }
.panel p { font-size: 0.9375rem; max-width: none; }

/* A panel reporting something that needs attention rather than
   offering something. Gold, not red: the form is not broken, it is
   simply not open at the moment. */
.panel--warn { background: #FCF6E9; border-color: var(--rgs-gold); }

/* Somewhere to put the action you take once, at the end. Quieter
   than a panel offering something you do often. */
.panel--quiet { background: none; border-style: dashed; margin-top: 2.5rem; }

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

.field { margin: 0 0 1.5rem; max-width: 34rem; }
.field label,
.field > p > label { display: block; font-weight: 600; margin-bottom: 0.35rem; }

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="number"],
input[type="date"],
input[type="datetime-local"],
input[type="search"],
select,
textarea {
  width: 100%;
  font: inherit;
  color: var(--rgs-ink);
  background: var(--rgs-field-bg);
  border: 1px solid var(--rgs-field-border);
  border-radius: var(--radius);
  padding: 0.6rem 0.7rem;
  min-height: 44px;
}
textarea { min-height: 7rem; resize: vertical; line-height: 1.5; }
select { appearance: none; background-image: none; padding-right: 2rem; }

input:hover, select:hover, textarea:hover { border-color: var(--rgs-ink-soft); }
input:focus, select:focus, textarea:focus { border-color: var(--rgs-green); }

/* Django renders help_text in a span; the escaping of its content is
   handled at source in forms/field_types.py. */
.helptext,
.field .helptext {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.875rem;
  color: var(--rgs-ink-soft);
  max-width: 52ch;
}

.errorlist {
  margin: 0 0 0.5rem;
  padding: 0;
  list-style: none;
  color: var(--rgs-red);
  font-size: 0.9375rem;
  font-weight: 500;
}

/* Checkboxes and radios: the control beside its label, not above it, and
   the whole line clickable. */
.check {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  max-width: 52ch;
  margin: 0 0 0.75rem;
}
.check input { margin: 0.2rem 0 0; width: 1.1rem; height: 1.1rem; flex: none; }
.check label { font-weight: 400; margin: 0; }
ul.check-list { list-style: none; margin: 0; padding: 0; }
ul.check-list li { margin: 0 0 0.6rem; }
ul.check-list label { font-weight: 400; }
ul.check-list input { margin-right: 0.5rem; }

/* A group of radios or checkboxes. Horizontal, wrapping: two short
   options ("Yes" / "No") read as one question rather than a stack, and a
   longer list wraps onto as many lines as it needs instead of forcing a
   choice between cramped and endless.

   Django's RadioSelect and CheckboxSelectMultiple render an outer div of
   plain divs with no classes of their own, so these select on structure.
   Confirmed against the rendered markup rather than assumed. */
fieldset.choices {
  border: 0;
  padding: 0;
  margin: 0 0 1.5rem;
  min-width: 0;  /* a fieldset will not shrink below its content without this */
}
fieldset.choices legend {
  padding: 0;
  margin-bottom: 0.45rem;
  font-weight: 600;
}
fieldset.choices > div {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
}
fieldset.choices > div > div { margin: 0; }
fieldset.choices label {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;          /* a comfortable target on a phone */
  padding: 0.35rem 0.9rem 0.35rem 0.75rem;
  font-weight: 400;
  background: #fff;
  border: 1px solid var(--rgs-field-border);
  border-radius: 999px;
  cursor: pointer;
}
fieldset.choices label:hover { border-color: var(--rgs-ink-soft); }
fieldset.choices input { width: 1.05rem; height: 1.05rem; margin: 0; flex: none; }
/* :has is what lets the whole pill show the selection rather than just
   the small native control. Without support the control still shows it,
   so nothing is lost. */
fieldset.choices label:has(input:checked) {
  border-color: var(--rgs-green);
  box-shadow: inset 0 0 0 1px var(--rgs-green);
  font-weight: 600;
}
fieldset.choices label:has(input:focus-visible) {
  outline: 3px solid var(--rgs-gold);
  outline-offset: 2px;
}
fieldset.choices .helptext { margin-top: 0.5rem; }

/* ---------- Disclosure switch (scheduling) ---------- */

.switch {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.85rem 1rem;
  background: #fff;
  border: 1px solid var(--rgs-rule);
  border-radius: var(--radius);
  max-width: 34rem;
  cursor: pointer;
}
.switch--bare { background: none; border: 0; padding: 0; margin-bottom: 0.25rem; }
.switch input { width: 1.1rem; height: 1.1rem; margin: 0; flex: none; }
.switch span { font-weight: 600; }

/* Revealed by the switch. Collapsed by default so the page is honest with
   JavaScript off: without the script the fields are simply visible, which
   is the old behaviour rather than a broken one. */
.reveal { margin-top: 1.25rem; padding-left: 1rem; border-left: 2px solid var(--rgs-rule); }
.reveal[hidden] { display: none; }

/* ---------- Preview ---------- */

.preview-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  align-items: baseline;
  margin: 0 0 1.75rem;
  padding: 0.9rem 1.1rem;
  background: var(--rgs-green);
  color: #fff;
  border-radius: var(--radius);
}
.preview-bar p { margin: 0; max-width: none; }
.preview-bar a { color: var(--rgs-gold); }
.preview-bar a:hover { color: #fff; }
.preview-bar__back { margin-left: auto; font-size: 0.9375rem; }

/* The preview shows the parent's narrow column inside a staff page, so
   the fields read at the width a parent gets rather than the width this
   page happens to be. */
.preview-page { max-width: 44rem; }

/* The preview's fields are live: a member of staff fills them in to
   check the form behaves. Nothing is stored — see builder_views.preview. */

/* ---------- The parent's form ---------- */

/* Which child this is about. Set against the gold rather than the green
   because it is the one thing on the page a parent must not skim past,
   and green is already doing the work of every heading around it. */
.for-child {
  border-left: 4px solid var(--rgs-gold);
  background: #fff;
  border: 1px solid var(--rgs-rule);
  border-left: 4px solid var(--rgs-gold);
  border-radius: var(--radius);
  padding: 0.85rem 1.1rem;
  margin: 0 0 1.5rem;
}
.for-child p { margin: 0; }

/* Choosing between children. The whole row is the target: on a phone the
   name is what a parent aims at. */
ul.pick { list-style: none; margin: 0 0 1.5rem; padding: 0; }
ul.pick li { margin: 0 0 0.75rem; }
ul.pick a {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 1rem 1.15rem;
  min-height: 44px;
  background: #fff;
  border: 1px solid var(--rgs-rule);
  border-left: 4px solid var(--rgs-green);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--rgs-ink);
}
ul.pick a:hover { background: var(--rgs-wash); color: var(--rgs-ink); }
.pick__name { font-weight: 600; font-size: var(--step-1); color: var(--rgs-green); }
.pick__meta { font-size: 0.9375rem; color: var(--rgs-ink-soft); }

.intro {
  margin: 0 0 2rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--rgs-rule);
  color: var(--rgs-ink-soft);
}
.intro > :last-child { margin-bottom: 0; }

/* ---------- Colleague picker ---------- */

/* Built by script on the share page; absent without JavaScript, where
   the plain person-id box remains. The admin people page writes its own
   markup rather than building it, so both anchor the absolutely
   positioned ul.combo below. */
#staff-picker,
.staff-picker { position: relative; }

/* The admin people page's picker, above the list it adds to rather than
   in a panel beside it. Held to a readable measure: a search field the
   width of a six-column table is a search field that looks like a
   mistake. */
.staff-picker {
  max-width: 34rem;
  margin: 0 0 2rem;
}
.staff-picker input[type="search"] { width: 100%; }
ul.combo {
  list-style: none;
  margin: 0.25rem 0 0;
  padding: 0.25rem;
  background: #fff;
  border: 1px solid var(--rgs-field-border);
  border-radius: var(--radius);
  box-shadow: 0 6px 18px rgba(17, 61, 42, 0.12);
  position: absolute;
  left: 0;
  right: 0;
  z-index: 5;
}
ul.combo[hidden] { display: none; }
ul.combo li {
  padding: 0.5rem 0.6rem;
  border-radius: 3px;
  cursor: pointer;
  font-size: 0.9375rem;
}
ul.combo li[aria-selected="true"],
ul.combo li:hover { background: var(--rgs-wash); }

/* "Searching", "no matches", "could not search" — a message, not an
   option. Never selectable, and never silently absent: an empty box
   under a search field reads as a fault rather than as an answer. */
ul.combo li.combo__note {
  color: var(--rgs-ink-soft);
  cursor: default;
  background: none;
}

/* What the search put in the hidden field, in words. Without it the only
   sign that a colleague was chosen is text in a box that also holds
   whatever was typed. */
.picked {
  margin: 0.5rem 0 0;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--rgs-green);
}
.picked[hidden] { display: none; }

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.7rem 1.35rem;
  font: inherit;
  font-weight: 600;
  color: #fff;
  background: var(--rgs-green);
  border: 1px solid var(--rgs-green);
  border-radius: var(--radius);
  cursor: pointer;
  text-decoration: none;
  min-height: 44px;
}
.btn:hover { background: var(--rgs-green-dark); border-color: var(--rgs-green-dark); color: #fff; }

.btn--quiet {
  color: var(--rgs-green);
  background: #fff;
  border-color: var(--rgs-field-border);
}
.btn--quiet:hover { color: var(--rgs-green-dark); background: var(--rgs-paper-warm); border-color: var(--rgs-ink-soft); }

/* Removing a question destroys answers already given, so it does not get
   to look like an ordinary action. */
.btn--danger { color: var(--rgs-red); background: #fff; border-color: #E4B4BB; }
.btn--danger:hover { color: #fff; background: var(--rgs-red); border-color: var(--rgs-red); }

.btn--small { padding: 0.4rem 0.8rem; min-height: 36px; font-size: 0.9375rem; }

.actions { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; margin-top: 1.5rem; }
.actions form { margin: 0; }

/* ---------- The question register ---------- */

/* Questions are a sequence — `order` is real stored data, so the number
   tells a member of staff which question a parent meets first rather
   than decorating the row, and it renumbers as rows are dragged. Set as
   a register: rule between rows, handle and number in the margin, type
   beside it. */
.register { margin: 0 0 1.5rem; border-top: 1px solid var(--rgs-rule); }
.register__row {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr) auto;
  gap: 0.5rem 1rem;
  align-items: baseline;
  padding: 1rem 0.25rem;
  border-bottom: 1px solid var(--rgs-rule);
}
/* Handle and position together in the left margin. */
.register__handle { display: flex; align-items: center; gap: 0.4rem; }
.handle {
  font: inherit;
  line-height: 1;
  padding: 0.25rem 0.3rem;
  color: var(--rgs-ink-soft);
  background: none;
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: grab;
}
.handle:hover { color: var(--rgs-green); border-color: var(--rgs-rule); background: #fff; }
.handle:active { cursor: grabbing; }
.register__row.is-dragging { opacity: 0.4; background: var(--rgs-wash); }
.nudge { display: inline-flex; gap: 0.25rem; }
.nudge[hidden] { display: none; }

.register__n {
  font-family: var(--font-heading);
  font-size: var(--step-1);
  color: var(--rgs-gold);
  font-variant-numeric: tabular-nums;
}
.register__label { font-weight: 600; }
.register__meta { font-size: 0.875rem; color: var(--rgs-ink-soft); }
.register__meta .required { color: var(--rgs-red); font-weight: 600; }
.register__act {
  grid-column: 3;
  grid-row: 1 / span 2;
  align-self: center;
  display: flex;
  gap: 0.5rem;
  align-items: center;
}
.register__row form { margin: 0; }

@media (max-width: 30rem) {
  .register__row { grid-template-columns: 4rem minmax(0, 1fr); }
  .register__act { grid-column: 2; grid-row: auto; margin-top: 0.5rem; }
}

/* ---------- Copyable link ---------- */

.link-out {
  display: flex;
  gap: 0.5rem;
  align-items: stretch;
  flex-wrap: wrap;
  margin: 0 0 0.75rem;
}
.link-out input {
  flex: 1 1 18rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.9375rem;
  background: #fff;
}

/* ---------- Tables (responses) ---------- */

.table-scroll { overflow-x: auto; margin: 0 0 1.5rem; }
table.data { width: 100%; border-collapse: collapse; font-size: 0.9375rem; }
table.data th, table.data td {
  text-align: left;
  padding: 0.7rem 0.75rem;
  border-bottom: 1px solid var(--rgs-rule);
  vertical-align: top;
}
table.data th { font-weight: 600; color: var(--rgs-green); white-space: nowrap; }
table.data tbody tr:hover { background: var(--rgs-wash); }

/* ---------- Utilities ---------- */

.muted { color: var(--rgs-ink-soft); }
.required { color: var(--rgs-red); }

/* A table column of actions needs a header for a screen reader and does
   not need one on screen. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.stack > * + * { margin-top: 1rem; }
ul.plain { list-style: none; margin: 0 0 1rem; padding: 0; }
ul.plain li { margin: 0 0 0.5rem; }
.empty {
  padding: 2rem 1.25rem;
  border: 1px dashed var(--rgs-field-border);
  border-radius: var(--radius);
  color: var(--rgs-ink-soft);
  background: #fff;
}
.empty > :last-child { margin-bottom: 0; }

@media (min-width: 48rem) {
  .wrap { padding: 2.5rem 2rem 5rem; }
  .site-header { padding: 1.5rem 2rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}


/* ---- Admin section ------------------------------------------------ */

/* Pushed to the right-hand end of the nav, away from the apps: the admin
   section is not one of them. margin-left:auto on the first of the two
   trailing items does it without a wrapper element. */
.site-nav__admin { margin-left: auto; }

/* A filter bar: label above control, wrapping to one per line on a
   phone, with the buttons ending up beside the last field rather than
   stretched across the row. */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: end;
  margin: 0 0 1.5rem;
  padding: 1rem;
  border: 1px solid var(--rgs-rule);
  border-radius: 0.5rem;
  background: var(--rgs-paper-warm);
}
.filters > div { display: flex; flex-direction: column; gap: 0.35rem; }
.filters label { font-size: 0.85rem; color: var(--rgs-ink-soft); }
.filters > div:last-child { flex-direction: row; gap: 0.5rem; }

/* The audit log's JSON column. Wraps rather than forcing the table
   wider than the screen, and stays small so the columns a person
   actually scans keep the room. */
.detail {
  display: block;
  max-width: 28rem;
  font-size: 0.8rem;
  word-break: break-word;
  color: var(--rgs-ink-soft);
}

.nowrap { white-space: nowrap; }

.pager {
  display: flex;
  gap: 1rem;
  align-items: center;
  justify-content: center;
  margin: 1.5rem 0;
}

/* ---- Responses table and stepper ---------------------------------- */

.responses-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
  margin: 0 0 1rem;
}
.responses-bar p { margin: 0; }

/* A column per question, so the answers need to stay legible without
   any one long answer forcing the table wider than the screen. */
.data--grid td { vertical-align: top; }
.data--grid td:not(:first-child) { max-width: 22rem; }

/* A response whose stored answers failed their integrity check. Marked,
   never dropped: a quietly missing row in a list the school acts on is
   worse than a visible failure. */
.row--bad { background: var(--rgs-warn-wash, #fdf3f2); }

/* Previous / position / next, for walking a form's responses one child
   at a time. Rendered above and below the answers. */
.stepper {
  display: flex;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
  margin: 1.5rem 0;
  padding: 0.75rem 1rem;
  border: 1px solid var(--rgs-rule);
  border-radius: 0.5rem;
  background: var(--rgs-paper-warm);
}

.note { max-width: 44rem; margin-top: 1.5rem; font-size: 0.9rem; }

/* A destructive link inside a dense table row, where a full .btn--danger
   would dominate the cell. Colour alone is not the signal — it sits after
   "Open", and the page it leads to asks before anything is deleted. */
.link--danger { margin-left: 0.75rem; color: var(--rgs-red); }

/* Only a member of staff viewing a live parent form ever sees this. It is
   above the form and visually unlike it, so it cannot be mistaken for
   something the school is saying to parents. */
.live-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  align-items: center;
  justify-content: space-between;
  margin: 0 0 1.5rem;
  padding: 0.75rem 1rem;
  border: 1px dashed var(--rgs-ink-soft);
  border-radius: 0.5rem;
  background: var(--rgs-paper-warm);
  color: var(--rgs-ink-soft);
  font-size: 0.9rem;
}

/* A one-button POST sitting inline among links in a table cell. It has to
   be a form -- it creates something -- but it should read as the links
   beside it rather than as a block interrupting them. */
.inline-form { display: inline; margin-left: 0.75rem; }



/* ---- The builder's page head ---------------------------------------- */

/* Status, dates and the one button that changes the status, on one line
   at the top right of every builder tab. They belong to each other --
   the dates decide the status and the button changes it -- so they read
   as one group rather than as a stack of three announcements. Wrapping
   only when the line will not hold them. */
.form-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem 1.25rem;
}
.form-head__now {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
.form-head__now form { margin: 0; }

/* Small and quiet: the dates are context for the status beside them, not
   a heading. Side by side, separated by space rather than by a
   character -- two dates are a pair, not a list. */
.form-head__dates {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.15rem 1.25rem;
  margin: 0;
  color: var(--rgs-ink-soft);
  font-size: 0.85rem;
}

@media (max-width: 40rem) {
  /* Under the title rather than beside it, and left-aligned with
     everything else on the page. */
  .form-head {
    justify-content: flex-start;
    width: 100%;
  }
}
