/* IECF Patient Management Software
   ----------------------------------------------------------------------------
   This is an instrument, not a brochure. Where the campaign pages were allowed
   warmth and a load animation, everything here is in service of a nurse getting
   through a queue of five hundred people without making a mistake.

   The shape of it: dark royal chrome wrapped around a paper working surface.
   The chrome is where the software lives, the paper is where the patient lives,
   and the boundary between them is hard so that at a glance you always know
   whether you are looking at a control or at a record.

   Three rules that are not negotiable.

   1. Every clinical number is set in tabular figures. IOP, blood pressure,
      blood sugar, keratometry, axial length, IOL power. Proportional digits on
      a lens power is a defect, not a style choice.

   2. Eye laterality is distinguished by SHAPE AND LABEL, never by colour alone.
      Operating on the wrong eye is the worst thing this software could cause,
      and a colour-blind surgeon, a bad monitor or a printout in greyscale must
      not be able to lose the distinction.

   3. Almost no motion. State-change confirmation only. Nothing moves because it
      would look nice.

   Colour follows the Rotary masterbrand, carried over from the club site where
   the contrast ratios are already worked out. Gold means one thing here and it
   is not "the ask": it marks the record you are currently working on.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Archivo';
  src: url('font/archivo-latin.woff2') format('woff2-variations');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Rotary masterbrand */
  --royal: #17458f;
  --azure: #005daa;
  --gold: #f7a81b;
  --gold-deep: #9a6605;

  /* Chrome: the software. */
  --ink: #071328;
  --ink-deep: #030a17;
  --ink-raise: #0e2043;
  --on-ink: #f2efe6;
  --on-ink-soft: #9fb0cb;

  /* Paper: the patient. */
  --paper: #fbf9f4;
  --paper-deep: #f1ede3;
  --paper-line: #e3dccc;
  --on-paper: #14202e;
  --on-paper-soft: #55637a;

  /* Status. Each one is always paired with a word, never used alone. */
  --alarm: #c0271c;
  --alarm-bg: #fceceb;
  --caution: #8a5b00;
  --caution-bg: #fdf3dd;
  --good: #1f6b41;
  --good-bg: #e8f3ec;

  --font: 'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;

  --wrap: 74rem;
  --gut: clamp(1rem, 3.5vw, 2.25rem);
  --radius: 3px;   /* almost square. This is a form, not an app icon. */
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;               /* never smaller. Bad monitors, older eyes. */
  line-height: 1.45;
  color: var(--on-paper);
  /* Flat. An earlier version ruled this surface like a ledger sheet, which
     looked right and read wrong: any text sitting directly on the background,
     the page heading and the footer warning among them, picked up a line
     through it at certain scroll positions. On a clinical screen a texture that
     can be mistaken for a strike-through is not worth the character it buys. */
  background: var(--paper-deep);
}

.num {
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 0.5rem;
  top: 0.5rem;
  z-index: 50;
  background: var(--gold);
  color: var(--ink);
  padding: 0.6rem 1rem;
  font-weight: 700;
}

/* ---------------------------------------------------------------------------
   Chrome
   ------------------------------------------------------------------------ */

.chrome {
  background: var(--ink);
  color: var(--on-ink);
  border-bottom: 3px solid var(--royal);
}

.chrome-in {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0.7rem var(--gut);
  display: flex;
  align-items: center;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.mark { display: block; flex: 0 0 auto; }
.mark img { display: block; width: 190px; height: auto; }

.nav {
  display: flex;
  gap: 0.35rem;
  margin-left: auto;
}

.nav a {
  display: block;
  padding: 0.6rem 0.95rem;             /* a real tap target */
  color: var(--on-ink);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.95rem;
  border-radius: var(--radius);
  border: 1px solid transparent;
}
.nav a:hover { background: var(--ink-raise); }
.nav a:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }

.who {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.2;
  font-size: 0.8rem;
}
.who-name { font-weight: 700; }
.who-role { color: var(--on-ink-soft); }
.who-out { color: var(--on-ink-soft); text-decoration: underline; margin-top: 0.15rem; }
.who-out:hover { color: var(--on-ink); }

/* On a phone the header would otherwise stack into three full-width rows and
   push the actual work off the screen. Logo left, who right, navigation
   underneath, wrapping onto as many rows as it needs.

   It said "on one line" and did not wrap, which was wrong: there are seven
   destinations and they do not fit on one line on any phone. Measured at
   320, 360, 390, 414 and 480px, the row ran to 486px every time, so Reports
   and Staff sat off the right edge where no amount of scrolling reached them,
   and every page on the site scrolled sideways as a result. Found by opening
   the pages at phone size and looking at them. */
@media (max-width: 40rem) {
  .chrome-in { gap: 0.6rem 1rem; padding: 0.6rem var(--gut); }
  .mark img { width: 130px; }
  .who { margin-left: auto; font-size: 0.72rem; }
  .nav { order: 3; width: 100%; margin-left: 0; flex-wrap: wrap; }
  .nav a { flex: 1 1 auto; text-align: center; padding: 0.6rem 0.5rem; }
}

/* ---------------------------------------------------------------------------
   The sheet
   ------------------------------------------------------------------------ */

.sheet {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: var(--gut) var(--gut) 4rem;
}

h1, h2, h3 {
  font-weight: 700;
  letter-spacing: -0.012em;
  margin: 0 0 0.4rem;
}
h1 { font-size: 1.65rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: 0.98rem; }

.sub {
  color: var(--on-paper-soft);
  margin: 0 0 1.6rem;
  max-width: 46rem;
}

.card {
  background: var(--paper);
  border: 1px solid var(--paper-line);
  border-radius: var(--radius);
  padding: 1.25rem var(--gut);
  margin-bottom: 1.25rem;
}

.card > h2:first-child { margin-top: 0; }

/* The bar down the left of the record you are currently working on. This is
   the only place gold appears. */
.card.current { border-left: 4px solid var(--gold); }

.flash {
  max-width: var(--wrap);
  margin: 1rem auto -0.25rem;
  padding: 0.8rem 1rem;
  background: var(--good-bg);
  border-left: 4px solid var(--good);
  color: var(--good);
  font-weight: 600;
}
.flash-warn { background: var(--caution-bg); border-color: var(--caution); color: var(--caution); }

/* ---------------------------------------------------------------------------
   Forms. Field order mirrors the paper forms so staff transcribe without
   hunting, and every control is big enough to hit at speed.
   ------------------------------------------------------------------------ */

.fieldset {
  border: 0;
  padding: 0;
  margin: 0 0 1.75rem;
}

.legend {
  display: block;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--royal);
  padding-bottom: 0.4rem;
  margin-bottom: 1rem;
  border-bottom: 2px solid var(--royal);
}

.legend .by {
  float: right;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: none;
  color: var(--on-paper-soft);
}

.row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0.9rem 1.1rem;
  margin-bottom: 0.9rem;
}
.row.tight { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); }

.field { display: flex; flex-direction: column; }
.field.wide { grid-column: 1 / -1; }

/* A box sized to what goes in it. An age field as wide as an address field
   reads as an invitation to type more than two digits. */
.field input.short { max-width: 7rem; }

/* The full Form 1 asks for an address; the camp form has no such box. Rather
   than two pages, the extra fields live here and collapse when the short form
   is chosen, so a screening that turns into a surgical case is a toggle and not
   a re-registration.

   No script. Where :has() is unsupported the field simply stays visible, which
   is a slightly longer form and not a broken one, and the server enforces the
   requirement either way. */
form:has(input[name="kind"][value="outreach"]:checked) .full-only {
  display: none;
}

.field label,
.group-label {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--on-paper);
  margin-bottom: 0.25rem;
}

.hint {
  font-size: 0.76rem;
  color: var(--on-paper-soft);
  margin-top: 0.25rem;
}

input[type="text"],
input[type="tel"],
input[type="date"],
input[type="number"],
input[type="password"],
input[type="search"],
select,
textarea {
  font: inherit;
  font-size: 1rem;
  color: var(--on-paper);
  background: #fff;
  border: 1px solid #b9b2a2;
  border-bottom-width: 2px;
  border-radius: var(--radius);
  padding: 0.62rem 0.7rem;
  min-height: 2.9rem;             /* thumb-sized on a phone at a camp gate */
  width: 100%;
}

textarea { min-height: 5rem; resize: vertical; }

input:focus-visible,
select:focus-visible,
textarea:focus-visible,
button:focus-visible,
a:focus-visible {
  outline: 3px solid var(--azure);
  outline-offset: 1px;
}

.field.bad input,
.field.bad select { border-color: var(--alarm); background: var(--alarm-bg); }

.err {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--alarm);
  margin-top: 0.25rem;
}

/* Tick boxes, sized to be hit rather than aimed at. */
.ticks { display: flex; flex-wrap: wrap; gap: 0.5rem; }

.tick {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 0.8rem;
  border: 1px solid #b9b2a2;
  border-radius: var(--radius);
  background: #fff;
  font-weight: 600;
  font-size: 0.92rem;
  cursor: pointer;
  min-height: 2.9rem;
}
.tick input { width: 1.15rem; height: 1.15rem; margin: 0; accent-color: var(--royal); }
.tick:has(input:checked) { border-color: var(--royal); background: #eef3fb; }
.tick:has(input:focus-visible) { outline: 3px solid var(--azure); outline-offset: 1px; }

/* ---------------------------------------------------------------------------
   Eye laterality. Shape and label, never colour alone.

   Right is a square, left is a circle, and each carries its letter and the
   clinical abbreviation. Printed in greyscale, seen by a colour-blind surgeon,
   or rendered on a washed-out monitor, the two remain different objects.
   ------------------------------------------------------------------------ */

.eye {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  flex: 0 0 auto;
  font-weight: 700;
  font-size: 0.9rem;
  border: 2px solid var(--on-paper);
  background: #fff;
}
.eye-r { border-radius: 2px; }                   /* square */
.eye-l { border-radius: 50%; }                   /* circle */

/* Blood pressure, sugar, right eye, left eye. Four cells that fit on one line
   on a laptop and do not fit on any phone: without wrapping, the left eye ran
   past the right edge of the screen on the clearance form and on the patient
   file, clipped where nobody could scroll to it. The left eye reading is half
   of what the decision to operate rests on, so it does not get to be the one
   that falls off. Wrapping puts two on a row instead. */
.eye-pair { display: flex; flex-wrap: wrap; gap: 0.75rem; }

.eye-cell {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--paper-line);
  border-radius: var(--radius);
  background: var(--paper);
  flex: 1 1 8rem;
}
.eye-cell b { font-size: 1.05rem; }
.eye-cell small { display: block; color: var(--on-paper-soft); font-size: 0.72rem; }

/* The operative-eye marker: big, persistent, and impossible to mistake. */
.operative {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.9rem 1.1rem;
  border: 3px solid var(--on-paper);
  border-radius: var(--radius);
  background: #fff;
}
.operative .eye { width: 3rem; height: 3rem; font-size: 1.3rem; border-width: 3px; }
.operative-what { font-weight: 700; font-size: 1.05rem; }
.operative-what small {
  display: block;
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--on-paper-soft);
}

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

.btn {
  font: inherit;
  font-weight: 700;
  font-size: 1rem;
  padding: 0.8rem 1.4rem;
  min-height: 3rem;
  border: 1px solid var(--royal);
  border-radius: var(--radius);
  background: var(--royal);
  color: #fff;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}
.btn:hover { background: var(--azure); border-color: var(--azure); }

.btn-quiet { background: #fff; color: var(--royal); }
.btn-quiet:hover { background: #eef3fb; color: var(--royal); }

.actions {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  align-items: center;
  padding-top: 0.5rem;
}

/* ---------------------------------------------------------------------------
   Tables and lists
   ------------------------------------------------------------------------ */

/* A table too wide for the screen scrolls sideways inside this box. On a laptop
   that never happens; on a phone it happens on nearly every table, and until
   now nothing on the screen said so. A column could be sitting just out of
   view with no clue it was there, and on the patient file the column in
   question is the one that says whether the patient was cleared.

   The shadows below are painted by the box itself, so they appear only when
   there is really something more to see and fade out at each end as it is
   reached. No JavaScript, which this application does not have and its content
   security policy would refuse anyway.

   How it works: the two solid `--paper` panels are attached to the *content*,
   so they slide away as it scrolls; the two dark smudges are attached to the
   *box*, so they stay put. At rest the panels sit on top of the smudges and
   hide them. Scroll, and the panel on that side moves off, uncovering the
   smudge underneath. */
.table-wrap {
  overflow-x: auto;
  background-image:
    linear-gradient(to right, var(--paper) 40%, rgba(251, 249, 244, 0)),
    linear-gradient(to left,  var(--paper) 40%, rgba(251, 249, 244, 0)),
    linear-gradient(to right, rgba(20, 32, 46, 0.16), rgba(20, 32, 46, 0)),
    linear-gradient(to left,  rgba(20, 32, 46, 0.16), rgba(20, 32, 46, 0));
  background-position: 0 0, 100% 0, 0 0, 100% 0;
  background-repeat: no-repeat;
  background-size: 2.5rem 100%, 2.5rem 100%, 0.9rem 100%, 0.9rem 100%;
  background-attachment: local, local, scroll, scroll;
}

/* A sentence was tried here too, and taken out again. CSS cannot tell whether
   a table actually overflows, so "scroll sideways to see the rest" would have
   been printed under tables that fit perfectly well. Telling somebody there is
   more to see when there is not is the same kind of untruth as the search
   screen reporting its own limit as a total. The shadows stay because they are
   drawn from the real scroll position and cannot claim anything false. */

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.94rem;
}

th {
  text-align: left;
  font-size: 0.74rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--on-paper-soft);
  border-bottom: 2px solid var(--paper-line);
  padding: 0.5rem 0.6rem;
  white-space: nowrap;
}

td {
  padding: 0.7rem 0.6rem;
  border-bottom: 1px solid var(--paper-line);
  vertical-align: top;
}

tbody tr:hover { background: var(--paper-deep); }

td a { color: var(--royal); font-weight: 700; }

.reg {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   Today's counts
   ------------------------------------------------------------------------ */

.counts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.count {
  background: var(--paper);
  border: 1px solid var(--paper-line);
  border-top: 3px solid var(--royal);
  border-radius: var(--radius);
  padding: 0.9rem 1rem;
}
.count b {
  display: block;
  font-size: 2.1rem;
  line-height: 1.05;
  font-variant-numeric: tabular-nums lining-nums;
}
.count span {
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--on-paper-soft);
  font-weight: 600;
}

/* ---------------------------------------------------------------------------
   The duplicate warning. This one is allowed to shout.
   ------------------------------------------------------------------------ */

.warn {
  border: 2px solid var(--caution);
  border-left-width: 6px;
  background: var(--caution-bg);
  border-radius: var(--radius);
  padding: 1.1rem var(--gut);
  margin-bottom: 1.5rem;
}
.warn h2 { color: var(--caution); }

/* ---------------------------------------------------------------------------
   STOP. The hard refusal.

   There is one of these in the system and it belongs to the wrong-surgery
   guard: a booking that disagrees with the clearance that authorised it. It is
   not a warning somebody clicks past, so it does not look like one. Nothing
   else in this stylesheet is allowed to borrow it.
   ------------------------------------------------------------------------ */

.stop {
  border: 3px solid var(--alarm);
  border-left-width: 10px;
  background: var(--alarm-bg);
  border-radius: var(--radius);
  padding: 1.2rem var(--gut);
  margin-bottom: 1.5rem;
}
.stop h2 { color: var(--alarm); font-size: 1.5rem; letter-spacing: 0.04em; text-transform: uppercase; }
.stop p { margin: 0.4rem 0 0; font-weight: 600; font-size: 1.02rem; }

.stop-word {
  color: var(--alarm);
  letter-spacing: 0.12em;
  font-size: 0.95rem;
}
tbody tr.row-stop { background: var(--alarm-bg); }
tbody tr.row-stop:hover { background: var(--alarm-bg); }
.stop-cell { color: var(--alarm); font-weight: 600; }

.agrees { color: var(--good); font-weight: 600; }
.warn-word { color: var(--caution); font-weight: 700; }
.warn-inline {
  border-left: 4px solid var(--caution);
  background: var(--caution-bg);
  color: var(--caution);
  font-weight: 600;
  padding: 0.6rem 0.9rem;
}
tbody tr.row-overdue { background: var(--caution-bg); }
.phone-cell { font-size: 1.05rem; font-weight: 700; white-space: nowrap; }

/* ---------------------------------------------------------------------------
   The restricted block.

   One block in the system carries HIV and hepatitis B, and it renders only for
   a role that holds serology.view. It is fenced so that nobody reading over a
   shoulder mistakes it for the rest of the form, and so that a screenshot of it
   is obviously a screenshot of something restricted.
   ------------------------------------------------------------------------ */

.restricted {
  border: 2px solid var(--ink);
  border-left-width: 6px;
  border-radius: var(--radius);
  background: #fff;
  padding: 1rem 1.1rem;
}
.restricted-note {
  margin: 0 0 0.9rem;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink);
}

/* ---------------------------------------------------------------------------
   The decision box: the one tick on a form that is the point of the form
   ------------------------------------------------------------------------ */

.decision {
  border: 2px solid var(--royal);
  border-radius: var(--radius);
  padding: 0.9rem 1rem;
  background: #eef3fb;
}
.decision.bad { border-color: var(--alarm); background: var(--alarm-bg); }

.tick-big {
  font-size: 1.02rem;
  padding: 0.7rem 0.9rem;
  align-items: flex-start;
  width: 100%;
}
.tick-big input { width: 1.4rem; height: 1.4rem; margin-top: 0.1rem; }

/* ---------------------------------------------------------------------------
   Form 4: two columns, one per eye

   The paper form is laid out this way and a specialist reading off a slit lamp
   works one eye at a time. On a narrow screen they stack, right first, and each
   keeps its shape marker so the order is never the only thing telling them
   apart.
   ------------------------------------------------------------------------ */

.eye-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 1.25rem;
}

.eye-col {
  border: 1px solid var(--paper-line);
  border-radius: var(--radius);
  padding: 1rem;
  background: #fff;
}
.eye-col .field { margin-bottom: 0.8rem; }

.eye-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 2px solid var(--on-paper);
  font-size: 1.02rem;
}

textarea.short-area { min-height: 3.4rem; }

/* The five numbers a surgeon acts on. Set larger than the rest of the form,
   in tabular figures, because a decimal place read wrong here is a bad lens. */
.investigation {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  gap: 0.7rem;
}
.investigation .field { margin-bottom: 0; }

input.big, b.big { font-size: 1.25rem; font-weight: 700; }

.unit {
  font-weight: 600;
  color: var(--on-paper-soft);
  text-transform: none;
  letter-spacing: 0;
}

.readout {
  border: 1px solid var(--paper-line);
  border-radius: var(--radius);
  padding: 0.5rem 0.6rem;
  background: var(--paper);
}
.readout-label {
  display: block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--on-paper-soft);
}

/* ---------------------------------------------------------------------------
   Checklists read back, and small tallies
   ------------------------------------------------------------------------ */

.checked { list-style: none; margin: 0.6rem 0 0; padding: 0; }
.checked li {
  padding: 0.35rem 0 0.35rem 1.8rem;
  position: relative;
  border-bottom: 1px solid var(--paper-line);
}
.checked li::before {
  position: absolute;
  left: 0;
  font-weight: 700;
}
.checked li.yes::before { content: '\2713'; color: var(--good); }
.checked li.no::before { content: '\2014'; color: var(--on-paper-soft); }
.checked li.no { color: var(--on-paper-soft); }

.tally { list-style: none; margin: 0.6rem 0 0; padding: 0; display: flex; gap: 1.5rem; flex-wrap: wrap; }
.tally b { font-size: 1.6rem; display: block; font-variant-numeric: tabular-nums lining-nums; }

tfoot tr.total th,
tfoot tr.total td {
  border-top: 2px solid var(--on-paper);
  border-bottom: 0;
  font-weight: 700;
  font-size: 1rem;
  color: var(--on-paper);
  text-transform: none;
  letter-spacing: 0;
  padding-top: 0.7rem;
}

textarea.rx { min-height: 12rem; line-height: 1.6; }

/* ---------------------------------------------------------------------------
   The patient file's pathway strip

   Clearance, consent, pre-operation, surgery and follow-up as five states of
   one file rather than five records, which is what the manual says they are.
   ------------------------------------------------------------------------ */

.pathway {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
  gap: 0.7rem;
  margin-bottom: 1.25rem;
}

.step {
  border: 1px solid var(--paper-line);
  border-top: 3px solid var(--paper-line);
  border-radius: var(--radius);
  background: var(--paper);
  padding: 0.7rem 0.8rem;
}
.step-name {
  display: block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--on-paper-soft);
}
.step b { display: block; font-size: 0.98rem; margin-top: 0.15rem; }
.step small { display: block; color: var(--on-paper-soft); font-size: 0.74rem; }

.step-done { border-top-color: var(--good); }
.step-done b { color: var(--good); }
.step-waiting { border-top-color: var(--caution); }
.step-waiting b { color: var(--caution); }
.step-blocked { border-top-color: var(--alarm); }
.step-blocked b { color: var(--alarm); }

/* Small controls that sit inside a table row, so an administrator can change a
   role or hand over a password without leaving the list. */
.inline-form {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  margin: 0;
}
.inline-form select,
.inline-form input { width: auto; min-width: 9rem; min-height: 2.4rem; padding: 0.35rem 0.5rem; }

.btn-small {
  font-size: 0.85rem;
  padding: 0.4rem 0.7rem;
  min-height: 2.4rem;
}

/* The role picker: each option carries what it actually lets somebody see,
   because one of the six decides who can read a serostatus. */
.role-list { display: grid; gap: 0.5rem; }
.role-list .tick-big { align-items: flex-start; }
.role-list .tick-big small {
  display: block;
  font-weight: 400;
  font-size: 0.82rem;
  color: var(--on-paper-soft);
  margin-top: 0.15rem;
}
.role-list.bad { outline: 2px solid var(--alarm); outline-offset: 4px; }

/* ---------------------------------------------------------------------------
   Login. The one screen with no chrome.
   ------------------------------------------------------------------------ */

.gate {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: var(--gut);
  background: var(--ink);
  background-image: radial-gradient(
    120% 80% at 50% -10%, var(--ink-raise) 0%, var(--ink) 55%, var(--ink-deep) 100%
  );
}

.gate-card {
  width: min(26rem, 100%);
  background: var(--paper);
  border-radius: var(--radius);
  padding: 2rem;
  border-top: 4px solid var(--gold);
}

/* Small on purpose. This is a sign-in box, not a poster: at full size the
   foundation's logo fills a phone screen and the two fields fall below the
   fold. */
.gate img { display: block; width: 5.5rem; height: auto; margin: 0 auto 1.5rem; }

.gate h1 { font-size: 1.15rem; text-align: center; }
.gate .sub { text-align: center; font-size: 0.88rem; margin-bottom: 1.5rem; }
.gate .btn { width: 100%; }

.gate-err {
  background: var(--alarm-bg);
  border-left: 4px solid var(--alarm);
  color: var(--alarm);
  font-weight: 600;
  font-size: 0.9rem;
  padding: 0.7rem 0.9rem;
  margin-bottom: 1.1rem;
}

/* ---------------------------------------------------------------------------
   The manual

   One long page of prose in an application otherwise made of forms and tables,
   so it needs two things nothing else here does: a line short enough to read a
   paragraph in, and headings a contents list can land on.

   Nothing new is introduced for it. No font, no colour, no component. A help
   page that looked like a different product would be read as a different
   product.
   ------------------------------------------------------------------------ */

/* Everything the manual needs is a class, and there is not one inline style on
   that page. `style-src 'self'` has no 'unsafe-inline', so a style attribute is
   refused by the browser and the rule simply never happens. Sixty-eight of them
   are sitting in the other views doing nothing. */

.prose { max-width: 42rem; }
.prose p, .prose ul, .prose ol { margin: 0 0 0.9rem; }
.prose li { margin-bottom: 0.35rem; }
.prose h3 { margin-top: 1.6rem; }
.prose > :last-child { margin-bottom: 0; }

/* The text that follows the table of who may do what. */
.table-wrap + .prose { margin-top: 1.5rem; }

/* Arriving from the contents list, the heading lands clear of the top edge
   rather than flush against it. */
.card[id] { scroll-margin-top: 1rem; }

.toc {
  columns: 2 15rem;
  gap: 1.5rem;
  margin: 0.6rem 0 0;
  padding-left: 1.3rem;
}
.toc li { margin-bottom: 0.35rem; break-inside: avoid; }
.toc a { color: var(--royal); font-weight: 600; }

/* The table of who may do what. Its first column is a sentence, not a column
   heading, so it does not get the small upright capitals the others have. */
.roles th[scope="row"] {
  font-size: 0.94rem;
  text-transform: none;
  letter-spacing: 0;
  color: var(--on-paper);
  white-space: normal;
  border-bottom: 1px solid var(--paper-line);
}
.roles td.no { color: var(--on-paper-soft); }

/* A rule on the manual page that must not be skimmed past. The same blue as the
   decision box on a clinical form, because it is the same kind of statement. */
.callout {
  border: 2px solid var(--royal);
  border-radius: var(--radius);
  background: #eef3fb;
  padding: 0.9rem 1.1rem;
  margin: 0 0 1.25rem;
  max-width: 42rem;
}
.callout p { margin: 0; }
.prose .callout { margin-top: 1.25rem; }

/* A message the software puts on screen, quoted as the person saw it, so what
   they are looking for is what they are scanning for. */
.said {
  font-weight: 700;
  font-size: 1rem;
  color: var(--on-paper);
}
.prose .said { margin: 1.6rem 0 0.3rem; }
.prose .said:first-child { margin-top: 0; }

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.92em;
  background: var(--paper-deep);
  border: 1px solid var(--paper-line);
  border-radius: 2px;
  padding: 0.05em 0.3em;
  white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   Footer
   ------------------------------------------------------------------------ */

.foot {
  border-top: 1px solid var(--paper-line);
  padding: 1.5rem var(--gut) 2.5rem;
  max-width: var(--wrap);
  margin: 0 auto;
  color: var(--on-paper-soft);
  font-size: 0.8rem;
}
.foot p { margin: 0.2rem 0; }
.foot-warn { font-weight: 600; }

/* ---------------------------------------------------------------------------
   Print. The hospital runs on paper and the software does not get to ignore it.
   ------------------------------------------------------------------------ */

@media print {
  .chrome, .foot, .actions, .nav, .skip { display: none !important; }
  body { background: #fff; }
  .card { border: 0; padding: 0; }
}

/* Motion: there is almost none, and what exists is a state change. */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
