/* Enterprise Rising program portal.
   Aesthetic: an institutional field ledger -- warm archival paper, ink navy, Alabama clay.
   Ruled hairlines instead of drop shadows, tabular figures everywhere a number matters,
   and enough density to work as a working record rather than a marketing page. */

/* ---------------------------------------------------------------- type ---- */
/* Self-hosted from /fonts/, so text no longer waits on two third-party connections before it can
   render in its own face. Latin subset only: the record is kept in English, and anything outside
   the range falls through to the system font rather than downloading another file. Fraunces is
   cut to the 400-700 weights the stylesheets use, with its full optical-size axis kept so the
   80px gate title and a 15px card heading each get the cut drawn for their size. The italic is the
   single 400 face it always was. The same block is in apply/apply.css; keep the two in step.
   Licences: /fonts/OFL.txt. */
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/fraunces-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Fraunces";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/fraunces-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/archivo-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/ibm-plex-mono-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/ibm-plex-mono-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Fallbacks reshaped to the web fonts' measure. Until a face arrives, the system font standing in
   for it is scaled to the same average letter width and given the same ascent and descent, so a
   line wraps where it will wrap in the real face and the swap does not shove the page down. The
   figures come from each pair's English-text advance widths and typographic ascent/descent. Arial
   stands in on Apple and Windows and Roboto on Android; the two measure within 1% of each other,
   so they share one set. Where none of these is installed the face is skipped and the stack below
   carries on to the generic family, exactly as before. */
@font-face {
  font-family: "Fraunces Fallback";
  font-style: normal;
  src: local("Georgia");
  size-adjust: 108%;
  ascent-override: 90.55%;
  descent-override: 23.61%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Fraunces Fallback";
  font-style: italic;
  src: local("Georgia Italic"), local("Georgia-Italic");
  size-adjust: 92.21%;
  ascent-override: 106.06%;
  descent-override: 27.65%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Archivo Fallback";
  src: local("Arial"), local("ArialMT"), local("Roboto");
  size-adjust: 98.7%;
  ascent-override: 88.96%;
  descent-override: 21.28%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "IBM Plex Mono Fallback";
  src: local("Courier New"), local("CourierNewPSMT");
  size-adjust: 100%;
  ascent-override: 102.52%;
  descent-override: 27.5%;
  line-gap-override: 0%;
}

:root {
  --paper: #f4efe6;
  --paper-2: #ece5d8;
  --paper-3: #e2d9c8;
  --ink: #1c2230;
  --ink-2: #2b3444;
  --ink-soft: #566175;
  --ink-faint: #8b93a3;
  --clay: #a6512f;
  --clay-deep: #823d21;
  --moss: #4c6a48;
  --gold: #9d7818;
  --rule: rgba(28, 34, 48, 0.14);
  --rule-strong: rgba(28, 34, 48, 0.28);
  --shadow: 0 1px 0 rgba(28, 34, 48, 0.06), 0 12px 28px -22px rgba(28, 34, 48, 0.5);

  --display: "Fraunces", "Fraunces Fallback", Georgia, serif;
  --body: "Archivo", "Archivo Fallback", "Helvetica Neue", sans-serif;
  --mono: "IBM Plex Mono", "IBM Plex Mono Fallback", ui-monospace, monospace;

  --rail-w: 15rem;
  /* The collapsed rail is exactly wide enough for a 1.05rem glyph on a 2.5rem tap target plus the
     hairline it sits against, so an icon lands on the same optical centre in both states. */
  --rail-w-mini: 3.9rem;
  --topbar-h: 4.25rem;
  /* Height of the phone bottom bar, reserved as stage padding and used to lift the toast and the
     deploy notice clear of it. */
  --navbar-h: 3.85rem;
}

* { box-sizing: border-box; }

/* `hidden` has to actually hide.

   The browser hides it with a plain `[hidden] { display: none }` in the user agent stylesheet, and
   any author rule beats the user agent no matter how weak its selector -- so a component that
   states its own `display` silently defeats the attribute. Several here do: `.gate` and `.shell`
   are grids, `.authform` and `.update` are flex, and all four are shown and hidden from JavaScript
   by setting `.hidden`. The deploy notice was the visible casualty: it stated `display: flex`, so
   it stood on screen from the first paint of every page load, and neither pressing Refresh (which
   reloads onto markup that carries the attribute) nor pressing Later (which sets it) could put it
   away again.

   `!important` rather than source order, because order only holds while every such rule stays
   weaker than a bare attribute selector -- one `#update.update` or `body:has(...) .update` and the
   notice is unhideable again, in a way that looks like a bug in the update logic rather than here.
   Nothing in this portal styles a hidden element to be visible on purpose. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
  /* Turning an iPhone to landscape otherwise makes Safari inflate body text on its own to fill
     the wider column, which re-wraps every ledger table mid-read. The ledgers are laid out in
     rem against a known base, so the base has to stay put. This suppresses Safari's automatic
     inflation only; it does not stop anyone zooming, and Text Size in Settings still applies. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* Paper grain: fixed, non-interactive, so it never taxes a scrolling table. */
.grain {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9;
  opacity: 0.42;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.22'/%3E%3C/svg%3E");
}

/* While the sign-in screen is up the page is black, so the paper tokens have to stand down:
   the body behind it (which shows on an overscroll bounce) and the grain, whose multiply blend
   would only smear the black. Screened at low opacity instead, it reads as film grain on the
   seal rather than dirt on paper. */
body:has(#gate:not([hidden])) { background: #0a0b0e; }
body:has(#gate:not([hidden])) .grain { opacity: 0.5; mix-blend-mode: screen; }

h1, h2, h3, h4 { font-family: var(--display); font-weight: 600; letter-spacing: -0.015em; margin: 0; }
em { font-style: italic; }
a { color: var(--clay-deep); }

/* Keyboard focus. Components that need a different colour or offset set their own below; this is
   the floor, so nothing that takes focus is ever left without a visible ring. Text fields keep
   their border-and-underline treatment on :focus as well. */
:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible { outline: 2px solid var(--clay); outline-offset: 2px; }
.omni__field:has(input:focus-visible) { outline: 2px solid var(--gold); outline-offset: 1px; }

/* Skip link: off-screen until a keyboard reaches it, then pinned to the top-left corner. */
.skip { position: fixed; left: -9999px; top: 0.5rem; z-index: 100; background: var(--ink); color: var(--paper); padding: 0.5rem 1rem; border-radius: 2px; text-decoration: none; }
.skip:focus { left: 0.5rem; }

/* The program badge. It is a full-colour lockup on a transparent field, so on the dark topbar it
   sits on a light chip and elsewhere it drops straight onto the paper. The sign-in screen uses
   the struck black-and-gold seal instead, sized with the rest of the gate. */
.mark { width: 1.5rem; height: 1.5rem; object-fit: contain; }
.mark--bar { width: 2.1rem; height: 2.1rem; padding: 0.12rem; border-radius: 3px; background: var(--paper); flex: none; }
.mark--boot { width: 6.5rem; height: 6.5rem; }

/* ---------------------------------------------------------------- gate ---- */

/* The sign-in screen is struck in black and gold, because the program badge is: a gilded seal on
   a black field. The rest of the portal stays on warm archival paper -- this is the one screen
   whose job is to say whose record this is before anyone is inside it, and a struck seal says it
   in a way a paper form cannot. Every rule below is scoped under .gate so none of it reaches the
   application behind it.

   Two columns that do different jobs. The left is the seal: the badge, the award, and the notice
   that opening the record is logged. The right is one card holding the four auth flows,
   deliberately narrow, so the eye lands on the field it has to fill in. */
.gate {
  /* Gate-local palette. Named for what they are on this screen, not for the paper tokens they
     replace, so nothing here can be mistaken for an application-wide colour. */
  --seal: #0a0b0e;
  --seal-2: #14161c;
  --seal-3: #1b1e26;
  --foil: #e6c56c;
  --foil-deep: #b8912f;
  --foil-line: rgba(230, 197, 108, 0.22);
  --foil-line-soft: rgba(230, 197, 108, 0.12);
  --cream: #f3eee2;
  --cream-soft: rgba(243, 238, 226, 0.72);
  --cream-faint: rgba(243, 238, 226, 0.58);

  min-height: 100dvh;
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  background: var(--seal);
  color: var(--cream);
  /* The boot splash it replaces is warm paper, so an instant swap flashes light-to-black. The
     body has already gone black underneath by this point, so fading the seal in means the
     transition is only ever black to gilt. */
  animation: strike 0.45s ease both;
}
@keyframes strike { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .gate { animation: none; }
}

/* The seal panel. Three layers: a gilded engine-turned hatch of the kind printed on a
   certificate, a low pool of light behind the badge, and the black ground under both. */
.gate__seal {
  position: relative;
  padding: clamp(2rem, 5vw, 4.5rem) clamp(1.75rem, 4.5vw, 4rem);
  padding-left: clamp(2.75rem, 6vw, 5.5rem);
  background:
    repeating-linear-gradient(52deg, var(--foil-line-soft) 0 1px, transparent 1px 9px),
    radial-gradient(58% 44% at 26% 24%, rgba(230, 197, 108, 0.13), transparent 70%),
    linear-gradient(165deg, var(--seal-3), var(--seal) 62%);
  border-right: 1px solid var(--foil-line);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(1.25rem, 2.5vw, 2rem);
}

/* Gilt margin rule, struck down the panel like the border of a certificate. */
.gate__seal::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 clamp(1.5rem, 3.4vw, 3rem);
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--foil-deep) 18%, var(--foil-deep) 82%, transparent);
  opacity: 0.5;
}

/* Badge and the line that places it. The badge is already a ring of type, so it is given room
   and nothing is drawn on top of it. */
.gate__crest { display: flex; align-items: center; gap: clamp(0.9rem, 2vw, 1.4rem); }

.mark--gate {
  width: clamp(6.5rem, 12vw, 10.5rem);
  height: auto;
  aspect-ratio: 1;
  /* A struck medal catches light: the glow reads as the metal, not as a drop shadow. */
  filter: drop-shadow(0 6px 18px rgba(0, 0, 0, 0.6)) drop-shadow(0 0 22px rgba(230, 197, 108, 0.16));
}

.gate__brandline {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin: 0;
  padding-left: clamp(0.9rem, 2vw, 1.3rem);
  border-left: 1px solid var(--foil-line);
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.gate__brandline span:first-child { color: var(--foil); }
.gate__brandline span + span { color: var(--cream-faint); letter-spacing: 0.14em; }

/* Stamp, lede and blurb read as one block, so they are spaced tighter than the sections. */
.gate__lede { display: flex; flex-direction: column; gap: 0.85rem; }

/* The one thing a stranger needs to read first. Set like a stamp pressed into the margin of a
   file: small, ruled in gilt, and unmistakably not an invitation. */
.gate__stamp {
  align-self: flex-start;
  margin: 0;
  padding: 0.32rem 0.6rem;
  border: 1px solid var(--foil-line);
  border-radius: 2px;
  background: rgba(230, 197, 108, 0.08);
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--foil);
}

.gate__title { font-size: clamp(2.85rem, 6.4vw, 5rem); line-height: 0.92; color: var(--cream); }
/* Gold leaf, not flat gold: the gradient is what stops a warm hex value reading as mustard. */
.gate__title em {
  background: linear-gradient(104deg, var(--foil-deep) 4%, #f7e6ae 42%, var(--foil) 68%, var(--foil-deep) 98%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* The italic l leans past its advance width, and background-clip:text paints only inside the box,
     so the box is widened to cover the overhang and the margin gives the width back to the layout. */
  padding-right: 0.12em;
  margin-right: -0.12em;
}
/* Gold leaf is painted, and a forced-colours mode strips the paint -- which would leave the
   second half of the page's own title as a transparent hole. */
@media (forced-colors: active) {
  .gate__title em { background: none; color: CanvasText; }
}

.gate__sub { max-width: 36ch; color: var(--cream-soft); font-size: 1rem; margin: 0; }

.gate__facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 2.5rem;
  margin: 0;
  padding-top: 1.15rem;
  border-top: 1px solid var(--foil-line);
}
.gate__facts dt { font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--foil-deep); }
.gate__facts dd { margin: 0.2rem 0 0; font-family: var(--mono); font-size: 0.9rem; color: var(--cream); }

/* The audit warning. Quiet by design -- it is a standing condition of use, not an alarm. */
.gate__legal {
  margin: 0;
  max-width: 46ch;
  padding-left: 0.7rem;
  border-left: 2px solid var(--foil-deep);
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--cream-faint);
}

/* The organization's website, under the audit warning. Stays on the phone, where the warning goes. */
.gate__org { margin: 0; font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.04em; }
.gate__orglink { color: var(--foil); text-decoration: underline; text-underline-offset: 2px; }
.gate__orglink:hover { color: #f7e6ae; }
.gate__orglink:focus-visible { outline: 2px solid var(--foil); outline-offset: 2px; }

.gate__panel {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.9rem;
  padding: clamp(1.5rem, 4vw, 3.5rem);
  width: 100%;
  max-width: 30rem;
  /* Centred in its column rather than pinned to the gilt divider: on a black ground a card
     pushed to one side reads as a layout that ran out of room. */
  justify-self: center;
}

/* One card, not four screens. Whichever flow is showing, it occupies the same frame in the same
   place, so switching tabs never moves the form out from under the cursor. Lifted off the black
   by a gilt top edge rather than a shadow, which black swallows. */
.gate__card {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  padding: clamp(1.1rem, 2.4vw, 1.6rem);
  background: linear-gradient(180deg, var(--seal-3), var(--seal-2) 70%);
  border: 1px solid var(--foil-line);
  border-top: 2px solid var(--foil-deep);
  border-radius: 2px;
  box-shadow: 0 26px 50px -30px #000, inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.gate__cardhead { display: flex; flex-direction: column; gap: 0.7rem; }
.gate__eyebrow {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--foil-deep);
}

.gate__help {
  margin: 0;
  padding-left: 0.2rem;
  font-size: 0.78rem;
  color: var(--cream-faint);
  max-width: 44ch;
}

/* ------------------------------------------------- gate: form furniture ---- */

/* The controls inside the card are the application's own -- tabs, fields, buttons, the notice
   line -- re-dressed for a black ground. Scoped to .gate so the paper originals are untouched. */

.gate .tabs { background: rgba(0, 0, 0, 0.45); border-color: var(--foil-line); }
.gate .tabs__btn { color: var(--cream-faint); }
.gate .tabs__btn:hover { color: var(--cream); background: rgba(230, 197, 108, 0.1); }
.gate .tabs__btn:focus-visible { outline-color: var(--foil); }
.gate .tabs__btn.is-active {
  background: linear-gradient(180deg, #f0d68f, var(--foil-deep));
  color: #17130a;
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.35);
}

.gate .field > span { color: var(--foil-deep); }
.gate .field > small { color: var(--cream-faint); }

.gate input,
.gate select,
.gate textarea {
  background: rgba(0, 0, 0, 0.35);
  border-color: var(--foil-line);
  color: var(--cream);
}
.gate input::placeholder { color: rgba(243, 238, 226, 0.45); }
.gate input:focus,
.gate select:focus,
.gate textarea:focus {
  border-color: var(--foil);
  background: rgba(0, 0, 0, 0.5);
  box-shadow: inset 0 -2px 0 rgba(230, 197, 108, 0.4);
}
/* Chrome paints autofilled inputs pale yellow, which on this card looks like a fault. There is
   no property for the fill, so the inset shadow is the background. */
.gate input:-webkit-autofill,
.gate input:-webkit-autofill:hover,
.gate input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--cream);
  caret-color: var(--cream);
  -webkit-box-shadow: inset 0 0 0 40rem #101216;
}

.gate .authform__lead, .gate .authform__note { color: var(--cream-soft); }
.gate .authform__lead { border-left-color: var(--foil-deep); }

.gate .linkbtn { color: var(--foil); }
.gate .linkbtn:hover { color: #f7e6ae; }
.gate .linkbtn:focus-visible { outline-color: var(--foil); }

.gate .pwfield__eye { color: var(--cream-faint); }
.gate .pwfield__eye:hover { color: var(--foil); background: rgba(230, 197, 108, 0.12); }

/* Both primary actions are gilt: only one flow is on screen at a time, so they never compete. */
.gate .btn--ink,
.gate .btn--clay {
  background: linear-gradient(180deg, #f2daa0, var(--foil-deep));
  border-color: rgba(0, 0, 0, 0.35);
  color: #17130a;
  font-weight: 600;
  letter-spacing: 0.06em;
}
.gate .btn--ink:hover,
.gate .btn--clay:hover { background: linear-gradient(180deg, #f7e6ae, #c79c33); }
.gate .btn:focus-visible { outline: 2px solid var(--foil); outline-offset: 2px; }

.gate .notice {
  border-left-color: var(--foil-deep);
  background: rgba(230, 197, 108, 0.09);
  color: var(--cream);
}
.gate .notice--good { border-left-color: #9dc08b; background: rgba(157, 192, 139, 0.12); }

/* The "?" bubbles on the claim-seat pane. Inverted: a cream bubble reads on black where the
   application's ink one would disappear into the card. */
.gate .field__ask { border-color: var(--foil-line); color: var(--cream-faint); }
.gate .field__ask:hover,
.gate .field__hint[data-open="true"] .field__ask { background: var(--foil-deep); border-color: var(--foil-deep); color: #17130a; }
.gate .field__bubble {
  background: var(--cream);
  border-color: var(--cream);
  color: #17130a;
  box-shadow: 0 8px 22px rgb(0 0 0 / 0.55);
}
.gate .field__bubble::after { border-top-color: var(--cream); }
.gate .field__hint--below .field__bubble::after { border-top-color: transparent; border-bottom-color: var(--cream); }
/* A segmented control rather than three underlined words: it reads as a switch you can press,
   which is what it is, and the selected segment holds its own ground on a small screen. */
.tabs {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 2px;
  padding: 2px;
  background: var(--paper-3);
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
}
.tabs__btn {
  -webkit-appearance: none;
  appearance: none;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 0.76rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 0.5rem 0.55rem;
  cursor: pointer;
  border-radius: 1px;
  white-space: nowrap;
  transition: background 0.15s ease, color 0.15s ease;
}
.tabs__btn:hover { color: var(--ink); background: rgba(255, 255, 255, 0.55); }
.tabs__btn:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
.tabs__btn.is-active {
  background: var(--ink);
  color: var(--paper);
  box-shadow: inset 0 -2px 0 var(--clay);
}

.authform { display: flex; flex-direction: column; gap: 0.9rem; animation: rise 0.4s ease both; }
.authform__lead, .authform__note { margin: 0; font-size: 0.85rem; color: var(--ink-soft); }
.authform__lead {
  padding-left: 0.65rem;
  border-left: 2px solid var(--clay);
  line-height: 1.45;
}
.authform__note { font-size: 0.8rem; line-height: 1.45; }
.authform__note + .authform__note { margin-top: -0.5rem; }

/* Password field with a reveal control sitting inside the input's own frame. */
.pwfield { position: relative; display: block; }
.pwfield > input { padding-right: 4.25rem; }
.pwfield__eye {
  position: absolute;
  top: 50%;
  right: 0.3rem;
  transform: translateY(-50%);
  -webkit-appearance: none;
  appearance: none;
  border: 0;
  background: none;
  font: inherit;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 0.35rem 0.45rem;
  border-radius: 2px;
  cursor: pointer;
}
.pwfield__eye:hover { color: var(--clay-deep); background: rgba(166, 81, 47, 0.08); }
.pwfield__eye:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }

/* -------------------------------------------------------------- fields ---- */

.field { display: flex; flex-direction: column; gap: 0.3rem; }
.field > span { font-size: 0.72rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-soft); }
.field > small { font-size: 0.75rem; color: var(--ink-faint); }

input, select, textarea {
  font: inherit;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.68);
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  padding: 0.6rem 0.7rem;
  width: 100%;
  transition: border-color 0.15s ease, background 0.15s ease;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--clay);
  background: #fff;
  box-shadow: inset 0 -2px 0 rgba(166, 81, 47, 0.25);
}
textarea { min-height: 5.5rem; resize: vertical; }
input[type="checkbox"] { width: 1.05rem; height: 1.05rem; accent-color: var(--clay); }

/* Typing on an iPhone or iPad.

   Safari on iOS zooms the whole viewport in whenever a field it is about to focus carries text
   under 16px, and it does not zoom back out afterwards. The body is set at 15px and every control
   here inherits it, so this fired on the very first tap of the sign-in email field and left the
   portal magnified and scrolled sideways for the rest of the session -- through intake, through
   the case notes, through a compliance sheet being filled in at a training kitchen.

   16px on touch pointers is the only fix that keeps zooming available. The other way round it is
   usually done -- `maximum-scale=1` on the viewport -- stops the zoom by taking pinch-zoom away
   from everyone, which on a records system read off a phone is a straight loss.

   `!important` because this has to hold over every component that sets a smaller size on a field
   of its own (the omnibox, the assistant composer, the ruled cells in a compliance instrument),
   and because a future one that does the same must not quietly bring the zoom back. Scoped to
   `screen` so none of it reaches the print stylesheet, which sets those same fields in points and
   owns what comes off the printer. */
@media screen and (any-pointer: coarse) {
  input, select, textarea { font-size: 16px !important; }
  /* The ruled cells in a compliance instrument are sized to a printed row. At 16px the text no
     longer fits the row height, so on a phone the row gives way instead of the answer. */
  .formdoc__cell-input { height: auto; min-height: 1.75rem; }
  .formdoc__signfill { height: auto; min-height: 1.9rem; }
  /* Same reason, sideways: these two are sized to hold a quantity and a dollar amount at the
     smaller text, and a draw amount that is cut off at the right edge is worse than a wide box. */
  input.formdoc__qty { width: 3.4rem; }
  .formdoc__money input.formdoc__write { width: 6.6rem; }
}

.check { flex-direction: row; align-items: center; gap: 0.55rem; }
.check { flex-wrap: wrap; }
.check > span { text-transform: none; letter-spacing: 0; font-size: 0.9rem; color: var(--ink); }
.check > input[type="checkbox"] { flex: 0 0 auto; }
.check > small { flex: 1 0 100%; margin-left: 1.6rem; }

/* --------------------------------------------------------------- button ---- */

.btn {
  -webkit-appearance: none;
  appearance: none;
  font: inherit;
  font-size: 0.86rem;
  letter-spacing: 0.04em;
  border-radius: 2px;
  padding: 0.62rem 1.05rem;
  cursor: pointer;
  border: 1px solid transparent;
  transition: transform 0.12s ease, background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.5; cursor: progress; }

.btn--ink { background: var(--ink); color: var(--paper); }
.btn--ink:hover { background: var(--ink-2); }
.btn--clay { background: var(--clay); color: #fdf7ef; }
.btn--clay:hover { background: var(--clay-deep); }
.btn--ghost { background: transparent; border-color: var(--rule-strong); color: var(--ink-soft); }
.btn--ghost:hover { border-color: var(--ink); color: var(--ink); }
.btn--tiny { padding: 0.3rem 0.55rem; font-size: 0.76rem; }
/* Full-width primary action, for a form whose only next step is to submit it. */
.btn--wide { width: 100%; justify-content: center; padding-block: 0.72rem; }
.btn--danger { background: transparent; border-color: rgba(130, 61, 33, 0.4); color: var(--clay-deep); }
.btn--danger:hover { background: rgba(166, 81, 47, 0.1); }

/* --------------------------------------------------------------- shell ---- */

.shell {
  min-height: 100dvh;
  display: grid;
  grid-template-columns: var(--rail-w) 1fr;
  grid-template-rows: var(--topbar-h) 1fr;
  /* Collapsing the rail moves the whole stage left, and doing it in one frame reads as a layout
     bug rather than a deliberate fold. Browsers that will not interpolate a track list simply
     snap, which is the old behaviour and no worse than it was. */
  transition: grid-template-columns 0.22s ease;
}

.topbar {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0 clamp(0.9rem, 2vw, 1.5rem);
  background: var(--ink);
  color: var(--paper);
  position: sticky;
  top: 0;
  z-index: 6;
}
.topbar__lead { display: flex; align-items: center; gap: 0.6rem; min-width: 0; }
.topbar__brand { display: flex; align-items: center; gap: 0.7rem; min-width: 0; }
.topbar__brand > div { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.topbar__brand strong { font-family: var(--display); font-size: 1.02rem; letter-spacing: -0.01em; }
.topbar__brand span { font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(244, 239, 230, 0.6); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar__right { display: flex; align-items: center; gap: 0.6rem; }

/* Rail control. A quiet outline on the ink ground -- it is chrome for the chrome, and must not
   compete with the brand beside it or the seat plate opposite. The tap target is 2.5rem square
   even though the glyph is half that, because on a laptop trackpad this is hit repeatedly. */
.navtoggle {
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(244, 239, 230, 0.2);
  border-radius: 2px;
  background: rgba(244, 239, 230, 0.04);
  color: rgba(244, 239, 230, 0.72);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.navtoggle:hover { background: rgba(244, 239, 230, 0.1); color: var(--paper); border-color: rgba(244, 239, 230, 0.38); }
.navtoggle svg { width: 1.2rem; height: 1.2rem; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
/* The chevron points the way the rail is about to move, so the button says what it will do rather
   than what state the rail is in. Rotated about its own centre so the box and divider stay put. */
.navtoggle__arrow { transform-origin: 14.3px 12px; transition: transform 0.2s ease; }

/* Refresh. The same quiet outline as the rail control, with a word beside the glyph on anything
   wider than a phone. It spins while the page is on its way out, so a slow reload on a kitchen
   connection does not look like a button that did nothing. */
.refreshbtn {
  flex: none;
  height: 2.5rem;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0 0.75rem;
  border: 1px solid rgba(244, 239, 230, 0.2);
  border-radius: 2px;
  background: rgba(244, 239, 230, 0.04);
  color: rgba(244, 239, 230, 0.8);
  font: inherit;
  font-size: 0.8rem;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.refreshbtn:hover { background: rgba(244, 239, 230, 0.1); color: var(--paper); border-color: rgba(244, 239, 230, 0.38); }
.refreshbtn:disabled { cursor: progress; opacity: 0.7; }
.refreshbtn svg { width: 1.1rem; height: 1.1rem; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.refreshbtn.is-busy svg { animation: refreshbtn-spin 0.8s linear infinite; }
@keyframes refreshbtn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .refreshbtn.is-busy svg { animation: none; } }
@media (max-width: 52rem) {
  .refreshbtn { width: 2.5rem; padding: 0; justify-content: center; }
  .refreshbtn__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}

/* The seat plate: a stamped personnel plate carrying seat number and role. */
.plate {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.3rem 0.55rem 0.3rem 0.3rem;
  border: 1px solid rgba(244, 239, 230, 0.22);
  border-radius: 2px;
  background: rgba(244, 239, 230, 0.05);
}
.plate__num {
  font-family: var(--mono);
  font-size: 0.8rem;
  width: 1.65rem;
  height: 1.65rem;
  display: grid;
  place-items: center;
  background: var(--clay);
  color: #fdf7ef;
  border-radius: 2px;
}
.plate__who { display: flex; flex-direction: column; line-height: 1.15; }
.plate__who b { font-size: 0.82rem; font-weight: 600; }
.plate__who span { font-size: 0.68rem; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(244, 239, 230, 0.62); }

/* A test program's banner, a thin strip across the top of the bar. The bar grows by its height, and
   every offset measured from the bar (the rail, the panels) reads --topbar-h, so nothing slides
   under it. */
body.is-test-program { --testbanner-h: 1.6rem; --topbar-h: calc(4.25rem + var(--testbanner-h)); }
body.is-test-program .topbar { padding-top: var(--testbanner-h); }
.testbanner {
  position: absolute;
  inset: 0 0 auto 0;
  height: var(--testbanner-h, 1.6rem);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.75rem;
  background: #e8b23a;
  color: #1d1a16;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.testbanner[hidden] { display: none; }

/* The active program, beside the seat plate: a name, or a select for a seat that may switch. */
.programplate { display: flex; align-items: center; gap: 0.4rem; font-size: 0.78rem; color: rgba(244, 239, 230, 0.85); }
.programplate:empty { display: none; }
.programplate__label { font-size: 0.68rem; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(244, 239, 230, 0.62); }
.programplate select {
  font: inherit;
  color: #f4efe6;
  background: rgba(244, 239, 230, 0.05);
  border: 1px solid rgba(244, 239, 230, 0.22);
  border-radius: 2px;
  padding: 0.3rem 0.4rem;
}
.programplate select option { color: #1d1a16; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  padding: 0.28rem 0.5rem;
  border-radius: 2px;
  border: 1px solid rgba(244, 239, 230, 0.22);
  color: rgba(244, 239, 230, 0.8);
  white-space: nowrap;
}
.chip::before { content: ""; width: 0.45rem; height: 0.45rem; border-radius: 50%; background: currentColor; }
.chip.is-live { color: #9dc08b; border-color: rgba(157, 192, 139, 0.4); }
/* Half a calendar: reading works, pushing does not (or the reverse). Neither green nor amber
   would be honest, so it gets its own colour. */
.chip.is-part { color: #bcd0a6; border-color: rgba(188, 208, 166, 0.34); }
.chip.is-part::before { background: transparent; box-shadow: inset 0 0 0 2px currentColor; }
.chip.is-idle { color: #d8b869; border-color: rgba(216, 184, 105, 0.4); }

/* ---------------------------------------------------------------- rail ---- */

/* One list, three shapes. On a desktop the rail is a sticky column beside the stage, at full width
   or folded to an icon strip. On a phone the same element is a bottom sheet that slides up over
   the page (see the responsive section) -- reusing the element means a capability change can never
   leave a phone drawer offering a screen the sidebar has already dropped. */
.rail {
  background: var(--paper-2);
  border-right: 1px solid var(--rule-strong);
  display: flex;
  flex-direction: column;
  min-height: 0;
  position: sticky;
  top: var(--topbar-h);
  height: calc(100dvh - var(--topbar-h));
}
/* Drawer titlebar. Nothing to title on a desktop, where the rail is simply part of the page. */
.rail__head { display: none; }
.rail__list {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 1rem 0.6rem 2rem;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.rail__group {
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding: 1rem 0.65rem 0.35rem;
}
.rail__list > .rail__group:first-child { padding-top: 0.15rem; }
.rail__link {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.52rem 0.65rem;
  border-radius: 2px;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.9rem;
  color: var(--ink-2);
  text-align: left;
  cursor: pointer;
  border-left: 2px solid transparent;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.rail__link svg { width: 1.05rem; height: 1.05rem; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; opacity: 0.75; }
.rail__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail__link:hover { background: rgba(28, 34, 48, 0.055); }
.rail__link.is-active { background: rgba(166, 81, 47, 0.1); color: var(--clay-deep); border-left-color: var(--clay); }
.rail__link.is-active svg { opacity: 1; }
.rail__link b { margin-left: auto; font-family: var(--mono); font-size: 0.72rem; font-weight: 500; color: var(--ink-faint); }

/* The three sibling properties at the foot of the rail.
 *
 * Anchors rather than buttons, so they carry an underline .rail__link never had to remove, and
 * they sit a shade back from the program areas above: leaving the portal is a different kind of
 * move from changing screen inside it, and a rail that gave both the same weight would read as
 * though the portal had seventeen areas rather than fourteen and three neighbours. */
.rail__link--out,
.rail__link--out:hover { text-decoration: none; }
.rail__link--out { color: var(--ink-faint); }
.rail__link--out:hover { color: var(--ink-2); }
.rail__link--out svg { opacity: 0.5; }
.rail__link--out:hover svg { opacity: 0.8; }
/* The organization's website closes the rail, set off from the areas and the network above it. */
.rail__link--org { margin-top: 0.5rem; }

/* --------------------------------------------------- rail, collapsed (pc) --- */

/* Scoped to the sidebar layout on purpose: the same .is-mini class stays on the shell when the
   window narrows into the drawer layout, and a drawer with its labels stripped off would be a
   column of unexplained glyphs. Each rule below is undone by the phone block further down anyway,
   but relying on that order is how a stray label goes missing on a tablet.

   Dropping the label leaves a button with no text in it, so every rail button carries an
   aria-label in both states (public/app.js) -- the icon strip is a visual economy, not an
   accessible one -- and gains a `title` while collapsed so a pointer can still read it. */
@media (min-width: 52.01rem) {
  .shell.is-mini { --rail-w: var(--rail-w-mini); }
  .shell.is-mini .navtoggle__arrow { transform: rotate(180deg); }
  .shell.is-mini .rail__list { padding-inline: 0.45rem; }
  .shell.is-mini .rail__link {
    gap: 0;
    padding: 0.62rem 0;
    justify-content: center;
    border-left-width: 0;
    border-right: 2px solid transparent;
  }
  .shell.is-mini .rail__link svg { width: 1.15rem; height: 1.15rem; }
  .shell.is-mini .rail__link.is-active { border-right-color: var(--clay); }
  .shell.is-mini .rail__label { display: none; }
  /* A group heading with no room for its words becomes the rule it was already implying: clipped
     to nothing, leaving the hairline and the space around it. */
  .shell.is-mini .rail__group {
    height: 0;
    padding: 0;
    margin: 0.7rem 0.55rem 0.6rem;
    border-top: 1px solid var(--rule);
    overflow: hidden;
  }
  .shell.is-mini .rail__list > .rail__group:first-child { margin-top: 0; border-top: 0; }
}

/* ------------------------------------------------------- nav drawer (phone) --- */

/* Both of these are phone furniture. They are declared here with the rest of the navigation so
   the whole control sits in one place, and switched on in the responsive section. */

.navscrim {
  display: none;
  position: fixed;
  inset: 0;
  /* Above the paper grain (9) and the topbar (6), below the drawer (20). */
  z-index: 19;
  background: rgba(10, 11, 14, 0.5);
  opacity: 0;
  /* `visibility` rather than the hidden attribute, because a display switch cannot be
     transitioned: the scrim would appear at full strength on the same frame the drawer starts
     moving. Dropping it at the end of the fade is also what takes it back out of hit-testing and
     out of the tab order.
     Given a duration rather than a delay: a discrete property holds its `visible` value for the
     whole duration and flips at the end, which is the fade-out wanted here, and unlike a delay it
     is something the reduced-motion block further down the file can shorten. */
  visibility: hidden;
  transition: opacity 0.2s ease, visibility 0.2s;
}
body.nav-open .navscrim { opacity: 1; visibility: visible; }

/* The bottom bar. Four areas plus "More", evenly divided, no horizontal scroll: a destination a
   thumb cannot see is a destination that does not exist. The rest live in the drawer. */
.navbar {
  display: none;
  position: fixed;
  inset: auto 0 0 0;
  z-index: 8;
  align-items: stretch;
  gap: 0.15rem;
  padding: 0.2rem 0.25rem calc(0.2rem + env(safe-area-inset-bottom));
  background: var(--paper-2);
  border-top: 1px solid var(--rule-strong);
}
.navbtn {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  /* Floor of the tap target, not of the glyph: 2.9rem plus the bar's own padding clears the 44px
     a thumb needs on the narrowest phone this has to work on. */
  min-height: 2.9rem;
  padding: 0.35rem 0.15rem;
  border: 0;
  border-top: 2px solid transparent;
  border-radius: 2px;
  background: none;
  font: inherit;
  font-size: 0.63rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.navbtn svg { width: 1.25rem; height: 1.25rem; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; opacity: 0.8; }
.navbtn__label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.navbtn.is-active {
  color: var(--clay-deep);
  border-top-color: var(--clay);
  background: rgba(166, 81, 47, 0.08);
}
.navbtn.is-active svg { opacity: 1; }
/* "More" is marked active when the screen being shown is one of the ones it is holding, so the
   bar never reads as though nothing is open. */
.navbtn--more[aria-expanded="true"] { color: var(--clay-deep); background: rgba(166, 81, 47, 0.08); }

/* --------------------------------------------------------------- stage ---- */

.stage { padding: clamp(1.1rem, 2.4vw, 2.1rem) clamp(1rem, 2.6vw, 2.4rem) 5rem; min-width: 0; }
.stage:focus { outline: none; }

.viewhead {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding-bottom: 0.85rem;
  border-bottom: 1px solid var(--rule-strong);
  margin-bottom: 1.35rem;
}
.viewhead h1 { font-size: clamp(1.7rem, 3.4vw, 2.5rem); line-height: 1.05; }
.viewhead p { margin: 0.35rem 0 0; color: var(--ink-soft); font-size: 0.9rem; max-width: 62ch; }
.viewhead__actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }

/* Metric tiles: ruled sheets, offset in a deliberately uneven grid. */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 0.85rem; margin-bottom: 1.5rem; }
.tile {
  background: rgba(255, 255, 255, 0.5);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--ink);
  border-radius: 2px;
  padding: 0.85rem 0.9rem 0.95rem;
  animation: rise 0.45s ease both;
}
.tile:nth-child(3n+2) { border-top-color: var(--clay); }
.tile:nth-child(4n+3) { border-top-color: var(--moss); }
.tile dt { font-size: 0.68rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-soft); }
.tile dd { margin: 0.3rem 0 0; font-family: var(--display); font-size: 2.05rem; line-height: 1; font-variant-numeric: tabular-nums; }
.tile small { display: block; margin-top: 0.3rem; font-size: 0.74rem; color: var(--ink-faint); }

.sheet-card {
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid var(--rule);
  border-radius: 2px;
  box-shadow: var(--shadow);
  margin-bottom: 1.35rem;
  overflow: hidden;
}
.sheet-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.8rem 1rem;
  border-bottom: 1px solid var(--rule);
  background: rgba(226, 217, 200, 0.4);
}
.sheet-card__head h2 { font-size: 1.08rem; }
.sheet-card__head p { margin: 0.1rem 0 0; font-size: 0.8rem; color: var(--ink-soft); }
.sheet-card__body { padding: 1rem; }
.sheet-card__body--flush { padding: 0; }

/* --------------------------------------------------------------- table ---- */

.tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.ledger { width: 100%; border-collapse: collapse; font-size: 0.86rem; }
table.ledger th {
  text-align: left;
  font-size: 0.66rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 600;
  padding: 0.6rem 0.75rem;
  border-bottom: 1px solid var(--rule-strong);
  white-space: nowrap;
  background: rgba(226, 217, 200, 0.35);
  position: sticky;
  top: 0;
}
table.ledger td { padding: 0.6rem 0.75rem; border-bottom: 1px solid var(--rule); vertical-align: top; }
table.ledger tbody tr:hover { background: rgba(166, 81, 47, 0.045); }
table.ledger tbody tr:last-child td { border-bottom: 0; }
table.ledger .num { font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
table.ledger .rowactions { display: flex; gap: 0.3rem; flex-wrap: wrap; }

.pill {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.7rem;
  padding: 0.15rem 0.42rem;
  border-radius: 2px;
  border: 1px solid var(--rule-strong);
  white-space: nowrap;
}
.pill--active { background: rgba(76, 106, 72, 0.13); border-color: rgba(76, 106, 72, 0.4); color: #3a5137; }
.pill--pending { background: rgba(157, 120, 24, 0.14); border-color: rgba(157, 120, 24, 0.42); color: #74580c; }
.pill--flag { background: rgba(166, 81, 47, 0.12); border-color: rgba(166, 81, 47, 0.42); color: var(--clay-deep); }
.pill--mute { color: var(--ink-faint); }

.redacted {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--ink-faint);
  background: repeating-linear-gradient(135deg, rgba(28,34,48,0.06) 0 4px, transparent 4px 8px);
  padding: 0.1rem 0.35rem;
  border-radius: 2px;
}

/* --------------------------------------------------- states + feedback ---- */

.notice {
  margin: 0;
  padding: 0.65rem 0.8rem;
  border-left: 3px solid var(--clay);
  background: rgba(166, 81, 47, 0.08);
  font-size: 0.86rem;
  border-radius: 2px;
}
.notice--good { border-left-color: var(--moss); background: rgba(76, 106, 72, 0.1); }

/* A fault report: what is stopping the calendar, named variable by variable. It reads as a
   maintenance note rather than an error, because the fix is a site setting, not a retry. */
.faultbox {
  border: 1px solid var(--rule-strong);
  border-left: 3px solid var(--gold);
  background: rgba(157, 120, 24, 0.07);
  border-radius: 2px;
  padding: 0.7rem 0.85rem;
}
.faultbox__title {
  margin: 0;
  font-family: var(--body);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
}
.faultbox__list {
  margin: 0.5rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.4rem;
}
.faultbox__list li {
  font-size: 0.86rem;
  line-height: 1.45;
  padding-left: 0.9rem;
  border-left: 1px solid var(--rule);
}
.faultbox__list code {
  font-family: var(--mono);
  font-size: 0.78rem;
  background: rgba(28, 34, 48, 0.06);
  padding: 0.05rem 0.25rem;
  border-radius: 2px;
}
/* The errand that produces a missing credential. Folded away by default: the faults are the news,
   and a six-step Google Cloud errand under every one of them would bury them. */
.faultbox__steps {
  margin: 0.6rem 0 0;
  font-size: 0.84rem;
}
.faultbox__steps > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--ink);
}
.faultbox__steps > summary:hover { color: var(--gold); }
.faultbox__steps ol {
  margin: 0.5rem 0 0;
  padding-left: 1.2rem;
  display: grid;
  gap: 0.35rem;
  line-height: 1.45;
  color: var(--ink-soft);
}

/* The outbound feed panel: a credential and the procedure for using it, closed until asked for.
   Set in moss rather than the gold of a fault, because this is a thing that works. */
.subcard {
  border: 1px solid var(--rule-strong);
  border-left: 3px solid var(--moss);
  background: rgba(76, 106, 72, 0.07);
  border-radius: 2px;
  padding: 0.7rem 0.85rem;
}
.subcard > summary {
  cursor: pointer;
  font-family: var(--body);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
}
.subcard > summary:hover { color: var(--moss); }
.subcard[open] > summary { margin-bottom: 0.7rem; }
.subcard p { font-size: 0.88rem; line-height: 1.5; }

/* The address itself. It has to wrap -- it is longer than a phone is wide -- and it has to be
   selectable by hand for the browsers that refuse the clipboard button. */
.copyable {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0.2rem 0 0;
}
.copyable__value {
  flex: 1 1 18rem;
  min-width: 0;
  font-family: var(--mono);
  font-size: 0.76rem;
  line-height: 1.5;
  overflow-wrap: anywhere;
  background: rgba(28, 34, 48, 0.06);
  border: 1px solid var(--rule);
  border-radius: 2px;
  padding: 0.4rem 0.5rem;
  user-select: all;
}

.faultbox__foot {
  margin: 0.6rem 0 0;
  padding-top: 0.5rem;
  border-top: 1px solid var(--rule);
  font-size: 0.78rem;
  color: var(--ink-soft);
}

.empty { padding: 2.5rem 1.25rem; text-align: center; }
.empty svg { width: 2.75rem; height: 2.75rem; fill: none; stroke: var(--ink-faint); stroke-width: 1.3; margin-bottom: 0.6rem; }
.empty h3 { font-size: 1.1rem; }
.empty p { margin: 0.4rem auto 0.9rem; max-width: 42ch; color: var(--ink-soft); font-size: 0.88rem; }

.skeleton { display: grid; gap: 0.5rem; padding: 0.5rem 0; }
.skeleton__row {
  height: 2.6rem;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(28,34,48,0.05), rgba(28,34,48,0.1), rgba(28,34,48,0.05));
  background-size: 220% 100%;
  animation: sweep 1.25s ease-in-out infinite;
}

.toast {
  position: fixed;
  left: 50%;
  bottom: 1.5rem;
  /* Centred with `translate`, not `transform`: the `rise` entrance animates `transform` and, with
     `both` fill, leaves it at `none`, which would undo a translateX(-50%) and push the right half
     of the box off the screen. The two properties compose, so the animation cannot clobber this. */
  translate: -50% 0;
  z-index: 30;
  max-width: min(34rem, calc(100vw - 2rem));
  padding: 0.7rem 1rem;
  background: var(--ink);
  color: var(--paper);
  border-radius: 2px;
  font-size: 0.87rem;
  box-shadow: 0 18px 40px -18px rgba(28, 34, 48, 0.7);
  animation: rise 0.28s ease both;
}
.toast.is-bad { background: var(--clay-deep); }

/* --------------------------------------------------------------- update ---- */

/* The deploy notice. It has to read on both grounds this portal uses -- warm paper behind the
   application, near-black behind the sign-in seal -- so it is struck as a paper card with an ink
   rule around it rather than tinted to suit either one. Bottom centre, where the toast lives,
   because that is where this portal already puts things it has to say. */
.update {
  position: fixed;
  left: 50%;
  bottom: 1.5rem;
  translate: -50% 0; /* not `transform` -- see .toast; otherwise Refresh ends up off-screen */
  z-index: 31; /* above the toast; a modal sheet is in the top layer and outranks both */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem 1.1rem;
  width: min(36rem, calc(100vw - 2rem));
  padding: 0.8rem 0.95rem;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 2px;
  box-shadow: 0 20px 44px -20px rgba(28, 34, 48, 0.75);
  animation: rise 0.28s ease both;
}
.update__body { flex: 1 1 15rem; min-width: 0; }
.update__title { display: block; font-family: var(--display); font-size: 0.95rem; }
.update__note { margin: 0.15rem 0 0; font-size: 0.78rem; color: var(--ink-soft); }
.update__actions { display: flex; flex: none; gap: 0.4rem; }

/* The toast is bottom-centre as well, and a confirmation that clears itself after three seconds
   must not land on top of a notice that is waiting for an answer. Lifted for as long as one is up.
   The phone figure is larger because the notice wraps to two rows in that width. */
/* A sheet opened after the notice went up covers it with a blurred backdrop from the top layer,
   which leaves it dimmed and unclickable. Stood down for as long as one is open, and back on its
   own when the sheet closes. (A notice raised *while* a sheet is open is held back in JS instead,
   so its announcement lands when there is something to act on.) */
body:has(dialog[open]) .update { display: none; }

body:has(#update:not([hidden])) .toast { bottom: 6.75rem; }
@media (max-width: 34rem) {
  body:has(#update:not([hidden])) .toast { bottom: 9.75rem; }
}

/* ------------------------------------------------------- display cutouts ---- */

/* The notch, the Dynamic Island and the rounded corners on an iPhone.

   The viewport is declared `viewport-fit=cover`, which is what lets the sign-in seal and the ink
   topbar run to the physical edge of the screen instead of sitting inside a pair of letterboxes.
   The cost of asking for that is that the page is then responsible for keeping anything a thumb
   has to hit out from under the hardware. Held in portrait by the bottom inset already reserved
   on the phone bar; landscape is where it bit, because that is where the cutout moves to the side
   of the screen and takes roughly 44px of the left or right edge with it -- which on this layout
   is the rail toggle at one end of the topbar and Sign out at the other, each half-swallowed by
   the notch and unhittable at its outer half.

   Applied as longhand after each shorthand rather than folded into it, so the spacing each of
   these already sets for a phone is what the inset is added to. The insets are 0 on every device
   without a cutout, which is every Mac, every iPad and every desktop browser, so none of this
   changes that layout by a pixel. */
.topbar {
  padding-left: calc(clamp(0.9rem, 2vw, 1.5rem) + env(safe-area-inset-left));
  padding-right: calc(clamp(0.9rem, 2vw, 1.5rem) + env(safe-area-inset-right));
}
.stage {
  padding-left: calc(clamp(1rem, 2.6vw, 2.4rem) + env(safe-area-inset-left));
  padding-right: calc(clamp(1rem, 2.6vw, 2.4rem) + env(safe-area-inset-right));
}
/* The bottom bar keeps its own vertical padding, including the home-indicator inset it already
   reserved; only the two sides are new. */
.navbar {
  padding-left: calc(0.25rem + env(safe-area-inset-left));
  padding-right: calc(0.25rem + env(safe-area-inset-right));
}
/* The rail is a left-hand sidebar on a desktop and a bottom drawer on a phone, and its links run
   to its own left edge in both. */
.rail__list {
  padding-left: calc(0.6rem + env(safe-area-inset-left));
  padding-right: calc(0.6rem + env(safe-area-inset-right));
}
/* The sign-in screen is the one page a seat can reach before anything else has loaded, so the
   email field and the Sign in button have to be clear of the cutout there too. */
.gate__seal { padding-left: calc(clamp(2.75rem, 6vw, 5.5rem) + env(safe-area-inset-left)); }
.gate__panel { padding-right: calc(clamp(1.5rem, 4vw, 3.5rem) + env(safe-area-inset-right)); }

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

.sheet {
  border: 0;
  padding: 0;
  background: transparent;
  max-width: 46rem;
  width: calc(100vw - 2rem);
  max-height: 88dvh;
}
/* Safari only dropped the prefix on backdrop-filter in 18; the iPhones and iPads in the field
   on 16 and 17 need the prefixed copy or the sheet opens over an unblurred page. */
.sheet::backdrop {
  background: rgba(28, 34, 48, 0.5);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}
.sheet > form {
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  border-top: 3px solid var(--clay);
  border-radius: 2px;
  max-height: 88dvh;
  overflow-y: auto;
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}
.sheet h2 { font-size: 1.35rem; }
.sheet__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 0.8rem; }
.sheet__grid--wide { grid-template-columns: 1fr; }
.sheet__legend {
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding-top: 0.4rem;
  border-top: 1px solid var(--rule);
  grid-column: 1 / -1;
}
.sheet__foot { display: flex; justify-content: flex-end; gap: 0.5rem; padding-top: 0.4rem; border-top: 1px solid var(--rule); }

/* --------------------------------------------------------------- misc ---- */

.bars { display: grid; gap: 0.55rem; }
.bar { display: grid; grid-template-columns: 12rem 1fr auto; gap: 0.7rem; align-items: center; font-size: 0.84rem; }
.bar__track { height: 0.55rem; background: rgba(28, 34, 48, 0.09); border-radius: 1px; overflow: hidden; }
.bar__fill { height: 100%; background: var(--clay); transform-origin: left; animation: grow 0.6s cubic-bezier(0.22, 1, 0.36, 1) both; }
.bar:nth-child(even) .bar__fill { background: var(--ink-2); }
.bar__val { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 0.8rem; }

.rolegrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 0.85rem; }
.seatcard {
  border: 1px solid var(--rule);
  border-left: 3px solid var(--ink);
  border-radius: 2px;
  padding: 0.9rem;
  background: rgba(255, 255, 255, 0.5);
}
.seatcard.is-open { border-left-color: var(--gold); }
.seatcard.is-self { border-left-color: var(--clay); background: rgba(166, 81, 47, 0.06); }
.seatcard__top { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; }
.seatcard__seat { font-family: var(--mono); font-size: 0.72rem; color: var(--ink-faint); }
.seatcard h3 { font-size: 1.02rem; margin-top: 0.15rem; }
.seatcard__role { font-size: 0.76rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--clay-deep); margin: 0.25rem 0 0.5rem; }
.seatcard__perm { display: inline-block; font-size: 0.72rem; margin: -0.25rem 0 0.5rem; padding: 0.1rem 0.45rem; border: 1px solid var(--rule); border-radius: 2px; }
.seatcard p { margin: 0; font-size: 0.83rem; color: var(--ink-soft); }
.seatcard__meta { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-top: 0.7rem; }
.seatcard__foot { margin-top: 0.75rem; display: flex; gap: 0.35rem; flex-wrap: wrap; }

.caps { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.caps code {
  font-family: var(--mono);
  font-size: 0.7rem;
  padding: 0.12rem 0.38rem;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.55);
  color: var(--ink-soft);
}

/* Written procedures. A numbered step reads as one instruction with its reason underneath, so the
   list can be followed at arm's length while setting up somebody else's phone. */
.steps { list-style: none; counter-reset: step; margin: 0; padding: 0; display: grid; gap: 0.7rem; }
.steps li { counter-increment: step; position: relative; padding-left: 2.1rem; }
.steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0.05rem;
  width: 1.5rem;
  height: 1.5rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
}
.steps strong { display: block; font-size: 0.9rem; line-height: 1.35; }
.steps span { display: block; margin-top: 0.15rem; font-size: 0.83rem; color: var(--ink-soft); }
.steps + .notice { margin-top: 1rem; }

/* One column per kind of device, the reader's own marked and moved to the front. */
.howto { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 0.75rem; }
.howto__card {
  border: 1px solid var(--rule);
  border-top: 2px solid var(--rule-strong);
  border-radius: 2px;
  padding: 0.8rem 0.85rem;
  background: rgba(255, 255, 255, 0.5);
}
.howto__card.is-current { border-top-color: var(--clay); background: rgba(166, 81, 47, 0.06); }
.howto__head { display: flex; align-items: center; justify-content: space-between; gap: 0.4rem; margin: 0; }
.howto__head b { font-size: 0.92rem; }
.howto__browser {
  margin: 0.15rem 0 0.6rem;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.howto__steps { margin: 0; padding-left: 1.15rem; display: grid; gap: 0.35rem; font-size: 0.83rem; color: var(--ink-soft); }
.howto__steps li::marker { font-family: var(--mono); font-size: 0.75rem; color: var(--ink-faint); }

/* The install offer sits above the written steps: button and reason in one line, wrapping to two
   on a phone rather than squeezing the label. */
.installbar { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 0.75rem; margin-bottom: 1rem; }
.installbar p { margin: 0; flex: 1 1 14rem; font-size: 0.83rem; color: var(--ink-soft); }
.installbar .notice { flex: 1 1 100%; margin: 0; }

.filters { display: flex; gap: 0.55rem; flex-wrap: wrap; align-items: flex-end; }
.filters .field { min-width: 9.5rem; flex: 0 1 auto; }

.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: 0.85rem;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--rule);
}
.timeline li:last-child { border-bottom: 0; }
.timeline__when { font-family: var(--mono); font-size: 0.75rem; color: var(--ink-soft); }
.timeline__what strong { display: block; font-size: 0.92rem; }
.timeline__what span { font-size: 0.8rem; color: var(--ink-soft); }

@keyframes rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes sweep { from { background-position: 120% 0; } to { background-position: -120% 0; } }
@keyframes grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* ------------------------------------------------------------ responsive -- */

@media (max-width: 60rem) {
  .gate { grid-template-columns: 1fr; }
  .gate__seal {
    border-right: 0;
    border-bottom: 1px solid var(--foil-line);
    padding-block: 2.25rem;
    gap: 1.1rem;
  }
  .gate__panel { max-width: none; align-self: start; }
}

/* Phone. The seal column becomes a masthead rather than a page of its own: the point of the
   screen is the form, and on a 5-inch display anything above it is scrolling the reader has to
   do before they can sign in. The badge stays -- shrunk to the size of a struck coin, it is
   still the fastest way to know you are at the right door. */
@media (max-width: 34rem) {
  .gate__seal {
    padding: 1.6rem 1.1rem 1.4rem 2rem;
    gap: 0.85rem;
    text-align: left;
  }
  .gate__seal::after { inset: 0 auto 0 0.9rem; }
  .gate__crest { gap: 0.8rem; }
  .mark--gate { width: 4.25rem; }
  .gate__brandline { font-size: 0.62rem; letter-spacing: 0.14em; padding-left: 0.8rem; }
  .gate__title { font-size: 2.5rem; }
  .gate__sub { font-size: 0.9rem; max-width: none; }
  .gate__facts { gap: 0.6rem 1.5rem; padding-top: 0.9rem; }
  /* Kept in the DOM for anyone who scrolls, dropped from the first screenful. */
  .gate__legal { display: none; }
  .gate__panel { padding: 1.1rem 1rem 2.5rem; gap: 0.75rem; }
  .gate__card { padding: 1rem 0.9rem; gap: 0.9rem; }
  .tabs__btn { font-size: 0.7rem; letter-spacing: 0.04em; padding: 0.5rem 0.3rem; }
}

/* Phone and small tablet. Navigation splits in two: a fixed bottom bar of the areas a field seat
   opens daily, within one-handed reach, and the full grouped rail as a bottom sheet behind
   "More". The bar this replaces was the whole rail laid out sideways -- fourteen areas on a strip
   about five wide, which meant Reporting, the Ledger, the Vault and the Audit Trail all lived off
   the right edge behind a horizontal scroll with nothing on screen to suggest they were there. */
@media (max-width: 52rem) {
  .shell { grid-template-columns: 1fr; grid-template-rows: var(--topbar-h) 1fr; }
  /* The seat's name and role move to the drawer head, where there is room for them. */
  .plate__who { display: none; }
  /* The program's name likewise; a seat that may switch keeps the select, without its caption. */
  .programplate__name, .programplate__label { display: none; }
  /* One opener is enough, and the bar's is the one a thumb can reach. */
  .navtoggle { display: none; }
  .navscrim { display: block; }
  .navbar { display: flex; }

  .rail {
    position: fixed;
    inset: auto 0 0 0;
    top: auto;
    /* Tall enough for the whole list on most phones, capped so the page behind stays visible --
       a sheet that covers everything is a screen, and a screen needs a back button. */
    height: auto;
    max-height: min(78dvh, 34rem);
    border-right: 0;
    border-top: 1px solid var(--rule-strong);
    border-radius: 12px 12px 0 0;
    padding-bottom: env(safe-area-inset-bottom);
    z-index: 20;
    box-shadow: 0 -20px 48px -24px rgba(28, 34, 48, 0.7);
    transform: translateY(100%);
    /* Off-screen and out of the tab order until asked for. See the scrim above on why the
       visibility is transitioned with a duration rather than a delay. */
    visibility: hidden;
    transition: transform 0.24s ease, visibility 0.24s;
  }
  body.nav-open .rail { transform: none; visibility: visible; }

  .rail__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex: none;
    padding: 0.85rem 0.9rem 0.7rem;
    border-bottom: 1px solid var(--rule);
  }
  .rail__headtext { min-width: 0; }
  .rail__headtitle { margin: 0; font-family: var(--display); font-size: 1rem; }
  .rail__headseat {
    margin: 0.1rem 0 0;
    font-family: var(--mono);
    font-size: 0.7rem;
    color: var(--ink-soft);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .rail__close {
    flex: none;
    width: 2.5rem;
    height: 2.5rem;
    display: grid;
    place-items: center;
    padding: 0;
    border: 1px solid var(--rule-strong);
    border-radius: 2px;
    background: none;
    color: var(--ink-soft);
    cursor: pointer;
  }
  .rail__close svg { width: 1.05rem; height: 1.05rem; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

  /* Restated rather than left to the base rule so the drawer keeps the cutout insets set
     further up: this is the layout a smaller iPhone is in when it is turned to landscape. */
  .rail__list {
    padding: 0.5rem 0.6rem 1rem;
    padding-left: calc(0.6rem + env(safe-area-inset-left));
    padding-right: calc(0.6rem + env(safe-area-inset-right));
  }
  .rail__list > .rail__group:first-child { padding-top: 0.5rem; }
  /* Full-width rows with real tap targets, not the sideways tabs this used to be. */
  .rail__link { padding: 0.72rem 0.65rem; font-size: 0.95rem; }
  .rail__link svg { width: 1.15rem; height: 1.15rem; }

  .stage { padding-bottom: calc(var(--navbar-h) + 2.75rem); }
  /* Neither may sit on top of the bottom bar, which is a permanent part of the screen here. */
  .toast, .update { bottom: calc(var(--navbar-h) + 0.9rem + env(safe-area-inset-bottom)); }
  body:has(#update:not([hidden])) .toast { bottom: calc(var(--navbar-h) + 6.15rem + env(safe-area-inset-bottom)); }
  /* The notice is fixed above the scrim, so with the drawer up it would be the one lit thing on a
     dimmed page. Stood down until the drawer closes, as it already is for an open sheet. */
  body.nav-open .update { display: none; }
  /* The page behind a bottom sheet must not scroll under it. */
  body.nav-open { overflow: hidden; }

  .bar { grid-template-columns: 8rem 1fr auto; }
}

/* The deploy notice wraps to two rows in this width, so the toast has further to climb over it. */
@media (max-width: 34rem) {
  body:has(#update:not([hidden])) .toast { bottom: calc(var(--navbar-h) + 9.4rem + env(safe-area-inset-bottom)); }
}

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

/* ------------------------------------------------- view-level fragments ---- */

/* Two columns on a desktop, stacked on a phone: used for paired report cards. */
.split { display: grid; grid-template-columns: repeat(auto-fit, minmax(21rem, 1fr)); gap: 0.9rem; }
.stack { display: grid; gap: 0.9rem; }

/* Secondary lines inside a ledger cell -- a business name under a participant, a
   location under an event title. Kept quiet so the primary value still reads first. */
.cell__sub { margin-top: 0.15rem; font-size: 0.76rem; color: var(--ink-soft); }
/* A figure that needs acting on rather than only reading: money cleared against the budget in
   the field that this ledger has no entry for. Weight and colour, not colour alone -- the
   reconciliation table is eight rows of numbers and the one that differs has to survive being
   read on a phone in a training kitchen, printed in grayscale, or by someone who does not
   distinguish clay from ink. */
.cell__warn { color: var(--clay-deep); font-weight: 600; }
.cell__note {
  font-size: 0.8rem;
  color: var(--ink-soft);
  max-width: 26rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Row actions sit right-aligned and wrap rather than widening the table. */
.row-actions { white-space: nowrap; text-align: right; }
.row-actions > * + * { margin-left: 0.3rem; }

.muted { color: var(--ink-faint); }
.trunc { display: inline-block; max-width: 9rem; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; font-size: 0.7rem; }

/* Training-track tags on the participant roster. */
.tracks { display: flex; flex-wrap: wrap; gap: 0.25rem; }
.tag {
  font-size: 0.68rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.1rem 0.35rem;
  border: 1px solid var(--rule);
  border-radius: 2px;
  color: var(--ink-soft);
  background: rgba(255, 255, 255, 0.6);
  white-space: nowrap;
}

/* Milestone dots on the launch ledger: filled means the filing or permit is done. */
.dots { display: flex; gap: 0.28rem; }
.dot {
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  border: 1px solid var(--rule-strong);
  background: transparent;
}
.dot--on { background: var(--moss); border-color: var(--moss); }

/* Knowledge gain reads as a signed figure; a negative result should not hide. */
.gain { color: var(--moss); font-variant-numeric: tabular-nums; }
.loss { color: var(--clay-deep); font-variant-numeric: tabular-nums; }

.legendrow { font-size: 0.74rem; color: var(--ink-faint); margin: -0.6rem 0 0.9rem; }

/* The filter bar's submit button aligns with the inputs beside it. */
.field--btn { display: flex; align-items: flex-end; }

.seatcard__dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.2rem 0.7rem;
  margin: 0.7rem 0 0;
  font-size: 0.78rem;
}
.seatcard__dl dt { color: var(--ink-faint); letter-spacing: 0.04em; text-transform: uppercase; font-size: 0.66rem; align-self: center; }
.seatcard__dl dd { margin: 0; color: var(--ink-2); }

/* Programs screen (views.js `programs`). Same card language as the seat roster; Enterprise Rising
   carries the clay rule and a lock, an archived program is faded but still fully readable. */
.proggrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr)); gap: 0.85rem; }
.progcard {
  border: 1px solid var(--rule);
  border-left: 3px solid var(--ink);
  border-radius: 2px;
  padding: 0.9rem;
  background: rgba(255, 255, 255, 0.5);
  min-width: 0;
}
.progcard.is-locked { border-left-color: var(--clay); background: rgba(166, 81, 47, 0.05); }
.progcard.is-archived { border-left-color: var(--rule); opacity: 0.78; }
.progcard__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem; flex-wrap: wrap; }
.progcard h3 { font-size: 1.02rem; display: flex; align-items: center; gap: 0.35rem; overflow-wrap: anywhere; }
.progcard__lock { display: inline-flex; color: var(--clay-deep); }
.progcard__lock svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.progcard__badges { display: flex; gap: 0.3rem; flex-wrap: wrap; }
.progcard p { margin: 0.25rem 0 0; font-size: 0.83rem; color: var(--ink-soft); }
.progcard__award { color: var(--ink-2); }
.progcard__note { font-size: 0.76rem; color: var(--clay-deep); }
.progcard__grant { font-size: 0.72rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-faint); }
.progcard .seatcard__dl dd { overflow-wrap: anywhere; }
.progcard .seatcard__foot .btn { min-height: 2.75rem; }
.field input[readonly] { background: rgba(0, 0, 0, 0.04); color: var(--ink-faint); cursor: not-allowed; }

@media (max-width: 52rem) {
  .row-actions { white-space: normal; }
  .cell__note { max-width: 14rem; }
}

/* First paint before /api/session answers. Removed by the shell, never shown twice. */
.boot {
  position: fixed;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 0.9rem;
  background: var(--paper);
  z-index: 20;
}
.boot .mark { animation: pulse 1.6s ease-in-out infinite; }
.boot p { font-size: 0.74rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-faint); margin: 0; }

@keyframes pulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }

/* ---------------------------------------------------- form guidance bubbles ---- */
/* The "?" beside a field label and the bubble it raises. Kept out of normal flow so a bubble
   never reflows the form when it appears, and always inside the sheet so it can be read. */

.field__label { display: inline-flex; align-items: center; gap: 0.4rem; }

.field__hint { position: relative; display: inline-flex; line-height: 1; }

.field__ask {
  width: 1.05rem;
  height: 1.05rem;
  padding: 0;
  border: 1px solid var(--rule-strong);
  border-radius: 50%;
  background: transparent;
  color: var(--ink-soft);
  font: 600 0.66rem/1 var(--mono);
  cursor: help;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.field__ask:hover,
.field__hint[data-open="true"] .field__ask { background: var(--clay); border-color: var(--clay); color: var(--paper); }
.field__ask:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

.field__bubble {
  position: absolute;
  bottom: calc(100% + 0.5rem);
  left: -0.4rem;
  z-index: 40;
  width: max-content;
  max-width: min(17rem, 68vw);
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--ink);
  border-radius: 3px;
  background: var(--ink);
  color: var(--paper);
  font: 400 0.76rem/1.45 var(--body);
  letter-spacing: 0;
  text-transform: none;
  white-space: pre-line;
  box-shadow: 0 6px 18px rgb(28 34 48 / 0.28);
  opacity: 0;
  pointer-events: none;
  transform: translateY(0.2rem);
  transition: opacity 0.14s ease, transform 0.14s ease;
}
/* Not display:none -- the text stays in the accessibility tree for aria-describedby. */
.field__hint[data-open="true"] .field__bubble { opacity: 1; pointer-events: auto; transform: translateY(0); }

/* A little pointer down at the "?" it belongs to. */
.field__bubble::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 0.75rem;
  border: 5px solid transparent;
  border-top-color: var(--ink);
}

.field__hint--left .field__bubble { left: auto; right: -0.4rem; }
.field__hint--left .field__bubble::after { left: auto; right: 0.75rem; }

.field__hint--below .field__bubble { bottom: auto; top: calc(100% + 0.5rem); }
.field__hint--below .field__bubble::after { top: auto; bottom: 100%; border-top-color: transparent; border-bottom-color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  .field__bubble { transition: none; transform: none; }
}

/* Guidance that belongs to a whole group of fields rather than to one input. */
.sheet__note {
  grid-column: 1 / -1;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: -0.2rem 0 0;
  font-size: 0.72rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* A button that reads as a link, for switching between the sign-in tabs mid-sentence. */
.linkbtn {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--clay);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.linkbtn:hover { color: var(--ink); }
.linkbtn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* ----------------------------------------------------------- print doc ---- */

/* Letterhead and certification blocks. They belong to the paper report only: on screen the
   reader already knows which award they are looking at, and a signature line in a browser is
   just furniture. Kept in the DOM (rather than assembled at print time) so the printed page
   carries the same figures, from the same request, as the screen it was printed from. */
.printdoc { display: none; }

/* The reverse of .printdoc: the one line that exists only on screen. What comes off the printer
   is a different document from the screen it was printed from -- letterhead, numbered sections,
   a certification to sign -- and someone about to hand a page to a grant reviewer should know
   that before pressing the button, not after. */
.printcue {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  margin: -0.5rem 0 1.35rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--gold);
  border-radius: 2px;
  background: rgba(157, 120, 24, 0.06);
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
.printcue__doc {
  flex: none;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--ink);
  white-space: nowrap;
}
@media (max-width: 34rem) {
  .printcue { flex-direction: column; gap: 0.3rem; }
}

/* -------------------------------------------------------- calendar views ---- */

/* The month, week and day grids.
   Drawn as ruled paper rather than as a web calendar: hairline cells on the same warm ground as
   the rest of the ledger, dates in the mono face so the columns line up, and no fills except
   where something needs to be found quickly -- today, and an archived entry that has been struck
   through. Colour carries the event type, but never alone: every chip states its time and title
   in text, so the grid still reads for anyone who cannot separate clay from moss. */

/* View switch and date navigator. The switch keeps its natural width so four segments do not
   stretch across a wide screen, and the navigator sits opposite it. */
.calbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin: 0 0 0.85rem;
}
.calbar__modes { flex: 0 0 auto; min-width: 17rem; }
.calbar__nav { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; }
.calbar__label {
  font-family: var(--display);
  font-size: 1.05rem;
  letter-spacing: 0.01em;
  min-width: 11rem;
  text-align: center;
}
/* The step arrows are square so a thumb can find them without reading them. */
.calbar__step {
  min-width: 2.2rem;
  padding-left: 0.5rem;
  padding-right: 0.5rem;
  font-size: 1.05rem;
  line-height: 1;
}

.calgrid { display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule-strong); }
.calgrid--month { grid-template-columns: repeat(7, minmax(0, 1fr)); }
/* Seven columns of a week, each as tall as its fullest day. */
.calgrid--week { grid-template-columns: repeat(7, minmax(0, 1fr)); align-items: stretch; }

.calgrid__dow {
  padding: 0.4rem 0.5rem;
  background: var(--paper-3);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.calgrid--month .calgrid__dow { text-align: center; }

.calgrid__day, .calgrid__col {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-height: 6.5rem;
  padding: 0.3rem;
  background: var(--paper);
}
.calgrid__col { min-height: 9rem; }
.calgrid__colhead {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  padding-bottom: 0.2rem;
  border-bottom: 1px solid var(--rule);
}
.calgrid__colhead .calgrid__dow { padding: 0; background: none; }

/* Days spilling in from the neighbouring month stay legible but recede, so the month being read
   holds its shape. */
.calgrid__day.is-outside { background: var(--paper-2); }
.calgrid__day.is-outside .calgrid__num { color: var(--ink-faint); }
.calgrid__day.is-today, .calgrid__col.is-today { background: rgba(157, 120, 24, 0.09); }
.calgrid__day.is-today .calgrid__num, .calgrid__col.is-today .calgrid__num {
  background: var(--ink);
  color: var(--paper);
}

/* The date is the control that schedules something on it, which is how a plan gets entered:
   press the day you mean. */
.calgrid__num {
  align-self: flex-start;
  min-width: 1.5rem;
  padding: 0.1rem 0.28rem;
  border: 0;
  border-radius: 2px;
  background: none;
  font-family: var(--mono);
  font-size: 0.76rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  text-align: center;
}
button.calgrid__num { cursor: pointer; }
button.calgrid__num:hover { background: var(--paper-3); color: var(--ink); }
button.calgrid__num:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }

.calgrid__events { display: flex; flex-direction: column; gap: 2px; }
.calgrid__quiet { margin: 0; font-size: 0.72rem; color: var(--ink-faint); }
.calgrid__more {
  align-self: flex-start;
  padding: 0.05rem 0.2rem;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.7rem;
  color: var(--clay);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.calgrid__more:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }

/* One entry in a grid. A left rule in the type's colour rather than a filled block: eight filled
   colours in a month grid turns the page into a chart of itself, and the point of the screen is
   the words. */
.calchip {
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
  width: 100%;
  padding: 0.16rem 0.3rem;
  border: 0;
  border-left: 3px solid var(--ink-soft);
  border-radius: 1px;
  background: rgba(255, 255, 255, 0.6);
  font: inherit;
  font-size: 0.72rem;
  line-height: 1.3;
  text-align: left;
  cursor: pointer;
}
.calchip:hover { background: #fff; }
.calchip:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }
.calchip__time {
  flex: none;
  font-family: var(--mono);
  font-size: 0.66rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
}
.calchip__title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* An all-day entry has no time to align to, so it reads as a banner across the day. */
.calchip.is-allday { background: rgba(157, 120, 24, 0.12); }
/* Archived: present, findable, and unmistakably not on the schedule. */
.calchip.is-archived { opacity: 0.6; }
.calchip.is-archived .calchip__title { text-decoration: line-through; }

/* Event type. Clay for delivery to participants, moss for compliance and reporting, ink for the
   team's own administration -- the three kinds of day this programme has. */
.calchip--food_truck_training { border-left-color: var(--clay); }
.calchip--financial_literacy { border-left-color: var(--clay-deep); }
.calchip--one_on_one_mentorship { border-left-color: #7a5b8f; }
.calchip--usda_compliance_deadline { border-left-color: var(--gold); }
.calchip--outreach_recruitment { border-left-color: #2f6b7a; }
.calchip--business_launch_follow_up { border-left-color: var(--moss); }
.calchip--graduation_community_event { border-left-color: #8f6f2a; }
.calchip--staff_administration { border-left-color: var(--ink-soft); }

/* An archived row in the range table: still readable as a record, plainly not a plan. */
.ledger tr.is-archived td:first-child strong, .ledger tr.is-archived .linkbtn { text-decoration: line-through; }
.ledger tr.is-archived { color: var(--ink-soft); }

/* The lesson plan whose documents are open below the library. */
.ledger tr.is-selected { background: rgba(166, 81, 47, 0.07); }
.ledger tr.is-selected td:first-child { box-shadow: inset 3px 0 0 var(--clay); }

/* The foot of the documents panel: an expanded image, and the line explaining which file types
   the portal can read. The panel's body is flush so the ledger reaches its edges, which leaves
   these to carry their own gutter. */
.docsfoot { padding: 0.85rem 1rem; display: grid; gap: 0.7rem; border-top: 1px solid var(--rule); }
.docsfoot p { margin: 0; font-size: 0.78rem; }

/* An image document read in place. Bounded by height rather than width so a portrait photo of a
   paper handout and a landscape slide both stay on one screen next to their caption. */
.docview {
  margin: 0;
  padding: 0.75rem;
  border: 1px solid var(--rule);
  background: var(--paper-2);
  display: grid;
  gap: 0.55rem;
  justify-items: center;
}
.docview__img {
  display: block;
  max-width: 100%;
  max-height: 60dvh;
  border: 1px solid var(--rule-strong);
  background: #fff;
}
.docview figcaption { display: grid; gap: 0.15rem; justify-items: center; text-align: center; }
.docview figcaption strong { font-size: 0.88rem; }
.docview figcaption span { font-size: 0.74rem; color: var(--ink-soft); }

/* A case note thread. Read top to bottom as a record of a person, so each entry is a block with
   its attribution on it rather than a table row: the author and the timestamp are what make a
   note evidence, and they should never be the column that gets truncated. */
.notes { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6rem; }
.notes__item {
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--clay);
  background: var(--paper-2);
  display: grid;
  gap: 0.4rem;
}
.notes__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
}
.notes__head strong { font-size: 0.82rem; letter-spacing: 0.04em; text-transform: uppercase; }
.notes__meta { font-family: var(--mono); font-size: 0.72rem; color: var(--ink-soft); margin-left: auto; }
.notes__body { margin: 0; font-size: 0.88rem; color: var(--ink-2); white-space: pre-wrap; }
.notes__item .row-actions { justify-content: flex-end; }

/* A text thread. Read forwards, unlike the note thread above it, because a conversation only
   makes sense in the order it happened -- so the newest message is at the bottom, next to the
   composer, where anyone who has used a phone will look for it. Inbound leans left and outbound
   leans right: with one shared program number, "who said this" is the only thing distinguishing
   two messages that otherwise look identical. */
.texts { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.55rem; }
.texts__item {
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--rule);
  background: var(--paper-2);
  display: grid;
  gap: 0.35rem;
  max-width: 42rem;
}
.texts__item--in { border-left: 3px solid var(--ink-soft); justify-self: start; }
.texts__item--out { border-right: 3px solid var(--clay); justify-self: end; }
/* An unread reply is the one thing on either screen somebody has to act on. */
.texts__item.is-unread { border-left-color: var(--clay); background: var(--paper); box-shadow: inset 0 0 0 1px var(--clay); }
/* A failed send is always outbound, so it marks the edge outbound messages already carry. */
.texts__item.is-failed { border-right-color: var(--clay-deep); background: rgba(166, 81, 47, 0.08); }
.texts__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem; }
.texts__head strong { font-size: 0.78rem; letter-spacing: 0.04em; text-transform: uppercase; }
.texts__meta { font-family: var(--mono); font-size: 0.7rem; color: var(--ink-soft); margin-left: auto; }
.texts__body { margin: 0; font-size: 0.9rem; color: var(--ink-2); white-space: pre-wrap; }
.texts__status { font-family: var(--mono); font-size: 0.7rem; color: var(--ink-soft); }
/* Seven seats means seven possible threads, most of them empty, so each collapses to its heading
   until it has something unread in it. */
.texts__thread { border: 1px solid var(--rule); padding: 0.55rem 0.7rem; display: grid; gap: 0.55rem; }
.texts__thread > summary { cursor: pointer; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem; }
.texts__thread > summary strong { font-size: 0.85rem; }

/* The vault's filing bar. Each folder carries what it holds, because a count of zero is the most
   useful thing the bar can tell you: it is the folder that wants relabelling or removing. */
.folders { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.folders__btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: var(--paper);
  color: var(--ink-2);
  font: inherit;
  font-size: 0.82rem;
  cursor: pointer;
  text-align: left;
}
.folders__btn:hover { border-color: var(--rule-strong); color: var(--ink); }
.folders__btn.is-active {
  border-color: var(--clay);
  box-shadow: inset 0 -2px 0 var(--clay);
  color: var(--ink);
}
.folders__count {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--ink-faint);
  padding: 0.02rem 0.3rem;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: var(--paper-2);
}
.folders__btn.is-active .folders__count { color: var(--ink-soft); }

/* The read-only detail panel shares the sheet's frame; only its inner box is a div, not a form. */
.sheet--detail > div {
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  border-top: 3px solid var(--clay);
  border-radius: 2px;
  max-height: 88dvh;
  overflow-y: auto;
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}
.detail {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.35rem 0.9rem;
  margin: 0;
  font-size: 0.85rem;
}
.detail dt {
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding-top: 0.12rem;
}
.detail dd { margin: 0; color: var(--ink-2); white-space: pre-wrap; }

@media (max-width: 60rem) {
  .calgrid__day, .calgrid__col { min-height: 5rem; }
  .calbar__label { min-width: 8rem; font-size: 0.95rem; }
}

/* A seven-column grid on a phone gives each day a strip too narrow to read. The month keeps its
   shape because its shape is the information; the week becomes the list of days it stands for. */
@media (max-width: 46rem) {
  .calgrid--week { grid-template-columns: minmax(0, 1fr); }
  .calgrid--week .calgrid__col { min-height: 0; }
  .calchip__title { white-space: normal; }
}
@media (max-width: 34rem) {
  .calbar { justify-content: stretch; }
  .calbar__modes { flex: 1 1 100%; min-width: 0; }
  .calbar__nav { flex: 1 1 100%; justify-content: space-between; }
  .calgrid--month .calgrid__dow { font-size: 0.6rem; letter-spacing: 0.04em; }
  .calgrid__day { min-height: 4.2rem; padding: 0.2rem; }
  .calchip { flex-direction: column; gap: 0; padding: 0.14rem 0.22rem; }
  .calchip__title { font-size: 0.68rem; }
}

/* -------------------------------------------------------------- omnibox ---- */

/* One search field over the whole record, sitting in the dark topbar between the brand and the
   seat plate. It is a combobox, so the panel below is a real listbox and the marked words in a
   result are <mark> elements rather than colour alone. */
.omni {
  position: relative;
  flex: 1 1 24rem;
  max-width: 34rem;
  min-width: 0;
}
.omni__field {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0 0.5rem;
  border: 1px solid rgba(244, 239, 230, 0.22);
  border-radius: 2px;
  background: rgba(244, 239, 230, 0.06);
}
.omni__field:focus-within {
  border-color: rgba(244, 239, 230, 0.5);
  background: rgba(244, 239, 230, 0.12);
}
.omni__field svg {
  width: 1rem; height: 1rem; flex: none;
  fill: none; stroke: rgba(244, 239, 230, 0.65);
  stroke-width: 1.7; stroke-linecap: round;
}
.omni__field input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.52rem 0;
  border: 0;
  background: none;
  color: var(--paper);
  font: inherit;
  font-size: 0.86rem;
}
.omni__field input::placeholder { color: rgba(244, 239, 230, 0.45); }
.omni__field input:focus { outline: none; }
/* The browser's own clear button draws a dark glyph on a dark field. */
.omni__field input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.omni__key {
  flex: none;
  font-family: var(--mono);
  font-size: 0.68rem;
  padding: 0.1rem 0.34rem;
  border: 1px solid rgba(244, 239, 230, 0.2);
  border-radius: 2px;
  color: rgba(244, 239, 230, 0.55);
}
.omni__field:focus-within .omni__key { visibility: hidden; }

/* The results panel hangs below the field on the paper ground, because what it contains is record
   content and belongs to the document, not to the chrome. */
.omni__panel {
  position: absolute;
  top: calc(100% + 0.4rem);
  left: 0;
  right: 0;
  max-height: min(28rem, 70vh);
  overflow-y: auto;
  z-index: 8;
  padding: 0.3rem;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  box-shadow: var(--shadow);
}
.omni__group {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.45rem 0.5rem 0.25rem;
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border-bottom: 1px solid var(--rule);
}
.omni__count { font-family: var(--mono); letter-spacing: 0; color: var(--ink-faint); }
.omni__hit {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.45rem 0.5rem;
  border: 0;
  border-left: 2px solid transparent;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.omni__hit:hover { background: var(--paper-2); }
/* Keyboard and pointer selection are the same state: arrow keys move it, so hover alone would let
   two rows look chosen at once and the wrong record get opened. */
.omni__hit.is-active { background: var(--paper-2); border-left-color: var(--clay); }
.omni__hitline { display: flex; align-items: baseline; justify-content: space-between; gap: 0.6rem; }
.omni__hittitle { font-weight: 600; font-size: 0.9rem; }
.omni__hitwhen { flex: none; font-family: var(--mono); font-size: 0.7rem; color: var(--ink-faint); }
.omni__hitsub { display: block; font-size: 0.76rem; color: var(--ink-soft); }
.omni__hitsnip {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--ink-2);
}
.omni__panel mark { background: rgba(157, 120, 24, 0.26); color: inherit; padding: 0 0.05em; border-radius: 1px; }
.omni__none { margin: 0; padding: 0.75rem 0.5rem; font-size: 0.84rem; color: var(--ink-soft); }
.omni__foot {
  margin: 0.3rem 0 0;
  padding: 0.45rem 0.5rem;
  border-top: 1px solid var(--rule);
  font-size: 0.74rem;
  color: var(--ink-faint);
}

/* The row a search result pointed at, once its screen has drawn. It fades rather than blinks: a
   marker that vanishes on a timer is missed by anyone who looked away, and one that stays becomes
   part of the record's appearance. */
.is-located {
  animation: located 2.6s ease-out 1;
  scroll-margin: 6rem;
}
@keyframes located {
  0%, 55% { background: rgba(157, 120, 24, 0.28); box-shadow: inset 3px 0 0 var(--clay); }
  100% { background: transparent; box-shadow: inset 3px 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .is-located { animation: none; background: rgba(157, 120, 24, 0.2); box-shadow: inset 3px 0 0 var(--clay); }
}

/* ------------------------------------------------------------ assistant ---- */

/* Past conversations down the side, the exchange in the middle, the composer pinned to the foot.
   The log is the only scrolling part, so the question box never walks off the bottom of a tablet. */
.chat {
  display: grid;
  grid-template-columns: 15rem minmax(0, 1fr);
  gap: 0.9rem;
  align-items: stretch;
  min-height: min(46rem, calc(100vh - var(--topbar-h) - 4rem));
}
.chat__list { display: flex; flex-direction: column; gap: 0.6rem; min-width: 0; }
.chat__new { width: 100%; }
.chat__past { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.chat__past li { display: flex; align-items: stretch; gap: 0.2rem; border-bottom: 1px solid var(--rule); }
.chat__pastlink {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  text-align: left;
  padding: 0.5rem 0.4rem;
  border: 0;
  border-left: 2px solid transparent;
  background: none;
  font: inherit;
  color: var(--ink-2);
  cursor: pointer;
}
.chat__pastlink:hover { background: var(--paper-2); }
.chat__pastlink.is-active { border-left-color: var(--clay); background: var(--paper-2); color: var(--ink); }
.chat__pasttitle {
  font-size: 0.82rem;
  line-height: 1.35;
  /* Titles are whole questions; two lines is enough to tell them apart. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.chat__pastwhen { font-family: var(--mono); font-size: 0.68rem; color: var(--ink-faint); }
.chat__drop {
  flex: none;
  width: 1.9rem;
  border: 0;
  background: none;
  font-size: 1.1rem;
  line-height: 1;
  color: var(--ink-faint);
  cursor: pointer;
}
.chat__drop:hover { color: var(--clay-deep); background: var(--paper-2); }
.chat__none { margin: 0; padding: 0.5rem 0.4rem; font-size: 0.8rem; color: var(--ink-faint); }

.chat__main {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  min-width: 0;
  background: #fbf8f2;
  border: 1px solid var(--rule);
  border-radius: 2px;
  padding: 0.9rem;
}
.chat__log {
  flex: 1 1 auto;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  min-height: 14rem;
  scroll-behavior: smooth;
}

.chat__seed { max-width: 44rem; }
.chat__seed h2 { font-family: var(--display); font-size: 1.15rem; margin: 0 0 0.3rem; }
.chat__seed p { margin: 0 0 0.9rem; font-size: 0.86rem; line-height: 1.55; color: var(--ink-soft); }
.chat__seeds { display: flex; flex-direction: column; gap: 0.4rem; align-items: flex-start; }
.chat__seedbtn {
  text-align: left;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--rule);
  border-left: 2px solid var(--clay);
  border-radius: 2px;
  background: var(--paper);
  font: inherit;
  font-size: 0.84rem;
  color: var(--ink-2);
  cursor: pointer;
}
.chat__seedbtn:hover { background: var(--paper-2); color: var(--ink); }
.chat__tools { margin-top: 1rem; font-size: 0.8rem; color: var(--ink-soft); }
.chat__tools summary { cursor: pointer; }
.chat__tools ul { margin: 0.4rem 0 0; padding-left: 1.1rem; line-height: 1.6; }

/* A turn is a ledger entry, not a speech bubble: ruled on the left, labelled with who said it. */
.turn { max-width: 46rem; border-left: 2px solid var(--rule-strong); padding-left: 0.7rem; }
.turn--me { border-left-color: var(--ink-faint); }
.turn--bot { border-left-color: var(--clay); }
.turn__who {
  font-size: 0.66rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.2rem;
}
.turn__body { font-size: 0.9rem; line-height: 1.6; color: var(--ink); }
.turn__body p { margin: 0 0 0.55rem; }
.turn__body p:last-child { margin-bottom: 0; }
.turn__body ul, .turn__body ol { margin: 0 0 0.55rem; padding-left: 1.2rem; }
.turn__body li { margin-bottom: 0.2rem; }
.turn__body code { font-family: var(--mono); font-size: 0.85em; background: var(--paper-2); padding: 0 0.2em; border-radius: 2px; }
.turn.is-waiting .turn__body { color: var(--ink-faint); font-style: italic; }
.turn__work { margin: -0.4rem 0 0 0.7rem; font-family: var(--mono); font-size: 0.7rem; color: var(--ink-faint); }

/* Citations. An answer that quotes a figure into a federal report has to be checkable, so each
   record the answer used is a way back to the screen that owns it. */
.turn__sources { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; margin-top: 0.55rem; }
.turn__srclabel {
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.srcchip {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35rem;
  max-width: 20rem;
  padding: 0.2rem 0.45rem;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: var(--paper);
  font: inherit;
  font-size: 0.74rem;
  color: var(--ink-2);
  cursor: pointer;
}
.srcchip:hover { border-color: var(--clay); color: var(--clay-deep); }
.srcchip__kind { font-family: var(--mono); font-size: 0.64rem; text-transform: uppercase; color: var(--ink-faint); }
.srcchip__title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.chat__form { display: flex; flex-direction: column; gap: 0.4rem; border-top: 1px solid var(--rule); padding-top: 0.7rem; }
.chat__ask {
  width: 100%;
  resize: vertical;
  min-height: 3.4rem;
  padding: 0.55rem 0.6rem;
  font: inherit;
  font-size: 0.9rem;
}
.chat__formfoot { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; }
.chat__formfoot small { font-family: var(--mono); font-size: 0.68rem; color: var(--ink-faint); }
.chat__actions { display: flex; align-items: center; gap: 0.4rem; }

/* Voice. The microphone is the one control that has to be findable at arm's length on a tablet in
   a training kitchen, so it is large, labelled, and unmistakably lit while it is listening. */
.chat__mic {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 2.4rem;
  padding: 0.4rem 0.85rem;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  background: var(--paper);
  font: inherit;
  font-size: 0.84rem;
  color: var(--ink-2);
  cursor: pointer;
}
.chat__mic:hover:not(:disabled) { border-color: var(--clay); color: var(--clay-deep); }
.chat__mic:disabled { opacity: 0.5; cursor: not-allowed; }
.chat__micdot { width: 0.7rem; height: 0.7rem; border-radius: 50%; background: var(--clay); flex: none; }
.chat__mic.is-live { background: var(--clay); border-color: var(--clay-deep); color: #fdf7ef; }
.chat__mic.is-live .chat__micdot { background: #fdf7ef; animation: chat-mic-pulse 1.1s ease-in-out infinite; }
@keyframes chat-mic-pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.45); opacity: 0.55; }
}
@media (prefers-reduced-motion: reduce) {
  .chat__mic.is-live .chat__micdot { animation: none; }
}
.chat__voicebar { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 1rem; font-size: 0.78rem; color: var(--ink-soft); }
.chat__toggle { display: inline-flex; align-items: center; gap: 0.35rem; cursor: pointer; }
.chat__toggle input { margin: 0; accent-color: var(--clay); }
.chat__hush { padding: 0.2rem 0.6rem; font-size: 0.76rem; }
.chat__voicestatus { font-style: italic; color: var(--clay-deep); }

.turn--bot .turn__who { display: flex; align-items: center; gap: 0.6rem; }
.turn__listen {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.05rem 0.45rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: transparent;
  font: inherit;
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
  cursor: pointer;
}
.turn__listen:hover { border-color: var(--clay); color: var(--clay-deep); }
.turn__listen.is-playing { background: var(--clay); border-color: var(--clay); color: #fdf7ef; }
.turn__listenicon { font-size: 0.8rem; letter-spacing: 0; }

@media (max-width: 60rem) {
  /* The field is worth more than the seat plate on a narrow topbar, so it keeps its width and the
     brand subtitle gives way instead. */
  .omni { flex: 1 1 12rem; }
  .omni__key { display: none; }
}
@media (max-width: 52rem) {
  .chat { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  /* Past conversations move below the exchange: on a phone the current answer is what matters. */
  .chat__list { order: 2; }
  .chat__main { order: 1; padding: 0.6rem; }
  .chat__log { max-height: none; overflow: visible; }
}
@media (max-width: 34rem) {
  .omni__panel { position: fixed; left: 0.5rem; right: 0.5rem; top: calc(var(--topbar-h) + 0.3rem); }
}

/* ------------------------------------------------------ award documents ---- */

/* The award read as a document rather than as a table. Sections stack in a single column with a
   ruled edge, because that is what a reader scanning for a clause is doing: going down a page. */
.award {
  display: grid;
  gap: 0.4rem;
  margin-top: 0.9rem;
}
.award__sec {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--rule-strong);
  border-radius: 2px;
  scroll-margin: 6rem;
}
.award__sec[open] { border-left-color: var(--clay); box-shadow: var(--shadow); }
.award__head {
  cursor: pointer;
  list-style: none;
  padding: 0.7rem 0.9rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.award__head::-webkit-details-marker { display: none; }
.award__head:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
/* The disclosure arrow is drawn rather than inherited, so it can point down when open on every
   browser instead of only the ones whose default marker rotates. */
.award__head::before {
  content: "";
  flex: none;
  width: 0.42rem;
  height: 0.42rem;
  border-right: 2px solid var(--clay);
  border-bottom: 2px solid var(--clay);
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
}
.award__sec[open] > .award__head::before { transform: rotate(45deg); }
.award__heading {
  flex: 1 1 auto;
  font-family: var(--display);
  font-size: 0.95rem;
  line-height: 1.3;
}

/* The document's own line breaks are kept. These sections are forms and budget tables -- Form RD
   1940-1's numbered boxes, a category-by-category revision -- and re-flowing them into prose is
   what turns a table a reviewer can check into a paragraph they cannot. Horizontal scrolling is
   allowed for the same reason: a wrapped budget row is a misread budget row. */
.award__text {
  margin: 0;
  padding: 0 0.9rem 0.9rem 0.9rem;
  font-family: var(--mono);
  font-size: 0.76rem;
  line-height: 1.65;
  color: var(--ink-2);
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

@media (max-width: 34rem) {
  .award__text { font-size: 0.72rem; }
}

/* -------------------------------------------------------------- form doc ---- */

/* The blank compliance instruments (public/forms.js): the contractor invoice, the attendance
   roster, the counseling record, and the packet procedure.

   These are the one family of documents in the portal that is visible on screen as well as on
   paper, which is the opposite of .printdoc above and deliberate. A report's reader already knows
   which award they are looking at, so its letterhead is print-only furniture. Here the paper *is*
   the product: a coordinator about to run twelve rosters off for a cohort needs to see the sheet
   they will get, including how much room a participant has to sign in. So the sheet is drawn
   white on the warm ground, at roughly the proportions it prints at, and the print block at the
   foot of this file only converts the units to points and sets the page breaks.

   Fields are ruled boxes rather than rows of underscores. Underscores are what a form looks like
   when it was typed in a text editor: they break in the middle of a name, they drift with the
   font, and they give every field the same amount of room whatever it holds. */

.formdoc {
  max-width: 54rem;
  margin: 0 0 1.5rem;
  padding: 1.55rem 1.7rem 1.15rem;
  background: #fff;
  border: 1px solid var(--rule);
  border-top: 3px solid var(--ink);
  border-radius: 2px;
  box-shadow: var(--shadow);
  color: var(--ink);
  font-size: 0.82rem;
  line-height: 1.45;
}

/* Mark, identification block, control box -- the three things across the top of a federal form,
   in that order, under one heavy rule. */
.formdoc__rule {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  padding-bottom: 0.6rem;
  border-bottom: 2px solid var(--ink);
}
.formdoc__mark { width: 3rem; height: 3rem; object-fit: contain; flex: none; }
.formdoc__ident { flex: 1 1 auto; min-width: 0; }
.formdoc__agency {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.formdoc__title { margin: 0.15rem 0 0; font-family: var(--display); font-size: 1.22rem; line-height: 1.1; }
.formdoc__eyebrow {
  margin: 0.2rem 0 0;
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.formdoc__org { margin: 0.2rem 0 0; font-size: 0.74rem; color: var(--ink-soft); }

/* The control box. Form number and revision rather than a timestamp: two seats printing this a
   month apart are filling in the same instrument, and what a reviewer needs to know is which
   revision the signature is against. */
.formdoc__control {
  flex: none;
  width: 13.5rem;
  margin: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  border: 1px solid var(--ink);
}
.formdoc__control dt {
  padding: 0.2rem 0.35rem;
  border-right: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 0.58rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-soft);
  white-space: nowrap;
}
.formdoc__control dd {
  margin: 0;
  padding: 0.2rem 0.35rem;
  font-family: var(--mono);
  font-size: 0.66rem;
  text-align: right;
}
.formdoc__control dt:not(:first-of-type),
.formdoc__control dt:not(:first-of-type) + dd { border-top: 1px solid var(--rule); }

/* Award particulars in ruled boxes, so a reviewer checking one field can find it without reading
   the other three. */
.formdoc__facts {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  margin: 0.7rem 0 0;
  border: 1px solid var(--rule);
  border-width: 1px 0 0 1px;
}
.formdoc__factcell {
  padding: 0.25rem 0.42rem 0.3rem;
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  min-width: 0;
}
.formdoc__factcell--span2 { grid-column: span 2; }
.formdoc__factcell dt {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.58rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.formdoc__factcell dd { margin: 0.1rem 0 0; font-size: 0.74rem; font-weight: 600; line-height: 1.25; }

/* A numbered section band: the heading a reader scans for when they are hunting one box. */
.formdoc__band {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin: 1.1rem 0 0.45rem;
  padding-bottom: 0.15rem;
  border-bottom: 1px solid var(--rule-strong);
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}
.formdoc__band small {
  font-family: var(--body);
  font-size: 0.68rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-soft);
}

/* ---- fields ---- */

.formdoc__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border: 1px solid var(--rule);
  border-width: 1px 0 0 1px;
}
.formdoc__cell {
  padding: 0.3rem 0.45rem 0.35rem;
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  min-width: 0;
}
.formdoc__cell--span2 { grid-column: span 2; }
.formdoc__cell--span3 { grid-column: span 3; }
.formdoc__cell--span4 { grid-column: span 4; }
/* A box the portal fills in itself, tinted the way an agency-use box is tinted on the form, so a
   person with a pen can see at a glance which boxes are theirs. */
.formdoc__cell.is-stated { background: var(--paper-2); }

.formdoc__label {
  display: block;
  font-family: var(--mono);
  font-size: 0.59rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.formdoc__value { display: block; margin-top: 0.15rem; font-size: 0.76rem; font-weight: 600; line-height: 1.3; }
.formdoc__hint { display: block; margin-top: 0.2rem; font-size: 0.63rem; line-height: 1.35; color: var(--ink-faint); }
/* The rule a person writes on. */
.formdoc__write {
  display: block;
  height: 1.05rem;
  margin-top: 0.15rem;
  border-bottom: 1px solid var(--rule-strong);
}

.formdoc__boxes { display: flex; flex-wrap: wrap; gap: 0.3rem 0.85rem; margin-top: 0.3rem; }
.formdoc__check { display: inline-flex; align-items: flex-start; gap: 0.35rem; font-size: 0.75rem; line-height: 1.35; }
.formdoc__check.is-strong { font-weight: 700; }
.formdoc__box {
  flex: none;
  width: 0.72rem;
  height: 0.72rem;
  margin-top: 0.15rem;
  border: 1px solid var(--ink);
  background: #fff;
}

/* ---- the invoice's claim blocks ---- */

/* Three blocks rather than one fee box, because the three agreements are earned three different
   ways. A single "amount claimed" line would let any of them be billed as if it were another. */
.formdoc__claim {
  margin: 0 0 0.5rem;
  padding: 0.45rem 0.6rem 0.5rem;
  border: 1px solid var(--rule-strong);
  border-left: 3px solid var(--ink);
}
.formdoc__claimhead { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 0.4rem; }
.formdoc__ceiling { font-family: var(--mono); font-size: 0.68rem; color: var(--ink-2); }
.formdoc__basis { margin: 0.25rem 0 0.35rem; font-size: 0.7rem; line-height: 1.4; color: var(--ink-soft); }
.formdoc__claimline {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 0.15rem 0.6rem;
  padding: 0.3rem 0;
  border-top: 1px solid var(--rule);
}
.formdoc__fixed, .formdoc__calc {
  justify-self: end;
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  white-space: nowrap;
}
.formdoc__evidence { grid-column: 1 / -1; font-size: 0.63rem; line-height: 1.35; color: var(--ink-faint); }
.formdoc__qty { display: inline-block; width: 2.6rem; height: 1.05rem; border-bottom: 1px solid var(--rule-strong); }
.formdoc__money { display: inline-flex; align-items: baseline; gap: 0.15rem; }
.formdoc__money .formdoc__write { width: 5.2rem; margin-top: 0; }
.formdoc__currency { font-family: var(--mono); }
.formdoc__total {
  display: flex;
  justify-content: flex-end;
  align-items: baseline;
  gap: 0.6rem;
  margin-top: 0.4rem;
  padding-top: 0.35rem;
  border-top: 2px solid var(--ink);
}

/* ---- ruled tables to write in ---- */

.formdoc__table { width: 100%; border-collapse: collapse; }
.formdoc__table th {
  padding: 0.22rem 0.4rem;
  border: 1px solid var(--rule);
  border-bottom-color: var(--rule-strong);
  font-family: var(--mono);
  font-size: 0.59rem;
  font-weight: 500;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  text-align: left;
  color: var(--ink-soft);
}
.formdoc__table td { height: 1.8rem; padding: 0.2rem 0.4rem; border: 1px solid var(--rule); vertical-align: bottom; }
.formdoc__table .is-num { text-align: right; }
.formdoc__rownum { font-family: var(--mono); font-size: 0.66rem; color: var(--ink-faint); }

.formdoc__line { display: block; height: 1.45rem; border-bottom: 1px solid var(--rule); }

.formdoc__areas {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.3rem 0.85rem;
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--rule);
}

/* ---- checklists and procedures ---- */

.formdoc__controls, .formdoc__packet { margin: 0; padding: 0; list-style: none; }
.formdoc__packet { counter-reset: packetitem; }
.formdoc__controls li, .formdoc__packet li { padding: 0.32rem 0; border-bottom: 1px solid var(--rule); }
.formdoc__controls li:first-child, .formdoc__packet li:first-child { border-top: 1px solid var(--rule); }
.formdoc__packet li::before {
  counter-increment: packetitem;
  content: counter(packetitem) ".";
  margin-right: 0.3rem;
  font-family: var(--mono);
  font-size: 0.66rem;
  color: var(--ink-faint);
}
/* Why the box is on the form -- what goes wrong when it is ticked without being true. */
.formdoc__because { display: block; margin: 0.12rem 0 0 1.1rem; font-size: 0.65rem; line-height: 1.4; color: var(--ink-faint); }

.formdoc__steps { margin: 0; padding-left: 1.3rem; }
.formdoc__steps li { margin-bottom: 0.45rem; }
.formdoc__steps strong { display: block; font-size: 0.77rem; }
.formdoc__steps span { display: block; font-size: 0.72rem; line-height: 1.45; color: var(--ink-soft); }

/* ---- certification and signatures ---- */

.formdoc__cert {
  margin: 0.4rem 0 0.55rem;
  padding-left: 0.55rem;
  border-left: 2px solid var(--ink);
  font-size: 0.68rem;
  line-height: 1.5;
  text-align: justify;
  color: var(--ink-2);
}
.formdoc__sign {
  display: grid;
  grid-template-columns: 1.55fr 1fr;
  border: 1px solid var(--ink);
  border-width: 1px 0 0 1px;
}
.formdoc__signcell {
  padding: 0.25rem 0.45rem 0.3rem;
  border-right: 1px solid var(--ink);
  border-bottom: 1px solid var(--ink);
  min-width: 0;
}
.formdoc__signcell.is-stated { background: var(--paper-2); }
/* An empty block is not empty space: it is the line someone signs on. */
.formdoc__signspace { display: block; height: 1.9rem; }

.formdoc__foot {
  margin: 1rem 0 0;
  padding-top: 0.4rem;
  border-top: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 0.6rem;
  line-height: 1.5;
  letter-spacing: 0.02em;
  color: var(--ink-faint);
  word-break: break-word;
}

/* ---- the same sheet, being filled in ---- */

/* One layout in two states, so the fields a person types into have to occupy exactly the space
   the ruled blanks occupied. Every control below inherits the rule it replaces -- same height,
   same baseline, no box of its own -- so switching to "Fill in on screen" does not reflow the
   sheet under the seat, and the printed result is the blank with answers on the lines rather
   than a second, differently-shaped document. Hence transparent backgrounds and a single bottom
   border: the border IS the rule. */
.formdoc__fillin {
  font: inherit;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 0 0.1rem;
  -webkit-appearance: none;
  appearance: none;
}
.formdoc__fillin:focus-visible {
  outline: 2px solid var(--clay);
  outline-offset: 1px;
  background: var(--paper-2);
}
input.formdoc__write {
  width: 100%;
  min-width: 0;
  border-bottom: 1px solid var(--rule-strong);
}
input.formdoc__qty { width: 2.6rem; border-bottom: 1px solid var(--rule-strong); }
.formdoc__money input.formdoc__write { width: 5.2rem; margin-top: 0; text-align: right; }

/* A typed answer inside a ruled table cell. No underline: the cell is already ruled on all four
   sides, and a second line inside it reads as a correction. */
.formdoc__cell-input {
  width: 100%;
  min-width: 0;
  height: 1.4rem;
  font-size: 0.72rem;
}
.formdoc__table .is-num .formdoc__cell-input { text-align: right; }

/* The signature grid's transcribed cells -- printed name, date, amount approved. The signature
   cells themselves stay .formdoc__signspace in both states: a typed name in a signature box
   would print looking like a signature and be worth nothing. */
.formdoc__signfill {
  display: block;
  width: 100%;
  min-width: 0;
  height: 1.9rem;
  border-bottom: 1px solid var(--rule);
}

/* Ruled writing space becomes a textarea of the same height, growing nowhere: a findings box
   that scrolls hides half of what it says once it is printed, so the lines are the limit. */
.formdoc__area {
  display: block;
  width: 100%;
  margin-top: 0.15rem;
  padding: 0.25rem 0.35rem;
  font: inherit;
  font-size: 0.76rem;
  line-height: 1.45rem;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 2px;
  resize: vertical;
}
.formdoc__area:focus-visible { outline: 2px solid var(--clay); outline-offset: 1px; }

/* A ticked box has to print as the same square, whether it was clicked or inked. */
input.formdoc__box {
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
  position: relative;
}
input.formdoc__box:checked::after {
  content: "";
  position: absolute;
  inset: 0.1rem;
  background: var(--ink);
}
input.formdoc__box:focus-visible { outline: 2px solid var(--clay); outline-offset: 1px; }

/* The fields that stay pen-only in both states -- the contractor's taxpayer identification. */
.formdoc__hint--pen { font-style: italic; }

/* A sheet being filled in says so on screen, and stops saying it on paper (see the print
   block): what comes out of the printer is the instrument, not a picture of an editor. */
.formdoc--filling { box-shadow: inset 3px 0 0 var(--clay), var(--shadow); }

/* ---- electronic signatures ---- */

/* A signed block keeps the height of the pen space it replaces, so a signed sheet and an unsigned
   one lay out identically; the stamp under the picture is the evidence of how it was made. */
.formdoc__esign { display: flex; flex-direction: column; align-items: flex-start; gap: 0.2rem; min-width: 0; }
.formdoc__esign .formdoc__signspace { width: 100%; }
.formdoc__esignbtn { margin-top: -1.75rem; margin-bottom: 0.2rem; }
.formdoc__esignimg { display: block; height: 2.6rem; width: auto; max-width: 100%; object-fit: contain; object-position: left center; }
.formdoc__esignstamp {
  font-family: var(--mono);
  font-size: 0.56rem;
  line-height: 1.4;
  color: var(--ink-2);
  word-break: break-word;
}
.formdoc__esignwarn { font-size: 0.66rem; color: var(--clay-deep); }

.sigpad { max-width: 40rem; }
.sigpad__surface {
  position: relative;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  background: #fff;
}
/* touch-action: none, or a stroke on a tablet scrolls the page instead of drawing. */
.sigpad__canvas { display: block; width: 100%; height: auto; aspect-ratio: 600 / 160; touch-action: none; cursor: crosshair; }
.sigpad__canvas.is-typed { cursor: default; }
.sigpad__baseline {
  position: absolute;
  left: 4%;
  right: 4%;
  bottom: 22%;
  border-bottom: 1px dashed var(--rule-strong);
  pointer-events: none;
}
.sigpad__row { display: flex; align-items: flex-end; gap: 0.6rem; }
.sigpad__namefield { flex: 1; }
.sigpad__consent .field__label { font-size: 0.78rem; line-height: 1.45; text-transform: none; letter-spacing: 0; }

/* ---- saved, then exported or not ---- */

/* The export question, asked after a save and left on screen until it is answered.
   Not a modal: the honest answer to "export now?" is often "let me look at the sheet first",
   and a dialog over the sheet makes that impossible. Neither button dismisses it by default. */
/* The strip above each sheet in the binder when it is being filled in: which saved copy the sheet
   is, and the buttons to keep it. Screen only -- the sheets print exactly as on their own tabs. */
.binderbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  margin: 1.25rem 0 0.5rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--paper-2);
}
.binderbar__title { flex: 1 1 16rem; min-width: 0; }
.binderbar__title strong { display: block; font-size: 0.88rem; }
.binderbar__title span { display: block; font-size: 0.75rem; color: var(--ink-soft); }
.binderbar__actions { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }
.binderbar select { max-width: 16rem; }

/* ---- folding ----
   A sheet folds to its header bar and a section folds to its band, on screen only: the fold
   rules sit under `screen`, so a print of a folded sheet still carries every box on it. */
.formdoc__chev { display: inline-flex; flex: none; }
.formdoc__chev svg {
  width: 1rem;
  height: 1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.15s ease;
}
.is-folded > .formdoc__chev svg,
.is-folded > .formdoc__bandbtn .formdoc__chev svg,
.foldbtn[aria-expanded="false"] .formdoc__chev svg { transform: rotate(-90deg); }
.foldbtn { display: inline-flex; align-items: center; gap: 0.25rem; }

/* The band keeps its look -- it is the same heading on the printed sheet -- and is pressable. */
.formdoc__bandbtn {
  -webkit-appearance: none;
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.formdoc__bandbtn:hover { color: var(--clay); }
.formdoc__bandbtn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

.formtabs { display: flex; flex-direction: column; gap: 0.4rem; }
/* Six labels of uneven length will not share one row of equal columns on anything narrower than
   a wide desktop, so the strip wraps instead of running off the card's right edge. */
.formtabs .tabs {
  display: flex;
  flex-wrap: wrap;
  min-width: 0;
}
.formtabs .tabs__btn { flex: 1 1 auto; }
.formtabs__toggle {
  -webkit-appearance: none;
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  align-self: flex-start;
  padding: 0.3rem 0.1rem;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.76rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
}
.formtabs__toggle small {
  font-size: 0.72rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-soft);
}
.formtabs__toggle:hover small { color: var(--clay); }
.formtabs__toggle:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

.binderfold { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.6rem; }

@media screen {
  .formdoc.is-folded { display: none; }
  .formdoc > .is-folded:not(.formdoc__band) { display: none; }
  .formdoc__band.is-folded { margin-bottom: 0.2rem; }
}
@media print {
  .formdoc__bandbtn .formdoc__chev { display: none; }
}

.formprompt {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.25rem;
  margin: 0 0 1rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--rule-strong);
  border-left: 3px solid var(--clay);
  border-radius: 6px;
  background: var(--paper-2);
}
.formprompt__text { flex: 1 1 22rem; min-width: 0; }
.formprompt__text strong { display: block; font-size: 0.9rem; }
.formprompt__text span { display: block; margin-top: 0.2rem; font-size: 0.78rem; line-height: 1.5; color: var(--ink-soft); }
.formprompt__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }

/* A phone is where a roster gets checked before it is printed from a desk, so the sheet has to
   stay legible at 22rem: the four-column identification grids fold to two, and the signature
   blocks stack into one column rather than squeezing a signature into 40% of a phone. */
@media (max-width: 52rem) {
  .formdoc { padding: 1rem 0.9rem 0.9rem; font-size: 0.8rem; }
  .formdoc__rule { flex-wrap: wrap; }
  .formdoc__control { width: 100%; }
  .formdoc__facts, .formdoc__grid { grid-template-columns: repeat(2, 1fr); }
  .formdoc__factcell--span2,
  .formdoc__cell--span2,
  .formdoc__cell--span3,
  .formdoc__cell--span4 { grid-column: span 2; }
  .formdoc__areas { grid-template-columns: 1fr; }
  .formdoc__sign { grid-template-columns: 1fr; }
  .formdoc__table { font-size: 0.7rem; }
  .formdoc__table th { font-size: 0.55rem; }
}

/* ---------------------------------------------------------------- print ---- */

/* A saved PDF from this screen is filed with a federal award, so it has to read as a document:
   white ground, black text, ruled tables, a letterhead at the top and a certification at the
   foot. Everything that belongs to the application -- the dark topbar, the navigation rail, the
   paper grain, every button -- comes off. */
@media print {
  @page { size: letter portrait; margin: 0.6in 0.55in; }

  html, body {
    background: #fff;
    color: #000;
    font-size: 10.5pt;
    line-height: 1.4;
  }

  /* The application chrome. None of it means anything on paper. */
  .grain,
  .topbar,
  .navtoggle,
  .refreshbtn,
  .rail,
  .navbar,
  .navscrim,
  .toast,
  .update,
  .sheet,
  #boot,
  #gate,
  .printcue,
  .noprint,
  .tabs,
  .viewhead__actions,
  .filters,
  .folders,
  .calbar,
  .calgrid__more,
  .btn,
  .linkbtn,
  .field__hint,
  .row-actions,
  .rowactions,
  .skeleton,
  .installbar,
  .field__bubble { display: none !important; }

  .shell { display: block; min-height: 0; }
  .stage { padding: 0; }

  /* Cards become ruled sections of one continuous report rather than floating panels. */
  .sheet-card {
    background: transparent;
    border: 0;
    border-top: 1pt solid #000;
    border-radius: 0;
    box-shadow: none;
    margin: 0 0 14pt;
    overflow: visible;
    break-inside: avoid;
  }
  .sheet-card__head {
    background: transparent;
    border-bottom: 0.5pt solid #666;
    padding: 4pt 0;
  }
  .sheet-card__head h2 { font-size: 11pt; letter-spacing: 0.02em; }
  .sheet-card__head p { color: #333; font-size: 8.5pt; }
  .sheet-card__body { padding: 6pt 0 0; }
  .sheet-card__body--flush { padding: 0; }

  /* Paired cards print one under the other: two narrow columns of figures on letter paper
     forces the numbers small enough to misread. */
  .split, .stack { display: block; }
  .split > * + *, .stack > * + * { margin-top: 0; }

  .tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6pt; margin-bottom: 12pt; }
  .tile {
    background: transparent;
    border: 0.5pt solid #999;
    border-top: 1.5pt solid #000;
    padding: 5pt 6pt;
    animation: none;
    break-inside: avoid;
  }
  .tile dd { font-size: 15pt; }

  /* A sticky header is a scrolling device. In print it would float over the first data row. */
  .tablewrap { overflow: visible; }
  table.ledger { font-size: 9pt; break-inside: auto; }
  table.ledger th {
    position: static;
    background: transparent;
    color: #000;
    border-bottom: 0.75pt solid #000;
    padding: 3pt 4pt;
    font-size: 7.5pt;
  }
  table.ledger td { padding: 3pt 4pt; border-bottom: 0.4pt solid #bbb; color: #000; }
  table.ledger tbody tr:hover { background: transparent; }
  /* Repeat the column heads when a long roster runs onto a second sheet. */
  thead { display: table-header-group; }
  tr, .cell__note { break-inside: avoid; }
  .cell__note { display: block; -webkit-line-clamp: none; overflow: visible; max-width: none; }

  /* Status words have to survive a monochrome laser printer, so they are read as text with a
     rule around them rather than as a colour. */
  .pill, .tag {
    background: transparent !important;
    color: #000 !important;
    border: 0.4pt solid #666;
  }
  .notice, .notice--good, .faultbox {
    background: transparent;
    border: 0.5pt solid #666;
    border-left-width: 2pt;
    color: #000;
    break-inside: avoid;
  }

  /* A folded procedure prints as a heading with nothing beneath it, which is worse than useless
     on a sheet someone is holding while they work through it. */
  .faultbox__steps:not([open]) > *:not(summary) {
    display: block;
    content-visibility: visible;
  }

  /* The feed address is a credential. It must not be on a sheet that gets left on a desk. */
  .subcard { display: none; }

  /* A step number set in white on ink navy disappears on a printer that drops backgrounds, which
     would leave an unnumbered procedure. On paper it is a ruled circle around black type. */
  .steps li::before {
    background: transparent;
    color: #000;
    border: 0.5pt solid #666;
    font-size: 7.5pt;
  }
  .steps li, .howto__card { break-inside: avoid; }
  .howto {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6pt;
  }
  .howto__card {
    background: transparent;
    border: 0.5pt solid #999;
    border-top: 1.5pt solid #000;
    padding: 5pt 6pt;
  }
  .howto__browser, .howto__steps { color: #333; }

  .viewhead { border-bottom: 0; padding-bottom: 0; margin-bottom: 10pt; }
  /* Where a letterhead is present it says everything the screen heading did, with the award and
     the grantee attached, so the screen heading would only repeat it. Every other screen keeps
     its heading -- a printed page with no title on it is worse than a repeated one. The blank
     forms carry their own letterhead for the same reason, so they drop the screen heading too. */
  .stage:has(.printdoc--head) .viewhead,
  .stage:has(.formdoc) .viewhead { display: none; }

  .muted, .cell__sub { color: #333; }
  .cell__warn { color: #000; font-weight: 700; }
  a { color: #000; text-decoration: none; }

  /* ---------------------------------------------------- numbered sections ---- */

  /* On a filed attachment a reviewer's question is "what does section 3 say", not "where is the
     card about cohorts". So on the screens that carry a letterhead -- and only those -- every
     card head is numbered in document order. The counter is print-only: on screen the sections
     are already visibly separate panels, and numbering them there would be bureaucracy for its
     own sake. */
  .stage:has(.printdoc--head) { counter-reset: filingsection; }
  .stage:has(.printdoc--head) .sheet-card__head h2::before {
    counter-increment: filingsection;
    content: counter(filingsection) ".";
    display: inline-block;
    min-width: 1.4em;
    font-family: var(--mono);
    font-size: 9.5pt;
    font-weight: 500;
  }

  /* -------------------------------------------------------- letterhead ---- */

  .printdoc { display: block; break-inside: avoid; }

  .printdoc--head { margin-bottom: 14pt; }

  /* Mark, identification block, control box -- the three things across the top of a federal
     form, in that order, under one heavy rule. */
  .printdoc__rule {
    display: flex;
    align-items: flex-start;
    gap: 10pt;
    border-bottom: 1.5pt solid #000;
    padding-bottom: 7pt;
  }
  .printdoc__mark { width: 46pt; height: 46pt; object-fit: contain; flex: none; }
  .printdoc__ident { flex: 1 1 auto; min-width: 0; }

  .printdoc__agency {
    margin: 0;
    font-family: var(--mono);
    font-size: 7pt;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #333;
  }
  .printdoc__title { margin: 1.5pt 0 0; font-size: 17pt; line-height: 1.05; }
  .printdoc__eyebrow {
    margin: 2pt 0 0;
    font-family: var(--mono);
    font-size: 7.5pt;
    letter-spacing: 0.1em;
    text-transform: uppercase;
  }
  .printdoc__org { margin: 2.5pt 0 0; font-size: 9pt; color: #333; }

  /* The document control box. Ruled on all four sides and pinned to the top right, where a
     reviewer already looks for the number they have to quote back. */
  .printdoc__control {
    flex: none;
    /* Wide enough that the control number never wraps: half a document number on two lines is
       worse than no box at all. */
    width: 170pt;
    margin: 0;
    display: grid;
    grid-template-columns: auto 1fr;
    border: 0.75pt solid #000;
  }
  .printdoc__control dt {
    font-family: var(--mono);
    font-size: 6.5pt;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #333;
    padding: 2.5pt 4pt;
    border-right: 0.4pt solid #bbb;
    white-space: nowrap;
  }
  .printdoc__control dd {
    margin: 0;
    padding: 2.5pt 4pt;
    font-family: var(--mono);
    font-size: 7.5pt;
    text-align: right;
  }
  .printdoc__control dt + dd { font-weight: 500; }
  /* The rows are dt/dd pairs, not wrappers, so the rule between rows is drawn on the cells. */
  .printdoc__control dt:not(:first-of-type),
  .printdoc__control dt:not(:first-of-type) + dd { border-top: 0.4pt solid #bbb; }

  /* Award particulars in ruled boxes rather than a paragraph: a reviewer checking one field --
     the grantee, the reporting basis -- can find it without reading the other seven. */
  .printdoc__facts {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    margin: 8pt 0 0;
    border: 0.5pt solid #999;
    border-width: 0.5pt 0 0 0.5pt;
  }
  .printdoc__cell {
    border-right: 0.5pt solid #999;
    border-bottom: 0.5pt solid #999;
    padding: 3pt 5pt 4pt;
    min-width: 0;
    break-inside: avoid;
  }
  .printdoc__cell dt {
    margin: 0;
    font-family: var(--mono);
    font-size: 6.5pt;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #444;
  }
  .printdoc__cell dd {
    margin: 1.5pt 0 0;
    font-size: 8.5pt;
    line-height: 1.25;
    font-weight: 600;
  }
  /* How many of the four columns a field takes. Declared per field where the letterhead is
     built, not by position here, so reordering the block cannot leave a hole in the grid. */
  .printdoc__cell--span2 { grid-column: span 2; }
  .printdoc__cell--span4 { grid-column: span 4; }

  .printdoc__note {
    margin: 8pt 0 0;
    font-size: 8pt;
    color: #333;
    border-left: 2pt solid #000;
    padding-left: 6pt;
    text-align: justify;
  }

  /* ----------------------------------------------------- certification ---- */

  /* The block a person signs. It never splits across a sheet: half a certification on the foot
     of page two is not a signed report. */
  .printdoc--cert {
    margin-top: 16pt;
    border-top: 1.5pt solid #000;
    padding-top: 8pt;
    break-inside: avoid;
  }
  .printdoc__certtitle {
    margin: 0;
    font-family: var(--mono);
    font-size: 8pt;
    letter-spacing: 0.16em;
    text-transform: uppercase;
  }
  .printdoc__certbody { margin: 5pt 0 0; font-size: 8pt; line-height: 1.45; text-align: justify; }

  /* Boxed blocks, lettered the way blocks 13a-13d are lettered on the form itself. The filled
     row is what the portal knows; the empty rows are for the certifying official, and their
     height is the space a person actually needs to write in. */
  .printsign {
    display: grid;
    grid-template-columns: 1.55fr 1fr;
    margin: 10pt 0 0;
    border: 0.75pt solid #000;
    border-width: 0.75pt 0 0 0.75pt;
  }
  .printsign__cell {
    border-right: 0.75pt solid #000;
    border-bottom: 0.75pt solid #000;
    padding: 2.5pt 5pt 3pt;
    min-width: 0;
    break-inside: avoid;
  }
  .printsign__label {
    display: block;
    font-family: var(--mono);
    font-size: 6.5pt;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #333;
  }
  .printsign__value {
    display: block;
    margin-top: 2pt;
    font-size: 8.5pt;
    font-weight: 600;
    line-height: 1.25;
  }
  /* An empty block is not empty space: it is the line someone signs on. */
  .printsign__space { display: block; height: 26pt; }
  /* A pre-printed block, tinted the way an agency-use box is tinted on the form itself, so the
     official signing it can see at a glance which boxes are theirs to fill in. */
  .printsign__cell--filled { background: #f1f0ed; }

  .printdoc__foot {
    margin: 14pt 0 0;
    padding-top: 5pt;
    border-top: 0.4pt solid #999;
    font-family: var(--mono);
    font-size: 6.5pt;
    letter-spacing: 0.03em;
    color: #444;
    word-break: break-word;
  }

  /* The calendar on paper. A month grid is one of the things this team actually pins up, so it
     prints as a ruled grid rather than coming off as a screenshot of an app. */
  .calgrid { border-color: #000; background: #999; gap: 0.5pt; break-inside: avoid; }
  .calgrid__dow { background: #f1f0ed; color: #000; font-size: 7pt; }
  .calgrid__day, .calgrid__col { background: #fff; min-height: 52pt; }
  .calgrid__day.is-outside { background: #f7f6f3; }
  .calgrid__day.is-today, .calgrid__col.is-today { background: #f1f0ed; }
  .calgrid__num { background: none !important; color: #000 !important; font-size: 7.5pt; }
  .calchip { background: #fff; border-left-width: 2pt; font-size: 7pt; }
  .calchip__time { color: #333; font-size: 6.5pt; }

  /* An event title is a button because pressing it opens the entry. On paper it is the title, and
     the blanket .linkbtn rule above would otherwise leave a calendar of times with no events. */
  .ledger .linkbtn,
  .timeline .linkbtn,
  .calchip {
    display: inline !important;
    color: #000;
    text-decoration: none;
  }
  .calchip { display: flex !important; }

  /* A printed conversation is a record of what was asked and answered, so the exchange goes on
     paper in full -- the scrolling log has to be let out of its box, and the composer and the
     sidebar of past questions mean nothing on a page. */
  .chat { display: block; min-height: 0; }
  .chat__list, .chat__form, .chat__tools, .chat__seeds { display: none !important; }
  .turn__listen { display: none !important; }
  .chat__main { background: none; border: 0; padding: 0; }
  .chat__log { display: block; max-height: none; overflow: visible; }
  .turn { max-width: none; page-break-inside: avoid; margin-bottom: 0.2in; border-left: 1pt solid #000; }
  .srcchip { border-color: #666; color: #000; }

  /* ---------------------------------------------------------- blank forms ---- */

  /* The sheet stops being a card on a page and becomes the page. Everything here is a unit
     conversion of the screen rules above plus the page breaks -- what a seat saw is what comes
     out of the printer, which is the whole reason these are drawn on screen at all. */
  .formdoc {
    max-width: none;
    margin: 0;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    font-size: 9.5pt;
    line-height: 1.35;
  }
  /* The binder is four instruments in packet order, and each one is signed and filed separately.
     Two of them sharing a sheet would be two records that cannot be separated afterwards. */
  .formdoc + .formdoc,
  .formdoc ~ .binderbar + .formdoc { break-before: page; }

  .formdoc__rule { gap: 10pt; padding-bottom: 7pt; border-bottom-width: 1.5pt; }
  .formdoc__mark { width: 46pt; height: 46pt; }
  .formdoc__agency { font-size: 7pt; color: #333; }
  .formdoc__title { font-size: 16pt; }
  .formdoc__eyebrow { font-size: 7pt; }
  .formdoc__org { font-size: 8.5pt; color: #333; }

  .formdoc__control { width: 170pt; border: 0.75pt solid #000; }
  .formdoc__control dt { padding: 2.5pt 4pt; border-right: 0.4pt solid #bbb; font-size: 6.5pt; color: #333; }
  .formdoc__control dd { padding: 2.5pt 4pt; font-size: 7.5pt; }
  .formdoc__control dt:not(:first-of-type),
  .formdoc__control dt:not(:first-of-type) + dd { border-top: 0.4pt solid #bbb; }

  .formdoc__facts { margin-top: 8pt; border-color: #999; border-width: 0.5pt 0 0 0.5pt; }
  .formdoc__factcell { padding: 3pt 5pt 4pt; border-right: 0.5pt solid #999; border-bottom: 0.5pt solid #999; }
  .formdoc__factcell dt { font-size: 6.5pt; color: #444; }
  .formdoc__factcell dd { font-size: 8pt; }

  .formdoc__band {
    margin: 10pt 0 4pt;
    padding-bottom: 1.5pt;
    border-bottom: 0.75pt solid #000;
    font-size: 7.5pt;
  }
  .formdoc__band small { font-size: 7.5pt; color: #333; }

  .formdoc__grid { border-color: #999; border-width: 0.5pt 0 0 0.5pt; }
  .formdoc__cell { padding: 3pt 5pt 4pt; border-right: 0.5pt solid #999; border-bottom: 0.5pt solid #999; }
  .formdoc__cell.is-stated, .formdoc__signcell.is-stated { background: #f1f0ed; }
  .formdoc__label { font-size: 6.5pt; color: #333; }
  .formdoc__value { font-size: 8pt; }
  .formdoc__hint { font-size: 6.5pt; color: #444; }
  /* The line a pen goes on. Black and hairline-thin: a grey rule is what a photocopier drops. */
  .formdoc__write { height: 13pt; border-bottom: 0.5pt solid #000; }
  .formdoc__qty { width: 34pt; height: 13pt; border-bottom: 0.5pt solid #000; }
  .formdoc__money .formdoc__write { width: 62pt; }

  .formdoc__check { font-size: 8pt; }
  .formdoc__box { width: 8.5pt; height: 8.5pt; margin-top: 1pt; border: 0.6pt solid #000; background: #fff; }
  .formdoc__boxes { gap: 3pt 12pt; }

  .formdoc__claim { margin-bottom: 6pt; padding: 4pt 6pt 5pt; border: 0.5pt solid #666; border-left: 2pt solid #000; }
  .formdoc__ceiling { font-size: 7.5pt; }
  .formdoc__basis { font-size: 7.5pt; color: #333; }
  .formdoc__claimline { padding: 3pt 0; border-top: 0.4pt solid #bbb; }
  .formdoc__fixed, .formdoc__calc { font-size: 8pt; }
  .formdoc__evidence, .formdoc__because { font-size: 6.8pt; color: #444; }
  .formdoc__total { margin-top: 5pt; padding-top: 4pt; border-top: 1.5pt solid #000; }

  .formdoc__table th {
    padding: 2.5pt 4pt;
    border: 0.5pt solid #999;
    border-bottom: 0.75pt solid #000;
    font-size: 6.5pt;
    color: #333;
  }
  /* Room for adult handwriting. A twelve-line sign-in sheet whose rows are 12pt high comes back
     with names written over the rules, which is the same as coming back blank. */
  .formdoc__table td { height: 22pt; padding: 2pt 4pt; border: 0.5pt solid #999; }
  .formdoc__rownum { font-size: 7.5pt; color: #444; }

  .formdoc__line { height: 17pt; border-bottom: 0.5pt solid #999; }
  .formdoc__areas { padding: 4pt 5pt; gap: 3pt 12pt; border: 0.5pt solid #999; }

  .formdoc__controls li, .formdoc__packet li { padding: 3pt 0; border-bottom: 0.4pt solid #bbb; }
  .formdoc__controls li:first-child, .formdoc__packet li:first-child { border-top: 0.4pt solid #bbb; }
  .formdoc__packet li::before { font-size: 7.5pt; color: #444; }
  .formdoc__steps li { margin-bottom: 4pt; }
  .formdoc__steps strong { font-size: 8.5pt; }
  .formdoc__steps span { font-size: 8pt; color: #333; }

  .formdoc__cert { margin: 4pt 0 6pt; padding-left: 6pt; border-left: 2pt solid #000; font-size: 7.5pt; color: #000; }
  .formdoc__sign { margin-top: 2pt; border-color: #000; border-width: 0.75pt 0 0 0.75pt; }
  .formdoc__signcell { padding: 2.5pt 5pt 3pt; border-right: 0.75pt solid #000; border-bottom: 0.75pt solid #000; }
  .formdoc__signspace { height: 26pt; }

  /* ---- a filled sheet, printed ---- */

  /* What comes off the printer is the instrument with the answers on it: the same rules, the
     same boxes, in the same places, with typed text sitting on the line instead of blank space.
     So the controls print as their rules and nothing else -- no focus ring, no field chrome, no
     hint that this was typed rather than written. The only difference a reader should be able to
     find between a printed blank and a printed filled copy is the answers. */
  .formdoc__fillin { padding: 0; color: #000; background: transparent; border: 0; }
  input.formdoc__write { height: 13pt; border-bottom: 0.5pt solid #000; }
  input.formdoc__qty { width: 34pt; height: 13pt; border-bottom: 0.5pt solid #000; }
  .formdoc__money input.formdoc__write { width: 62pt; }
  .formdoc__cell-input { height: 18pt; font-size: 8pt; border: 0; }
  .formdoc__signfill { height: 26pt; border-bottom: 0.5pt solid #999; }
  .formdoc__area {
    margin-top: 2pt;
    padding: 2pt 3pt;
    font-size: 8pt;
    line-height: 13pt;
    color: #000;
    background: transparent;
    border: 0.5pt solid #999;
    border-radius: 0;
    resize: none;
    overflow: hidden;
  }
  input.formdoc__box { width: 8.5pt; height: 8.5pt; border: 0.6pt solid #000; background: #fff; }
  input.formdoc__box:checked::after { inset: 1.2pt; background: #000; }
  /* The on-screen cue that a sheet is being filled in is not part of the instrument. */
  .formdoc--filling { box-shadow: none; }
  .formprompt { display: none; }

  .formdoc__foot { margin-top: 12pt; padding-top: 5pt; border-top: 0.4pt solid #999; font-size: 6.5pt; color: #444; }

  /* A claim block, a signature grid or an identification grid split across two sheets is half an
     instrument on each. The sheet itself is deliberately not held together: the invoice runs past
     one page, and `break-inside: avoid` on something taller than the paper is ignored anyway. */
  .formdoc__claim,
  .formdoc__sign,
  .formdoc__grid,
  .formdoc__areas,
  .formdoc__table tr,
  .formdoc__head { break-inside: avoid; }

  /* Keep laser-printer greys from being dropped to pure white by a browser's colour saving. */
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* ---- Form helper ----------------------------------------------------------------------------
   The guided interview docked beside a reimbursement form being filled in (public/form-helper.js).
   Docked rather than stacked above the sheet, because the whole point is to watch the boxes fill
   in while answering: a chat that pushes the form off the screen hides the thing it is doing. It
   folds to a single button so it never covers a box the seat wants to type in themselves. */
.fhelper {
  position: fixed;
  right: clamp(0.75rem, 2vw, 1.5rem);
  bottom: calc(1.25rem + env(safe-area-inset-bottom));
  z-index: 25;
  display: flex;
  justify-content: flex-end;
  pointer-events: none;
}
.fhelper > * { pointer-events: auto; }
.fhelper__spark { display: inline-grid; place-items: center; flex: none; width: 2rem; height: 2rem; border-radius: 50%; background: var(--clay); color: var(--paper); }
.fhelper__spark svg { width: 1.05rem; height: 1.05rem; fill: currentColor; }

.fhelper__fab {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.95rem 0.55rem 0.55rem;
  border: 1px solid var(--clay-deep);
  border-radius: 999px;
  background: var(--ink);
  color: var(--paper);
  font: inherit;
  text-align: left;
  cursor: pointer;
  box-shadow: 0 12px 30px -14px rgba(28, 34, 48, 0.65);
  animation: fhelper-in 0.25s ease both;
}
.fhelper__fab:hover { background: var(--ink-2); }
.fhelper__fab:focus-visible { outline: 2px solid var(--clay); outline-offset: 2px; }
.fhelper__fab strong { display: block; font-size: 0.88rem; }
.fhelper__fab small { display: block; font-size: 0.72rem; color: rgba(244, 239, 230, 0.7); }

.fhelper__panel {
  display: flex;
  flex-direction: column;
  width: min(26rem, calc(100vw - 1.5rem));
  height: min(40rem, calc(100vh - var(--topbar-h) - 2.5rem));
  border: 1px solid var(--rule-strong);
  border-radius: 6px;
  background: var(--paper);
  box-shadow: 0 24px 50px -24px rgba(28, 34, 48, 0.6);
  overflow: hidden;
  animation: fhelper-in 0.2s ease both;
}
.fhelper__head { display: flex; align-items: center; gap: 0.55rem; padding: 0.6rem 0.7rem; background: var(--ink); color: var(--paper); }
.fhelper__title { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.fhelper__title strong { font-size: 0.9rem; }
.fhelper__title small { font-family: var(--mono); font-size: 0.66rem; color: rgba(244, 239, 230, 0.65); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fhelper__headactions { display: flex; align-items: center; gap: 0.3rem; }
.fhelper__headactions .btn--ghost { color: var(--paper); border-color: rgba(244, 239, 230, 0.35); }
.fhelper__headactions .btn--ghost:hover { background: rgba(244, 239, 230, 0.12); }
.fhelper__close { width: 1.8rem; height: 1.8rem; border: 0; border-radius: 3px; background: transparent; color: var(--paper); font-size: 1.2rem; line-height: 1; cursor: pointer; }
.fhelper__close:hover { background: rgba(244, 239, 230, 0.12); }

.fhelper__log { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 0.85rem; padding: 0.85rem 0.85rem 0.6rem; overscroll-behavior: contain; }
.fhelper__log .turn { max-width: none; }
.fhelper__log .turn__body { font-size: 0.86rem; }
.fhelper__intro { margin: 0; font-size: 0.84rem; line-height: 1.55; color: var(--ink-soft); }

.fhelper__fills { margin-top: 0.45rem; border: 1px solid var(--rule); border-radius: 3px; background: rgba(76, 106, 72, 0.08); font-size: 0.78rem; }
.fhelper__fills summary { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; padding: 0.3rem 0.5rem; cursor: pointer; color: var(--moss); font-weight: 600; }
.fhelper__fills.is-undone { background: var(--paper-2); }
.fhelper__fills.is-undone summary { color: var(--ink-faint); font-weight: 400; }
.fhelper__fills ul { list-style: none; margin: 0; padding: 0 0.5rem 0.4rem; display: flex; flex-direction: column; gap: 0.2rem; }
.fhelper__fills li { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0.5rem; border-top: 1px dashed var(--rule); padding-top: 0.2rem; }
.fhelper__fillname { padding: 0; border: 0; background: none; font: inherit; color: var(--ink-soft); text-align: left; text-decoration: underline dotted; cursor: pointer; }
.fhelper__fillname:hover { color: var(--clay-deep); }
.fhelper__fillvalue { color: var(--ink); overflow-wrap: anywhere; }
.fhelper__sources { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem; margin-top: 0.45rem; font-size: 0.68rem; color: var(--ink-faint); }

.fhelper__error { border: 1px solid var(--clay); border-radius: 3px; padding: 0.5rem 0.6rem; background: rgba(166, 81, 47, 0.08); font-size: 0.8rem; }
.fhelper__error p { margin: 0 0 0.4rem; color: var(--clay-deep); }

.fhelper__replies { display: flex; flex-wrap: wrap; gap: 0.35rem; padding: 0 0.85rem 0.55rem; }
.fhelper__reply {
  padding: 0.32rem 0.65rem;
  border: 1px solid var(--clay);
  border-radius: 999px;
  background: var(--paper);
  font: inherit;
  font-size: 0.78rem;
  color: var(--clay-deep);
  cursor: pointer;
}
.fhelper__reply:hover, .fhelper__reply:focus-visible { background: var(--clay); color: var(--paper); }

.fhelper__composer { display: flex; flex-direction: column; gap: 0.35rem; padding: 0.6rem 0.85rem 0.7rem; border-top: 1px solid var(--rule); background: var(--paper-2); }
.fhelper__input { width: 100%; resize: none; min-height: 2.8rem; max-height: 8rem; padding: 0.5rem 0.55rem; font: inherit; font-size: 0.88rem; }
.fhelper__composerfoot { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.fhelper__composerfoot small { font-size: 0.66rem; line-height: 1.35; color: var(--ink-faint); }

/* Voice: the helper reading its questions aloud and taking spoken answers. Listening is the one state
   that has to be unmistakable -- an open microphone the seat has forgotten about is the failure. */
.fhelper__log .turn--bot .turn__who { display: flex; align-items: center; gap: 0.35rem; }
.fhelper__listen { display: inline-grid; place-items: center; width: 1.35rem; height: 1.35rem; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--ink-faint); cursor: pointer; }
.fhelper__listen svg { width: 0.85rem; height: 0.85rem; fill: currentColor; }
.fhelper__listen:hover, .fhelper__listen:focus-visible { background: var(--paper-2); color: var(--clay-deep); }
.fhelper__voicebtn { display: inline-flex; align-items: center; gap: 0.3rem; }
.fhelper__voicebtn svg { width: 0.85rem; height: 0.85rem; fill: currentColor; vertical-align: middle; }
.fhelper__headactions .fhelper__voicebtn.is-on { background: var(--clay); border-color: var(--clay); color: var(--paper); }
.fhelper__headactions .fhelper__voicebtn.is-on:hover { background: var(--clay-deep); }
.fhelper__sendrow { display: flex; align-items: center; gap: 0.35rem; flex: none; }
.fhelper__mic { display: inline-grid; place-items: center; width: 2rem; height: 2rem; padding: 0; border: 1px solid var(--rule-strong); border-radius: 50%; background: var(--paper); color: var(--ink); cursor: pointer; }
.fhelper__mic svg { width: 1rem; height: 1rem; fill: currentColor; }
.fhelper__mic:hover:not(:disabled) { border-color: var(--clay); color: var(--clay-deep); }
.fhelper__mic:focus-visible { outline: 2px solid var(--clay); outline-offset: 2px; }
.fhelper__mic:disabled { opacity: 0.45; cursor: default; }
.fhelper__mic.is-listening { background: var(--clay); border-color: var(--clay-deep); color: var(--paper); animation: fhelper-pulse 1.3s ease-out infinite; }
.fhelper__voicebar { display: flex; align-items: center; gap: 0.45rem; margin: 0 0.85rem 0.55rem; padding: 0.35rem 0.5rem; border: 1px solid var(--rule); border-radius: 3px; background: var(--paper-2); font-size: 0.76rem; color: var(--ink-soft); }
.fhelper__voicebar.is-listening { border-color: var(--clay); background: rgba(166, 81, 47, 0.08); color: var(--clay-deep); }
.fhelper__voicetext { flex: 1; min-width: 0; }
.fhelper__voicedot { flex: none; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--moss); }
.fhelper__voicebar.is-listening .fhelper__voicedot { background: var(--clay); animation: fhelper-pulse 1.3s ease-out infinite; }
@keyframes fhelper-pulse { 0% { box-shadow: 0 0 0 0 rgba(166, 81, 47, 0.45); } 100% { box-shadow: 0 0 0 0.55rem rgba(166, 81, 47, 0); } }
@media (prefers-reduced-motion: reduce) { .fhelper__mic.is-listening, .fhelper__voicebar.is-listening .fhelper__voicedot { animation: none; } }

/* A box the helper wrote, until the seat edits it: tinted so every answer it gave can be checked. */
.formdoc--filling .is-helperfilled:not(.formdoc__check) { background: rgba(76, 106, 72, 0.14); box-shadow: inset 0 -2px 0 var(--moss); }
.formdoc--filling .formdoc__check.is-helperfilled { background: rgba(76, 106, 72, 0.14); border-radius: 2px; }

@keyframes fhelper-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .fhelper__fab, .fhelper__panel { animation: none; } }

@media (max-width: 52rem) {
  .fhelper { left: 0.5rem; right: 0.5rem; bottom: calc(var(--navbar-h) + 0.6rem + env(safe-area-inset-bottom)); }
  .fhelper__panel { width: 100%; height: min(34rem, calc(100vh - var(--topbar-h) - var(--navbar-h) - 1.5rem)); }
  .fhelper__headactions .btn { padding-inline: 0.45rem; }
}

@media print {
  .fhelper { display: none !important; }
  .formdoc--filling .is-helperfilled, .formdoc--filling .formdoc__check.is-helperfilled { background: none !important; box-shadow: none !important; }
}

/* ------------------------------------------------------- AI intake review ---- */

.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.mono { font-family: var(--mono); font-size: 0.82rem; }
.screen-grid { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 1.25rem; align-items: start; margin-bottom: 0.5rem; }
.screen-decision { border: 1px solid var(--rule-strong); border-left: 3px solid var(--clay); border-radius: 6px; padding: 0.9rem 1rem; background: rgba(255, 255, 255, 0.4); }
.screen-decision h3 { margin: 0 0 0.4rem; font: 650 1.05rem/1.2 var(--display); }
.screen-decision__buttons { flex-wrap: wrap; margin-top: 0.6rem; }
.screen-section { border-top: 1px solid var(--rule); padding: 0.4rem 0; }
.screen-section > summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: 0.5rem; padding: 0.4rem 0; }
.screen-section > summary::-webkit-details-marker { display: none; }
.screen-section > summary::before { content: "▸"; color: var(--clay); transition: transform 0.15s; }
.screen-section[open] > summary::before { transform: rotate(90deg); }
.screen-section > summary h3 { margin: 0; font: 650 1rem/1.2 var(--display); }
.screen-section > summary:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.screen-criteria { list-style: none; margin: 0.25rem 0; padding: 0; display: grid; gap: 0.5rem; }
.screen-criteria li { display: flex; gap: 0.6rem; align-items: flex-start; }
.screen-criteria__mark { flex: none; width: 1.4rem; height: 1.4rem; border-radius: 50%; display: grid; place-items: center; font-size: 0.8rem; font-weight: 700; color: #fff; background: var(--ink-faint); }
.screen-criteria .is-met .screen-criteria__mark { background: var(--moss); }
.screen-criteria .is-not_met .screen-criteria__mark { background: var(--clay); }
.screen-criteria small { color: var(--ink-soft); }
.screen-score { margin: 0.2rem 0 0.6rem; }
.screen-score strong { font: 700 1.5rem/1 var(--display); }
.screen-bar { display: inline-block; width: 4.5rem; height: 0.45rem; border-radius: 999px; vertical-align: middle; background: linear-gradient(90deg, var(--moss) var(--v), var(--paper-3) var(--v)); }
.screen-reasoning { margin: 0.75rem 0 0.25rem; color: var(--ink-2); }
.screen-flags { margin: 0.5rem 0; padding: 0.6rem 0.8rem 0.6rem 1.8rem; border-radius: 6px; background: rgba(157, 120, 24, 0.1); color: var(--ink-2); }
.screen-checks summary { cursor: pointer; font-size: 0.82rem; color: var(--ink-soft); margin-top: 0.3rem; }
.screen-checks ul { margin: 0.3rem 0; padding-left: 1.1rem; font-size: 0.82rem; }
.screen-checks .is-fail { color: var(--clay-deep); }
.screen-checks .is-pass { color: var(--moss); }
.screen-transcript { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; max-height: 28rem; overflow: auto; }
.screen-transcript li { max-width: 46rem; padding: 0.5rem 0.75rem; border-radius: 8px; background: var(--paper-2); }
.screen-transcript li.is-user { margin-left: auto; background: rgba(166, 81, 47, 0.1); }
.screen-transcript p { margin: 0.15rem 0; white-space: pre-wrap; }
.screen-transcript__who, .screen-transcript time { font: 500 0.72rem/1.2 var(--mono); color: var(--ink-soft); text-transform: uppercase; letter-spacing: 0.05em; }
.screen-json { font-family: var(--mono); font-size: 0.72rem; word-break: break-all; max-width: 32rem; }
@media (max-width: 52rem) {
  .screen-grid { grid-template-columns: 1fr; }
}
@media print {
  .screen-decision__buttons { display: none !important; }
  .screen-section { break-inside: avoid; }
}

/* ------------------------------------------------------ assistant panel ---- */

/* The program assistant over every screen (public/assistant-dock.js). A clay button in the
   bottom-right corner, and a paper panel above it that stays put while the stage behind it
   changes -- that persistence is what lets "take me to the ledger" open the ledger mid-conversation.
   Below the toast and the deploy notice, which are the portal's own voice and must stay readable;
   a modal sheet is in the top layer and outranks all three. */
.dock {
  position: fixed;
  right: calc(1.25rem + env(safe-area-inset-right));
  bottom: calc(1.25rem + env(safe-area-inset-bottom));
  z-index: 24;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.7rem;
  pointer-events: none;
}
.dock > * { pointer-events: auto; }

.dock__fab {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 3rem;
  padding: 0 1.1rem 0 0.95rem;
  border: 1px solid var(--clay-deep);
  border-radius: 999px;
  background: var(--clay);
  color: #fdf7ef;
  font: 600 0.88rem/1 var(--body);
  letter-spacing: 0.02em;
  cursor: pointer;
  box-shadow: 0 16px 34px -16px rgba(130, 61, 33, 0.85), 0 2px 0 rgba(28, 34, 48, 0.08);
  transition: transform 0.16s ease, background 0.16s ease;
}
.dock__fab:hover { background: var(--clay-deep); transform: translateY(-1px); }
.dock__fab:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.dock__fab svg { width: 1.15rem; height: 1.15rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.dock.is-open .dock__fab { background: var(--ink); border-color: var(--ink); box-shadow: 0 12px 26px -16px rgba(28, 34, 48, 0.8); }
/* A live conversation keeps a pulse on the button, so a closed-over panel is never listening unseen. */
.dock__fab.is-live::after {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: #fdf7ef;
  animation: chat-mic-pulse 1.1s ease-in-out infinite;
}

.dock__panel {
  width: min(25.5rem, calc(100vw - 2rem));
  height: min(40rem, calc(100vh - var(--topbar-h) - 6.5rem));
  height: min(40rem, calc(100dvh - var(--topbar-h) - 6.5rem));
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  border-top: 3px solid var(--clay);
  border-radius: 4px;
  box-shadow: 0 30px 60px -28px rgba(28, 34, 48, 0.55), 0 2px 0 rgba(28, 34, 48, 0.05);
  overflow: hidden;
  animation: rise 0.22s ease both;
}

.dock__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.7rem 0.6rem 0.65rem 0.95rem;
  border-bottom: 1px solid var(--rule);
  background: var(--paper-2);
}
.dock__title strong { display: block; font-family: var(--display); font-size: 1.02rem; font-weight: 600; }
.dock__where { margin: 0.1rem 0 0; font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); }
.dock__tools { display: flex; gap: 0.15rem; }
.dock__tool {
  display: grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  border: 0;
  border-radius: 3px;
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
}
.dock__tool:hover { background: var(--paper-3); color: var(--ink); }
.dock__tool svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.dock__log {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  padding: 0.95rem;
}
.dock__log .turn { max-width: none; }
.dock__log .turn__body { font-size: 0.86rem; }
.dock__log .turn__sources { gap: 0.3rem; }

.dock__empty { display: flex; flex-direction: column; gap: 0.6rem; }
.dock__hello { margin: 0; font-family: var(--display); font-size: 1.25rem; line-height: 1.2; }
.dock__lead { margin: 0; font-size: 0.83rem; line-height: 1.55; color: var(--ink-soft); }
.dock__seeds { display: flex; flex-direction: column; gap: 0.35rem; align-items: stretch; }
.dock__seed {
  text-align: left;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--rule-strong);
  border-radius: 3px;
  background: transparent;
  color: var(--ink-2);
  font: 0.83rem/1.35 var(--body);
  cursor: pointer;
}
.dock__seed:hover { border-color: var(--clay); background: var(--paper-2); color: var(--ink); }
.dock__tip { margin: 0.2rem 0 0; font-size: 0.75rem; color: var(--ink-faint); }
.dock__action {
  align-self: flex-start;
  margin: -0.4rem 0 0 0.7rem;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: rgba(76, 106, 72, 0.12);
  color: var(--moss);
  font: 500 0.7rem/1.4 var(--mono);
}
.dock__dots::after { content: "…"; animation: dock-dots 1.2s steps(4, end) infinite; display: inline-block; width: 1em; overflow: hidden; vertical-align: bottom; }
@keyframes dock-dots { from { width: 0; } to { width: 1em; } }

.dock__form { display: flex; flex-direction: column; gap: 0.45rem; padding: 0.7rem 0.8rem 0.8rem; border-top: 1px solid var(--rule); background: var(--paper); }
.dock__ask {
  width: 100%;
  min-height: 2.6rem;
  max-height: 140px;
  resize: none;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--rule-strong);
  border-radius: 3px;
  background: #fffdf9;
  color: var(--ink);
  font: 0.88rem/1.4 var(--body);
}
.dock__ask:focus { outline: none; border-color: var(--clay); }
.dock__formrow { display: flex; align-items: center; gap: 0.4rem; }
.dock__spacer { flex: 1; }
.dock__send { padding-inline: 1rem; }
.dock__mic {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid var(--rule-strong);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
}
.dock__mic:hover:not(:disabled) { border-color: var(--clay); }
.dock__mic:disabled { opacity: 0.45; cursor: not-allowed; }
.dock__micdot { width: 0.75rem; height: 0.75rem; border-radius: 50%; background: var(--clay); }
.dock__mic.is-live { background: var(--clay); border-color: var(--clay-deep); }
.dock__mic.is-live .dock__micdot { background: #fdf7ef; animation: chat-mic-pulse 1.1s ease-in-out infinite; }
.dock__talkbtn { display: inline-flex; align-items: center; gap: 0.45rem; }
.dock__talkwave { display: inline-flex; align-items: center; gap: 2px; height: 0.9rem; }
.dock__talkwave i { display: block; width: 3px; height: 40%; border-radius: 2px; background: currentColor; }
.dock__talkwave i:nth-child(2) { height: 100%; }
.dock__talkwave i:nth-child(3) { height: 65%; }

/* Talk mode: the log stays above so the conversation is still readable; the composer gives way to
   one large control, because a hands-free user needs one target, not five. */
.dock__talk {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  padding: 1rem 1rem 0.9rem;
  border-top: 1px solid var(--rule);
  background: linear-gradient(180deg, var(--paper-2), var(--paper));
}
.dock__orb {
  position: relative;
  width: 5.25rem;
  height: 5.25rem;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
}
.dock__orb:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }
.dock__orbcore, .dock__orbring { position: absolute; inset: 0; border-radius: 50%; }
.dock__orbcore {
  inset: 0.9rem;
  background: radial-gradient(circle at 35% 30%, #c86f48, var(--clay) 55%, var(--clay-deep));
  box-shadow: 0 10px 24px -10px rgba(130, 61, 33, 0.9);
  transition: transform 0.2s ease, background 0.2s ease;
}
.dock__orbring { border: 2px solid rgba(166, 81, 47, 0.35); }
.dock__orb[data-state="listening"] .dock__orbring { animation: dock-listen 1.4s ease-out infinite; }
.dock__orb[data-state="listening"] .dock__orbcore { transform: scale(1.06); }
.dock__orb[data-state="thinking"] .dock__orbring { border-color: transparent; border-top-color: var(--clay); animation: dock-spin 0.9s linear infinite; }
.dock__orb[data-state="thinking"] .dock__orbcore { transform: scale(0.88); }
.dock__orb[data-state="speaking"] .dock__orbcore { background: radial-gradient(circle at 35% 30%, #6d8a68, var(--moss) 60%, #33492f); animation: dock-speak 0.7s ease-in-out infinite alternate; }
.dock__orb[data-state="speaking"] .dock__orbring { border-color: rgba(76, 106, 72, 0.35); }
.dock__orb[data-state="paused"] .dock__orbcore { background: var(--ink-faint); box-shadow: none; }
@keyframes dock-listen { from { transform: scale(0.85); opacity: 1; } to { transform: scale(1.25); opacity: 0; } }
@keyframes dock-spin { to { transform: rotate(360deg); } }
@keyframes dock-speak { from { transform: scale(0.92); } to { transform: scale(1.04); } }
.dock__talkstate { margin: 0; font-family: var(--display); font-size: 1.05rem; }
.dock__heard { margin: 0; min-height: 1.2em; max-width: 100%; text-align: center; font-size: 0.82rem; font-style: italic; color: var(--ink-soft); }
.dock__endtalk { margin-top: 0.3rem; padding: 0.3rem 0.8rem; font-size: 0.78rem; }

/* Phones: the button rides above the bottom bar, and the panel becomes a sheet across the width. */
@media (max-width: 52rem) {
  .dock {
    right: calc(0.8rem + env(safe-area-inset-right));
    bottom: calc(var(--navbar-h) + 0.8rem + env(safe-area-inset-bottom));
  }
  .dock__fab { min-height: 2.9rem; padding: 0 0.95rem; }
  .dock__fablabel { display: none; }
  .dock__panel {
    position: fixed;
    left: 0.5rem;
    right: 0.5rem;
    bottom: calc(var(--navbar-h) + 4.3rem + env(safe-area-inset-bottom));
    width: auto;
    height: min(34rem, calc(100dvh - var(--navbar-h) - var(--topbar-h) - 5.5rem));
  }
  /* The nav sheet is the one thing on screen while it is up. */
  body.nav-open .dock { display: none; }
}

@media print {
  .dock { display: none !important; }
}
.turn__go { align-self: flex-start; margin: -0.3rem 0 0 0.7rem; }

/* Participant roster: per-row actions that expand and collapse behind one toggle. */
.rowmenu { display: inline-block; vertical-align: top; text-align: right; }
.rowmenu > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem; }
.rowmenu > summary::-webkit-details-marker { display: none; }
.rowmenu > summary::after { content: "▸"; transition: transform 0.15s; }
.rowmenu[open] > summary::after { transform: rotate(90deg); }
.rowmenu:not([open]) .rowmenu__label--open,
.rowmenu[open] .rowmenu__label--closed { display: none; }
.rowmenu__items { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.3rem; margin-top: 0.35rem; white-space: normal; }
@media print { .rowmenu { display: none !important; } }

/* ------------------------------------------------------------ app store ---- */

.apptoolbar { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; justify-content: space-between; margin-bottom: 1.25rem; }
.appfilters { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.appfilter {
  -webkit-appearance: none;
  appearance: none;
  font: inherit;
  font-size: 0.78rem;
  letter-spacing: 0.03em;
  min-height: 2.25rem;
  padding: 0.4rem 0.75rem;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
}
.appfilter:hover { border-color: var(--ink); color: var(--ink); }
.appfilter[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.appsearch {
  font: inherit;
  font-size: 0.88rem;
  min-height: 2.4rem;
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.7);
  color: var(--ink);
  width: min(100%, 16rem);
}
.appgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
.appcard {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  padding: 1rem;
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid var(--rule);
  border-top: 3px solid var(--clay);
  border-radius: 2px;
  box-shadow: var(--shadow);
}
.appcard[data-category="operations"] { border-top-color: var(--ink); }
.appcard[data-category="media"] { border-top-color: #6b3a6e; }
.appcard[data-category="learning"] { border-top-color: var(--moss); }
.appcard[data-category="reference"] { border-top-color: var(--gold); }
.appcard[data-category="games"] { border-top-color: #2f5a3a; }
.appcard__head { display: flex; gap: 0.85rem; align-items: center; }
.appicon {
  flex: 0 0 auto;
  width: 4rem;
  height: 4rem;
  border-radius: 22%;
  object-fit: cover;
  background: var(--paper-2);
  box-shadow: 0 0 0 1px var(--rule);
}
.appicon--mono {
  display: grid;
  place-items: center;
  background: var(--clay);
  color: #fdf7ef;
  font-family: var(--display);
  font-size: 1.35rem;
  font-weight: 600;
}
.appcard__title { min-width: 0; }
.appcard__title h3 { margin: 0; font-family: var(--display); font-size: 1.15rem; line-height: 1.15; }
.appcard__tagline { margin: 0.15rem 0 0; font-size: 0.83rem; color: var(--ink-soft); }
.appcard__host { margin: 0.2rem 0 0; font-family: var(--mono); font-size: 0.68rem; color: var(--ink-faint); overflow-wrap: anywhere; }
.appcard__tags { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.appcard__about { margin: 0; font-size: 0.86rem; line-height: 1.5; color: var(--ink); }
.appcard__why { padding: 0.6rem 0.7rem; background: rgba(166, 81, 47, 0.07); border-left: 2px solid var(--clay); }
.appcard__why b { display: block; font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--clay-deep); }
.appcard__why p { margin: 0.3rem 0 0; font-size: 0.84rem; line-height: 1.5; color: var(--ink-soft); }
.appcard__actions { display: flex; flex-wrap: wrap; gap: 0.45rem; margin-top: auto; }
.appcard__actions .btn { text-decoration: none; display: inline-flex; align-items: center; min-height: 2.5rem; }

/* ------------------------------------------------- passkeys & 2-step ---- */

/* The fingerprint/face buttons on the dark sign-in card. Outlined in foil rather than filled, so
   "Sign in" stays the obvious first action and the passkey reads as the faster alternative. */
.passkeybtn { display: inline-flex; align-items: center; gap: 0.55rem; justify-content: center; }
.passkeybtn svg { width: 1.15rem; height: 1.15rem; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.gate .btn--ghost.passkeybtn { border-color: rgba(231, 205, 130, 0.45); color: var(--foil, #e7cd82); background: transparent; }
.gate .btn--ghost.passkeybtn:hover { background: rgba(231, 205, 130, 0.1); }
#form-login .passkeybtn { margin-top: -0.25rem; }

.secsummary {
  display: flex; gap: 1rem; align-items: flex-start;
  padding: 1rem 1.15rem; border: 1px solid rgba(166, 81, 47, 0.35); border-left-width: 3px;
  background: rgba(166, 81, 47, 0.06);
}
.secsummary.is-on { border-color: rgba(76, 106, 72, 0.4); background: rgba(76, 106, 72, 0.08); }
.secsummary h2 { font-family: var(--display); font-size: 1.2rem; margin: 0 0 0.25rem; }
.secsummary p { margin: 0; color: var(--ink-soft); max-width: 62ch; }
.secsummary__icon svg { width: 2.2rem; height: 2.2rem; fill: none; stroke: var(--clay); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.secsummary.is-on .secsummary__icon svg { stroke: var(--moss); }

.seclist { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.secitem {
  display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap;
  padding: 0.65rem 0.8rem; border: 1px solid var(--rule); background: var(--paper);
}
.secitem strong { display: block; }
.secitem small { color: var(--ink-faint); }
.secadd { display: flex; gap: 0.75rem; align-items: flex-end; flex-wrap: wrap; }
.secadd .field { flex: 1 1 14rem; }
.secsteps { margin: 0; padding-left: 1.2rem; color: var(--ink-soft); display: grid; gap: 0.3rem; }

.sectotp { display: flex; gap: 1.25rem; flex-wrap: wrap; align-items: flex-start; }
.sectotp__qr { width: 11rem; height: 11rem; padding: 0.4rem; background: #fff; border: 1px solid var(--rule); }
.sectotp__qr svg { width: 100%; height: 100%; display: block; }
.sectotp__key { display: block; font-family: var(--mono); font-size: 0.95rem; letter-spacing: 0.06em; word-break: break-all; }

.codes { display: grid; gap: 1rem; }
.codes__grid {
  margin: 0; padding: 1rem 1rem 1rem 2.4rem; display: grid; grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
  gap: 0.5rem 1.5rem; border: 1px dashed var(--rule-strong); background: var(--paper);
}
.codes__grid code { font-family: var(--mono); font-size: 1rem; letter-spacing: 0.08em; }
.codes__actions { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; }

/* ------------------------------------------------ assistant drafts ---- */

.draftcard {
  margin-top: 0.75rem; padding: 0.8rem 0.9rem; border: 1px solid rgba(157, 120, 24, 0.45);
  border-left-width: 3px; background: rgba(157, 120, 24, 0.06); display: grid; gap: 0.55rem;
}
.draftcard.is-saved { border-color: rgba(76, 106, 72, 0.45); background: rgba(76, 106, 72, 0.06); }
.draftcard.is-discarded { opacity: 0.6; border-color: var(--rule); background: transparent; }
.draftcard__head { display: flex; justify-content: space-between; gap: 0.5rem; align-items: center; }
.draftcard__summary { margin: 0; color: var(--ink-soft); font-size: 0.9rem; }
.draftcard__form { display: grid; grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr)); gap: 0.5rem 0.75rem; }
.draftcard__row { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.85rem; }
.draftcard__row.is-wide { grid-column: 1 / -1; }
.draftcard__row > span { font-size: 0.68rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); }
.draftcard__row p { margin: 0; white-space: pre-wrap; }
.draftcard__actions { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
.draftcard__actions small { flex: 1 1 14rem; color: var(--ink-faint); }

/* ------------------------------------------------------- zoom video calls ---- */
.zoompage { display: grid; gap: 1.25rem; }
.zoomstart .sheet-card__body { display: grid; gap: 0.6rem; justify-items: start; }
.zoomgrid { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr)); align-items: start; }
.zoomform { display: grid; gap: 0.85rem; }
.zoomform input:not([type="checkbox"]), .zoomform select, .zoomform textarea { width: 100%; }
.zoomform__row { display: grid; gap: 0.85rem; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); }
.zoomform__opts { border: 1px solid var(--rule); border-radius: 0.5rem; padding: 0.6rem 0.85rem; display: grid; gap: 0.45rem; }
.zoomform__opts legend { font-size: 0.72rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-soft); padding: 0 0.3rem; }
.zoomcheck { display: flex; gap: 0.55rem; align-items: center; justify-content: flex-start; text-align: left; cursor: pointer; }
.zoomcheck > input[type="checkbox"] { flex: 0 0 auto; margin: 0; }
.zoomcheck > span { flex: 1 1 auto; }
.zoomhint { color: var(--ink-soft); font-size: 0.85rem; margin: 0; }
.zoomsteps { display: grid; gap: 0.8rem; padding-left: 1.2rem; line-height: 1.55; }
.zoomsteps code { font-family: var(--mono); font-size: 0.8rem; background: var(--paper-2); padding: 0.05rem 0.3rem; border-radius: 0.25rem; }
.zoomlist { display: grid; gap: 0.75rem; }
.zoommeeting { display: flex; flex-wrap: wrap; gap: 0.75rem 1rem; justify-content: space-between; align-items: center; border: 1px solid var(--rule); border-radius: 0.6rem; padding: 0.8rem 1rem; }
.zoommeeting h3 { margin: 0 0 0.2rem; font-size: 1rem; }
.zoommeeting p { margin: 0; }
.zoommeeting__actions { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.zoomcall { padding: 1rem; }
.zoomcall__head { display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: space-between; align-items: center; margin-bottom: 0.75rem; }
.zoomcall__title { margin: 0; font-size: 1.1rem; }
.zoomcall__status { margin: 0.2rem 0 0; color: var(--ink-soft); font-size: 0.85rem; }
/* The call box: the frame is sized by zoom.js (Fit, S/M/L, or a drag on its corner handle) and
   the SDK root fills it. Beside it on a wide screen, below it on a narrow one, the dock Zoom's
   chat and participant panels are anchored to. */
.zoomcall__controls { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; align-items: center; margin-bottom: 0.75rem; }
.zoomseg { display: inline-flex; align-items: center; gap: 0.25rem; }
.zoomseg__label { font-size: 0.72rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-soft); margin-right: 0.3rem; }
.zoomseg__btn { font: inherit; font-size: 0.82rem; padding: 0.25rem 0.6rem; border: 1px solid var(--rule); border-radius: 999px; background: transparent; color: inherit; cursor: pointer; }
.zoomseg__btn[aria-pressed="true"] { background: var(--ink, #111); border-color: var(--ink, #111); color: var(--paper, #fff); }
.zoomcall__stage { display: grid; gap: 1rem; align-items: start; }
.zoomcall__stage.is-docked { grid-template-columns: minmax(0, 1fr) var(--zoomchat-w, 340px); }
.zoomcall__frame { box-sizing: border-box; min-width: 320px; min-height: 220px; max-width: 100%; background: #111; border-radius: 0.6rem; overflow: auto; resize: both; position: relative; }
.zoomcall__root { width: 100%; height: 100%; position: relative; }
.zoomcall__chat { display: grid; gap: 0.5rem; align-content: start; min-width: 0; }
.zoomcall__chatanchor { height: 0; }
.zoomcall__chatdock { box-sizing: border-box; width: min(var(--zoomchat-w, 340px), 100%); height: var(--zoomchat-h, 480px); border: 1px dashed var(--rule); border-radius: 0.6rem; }
/* Zoom's own chat panel, which it portals outside the page section: held to the size picked under
   Chat size, never past the window, and resizable from its corner. */
[class*="zmwebsdk-makeStyles-chatCustomize"] {
  width: min(var(--zoomchat-w, 340px), calc(100vw - 1.5rem)) !important;
  height: min(var(--zoomchat-h, 480px), calc(100vh - 6rem)) !important;
  max-width: calc(100vw - 1.5rem); max-height: calc(100vh - 6rem);
  min-width: 240px; min-height: 260px;
  resize: both; overflow: auto; box-sizing: border-box;
}
@media (max-width: 40rem) { .zoomcall__frame { resize: vertical; } }
.zoomprompts { display: grid; gap: 0.9rem; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); }
.zoomprompt { border: 1px solid var(--rule); border-radius: 0.6rem; padding: 0.85rem 1rem; display: grid; gap: 0.5rem; align-content: start; }
.zoomprompt h3 { margin: 0; font-size: 0.95rem; }
.zoomprompt p { margin: 0; font-size: 0.88rem; color: var(--ink-2); line-height: 1.5; }
.zoomprompt .btn { justify-self: start; }
.zoomroom__list { display: grid; gap: 0.55rem; margin: 0; }
.zoomroom__row { display: grid; grid-template-columns: minmax(9rem, 13rem) 1fr; gap: 0.25rem 1rem; align-items: center; border-bottom: 1px solid var(--rule); padding-bottom: 0.5rem; }
.zoomroom__row:last-child { border-bottom: 0; padding-bottom: 0; }
.zoomroom__row dt { font-size: 0.72rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-soft); }
.zoomroom__row dd { margin: 0; display: flex; gap: 0.5rem; align-items: center; min-width: 0; }
.zoomroom__row dd > a, .zoomroom__row dd > span { overflow-wrap: anywhere; font-family: var(--mono); font-size: 0.88rem; }
@media (max-width: 34rem) { .zoomroom__row { grid-template-columns: 1fr; } }
.zoomform__peoplelist { display: grid; gap: 0.45rem; max-height: 14rem; overflow-y: auto; }
.zoomdocs { display: grid; gap: 0.35rem; margin-top: 0.5rem; }
.zoomdocs__label { font-size: 0.72rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-soft); }
.zoomdocs__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.3rem; }
.zoomdocs__item { display: flex; flex-wrap: wrap; gap: 0.2rem 0.6rem; align-items: center; }
.zoomdocs__item > a { overflow-wrap: anywhere; font-weight: 600; }
.zoomdocs .btn--tiny { justify-self: start; }
.zoomdocs__picker { display: grid; gap: 0.6rem; }
.zoomhandoff { border-color: var(--clay, var(--rule)); }
.zoomhandoff h2 { margin: 0; font-size: 1.1rem; }
.zoomroster__scroll { overflow-x: auto; }
.zoomroster__table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.zoomroster__table th { text-align: left; font-size: 0.72rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-soft); padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--rule); }
.zoomroster__table td { padding: 0.5rem 0.6rem; border-bottom: 1px solid var(--rule); vertical-align: middle; }
.zoomroster__table a { overflow-wrap: anywhere; }

/* ------------------------------------------------------------------ inbox ---- */
/* The seat's own mailbox: a list beside the open message, stacked on a phone where the open
   message takes the whole stage and "Back to the list" returns. */
.inboxpage { display: grid; gap: 1rem; }
.inbox__setup { display: grid; gap: 0.75rem; }
.inbox__steps { margin: 0; padding-left: 1.3rem; display: grid; gap: 0.45rem; font-size: 0.9rem; }
.inbox__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.inbox__tabs { max-width: 40rem; }
.inbox__search { display: flex; gap: 0.5rem; max-width: 40rem; }
.inbox__search input { flex: 1; min-width: 0; }
.inbox {
  display: grid;
  grid-template-columns: minmax(16rem, 24rem) 1fr;
  gap: 1rem;
  align-items: start;
}
.inbox__col { display: grid; gap: 0.5rem; }
.inbox__list {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  max-height: 72vh;
  overflow-y: auto;
}
.inbox__row {
  padding: 0.65rem 0.8rem;
  border-bottom: 1px solid var(--rule);
  cursor: pointer;
  display: grid;
  gap: 0.15rem;
}
.inbox__row:hover { background: var(--paper-2); }
.inbox__row:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
.inbox__row.is-open { background: var(--paper-3); box-shadow: inset 3px 0 0 var(--clay); }
.inbox__row.is-unread .inbox__from, .inbox__row.is-unread .inbox__subj { font-weight: 700; color: var(--ink); }
.inbox__line { display: flex; justify-content: space-between; gap: 0.5rem; }
.inbox__from, .inbox__subj, .inbox__snip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inbox__from { color: var(--ink-2); font-size: 0.9rem; }
.inbox__when { color: var(--ink-faint); font-size: 0.76rem; white-space: nowrap; font-family: var(--mono); }
.inbox__subj { font-size: 0.88rem; color: var(--ink-2); }
.inbox__snip { font-size: 0.8rem; color: var(--ink-soft); }
.inbox__more { display: flex; justify-content: center; }
.inbox__pane {
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  padding: 1rem 1.1rem;
  min-height: 20rem;
  display: grid;
  gap: 0.85rem;
  align-content: start;
  min-width: 0;
}
.inbox__hint, .inbox__loading { margin: 0; }
.inbox__readhead { display: grid; gap: 0.6rem; }
.inbox__back { display: none; justify-self: start; }
.inbox__subject { margin: 0; font-size: 1.25rem; overflow-wrap: anywhere; }
.inbox__meta { display: grid; grid-template-columns: auto 1fr; gap: 0.15rem 0.75rem; margin: 0; font-size: 0.85rem; }
.inbox__meta dt { color: var(--ink-faint); }
.inbox__meta dd { margin: 0; overflow-wrap: anywhere; }
.inbox__files { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.4rem 1rem; font-size: 0.86rem; }
.inbox__frame { width: 100%; height: 70vh; border: 1px solid var(--rule); background: #fff; }
.inbox__text { white-space: pre-wrap; overflow-wrap: anywhere; font-family: var(--body); font-size: 0.92rem; margin: 0; }
@media (max-width: 52rem) {
  .inbox { grid-template-columns: 1fr; }
  .inbox .inbox__pane { display: none; }
  .inbox.is-reading .inbox__col { display: none; }
  .inbox.is-reading .inbox__pane { display: grid; }
  .inbox__back { display: inline-flex; }
  .inbox__list { max-height: none; }
}

/* ---------------------------------------------------------- feedback ---- */
.fbpage { display: grid; gap: 1rem; }
.fbgrid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); align-items: start; }
.fbform { display: grid; gap: 0.9rem; }
.stars { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; }
.stars__row { display: inline-flex; gap: 0.15rem; }
.stars__btn {
  min-width: 44px; min-height: 44px; padding: 0; border: 0; background: none; cursor: pointer;
  font-size: 1.9rem; line-height: 1; color: var(--rule-strong); transition: color 0.12s, transform 0.12s;
}
.stars__btn.is-on { color: var(--gold); }
.stars__btn:hover { transform: scale(1.08); }
.stars__btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: 4px; }
.stars__caption { font-size: 0.88rem; color: var(--ink-soft); }
.stars__static { letter-spacing: 0.05em; color: var(--rule-strong); white-space: nowrap; }
.stars__static .is-on { color: var(--gold); }
.fbsum { display: grid; grid-template-columns: auto 1fr; gap: 1.25rem; align-items: center; }
.fbsum__avg { display: grid; justify-items: center; gap: 0.2rem; }
.fbsum__avg strong { font-family: var(--display, inherit); font-size: 2.6rem; line-height: 1; color: var(--ink); }
.fbsum__bars { display: grid; grid-template-columns: auto 1fr; gap: 0.3rem 0.6rem; margin: 0; font-size: 0.84rem; }
.fbsum__bars dt { color: var(--ink-soft); white-space: nowrap; }
.fbsum__bars dd { margin: 0; display: flex; align-items: center; gap: 0.4rem; }
.fbsum__bar { display: block; height: 0.55rem; min-width: 2px; border-radius: 99px; background: var(--gold); }
.fbsum__n { font-family: var(--mono); color: var(--ink-faint); font-size: 0.78rem; }
.fblist { display: grid; gap: 0.75rem; }
.fbitem { border-top: 1px solid var(--rule); padding-top: 0.7rem; display: grid; gap: 0.35rem; }
.fbitem:first-child { border-top: 0; padding-top: 0; }
.fbitem__head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem 0.75rem; font-size: 0.9rem; }
.fbitem__head .btn { margin-left: auto; }
.fbitem__comment { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.inbox__tray:empty { display: none; }
.inbox__tray { border: 1px solid var(--rule); border-radius: 6px; padding: 0.8rem; background: var(--paper-2); }
.inbox__compose { display: grid; gap: 0.6rem; }
.inbox__compose p { margin: 0; font-size: 0.85rem; overflow-wrap: anywhere; }
.inbox__compose textarea { width: 100%; min-height: 9rem; resize: vertical; }
.inbox__compose--new { gap: 0.7rem; }
.inbox__field { display: grid; grid-template-columns: 6.5rem 1fr; align-items: center; gap: 0.5rem; }
.inbox__field span { font-size: 0.85rem; font-weight: 600; }
.inbox__field input, .inbox__field select { width: 100%; min-width: 0; }
@media (max-width: 560px) { .inbox__field { grid-template-columns: 1fr; gap: 0.2rem; } }
.inbox__file { display: grid; gap: 0.9rem; }
.inbox__fileopt { display: grid; gap: 0.4rem; justify-items: start; }
.inbox__fileopt p { margin: 0; font-size: 0.82rem; }
.inbox__fileopt select, .inbox__fileopt input { max-width: 100%; }
.inbox__filerow { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.inbox__moved { display: grid; gap: 0.6rem; }
.inbox__moved p { margin: 0; }

/* Zoom page: each titled card folds down to its head. */
.zoomfold { margin-left: auto; }
.sheet-card.is-folded > .sheet-card__head { border-bottom: 0; }
.zoomform__opts legend { display: flex; align-items: center; gap: 0.6rem; }
.zoomfold--box { margin-left: 0; letter-spacing: normal; text-transform: none; }
.zoomform__opts .is-foldhidden { display: none !important; }
.zoomform__opts.is-folded { padding-bottom: 0.2rem; }
@media print { .zoomfold { display: none; } .zoomform__opts .is-foldhidden { display: revert !important; } }

/* ------------------------------------------------------ master controller -- */

/* The task desk. Built from the same pieces as every other screen -- tiles, tabs, the filter bar,
   the ledger table, sheet cards -- with only the layout and the overdue marking its own. */
/* The rule note: one line, with a "?" that lets it run to its full text. */
.mc__rule { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.85rem; padding-block: 0.2rem; font-size: 0.78rem; }
.mc__ruletext { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mc__rule.is-open .mc__ruletext { white-space: normal; overflow: visible; }
.mc__ruletoggle {
  flex: none; min-width: 44px; min-height: 44px; margin-block: -0.2rem; border: 0; background: none; cursor: pointer;
  font: inherit; font-weight: 700; font-size: 0.86rem; color: var(--clay-deep); border-radius: 2px;
}
.mc__ruletoggle:hover { background: rgba(166, 81, 47, 0.1); }
.mc__ruletoggle:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }

/* The stat cards are filter buttons: the same tiles, pressable, with the active one marked. */
.mc__stats { grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); gap: 0.6rem; margin-bottom: 1rem; }
.mc__stat {
  -webkit-appearance: none; appearance: none; font: inherit; color: inherit; text-align: left; cursor: pointer;
  display: flex; flex-direction: column; gap: 0.3rem; min-height: 44px; padding: 0.65rem 0.8rem 0.7rem;
  transition: background 0.15s ease, box-shadow 0.15s ease;
}
.mc__stat:hover { background: rgba(255, 255, 255, 0.85); }
.mc__stat:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.mc__stat.is-active { background: rgba(166, 81, 47, 0.1); box-shadow: inset 0 0 0 2px var(--clay); }
.mc__statlabel { font-size: 0.68rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-soft); }
.mc__statvalue { font-family: var(--display); font-size: 1.75rem; line-height: 1; font-variant-numeric: tabular-nums; }
.mc__tile--alert .mc__statvalue { color: var(--clay); }
.mc__filters .mc__reset { align-self: center; min-height: 44px; padding-inline: 0.25rem; font-size: 0.82rem; }
.mc__notfound { margin-bottom: 0.9rem; }
.mc__tabs { margin-bottom: 0.9rem; max-width: 30rem; }
.mc__filters { margin-bottom: 0.9rem; }
.mc__hide { align-self: center; min-width: 0; }
.mc__layout { display: grid; grid-template-columns: minmax(0, 1.65fr) minmax(18rem, 1fr); gap: 0.9rem; align-items: start; }
.mc__layout--board { grid-template-columns: minmax(0, 1fr); }
.mc__main { min-width: 0; }
/* Beside the list, the detail stays in view while the list scrolls, and scrolls on its own. */
.mc__detail {
  position: sticky; top: calc(var(--topbar-h) + 0.75rem);
  max-height: calc(100dvh - var(--topbar-h) - 1.5rem); overflow-y: auto; overscroll-behavior: contain;
}
.mc__layout--board .mc__detail { position: static; }
.mc__title { text-align: left; font-weight: 600; margin-right: 0.4rem; }
.mc__tag { margin-left: 0.15rem; font-size: 0.62rem; letter-spacing: 0.06em; }
.mc__due { display: inline-flex; flex-direction: column; gap: 0.1rem; }
.mc__due.is-overdue, .timeline__when.is-overdue { color: var(--clay); }
.mc__overdue { font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.1em; color: var(--clay); margin-left: 0.35rem; }
.mc__due .mc__overdue { margin-left: 0; }
.mc__tile--alert dd { color: var(--clay); }
.ledger tr.mc__row { cursor: pointer; }
.ledger tr.mc__row:hover { background: rgba(28, 34, 48, 0.04); }
.ledger tr.mc__row:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
.ledger tr.mc__row.is-selected { background: rgba(166, 81, 47, 0.07); }
.ledger tr.mc__row.is-selected td:first-child { box-shadow: inset 3px 0 0 var(--clay); }

.mc__board { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0.6rem; }
.mc__col { background: var(--paper-2); border: 1px solid var(--rule); border-radius: 2px; padding: 0.55rem; min-width: 0; }
.mc__colhead {
  display: flex; justify-content: space-between; gap: 0.4rem; margin: 0 0 0.5rem;
  font-family: var(--body); font-size: 0.7rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-soft);
}
.mc__cards { display: grid; gap: 0.45rem; }
.mc__card {
  display: grid; gap: 0.3rem; text-align: left; font: inherit; font-size: 0.82rem; color: var(--ink);
  background: rgba(255, 255, 255, 0.6); border: 1px solid var(--rule); border-radius: 2px; padding: 0.55rem 0.6rem; cursor: pointer;
}
.mc__card:hover { border-color: var(--rule-strong); }
.mc__card:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }
.mc__card.is-selected { box-shadow: inset 3px 0 0 var(--clay); }
.mc__card .mc__tag { justify-self: start; margin-left: 0; }
.mc__meta { display: flex; flex-wrap: wrap; align-items: baseline; font-family: var(--mono); font-size: 0.7rem; color: var(--ink-soft); }
.mc__meta .mc__due { flex-direction: row; gap: 0.35rem; }
.mc__none { font-size: 0.78rem; margin: 0; }

.mc__deadlines .timeline__what p { margin: 0 0 0.35rem; font-size: 0.86rem; }
.mc__deadlines .timeline__what p:last-child { margin-bottom: 0; }
.mc__ref strong { display: inline; margin-right: 0.4rem; }
.mc__deadline .pill { margin-right: 0.25rem; }

.mc__details { white-space: pre-wrap; font-size: 0.86rem; color: var(--ink-2); margin: 0.8rem 0 0; }
.mc__sub {
  margin: 1rem 0 0.45rem; font-family: var(--body); font-size: 0.68rem; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--ink-soft);
}
.mc__links, .mc__actions { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.mc__actions { margin-top: 1rem; padding-top: 0.8rem; border-top: 1px solid var(--rule); }
.mc__detail textarea { width: 100%; }
.mc__detail .field + .btn { margin-top: 0.45rem; }
.mc__dash { margin-top: 0.9rem; }

/* Previous / Next and the confirmation after a save, at the top of the detail. */
.mc__steps { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.4rem; margin-bottom: 0.8rem; }
.mc__step { min-height: 44px; padding-inline: 0.7rem; }
.mc__stepcount { font-family: var(--mono); font-size: 0.7rem; text-align: center; }
.mc__flash { margin-bottom: 0.8rem; }

/* Narrower than 68rem (and always on the board) the detail is a sheet that slides over from the
   right, with a Close bar; Esc closes it too. The selectors carry the layout class so they outrank
   the side-panel rules above and below. */
.mc .mc__layout--sheet { grid-template-columns: minmax(0, 1fr); }
.mc .mc__layout .mc__detail--sheet {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 31;
  width: min(34rem, 100vw); max-height: none; overflow-y: auto; overscroll-behavior: contain;
  padding: 0 0.75rem calc(1rem + env(safe-area-inset-bottom)); background: var(--paper);
  box-shadow: -12px 0 32px rgba(10, 11, 14, 0.22);
  animation: mc-sheet-in 0.2s ease both;
}
.mc .mc__layout .mc__detail--sheet[hidden] { display: none; }
.mc__sheetbar {
  position: sticky; top: 0; z-index: 1; display: flex; justify-content: flex-end;
  padding: 0.5rem 0; margin-bottom: 0.25rem; background: var(--paper); border-bottom: 1px solid var(--rule);
}
.mc__close { min-height: 44px; min-width: 44px; }
.mc__scrim { position: fixed; inset: 0; z-index: 30; background: rgba(10, 11, 14, 0.45); }
@keyframes mc-sheet-in { from { transform: translateX(100%); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) { .mc .mc__layout .mc__detail--sheet { animation: none; } }

/* The badge on the Master Controller nav item: what is waiting on this seat. */
.rail__link .mc__navbadge, .navbtn .mc__navbadge {
  display: inline-block; min-width: 1.35rem; padding: 0.08rem 0.35rem; border-radius: 999px;
  background: var(--clay); color: #fff; font-family: var(--mono); font-size: 0.66rem; font-weight: 600;
  line-height: 1.35; text-align: center; font-variant-numeric: tabular-nums;
}
.rail__link .mc__navbadge { margin-left: auto; }
.rail__link { position: relative; }
.navbtn { position: relative; }
.navbtn .mc__navbadge { position: absolute; top: 0.15rem; left: calc(50% + 0.35rem); }
@media (min-width: 52.01rem) {
  .shell.is-mini .rail__link .mc__navbadge { position: absolute; top: 0.15rem; right: 0.1rem; margin: 0; min-width: 1.1rem; padding: 0 0.25rem; }
}

@media (max-width: 60rem) {
  .mc__layout { grid-template-columns: minmax(0, 1fr); }
  .mc__detail { position: static; max-height: none; overflow: visible; }
  .mc__board { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 34rem) {
  .mc__board { grid-template-columns: minmax(0, 1fr); }
  .mc__tabs { max-width: none; }
  .mc__filters .field { flex: 1 1 100%; }
  .mc__stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mc__statvalue { font-size: 1.45rem; }
  /* On a phone each task row stacks into a small card, so the list never scrolls sideways. */
  .mc__main .ledger thead { display: none; }
  .mc__main .ledger tr.mc__row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.2rem 0.6rem; padding: 0.6rem 0.5rem; border-bottom: 1px solid var(--rule); }
  .mc__main .ledger tr.mc__row td { display: block; padding: 0; border: 0; min-width: 0; overflow-wrap: anywhere; }
  .mc__main .ledger tr.mc__row td:nth-child(2) { grid-column: 1 / -1; grid-row: 1; }
  .mc__main .ledger tr.mc__row td:nth-child(3), .mc__main .ledger tr.mc__row td:nth-child(4) { grid-column: 1 / -1; font-size: 0.78rem; color: var(--ink-soft); }
  .mc__main .ledger tr.mc__row td.num { text-align: left; }
  .mc__steps .mc__step { padding-inline: 0.5rem; font-size: 0.78rem; }
}
@media print {
  .mc__detail, .mc__filters, .mc__tabs, .mc__scrim, .mc__ruletoggle, .mc__reset { display: none; }
  .mc__ruletext { white-space: normal; }
  .mc__layout { display: block; }
}

/* Master Controller: the Program apps card, at the foot of the screen as one compact row of chips. */
.mc__appscard { margin-top: 1.25rem; }
.mc__apps { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 0; }
.mc .mc__apps .mc__app {
  display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 0.45rem;
  padding: 0.3rem 0.35rem 0.3rem 0.7rem; border-top-width: 1px; border-top-color: var(--rule); animation: none; min-width: 0;
}
.mc__appname { font-family: var(--display); font-size: 0.98rem; line-height: 1.15; }
.mc__app .btn { min-height: 44px; padding: 0.5rem 0.75rem; }
.mc__app .mc__chip { align-self: center; }
@media print { .mc__apps .btn { display: none; } }

/* Master Controller: the WWW Accounting connection -- status chips and the read-only look-up. */
.mc__chip { align-self: flex-start; }
.mc__hint { font-size: 0.78rem; margin: 0.7rem 0 0; }
.mc__acct { margin-top: 1rem; }
.mc__acctbar { margin-bottom: 0.5rem; }
.mc__acctbar .check { align-self: center; min-width: 0; }
.mc__args { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 0.45rem; margin-bottom: 0.5rem; }
.mc__args:empty { display: none; }
.mc__result { margin-top: 0.6rem; max-height: 22rem; overflow: auto; }
.mc__result .detail dd { word-break: break-word; }
