/* ============================================================================
   xw-controls.css — the ONE definition of every interactive control.
   Transcribed from Guide Page Wireframes, turn 38 (cards 38a-38g).

   WHY THIS FILE EXISTS
   --------------------
   Before this, control colours were written inline, page by page: roughly 390
   hardcoded hex occurrences across the customer surface, with no shared source.
   That is how a system drifts — two pages disagree about what "primary" is, and
   nobody can say which one is wrong. Every value below is copied from turn 38,
   so this file is the answer to "what colour should this button be?".

   THE RULE THAT GOVERNS ALL OF IT (38a)
   -------------------------------------
   A control's colour is decided by WHAT IT DOES, not by how important it looks.

     violet  #7C3AED  acts        add, book, request a quote, submit
     blue    #2563EB  informs     read the guide, see all results, navigate
     green   #15803D  confirms    added, paid, credited, live, settled price
     amber   #B45309  warns       not covered, expiring, offline
     red     #DC2626  destroys    cancel a job, delete an account
     ink     #111111  neutral     secondary and cancel

   And the boundaries, which matter more than the permissions:
     - violet NEVER on a link, a tab, or anything reversible by scrolling
     - blue   NEVER on a button that changes data
     - green  NEVER as a call to action. Green reports, it does not ask
     - amber  NEVER on anything routine. It must stay rare to keep working
     - red    NEVER filled, until a typed confirmation has been given
     - ink    NEVER two solids side by side

   Two hues on one screen is normal. Three means something is mislabelled.

   USAGE
   -----
     <button class="xw-btn xw-btn--violet xw-btn--md">Add</button>
     <button class="xw-btn xw-btn--ink xw-btn--outline xw-btn--md">Cancel</button>
     <button class="xw-btn xw-btn--violet xw-btn--lg xw-btn--full">Request a quote</button>

   Hue class sets the colour. Variant class (--solid is the default, so it may be
   omitted) sets the weight. Size class sets the geometry.
   ============================================================================ */

/* ── Scrollbar gutter: the page must never move when a modal opens ────────────
   Every modal on this site locks the background so it cannot scroll behind the
   overlay. The old way to do that was `overflow:hidden` on <html>, which also
   DELETES the scrollbar — and on a desktop the scrollbar occupies real width
   (~15px on Windows). Removing it widens the viewport, so:

     - page content reflows ~15px wider,
     - and every `position:fixed` overlay grows with it, moving its own centre
       ~7px to the right.

   That is why a dialog appeared to land centred, then visibly slid left as it
   closed and the scrollbar came back. Padding the <body> hid half of it (body
   content stopped moving) but could never fix the overlay, because a fixed
   element is measured against the viewport, not against the body.

   The fix is to stop the width from ever changing:

     overflow-y: scroll      the scrollbar track is ALWAYS painted, even on a
                             short page and even while the background is locked,
                             so it never appears or disappears.
     scrollbar-gutter: stable  belt and braces — the gutter stays reserved even
                             if some code sets `overflow:hidden` on <html>, so a
                             lock we have not routed through the shared helper
                             still cannot shift the page.

   With the width pinned, modals lock by taking <body> out of flow
   (position:fixed) alone — see assets/js/xw-scroll-lock.js. No compensating
   padding is needed anywhere, and none should be re-added: with the gutter
   reserved, padding would push content the OTHER way.

   Overlay-scrollbar platforms (macOS, iOS, Android) reserve no width at all,
   so both rules are inert there and nothing looks different. */
html {
  overflow-y: scroll;
  scrollbar-gutter: stable;
}

:root {
  /* ---- 38a / 38b : the six hues, four values each ---- */
  --xw-violet:        #7c3aed;
  --xw-violet-dark:   #6d28d9;   /* pressed, and tint/outline/ghost text */
  --xw-violet-tint:   #f5f3ff;
  --xw-violet-border: #ddd6fe;

  --xw-blue:          #2563eb;
  --xw-blue-dark:     #1d4ed8;
  --xw-blue-tint:     #eff6ff;
  --xw-blue-border:   #bfdbfe;

  --xw-green:         #15803d;
  --xw-green-dark:    #166534;
  --xw-green-tint:    #f0fdf4;
  --xw-green-border:  #bbf7d0;

  --xw-amber:         #b45309;
  --xw-amber-dark:    #92400e;
  --xw-amber-tint:    #fffbeb;
  --xw-amber-border:  #fde68a;

  --xw-red:           #dc2626;
  --xw-red-dark:      #b91c1c;
  --xw-red-tint:      #fef2f2;
  --xw-red-border:    #fecaca;

  --xw-ink:           #111111;
  --xw-ink-dark:      #242424;
  --xw-ink-tint:      #f8f9fa;
  --xw-ink-border:    #e5e7eb;

  /* ---- neutrals ---- */
  --xw-surface:       #ffffff;
  --xw-line:          #e5e7eb;   /* the standard border */
  --xw-line-soft:     #f3f4f6;   /* hairline dividers, and the disabled fill */
  --xw-line-input:    #d1d5db;   /* unchecked checkbox / radio border ONLY */
  --xw-text:          #374151;   /* body copy, icon glyphs, ink ghost */
  --xw-text-soft:     #6b7280;   /* descriptions, inactive tabs */
  --xw-text-mute:     #9ca3af;   /* mono labels, disabled text, counts */
  --xw-band:          #101010;   /* dark tab band (pro portal) */
  --xw-band-mute:     #8b9099;   /* inactive tab on the dark band only */

  /* ---- disabled is hue-blind: a disabled control carries no meaning,
          so it is given no colour to carry it with (38b) ---- */
  --xw-disabled-bg:     #f3f4f6;
  --xw-disabled-border: #e5e7eb;
  --xw-disabled-text:   #9ca3af;

  /* ---- radii, one per role (38c) ---- */
  --xw-r-xs:      6px;
  --xw-r-sm:      7px;
  --xw-r-control: 8px;   /* md AND lg both — a big button is the same object scaled */
  --xw-r-status:  9px;
  --xw-r-band:    10px;
  --xw-r-card:    12px;
  --xw-r-frame:   14px;
  --xw-r-pill:    999px;

  /* ---- type ---- */
  --xw-font-ui:   'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --xw-font-disp: 'Manrope', system-ui, sans-serif;
  --xw-font-mono: 'JetBrains Mono', ui-monospace, monospace;

  /* ---- rating glyph: a REGISTERED EXCEPTION, not a seventh hue ----
     A star is not a control and it carries none of the six meanings: it does not
     act, inform, confirm, warn or destroy. It was being drawn in three different
     colours across the portal (#f59e0b, #b45309, and a Tailwind gold), which is
     worse than any one of them. One value, named, so it stops being invented.

     It may ONLY paint a rating glyph or a rating bar. It is not available to a
     button, a badge, a border or any text. If you reach for it for anything
     else, the answer is one of the six. */
  --xw-star: #f59e0b;

  /* ---- decorative surfaces: REGISTERED EXCEPTIONS, like --xw-star ----
     Neither is a control and neither carries one of the six meanings. They are
     the ground behind an image that has not loaded. Flattening them to a system
     grey would be wrong -- the warm tint reads as "a photo belongs here" and the
     green-grey reads as "a map belongs here" -- but leaving them as loose hexes
     scattered across four stylesheets was how they drifted in the first place.
     Named here so they are deliberate. Not available to any control. */
  --xw-photo: #eef0e9;   /* behind a service or portfolio image */
  --xw-map:   #e9efe6;   /* behind a map that has not drawn yet */

  /* ---- elevation ---- */
  --xw-shadow-seg:    0 1px 2px rgba(0,0,0,.05);
  --xw-shadow-sticky: 0 -4px 14px rgba(0,0,0,.07);
}

/* ══════════════════════════════════════════════════════════════════════════
   BUTTON — base geometry. Only colour changes across the 6x8 matrix (38b);
   geometry is frozen, which is what makes a mixed grid readable.
   ══════════════════════════════════════════════════════════════════════════ */
.xw-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  border: 1px solid transparent;
  border-radius: var(--xw-r-control);
  padding: 12px 18px;                       /* md, the default */
  font: 600 12.5px var(--xw-font-ui);
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
  -webkit-appearance: none;
  appearance: none;
  /* No transition is specified by turn 38. A short one is added here because a
     control that changes colour instantly reads as a repaint rather than a
     response; it is deliberately below the threshold where it feels animated. */
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
@media (prefers-reduced-motion: reduce) {
  .xw-btn { transition: none; }
}

/* ---- sizes (38c). Heights: xs 28 / sm 34 / md 42 / lg 50 ---- */
.xw-btn--xs { border-radius: var(--xw-r-xs); padding: 7px 12px;  font-size: 11px; }
.xw-btn--sm { border-radius: var(--xw-r-sm); padding: 9px 14px;  font-size: 11.5px; }
.xw-btn--md { border-radius: var(--xw-r-control); padding: 12px 18px; font-size: 12.5px; }
.xw-btn--lg { border-radius: var(--xw-r-control); padding: 15px 22px; font-size: 14px; gap: 9px; }

/* Full width. On mobile this is the default for anything page-level (38f). */
.xw-btn--full { width: 100%; }

/* Pill, for filters and switches only. Never in the same group as a square
   button — that reads as two different systems on one card (38g, rule 6). */
.xw-btn--pill { border-radius: var(--xw-r-pill); }

/* ---- VIOLET · acts ---- */
.xw-btn--violet                  { background: var(--xw-violet); border-color: var(--xw-violet); color: #fff; }
.xw-btn--violet:active,
.xw-btn--violet.is-pressed       { background: var(--xw-violet-dark); border-color: var(--xw-violet-dark); }
.xw-btn--violet.xw-btn--tint     { background: var(--xw-violet-tint); border-color: var(--xw-violet-border); color: var(--xw-violet-dark); }
.xw-btn--violet.xw-btn--outline  { background: var(--xw-surface); border-color: var(--xw-violet-border); color: var(--xw-violet-dark); }
.xw-btn--violet.xw-btn--ghost    { background: transparent; border-color: transparent; color: var(--xw-violet-dark); }

/* ---- BLUE · informs and navigates ---- */
.xw-btn--blue                    { background: var(--xw-blue); border-color: var(--xw-blue); color: #fff; }
.xw-btn--blue:active,
.xw-btn--blue.is-pressed         { background: var(--xw-blue-dark); border-color: var(--xw-blue-dark); }
.xw-btn--blue.xw-btn--tint       { background: var(--xw-blue-tint); border-color: var(--xw-blue-border); color: var(--xw-blue-dark); }
.xw-btn--blue.xw-btn--outline    { background: var(--xw-surface); border-color: var(--xw-blue-border); color: var(--xw-blue-dark); }
.xw-btn--blue.xw-btn--ghost      { background: transparent; border-color: transparent; color: var(--xw-blue-dark); }

/* ---- GREEN · confirms and reports money. Never a call to action. ---- */
.xw-btn--green                   { background: var(--xw-green); border-color: var(--xw-green); color: #fff; }
.xw-btn--green:active,
.xw-btn--green.is-pressed        { background: var(--xw-green-dark); border-color: var(--xw-green-dark); }
.xw-btn--green.xw-btn--tint      { background: var(--xw-green-tint); border-color: var(--xw-green-border); color: var(--xw-green-dark); }
.xw-btn--green.xw-btn--outline   { background: var(--xw-surface); border-color: var(--xw-green-border); color: var(--xw-green-dark); }
.xw-btn--green.xw-btn--ghost     { background: transparent; border-color: transparent; color: var(--xw-green-dark); }

/* ---- "₹0 to book" ------------------------------------------------------- */
/* The money model as a figure rather than a sentence. Prose in this position
   was true and skipped; the reader's question is "am I committing to this?",
   and a visible zero answers it where a caption does not. Green because it
   reports money and is never a call to action — the rule directly above. */
.xw-free-chip { display: inline-flex; align-items: center;
                background: var(--xw-green-tint); border: 1px solid var(--xw-green-border);
                color: var(--xw-green-dark); border-radius: var(--xw-r-pill, 999px);
                padding: 3px 9px; font: 600 10.5px/1.3 var(--xw-font-ui, 'Inter', sans-serif);
                white-space: nowrap; }

/* ---- AMBER · warns ---- */
.xw-btn--amber                   { background: var(--xw-amber); border-color: var(--xw-amber); color: #fff; }
.xw-btn--amber:active,
.xw-btn--amber.is-pressed        { background: var(--xw-amber-dark); border-color: var(--xw-amber-dark); }
.xw-btn--amber.xw-btn--tint      { background: var(--xw-amber-tint); border-color: var(--xw-amber-border); color: var(--xw-amber-dark); }
.xw-btn--amber.xw-btn--outline   { background: var(--xw-surface); border-color: var(--xw-amber-border); color: var(--xw-amber-dark); }
.xw-btn--amber.xw-btn--ghost     { background: transparent; border-color: transparent; color: var(--xw-amber-dark); }

/* ---- RED · destroys. Outlined by default; solid only after a typed
        confirmation (38a, and 38g rule 3). ---- */
.xw-btn--red                     { background: var(--xw-surface); border-color: var(--xw-red-border); color: var(--xw-red-dark); }
.xw-btn--red.xw-btn--solid       { background: var(--xw-red); border-color: var(--xw-red); color: #fff; }
.xw-btn--red.xw-btn--solid:active,
.xw-btn--red.xw-btn--solid.is-pressed { background: var(--xw-red-dark); border-color: var(--xw-red-dark); }
.xw-btn--red.xw-btn--tint        { background: var(--xw-red-tint); border-color: var(--xw-red-border); color: var(--xw-red-dark); }
.xw-btn--red.xw-btn--outline     { background: var(--xw-surface); border-color: var(--xw-red-border); color: var(--xw-red-dark); }
.xw-btn--red.xw-btn--ghost       { background: transparent; border-color: transparent; color: var(--xw-red-dark); }

/* ---- INK · neutral. Note the ghost is #374151, NOT #111111 — a full-strength
        ink ghost reads as a heading rather than a control (38b). ---- */
.xw-btn--ink                     { background: var(--xw-ink); border-color: var(--xw-ink); color: #fff; }
.xw-btn--ink:active,
.xw-btn--ink.is-pressed          { background: var(--xw-ink-dark); border-color: var(--xw-ink-dark); }
.xw-btn--ink.xw-btn--tint        { background: var(--xw-ink-tint); border-color: var(--xw-ink-border); color: var(--xw-ink-dark); }
.xw-btn--ink.xw-btn--outline     { background: var(--xw-surface); border-color: var(--xw-ink-border); color: var(--xw-ink); }
.xw-btn--ink.xw-btn--ghost       { background: transparent; border-color: transparent; color: var(--xw-text); }

/* ---- disabled beats every hue ---- */
.xw-btn:disabled,
.xw-btn[disabled],
.xw-btn.is-disabled {
  background: var(--xw-disabled-bg) !important;
  border-color: var(--xw-disabled-border) !important;
  color: var(--xw-disabled-text) !important;
  cursor: not-allowed;
  pointer-events: none;
}

/* ---- focus. Turn 38 defines no focus ring; one is required for keyboard use,
        so it is drawn in the control's own hue rather than a browser default. ---- */
.xw-btn:focus-visible {
  outline: 2px solid var(--xw-violet);
  outline-offset: 2px;
}
.xw-btn--blue:focus-visible  { outline-color: var(--xw-blue); }
.xw-btn--green:focus-visible { outline-color: var(--xw-green); }
.xw-btn--amber:focus-visible { outline-color: var(--xw-amber); }
.xw-btn--red:focus-visible   { outline-color: var(--xw-red); }
.xw-btn--ink:focus-visible   { outline-color: var(--xw-ink); }

/* ---- loading. Ring is 3/4 faded with one bright quarter (38b). ---- */
.xw-spin {
  flex: none;
  width: 12.5px;
  height: 12.5px;
  border-radius: 50%;
  border: 2px solid rgba(255,255,255,.35);
  border-top-color: #fff;
  animation: xw-spin .7s linear infinite;
}
.xw-btn--tint .xw-spin,
.xw-btn--outline .xw-spin,
.xw-btn--ghost .xw-spin {
  border-color: rgba(0,0,0,.15);
  border-top-color: currentColor;
}
@keyframes xw-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .xw-spin { animation: none; } }

/* ══════════════════════════════════════════════════════════════════════════
   ICON BUTTON (38c) — 36px, square or circle
   ══════════════════════════════════════════════════════════════════════════ */
.xw-ico {
  width: 36px; height: 36px;
  border-radius: var(--xw-r-control);
  border: 1px solid var(--xw-line);
  background: var(--xw-surface);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; color: var(--xw-text);
  cursor: pointer; flex: none; position: relative;
  -webkit-appearance: none; appearance: none;
}
.xw-ico--circle { border-radius: 50%; }
.xw-ico--violet { border-color: var(--xw-violet-border); background: var(--xw-violet-tint); color: var(--xw-violet); }
.xw-ico--blue   { border-color: var(--xw-blue-border);   background: var(--xw-blue-tint);   color: var(--xw-blue); }
.xw-ico--green  { border-color: var(--xw-green-border);  background: var(--xw-green-tint);  color: var(--xw-green); }
.xw-ico--amber  { border-color: var(--xw-amber-border);  background: var(--xw-amber-tint);  color: var(--xw-amber); }
.xw-ico--red    { border-color: var(--xw-red-border);    background: var(--xw-red-tint);    color: var(--xw-red); }
.xw-ico:focus-visible { outline: 2px solid var(--xw-violet); outline-offset: 2px; }

/* Count badge. The 2px white ring is what stops the badge border and the
   button border merging into one muddy line (38c). */
.xw-ico__count {
  position: absolute; top: -5px; right: -5px;
  min-width: 17px; height: 17px;
  border-radius: var(--xw-r-pill);
  /* BLUE, not violet. A count is a fact — it informs, it does not act — and this
     badge is rendered twice on every phone page: on the header cart button and
     inside #mobile-bottom-nav. Violet there put the system's strongest "commit"
     hue permanently into navigation, which rule 5 forbids outright, and it did
     it on an element the customer cannot even press. */
  background: var(--xw-blue);
  border: 2px solid #fff;
  display: flex; align-items: center; justify-content: center;
  font: 600 9px var(--xw-font-mono); color: #fff;
}
.xw-ico__dot {
  position: absolute; top: -3px; right: -3px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--xw-amber); border: 2px solid #fff;
}

/* ══════════════════════════════════════════════════════════════════════════
   TABS AND SWITCHERS (38d) — shape is chosen by what the tabs DO
   ══════════════════════════════════════════════════════════════════════════ */

/* segmented · 2-3 exclusive modes */
.xw-seg {
  display: inline-flex;
  background: var(--xw-ink-tint);
  border: 1px solid var(--xw-line);
  border-radius: var(--xw-r-pill);
  padding: 4px; gap: 4px;
}
.xw-seg__item {
  border: 0; border-radius: var(--xw-r-pill);
  padding: 8px 15px; background: transparent;
  font: 500 11.5px var(--xw-font-ui); color: var(--xw-text-soft);
  white-space: nowrap; cursor: pointer;
}
.xw-seg__item.is-active {
  background: var(--xw-surface);
  box-shadow: var(--xw-shadow-seg);
  font-weight: 600; color: var(--xw-ink);
}

/* counted pills · filters. Ink active by default; violet only when filtering
   IS the action rather than a view change (38d). */
.xw-cpill {
  display: inline-flex; align-items: center; gap: 7px;
  border-radius: var(--xw-r-pill); padding: 8px 14px;
  background: var(--xw-ink-tint); border: 1px solid var(--xw-line);
  white-space: nowrap; cursor: pointer;
}
.xw-cpill__label { font: 600 11.5px var(--xw-font-ui); color: var(--xw-text); }
.xw-cpill__count { font: 600 9.5px var(--xw-font-mono); color: var(--xw-text-mute); }
.xw-cpill.is-active { background: var(--xw-ink); border-color: var(--xw-ink); }
.xw-cpill.is-active .xw-cpill__label { color: #fff; }
.xw-cpill.is-active .xw-cpill__count { color: rgba(255,255,255,.7); }
.xw-cpill.is-active.xw-cpill--violet { background: var(--xw-violet); border-color: var(--xw-violet); }

/* underline · page sections. Drawn with inset box-shadow, NOT border-bottom,
   so inactive tabs keep identical geometry and the row never shifts 2px when
   selection moves (38d). */
.xw-tabs { display: flex; align-items: center; gap: 22px; border-bottom: 1px solid var(--xw-line); }
.xw-tabs__item {
  border: 0; background: none; cursor: pointer;
  padding: 0 0 11px; box-shadow: none;
  font: 500 12.5px var(--xw-font-ui); color: var(--xw-text-soft);
  white-space: nowrap;
}
.xw-tabs__item.is-active {
  box-shadow: inset 0 -2px 0 var(--xw-blue);
  font-weight: 600; color: var(--xw-blue-dark);
}
/* on a dark band */
.xw-tabs--dark { background: var(--xw-band); border-radius: var(--xw-r-band); padding: 16px 18px 0; border-bottom: 0; }
.xw-tabs--dark .xw-tabs__item { color: var(--xw-band-mute); }
.xw-tabs--dark .xw-tabs__item.is-active { box-shadow: inset 0 -2px 0 #fff; color: #fff; }

/* rail · sibling navigation */
.xw-rail { border: 1px solid var(--xw-line); border-radius: var(--xw-r-card); overflow: hidden; background: var(--xw-surface); }
.xw-rail__item {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 14px; background: var(--xw-surface);
  border-top: 1px solid var(--xw-line-soft);
  font: 500 12px var(--xw-font-ui); color: var(--xw-text);
  text-decoration: none; cursor: pointer;
}
.xw-rail__item:first-child { border-top: 0; }
/* INK, not violet. A rail is sibling NAVIGATION, and both 38f ("navigation never
   takes a hue") and rule 5 forbid violet there -- violet is the commit hue, and a
   selected nav row commits nothing. This was my own error in the first draft of
   this file; the account rail and the bottom nav were already correctly ink, so
   the canonical sheet was the thing out of step, not the pages. */
.xw-rail__item.is-active { background: var(--xw-ink-tint); font-weight: 600; color: var(--xw-ink); }

/* scrolling row · mobile filters. One step smaller than desktop. */
.xw-scrollrow { display: flex; gap: 7px; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.xw-scrollrow::-webkit-scrollbar { display: none; }
.xw-scrollrow > * { flex: none; }
.xw-scrollrow .xw-cpill { padding: 8px 13px; gap: 6px; }
.xw-scrollrow .xw-cpill__label { font-size: 11px; }
.xw-scrollrow .xw-cpill__count { font-size: 9px; }

/* ══════════════════════════════════════════════════════════════════════════
   SWITCHES, CHOICES, BADGES, STATUS (38e)
   ══════════════════════════════════════════════════════════════════════════ */
.xw-toggle {
  width: 42px; height: 24px; border-radius: var(--xw-r-pill);
  background: var(--xw-line); padding: 3px;
  display: inline-flex; justify-content: flex-start;
  flex: none; cursor: pointer; border: 0;
  transition: background-color .15s ease, justify-content 0s;
}
.xw-toggle__knob { width: 18px; height: 18px; border-radius: 50%; background: #fff; display: block; }
.xw-toggle.is-on { justify-content: flex-end; background: var(--xw-green); }   /* green = live */
.xw-toggle.is-on.xw-toggle--violet { background: var(--xw-violet); }           /* violet = a preference */
@media (prefers-reduced-motion: reduce) { .xw-toggle { transition: none; } }

/* A checked box FILLS with the hue; a checked radio takes the hue only on its
   border and dot, so a column of radios does not read as a block of colour. */
.xw-check {
  width: 18px; height: 18px; border-radius: 5px;
  background: var(--xw-surface); border: 1.5px solid var(--xw-line-input);
  display: inline-flex; align-items: center; justify-content: center;
  font: 400 10px var(--xw-font-ui); color: transparent; flex: none; cursor: pointer;
}
.xw-check.is-checked { background: var(--xw-violet); border-color: var(--xw-violet); color: #fff; }
.xw-check.is-checked.xw-check--blue  { background: var(--xw-blue);  border-color: var(--xw-blue); }
.xw-check.is-checked.xw-check--green { background: var(--xw-green); border-color: var(--xw-green); }

.xw-radio {
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--xw-surface); border: 1.5px solid var(--xw-line-input);
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; cursor: pointer;
}
.xw-radio__dot { width: 8px; height: 8px; border-radius: 50%; background: transparent; display: block; }
.xw-radio.is-checked { border-color: var(--xw-violet); }
.xw-radio.is-checked .xw-radio__dot { background: var(--xw-violet); }
.xw-radio.is-checked.xw-radio--blue { border-color: var(--xw-blue); }
.xw-radio.is-checked.xw-radio--blue .xw-radio__dot { background: var(--xw-blue); }

/* badges — a tint triple, always */
.xw-badge {
  display: inline-flex; align-items: center;
  border-radius: var(--xw-r-pill); padding: 4px 10px;
  font: 600 10px var(--xw-font-ui); border: 1px solid;
  white-space: nowrap;
}
.xw-badge--blue  { background: var(--xw-blue-tint);  border-color: var(--xw-blue-border);  color: var(--xw-blue-dark); }
.xw-badge--green { background: var(--xw-green-tint); border-color: var(--xw-green-border); color: var(--xw-green-dark); }
.xw-badge--amber { background: var(--xw-amber-tint); border-color: var(--xw-amber-border); color: var(--xw-amber-dark); }
.xw-badge--red   { background: var(--xw-red-tint);   border-color: var(--xw-red-border);   color: var(--xw-red-dark); }
.xw-badge--ink   { background: var(--xw-ink-tint);   border-color: var(--xw-ink-border);   color: var(--xw-ink-dark); }

/* status row — a FACT, not a control. It carries no affordance; if it needs an
   action, the action sits outside it (38e). */
.xw-status {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 14px; border-radius: var(--xw-r-status);
  border: 1px solid;
}
.xw-status__dot  { width: 6px; height: 6px; border-radius: 50%; flex: none; }
.xw-status__text { flex: 1; font: 500 11.5px var(--xw-font-ui); }
.xw-status__key  { font: 500 9.5px var(--xw-font-mono); }
.xw-status--green { background: var(--xw-green-tint); border-color: var(--xw-green-border); color: var(--xw-green-dark); }
.xw-status--green .xw-status__dot { background: var(--xw-green); }
.xw-status--blue  { background: var(--xw-blue-tint);  border-color: var(--xw-blue-border);  color: var(--xw-blue-dark); }
.xw-status--blue  .xw-status__dot { background: var(--xw-blue); }
.xw-status--amber { background: var(--xw-amber-tint); border-color: var(--xw-amber-border); color: var(--xw-amber-dark); }
.xw-status--amber .xw-status__dot { background: var(--xw-amber); }
.xw-status--red   { background: var(--xw-red-tint);   border-color: var(--xw-red-border);   color: var(--xw-red-dark); }
.xw-status--red   .xw-status__dot { background: var(--xw-red); }

/* inline link — a 1px tinted underline, not the browser's */
.xw-link {
  color: var(--xw-blue-dark); font-weight: 600; text-decoration: none;
  box-shadow: inset 0 -1px 0 var(--xw-blue-border);
}
.xw-link:hover { box-shadow: inset 0 -1px 0 var(--xw-blue); }

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE (38f) — anything page-level is lg and full width. Buttons only hug
   their label inside a row, where a full-width button would be absurd.
   ══════════════════════════════════════════════════════════════════════════ */
.xw-stack { display: flex; flex-direction: column; gap: 10px; }   /* pairs stack, never side by side */

.xw-stickybar {
  background: var(--xw-surface);
  border-top: 1px solid var(--xw-line);
  box-shadow: var(--xw-shadow-sticky);
  padding: 11px 14px;
  display: flex; align-items: center; gap: 12px;
}

/* Navigation never takes a hue — a violet bottom bar would make every screen
   look like it wanted something (38f). */
.xw-bottomnav__item        { font: 500 9px var(--xw-font-ui); color: var(--xw-text-mute); }
.xw-bottomnav__item.is-active { font-weight: 600; color: var(--xw-ink); }

@media (max-width: 640px) {
  .xw-btn--page { width: 100%; border-radius: var(--xw-r-control); padding: 15px 22px; font-size: 14px; gap: 9px; }
}
