/*
 * SWDS-GCAMS components
 *
 * This file adds only what the OneUI template and Bootstrap do not already
 * provide. It was rewritten after an audit found several components here that
 * re-implemented classes the template already ships. The rule now is:
 *
 *   1. If OneUI or Bootstrap has the pattern, use their class and add a
 *      modifier. Do not draw it again.
 *   2. If they have most of it, extend their class.
 *   3. Only build from scratch when there is nothing to extend.
 *
 * Which is which, per component, is recorded in
 * docs/dev/12-Frontend-Integration-Guide.md section 4.
 *
 * Every colour is a token. No hex value appears below.
 */

/* =========================================================================
   C02 sensitivity ribbon  ·  EXTENDS .block.block-rounded
   =========================================================================
   The template gives the card; the ribbon is ours. It is the signature element
   of this interface: a coloured edge and a small word, so someone walking past
   a screen can tell what is on it. Thickness rises with sensitivity, and the
   top tier adds a lock, because colour alone must never be the only signal. */

.block--tier1 { border-inline-start: 2px solid var(--gc-tier1); }
.block--tier2 { border-inline-start: 3px solid var(--gc-tier2); }
.block--tier3 { border-inline-start: 4px solid var(--gc-tier3); }

.gc-tier-label {
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.block--tier1 .gc-tier-label { color: var(--gc-neutral-on-subtle); }
.block--tier2 .gc-tier-label { color: var(--gc-tier2); }
.block--tier3 .gc-tier-label { color: var(--gc-tier3); }

/* =========================================================================
   C03 data table  ·  EXTENDS .table.table-hover.table-vcenter
   =========================================================================
   The template's table classes already give the row rhythm, the hover and the
   vertical centring. Four things it has no opinion about are added here: the
   scroll container, sortable headers, the loading state, and the card
   transformation below 768px. Sorting, filtering and paging happen on the
   server, because a role-scoped queryset means the browser never holds the
   full set. */

.gc-table-wrap {
  overflow-x: auto;
  /* Explicit, and not redundant. When one axis is not `visible` CSS computes the
     other to `auto`, so `overflow-x: auto` alone made this a vertical scroll
     container too -- and row heights are fractional (49.74px, 50.15px), so the
     table was a sub-pixel taller than the integer clientHeight and every table
     in the system carried a dead vertical scrollbar. No table wrap contains a
     dropdown, so clipping the block axis costs nothing. */
  overflow-y: hidden;
  border: 1px solid var(--gc-border);
  border-radius: var(--bs-border-radius);
}

.gc-table-wrap:focus-visible { outline-offset: -3px; }

/* Numeric columns. Declared here rather than written inline on the cell,
   because a `style=` attribute is invisible to every gate this project has and
   the next table that needs it would grow a second copy. Digits that line up
   are the difference between a price column somebody can scan and one they
   have to read. */
.gc-num { font-variant-numeric: tabular-nums; }

/* A dashboard bar. Thin, because the number sits beside it and the bar is an
   aid to scanning rather than the carrier of the value. */
.gc-bar { height: .6rem; }

/* `.gc-sort` used to live here: a hand-built sortable heading with its arrow
   drawn from aria-sort. D-78 adopted DataTables in server-side mode, which
   makes the <th> its own control and draws its own arrow, so those rules were
   dead the day that decision landed. Removed rather than kept "in case":
   unused CSS is what a reader takes for a component that exists. */

/* Loading. The table stays readable and in place; a bar and a dimming say that
   fresher data is coming. Replacing rows with skeletons would move the thing
   the reader was looking at. */
.gc-table-wrap.htmx-request { position: relative; }
.gc-table-wrap.htmx-request .table { opacity: .6; }

.gc-table-wrap.htmx-request::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  height: 3px;
  background: var(--gc-primary);
  animation: gc-indeterminate 1.1s ease-in-out infinite;
}

@keyframes gc-indeterminate {
  0%   { clip-path: inset(0 100% 0 0); }
  50%  { clip-path: inset(0 0 0 0); }
  100% { clip-path: inset(0 0 0 100%); }
}

/* Card mode. Below 768px a row becomes a stacked card whose cells carry their
   own heading from data-label. Two registers are exempt, because their column
   order is what staff cross-check against the paper form; those scroll inside
   .gc-table-wrap instead. */
@media (max-width: 767.98px) {
  .table--cards,
  .table--cards > tbody,
  .table--cards > tbody > tr,
  .table--cards > tbody > tr > td { display: block; width: 100%; }

  .table--cards > thead { display: none; }

  .table--cards > tbody > tr {
    margin-bottom: .75rem;
    padding: .75rem 1rem;
    background: var(--gc-surface-raised);
    border: 1px solid var(--gc-border);
    border-radius: var(--bs-border-radius);
  }

  .table--cards > tbody > tr > td { padding: .25rem 0; border: 0; }

  .table--cards td[data-label]::before {
    content: attr(data-label) ": ";
    font-weight: 600;
    color: var(--gc-text-muted);
  }

  /* The first cell is the row's own link and reads as the card title. */
  .table--cards td:first-child::before { content: none; }
  .table--cards td:first-child { font-size: 1.0625rem; font-weight: 600; }
}

/* =========================================================================
   C04 status badge  ·  EXTENDS .badge
   =========================================================================
   Bootstrap gives the pill. What it does not give is the rule that every badge
   in this system carries a glyph and a word, so the interface still works in
   greyscale and for a colour-blind reader. Colour is the third signal, never
   the only one. */

.badge {
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  min-height: 24px;
  font-weight: 600;
}

.badge .gc-icon { width: .875rem; height: .875rem; }

.badge--neutral { color: var(--gc-neutral-on-subtle); background: var(--gc-neutral-subtle); }
.badge--info    { color: var(--gc-info-on-subtle);    background: var(--gc-info-subtle); }
.badge--success { color: var(--gc-success-on-subtle); background: var(--gc-success-subtle); }
.badge--warning { color: var(--gc-warning-on-subtle); background: var(--gc-warning-subtle); }
.badge--danger  { color: var(--gc-danger-on-subtle);  background: var(--gc-danger-subtle); }

/* Solid rather than tinted, because each means somebody has to act now, or --
   for checked-in -- that somebody is standing at the counter right now. The
   status table in 10 section C04 names these five; the sentence above it still
   said three, which is how `primary` and `urgent` came to have no class. */
.badge--crisis   { color: var(--gc-crisis-on);  background: var(--gc-crisis-fill); }
.badge--overdue  { color: var(--gc-text-on-dark); background: var(--gc-danger); }
.badge--required { color: var(--gc-text-on-dark); background: var(--gc-warning); }
.badge--primary  { color: var(--gc-text-on-dark); background: var(--gc-primary); }
.badge--urgent   { color: var(--gc-text-on-dark); background: var(--gc-danger); }

/* =========================================================================
   C10 empty state  ·  NEW, nothing to extend
   =========================================================================
   The template's demo tables are always full, so it has no empty state at all.
   Six variants, because "nothing here" means six different things and each
   wants a different next step. Never an illustration: this is an office tool. */

.gc-empty {
  padding: 2.5rem 1.5rem;
  text-align: center;
  color: var(--gc-text-muted);
}

.gc-empty__icon { width: 2rem; height: 2rem; opacity: .5; margin-bottom: .75rem; }

.gc-empty__title {
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--gc-text);
  margin-bottom: .25rem;
}

.gc-empty__body { max-width: 42ch; margin: 0 auto 1rem; }

/* Waiting on someone else is not the reader's fault, and should not offer an
   action they cannot take. */
.gc-empty--waiting .gc-empty__title { color: var(--gc-text-muted); }

/* Restricted is not emptiness. It says the records exist and are not yours. */
.gc-empty--restricted {
  border-inline-start: 4px solid var(--gc-tier3);
  text-align: start;
  background: var(--gc-surface-sunken);
}

/* =========================================================================
   C13 slot picker  ·  tiles EXTEND .form-block
   =========================================================================
   The template's .form-block is exactly the card-shaped radio this needs: it
   hides the input, makes the label the card, and handles hover, checked, focus
   and disabled. Only the day strip and the slot's own content are added.

   This is the most important student-facing control in the product. */

.gc-daystrip {
  display: flex;
  gap: .5rem;
  overflow-x: auto;
  padding-block: .25rem;
  scroll-snap-type: x mandatory;
}

.gc-daystrip .form-block { flex: none; width: 56px; scroll-snap-align: start; }

.gc-daystrip .form-check-label {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .125rem;
  min-height: 56px;
  padding: .25rem;
  text-align: center;
}

.gc-day__dow { font-size: .6875rem; text-transform: uppercase; color: var(--gc-text-muted); }
.gc-day__num { font-size: 1.0625rem; font-weight: 600; }
.gc-day__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--gc-success); }

/* The day strip is too small to carry the template's corner checkmark. */
.gc-daystrip .form-check-label::before,
.gc-daystrip .form-check-input:checked ~ .form-check-label::after { display: none; }

.gc-daystrip .form-check-input:checked ~ .form-check-label {
  background: var(--gc-primary);
  color: var(--gc-text-on-dark);
}

.gc-daystrip .form-check-input:checked ~ .form-check-label .gc-day__dow {
  color: var(--gc-text-on-dark);
}

.gc-slotgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: .5rem;
}

.gc-slotgrid .form-check-label {
  display: flex;
  flex-direction: column;
  gap: .125rem;
  min-height: var(--gc-tap-min);
}

.gc-slot__time { font-weight: 600; }
.gc-slot__meta { font-size: .8125rem; color: var(--gc-text-muted); }

/* A slot that clashes with a class is a warning, never a block. The office's
   own rule is that a timetable must not stop a student getting help. */
.gc-slot--conflict .form-check-label { border-color: var(--gc-warning); }
.gc-slot--conflict .gc-slot__meta { color: var(--gc-warning-on-subtle); font-weight: 600; }

/* =========================================================================
   C14 signature pad  ·  NEW, nothing to extend
   ========================================================================= */

.gc-sigpad {
  border: 1px solid var(--gc-text-muted);
  border-radius: var(--bs-border-radius);
  background: var(--gc-surface-raised);
  touch-action: none;
}

.gc-sigpad__canvas { display: block; width: 100%; height: 180px; cursor: crosshair; }

.gc-sigpad__actions {
  display: flex;
  gap: .5rem;
  align-items: center;
  padding: .5rem;
  border-top: 1px solid var(--gc-border);
}

.gc-sigpad__hint { font-size: .8125rem; color: var(--gc-text-muted); }

/* The typed alternative is not a fallback of last resort. It is an equal path,
   and it is the only one available by keyboard. */
.gc-sigpad__typed { margin-top: .5rem; }

/* =========================================================================
   C18 AI message bubble  ·  NEW, nothing to extend
   =========================================================================
   The template's nearest shapes are a forum post table and a mail list, neither
   of which is a message stream. Everything the assistant says is marked as
   machine-written, and the marking cannot be styled away. The colour is
   reserved: it appears nowhere else in the interface. */

.gc-chat { display: flex; flex-direction: column; gap: 1rem; }

.gc-msg { max-width: 560px; padding: .75rem 1rem; border-radius: .75rem; }

.gc-msg--user {
  align-self: flex-end;
  background: var(--gc-primary-subtle);
  color: var(--gc-primary-on-subtle);
  border-bottom-right-radius: .25rem;
}

.gc-msg--ai {
  align-self: flex-start;
  background: var(--gc-ai-subtle);
  border: 1px solid var(--gc-ai-border);
  border-bottom-left-radius: .25rem;
}

.gc-msg__who {
  display: flex;
  align-items: center;
  gap: .375rem;
  margin-bottom: .375rem;
  font-size: .75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--gc-ai-on-subtle);
}

.gc-msg__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  font-size: .625rem;
  color: var(--gc-text-on-dark);
  background: var(--gc-ai);
  border-radius: 50%;
}

/* Where the answer came from, and how old that source is. An answer with no
   citation says so plainly rather than looking the same as one with. */
.gc-msg__cite {
  margin-top: .5rem;
  padding-top: .5rem;
  border-top: 1px solid var(--gc-ai-border);
  font-size: .8125rem;
}

.gc-msg__stale {
  color: var(--gc-warning-on-subtle);
  background: var(--gc-warning-subtle);
  padding: .0625rem .375rem;
  border-radius: .25rem;
}

.gc-msg--unverified { border-style: dashed; }
.gc-msg--unverified .gc-msg__cite { color: var(--gc-warning-on-subtle); }

.gc-msg__actions { display: flex; gap: .25rem; margin-top: .5rem; }

.gc-typing { display: inline-flex; gap: .25rem; }

.gc-typing span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gc-ai);
  animation: gc-typing 1.2s infinite ease-in-out;
}

.gc-typing span:nth-child(2) { animation-delay: .15s; }
.gc-typing span:nth-child(3) { animation-delay: .3s; }

@keyframes gc-typing {
  0%, 60%, 100% { opacity: .3; }
  30%           { opacity: 1; }
}

/* The disclosure sits in the chat header and is not collapsible. */
.gc-ai-disclosure {
  padding: .5rem .75rem;
  font-size: .8125rem;
  color: var(--gc-ai-on-subtle);
  background: var(--gc-ai-subtle);
  border-bottom: 1px solid var(--gc-ai-border);
}

/* =========================================================================
   C19 crisis banner  ·  NEW, deliberately not .alert
   =========================================================================
   Bootstrap's alert is dismissible by default and its palette is shared with
   ordinary warnings. Neither is acceptable here: an open crisis alert is not
   something a counsellor may hide, and this colour must mean one thing only.
   Reserved colour, no dismiss control, no animation. */

.gc-crisis-strip {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .625rem 1rem;
  color: var(--gc-crisis-on);
  background: var(--gc-crisis-fill);
  font-weight: 600;
}

.gc-crisis-strip .btn { flex: none; }

.gc-crisis-card {
  border: 1px solid var(--gc-crisis-edge);
  border-inline-start: 4px solid var(--gc-crisis-fill);
  border-radius: var(--bs-border-radius);
  background: var(--gc-surface-raised);
  padding: 1rem 1.25rem;
}

.gc-hotlines {
  margin-top: .75rem;
  padding: .75rem;
  background: var(--gc-crisis-tint);
  border-radius: var(--bs-border-radius);
}

/* A hotline is a phone link with a large target. This is the one control that
   must work when someone is distressed and not looking carefully. */
.gc-hotline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: var(--gc-tap-min);
  padding: .5rem .25rem;
  font-weight: 600;
  text-decoration: none;
}

.gc-hotline + .gc-hotline { border-top: 1px solid var(--gc-crisis-edge); }
.gc-hotline__num { font-variant-numeric: tabular-nums; }

/* =========================================================================
   C21 concern grid  ·  rows EXTEND .form-check, chips are NEW
   =========================================================================
   The 47 official checkboxes in five printed groups. The chip summary is what
   makes a long grid usable on a phone. */

.gc-concerns { display: grid; gap: .5rem; }

@media (min-width: 576px) { .gc-concerns { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 992px) { .gc-concerns { grid-template-columns: repeat(3, 1fr); } }

.gc-concerns .form-check {
  display: flex;
  align-items: center;
  gap: .5rem;
  min-height: var(--gc-tap-min);
  margin: 0;
  padding: .375rem .5rem;
  border-radius: .375rem;
}

.gc-concerns .form-check:hover { background: var(--gc-primary-subtle); }

.gc-concern-count { font-size: .8125rem; color: var(--gc-text-muted); font-weight: 600; }

.gc-chipbar {
  position: sticky;
  bottom: 0;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  gap: .375rem;
  padding: .625rem;
  background: var(--gc-surface-raised);
  border-top: 1px solid var(--gc-border);
}

.gc-chip {
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  padding: .125rem .25rem .125rem .5rem;
  font-size: .8125rem;
  background: var(--gc-primary-subtle);
  color: var(--gc-primary-on-subtle);
  border-radius: 1rem;
}

.gc-chip__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--gc-tap-min);
  height: var(--gc-tap-min);
  margin: calc(var(--gc-tap-min) / -2 + .6875rem) 0;
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
}

/* =========================================================================
   C22 scale item row  ·  options EXTEND .form-block
   =========================================================================
   Used by every clinical instrument and every evaluation questionnaire. The
   official wording of each option is always visible: a bare number or a star
   cannot carry "More than half the days". The template's card-radio does the
   work; only the row rhythm and the running count are added. */

.gc-scale__item + .gc-scale__item { border-top: 1px solid var(--gc-border); }
.gc-scale__item { padding: .75rem 0; }
.gc-scale__item:nth-child(odd) { background: var(--gc-surface-sunken); }

.gc-scale__legend { font-weight: 500; margin-bottom: .5rem; }

.gc-scale__options { display: grid; gap: .5rem; }

@media (min-width: 768px) {
  .gc-scale__options { grid-template-columns: repeat(var(--gc-scale-cols, 4), 1fr); }
}

.gc-scale__options .form-check-label {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--gc-tap-min);
  text-align: center;
  font-size: .875rem;
}

.gc-scale__options .form-check-input:checked ~ .form-check-label {
  background: var(--gc-primary);
  color: var(--gc-text-on-dark);
  font-weight: 600;
}

/* Progress through a long instrument, pinned so the student always knows how
   much is left. It never shows a score or an interpretation. */
.gc-scale__progress {
  position: sticky;
  top: var(--gc-header-h, 4rem);
  z-index: 2;
  padding: .5rem 0;
  background: var(--gc-surface);
  border-bottom: 1px solid var(--gc-border);
  font-size: .875rem;
  font-weight: 600;
}

/* =========================================================================
   C23 autosave indicator  ·  NEW, nothing to extend
   =========================================================================
   Five states. The one that matters is "not saved": while it shows, the sign
   and submit controls are disabled, because a signed form must never be built
   on text the server never received. */

.gc-autosave {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  font-size: .8125rem;
  color: var(--gc-text-muted);
}

.gc-autosave--saving { color: var(--gc-text-muted); }
.gc-autosave--saved  { color: var(--gc-success-on-subtle); }
.gc-autosave--failed { color: var(--gc-danger-on-subtle); font-weight: 600; }
.gc-autosave--stale  { color: var(--gc-warning-on-subtle); font-weight: 600; }

/* =========================================================================
   C25 check-in poster  ·  NEW, nothing to extend
   =========================================================================
   The office displays this; the student's own phone camera reads it. The code
   below the image is the manual path for a camera that will not focus. */

.gc-qr {
  display: inline-block;
  padding: 1rem;
  background: #fff;   /* a QR needs a true white quiet zone to scan reliably */
  border: 1px solid var(--gc-border);
  border-radius: var(--bs-border-radius);
}

.gc-qr svg { display: block; width: 240px; height: 240px; }

.gc-qr__code {
  margin-top: .75rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-align: center;
}

.gc-qr__expiry { text-align: center; font-size: .875rem; color: var(--gc-text-muted); }

/* =========================================================================
   Shared: sticky action bar  ·  NEW
   =========================================================================
   Below 576px the primary action of a long form follows the reader down, so a
   wizard step never ends in a hunt for the button. */

@media (max-width: 575.98px) {
  .gc-actionbar {
    position: sticky;
    bottom: 0;
    z-index: 3;
    display: flex;
    gap: .5rem;
    padding: .75rem;
    margin-inline: -1rem;
    background: var(--gc-surface-raised);
    border-top: 1px solid var(--gc-border);
    box-shadow: 0 -2px 8px rgb(0 0 0 / .06);
  }
  .gc-actionbar .btn { flex: 1; }
}

/* D-145: the office referral screens run at the wide width, where the submit
   button would otherwise be two screens below the last field. `--pinned` keeps
   the bar in view from the desktop breakpoint up; between the two ranges the
   bar is an ordinary block. */
@media (min-width: 992px) {
  .gc-actionbar--pinned {
    position: sticky;
    bottom: 0;
    z-index: 3;
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .75rem 0;
    background: var(--gc-surface-raised);
    border-top: 1px solid var(--gc-border);
  }
}

/* --- Stat tile ------------------------------------------------------------
   The dashboard number. EXTENDS the template's `.block.block-rounded`, so the
   card shape, radius and shadow come from OneUI and only the type scale and the
   tone edge are ours.

   The tone is an inline-start edge rather than a filled background, the way the
   sensitivity ribbon is. A wall of five saturated tiles is how the template's
   demo dashboard looks, and it makes every number shout equally; the one tile
   that means "somebody is waiting" has to be able to stand out from the four
   that are just counts. */
.gc-stat {
  border-inline-start: 4px solid var(--gc-border);
}

.gc-stat--primary { border-inline-start-color: var(--gc-primary); }
.gc-stat--warning { border-inline-start-color: var(--gc-warning); }
.gc-stat--danger  { border-inline-start-color: var(--gc-danger); }

.gc-stat__icon {
  width: 1.75rem;
  height: 1.75rem;
  color: var(--gc-text-muted);
  flex-shrink: 0;
}

.gc-stat--primary .gc-stat__icon { color: var(--gc-primary); }
.gc-stat--warning .gc-stat__icon { color: var(--gc-warning); }
.gc-stat--danger  .gc-stat__icon { color: var(--gc-danger); }

.gc-stat__value {
  font-size: 1.75rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--gc-text);
}

.gc-stat__label {
  font-size: .8125rem;
  color: var(--gc-text-muted);
}

/* A linked tile is a link: it takes the same focus ring as everything else, and
   the whole tile is the target rather than the number inside it. */
a.gc-stat {
  display: block;
  text-decoration: none;
}

a.gc-stat:hover .gc-stat__value {
  color: var(--gc-primary);
}

/* --------------------------------------------------------------------------
   C26 Side navigation rail
   -------------------------------------------------------------------------- */

/* A rail of sibling screens beside the one that is open. Bootstrap's pills give
   the states; what is ours is the axis, the left alignment a vertical list needs
   and the two behaviours below. */
.gc-side-nav .nav-link {
  text-align: left;
  width: 100%;
}

@media (min-width: 768px) {
  /* A panel here can be eighteen fields long. Without this the rail scrolls
     away and the reader loses the one control that says where they are. The
     same fallback as the page header offset above: `--gc-header-h` is consumed
     in two places and declared in none. */
  .gc-side-nav {
    position: sticky;
    top: calc(var(--gc-header-h, 4rem) + 1rem);
  }
}

@media (max-width: 767.98px) {
  /* Below the breakpoint the rail is a horizontal strip. `overflow-x: auto`
     alone makes a box scroll on *both* axes, which puts a second scrollbar
     under a one-line strip -- section 5.8 rule 12. */
  .gc-side-nav {
    overflow-x: auto;
    overflow-y: hidden;
  }

  .gc-side-nav .nav {
    flex-wrap: nowrap;
  }

  .gc-side-nav .nav-link {
    width: auto;
    white-space: nowrap;
  }
}

/* --------------------------------------------------------------------------
   Settings controls: the repeating row list and the ordered chain
   -------------------------------------------------------------------------- */

/* `table-responsive` supplies `overflow-x: auto`, and on its own that scrolls
   both axes -- a second scrollbar under a table that already fits vertically
   (section 5.8 rule 12). Same element, so the pair lives here. */
.gc-row-list {
  overflow-y: hidden;
}

/* A row nobody has filled in yet is still a row somebody can type into, so it
   is dimmed rather than hidden or bordered differently. */
.gc-row-list tbody tr:last-child .form-control,
.gc-row-list tbody tr:last-child .form-select {
  background-color: var(--gc-surface-muted, transparent);
}

/* The rank label is fixed-width so every select in the chain starts at the same
   place; a ragged left edge makes the order harder to read, which is the one
   thing this control exists to show. */
.gc-ordered-choice__rank {
  flex: 0 0 6.5rem;
}

.gc-ordered-choice .form-select {
  max-width: 22rem;
}

/* --------------------------------------------------------------------------
   Knowledge base (SCR-142, SCR-161 to SCR-164)
   -------------------------------------------------------------------------- */

/* A rendered document body. The width is the reading measure of the narrow
   page; the headings are the sections a citation names, so they are kept
   visibly distinct from the running text. */
.gc-prose { max-width: 65ch; line-height: 1.6; }
.gc-prose h1 { font-size: 1.5rem; margin-top: 1.5rem; }
.gc-prose h2 { font-size: 1.25rem; margin-top: 1.25rem; }
.gc-prose h3 { font-size: 1.0625rem; margin-top: 1rem; }
.gc-prose table { width: 100%; margin-bottom: 1rem; border-collapse: collapse; }
.gc-prose th, .gc-prose td { padding: .375rem .5rem; border: 1px solid var(--gc-border, #dee2e6); }
.gc-prose blockquote { border-left: 3px solid var(--gc-warning-on-subtle); padding-left: .75rem; color: var(--gc-text-muted, #6c757d); }

/* difflib's table, made legible: monospace, the change colours from the theme,
   and the line-number gutters dimmed so the words carry the eye. */
.gc-diff table.diff { width: 100%; font-family: var(--bs-font-monospace); font-size: .8125rem; border-collapse: collapse; }
.gc-diff .diff_header { background: var(--gc-surface-muted, #f8f9fa); color: var(--gc-text-muted, #6c757d); padding: 0 .5rem; text-align: right; }
.gc-diff td { vertical-align: top; padding: .0625rem .375rem; white-space: pre-wrap; }
.gc-diff .diff_add { background: var(--gc-success-subtle, #d1e7dd); }
.gc-diff .diff_chg { background: var(--gc-warning-subtle, #fff3cd); }
.gc-diff .diff_sub { background: var(--gc-danger-subtle, #f8d7da); }
.gc-diff .diff_next { display: none; }
