/* ui/components.css — the house's components (docs/roadmap/phase1-design-system.md §3; phase 1, stage D2).
 *
 * Every selector carries a .ufw- class (tests/design-tokens.test.cjs), so nothing here can reach a screen that has not
 * asked for it — and no paper: the contract, a change order and the signed papers are drawn by src/contract-document.css
 * alone. Every colour, size, radius, shadow and face is a token (ui/tokens.css; the design ratchet counts any literal
 * here). Loaded after each app's own sheet: the iPad (index.html), the office (ops/web/index.html), and — with stage F —
 * the customer's pages. ui/specimen.html shows each one, as the look harness pictures it (tests/look/library.look.cjs).
 *
 * The rules for everything (§3): a button is filled or outlined, 8px corners, at least --ufw-target tall; a link is
 * pine-700 and always underlined; a card or row that opens carries a › and a pressed tint, and hover only where there
 * is a mouse (@media (hover: hover)); "chosen" is drawn from ARIA state (aria-pressed, aria-checked, aria-current,
 * aria-selected), one look for all of it — a pine-700 edge, the pine-50 wash, 600 weight — and tabs an underline;
 * disabled is 45% and not-allowed; one focus ring. No @layer, no nesting, no :has() — the iPads' Safari versions are not
 * all known. Sizes in px, never rem: each app's root size is its own (the iPad's is 15px), and a component is one size
 * everywhere (the audit of stage D, S5: the sheet was 480px on the iPad, 512px in the guide).
 *
 *   1 button · 2 field · 3 page header · 4 tabs, segmented, chip, tag · 5 card · 6 tile · 7 row · 8 link · 9 pill
 *   10 notice, banner · 11 empty · 12 section title, sum · 13 table · 14 sheet · 15 toast · 16 form foot · 17 notes
 *   18 paper shell · 19 customer shell · 21 rep bar · 22 glove   (20, the email shell, is src/email-look.js at stage F:
 *   an email's <style> is stripped, so it is inline)
 */

/* --- shared ---------------------------------------------------------------------------------------------------------- */

.ufw-visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
/* The › of whatever opens: a card, a row. */
.ufw-chevron { flex: none; margin-left: var(--ufw-space-2); color: var(--ufw-ink-3); font-size: var(--ufw-text-xl); line-height: 1; }

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

.ufw-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--ufw-space-2);
  box-sizing: border-box; min-height: var(--ufw-target); min-width: var(--ufw-target);
  padding: var(--ufw-space-2) var(--ufw-space-4); margin: 0;
  font-family: var(--ufw-font); font-size: var(--ufw-text-md); font-weight: 600; line-height: var(--ufw-leading-tight);
  color: var(--ufw-ink); background: var(--ufw-surface);
  border: 1px solid var(--ufw-control-line); border-radius: var(--ufw-radius-control);
  text-decoration: none; text-align: center; cursor: pointer; white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--ufw-motion-fast) var(--ufw-ease), border-color var(--ufw-motion-fast) var(--ufw-ease);
}
.ufw-btn:active { background: var(--ufw-sunken); }
.ufw-btn:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus); outline-offset: var(--ufw-focus-offset); }
.ufw-btn--primary { color: var(--ufw-on-brand); background: var(--ufw-brand); border-color: var(--ufw-brand); }
.ufw-btn--primary:active { background: var(--ufw-pine-900); border-color: var(--ufw-pine-900); }
.ufw-btn--danger { color: var(--ufw-blocked); border-color: var(--ufw-blocked); }
.ufw-btn--danger:active { background: var(--ufw-blocked-wash); }
.ufw-btn--quiet { background: var(--ufw-sunken); border-color: transparent; }
.ufw-btn--quiet:active { background: var(--ufw-rule-soft); }
/* A link's words, inline: no box, its words underlined; a finger's reach on a touchscreen (below). */
.ufw-btn--link {
  min-height: 0; min-width: 0; padding: 0; border: 0; background: none; font-weight: 600;
  color: var(--ufw-pine-700); text-decoration: underline; text-underline-offset: 2px; position: relative;
}
.ufw-btn--link:active { background: none; color: var(--ufw-brand); }
.ufw-btn--small { min-height: var(--ufw-target-small); padding: var(--ufw-space-1) var(--ufw-space-3); font-size: var(--ufw-text-sm); }
.ufw-btn--block { display: flex; width: 100%; }
.ufw-btn:disabled, .ufw-btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.ufw-btn[aria-busy="true"] { cursor: progress; }
.ufw-btn[aria-busy="true"]::after {
  content: ""; width: 1em; height: 1em; border: 2px solid currentColor; border-right-color: transparent;
  border-radius: var(--ufw-radius-pill); animation: ufw-spin 800ms linear infinite;
}
@keyframes ufw-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .ufw-btn[aria-busy="true"]::after { animation: none; } }
@media (hover: hover) {
  .ufw-btn:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--ufw-surface-2); border-color: var(--ufw-pine-600); }
  .ufw-btn--primary:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--ufw-pine-700); border-color: var(--ufw-pine-700); }
  .ufw-btn--danger:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--ufw-blocked-wash); border-color: var(--ufw-blocked); }
  .ufw-btn--quiet:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--ufw-rule-soft); border-color: transparent; }
  .ufw-btn--link:hover:not(:disabled) { background: none; color: var(--ufw-brand); }
}

/* --- 2 field ------------------------------------------------------------------------------------------------------------ */

.ufw-field { display: grid; gap: var(--ufw-space-1); margin: 0 0 var(--ufw-space-4); }
.ufw-field__label { font-family: var(--ufw-font); font-size: var(--ufw-text-sm); font-weight: 600; color: var(--ufw-ink-2); }
.ufw-field__optional { font-weight: 400; color: var(--ufw-ink-3); }
.ufw-field__hint { margin: 0; font-size: var(--ufw-text-sm); color: var(--ufw-ink-3); }
.ufw-field__error { margin: 0; font-size: var(--ufw-text-sm); font-weight: 600; color: var(--ufw-blocked); }
.ufw-input, .ufw-select, .ufw-textarea {
  box-sizing: border-box; width: 100%; min-height: var(--ufw-target); margin: 0;
  padding: var(--ufw-space-2) var(--ufw-space-3);
  font-family: var(--ufw-font); font-size: var(--ufw-text-lg); line-height: var(--ufw-leading-tight);
  color: var(--ufw-ink); background: var(--ufw-surface);
  border: 1px solid var(--ufw-control-line); border-radius: var(--ufw-radius-control);
}
.ufw-textarea { min-height: calc(var(--ufw-target) * 2.5); line-height: var(--ufw-leading); resize: vertical; }
/* The select's arrow, drawn from its own colour (no picture to fetch, nothing to keep offline). */
.ufw-select {
  -webkit-appearance: none; appearance: none; padding-right: calc(var(--ufw-space-3) * 3);
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.ufw-input:focus-visible, .ufw-select:focus-visible, .ufw-textarea:focus-visible {
  outline: var(--ufw-focus-width) solid var(--ufw-focus); outline-offset: 0; border-color: var(--ufw-focus);
}
.ufw-field--error .ufw-input, .ufw-field--error .ufw-select, .ufw-field--error .ufw-textarea { border-color: var(--ufw-blocked); }
/* One read-only look: the sunken ground, the words as they are (never grey: it is not disabled). */
.ufw-input[readonly], .ufw-textarea[readonly] { background: var(--ufw-sunken); border-color: var(--ufw-rule); }
.ufw-input:disabled, .ufw-select:disabled, .ufw-textarea:disabled { opacity: .45; cursor: not-allowed; }
.ufw-input::placeholder, .ufw-textarea::placeholder { color: var(--ufw-ink-3); opacity: 1; }
/* A tick box or a choice of one: the whole row its label, a finger's height. */
.ufw-check {
  display: flex; align-items: center; gap: var(--ufw-space-3); min-height: var(--ufw-target);
  font-family: var(--ufw-font); font-size: var(--ufw-text-md); color: var(--ufw-ink); cursor: pointer;
}
/* The box at the row's start a finger's reach on its left too: the row reaches out past it by half what the box is short
   of a target, and is drawn where it was — its words and box do not move (phase 1, G1: to a finger the box was 33 wide). */
.ufw-check { padding-left: calc((var(--ufw-target) - 22px) / 2); margin-left: calc((22px - var(--ufw-target)) / 2); }
.ufw-check input { flex: none; width: 22px; height: 22px; margin: 0; accent-color: var(--ufw-pine-700); cursor: pointer; }
.ufw-check input:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus); outline-offset: var(--ufw-focus-offset); }
.ufw-check__label { display: grid; gap: 2px; }
.ufw-check__hint { font-size: var(--ufw-text-sm); color: var(--ufw-ink-3); }
.ufw-check input:disabled, .ufw-check input:disabled + .ufw-check__label { opacity: .45; cursor: not-allowed; }

/* --- 3 page header ------------------------------------------------------------------------------------------------------ */

.ufw-page-head { margin: 0 0 var(--ufw-space-5); font-family: var(--ufw-font); }
.ufw-page-head__back {
  display: inline-flex; align-items: center; min-height: var(--ufw-target); margin: 0 0 var(--ufw-space-1);
  font-size: var(--ufw-text-md); font-weight: 600; color: var(--ufw-pine-700); text-decoration: none;
}
.ufw-page-head__back:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus); outline-offset: var(--ufw-focus-offset); }
.ufw-page-head__row { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--ufw-space-3) var(--ufw-space-4); }
.ufw-page-head__title { min-width: 0; }
.ufw-page-head h1, .ufw-page-head h2 { margin: 0; font-size: var(--ufw-text-2xl); font-weight: 700; line-height: var(--ufw-leading-tight); color: var(--ufw-ink); }
.ufw-page-head__count { font-weight: 400; color: var(--ufw-ink-3); }
.ufw-page-head__sub { margin: var(--ufw-space-1) 0 0; font-size: var(--ufw-text-md); color: var(--ufw-ink-3); }
.ufw-page-head__actions { display: flex; flex-wrap: wrap; gap: var(--ufw-space-2); margin-left: auto; }
/* The "?" that opens what a page or a card is for. */
.ufw-help-q {
  display: inline-flex; align-items: center; justify-content: center; position: relative; vertical-align: middle;
  width: 20px; height: 20px; padding: 0; margin: 0 0 0 var(--ufw-space-1);
  font-family: var(--ufw-font); font-size: var(--ufw-text-xs); font-weight: 700; line-height: 1;
  color: var(--ufw-ink-2); background: var(--ufw-surface); border: 1px solid var(--ufw-control-line);
  border-radius: var(--ufw-radius-pill); cursor: pointer;
}
/* A finger's reach round it on a touchscreen, its look as small as it is. */
.ufw-help-q::after { content: ""; position: absolute; inset: -12px; }
.ufw-help-q:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus); outline-offset: var(--ufw-focus-offset); }
@media (hover: hover) { .ufw-help-q:hover { border-color: var(--ufw-pine-700); color: var(--ufw-pine-700); } }

/* --- 4 tabs, segmented, chip, tag ---------------------------------------------------------------------------------------- */

.ufw-tabs { display: flex; flex-wrap: wrap; gap: 0 var(--ufw-space-1); margin: 0 0 var(--ufw-space-4); border-bottom: 1px solid var(--ufw-rule); font-family: var(--ufw-font); }
.ufw-tabs__tab {
  display: inline-flex; align-items: center; min-height: var(--ufw-target); padding: 0 var(--ufw-space-3); margin: 0 0 -1px;
  font-size: var(--ufw-text-md); font-weight: 600; color: var(--ufw-ink-2); text-decoration: none;
  background: none; border: 0; border-bottom: 3px solid transparent; cursor: pointer;
}
.ufw-tabs__tab[aria-current="page"], .ufw-tabs__tab[aria-current="true"], .ufw-tabs__tab[aria-selected="true"] { color: var(--ufw-brand); border-bottom-color: var(--ufw-pine-700); }
.ufw-tabs__tab:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus); outline-offset: calc(var(--ufw-focus-width) * -1); }
.ufw-tabs__tab:disabled { opacity: .45; cursor: not-allowed; }
@media (hover: hover) { .ufw-tabs__tab:hover:not([aria-current="page"]):not([aria-current="true"]):not([aria-selected="true"]) { color: var(--ufw-ink); border-bottom-color: var(--ufw-rule); } }

.ufw-segmented {
  display: inline-flex; padding: 3px; gap: 3px; background: var(--ufw-sunken);
  border: 1px solid var(--ufw-rule); border-radius: var(--ufw-radius-control); font-family: var(--ufw-font);
}
.ufw-segmented__option {
  min-height: calc(var(--ufw-target) - 8px); padding: 0 var(--ufw-space-3);
  font-family: var(--ufw-font); font-size: var(--ufw-text-sm); font-weight: 600; color: var(--ufw-ink-2);
  background: none; border: 1px solid transparent; border-radius: var(--ufw-radius-control); cursor: pointer;
}
@media (pointer: coarse) { .ufw-segmented__option { min-height: var(--ufw-target); } }
.ufw-segmented__option[aria-checked="true"], .ufw-segmented__option[aria-pressed="true"] {
  color: var(--ufw-brand); background: var(--ufw-surface); border-color: var(--ufw-pine-700);
}
.ufw-segmented__option:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus); outline-offset: var(--ufw-focus-offset); }
.ufw-segmented__option:disabled { opacity: .45; cursor: not-allowed; }

.ufw-chip {
  display: inline-flex; align-items: center; gap: var(--ufw-space-1); min-height: var(--ufw-target-small);
  padding: 0 var(--ufw-space-3); margin: 0;
  font-family: var(--ufw-font); font-size: var(--ufw-text-sm); font-weight: 600; color: var(--ufw-ink-2);
  background: var(--ufw-surface); border: 1px solid var(--ufw-control-line); border-radius: var(--ufw-radius-pill); cursor: pointer;
}
.ufw-chip[aria-pressed="true"] { color: var(--ufw-brand); background: var(--ufw-pine-50); border-color: var(--ufw-pine-700); }
/* A chip whose count is something late: the state's colours, whatever it filters or goes to. */
.ufw-chip--blocked { color: var(--ufw-blocked); background: var(--ufw-blocked-wash); border-color: var(--ufw-blocked); }
.ufw-chip__count { font-weight: 400; color: var(--ufw-ink-3); }
.ufw-chip:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus); outline-offset: var(--ufw-focus-offset); }
.ufw-chip:disabled { opacity: .45; cursor: not-allowed; }
@media (hover: hover) { .ufw-chip:hover:not(:disabled):not([aria-pressed="true"]) { border-color: var(--ufw-pine-600); } }
/* A chip that goes somewhere says so: its words and a trailing →. */
.ufw-chip--link { text-decoration: none; }
.ufw-chip--link::after { content: "→"; }

/* A kind of thing — an appointment's kind — with its dot: static, never a pill's shape (no fill, no rounded box). */
.ufw-tag { display: inline-flex; align-items: center; gap: 6px; font-family: var(--ufw-font); font-size: var(--ufw-text-label); font-weight: 600; color: var(--ufw-ink-2); }
.ufw-tag__dot { flex: none; width: 8px; height: 8px; border-radius: var(--ufw-radius-pill); background: var(--ufw-ink-3); }

/* --- 5 card ----------------------------------------------------------------------------------------------------------------- */

.ufw-card {
  display: block; box-sizing: border-box; margin: 0 0 var(--ufw-space-4); padding: var(--ufw-space-4);
  font-family: var(--ufw-font); color: var(--ufw-ink); background: var(--ufw-surface);
  border: 1px solid var(--ufw-rule); border-radius: var(--ufw-radius-card); box-shadow: var(--ufw-shadow-card);
}
.ufw-card__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--ufw-space-2); margin: 0 0 var(--ufw-space-3); }
.ufw-card__overline { flex-basis: 100%; margin: 0; font-size: var(--ufw-text-xs); font-weight: 700; letter-spacing: var(--ufw-label-spacing); text-transform: uppercase; color: var(--ufw-ink-3); }
.ufw-card__title { margin: 0; font-size: var(--ufw-text-lg); font-weight: 600; line-height: var(--ufw-leading-tight); color: var(--ufw-ink); }
.ufw-card__body > :first-child { margin-top: 0; }
.ufw-card__body > :last-child { margin-bottom: 0; }
/* The whole card a link: its › at the right, a tint when pressed (and when a mouse is over it). */
.ufw-card--link { display: flex; align-items: center; gap: var(--ufw-space-3); text-decoration: none; cursor: pointer; }
.ufw-card--link > .ufw-card__head, .ufw-card--link > .ufw-card__body { flex: 1 1 auto; min-width: 0; }
.ufw-card--link > .ufw-card__head { margin-bottom: 0; }
.ufw-card--link > .ufw-chevron { margin-left: auto; }
.ufw-card--link:active { background: var(--ufw-pine-50); }
.ufw-card--link:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus); outline-offset: var(--ufw-focus-offset); }
@media (hover: hover) { .ufw-card--link:hover { border-color: var(--ufw-pine-600); background: var(--ufw-surface-2); } }
/* Not yet open to this person: dashed, no shadow. */
.ufw-card--locked { border-style: dashed; box-shadow: none; background: var(--ufw-surface-2); }

/* --- 6 tile ----------------------------------------------------------------------------------------------------------------- */

.ufw-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--ufw-space-3); margin: 0 0 var(--ufw-space-4); }
.ufw-tile {
  display: grid; align-content: start; gap: 2px; box-sizing: border-box; min-height: var(--ufw-target); margin: 0;
  padding: var(--ufw-space-3) var(--ufw-space-4); text-align: left;
  font-family: var(--ufw-font); color: var(--ufw-ink); background: var(--ufw-surface);
  border: 1px solid var(--ufw-rule); border-radius: var(--ufw-radius-card);
}
.ufw-tile__label { font-size: var(--ufw-text-xs); font-weight: 700; letter-spacing: var(--ufw-label-spacing); text-transform: uppercase; color: var(--ufw-ink-3); }
.ufw-tile__figure { font-size: var(--ufw-text-figure); font-weight: 700; line-height: var(--ufw-leading-tight); font-variant-numeric: tabular-nums; color: var(--ufw-ink); }
.ufw-tile__figure--ready { color: var(--ufw-ready); }
.ufw-tile__figure--waiting { color: var(--ufw-waiting); }
.ufw-tile__figure--blocked { color: var(--ufw-blocked); }
.ufw-tile__figure--done { color: var(--ufw-done); }
.ufw-tile__figure--quiet { color: var(--ufw-ink-2); }
.ufw-tile__note { font-size: var(--ufw-text-sm); color: var(--ufw-ink-3); }
/* A tile that acts says so at rest, the same under a finger as under a mouse: the control's darker edge and the ›. A tile
   that only counts has neither. One way, whether it filters the page (a button, chosen by aria-pressed) or goes to one
   (an <a>: --goes). */
.ufw-tile--filter, .ufw-tile--goes { position: relative; padding-right: var(--ufw-space-8); border-color: var(--ufw-control-line); }
.ufw-tile--filter::after, .ufw-tile--goes::after { content: "›"; position: absolute; top: 50%; right: var(--ufw-space-3); transform: translateY(-50%); font-size: var(--ufw-text-xl); line-height: 1; color: var(--ufw-pine-700); }
.ufw-tile--filter { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.ufw-tile--filter[aria-pressed="true"] { background: var(--ufw-pine-50); border-color: var(--ufw-pine-700); }
.ufw-tile--filter[aria-pressed="true"] .ufw-tile__label { color: var(--ufw-pine-700); }
.ufw-tile--filter:active { background: var(--ufw-pine-50); }
.ufw-tile--filter:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus); outline-offset: var(--ufw-focus-offset); }
.ufw-tile--filter:disabled { opacity: .45; cursor: not-allowed; }
@media (hover: hover) { .ufw-tile--filter:hover:not(:disabled):not([aria-pressed="true"]) { border-color: var(--ufw-pine-600); } }

/* --- 7 row ------------------------------------------------------------------------------------------------------------------ */

.ufw-rows { margin: 0 0 var(--ufw-space-4); padding: 0; list-style: none; border-top: 1px solid var(--ufw-rule-soft); }
.ufw-rows > li { margin: 0; border-bottom: 1px solid var(--ufw-rule-soft); }
/* A row that opens: the whole row a link, its ›, a tint when pressed. */
.ufw-row-link {
  display: flex; align-items: center; gap: var(--ufw-space-3); min-height: var(--ufw-target);
  padding: var(--ufw-space-2) var(--ufw-space-2); font-family: var(--ufw-font); color: var(--ufw-ink); text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
/* A row that opens on a page with no address to go to (the iPad's): a button, drawn the same. */
button.ufw-row-link { box-sizing: border-box; width: 100%; margin: 0; background: none; border: 0; border-radius: 0; text-align: left; cursor: pointer; }
.ufw-row-link:active { background: var(--ufw-pine-50); }
.ufw-row-link:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus); outline-offset: calc(var(--ufw-focus-width) * -1); }
@media (hover: hover) { .ufw-row-link:hover { background: var(--ufw-surface-2); } }
.ufw-row-link__main { display: grid; flex: 1 1 auto; min-width: 0; }
.ufw-row-link__title { font-size: var(--ufw-text-md); font-weight: 600; color: var(--ufw-ink); overflow-wrap: anywhere; }
.ufw-row-link__meta { font-size: var(--ufw-text-sm); color: var(--ufw-ink-3); }
.ufw-row-link__aside { flex: none; font-size: var(--ufw-text-sm); color: var(--ufw-ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* A row with its own actions: the name a link, small buttons at the right (each stops the row's own click). */
.ufw-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ufw-space-2) var(--ufw-space-3); min-height: var(--ufw-target); padding: var(--ufw-space-2); font-family: var(--ufw-font); }
.ufw-row__main { flex: 1 1 192px; min-width: 0; }
.ufw-row__actions { display: flex; flex-wrap: wrap; gap: var(--ufw-space-2); margin-left: auto; }

/* --- 8 link ----------------------------------------------------------------------------------------------------------------- */

.ufw-link { color: var(--ufw-pine-700); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; position: relative; }
.ufw-link:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus); outline-offset: var(--ufw-focus-offset); }
@media (hover: hover) { .ufw-link:hover { color: var(--ufw-brand); } }
.ufw-link--on-dark { color: var(--ufw-on-brand); }
.ufw-link--on-dark:focus-visible { outline-color: var(--ufw-focus-on-dark); }
@media (hover: hover) { .ufw-link--on-dark:hover { color: var(--ufw-on-brand); } }
/* A link in a line of words: on a touchscreen, a finger's reach, 44px tall whatever the size of its words, centred on
   them — its look as it is. (An inset of -12px reached 43px over 16px words; the stage F builder's find. Where two links
   sit on lines one under the other, the customer's cards make each a box of its own instead: ui/customer.css.) */
@media (pointer: coarse) {
  .ufw-link::after, .ufw-btn--link::after { content: ""; position: absolute; left: -4px; right: -4px; top: 50%; height: 44px; margin-top: -22px; }
}

/* --- 9 pill ----------------------------------------------------------------------------------------------------------------- */

.ufw-pill {
  display: inline-block; padding: 3px 9px; font-family: var(--ufw-font); font-size: var(--ufw-text-label); font-weight: 600;
  line-height: var(--ufw-leading-tight); white-space: nowrap; border-radius: var(--ufw-radius-pill);
  color: var(--ufw-ink-2); background: var(--ufw-rule-soft);
}
.ufw-pill--ready { color: var(--ufw-ready); background: var(--ufw-ready-wash); }
.ufw-pill--waiting { color: var(--ufw-waiting); background: var(--ufw-waiting-wash); }
.ufw-pill--blocked { color: var(--ufw-blocked); background: var(--ufw-blocked-wash); }
.ufw-pill--done { color: var(--ufw-done); background: var(--ufw-done-wash); }
.ufw-pill--quiet { color: var(--ufw-ink-2); background: var(--ufw-rule-soft); }

/* --- 10 notice and banner ------------------------------------------------------------------------------------------------- */

.ufw-notice {
  display: block; margin: 0 0 var(--ufw-space-4); padding: var(--ufw-space-3) var(--ufw-space-4);
  font-family: var(--ufw-font); font-size: var(--ufw-text-md); line-height: var(--ufw-leading); color: var(--ufw-ink);
  background: var(--ufw-pine-50); border-left: 4px solid var(--ufw-pine-600); border-radius: var(--ufw-radius-control);
}
.ufw-notice--info { background: var(--ufw-pine-50); border-left-color: var(--ufw-pine-600); }
.ufw-notice__title { display: block; font-weight: 700; }
.ufw-notice__text { display: block; }
.ufw-notice--success { background: var(--ufw-ready-wash); border-left-color: var(--ufw-ready); }
.ufw-notice--warning { background: var(--ufw-waiting-wash); border-left-color: var(--ufw-waiting); }
.ufw-notice--danger { background: var(--ufw-blocked-wash); border-left-color: var(--ufw-blocked); }
.ufw-notice--danger .ufw-notice__title { color: var(--ufw-blocked); }
/* Worth saying, nothing to act on: no wash, a quiet edge. */
.ufw-notice--quiet { background: transparent; border-left-color: var(--ufw-rule); }
/* The office's three banners at the top of a page (a ticket, a sent email, a stop): the width of the page, one line. */
.ufw-banner { display: block; margin: 0; padding: var(--ufw-space-3) var(--ufw-space-5); font-family: var(--ufw-font); font-size: var(--ufw-text-md); font-weight: 600; color: var(--ufw-on-brand); background: var(--ufw-pine-700); }
.ufw-banner--danger { background: var(--ufw-blocked); }
.ufw-banner--warning { color: var(--ufw-ink); background: var(--ufw-waiting-wash); border-bottom: 1px solid var(--ufw-waiting); }
.ufw-banner a { color: inherit; text-decoration: underline; }
.ufw-banner a:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus-on-dark); outline-offset: var(--ufw-focus-offset); }
.ufw-banner--warning a:focus-visible { outline-color: var(--ufw-focus); }

/* --- 11 empty --------------------------------------------------------------------------------------------------------------- */

.ufw-empty {
  margin: 0 0 var(--ufw-space-4); padding: var(--ufw-space-6) var(--ufw-space-4); text-align: center;
  font-family: var(--ufw-font); color: var(--ufw-ink-2); background: var(--ufw-surface);
  border: 1px dashed var(--ufw-control-line); border-radius: var(--ufw-radius-card);
}
.ufw-empty__title { margin: 0 0 var(--ufw-space-1); font-size: var(--ufw-text-lg); font-weight: 600; color: var(--ufw-ink); }
.ufw-empty__text { margin: 0 auto; max-width: 512px; font-size: var(--ufw-text-md); }
.ufw-empty__action { margin: var(--ufw-space-3) 0 0; }

/* A quiet line where a list would be: nothing there, or a thing in passing. Not a box: that is .ufw-empty. */
.ufw-quiet { font-size: var(--ufw-text-sm); color: var(--ufw-ink-3); }

/* --- 12 section title and sum ---------------------------------------------------------------------------------------------- */

.ufw-section-title {
  margin: var(--ufw-space-6) 0 var(--ufw-space-3); padding: 0 0 var(--ufw-space-1);
  font-family: var(--ufw-font); font-size: var(--ufw-text-xs); font-weight: 700; letter-spacing: var(--ufw-label-spacing);
  text-transform: uppercase; color: var(--ufw-pine-700); border-bottom: 1px solid var(--ufw-rule);
}
.ufw-sum {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--ufw-space-4); margin: 0;
  padding: var(--ufw-space-2) 0; font-family: var(--ufw-font); font-size: var(--ufw-text-md); color: var(--ufw-ink);
  border-bottom: 1px solid var(--ufw-rule-soft);
}
.ufw-sum__label { color: var(--ufw-ink-2); }
.ufw-sum__figure { font-variant-numeric: tabular-nums; white-space: nowrap; }
.ufw-sum--strong { font-weight: 700; border-bottom: 0; border-top: 2px solid var(--ufw-ink); }
.ufw-sum--strong .ufw-sum__label { color: var(--ufw-ink); }

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

.ufw-table-wrap { overflow-x: auto; margin: 0 0 var(--ufw-space-4); -webkit-overflow-scrolling: touch; }
.ufw-table { width: 100%; border-collapse: collapse; font-family: var(--ufw-font); font-size: var(--ufw-text-table); color: var(--ufw-ink); }
.ufw-table th {
  padding: var(--ufw-space-2) var(--ufw-space-3) var(--ufw-space-2) 0; text-align: left; vertical-align: bottom;
  font-size: var(--ufw-text-xs); font-weight: 700; letter-spacing: var(--ufw-label-spacing); text-transform: uppercase;
  color: var(--ufw-ink-3); border-bottom: 1px solid var(--ufw-rule);
}
/* A row's own heading (th scope="row") reads as the row's name, not as a column's heading. */
.ufw-table tbody th { font-size: inherit; font-weight: 600; letter-spacing: 0; text-transform: none; color: inherit; vertical-align: top; border-bottom-color: var(--ufw-rule-soft); }
.ufw-table td { padding: var(--ufw-space-2) var(--ufw-space-3) var(--ufw-space-2) 0; vertical-align: top; border-bottom: 1px solid var(--ufw-rule-soft); }
.ufw-table caption { padding: 0 0 var(--ufw-space-2); text-align: left; font-size: var(--ufw-text-sm); color: var(--ufw-ink-3); }
/* A number: right, same-width digits, never wrapped — in the face of the words (no monospace money). */
.ufw-num, .ufw-table .ufw-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ufw-table .ufw-num:last-child, .ufw-table th:last-child, .ufw-table td:last-child { padding-right: 0; }
.ufw-table__none { color: var(--ufw-ink-3); text-align: center; }
/* A row that opens (its first cell a .ufw-row-link): the hover is the row's. */
@media (hover: hover) { .ufw-table tr.ufw-table__opens:hover > td { background: var(--ufw-surface-2); } }

/* --- 14 sheet (ui/sheet.js, stage D3) ------------------------------------------------------------------------------------- */

.ufw-sheet {
  box-sizing: border-box; width: min(512px, calc(100vw - 32px)); max-height: calc(100vh - 32px); margin: auto; padding: 0;
  font-family: var(--ufw-font); color: var(--ufw-ink); background: var(--ufw-surface);
  border: 0; border-radius: var(--ufw-radius-card); box-shadow: var(--ufw-shadow-sheet); overflow: auto;
}
.ufw-sheet::backdrop { background: var(--ufw-backdrop); }
.ufw-sheet--wide { width: min(768px, calc(100vw - 32px)); }
.ufw-sheet__head { display: flex; align-items: flex-start; gap: var(--ufw-space-3); padding: var(--ufw-space-4) var(--ufw-space-2) 0 var(--ufw-space-5); }
.ufw-sheet__title { flex: 1 1 auto; margin: 10px 0 0; font-size: var(--ufw-text-xl); font-weight: 700; line-height: var(--ufw-leading-tight); }
/* The one way to close, top right: 44px whatever the pointer. */
.ufw-sheet__close {
  flex: none; display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; padding: 0; margin: 0;
  font-family: var(--ufw-font); font-size: var(--ufw-text-2xl); line-height: 1; color: var(--ufw-ink-2);
  background: none; border: 0; border-radius: var(--ufw-radius-control); cursor: pointer;
}
.ufw-sheet__close:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus); outline-offset: calc(var(--ufw-focus-width) * -1); }
@media (hover: hover) { .ufw-sheet__close:hover { background: var(--ufw-sunken); color: var(--ufw-ink); } }
.ufw-sheet__body { padding: var(--ufw-space-3) var(--ufw-space-5) 0; font-size: var(--ufw-text-md); line-height: var(--ufw-leading); color: var(--ufw-ink-2); overflow-wrap: anywhere; }
.ufw-sheet__body > p { margin: 0 0 var(--ufw-space-3); }
.ufw-sheet__body .ufw-field { margin-top: var(--ufw-space-2); }
.ufw-sheet__foot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--ufw-space-2); padding: var(--ufw-space-4) var(--ufw-space-5) var(--ufw-space-5); }
/* While a sheet is open the page under it does not scroll. */
.ufw-sheet-open { overflow: hidden; }

/* --- 15 toast ----------------------------------------------------------------------------------------------------------------- */

.ufw-toast {
  position: fixed; left: 50%; bottom: calc(var(--ufw-space-6) + env(safe-area-inset-bottom, 0px)); z-index: var(--ufw-z-toast);
  display: flex; align-items: center; gap: var(--ufw-space-3); max-width: calc(100vw - 32px); box-sizing: border-box;
  padding: var(--ufw-space-3) var(--ufw-space-4); transform: translateX(-50%);
  font-family: var(--ufw-font); font-size: var(--ufw-text-md); font-weight: 600; color: var(--ufw-on-brand);
  background: var(--ufw-pine-900); border-radius: var(--ufw-radius-control); box-shadow: var(--ufw-shadow-raised);
  animation: ufw-toast-in var(--ufw-motion) var(--ufw-ease);
}
/* A paper printed with "Saved" still up: printing emits the document alone. */
@media print { .ufw-toast { display: none; } }
.ufw-toast__undo {
  min-height: var(--ufw-target-small); padding: 0 var(--ufw-space-2); margin: 0;
  font-family: var(--ufw-font); font-size: var(--ufw-text-md); font-weight: 700; color: var(--ufw-on-brand);
  background: none; border: 0; text-decoration: underline; cursor: pointer;
}
.ufw-toast__undo:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus-on-dark); outline-offset: var(--ufw-focus-offset); }
@keyframes ufw-toast-in { from { opacity: 0; transform: translate(-50%, 8px); } to { opacity: 1; transform: translateX(-50%); } }

/* --- 16 form foot ------------------------------------------------------------------------------------------------------------ */

.ufw-form-foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ufw-space-2); margin: var(--ufw-space-5) 0 0; padding: var(--ufw-space-4) 0 0; border-top: 1px solid var(--ufw-rule); }
.ufw-form-foot__gap { flex: 1 1 auto; }
/* The iPad: kept at the foot of the screen while the form scrolls under it. */
.ufw-form-foot--sticky {
  position: sticky; bottom: 0; z-index: var(--ufw-z-bar); margin: var(--ufw-space-5) calc(var(--ufw-space-4) * -1) 0;
  padding: var(--ufw-space-3) var(--ufw-space-4) calc(var(--ufw-space-3) + env(safe-area-inset-bottom, 0px)); background: var(--ufw-surface);
}

/* --- 17 notes ----------------------------------------------------------------------------------------------------------------- */

.ufw-notes { display: grid; gap: var(--ufw-space-2); font-family: var(--ufw-font); }
.ufw-notes__add { display: flex; justify-content: flex-end; }
.ufw-notes__log { margin: var(--ufw-space-2) 0 0; padding: 0; list-style: none; }
.ufw-notes__entry { margin: 0; padding: var(--ufw-space-2) 0 var(--ufw-space-2) var(--ufw-space-3); border-left: 3px solid var(--ufw-rule); white-space: pre-line; overflow-wrap: anywhere; }
.ufw-notes__entry + .ufw-notes__entry { margin-top: var(--ufw-space-2); }
.ufw-notes__when { display: block; font-size: var(--ufw-text-sm); color: var(--ufw-ink-3); }

/* --- 18 paper shell (an unsigned paper: the presentation, Your price, the written quote) ------------------------------------ */

.ufw-paper {
  box-sizing: border-box; max-width: 832px; margin: 0 auto; padding: var(--ufw-space-8) var(--ufw-space-8) var(--ufw-space-12);
  font-family: var(--ufw-font-paper); font-size: var(--ufw-text-lg); line-height: var(--ufw-leading); color: var(--ufw-ink);
  background: var(--ufw-surface); box-shadow: var(--ufw-shadow-raised);
}
.ufw-paper__title { margin: 0 0 var(--ufw-space-6); font-family: var(--ufw-font); font-size: var(--ufw-text-2xl); font-weight: 700; letter-spacing: var(--ufw-label-spacing); text-transform: uppercase; text-align: center; }
/* The sun's short rule under a paper's title (an accent, never a button). */
.ufw-paper__title::after { content: ""; display: block; width: 48px; height: 3px; margin: var(--ufw-space-3) auto 0; background: var(--ufw-brand-accent); }
.ufw-paper__section { margin: var(--ufw-space-6) 0 var(--ufw-space-2); padding: 0 0 var(--ufw-space-1) var(--ufw-space-2); font-family: var(--ufw-font); font-size: var(--ufw-text-xs); font-weight: 700; letter-spacing: var(--ufw-label-spacing); text-transform: uppercase; color: var(--ufw-pine-700); border-left: 3px solid var(--ufw-pine-700); }
@media print { .ufw-paper { max-width: none; padding: 0; box-shadow: none; } }
/* The presentation on the contract's own paper (stage H1, sales/quote-presentation.js presentPaperHtml): the letterhead,
   title, section headings, face and sheet are the contract's (src/contract-document.css, used as they are); what is the
   presentation's own — the last word under the payment table — set here. */
.ufw-present .quote-close { margin-top: var(--ufw-space-5); }

/* --- 19 customer shell (their pages: the portal, signing, a change order, the HOA packet, a link that has gone) ------------- */

.ufw-customer { margin: 0; min-height: 100vh; font-family: var(--ufw-font); font-size: var(--ufw-text-lg); line-height: var(--ufw-leading); color: var(--ufw-ink); background: var(--ufw-ground); }
/* The mark, the name in type beside it (a picture may not come), the number to ring at the right — one line on a phone,
   the name wrapping first; its edges the page's column on a wide screen. */
.ufw-customer__head {
  display: flex; align-items: center; gap: var(--ufw-space-3);
  padding: var(--ufw-space-2) max(var(--ufw-space-4), calc((100% - 704px) / 2 + var(--ufw-space-4)));
  background: var(--ufw-surface); border-bottom: 1px solid var(--ufw-rule);
}
.ufw-customer__logo { display: block; flex: none; height: 40px; width: auto; }
.ufw-customer__name { flex: 1 1 auto; min-width: 0; margin: 0; font-size: var(--ufw-text-lg); font-weight: 700; line-height: var(--ufw-leading-tight); color: var(--ufw-brand); }
.ufw-customer__phone {
  display: inline-flex; flex: none; align-items: center; min-height: 44px; margin-left: auto; font-weight: 600; color: var(--ufw-pine-700);
  text-decoration: underline; text-underline-offset: 2px; white-space: nowrap;
}
.ufw-customer__phone:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus); outline-offset: var(--ufw-focus-offset); }
.ufw-customer__main { box-sizing: border-box; max-width: 704px; margin: 0 auto; padding: var(--ufw-space-6) var(--ufw-space-4) var(--ufw-space-12); }
.ufw-customer__foot { padding: var(--ufw-space-5) var(--ufw-space-4); text-align: center; font-size: var(--ufw-text-sm); color: var(--ufw-ink-3); }

/* --- 21 rep bar (present mode: the rep's way back, never on the paper) ------------------------------------------------------ */

.ufw-rep-bar { display: flex; align-items: center; gap: var(--ufw-space-3); min-height: 52px; padding: 0 var(--ufw-space-4); font-family: var(--ufw-font); background: var(--ufw-brand); color: var(--ufw-on-brand); }
.ufw-rep-bar__back {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--ufw-space-2); margin-left: calc(var(--ufw-space-2) * -1);
  font-family: var(--ufw-font); font-size: var(--ufw-text-md); font-weight: 600; color: var(--ufw-on-brand);
  background: none; border: 0; border-radius: var(--ufw-radius-control); text-decoration: none; cursor: pointer;
}
.ufw-rep-bar__back:focus-visible { outline: var(--ufw-focus-width) solid var(--ufw-focus-on-dark); outline-offset: var(--ufw-focus-offset); }
/* The way back's ‹, drawn here so the button's words are its own ("Back to the quote") — every screen's one bar alike. */
.ufw-rep-bar__back::before { content: "‹"; margin-right: var(--ufw-space-2); font-size: var(--ufw-text-xl); line-height: 1; }
/* In present mode: at the top of the screen, the paper under it — the room the bar's own, nothing of the paper's moved. */
body.present-mode .ufw-rep-bar { margin: 0 0 var(--ufw-space-4); border-radius: var(--ufw-radius-control); }
@media print { .ufw-rep-bar { display: none; } }

/* --- 22 glove (the crew's phone: the same components, a gloved finger's size) ---------------------------------------------- */

.ufw-glove { font-size: var(--ufw-text-glove); }
.ufw-glove .ufw-btn, .ufw-glove .ufw-input, .ufw-glove .ufw-select, .ufw-glove .ufw-check, .ufw-glove .ufw-row-link,
.ufw-glove .ufw-segmented__option, .ufw-glove .ufw-chip, .ufw-glove .ufw-tile--filter { min-height: var(--ufw-target-glove); }
.ufw-glove .ufw-btn { font-size: var(--ufw-text-glove); }
.ufw-glove .ufw-card, .ufw-glove .ufw-tile, .ufw-glove .ufw-empty { border-radius: var(--ufw-radius-card); }
.ufw-glove .ufw-check input { width: 28px; height: 28px; }

/* --- 23 small helpers ------------------------------------------------------------------------------------------------- */

/* What was a style="…" on one element (stage I; the ratchet bans the attribute). Each says one thing, and each wins as the
 * attribute did, whatever else is on the element — and a display helper never over a [hidden]. Nothing new is built from
 * these: a screen that needs a look it does not have gets a component. */
.ufw-between { justify-content: space-between !important; }
.ufw-big { font-size: 1.35em !important; }
.ufw-col { flex-direction: column !important; }
/* Screen only: print hides what it hides with display: none !important (.no-print, button, the chrome around a paper), which an
 * inline display never beat and a helper at 0,2,0 with !important would. Nothing printed leans on these (stage I's audit). */
@media screen {
  .ufw-d-block:not([hidden]) { display: block !important; }
  .ufw-d-flex:not([hidden]) { display: flex !important; }
}
.ufw-flex-1 { flex: 1 !important; }
.ufw-flex-2 { flex: 2 !important; }
.ufw-gap-6 { gap: 6px !important; }
.ufw-gap-8 { gap: var(--ufw-space-2) !important; }
.ufw-gap-10 { gap: 10px !important; }
.ufw-gap-12 { gap: var(--ufw-space-3) !important; }
.ufw-gap-16 { gap: var(--ufw-space-4) !important; }
.ufw-gap-26 { gap: 26px !important; }
.ufw-items-baseline { align-items: baseline !important; }
.ufw-items-center { align-items: center !important; }
.ufw-items-end { align-items: flex-end !important; }
.ufw-items-start { align-items: flex-start !important; }
.ufw-left { text-align: left !important; }
.ufw-m-0 { margin: 0 !important; }
.ufw-m-0-0-10 { margin: 0 0 10px !important; }
.ufw-m-4-0-0-18 { margin: var(--ufw-space-1) 0 0 18px !important; }
.ufw-m-6-0 { margin: 6px 0 !important; }
.ufw-m-6-0-0 { margin: 6px 0 0 !important; }
.ufw-m-6-0-0-18 { margin: 6px 0 0 18px !important; }
.ufw-m-6-0-10 { margin: 6px 0 10px !important; }
.ufw-m-8-0-0-18 { margin: var(--ufw-space-2) 0 0 18px !important; }
.ufw-m-10-0-n4 { margin: 10px 0 -4px !important; }
.ufw-m-n6-0-10 { margin: -6px 0 10px !important; }
.ufw-maxw-220 { max-width: 220px !important; }
.ufw-maxw-320 { max-width: 320px !important; }
.ufw-mb-8 { margin-bottom: var(--ufw-space-2) !important; }
.ufw-mb-10 { margin-bottom: 10px !important; }
.ufw-mb-12 { margin-bottom: var(--ufw-space-3) !important; }
.ufw-mb-14 { margin-bottom: 14px !important; }
.ufw-minh-70 { min-height: 70px !important; }
.ufw-minw-200 { min-width: 200px !important; }
.ufw-ml-8 { margin-left: var(--ufw-space-2) !important; }
.ufw-mono { font-family: var(--ufw-font-mono) !important; }
.ufw-mt-0 { margin-top: 0 !important; }
.ufw-mt-3 { margin-top: 3px !important; }
.ufw-mt-4 { margin-top: var(--ufw-space-1) !important; }
.ufw-mt-6 { margin-top: 6px !important; }
.ufw-mt-8 { margin-top: var(--ufw-space-2) !important; }
.ufw-mt-10 { margin-top: 10px !important; }
.ufw-mt-12 { margin-top: var(--ufw-space-3) !important; }
.ufw-mt-14 { margin-top: 14px !important; }
.ufw-mt-16 { margin-top: var(--ufw-space-4) !important; }
.ufw-mt-18 { margin-top: 18px !important; }
.ufw-muted { color: var(--ufw-ink-3) !important; }
.ufw-pointer { cursor: pointer !important; }
.ufw-prewrap { white-space: pre-wrap !important; }
.ufw-right { text-align: right !important; }
.ufw-text-label { font-size: var(--ufw-text-label) !important; }
.ufw-text-xl { font-size: var(--ufw-text-xl) !important; }
.ufw-w-110 { width: 110px !important; }
.ufw-w-500 { font-weight: 500 !important; }
.ufw-w-auto { width: auto !important; }
.ufw-w-full { width: 100% !important; }
.ufw-wrap { flex-wrap: wrap !important; }
.ufw-text-blocked { color: var(--ufw-blocked) !important; }
.ufw-text-ready { color: var(--ufw-ready) !important; }
.ufw-thumb { width: 100px; height: auto; border-radius: var(--ufw-radius-control); }
.ufw-zoom-in { cursor: zoom-in; }
