/* VertiServices — the UI kit (sprint ui-kit-foundation, K0, 8 Oct 2026)

   ONE shared CSS language for every page: one component per family, reading
   one set of tokens, so that one CSS change reflects on every page (operator,
   8 Oct 2026). Linked by every product page right AFTER style.css, with the
   same ?v= token; precached beside it in sw.js. Never @import'ed (rule E1).

   K0 (this sprint) defines TOKENS ONLY and points nothing visible at them:
   no product page changes by a pixel because this file exists (proven with
   scripts/visual-diff.mjs). style.css keeps every rule it has. The family
   sweeps move the components in here, one family per sprint:

     K1 buttons  ->  K2 filter chips + segmented choice  ->  K3 badges
     ->  page buckets (estimates, portal, installation-followup, projects,
         map, then 3-6 pages a sprint)  ->  tables LAST, in their own sprint(s)

   Operator decisions already taken for those sweeps (8 Oct 2026, mockup
   "UI Kit — Ortak Dil"): (a) the primary button is FLAT NAVY, the gradient
   stays on the page header band only (applied in K1); (b) a filter chip is ONE
   pill shape whose height comes from --chip-h, 32 px on a desk and 44 px on a
   phone, and the segmented single choice has the same height in an r10
   container (applied in K2); (c) the customer-facing pages (sign.html,
   privacy.html) load this file too, with the letterhead pixel-identical.

   THE RATCHET. scripts/check-kit-ratchet.mjs counts, per product page, the
   page-local CSS that styles a kit family (buttons, chips, tabs, badges,
   fields, modals/sheets, cards, empty/loading/toast, the page header) - in
   its <style>, in style="" attributes, and in CSS its modules inject - and
   FAILS when a count rises or a new page is not at zero. A rule that must
   stay local says so in its own body: kit-exempt, a colon and the reason, in
   a CSS comment. Table rules are counted in a family of their own and only
   reported until the table sprint. docs/design-system.md, "UI kit".

   TOKENS. Every value below is today's value of the thing it names: the
   heights and radii are the ones the approved mockup drew, the tones are
   today's badge and alert colours (style.css .badge-*, .alert.*), so a sweep
   that points a component at a token moves no colour by accident. */

:root {
  /* Control heights. --ctl-h is a button / input / house dropdown; -sm is the
     compact one (a table row action, a table filter chip); --chip-h is a
     filter chip and a segmented choice; --tab-h a tab. */
  --ctl-h: 34px;
  --ctl-h-sm: 28px;
  --chip-h: 32px;
  --tab-h: 36px;

  /* Radii: a control, a pill (chip, badge), a segmented container. */
  --radius-ctl: 8px;
  --radius-pill: 999px;
  --radius-seg: 10px;

  /* The keyboard focus ring, in the navy's channels (--verti-navy-rgb). */
  --focus-ring: 0 0 0 3px rgba(var(--verti-navy-rgb), .28);

  /* Badge tones - a status maps to a TONE, never to a colour of its own.
       ok       .badge-status-on
       warn     .alert.warning (table.data tr.row-warn's background)
       danger   .alert.error   (table.data tr.row-danger's background)
       info     .badge-technician / -type-elevator / -work-maintenance
       neutral  .badge-viewer / -type-other / -work-meeting
       brand    the navy on its 50 tint */
  --tone-ok-bg: #D9F1E4;
  --tone-ok-fg: #1E6C49;
  --tone-warn-bg: #FBF2DA;
  --tone-warn-fg: #6E5318;
  --tone-danger-bg: #FBE9E9;
  --tone-danger-fg: #8C2A2A;
  --tone-info-bg: #DCEAF7;
  --tone-info-fg: #214E7E;
  --tone-neutral-bg: #E8ECF2;
  --tone-neutral-fg: #495568;
  --tone-brand-bg: var(--verti-navy-50);
  --tone-brand-fg: var(--verti-navy);

  /* A registered brand shape (rule Z1 reads any --brand-gradient* declaration
     as the register, check-page-conformance.mjs): the three-stop 90 degree
     navy -> purple -> orange, the strip under sign.html's brand bar. It is
     NOT --brand-gradient (that one holds the navy to 20 %), and the signing
     page must look exactly as it did, so its hand-written copy became this
     name rather than the house gradient. Written from the colour tokens. */
  --brand-gradient-3stop: linear-gradient(90deg, var(--verti-navy) 0%, var(--tke-purple) 55%, var(--tke-orange) 100%);

  /* The four role badges keep today's colours as tokens of their own
     (style.css .badge-admin / -manager / -technician / -viewer). */
  --role-admin-bg: #FCE3D9;
  --role-admin-fg: #9C3712;
  --role-manager-bg: #E7E0F2;
  --role-manager-fg: #4F2D6F;
  --role-tech-bg: #DCEAF7;
  --role-tech-fg: #214E7E;
  --role-viewer-bg: #E8ECF2;
  --role-viewer-fg: #495568;
}

/* The phone. Below 700 px is the fleet's phone everywhere a component already
   switches: the house dropdown opens its sheet (house-select.js PHONE_BELOW),
   the house sheet rises from the bottom edge instead of centring (style.css,
   .mobile-sheet at min-width 700px). A touch target is 44 px there. */
@media (max-width: 699.98px) {
  :root {
    --ctl-h: 44px;
    --chip-h: 44px;
    --tab-h: 44px;
  }
}
/* A phone page (body.mobile-body - the mobile-shell pages) is a phone at any
   width: its controls keep the 44 px tap target even when the page is opened
   on a desk (sprint ui-kit-buttons, K1). */
.mobile-body { --ctl-h: 44px; }

/* ===========================================================================
   BUTTONS (K1, sprint ui-kit-buttons, 8 Oct 2026; mockup "UI Kit - Ortak
   Dil", Buttons family). ONE button, defined here and nowhere else: a page
   writes the class name, never its own copy (the ratchet holds the button
   family at its floor - scripts/check-kit-ratchet.mjs, FAIL).

     .btn                 primary - FLAT NAVY (operator decision a); hover
                          --verti-navy-700. The brand gradient stays on the
                          page header band only (house rule B9).
     .btn-ghost           white, a rim, navy text - the secondary action
     .btn-danger          red fill - a destructive confirm
     .btn-ghost.btn-danger  red text on white - an undo, a cancel, a remove
     .btn-accent          TKE orange - the page's one "new" action
     .btn-ok / .btn-go    green (finish, approve) / amber (start, do it now) -
                          the field states the shared row button carried
                          (style.css .fr-btn.ok / .go, hotfix billable-jobs-ui)
     .btn-sm              --ctl-h-sm (28 px) - a compact toolbar / row action
     .btn-icon            square, icon only (keep the aria-label)
     .btn-block           full width
   States: :hover, :focus-visible (the --focus-ring), :active, :disabled,
   [aria-busy="true"] (working: full strength, progress cursor), offline
   (shell.js's [data-requires-online] guard), [hidden].

   Height comes from --ctl-h: 34 px on a desk, 44 px on a phone (below 700 px
   and on every body.mobile-body page). min-height, not height, so a button in
   a stretching row still stretches as it always did, and on a phone a long
   label (the az one) WRAPS inside the button instead of overflowing its row.

   Older names that remain ALIASES of the kit button (markup keeps them; the
   look is the kit's): .btn.ghost / .small / .danger / .icon (the Sprint 183
   puantaj pages), and the shared row buttons that lived in style.css -
   .fr-btn (unit task, billable jobs), .pf-btn (the photo slots), .ft-btn (the
   field tools under a textarea), .pcc-btn (the project contacts card),
   .btn-ai-fix (the AI text fix) and the house sheet header's Save / Cancel
   (.mobile-sheet-act .sv / .cn). Print hides the header's buttons as before
   (style.css @media print).

   THE [hidden] TRAP, canonical statement (Sprint 718; see also .row,
   .mobile-h1-action, .msh-ttabs in style.css and .offline-chip in shell.js).
   The `hidden` attribute contributes exactly one thing: the USER-AGENT rule
   `[hidden] { display: none }`. Origin is resolved BEFORE specificity, so the
   author-origin `display: inline-flex` below beats it outright and a
   `<button class="btn" hidden>` stays fully visible. Every permission-gated
   create button in this app is written that way, which is how view-only users
   were being shown ecNew / sqNew / esNew / esImport. Hence every display rule
   here has its [hidden] twin.
   =========================================================================== */
.btn,
.fr-btn, .pf-btn, .ft-btn, .pcc-btn, .btn-ai-fix {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: var(--ctl-h);
  padding: 0 14px;
  border: 1px solid transparent;
  border-radius: var(--radius-ctl);
  background: var(--verti-navy);
  color: #fff;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 650;
  line-height: 1.25;
  letter-spacing: normal;
  text-transform: none;
  text-decoration: none;
  text-align: center;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .15s, border-color .15s, box-shadow .15s, transform .05s;
}
.btn[hidden], .fr-btn[hidden], .pf-btn[hidden], .ft-btn[hidden], .pcc-btn[hidden], .btn-ai-fix[hidden] { display: none; }
/* An <a class="btn"> is a button, not a link: no underline on hover either
   (style.css a:hover is (0,1,1)). */
.btn:hover { text-decoration: none; }
.btn:where(:not(:disabled)):hover,
.fr-btn.pri:where(:not(:disabled)):hover, .pf-btn.solid:where(:not(:disabled)):hover,
.ft-btn.btn-ai-fix:where(:not(:disabled)):hover, .btn-ai-fix:where(:not(:disabled)):hover { background: var(--verti-navy-700); border-color: transparent; }
.btn:focus-visible,
.fr-btn:focus-visible, .pf-btn:focus-visible, .ft-btn:focus-visible, .pcc-btn:focus-visible, .btn-ai-fix:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
.btn:where(:not(:disabled)):active,
.fr-btn:where(:not(:disabled)):active, .pf-btn:where(:not(:disabled)):active, .ft-btn:where(:not(:disabled)):active,
.pcc-btn:where(:not(:disabled)):active, .btn-ai-fix:where(:not(:disabled)):active { transform: translateY(1px); }
.btn:disabled,
.fr-btn:disabled, .pf-btn:disabled, .ft-btn:disabled, .pcc-btn:disabled, .btn-ai-fix:disabled { opacity: .5; cursor: not-allowed; }
/* hotfix items-sync-buttons: a button that is WORKING (aria-busy) is disabled
   against a second click but must not look dead - full strength, a spinning
   icon and a "Syncing..." label say "wait, it is running". */
.btn[aria-busy="true"]:disabled,
.fr-btn[aria-busy="true"]:disabled, .ft-btn[aria-busy="true"]:disabled,
.btn-ai-fix[aria-busy="true"]:disabled { opacity: 1; cursor: progress; }
/* Offline: shell.js's guard disables a [data-requires-online] control and adds
   its plug; on a button the look is the kit's disabled one. */
.btn[data-requires-online][data-offline-disabled] { opacity: .5; cursor: not-allowed; }

/* ghost - the secondary action */
.btn.btn-ghost, .btn.ghost,
.fr-btn, .pf-btn, .ft-btn, .pcc-btn {
  background: var(--surface);
  color: var(--verti-navy);
  border-color: var(--border);
}
.btn.btn-ghost:where(:not(:disabled)):hover, .btn.ghost:where(:not(:disabled)):hover,
.fr-btn:where(:not(:disabled)):hover, .pf-btn:where(:not(:disabled)):hover,
.ft-btn:where(:not(:disabled)):hover, .pcc-btn:where(:not(:disabled)):hover {
  background: var(--verti-navy-50);
  border-color: var(--verti-navy);
}
/* the primary of an aliased family */
.fr-btn.pri, .pf-btn.solid, .ft-btn.btn-ai-fix {
  background: var(--verti-navy);
  color: #fff;
  border-color: transparent;
}
/* danger - a red fill */
.btn.btn-danger, .btn.danger { background: var(--danger); color: #fff; }
.btn.btn-danger:where(:not(:disabled)):hover, .btn.danger:where(:not(:disabled)):hover { background: #B83C3C; }
/* danger ghost - red text on white: an undo, a cancel, a remove */
.btn.btn-ghost.btn-danger, .btn.danger.ghost, .fr-btn.bad {
  background: var(--surface);
  color: var(--danger);
  border-color: var(--border);
}
.btn.btn-ghost.btn-danger:where(:not(:disabled)):hover, .btn.danger.ghost:where(:not(:disabled)):hover,
.fr-btn.bad:where(:not(:disabled)):hover { background: #FBE9E9; border-color: var(--danger); }
/* accent - TKE orange */
.btn.btn-accent { background: var(--tke-orange); color: #fff; }
.btn.btn-accent:where(:not(:disabled)):hover { background: #C9491E; }
/* ok - green: finish, approve, complete */
.btn.btn-ok, .fr-btn.ok { background: #15803D; color: #fff; border-color: transparent; }
.btn.btn-ok:where(:not(:disabled)):hover, .fr-btn.ok:where(:not(:disabled)):hover { background: #116632; border-color: transparent; }
/* go - amber: start, do it now (#B45309 is 5.02:1 under white). A row button
   that is a TOGGLE (the Before-photo exit on the Billable Jobs phone) shows
   its pressed state in the same amber. */
.btn.btn-go, .fr-btn.go, .fr-btn[aria-pressed="true"] { background: #B45309; color: #fff; border-color: transparent; }
.btn.btn-go:where(:not(:disabled)):hover, .fr-btn.go:where(:not(:disabled)):hover,
.fr-btn[aria-pressed="true"]:where(:not(:disabled)):hover { background: #92400E; border-color: transparent; }

/* sizes */
.btn.btn-sm, .btn.small,
.ft-btn, .pcc-btn, .btn-ai-fix {
  min-height: var(--ctl-h-sm);
  padding: 0 10px;
  gap: 5px;
  font-size: 12.5px;
}
.btn.btn-icon, .btn.icon {
  width: var(--ctl-h);
  height: var(--ctl-h);
  min-width: var(--ctl-h);
  padding: 0;
}
.btn.btn-sm.btn-icon, .btn.small.icon {
  width: var(--ctl-h-sm);
  height: var(--ctl-h-sm);
  min-width: var(--ctl-h-sm);
}
.btn.btn-block { width: 100%; }
/* .btn-icon WITHOUT .btn is the older standalone square of Raw Records' row
   actions - a TABLE's, kept exactly as it was (32 px, white, a rim) until the
   table sprint makes those rows .btn.btn-ghost.btn-sm.btn-icon. */
.btn-icon:not(.btn) {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border: 1px solid var(--border);
  border-radius: var(--radius-ctl);
  background: #fff;
  cursor: pointer;
  font-size: 16px;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  color: var(--text);
}
.btn-icon:not(.btn):hover { background: var(--verti-navy-50); border-color: var(--verti-navy); }
.btn-icon:not(.btn).btn-icon-danger { color: var(--danger); }
.btn-icon:not(.btn).btn-icon-danger:hover { background: #FBE9E9; border-color: var(--danger); }
.btn-icon:not(.btn):disabled { opacity: 0.5; cursor: not-allowed; }
/* A button that shows an upload's progress (api.js uploadWithProgress: the
   Import buttons of projects, units, faults and service records) carries a
   .btn-progress-fill bar behind its .btn-label; while it runs it is disabled
   but not dimmed. */
.btn:has(> .btn-progress-fill) { position: relative; overflow: hidden; }
.btn:has(> .btn-progress-fill):disabled { opacity: 1; cursor: progress; }
.btn > .btn-progress-fill {
  position: absolute; left: 0; top: 0; bottom: 0; width: 0%;
  background: rgba(34, 197, 94, .30);
  transition: width .25s ease-out;
  pointer-events: none; z-index: 0;
}
.btn > .btn-label { position: relative; z-index: 1; }
/* The AI text fix sits INLINE beside a field's label: its 28 px box is pulled
   into the label's line (negative block margins) so the label row keeps its
   height - the button changed, the form did not. */
.btn-ai-fix { margin: -4px 0 -4px 8px; vertical-align: middle; }
.ft-btn.btn-ai-fix { margin: 0; }

/* The house sheet header's Save + Cancel pair (style.css .mobile-sheet-act):
   Save LEFT of Cancel, in the header, on the brand band - kit height, the
   white Save and the glass Cancel (the approved mockup's sheet header). */
.mobile-sheet-act button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 34px;
  padding: 0 13px;
  border: 0;
  border-radius: var(--radius-ctl);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 800;
  line-height: 1.25;
  white-space: nowrap;
  cursor: pointer;
}
.mobile-sheet-act button[hidden] { display: none; }
.mobile-sheet-act .sv { background: #fff; color: var(--verti-navy); }
.mobile-sheet-act .cn { background: rgba(255, 255, 255, .2); color: #fff; }
.mobile-sheet-act button:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(255, 255, 255, .45); }
.mobile-sheet-act button:disabled { opacity: .5; cursor: not-allowed; }

/* The phone: a long label wraps inside its button (two lines fit in 44 px)
   and a button never grows past its row. */
@media (max-width: 699.98px) {
  .btn,
  .fr-btn, .pf-btn, .ft-btn, .pcc-btn {
    max-width: 100%;
    white-space: normal;
    overflow-wrap: break-word;
  }
}

/* ---- K2 chips + segmented ---- */
/* ===========================================================================
   FILTER CHIPS + THE SEGMENTED CHOICE (K2, sprint ui-kit-chips, 8 Oct 2026;
   mockup "UI Kit - Ortak Dil", Filter chips family, operator decision b).
   ONE filter chip and ONE segmented single choice, defined here and nowhere
   else: a page writes the class name, never its own copy (the ratchet holds
   the chip family at its floor - scripts/check-kit-ratchet.mjs, FAIL).

     .mobile-chips        the chip row: wraps, 6 px gap (and the 12 px under
                          it the row always had)
     .mobile-chips.chips-scroll  a row that SCROLLS sideways instead of
                          wrapping (a phone strip that already scrolled)
     .mobile-chip         ONE PILL (--radius-pill), height --chip-h: 32 px on a
                          desk, 44 px on a phone (below 700 px and on every
                          body.mobile-body page) - the tap target
     .mobile-chip .chip-n a count inside the pill (tabular figures)
     .seg-choice          the segmented single choice, full width (a phone
                          sheet, a form): equal shares, a long label wraps
                          inside its own segment
     .seg-choice.inline   the desk form: content width
   The name is .mobile-chip, not a new .chip: the existing house chip was
   written by 5 product pages (mobile-finance, mobile-photo, projects,
   unit-photos, app-ui - through mobile-units.js and unit-detail-modal.js),
   while the two pages that own a local `.chip` (attendance's status chip,
   tasks' dismissible scope tag) use it for a badge and a tag, not a filter.

   STATE. Selected is the ARIA attribute - aria-pressed on a multi toggle,
   aria-checked on a single choice - read the same way on every page; .active
   and .on (the classes the older page scripts toggle) are its aliases, so a
   page's click handler stays as it was. Navy fill when selected (the house
   rule: a FILTER is VERTI NAVY when pressed; the gradient is the buttons').
   States: :hover (navy rim and ink), :focus-visible (--focus-ring), selected,
   :disabled (the kit's disabled look; no data-requires-online is added),
   [hidden]. The table's filter-row chip (.dt-chip, inside a th) is a TABLE
   element and keeps its look until the table sprint (style.css).
   =========================================================================== */
.mobile-body { --chip-h: 44px; }

/* THE COMPACT BUTTON ON A PHONE (K2, the Sef's addition to the brief, 8 Oct
   2026; house tap-target rule mobile.2). --ctl-h-sm (.btn-sm, .btn-sm.btn-icon)
   is 28 px on a desk and 44 px wherever --ctl-h is: below 700 px and on every
   body.mobile-body page. K1 left four page rules holding a compact button at a
   touch height (elevator-catalog's phone sheet, mobile-report's Retry,
   mobile-photo's Approve / Reject; portal's answer bar is a desk floor of
   regular buttons and stays) - the token holds them now. */
@media (max-width: 699.98px) {
  :root { --ctl-h-sm: 44px; }
}
.mobile-body { --ctl-h-sm: 44px; }
.mobile-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 0 12px; }
.mobile-chips[hidden] { display: none; }
.mobile-chips.chips-scroll {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.mobile-chips.chips-scroll::-webkit-scrollbar { display: none; }
.mobile-chips.chips-scroll > .mobile-chip { flex: none; }
.mobile-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  box-sizing: border-box;
  min-height: var(--chip-h);
  margin: 0;
  padding: 0 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: #374151;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.25;
  font-variant-numeric: tabular-nums;
  letter-spacing: normal;
  text-transform: none;
  text-decoration: none;
  text-align: center;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .15s, border-color .15s, color .15s, box-shadow .15s;
}
.mobile-chip[hidden] { display: none; }
/* hover is for a chip that is NOT selected: a pressed chip stays navy under the
   pointer, whatever order a page or the kit page's forced states put the rules in */
.mobile-chip:where(:not(:disabled):not([aria-pressed="true"]):not([aria-checked="true"]):not(.active):not(.on)):hover { border-color: var(--verti-navy); color: var(--verti-navy); text-decoration: none; }
.mobile-chip:hover { text-decoration: none; }
.mobile-chip:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.mobile-chip:is([aria-pressed="true"], [aria-checked="true"], .active, .on) {
  background: var(--verti-navy);
  border-color: var(--verti-navy);
  color: #fff;
}
.mobile-chip:disabled, .mobile-chip[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }
/* A label that can outgrow its row (a facet value, a site name) sits in a
   .chip-l and is cut with an ellipsis - only on a chip that carries the whole
   label in its title (the implied state "ellipsis only with a title"). */
.mobile-chip { max-width: 100%; }
.mobile-chip .chip-l { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* a count inside the pill or the segment: orange figures, white when selected */
:is(.mobile-chip, .seg-choice > button) .chip-n { font-weight: 800; color: var(--tke-orange); font-variant-numeric: tabular-nums; }
.mobile-chip:is([aria-pressed="true"], [aria-checked="true"], .active, .on) .chip-n,
.seg-choice > button:is([aria-checked="true"], [aria-pressed="true"], .on, .active) .chip-n { color: #fff; }

/* The segmented choice - ONE row of 2-5 options (operator: "ikili, uclu,
   dortlu"), the chosen one navy. Equal shares, and the automatic minimum of a
   flex item keeps the longest word whole: a long label wraps inside its own
   segment while the short ones give way. The font steps down by option count
   so five fit a Samsung A56 (360 px). NO default where the choice is the
   user's: an unanswered row wears .need until it is answered (house-sheet.js
   sheetMissing). The container is the r10 box (--radius-seg).
   HEIGHT (--seg-opt-h, the option's own height): on a desk the WHOLE control
   is --chip-h tall, as a chip beside it is (the option is --chip-h less the
   box's two 1 px rims: 30 + 2 = 32); on a phone (below 700 px and on every
   body.mobile-body page) each OPTION is the 44 px tap target itself, so the
   box is 46 - the house tap-target rule counts the thing you press. */
.seg-choice {
  --seg-opt-h: calc(var(--chip-h) - 2px);
  display: flex;
  width: 100%;
  box-sizing: border-box;
  margin: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-seg);
  overflow: hidden;
  background: var(--surface);
}
.mobile-body .seg-choice { --seg-opt-h: var(--chip-h); }
.seg-choice[hidden] { display: none; }
.seg-choice > button {
  flex: 1 1 0;
  min-height: var(--seg-opt-h);
  margin: 0;
  padding: 6px 6px;
  border: 0;
  border-right: 1px solid var(--border);
  border-radius: 0;
  background: var(--surface);
  color: var(--verti-navy);
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  white-space: normal;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .15s, color .15s, box-shadow .15s;
}
.seg-choice > button[hidden] { display: none; }
.seg-choice > button:last-child { border-right: 0; }
.seg-choice > button:where(:not(:disabled):not([aria-pressed="true"]):not([aria-checked="true"]):not(.active):not(.on)):hover { background: var(--verti-navy-50); }
.seg-choice > button:is([aria-checked="true"], [aria-pressed="true"], .on, .active) { background: var(--verti-navy); color: #fff; }
.seg-choice > button:focus-visible { outline: none; box-shadow: inset var(--focus-ring); }
.seg-choice > button:disabled { color: #A6AFBE; cursor: not-allowed; }
/* a choice that is shown but locked (estimates' read-only header) */
.seg-choice > button:is([aria-checked="true"], [aria-pressed="true"], .on, .active):disabled { background: #6B7588; color: #fff; }
.seg-choice:not(.inline):has(> button:nth-child(4)) > button { font-size: 11.5px; padding: 6px 4px; }
.seg-choice:not(.inline):has(> button:nth-child(5)) > button { font-size: 10.5px; padding: 6px 3px; }
.seg-choice.need { border: 1.4px dashed #B45309; }
/* The DESK form (sprint w7-desk-shell, the operator's W7 M2 A, 6 Oct 2026):
   content width, the same --chip-h and r10 box. Under a coarse pointer (a
   tablet at desk width) the options keep the 44 px tap target. */
.seg-choice.inline { display: inline-flex; width: auto; max-width: 100%; vertical-align: middle; }
.seg-choice.inline > button {
  flex: 0 0 auto;
  padding: 0 13px;
  white-space: nowrap;
}
@media (pointer: coarse) {
  .seg-choice.inline > button { min-height: 44px; }
}

/* The phone: a long label (the az one) wraps inside its pill or segment
   instead of pushing the page sideways, and a chip never grows past its row. */
@media (max-width: 699.98px) {
  .seg-choice { --seg-opt-h: var(--chip-h); }
  .mobile-chip { max-width: 100%; white-space: normal; overflow-wrap: break-word; }
  .mobile-chips.chips-scroll > .mobile-chip { max-width: none; white-space: nowrap; }
  .seg-choice.inline > button { flex: 1 1 auto; white-space: normal; }
  /* a choice wider than its row scrolls sideways inside its own box rather
     than cutting its last options off (faults' six sources at 360 px) */
  .seg-choice.inline { overflow-x: auto; scrollbar-width: none; }
  .seg-choice.inline::-webkit-scrollbar { display: none; }
}
