/* The chrome: every page's frame. Values come from tokens.css by name; no
   colour, size or font is written here (spec U23). The values are C · Marker's, from
   part H (theme.toml). Phone first: one column, tap targets
   at least --ub-shape-tap high, body text large enough that iOS does not zoom
   a focused field (spec U20). */

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--ub-ground);
  color: var(--ub-text);
  font-family: var(--ub-type-body);
  font-size: var(--ub-type-size);
  line-height: var(--ub-type-line);
  overflow-wrap: anywhere;
}

main {
  max-width: var(--ub-shape-measure);
  margin: 0 auto;
  padding: var(--ub-shape-space);
}

h1 {
  font-family: var(--ub-type-display);
  font-weight: var(--ub-type-display-weight);
  letter-spacing: var(--ub-type-display-tracking);
  font-size: var(--ub-type-size-large);
  line-height: 1.2;
  margin: var(--ub-shape-space) 0;
  color: var(--ub-primary);
}

h2, h3, h4 { font-family: var(--ub-type-display); }

p { margin: 0 0 var(--ub-shape-space); }

a { color: var(--ub-primary); }

label {
  display: block;
  font-weight: 600;
  margin-bottom: calc(var(--ub-shape-space) / 4);
}

input[type="email"], input[type="text"], input:not([type]) {
  display: block;
  width: 100%;
  min-height: var(--ub-shape-tap);
  padding: 0 calc(var(--ub-shape-space) * 0.75);
  margin-bottom: var(--ub-shape-space);
  font: inherit;
  color: var(--ub-text);
  background: var(--ub-surface);
  border: 1px solid var(--ub-border);
  border-radius: var(--ub-shape-radius-md);
}

button, .ub-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--ub-shape-tap);
  padding: 0 calc(var(--ub-shape-space) * 1.25);
  font: inherit;
  font-weight: 600;
  color: var(--ub-on-primary);
  background: var(--ub-primary);
  border: 0;
  border-radius: var(--ub-shape-radius-md);
  text-decoration: none;
  cursor: pointer;
}

main form button { width: 100%; }

a:focus-visible, button:focus-visible, input:focus-visible {
  outline: 3px solid var(--ub-focus);
  outline-offset: 2px;
}

/* ADDIE's mark (ADDIE-SPEC AE1, ARU5): AOD's chat mark, drawn inline (templates/addie_mark.html), in AOD's indigo
   with the amber tip. The stroke widths are the drawing's own units. */
.ub-addie-mark .ub-mark-body, .ub-addie-mark .ub-mark-eye { fill: var(--ub-mark-ink); }

.ub-addie-mark .ub-mark-shade { fill: var(--ub-mark-shade); }

.ub-addie-mark .ub-mark-face, .ub-addie-mark .ub-mark-glint { fill: var(--ub-surface); }

.ub-addie-mark .ub-mark-halo { fill: none; stroke: var(--ub-surface); stroke-width: 17; stroke-linecap: round; }

.ub-addie-mark .ub-mark-stem { fill: none; stroke: var(--ub-mark-ink); stroke-width: 10; stroke-linecap: round; }

.ub-addie-mark .ub-mark-tip { fill: var(--ub-mark-tip); }

.ub-addie-mark .ub-mark-smile { fill: none; stroke: var(--ub-mark-ink); stroke-width: 7; stroke-linecap: round; }

.ub-menu-list a.ub-tap { justify-content: flex-start; font-weight: 600; }

/* ADDIE's button (ADDIE-SPEC AE1): the AOD chat mark, white, ringed in the mark's ink. Open (aria-current) is
   the soft tint and a heavier ring, so the mark itself never changes. On a desktop it sits in the sidebar and
   names its chord (AE8); on a phone it floats at the bottom right, 48 px, and the sidebar's is hidden. */
.ub-addie-open {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--ub-shape-space) / 2);
  min-width: var(--ub-shape-tap);
  min-height: var(--ub-shape-tap);
  color: var(--ub-mark-ink);
  background: var(--ub-surface);
  border: 1.5px solid var(--ub-mark-ink);
  border-radius: var(--ub-shape-radius-full);
  text-decoration: none;
}

.ub-addie-open[aria-current="true"] { background: var(--ub-mark-soft); border-width: 2.5px; }

.ub-addie-open .ub-addie-mark { display: block; width: calc(var(--ub-shape-space) * 1.625); height: calc(var(--ub-shape-space) * 1.625); }

.ub-addie-open.ub-is-labeled {
  padding: 0 calc(var(--ub-shape-space) * 0.875) 0 calc(var(--ub-shape-space) * 0.625);
  font-size: var(--ub-type-size-small);
  font-weight: 600;
}

.ub-addie-open.ub-is-floating {
  position: fixed;
  right: calc(var(--ub-shape-space) / 2);
  bottom: calc(var(--ub-shape-space) / 2);
  z-index: 2;
  width: var(--ub-shape-tap);
  height: var(--ub-shape-tap);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--ub-text) 18%, transparent);
}

.ub-addie-open.ub-is-floating .ub-addie-mark { width: calc(var(--ub-shape-space) * 1.875); height: calc(var(--ub-shape-space) * 1.875); }

.ub-has-floating main { padding-bottom: calc(var(--ub-shape-space) * 4.5); }

/* A control the browser scrolls into view (a focus, a fragment such as #latest) stops above the button, not under it.
   Mid-scroll overlap is accepted (the lead, 2026-10-08). */
html:has(body.ub-has-floating) { scroll-padding-bottom: calc(var(--ub-shape-space) * 4.5); }

@media (min-width: 900px) {
  .ub-addie-open.ub-is-floating { display: none; }
  .ub-has-floating main { padding-bottom: var(--ub-shape-space); }
  html:has(body.ub-has-floating) { scroll-padding-bottom: 0; }
}

@media (max-width: 899px) {
  .ub-side .ub-addie-open { display: none; }
}

/* The cards on "Needs you", as the approved approval-card canvas draws them (ADDIE-SPEC §16.4). */
.ub-approval-list { list-style: none; margin: 0 0 var(--ub-shape-space); padding: 0; display: flex; flex-direction: column; gap: var(--ub-shape-space); }

.ub-approval {
  padding: calc(var(--ub-shape-space) / 2) calc(var(--ub-shape-space) * 0.75) var(--ub-shape-space);
  background: var(--ub-surface);
  border: 1px solid var(--ub-line);
  border-radius: var(--ub-shape-radius-lg);
}

.ub-approval p { margin: 0 0 calc(var(--ub-shape-space) / 2); }

.ub-approval > :last-child { margin-bottom: 0; }

/* A card's tick, then its summary, a link that selects it for ADDIE (ADDIE-SPEC AE5, AO9). */
.ub-approval-head { display: flex; align-items: flex-start; gap: calc(var(--ub-shape-space) / 4); }

.ub-approval-tick { flex: none; display: inline-flex; align-items: center; justify-content: center; min-width: var(--ub-shape-tap); min-height: var(--ub-shape-tap); margin: 0; }

.ub-approval-summary {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  min-height: var(--ub-shape-tap);
  color: var(--ub-text);
  text-decoration: underline;
  text-decoration-color: var(--ub-border);
  text-underline-offset: 0.2em;
}

.ub-approval.ub-is-selected { border: 2px solid var(--ub-primary); background: var(--ub-primary-soft); }

.ub-approval-subject-line { font-size: var(--ub-type-size-small); font-weight: 600; color: var(--ub-primary); }

/* The decision's two buttons: Approve filled, "Don't do this" outlined (`ub-button ub-is-secondary`), half a space apart. */
.ub-approval-decide { display: flex; flex-direction: column; gap: calc(var(--ub-shape-space) / 2); margin-bottom: var(--ub-shape-space); }

/* The reason field above the decision's buttons (the base look: the label, the field, then the buttons stacked). */
.ub-reason { margin-bottom: calc(var(--ub-shape-space) * 1.25); }
.ub-reason > label { margin-bottom: 0; }

/* Needs you as a desk (owner-desk design page 4, the operator's approval of 2026-10-13: "build it as drawn", menu open and collapsed).
   `ub-needs-cols` is on the page only with no card selected; with one, the list-and-panel arrangement of addie.css keeps the page
   and none of this is drawn. Each group is a box with a head band, then rows. The grid follows main's width (main is the `desk`
   container, `main.ub-dash`): below a desk, one column; a desk with the menu open, the decision box over Expired beside Needs
   attention; main from 76rem on (the menu collapsed), the three side by side. */
.ub-needs-cols { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--ub-shape-space); align-items: start; margin-bottom: var(--ub-shape-space); }
.ub-needs-a { display: flex; flex-direction: column; gap: var(--ub-shape-space); min-width: 0; }
.ub-needs-cols .ub-approval-group { min-width: 0; overflow: hidden; background: var(--ub-surface); border: 1px solid var(--ub-line); border-radius: var(--ub-shape-radius-lg); }
.ub-needs-cols .ub-needs-head { padding: calc(var(--ub-shape-space) * 0.75) var(--ub-shape-space); border-bottom: 1px solid var(--ub-line); }
.ub-needs-cols .ub-needs-head h2 { margin: 0; font-family: var(--ub-type-body); font-size: var(--ub-type-size); font-weight: 600; line-height: 1.375; color: var(--ub-text); }
.ub-needs-cols .ub-addie-grid { display: block; }
.ub-needs-cols .ub-approval-list { margin: 0; gap: 0; }
.ub-needs-cols .ub-approval { padding: calc(var(--ub-shape-space) * 0.875) var(--ub-shape-space); background: none; border: 0; border-radius: 0; }
.ub-needs-cols .ub-approval + .ub-approval { border-top: 1px solid var(--ub-line); }
.ub-needs-cols .ub-approval p { font-size: var(--ub-type-size-label); line-height: 1.43; color: var(--ub-text-2); }
.ub-needs-cols .ub-approval-empty, .ub-needs-cols .ub-attention-empty { margin: 0; padding: calc(var(--ub-shape-space) * 0.75) var(--ub-shape-space); font-size: var(--ub-type-size-label); line-height: 1.43; color: var(--ub-text-2); }
/* The waiting decision: the summary, then its facts as ruled rows, then the reason and the buttons on one wrapping row. */
/* The row's tap targets are the full tap size and overlap the card's padding, so the row is no taller than drawn. */
.ub-needs-cols .ub-needs-waiting .ub-approval-head { align-items: center; gap: calc(var(--ub-shape-space) / 4); margin: calc(var(--ub-shape-space) * -0.875) 0 calc(var(--ub-shape-space) / -4); }
/* The tick's target is the tap size; the box inside it is drawn at the card's left edge. */
.ub-needs-cols .ub-needs-waiting .ub-approval-tick { margin-left: calc(var(--ub-shape-space) * -0.75); }
.ub-needs-cols .ub-needs-waiting .ub-approval-tick input { width: calc(var(--ub-shape-space) * 1.25); height: calc(var(--ub-shape-space) * 1.25); margin: 0; accent-color: var(--ub-primary); }
.ub-needs-cols .ub-needs-waiting .ub-approval-summary { color: var(--ub-primary); font-size: var(--ub-type-size-small); line-height: 1.4; }
.ub-needs-cols .ub-needs-waiting .ub-approval p { margin: 0; padding: calc(var(--ub-shape-space) * 0.4375) 0; border-bottom: 1px solid var(--ub-line); }
.ub-needs-cols .ub-needs-waiting .ub-approval > :last-child { border-bottom: 0; }
.ub-needs-cols .ub-needs-waiting .ub-reason { margin: 0; padding: 0 var(--ub-shape-space) calc(var(--ub-shape-space) * 0.875); }
.ub-needs-cols .ub-needs-waiting .ub-reason > label { margin-bottom: calc(var(--ub-shape-space) / 4); font-size: var(--ub-type-size-label); line-height: 1.43; }
.ub-needs-cols .ub-needs-waiting .ub-reason-row { display: flex; flex-wrap: wrap; gap: calc(var(--ub-shape-space) / 2); }
.ub-needs-cols .ub-needs-waiting .ub-reason-row input[type="text"] { flex: 1 1 13rem; width: auto; min-width: 0; margin: 0; }
.ub-needs-cols .ub-needs-waiting .ub-approval-decide { flex: 0 0 auto; flex-direction: row; margin: 0; }
.ub-needs-cols .ub-needs-waiting .ub-approval-decide button { width: auto; }
/* Note 29 (the shakedown of 2026-10-27): each card carries its own reason and pair, inside the card; the pair under the list acts on the
   ticked cards and counts them with a CSS counter of the ticked boxes (no page script). */
.ub-approval-own { margin: calc(var(--ub-shape-space) / 2) 0 0; }
.ub-needs-cols .ub-needs-waiting .ub-approval .ub-approval-own { padding: calc(var(--ub-shape-space) / 2) 0 0; }
.ub-addie-grid-form { counter-reset: chosen; }
.ub-addie-grid-form > .ub-approval-default { display: none; }  /* the form's disabled default button: never drawn (a form button is display: block) */
.ub-approval-tick input:checked { counter-increment: chosen; }
.ub-chosen-count::before { content: counter(chosen); }
.ub-approval-chosen-head { margin: 0 0 calc(var(--ub-shape-space) / 4); font-size: var(--ub-type-size-label); font-weight: 600; color: var(--ub-text); }
.ub-needs-cols .ub-needs-waiting .ub-approval-chosen { padding-top: calc(var(--ub-shape-space) * 0.75); border-top: 1px solid var(--ub-line); }
/* Needs attention: each item a block with its time under it and its buttons in a wrapping row. */
.ub-needs-cols .ub-needs-attention .ub-attention-list { list-style: none; margin: 0; padding: 0; }
.ub-needs-cols .ub-needs-attention .ub-attention { padding: calc(var(--ub-shape-space) * 0.625) var(--ub-shape-space); border-bottom: 1px solid var(--ub-line); font-size: var(--ub-type-size-label); line-height: 1.43; }
.ub-needs-cols .ub-needs-attention .ub-attention:last-child { border-bottom: 0; }
.ub-needs-cols .ub-needs-attention .ub-attention p { margin: calc(var(--ub-shape-space) / 8) 0 0; }
.ub-needs-cols .ub-needs-attention .ub-attention-when { font-size: var(--ub-type-size-caption); line-height: 1.4; color: var(--ub-muted); }
.ub-needs-cols .ub-needs-attention .ub-attention-resolve { display: flex; flex-wrap: wrap; gap: calc(var(--ub-shape-space) / 2); margin: calc(var(--ub-shape-space) * 0.375) 0 0; }
.ub-needs-cols .ub-needs-attention .ub-attention-resolve button { width: auto; }
.ub-needs-cols .ub-needs-attention .ub-attention-note { margin: 0; padding: calc(var(--ub-shape-space) * 0.625) var(--ub-shape-space); border-top: 1px solid var(--ub-line); background: var(--ub-surface-sunk); font-size: var(--ub-type-size-caption); line-height: 1.45; color: var(--ub-text-2); }
/* Expired: the title and the sentence, then Ask again and Dismiss side by side. */
.ub-needs-cols .ub-needs-expired .ub-approval { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--ub-shape-space) * 0.375) calc(var(--ub-shape-space) / 2); }
.ub-needs-cols .ub-needs-expired .ub-approval > strong, .ub-needs-cols .ub-needs-expired .ub-approval > p { flex: 1 1 100%; margin: 0; }
.ub-needs-cols .ub-needs-expired .ub-approval > form { flex: 0 0 auto; margin: calc(var(--ub-shape-space) / 4) 0 0; }
.ub-needs-cols .ub-needs-expired .ub-approval > form button { width: auto; }
.ub-needs-cols .ub-needs-expired .ub-approval > strong { font-size: var(--ub-type-size-label); line-height: 1.43; }
main:has(> .ub-needs-cols) > h1 { margin-top: 0; }
main:has(> .ub-needs-cols) > .ub-approval-zone { font-size: var(--ub-type-size-caption); line-height: 1.4; color: var(--ub-muted); }
@media screen and (min-width: 900px) {
  .ub-needs-cols { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); grid-template-areas: "a b" "c b"; grid-template-rows: auto 1fr; }
  .ub-needs-cols button { padding: 0 var(--ub-shape-space); font-size: var(--ub-type-size-small); }
  .ub-needs-a { grid-area: a; }
  .ub-needs-cols .ub-needs-attention { grid-area: b; }
  .ub-needs-cols .ub-needs-expired { grid-area: c; }
}
@container desk (min-width: 76rem) {
  .ub-needs-cols { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 1fr); grid-template-areas: "a b c"; grid-template-rows: auto; }
}
@media (max-width: 899px) {
  .ub-needs-cols .ub-approval p, .ub-needs-cols .ub-needs-attention .ub-attention, .ub-needs-cols .ub-approval-empty, .ub-needs-cols .ub-attention-empty { font-size: var(--ub-type-size); line-height: 1.5; }
  .ub-needs-cols .ub-needs-attention .ub-attention-when, .ub-needs-cols .ub-needs-attention .ub-attention-note { font-size: var(--ub-type-size-label); line-height: 1.45; }
  .ub-needs-cols .ub-needs-waiting .ub-approval-summary, .ub-needs-cols .ub-needs-expired .ub-approval > strong { font-size: var(--ub-type-size); }
  .ub-needs-cols .ub-needs-waiting .ub-reason > label { font-size: var(--ub-type-size-label); }
  .ub-needs-cols .ub-needs-waiting .ub-reason-row input[type="text"] { flex-basis: 100%; }
  .ub-needs-cols .ub-needs-waiting .ub-approval-decide { flex: 1 1 100%; }
  .ub-needs-cols .ub-needs-waiting .ub-approval-decide button { flex: 1 1 0; }
  .ub-needs-cols .ub-needs-attention .ub-attention-resolve button { flex: 1 1 100%; }
  .ub-needs-cols .ub-needs-expired .ub-approval > form { flex: 1 1 0; }
  .ub-needs-cols .ub-needs-expired .ub-approval > form button { width: 100%; }
}

/* AE10: the Keyboard shortcuts page. On a phone each row is a block. */
.ub-keys { width: 100%; border-collapse: collapse; margin: 0 0 var(--ub-shape-space); background: var(--ub-surface); border: 1px solid var(--ub-line); }

.ub-keys th, .ub-keys td {
  padding: calc(var(--ub-shape-space) / 2) calc(var(--ub-shape-space) * 0.75);
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--ub-line);
}

.ub-keys th {
  font-family: var(--ub-type-display);
  font-size: var(--ub-type-size-eyebrow);
  font-weight: 650;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ub-muted);
  background: var(--ub-surface-sunk);
}

.ub-keys kbd {
  display: inline-block;
  min-width: calc(var(--ub-shape-space) * 1.75);
  padding: 0 calc(var(--ub-shape-space) * 0.375);
  font: inherit;
  font-weight: 700;
  text-align: center;
  background: var(--ub-surface-sunk);
  border: 1px solid var(--ub-border);
  border-radius: var(--ub-shape-radius-sm);
}

.ub-keys td:last-child { font-size: var(--ub-type-size-small); color: var(--ub-text-2); }

@media (max-width: 899px) {
  .ub-keys thead { display: none; }
  .ub-keys tr { display: block; padding: calc(var(--ub-shape-space) / 2) 0; border-bottom: 1px solid var(--ub-line); }
  .ub-keys td { display: block; border: 0; padding: calc(var(--ub-shape-space) / 8) calc(var(--ub-shape-space) * 0.75); }
}

main form { margin-bottom: var(--ub-shape-space); }

.ub-test-band {
  margin: 0;
  padding: calc(var(--ub-shape-space) / 4) var(--ub-shape-space);
  color: var(--ub-on-status);
  background: var(--ub-test-band);
  font-size: var(--ub-type-size-small);
  font-weight: 600;
  text-align: center;
}

/* AOD-ADMIN-SPEC AD4: the plain line on every page while an administration session is live in this browser, and AD1's link
   at the foot of the person menu. Kernel chrome, beside the test band. */
.ub-aod-bar { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--ub-shape-space) / 2); margin: var(--ub-shape-space) 0 0;
  padding: calc(var(--ub-shape-space) / 4) calc(var(--ub-shape-space) / 2); border-left: calc(var(--ub-shape-space) / 4) solid var(--ub-primary);
  background: var(--ub-surface-sunk); font-size: var(--ub-type-size-small); }
.ub-aod-bar button { flex: 0 0 auto; width: auto; min-height: var(--ub-shape-tap); font-size: var(--ub-type-size-small); }
.ub-menu-list .ub-menu-aod { font-size: var(--ub-type-size-caption); color: var(--ub-text); padding-top: calc(var(--ub-shape-space) / 2); border-top: 1px solid var(--ub-line);
  min-height: var(--ub-shape-tap); display: flex; align-items: center; }
/* D5: her privacy policy, the menu's last line, as small as the line above it. */
.ub-menu-list .ub-menu-privacy { font-size: var(--ub-type-size-caption); color: var(--ub-text); min-height: var(--ub-shape-tap); display: flex; align-items: center; }
/* Her grant (AD12), one compact row at the top of People: the sentence, then small outlined buttons, never full width. */
.ub-aod-grant { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--ub-shape-space) / 2) var(--ub-shape-space); }
.ub-aod-grant p { flex: 1 1 calc(var(--ub-shape-space) * 18); }
.ub-aod-grant form { display: flex; flex-wrap: wrap; gap: calc(var(--ub-shape-space) / 2); margin: 0; }
.ub-aod-grant .ub-button { width: auto; flex: 0 0 auto; padding-inline: calc(var(--ub-shape-space) * 0.75); }

.ub-notice {
  padding: calc(var(--ub-shape-space) * 0.75);
  background: var(--ub-surface);
  border: 1px solid var(--ub-line);
  border-left: 4px solid var(--ub-primary);
  border-radius: var(--ub-shape-radius-sm);
}

.ub-refusal { border-left-color: var(--ub-fail); }

/* The Notices page's list of cards: a card is not a bullet point (walkthrough finding 10, 2026-10-13), and it is not indented either: the
   list's own padding set the cards in from the heading (lead 27, 2026-10-27). */
.ub-notice-list { list-style: none; padding: 0; margin: 0 0 var(--ub-shape-space); }

/* The Notices page as a desk (owner-desk design round 2, the operator's approval of 2026-10-13): one table, New | Notice | When | Open. The
   `.ub-notice` card look above is not drawn on a row; the New badge is what marks an unread notice. The notice's cell holds the title and
   what it says, and from a desk 76rem wide (the menu collapsed; main is the `desk` container) its own grid puts them side by side, so no
   column is shown or hidden between layouts. Below 900 px the table is the chrome's stacked rows. */
.ub-notes-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: calc(var(--ub-shape-space) / 2) var(--ub-shape-space); margin-bottom: var(--ub-shape-space); }
.ub-notes-box + .ub-notice-zone { margin-top: var(--ub-shape-space); }
.ub-notes-head h1 { margin: 0; }
.ub-notes-head form { margin: 0; }
.ub-notes-head button { width: auto; }
.ub-n-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.ub-table.ub-notes tr.ub-notice { padding: 0; background: none; border: 0; border-radius: 0; }
.ub-table.ub-notes td { vertical-align: top; }
.ub-table.ub-notes { table-layout: fixed; }
.ub-n-notice { width: auto; }
.ub-n-new { width: calc(var(--ub-shape-space) * 3.5); }
.ub-n-when { width: calc(var(--ub-shape-space) * 14.375); }
.ub-n-open { width: calc(var(--ub-shape-space) * 10); text-align: right; }
.ub-table.ub-notes th.ub-n-open { padding-right: var(--ub-shape-space); }
.ub-n-title { margin: 0; font-family: inherit; font-size: inherit; font-weight: 600; line-height: inherit; letter-spacing: inherit; color: inherit; }
.ub-n-says p, .ub-n-when p { margin: 0; }
.ub-n-says p { font-size: var(--ub-type-size-caption); line-height: 1.4; color: var(--ub-text-2); }
.ub-n-says p + p { margin-top: calc(var(--ub-shape-space) / 8); }
.ub-n-says .ub-notice-meta, .ub-n-when .ub-notice-meta { font-size: var(--ub-type-size-caption); line-height: 1.4; color: var(--ub-muted); }
.ub-n-says .ub-notice-meta { font-size: var(--ub-type-size-eyebrow); }
.ub-n-when .ub-notice-meta { color: var(--ub-text-2); }
.ub-n-open form { margin: 0; }
.ub-n-open button { width: auto; padding: 0 calc(var(--ub-shape-space) * 0.875); font-size: var(--ub-type-size-label); }
/* The trash can on each notice (notes 20 and 31, 2026-10-27): a 48 px icon button that takes it off the person's own list. On a
   tutor's card it sits in the top corner; in the owner's table, beside Open. */
.ub-n-acts { display: inline-flex; align-items: center; gap: calc(var(--ub-shape-space) / 4); }
.ub-notice-list .ub-notice { position: relative; padding-right: calc(var(--ub-shape-tap) + var(--ub-shape-space) / 2); }
.ub-notice-list .ub-notice-dismiss { position: absolute; top: 0; right: 0; margin: 0; }
/* A past notice (OPS-NOTICES-SPEC N63, the operator's run of 2026-10-28): what it asked is done. A "Done" chip, the card quieter, sorted
   below the open ones; it stays on the list. Her message on its own page keeps its line breaks (N64). */
.ub-notice-past { border-left-color: var(--ub-line); color: var(--ub-text-2); }
.ub-notice-list .ub-notice-past h2 { color: var(--ub-text-2); }
.ub-badge.ub-notice-done { color: var(--ub-ok); background: var(--ub-ok-soft); box-shadow: none; }
.ub-notice-says { white-space: pre-line; }
/* The steps from a notice's own page (N64, T63a: home, the training, the Tutor Gym): a row that wraps at a desk, one under
   another on a phone, so no label breaks inside its button. */
.ub-notice-steps { display: flex; flex-wrap: wrap; gap: calc(var(--ub-shape-space) / 2); margin: 0 0 var(--ub-shape-space); }
@media (max-width: 899px) { .ub-notice-steps .ub-button { flex: 1 1 100%; } }
.ub-notice-dismiss button { width: var(--ub-shape-tap); min-width: var(--ub-shape-tap); height: var(--ub-shape-tap); padding: 0;
  display: inline-flex; align-items: center; justify-content: center; background: none; border: 0; box-shadow: none; color: var(--ub-muted); }
.ub-notice-dismiss button:hover { color: var(--ub-fail); }
.ub-notice-dismiss .ub-icon { fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.ub-n-says-head { display: none; }
@container desk (min-width: 76rem) {
  .ub-n-cell { display: grid; grid-template-columns: 20rem minmax(0, 1fr); column-gap: calc(var(--ub-shape-space) * 1.25); }
  .ub-n-says-head { display: inline; }
}
@media (max-width: 899px) {
  .ub-notes-head { flex-direction: column; align-items: stretch; }
  .ub-notes-head button { width: 100%; }
  .ub-table.ub-notes tr.ub-notice { display: block; padding: calc(var(--ub-shape-space) * 0.875) var(--ub-shape-space); border-bottom: 1px solid var(--ub-line); }
  .ub-table.ub-notes tr.ub-notice:last-child { border-bottom: 0; }
  .ub-table.ub-notes { table-layout: auto; }
  .ub-table.ub-notes td { display: block; width: auto; }
  .ub-table.ub-notes td.ub-n-new { float: left; margin: calc(var(--ub-shape-space) / 8) calc(var(--ub-shape-space) / 2) 0 0; }
  .ub-table.ub-notes td.ub-n-new:empty { display: none; }
  .ub-n-says p, .ub-n-says .ub-notice-meta, .ub-n-when .ub-notice-meta { font-size: var(--ub-type-size-label); line-height: 1.43; }
  .ub-n-says { margin-top: calc(var(--ub-shape-space) / 4); }
  .ub-n-when { margin-top: calc(var(--ub-shape-space) / 4); }
  .ub-n-open { margin-top: calc(var(--ub-shape-space) / 2); text-align: left; }
  .ub-n-open button { font-size: var(--ub-type-size); padding: 0 calc(var(--ub-shape-space) * 1.25); }
}

.ub-role, .ub-address { font-weight: 600; }

.ub-sim {
  display: inline-flex;
  align-items: center;
  min-height: calc(var(--ub-shape-space) * 1.375);
  padding: 0 calc(var(--ub-shape-space) / 2);
  color: var(--ub-on-status);
  background: var(--ub-sim);
  border-radius: var(--ub-shape-radius-lg);
  font-size: var(--ub-type-size-eyebrow);
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  vertical-align: middle;
}

.ub-code {
  font-size: var(--ub-type-size-large);
  letter-spacing: 0.2em;
}

.ub-message {
  margin: 0 0 var(--ub-shape-space);
  padding: var(--ub-shape-space);
  background: var(--ub-surface);
  border: 1px solid var(--ub-line);
  border-radius: var(--ub-shape-radius-md);
}

.ub-message pre {
  margin: calc(var(--ub-shape-space) / 2) 0 0;
  white-space: pre-wrap;
  font: inherit;
  font-size: var(--ub-type-size-small);
  color: var(--ub-muted);
}

.ub-wide { max-width: 60rem; }

/* The approval card's preview (ADDIE-SPEC RW3, AW46): rows of label and plain text, written by code from the
   stored arguments, shown in full. Copied from the approved canvas (needs-you.css); the panel, ADDIE's button
   and its mark are AD-P1b's. Line breaks in the text are kept by pre-wrap; no <br> is built from it. */
.ub-approval-preview { margin: calc(var(--ub-shape-space) / 4) 0 calc(var(--ub-shape-space) * 0.75); padding: calc(var(--ub-shape-space) * 0.75); background: var(--ub-surface-sunk); border-radius: var(--ub-shape-radius-md); }
.ub-approval-preview-head {
  font-family: var(--ub-type-display); font-size: var(--ub-type-size-eyebrow); font-weight: 650;
  line-height: 1.33; letter-spacing: 0.09em; text-transform: uppercase; color: var(--ub-muted);
}
/* The canvas wrote this under `.ub-frame`, its stand-in for a page, to outrank its `.ub-frame p`; here the
   page's own `p` rule is the one to outrank, and the class alone does. */
.ub-approval-preview-head { margin: 0 0 calc(var(--ub-shape-space) / 4); }
.ub-approval-preview dl { margin: 0; }
.ub-approval-row { padding: calc(var(--ub-shape-space) / 2) 0; border-bottom: 1px solid var(--ub-line); }
.ub-approval-row:last-child { border-bottom: 0; padding-bottom: 0; }
.ub-approval-row dt { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--ub-shape-space) / 2); font-size: var(--ub-type-size-label); font-weight: 600; line-height: 1.43; color: var(--ub-muted); }
.ub-approval-row dd { margin: 0; color: var(--ub-text); overflow-wrap: anywhere; }
.ub-approval-plain { white-space: pre-wrap; }
@media (min-width: 900px) {
  .ub-approval-preview { padding: calc(var(--ub-shape-space) * 0.75) var(--ub-shape-space); }
  .ub-approval-row { display: grid; grid-template-columns: 7rem minmax(0, 1fr); column-gap: calc(var(--ub-shape-space) * 0.75); }
  .ub-approval-row dt { align-items: flex-start; align-content: flex-start; padding-top: 0.15em; }
}

/* ---------- System Updates (AOD-ADMIN-SPEC AD16) ---------- */
.ub-updates-intro { color: var(--ub-muted); }
.ub-updates-month { margin-bottom: calc(var(--ub-shape-space) * 1.5); }
.ub-updates-month > h2 { font-size: var(--ub-type-size-heading); margin: 0 0 calc(var(--ub-shape-space) / 2); }
.ub-updates-group { margin-bottom: calc(var(--ub-shape-space) / 2); padding: var(--ub-shape-space); }
.ub-updates-group h3 { font-size: var(--ub-type-size); margin: 0 0 calc(var(--ub-shape-space) / 2); }
.ub-updates-group ul { margin: 0; padding-left: calc(var(--ub-shape-space) * 1.25); }
.ub-updates-group li + li { margin-top: calc(var(--ub-shape-space) / 4); }
.ub-updates-none { color: var(--ub-muted); }

/* ==========================================================================

   The shared app-chrome classes (docs/design/CHROME-CLASSES.md).
   From C's re-skin (design/systems/c/reskin/reskin.css). Everything is `ub-`
   prefixed: a component is `ub-<noun>`, a part of it is `ub-<noun>-<part>`, and
   a modifier or state is a second class, `ub-is-<word>`, used beside its
   component. No unprefixed class is added: `.card` and `.slide` belong to C's
   lesson bundle and never appear here. Sizes are multiples of --ub-shape-space
   or --ub-shape-tap, or type tokens; only hairlines, focus outlines and the
   900px breakpoint are written as literals. Phone first, desktop from 900px.
   Nothing above this line is changed by what follows.
   ========================================================================== */

/* ---------- the shell, icons, labels, avatar, logo ---------- */
.ub-app { -webkit-font-smoothing: antialiased; }
.ub-app a { text-decoration: none; }
.ub-app a:not(.ub-button) { color: inherit; }

.ub-icon { display: block; flex: none; width: calc(var(--ub-shape-space) * 1.25); height: calc(var(--ub-shape-space) * 1.25); }
.ub-icon-small { display: block; flex: none; width: var(--ub-shape-space); height: var(--ub-shape-space); }

.ub-label, .ub-stat-label {
  margin: 0;
  font-family: var(--ub-type-display);
  font-size: var(--ub-type-size-eyebrow);
  font-weight: 650;
  line-height: 1.33;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ub-muted);
}

.ub-avatar {
  display: grid;
  place-items: center;
  flex: none;
  width: calc(var(--ub-shape-space) * 2.5);
  height: calc(var(--ub-shape-space) * 2.5);
  border-radius: var(--ub-shape-radius-full);
  background: var(--ub-primary-soft);
  color: var(--ub-primary);
  font-family: var(--ub-type-display);
  font-size: var(--ub-type-size-caption);
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.02em;
}

.ub-logo { display: block; height: calc(var(--ub-shape-space) * 1.75); width: auto; }
.ub-logo-plate {
  display: inline-flex;
  align-items: center;
  flex: none;
  padding: calc(var(--ub-shape-space) * 0.375) calc(var(--ub-shape-space) * 0.625) calc(var(--ub-shape-space) * 0.375) calc(var(--ub-shape-space) * 0.5);
  border-radius: var(--ub-shape-radius-md);
  background: var(--ub-surface);
}
.ub-logo-mark { display: block; width: var(--ub-shape-tap); height: var(--ub-shape-tap); border-radius: var(--ub-shape-radius-sm); }

/* ---------- 48 px: a link or a field that has to be tapped ---------- */
/* 48 px wide as well: a one-word link ("Back", "Open") was 36 to 41 px wide at 390 px (the lead's leave, 2026-10-03). */
.ub-tap { display: inline-flex; align-items: center; justify-content: center; min-height: var(--ub-shape-tap); min-width: var(--ub-shape-tap); }
/* The one global rule of this section, and the only one that changes an existing page (operator-paths):
   number, date, select and textarea are 48 px tall. A checkbox or a radio is not in the list and is never
   stretched. Height only: the control edge is the opt-in .ub-input, because a border here would also
   restyle the rehearsal composer's textarea, which sets its own padding and width. */
input[type="number"], input[type="date"], select, textarea { min-height: var(--ub-shape-tap); }
/* A select is as wide as its longest option unless told otherwise: the work order's select names each order by its
   title, and a content request's title (her words) pushed the operator's version page 8 px past 390 (v20, v22 on the
   test host, 30 Oct; a published version's page, 311 px, in test_content_request_draft_browser.py). Never past its column. */
select { max-width: 100%; }
/* A number or date field keeps the browser's own small font unless told otherwise, and a field under 16px makes iOS
   zoom the page: measured on operator-paths at 390 px (lane C, with the lead's leave, 2026-10-03). */
input[type="number"], input[type="date"] { font-size: var(--ub-type-size); }
.ub-input {
  display: block;
  width: 100%;
  min-height: var(--ub-shape-tap);
  padding: 0 calc(var(--ub-shape-space) * 0.75);
  font: inherit;
  color: var(--ub-text);
  background: var(--ub-surface);
  border: 1px solid var(--ub-border);
  border-radius: var(--ub-shape-radius-md);
}
textarea.ub-input { padding-top: calc(var(--ub-shape-space) * 0.75); padding-bottom: calc(var(--ub-shape-space) * 0.75); }

/* ---------- buttons: variants beside .ub-button ---------- */
.ub-button.ub-is-secondary {
  color: var(--ub-text);
  background: var(--ub-surface);
  border: 1.5px solid var(--ub-border);
}
.ub-button.ub-is-secondary:hover { background: var(--ub-surface-sunk); }
.ub-button.ub-is-spark { color: var(--ub-text); background: var(--ub-secondary); }
.ub-button .ub-icon { width: calc(var(--ub-shape-space) * 1.125); height: calc(var(--ub-shape-space) * 1.125); }
.ub-button { gap: calc(var(--ub-shape-space) / 2); }

/* ---------- panels and chips ---------- */
.ub-panel {
  background: var(--ub-surface);
  border: 1px solid var(--ub-line);
  border-radius: var(--ub-shape-radius-lg);
}
/* A table that is a card's direct child and is wider than the card scrolls inside it, so it never widens the page (found 2026-10-08: a 995 px table in a 656 px column). */
.ub-panel:has(> .ub-table) { overflow-x: auto; }
.ub-panel.ub-is-deep { background: var(--ub-primary); color: var(--ub-on-primary); border-color: var(--ub-primary); }

.ub-chip {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--ub-shape-space) * 0.3125);
  min-height: calc(var(--ub-shape-space) * 1.625);
  padding: 0 calc(var(--ub-shape-space) * 0.5625) 0 calc(var(--ub-shape-space) * 0.4375);
  border-radius: var(--ub-shape-radius-sm);
  font-size: var(--ub-type-size-caption);
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
}
.ub-chip .ub-icon-small { width: calc(var(--ub-shape-space) * 0.9375); height: calc(var(--ub-shape-space) * 0.9375); }
.ub-chip.ub-is-new { color: var(--ub-text-2); background: var(--ub-surface-sunk); box-shadow: inset 0 0 0 1px var(--ub-line); }
.ub-chip.ub-is-progress { color: var(--ub-info); background: var(--ub-info-soft); }
.ub-chip.ub-is-passed { color: var(--ub-ok); background: var(--ub-ok-soft); }
.ub-chip.ub-is-overdue { color: var(--ub-fail); background: var(--ub-fail-soft); }
.ub-chip.ub-is-due { color: var(--ub-warn); background: var(--ub-warn-soft); }
.ub-chip.ub-is-agent { color: var(--ub-agent); background: var(--ub-agent-soft); }

.ub-agent-tag {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--ub-shape-space) * 0.3125);
  font-family: var(--ub-type-display);
  font-size: var(--ub-type-size-eyebrow);
  font-weight: 700;
  line-height: 1.33;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ub-agent);
}

/* ---------- 2. top bar: logo, title, avatar ---------- */
.ub-appbar {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: calc(var(--ub-shape-space) * 0.75);
  padding: calc(var(--ub-shape-space) * 0.625) var(--ub-shape-space);
  background: var(--ub-surface);
  border-bottom: 1px solid var(--ub-line);
}
.ub-appbar-brand { display: flex; align-items: center; gap: calc(var(--ub-shape-space) * 0.75); min-width: 0; }
.ub-appbar-brand .ub-logo-plate { padding: calc(var(--ub-shape-space) * 0.375) calc(var(--ub-shape-space) * 0.625) calc(var(--ub-shape-space) * 0.375) calc(var(--ub-shape-space) * 0.5); }
.ub-appbar-title { display: flex; flex-direction: column; min-width: 0; }
.ub-appbar-title b {
  font-family: var(--ub-type-display);
  font-size: var(--ub-type-size-heading);
  font-weight: 700;
  line-height: 1.33;
  letter-spacing: -0.005em;
  color: var(--ub-primary);
}
.ub-appbar-title span { font-size: var(--ub-type-size-caption); font-weight: 500; line-height: 1.4; color: var(--ub-muted); }

/* ---------- 3. tab bar: at the bottom on a phone, in the top bar on desktop ---------- */
.ub-tabbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  display: flex;
  padding: calc(var(--ub-shape-space) / 4) calc(var(--ub-shape-space) / 4) calc(var(--ub-shape-space) / 4 + env(safe-area-inset-bottom, 0px));
  background: var(--ub-surface);
  border-top: 1px solid var(--ub-line);
}
.ub-tabbar a {
  flex: 1;
  min-width: 0;
  min-height: calc(var(--ub-shape-space) * 3.5);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(var(--ub-shape-space) / 8);
  border-radius: var(--ub-shape-radius-md);
  font-size: var(--ub-type-size-eyebrow);
  font-weight: 600;
  line-height: 1.33;
  color: var(--ub-muted);
}
.ub-tabbar a .ub-icon { width: calc(var(--ub-shape-space) * 1.5); height: calc(var(--ub-shape-space) * 1.5); }
.ub-tabbar a.ub-is-current { color: var(--ub-primary); background: var(--ub-primary-soft); }
.ub-tabbar a:focus-visible, .ub-side-nav a:focus-visible, .ub-tabs a:focus-visible { outline: 2px solid var(--ub-focus); outline-offset: -2px; }

/* ---------- a page of cards: hero, tiles, notes (the page styles its own greeting) ---------- */
.ub-page {
  display: grid;
  gap: var(--ub-shape-space);
  max-width: calc(var(--ub-shape-space) * 70);
  margin: 0 auto;
  padding: calc(var(--ub-shape-space) * 1.25) var(--ub-shape-space) calc(var(--ub-shape-space) * 6);
}

/* ---------- 5. hero slab: eyebrow, title, text, one action ---------- */
.ub-hero { display: flex; flex-direction: column; gap: calc(var(--ub-shape-space) / 2); padding: calc(var(--ub-shape-space) * 1.25); }
.ub-hero .ub-label { color: var(--ub-on-primary-2); }
.ub-hero h2 {
  margin: 0;
  font-size: var(--ub-type-size-large);
  font-weight: var(--ub-type-display-weight);
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--ub-on-primary);
}
.ub-hero p { margin: 0; }
.ub-hero p:not(.ub-label) { color: var(--ub-on-primary-2); }
.ub-hero .ub-button { align-self: flex-start; margin-top: calc(var(--ub-shape-space) / 2); }

/* ---------- 7. stat tiles; the value may be a word ---------- */
.ub-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: calc(var(--ub-shape-space) * 0.75); }
.ub-stat { display: flex; flex-direction: column; gap: calc(var(--ub-shape-space) / 4); min-width: 0; padding: var(--ub-shape-space); }
.ub-stat-num {
  display: flex;
  align-items: flex-end;
  gap: calc(var(--ub-shape-space) * 0.375);
  min-height: calc(var(--ub-shape-space) * 3.5);
  margin: calc(var(--ub-shape-space) / 8) 0 0;
}
.ub-stat-num b {
  font-family: var(--ub-type-display);
  font-size: var(--ub-type-size-numeral);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ub-primary);
}
.ub-stat-num span { font-family: var(--ub-type-display); font-size: var(--ub-type-size-heading); font-weight: 700; letter-spacing: -0.01em; color: var(--ub-text-2); }
/* A word takes proportional figures: tabular ones give a comma a figure's width ("Fri , Oct 30", the lead's review of 2026-10-05). */
.ub-stat-num b.ub-is-word { font-size: var(--ub-type-size-large); line-height: 1.2; letter-spacing: -0.015em; padding-bottom: calc(var(--ub-shape-space) * 0.375); font-variant-numeric: normal; }
.ub-stat-num span.ub-stat-ok { display: inline-flex; padding-bottom: calc(var(--ub-shape-space) * 0.75); color: var(--ub-ok); }
.ub-stat-cap { margin: 0; font-size: var(--ub-type-size-label); line-height: 1.43; color: var(--ub-text-2); display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--ub-shape-space) / 2); }
.ub-segs { display: flex; gap: calc(var(--ub-shape-space) * 0.1875); }
.ub-segs i {
  display: block;
  width: calc(var(--ub-shape-space) * 0.875);
  height: calc(var(--ub-shape-space) / 2);
  border-radius: calc(var(--ub-shape-space) / 8);
  background: var(--ub-surface-sunk);
  box-shadow: inset 0 0 0 1px var(--ub-border);
}
.ub-segs i.ub-is-on { background: var(--ub-primary); box-shadow: none; }

/* ---------- 8. a plain text card with a label ---------- */
.ub-note-card { display: flex; flex-direction: column; gap: calc(var(--ub-shape-space) / 2); padding: var(--ub-shape-space); }
.ub-note-card p { margin: 0; }
.ub-note-card p:not(.ub-label) { color: var(--ub-text-2); }
.ub-note-card q { quotes: "\201C" "\201D"; color: var(--ub-text); }

/* ---------- 19. the frame: the sidebar, and the page's column ---------- */
/* One header for both widths. A desk (from 900px) draws it as a sticky navy sidebar with the page's `main` in the
   column beside it; a phone draws it as a navy bar over a row of links that scrolls sideways. The person's menu
   and the one sign-out form are in the DOM once; the phone's rules below move them (the lead, 2026-10-05). */
.ub-side { display: flex; flex-direction: column; min-width: 0; background: var(--ub-primary); color: var(--ub-on-primary); }
.ub-side > * { flex: none; }
.ub-side-head { display: flex; align-items: center; gap: calc(var(--ub-shape-space) * 0.625); padding: var(--ub-shape-space); border-bottom: 1px solid var(--ub-primary-dark); }
.ub-side-head > div { min-width: 0; }
.ub-tenant { display: block; font-family: var(--ub-type-display); font-size: var(--ub-type-size); font-weight: 700; line-height: 1.35; color: var(--ub-on-primary); }
.ub-side-head span { display: block; font-size: var(--ub-type-size-caption); line-height: 1.4; color: var(--ub-on-primary-2); }
.ub-side-mark { flex: none; display: block; }
.ub-side-home { display: flex; flex-direction: column; justify-content: center; min-height: var(--ub-shape-tap); color: inherit; text-decoration: none; }
.ub-side-home:hover .ub-tenant { text-decoration: underline; }
.ub-side-nav { display: flex; flex-direction: column; gap: calc(var(--ub-shape-space) / 8); padding: calc(var(--ub-shape-space) * 0.75) calc(var(--ub-shape-space) / 2); }
.ub-side-nav a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(var(--ub-shape-space) / 2);
  min-height: calc(var(--ub-shape-space) * 2.5);
  padding: 0 calc(var(--ub-shape-space) * 0.625);
  border-radius: var(--ub-shape-radius-sm);
  font-size: var(--ub-type-size-label);
  font-weight: 500;
  line-height: 1.43;
  color: var(--ub-on-primary-2);
  text-decoration: none;
  white-space: nowrap;
}
/* Not in the canvas: the hover fill and text, and the focus ring on navy (the page's `--ub-focus` is 1.6:1 there). */
.ub-side-nav a:hover { background: var(--ub-primary-dark); color: var(--ub-on-primary); }
.ub-side-nav a.ub-is-current { background: var(--ub-primary-dark); color: var(--ub-on-primary); font-weight: 600; }
.ub-side a:focus-visible, .ub-side button:focus-visible, .ub-side summary:focus-visible { outline-color: var(--ub-focus-on-primary); }
/* The rail's icons and tooltips are drawn only from 900px and only when the sidebar is collapsed (the rules at the end of
   the file); the toggle is drawn from 900px in both states. Everywhere else the wrapper is plain and they are not drawn. */
.ub-nav-item { position: relative; }
.ub-nav-icon, .ub-nav-tip, .ub-side-toggle { display: none; }
.ub-side-toggle .ub-icon { width: var(--ub-shape-space); height: var(--ub-shape-space); fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
/* The count chip: neutral; amber on an item that waits on the person (`ub-is-flag`, from NavItem.badge_tone). */
.ub-badge {
  display: inline-flex;
  align-items: center;
  min-height: calc(var(--ub-shape-space) * 1.375);
  padding: 0 calc(var(--ub-shape-space) * 0.4375) 0 calc(var(--ub-shape-space) * 0.375);
  border-radius: var(--ub-shape-radius-sm);
  font-size: var(--ub-type-size-eyebrow);
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
  color: var(--ub-text-2);
  background: var(--ub-surface-sunk);
  box-shadow: inset 0 0 0 1px var(--ub-line);
}
.ub-side-nav a.ub-is-flag .ub-badge { color: var(--ub-warn); background: var(--ub-warn-soft); box-shadow: none; }
.ub-side-foot {
  margin-top: auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: calc(var(--ub-shape-space) / 2);
  padding: calc(var(--ub-shape-space) * 0.375) var(--ub-shape-space);
  border-top: 1px solid var(--ub-primary-dark);
  font-size: var(--ub-type-size-caption);
  line-height: 1.4;
  color: var(--ub-on-primary-2);
}
/* The person's menu: at a desk "Signed in as" and the name, which opens "Sign out everywhere" under it. */
.ub-menu { position: relative; min-width: 0; }
.ub-menu summary { display: flex; flex-direction: column; justify-content: center; min-height: var(--ub-shape-tap); cursor: pointer; list-style: none; }
.ub-menu summary::-webkit-details-marker { display: none; }
.ub-menu-as { display: block; }
.ub-side .ub-person { display: block; color: var(--ub-on-primary); font-weight: 600; }
.ub-initials { display: none; }
/* What the menu opens is a panel over the page, so the foot does not grow: above the name at a desk, under the circle on a phone. */
.ub-menu-list { position: absolute; left: 0; bottom: 100%; z-index: 1; display: flex; flex-direction: column; gap: calc(var(--ub-shape-space) / 2); width: calc(var(--ub-shape-space) * 12); padding: calc(var(--ub-shape-space) / 2); margin-bottom: calc(var(--ub-shape-space) / 4); background: var(--ub-surface); border: 1px solid var(--ub-border); border-radius: var(--ub-shape-radius-md); }
.ub-menu-list form { margin: 0; }
.ub-side .ub-menu-list button { width: 100%; font-size: var(--ub-type-size-label); }
.ub-side .ub-menu-list .ub-menu-out { display: none; }
.ub-sign-out { margin: 0; }
.ub-side .ub-sign-out button {
  min-width: var(--ub-shape-tap);
  padding: 0;
  background: none;
  color: var(--ub-on-primary);
  font-size: var(--ub-type-size-caption);
  text-decoration: underline;
  text-underline-offset: calc(var(--ub-shape-space) / 5);
}

/* Spec F22, "Open on my phone": the foot's button (open menu, from 900px); the person's menu holds it otherwise. */
.ub-device-open { display: none; margin: 0; }
.ub-side .ub-device-open button {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--ub-shape-space) / 2);
  min-height: var(--ub-shape-tap);
  padding: 0;
  background: none;
  color: var(--ub-on-primary);
  font-size: var(--ub-type-size-caption);
}
.ub-device-open svg { width: calc(var(--ub-shape-space) * 1.25); height: calc(var(--ub-shape-space) * 1.25); fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.ub-side .ub-menu-list .ub-menu-device { display: none; }
.ub-device-to-computer { display: none; }

/* The code's page. No script: at two minutes, the link's life (`host.identity.device.TTL`), the QR and the code go and the sentence comes. */
.ub-device { display: flex; flex-wrap: wrap; gap: calc(var(--ub-shape-space) * 2); }
.ub-device-scan, .ub-device-type { flex: 1 1 calc(var(--ub-shape-space) * 16); min-width: 0; }
.ub-device-qr svg { display: block; width: calc(var(--ub-shape-space) * 16); height: auto; max-width: 100%; }
.ub-device-code { font-size: var(--ub-type-size-heading); font-weight: 700; letter-spacing: 0.08em; white-space: nowrap; }
.ub-device-live { animation: ub-device-gone 0s linear 120s forwards; }
.ub-device-dead { visibility: hidden; height: 0; margin: 0; padding: 0; overflow: hidden; animation: ub-device-come 0s linear 120s forwards; }
@keyframes ub-device-gone { to { visibility: hidden; height: 0; overflow: hidden; } }
@keyframes ub-device-come { to { visibility: visible; height: auto; margin: 0 0 var(--ub-shape-space); padding: var(--ub-shape-space); } }

/* list pane, with its head and toolbar */
.ub-list { display: flex; flex-direction: column; min-width: 0; background: var(--ub-surface); border-right: 1px solid var(--ub-line); }
.ub-pane-head { display: flex; align-items: center; justify-content: space-between; gap: calc(var(--ub-shape-space) * 0.75); padding: var(--ub-shape-space) var(--ub-shape-space) calc(var(--ub-shape-space) * 0.625); }
.ub-pane-head h1 { margin: 0; font-size: var(--ub-type-size-heading); font-weight: 700; line-height: 1.33; letter-spacing: -0.005em; }
.ub-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--ub-shape-space) / 2); padding: 0 var(--ub-shape-space) calc(var(--ub-shape-space) * 0.75); }
.ub-pane-foot { margin-top: auto; padding: calc(var(--ub-shape-space) * 0.75) var(--ub-shape-space); border-top: 1px solid var(--ub-line); font-size: var(--ub-type-size-caption); line-height: 1.4; color: var(--ub-muted); }

/* 10. a search field (the field inside is a real input) */
.ub-field {
  display: flex;
  align-items: center;
  gap: calc(var(--ub-shape-space) / 2);
  flex: 1 0 100%;
  min-width: 0;
  min-height: var(--ub-shape-tap);
  padding: 0 calc(var(--ub-shape-space) * 0.625);
  border-radius: var(--ub-shape-radius-sm);
  background: var(--ub-surface);
  box-shadow: inset 0 0 0 1.5px var(--ub-border);
  color: var(--ub-muted);
  font-size: var(--ub-type-size);
}
.ub-field .ub-icon { width: var(--ub-shape-space); height: var(--ub-shape-space); }
.ub-field input { flex: 1; min-width: 0; min-height: 0; margin: 0; padding: 0; border: 0; border-radius: 0; background: transparent; color: var(--ub-text); font: inherit; width: auto; }
.ub-field input::placeholder { color: var(--ub-muted); opacity: 1; }
.ub-field input:focus-visible { outline: none; }
.ub-field:focus-within { outline: 2px solid var(--ub-focus); outline-offset: 2px; }

/* 11. a segmented control */
.ub-seg { display: inline-flex; flex: none; min-height: var(--ub-shape-tap); overflow: hidden; border-radius: var(--ub-shape-radius-sm); box-shadow: inset 0 0 0 1.5px var(--ub-border); }
.ub-seg > * {
  display: inline-flex;
  align-items: center;
  padding: 0 calc(var(--ub-shape-space) * 0.75);
  border-right: 1.5px solid var(--ub-border);
  font-size: var(--ub-type-size-label);
  font-weight: 600;
  color: var(--ub-text-2);
}
.ub-seg > *:last-child { border-right: 0; }
.ub-seg > .ub-is-on { background: var(--ub-primary); color: var(--ub-on-primary); }

/* ---------- 12. data table, denser than a roster ---------- */
.ub-table { width: 100%; border-collapse: collapse; }
.ub-table th {
  padding: calc(var(--ub-shape-space) / 2) calc(var(--ub-shape-space) * 0.75);
  border-bottom: 1px solid var(--ub-line);
  font-family: var(--ub-type-display);
  font-size: var(--ub-type-size-eyebrow);
  font-weight: 650;
  line-height: 1.33;
  letter-spacing: 0.09em;
  text-align: left;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ub-muted);
}
.ub-table td {
  padding: calc(var(--ub-shape-space) * 0.5625) calc(var(--ub-shape-space) * 0.75);
  border-bottom: 1px solid var(--ub-line);
  vertical-align: middle;
  font-size: var(--ub-type-size-label);
  line-height: 1.43;
  color: var(--ub-text);
}
.ub-table tr:last-child td { border-bottom: 0; }
.ub-table .ub-num { letter-spacing: -0.01em; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--ub-text-2); }
.ub-table .ub-sub { display: block; font-size: var(--ub-type-size-caption); line-height: 1.4; color: var(--ub-muted); }
.ub-table .ub-cite { font-size: var(--ub-type-size-caption); line-height: 1.4; color: var(--ub-text-2); }
.ub-table .ub-cite i { font-style: normal; color: var(--ub-muted); }
.ub-table .ub-dim { color: var(--ub-muted); }
.ub-table b { font-weight: 600; }
.ub-table tr.ub-is-selected td { background: var(--ub-primary-soft); }
.ub-table.ub-is-tight td { padding-top: calc(var(--ub-shape-space) * 0.375); padding-bottom: calc(var(--ub-shape-space) * 0.375); }
.ub-table.ub-is-narrow th, .ub-table.ub-is-narrow td { padding-left: calc(var(--ub-shape-space) / 2); padding-right: calc(var(--ub-shape-space) / 4); }
.ub-table.ub-is-narrow th:first-child, .ub-table.ub-is-narrow td:first-child { padding-left: var(--ub-shape-space); }
.ub-table.ub-is-narrow th:last-child, .ub-table.ub-is-narrow td:last-child { padding-right: calc(var(--ub-shape-space) * 0.75); text-align: right; }
.ub-table-fixed { table-layout: fixed; }
.ub-table-fixed th, .ub-table-fixed td { padding-left: calc(var(--ub-shape-space) * 0.625); padding-right: calc(var(--ub-shape-space) * 0.375); }
.ub-table-fixed th:first-child, .ub-table-fixed td:first-child { padding-left: var(--ub-shape-space); }
.ub-table-fixed td { padding-top: calc(var(--ub-shape-space) * 0.4375); padding-bottom: calc(var(--ub-shape-space) * 0.4375); }

/* ---------- detail pane: header, body, boxes ---------- */
.ub-detail { display: flex; flex-direction: column; min-width: 0; }
.ub-detail-head { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--ub-shape-space) * 0.75); padding: calc(var(--ub-shape-space) * 0.875) calc(var(--ub-shape-space) * 1.5) calc(var(--ub-shape-space) * 0.75); background: var(--ub-surface); border-bottom: 1px solid var(--ub-line); }
.ub-detail-name { flex: 1; min-width: calc(var(--ub-shape-space) * 15); }
.ub-detail-head h2 { margin: 0; font-size: var(--ub-type-size-large); font-weight: var(--ub-type-display-weight); line-height: 1.2; letter-spacing: -0.015em; color: var(--ub-primary); }
.ub-detail-head p { margin: calc(var(--ub-shape-space) / 8) 0 0; font-size: var(--ub-type-size-caption); line-height: 1.4; color: var(--ub-muted); }
.ub-detail-acts { display: flex; flex-wrap: wrap; gap: calc(var(--ub-shape-space) / 2); }
.ub-detail-body { display: grid; grid-template-columns: minmax(0, 1fr) calc(var(--ub-shape-space) * 16.5); align-items: start; flex: 1; gap: var(--ub-shape-space); padding: var(--ub-shape-space) calc(var(--ub-shape-space) * 1.5); }
.ub-col { display: flex; flex-direction: column; gap: calc(var(--ub-shape-space) * 0.75); min-width: 0; }

/* 14. a card with a header row; 15. key and value list; 16. the agent's panel */
/* Hidden on y keeps the rounded corners; a table wider than its box scrolls on x instead of being cut off (found 2026-10-08: Clockwatch and a hire's steps at 900 to 1280 px). */
.ub-box { overflow-x: auto; overflow-y: hidden; background: var(--ub-surface); border: 1px solid var(--ub-line); border-radius: var(--ub-shape-radius-lg); }
.ub-box-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--ub-shape-space); padding: calc(var(--ub-shape-space) * 0.75) var(--ub-shape-space); border-bottom: 1px solid var(--ub-line); }
.ub-box-head b { font-weight: 600; line-height: 1.375; white-space: nowrap; color: var(--ub-text); }
.ub-box-head span { font-size: var(--ub-type-size-caption); line-height: 1.4; text-align: right; color: var(--ub-muted); }
.ub-box-pad { display: flex; flex-direction: column; gap: calc(var(--ub-shape-space) / 2); padding: calc(var(--ub-shape-space) * 0.875) var(--ub-shape-space); }
.ub-box-pad p { margin: 0; }
.ub-box-pad p:not(.ub-label) { font-size: var(--ub-type-size-label); line-height: 1.43; color: var(--ub-text-2); }
.ub-box-pad .ub-meta { font-size: var(--ub-type-size-caption); line-height: 1.4; color: var(--ub-muted); }
.ub-kv { display: flex; flex-direction: column; }
.ub-kv div { display: flex; align-items: center; justify-content: space-between; gap: calc(var(--ub-shape-space) / 2); padding: calc(var(--ub-shape-space) * 0.4375) 0; border-bottom: 1px solid var(--ub-line); font-size: var(--ub-type-size-label); line-height: 1.43; }
.ub-kv div:last-child { padding-bottom: 0; border-bottom: 0; }
.ub-box.ub-is-agent { background: var(--ub-agent-soft); border-color: var(--ub-agent); }
.ub-box.ub-is-agent p:not(.ub-meta) { color: var(--ub-text); }
.ub-button-row { display: flex; gap: calc(var(--ub-shape-space) / 2); }

/* ---------- 17. activity strip and its tabs ---------- */
.ub-strip { background: var(--ub-surface); border-top: 1px solid var(--ub-line); }
.ub-tabs { display: flex; align-items: center; gap: calc(var(--ub-shape-space) / 8); min-height: calc(var(--ub-shape-space) * 2.5); padding: 0 var(--ub-shape-space); overflow-x: auto; border-bottom: 1px solid var(--ub-line); }
.ub-tabs a { display: flex; align-items: center; gap: calc(var(--ub-shape-space) * 0.375); height: calc(var(--ub-shape-space) * 2.5); padding: 0 calc(var(--ub-shape-space) * 0.625); font-size: var(--ub-type-size-caption); font-weight: 600; line-height: 1.4; white-space: nowrap; color: var(--ub-muted); }
.ub-tabs a.ub-is-current { color: var(--ub-text); box-shadow: inset 0 -2px 0 var(--ub-primary); }
.ub-tabs a .ub-icon-small { color: var(--ub-agent); }
.ub-tabs-note { margin-left: auto; padding-left: var(--ub-shape-space); font-size: var(--ub-type-size-caption); line-height: 1.4; white-space: nowrap; color: var(--ub-muted); }
.ub-tabs-note-phone { display: none; }

/* ---------- desktop: from 900px ---------- */
@media (min-width: 900px) {
  .ub-appbar { grid-template-columns: auto 1fr auto; gap: calc(var(--ub-shape-space) * 2); padding: calc(var(--ub-shape-space) * 0.75) calc(var(--ub-shape-space) * 2.5); }
  .ub-tabbar { position: static; justify-content: flex-start; gap: calc(var(--ub-shape-space) / 4); padding: 0; background: transparent; border: 0; }
  .ub-tabbar a { flex: none; flex-direction: row; gap: calc(var(--ub-shape-space) / 2); min-height: var(--ub-shape-tap); padding: 0 calc(var(--ub-shape-space) * 0.875); font-size: var(--ub-type-size-label); line-height: 1.43; }
  .ub-tabbar a .ub-icon { width: calc(var(--ub-shape-space) * 1.25); height: calc(var(--ub-shape-space) * 1.25); }
  .ub-page { grid-template-columns: repeat(12, minmax(0, 1fr)); gap: calc(var(--ub-shape-space) * 1.5); padding: calc(var(--ub-shape-space) * 3) calc(var(--ub-shape-space) * 2.5) calc(var(--ub-shape-space) * 4); }
  .ub-span-7 { grid-column: span 7; }
  .ub-span-5 { grid-column: span 5; }
  .ub-hero { padding: calc(var(--ub-shape-space) * 2); gap: calc(var(--ub-shape-space) * 0.625); }
  .ub-tiles { gap: var(--ub-shape-space); }
  .ub-note-card { padding: calc(var(--ub-shape-space) * 1.5); }
  .ub-button.ub-is-small { min-height: calc(var(--ub-shape-space) * 2.125); padding: 0 calc(var(--ub-shape-space) * 0.75); font-size: var(--ub-type-size-label); border-radius: var(--ub-shape-radius-sm); }
  .ub-field, .ub-seg { min-height: calc(var(--ub-shape-space) * 2.125); }
  .ub-field { font-size: var(--ub-type-size-label); }
  .ub-field .ub-icon { width: var(--ub-shape-space); height: var(--ub-shape-space); }
  .ub-seg > * { padding: 0 calc(var(--ub-shape-space) * 0.5625); font-size: var(--ub-type-size-caption); }
}

/* ---------- the frame at a desk: from 900px, on screen ---------- */
@media screen and (min-width: 900px) {
  body:has(> .ub-side) { display: grid; grid-template-columns: calc(var(--ub-shape-space) * 14) minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); min-height: 100vh; }
  /* The sidebar's column runs the page's full height (owner-desk round 2): the navy column is drawn by a grid item that fills
     the single row under the test band, and the sidebar itself stays sticky on top of it, so the foot with Sign out is in view
     whatever the page's length. */
  body:has(> .ub-side)::before { content: ""; grid-column: 1; grid-row: 2; background: var(--ub-primary); }
  /* Not in the canvas: the test band stays at the top of the screen, 32 px tall, so the sidebar below it is the rest of
     the screen and its foot is never pushed out of sight by the band at the top of a long page. */
  body:has(> .ub-side) > .ub-test-band { grid-column: 1 / -1; position: sticky; top: 0; z-index: 2; display: flex; align-items: center; justify-content: center; height: calc(var(--ub-shape-space) * 2); padding-top: 0; padding-bottom: 0; }
  /* `overflow: visible`: the toggle sits half outside the sidebar, and a collapsed rail's tooltips must not be clipped.
     The sidebar's own scrolling is the link list's (below), so a screen too short for it scrolls the links, not the foot. */
  body:has(> .ub-side) > .ub-side { grid-column: 1; grid-row: 2; position: sticky; top: 0; z-index: 2; max-height: 100vh; overflow: visible; }
  body:has(> .ub-test-band) > .ub-side { top: calc(var(--ub-shape-space) * 2); max-height: calc(100vh - var(--ub-shape-space) * 2); }
  body:has(> .ub-side) > main { grid-column: 2; grid-row: 2; width: 100%; min-width: 0; }
  /* The reading column: a signed-in page on the default measure is 41rem here, not the phone's 34rem (the operator,
     2026-10-08). `:where()` keeps this rule at the specificity of `main`, so it beats the base `main` rule by coming after
     it, and any class that sets a page's own width on purpose (the wide pages, onboarding's, the camp's, Needs you with a
     panel) still wins, whatever sheet it is in. The sign-in pages have no menu: they keep the base measure. */
  :where(body:has(> .ub-side)) > main { max-width: var(--ub-shape-measure-desk); }
  /* Dashboard pages (owner-desk design, the operator's approval of 2026-10-13): a page opts in by its template, never by its URL,
     with `{% block main_class %}ub-dash{% endblock %}`. Its main drops the reading measure and is the `desk` container, so the page's
     layout follows main's width, not the window's: one `@container desk (min-width: 76rem)` in the page's own sheet switches it to the
     wide layout, which with the menu open (72rem at 1440) it is not, and on the collapsed rail (82.5rem) it is. Every page that does
     not carry the class keeps the 41rem measure above. */
  :where(body:has(> .ub-side)) > main.ub-dash {
    max-width: none;
    padding: calc(var(--ub-shape-space) * 1.5) calc(var(--ub-shape-space) * 2) calc(var(--ub-shape-space) * 2.5);
    container: desk / inline-size;
  }

  /* The link list is what scrolls when the screen is too short for the sidebar (it shrinks only then, so its box is the
     same when it fits); the head, ADDIE's button and the foot keep their size. */
  .ub-side-nav { flex: 0 1 auto; min-height: 0; overflow-y: auto; }
  .ub-side-nav > .ub-nav-item { flex: none; }

  /* The toggle: a <button> whose target is 44 px square, centered on the sidebar's right edge at the head's mid-height,
     half over the page. The 28 px circle you see is its ::before. It is out of the head's flow, so it takes no room: every
     box in the open sidebar is what it would be without it. The target is the tap size, and the head is taller than it,
     so it covers no link and no sign-out control; over the page it stops short where it would cover a first control
     (the rules below). The focus ring is on the circle, yellow between two navy rings, so it shows on the navy half and
     on the page's half. */
  .ub-side-head { position: relative; }
  .ub-side-toggle { display: block; position: absolute; z-index: 1; top: 50%; right: 0; width: calc(var(--ub-shape-space) * 2.75); height: calc(var(--ub-shape-space) * 2.75); margin: 0; transform: translate(50%, -50%); }
  .ub-side .ub-side-toggle button { position: relative; width: 100%; height: 100%; min-width: 0; min-height: 0; padding: 0; border: 0; border-radius: var(--ub-shape-radius-full); background: none; color: var(--ub-on-primary); }
  .ub-side .ub-side-toggle button::before { content: ""; position: absolute; inset: 0; margin: auto; width: calc(var(--ub-shape-space) * 1.75); height: calc(var(--ub-shape-space) * 1.75); box-sizing: border-box; border: 1px solid var(--ub-on-primary-2); border-radius: var(--ub-shape-radius-full); background: var(--ub-primary-dark); }
  .ub-side .ub-side-toggle .ub-icon { position: relative; }
  .ub-side .ub-side-toggle button:focus-visible { outline: none; }
  .ub-side .ub-side-toggle button:focus-visible::before { outline: 2px solid var(--ub-focus-on-primary); outline-offset: 2px; box-shadow: 0 0 0 6px var(--ub-primary); }

  /* Collapsed: an icon rail, 56 px wide. The content column takes the rest. */
  body:has(> .ub-side.ub-is-collapsed) { grid-template-columns: calc(var(--ub-shape-space) * 3.5) minmax(0, 1fr); }
  .ub-is-collapsed .ub-side-head { flex-direction: column; gap: calc(var(--ub-shape-space) / 2); padding: calc(var(--ub-shape-space) / 4) calc(var(--ub-shape-space) / 4) calc(var(--ub-shape-space) * 4); }
  .ub-is-collapsed .ub-side-head > div { display: none; }
  /* The rail's head keeps a row under the logo for the toggle (the approved rail's), so the links start where they did; the
     toggle itself is out of the flow, centered on the edge at that row's mid-height, clear of the logo. */
  .ub-is-collapsed .ub-side-toggle { top: calc(var(--ub-shape-space) / 4 + var(--ub-shape-tap) * 1.5 + var(--ub-shape-space) / 2); }
  /* The rail's links scroll when the screen is too short (the rule above), under the head and above the foot, as the open
     menu's do, so the foot with Sign out never leaves the screen. A scroll box clips what overflows it, and the names beside
     the icons overflow the 56 px rail: so the list's box is wider than the rail (the rail, a 16 px gap, the longest name
     and room to spare) and draws nothing. Its transparent part lets every pointer event through to the page; only the
     links take them. No scrollbar: a rail this narrow has no room for one, and the wheel, touch and Tab still scroll it. */
  .ub-is-collapsed .ub-side-nav { align-self: flex-start; width: calc(var(--ub-shape-space) * 19.5); padding: calc(var(--ub-shape-space) * 0.75) calc(var(--ub-shape-space) / 2); scrollbar-width: none; pointer-events: none; }
  .ub-is-collapsed .ub-nav-item { width: calc(var(--ub-shape-space) * 2.5); }
  .ub-is-collapsed .ub-nav-item a { pointer-events: auto; }
  .ub-is-collapsed .ub-nav-icon { position: absolute; z-index: 1; inset: 0; margin: auto; display: block; width: calc(var(--ub-shape-space) * 1.25); height: calc(var(--ub-shape-space) * 1.25); pointer-events: none; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; color: var(--ub-on-primary-2); }
  .ub-is-collapsed .ub-nav-icon.ub-is-letter { display: flex; align-items: center; justify-content: center; border: 1.5px solid currentColor; border-radius: var(--ub-shape-radius-full); font-size: var(--ub-type-size-caption); font-weight: 600; line-height: 1; }
  .ub-is-collapsed .ub-nav-item:has(a:hover) .ub-nav-icon, .ub-is-collapsed .ub-nav-item:has(a.ub-is-current) .ub-nav-icon { color: var(--ub-on-primary); }
  /* The link keeps its label as text, out of sight but read by a screen reader; the tooltip shows it. */
  .ub-is-collapsed .ub-side-nav a { position: relative; width: calc(var(--ub-shape-space) * 2.5); padding: 0; font-size: 0; overflow: hidden; }
  .ub-is-collapsed .ub-side-nav a .ub-badge { position: absolute; z-index: 2; top: calc(var(--ub-shape-space) / 16); right: calc(var(--ub-shape-space) / 16); min-height: calc(var(--ub-shape-space) * 1.125); padding: 0 calc(var(--ub-shape-space) / 4); font-size: var(--ub-type-size-eyebrow); }
  .ub-is-collapsed .ub-nav-tip { position: absolute; left: calc(100% + var(--ub-shape-space)); top: 50%; z-index: 3; display: block; transform: translateY(-50%); padding: calc(var(--ub-shape-space) / 4) calc(var(--ub-shape-space) * 0.625); border-radius: var(--ub-shape-radius-sm); background: var(--ub-text); color: var(--ub-surface); font-size: var(--ub-type-size-label); font-weight: 600; line-height: 1.43; white-space: nowrap; pointer-events: none; opacity: 0; visibility: hidden; }
  .ub-is-collapsed .ub-nav-item:hover .ub-nav-tip, .ub-is-collapsed .ub-nav-item:focus-within .ub-nav-tip { opacity: 1; visibility: visible; }
  /* ADDIE's labeled button sits under the links in the sidebar; collapsed, it is the mark alone, in a circle. */
  .ub-side > .ub-addie-open { align-self: flex-start; margin: calc(var(--ub-shape-space) / 2) var(--ub-shape-space) calc(var(--ub-shape-space) / 2); }
  .ub-side.ub-is-collapsed > .ub-addie-open.ub-is-labeled { align-self: center; margin: calc(var(--ub-shape-space) / 4) 0; padding: 0; }
  .ub-side.ub-is-collapsed > .ub-addie-open > span { display: none; }
  /* The foot is the person's initials, as on a phone: the menu holds both sign-outs. */
  .ub-device-open { display: block; grid-column: 1 / -1; }
  .ub-is-collapsed .ub-device-open { display: none; }
  .ub-side.ub-is-collapsed .ub-menu-list .ub-menu-device { display: block; }
  .ub-is-collapsed .ub-side-foot { display: flex; justify-content: center; padding: calc(var(--ub-shape-space) / 4); }
  .ub-is-collapsed .ub-menu-as { display: none; }
  .ub-is-collapsed .ub-menu summary { align-items: center; width: var(--ub-shape-tap); border-radius: var(--ub-shape-radius-full); background: var(--ub-primary-dark); }
  .ub-is-collapsed .ub-initials { display: block; font-size: var(--ub-type-size-label); font-weight: 600; line-height: 1; color: var(--ub-on-primary); }
  .ub-is-collapsed .ub-person { position: absolute; width: calc(var(--ub-shape-space) / 16); height: calc(var(--ub-shape-space) / 16); margin: calc(var(--ub-shape-space) / -16); overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .ub-is-collapsed .ub-menu-list { left: calc(100% + var(--ub-shape-space) / 2); bottom: 0; }
  .ub-side.ub-is-collapsed .ub-menu-list .ub-menu-out { display: inline-flex; }
  .ub-side.ub-is-collapsed .ub-sign-out { display: contents; }
  .ub-side.ub-is-collapsed .ub-sign-out button { display: none; }
}

/* ---------- phone: below 900px. Panes stack; a table becomes labelled rows ---------- */
@media (max-width: 899px) {
  .ub-side { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "head menu" "nav nav"; }
  .ub-side-head { grid-area: head; padding: calc(var(--ub-shape-space) * 0.75) var(--ub-shape-space); border-bottom: 0; }
  .ub-side-nav { grid-area: nav; flex-direction: row; gap: calc(var(--ub-shape-space) / 4); overflow-x: auto; padding: calc(var(--ub-shape-space) / 4) calc(var(--ub-shape-space) / 2) calc(var(--ub-shape-space) / 2); scroll-padding-inline: calc(var(--ub-shape-space) / 2); border-top: 1px solid var(--ub-primary-dark); }
  .ub-nav-item { flex: none; }
  .ub-side-nav a { flex: none; min-height: var(--ub-shape-tap); padding: 0 calc(var(--ub-shape-space) * 0.875); font-size: var(--ub-type-size); }
  /* The row opens scrolled to the current link, so it is never off the screen. Progressive: a browser without
     `scroll-initial-target` shows the row from its start, as before. No script (several pages assert they hold none). */
  .ub-side-nav a.ub-is-current { scroll-initial-target: nearest; }
  .ub-side-foot { display: contents; }
  /* The menu replaces the bare "Sign out": the person's initials, 48 px, opening "Sign out" and "Sign out everywhere".
     The full name stays in the summary for a screen reader, drawn out of sight. */
  .ub-menu { grid-area: menu; align-self: center; margin-right: var(--ub-shape-space); }
  .ub-menu summary { align-items: center; width: var(--ub-shape-tap); border-radius: var(--ub-shape-radius-full); background: var(--ub-primary-dark); }
  .ub-menu-as { display: none; }
  .ub-initials { display: block; font-size: var(--ub-type-size-label); font-weight: 600; line-height: 1; color: var(--ub-on-primary); }
  .ub-side .ub-person { position: absolute; width: calc(var(--ub-shape-space) / 16); height: calc(var(--ub-shape-space) / 16); margin: calc(var(--ub-shape-space) / -16); overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .ub-menu-list { left: auto; right: 0; bottom: auto; top: 100%; width: calc(var(--ub-shape-space) * 13); margin: calc(var(--ub-shape-space) / 4) 0 0; }
  .ub-side .ub-menu-list .ub-menu-device { display: block; }
  .ub-device-to-phone { display: none; }
  .ub-device-to-computer { display: inline; }
  /* On a phone the code is what the person needs: the other device is a computer. */
  .ub-device-type { order: -1; }
  .ub-side .ub-menu-list .ub-menu-out { display: inline-flex; }
  .ub-sign-out { display: contents; }
  .ub-side .ub-sign-out button { display: none; }
  .ub-list { border-right: 0; border-bottom: 1px solid var(--ub-line); }
  .ub-seg > * { padding: 0 calc(var(--ub-shape-space) * 0.75); }
  .ub-detail-head { padding: var(--ub-shape-space); }
  .ub-detail-body { grid-template-columns: minmax(0, 1fr); padding: var(--ub-shape-space); }
  .ub-detail-body .ub-col-rail { order: -1; }
  .ub-box-head { flex-direction: column; gap: calc(var(--ub-shape-space) / 8); }
  .ub-box-head span { text-align: left; }
  .ub-box-pad p:not(.ub-label), .ub-kv div { font-size: var(--ub-type-size); line-height: 1.5; }
  .ub-button-row .ub-button { flex: 1; }
  .ub-tabs a { min-height: var(--ub-shape-tap); }
  .ub-tabs .ub-tabs-note { display: none; }
  .ub-strip .ub-tabs-note-phone { display: block; padding: calc(var(--ub-shape-space) * 0.625) var(--ub-shape-space); border-bottom: 1px solid var(--ub-line); font-size: var(--ub-type-size-label); line-height: 1.43; color: var(--ub-muted); }

  /* 13. a table becomes rows: each cell with a data-label shows its label before its value */
  .ub-table, .ub-table tbody { display: block; }
  .ub-table thead, .ub-table colgroup { display: none; }
  .ub-table tr { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--ub-shape-space) / 4) calc(var(--ub-shape-space) * 1.25); padding: calc(var(--ub-shape-space) * 0.875) var(--ub-shape-space); border-bottom: 1px solid var(--ub-line); }
  .ub-table tr:last-child { border-bottom: 0; }
  .ub-table td, .ub-table.ub-is-tight td, .ub-table.ub-is-narrow td, .ub-table-fixed td, .ub-table.ub-is-narrow td:first-child, .ub-table-fixed td:first-child {
    display: block;
    padding: 0;
    border: 0;
    font-size: var(--ub-type-size);
    line-height: 1.5;
    text-align: left;
  }
  .ub-table tr.ub-is-selected { background: var(--ub-primary-soft); }
  .ub-table td[data-label]::before {
    content: attr(data-label);
    margin-right: calc(var(--ub-shape-space) / 2);
    font-family: var(--ub-type-display);
    font-size: var(--ub-type-size-eyebrow);
    font-weight: 650;
    line-height: 1.33;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ub-muted);
  }
  .ub-table td[data-label] { display: flex; align-items: center; }
  .ub-table .ub-ph-1 { order: 1; flex: 1 1 50%; font-weight: 600; }
  .ub-table .ub-ph-1.ub-ph-full { flex-basis: 100%; }
  .ub-table .ub-ph-2 { order: 2; margin-left: auto; }
  .ub-table .ub-ph-3 { order: 3; flex: 0 0 100%; }
  .ub-table .ub-ph-4 { order: 4; }
  .ub-table .ub-ph-5 { order: 5; flex: 0 0 100%; }
  .ub-table .ub-cite, .ub-table .ub-sub { font-size: var(--ub-type-size-label); line-height: 1.43; }
  .ub-table .ub-sub { font-weight: 400; }
  .ub-table td .ub-button { margin-top: calc(var(--ub-shape-space) / 4); }
}

/* ---------- the People page (owner-desk design round 2, 2026-10-13; scoped to `main.ub-people`, which also carries `ub-dash`) ----------
   Add a person on ONE row (Name, Email address, Role, the checkbox, Add), labels above the fields; the roster is full width and its Address
   column is the wide one, so an address stays on one line. On the phone the chrome's rules apply (one column, tables as rows). */
main.ub-people .ub-addrow { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr) calc(var(--ub-shape-space) * 11) auto auto; align-items: end; gap: calc(var(--ub-shape-space) * 0.625) calc(var(--ub-shape-space) * 0.75); }
main.ub-people .ub-addrow label { margin-bottom: 0; }
main.ub-people .ub-addrow .ub-fl { display: flex; flex-direction: column; gap: calc(var(--ub-shape-space) / 4); font-size: var(--ub-type-size-label); font-weight: 600; }
main.ub-people .ub-addrow input, main.ub-people .ub-addrow select { margin-bottom: 0; font-size: var(--ub-type-size); font-weight: 400; }
main.ub-people .ub-addrow .ub-checkrow { display: flex; align-items: center; justify-content: flex-start; gap: calc(var(--ub-shape-space) / 2); font-size: var(--ub-type-size-label); font-weight: 600; white-space: nowrap; }
main.ub-people .ub-addrow .ub-checkrow input { width: var(--ub-shape-tap); height: var(--ub-shape-tap); margin: 0; flex: none; }
main.ub-people .ub-addrow .ub-button { min-width: calc(var(--ub-shape-space) * 6); }
main.ub-people .ub-box-head h2 { margin: 0; font-size: var(--ub-type-size); font-weight: 600; line-height: 1.375; color: var(--ub-text); }
main.ub-people .ub-addrow { padding: calc(var(--ub-shape-space) * 0.75) var(--ub-shape-space); }
main.ub-people .ub-people-list > p { margin: 0; padding: 0 var(--ub-shape-space); }
main.ub-people .ub-people-zone { font-size: var(--ub-type-size-caption); color: var(--ub-muted); }
main.ub-people .ub-people-list .ub-address { font-size: var(--ub-type-size-caption); overflow-wrap: anywhere; }
@container desk (max-width: 56rem) {
  main.ub-people .ub-addrow { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
@media (min-width: 900px) {
  main.ub-people .ub-people-list th:first-child, main.ub-people .ub-people-list td:first-child { padding-left: var(--ub-shape-space); }
  main.ub-people .ub-people-list td .ub-tap { margin-block: calc((var(--ub-shape-space) * 2 - var(--ub-shape-tap)) / 2); }
  main.ub-people .ub-people-list th:nth-child(1) { width: calc(var(--ub-shape-space) * 14.375); }
  main.ub-people .ub-people-list th:nth-child(3), main.ub-people .ub-people-list th:nth-child(4) { width: calc(var(--ub-shape-space) * 12.5); }
  main.ub-people .ub-people-list th:nth-child(5) { width: calc(var(--ub-shape-space) * 16.25); }
}
@media (max-width: 899px) {
  main.ub-people .ub-people-when { margin-left: auto; }
  main.ub-people .ub-addrow { grid-template-columns: minmax(0, 1fr); }
  main.ub-people .ub-addrow .ub-button { width: 100%; }
}

/* The sign-in pages' head and foot (note 3, 2026-10-27): her logo above the heading, AOD's mark and name beneath the form.
   A logo file drawn on white takes the page's ground this way, with no white box round it. */
.ub-sign-in-brand { margin-top: var(--ub-shape-space); }
.ub-sign-in-privacy { font-size: var(--ub-type-size-caption); margin-top: 0; }
.ub-sign-in-logo { mix-blend-mode: multiply; display: block; width: auto; max-width: 100%; height: auto; max-height: calc(var(--ub-shape-tap) * 1.5); }
.ub-sign-in-name { font-family: var(--ub-type-display); font-size: var(--ub-type-size-large); color: var(--ub-primary); }
.ub-sign-in-go { color: var(--ub-brand-on-accent, var(--ub-on-primary)); background: var(--ub-brand-accent, var(--ub-primary)); }
.ub-sign-in-spelling { color: var(--ub-muted); font-size: var(--ub-type-size-small); }
.ub-sign-in-by { display: flex; align-items: center; gap: calc(var(--ub-shape-space) / 2); margin-top: calc(var(--ub-shape-space) * 2);
  color: var(--ub-muted); font-size: var(--ub-type-size-caption); }

