/* =============================================================================================
   SalX.UI — component styles
   Every selector is sx-prefixed, so this sheet is safe to load alongside MudBlazor from Phase 0.
   Components consume LAYER 2 tokens only, always with a fallback. This sheet must be
   self-contained: utilities.css is NOT loaded app-wide until cutover, so no component may rely
   on d-flex / gap-N / pa-N here.

   Contents, in tier order (the file grows by appending):
     Tier 1  tone + text-style classes · SxText · SxIcon · SxButton · SxIconButton · SxStack ·
             SxGrid/SxGridItem · SxSurface · SxDivider · SxSpacer · motifs (glass, grain, glow, focus)
     Tier 2  dialog · snackbar · popover host (menu / tooltip / popover) · overlay
     Tier 3  field chrome · text / numeric / select / checkbox / switch / radio · date + time pickers
     Tier 4  chip · alert · banner · spinner · progress bar · skeleton · avatar · badge
     Tier 5  layout · container · card · collapse · expansion · tabs · tables + sort + pager ·
             app bar · toolbar · drawer · nav menu · list · pagination · image · link · fab ·
             stepper · chat
     Tier 6  pinned columns + sticky footer + fill (the two data grids) · tree · pie chart ·
             sr-only
   ============================================================================================= */

/* ---------------------------------------------------------------------------------------------
   Tone → colour. `Tone.Default` sets nothing (inherit the surface's text colour).
   --------------------------------------------------------------------------------------------- */
.sx-tone-inherit  { color: inherit; }
.sx-tone-muted    { color: var(--sx-text-2, #4b5565); }
.sx-tone-accent   { color: var(--sx-accent-text, #1a63b3); }
.sx-tone-accent2  { color: var(--sx-accent2-text, #5b49c0); }
.sx-tone-numeric  { color: var(--sx-numeric-text, #0a6f5a); }
.sx-tone-success  { color: var(--sx-success-text, #136a42); }
.sx-tone-warning  { color: var(--sx-warning-text, #8a4b00); }
.sx-tone-danger   { color: var(--sx-danger-text, #b42f2f); }
.sx-tone-info     { color: var(--sx-info-text, #086a7c); }
.sx-tone-contrast { color: var(--sx-contrast-text, #f3f5f9); }

/* Tone ladder as custom properties — buttons, chips and any filled control read these. */
.sx-btn, .sx-icon-btn {
  --_base:        var(--sx-neutral, #e3e7ee);
  --_hover:       var(--sx-neutral-hover, #d6dbe5);
  --_pressed:     var(--sx-neutral-pressed, #c6ccd8);
  --_soft:        var(--sx-neutral-soft, rgba(16, 24, 40, 0.06));
  --_soft-border: var(--sx-neutral-soft-border, rgba(16, 24, 40, 0.16));
  --_text:        var(--sx-neutral-text, #151a24);
  --_on:          var(--sx-neutral-on, #151a24);
}
.sx-btn--t-muted, .sx-icon-btn--t-muted { --_text: var(--sx-text-2, #4b5565); }
.sx-btn--t-inherit, .sx-icon-btn--t-inherit {
  --_base: currentColor; --_hover: currentColor; --_pressed: currentColor;
  --_soft: color-mix(in srgb, currentColor 12%, transparent);
  --_soft-border: color-mix(in srgb, currentColor 32%, transparent);
  --_text: inherit; --_on: var(--sx-surface-1, #fff);
}
.sx-btn--t-accent, .sx-icon-btn--t-accent {
  --_base: var(--sx-accent, #1f6fc6); --_hover: var(--sx-accent-hover, #1a63b3); --_pressed: var(--sx-accent-pressed, #165699);
  --_soft: var(--sx-accent-soft, rgba(31, 111, 198, 0.1)); --_soft-border: var(--sx-accent-soft-border, rgba(31, 111, 198, 0.28));
  --_text: var(--sx-accent-text, #1a63b3); --_on: var(--sx-accent-on, #fff);
}
.sx-btn--t-accent2, .sx-icon-btn--t-accent2 {
  --_base: var(--sx-accent2, #6d5bd0); --_hover: var(--sx-accent2-hover, #5b49c0); --_pressed: var(--sx-accent2-pressed, #4d3daa);
  --_soft: var(--sx-accent2-soft, rgba(109, 91, 208, 0.1)); --_soft-border: var(--sx-accent2-soft-border, rgba(109, 91, 208, 0.28));
  --_text: var(--sx-accent2-text, #5b49c0); --_on: var(--sx-accent2-on, #fff);
}
.sx-btn--t-numeric, .sx-icon-btn--t-numeric {
  --_base: var(--sx-numeric, #0c8068); --_hover: var(--sx-numeric-hover, #0a6f5a); --_pressed: var(--sx-numeric-pressed, #085e4c);
  --_soft: var(--sx-numeric-soft, rgba(12, 128, 104, 0.1)); --_soft-border: var(--sx-numeric-soft-border, rgba(12, 128, 104, 0.3));
  --_text: var(--sx-numeric-text, #0a6f5a); --_on: var(--sx-text-on-status, #fff);
}
.sx-btn--t-success, .sx-icon-btn--t-success {
  --_base: var(--sx-success, #177a4d); --_hover: var(--sx-success-hover, #136a42); --_pressed: var(--sx-success-pressed, #105a38);
  --_soft: var(--sx-success-soft, rgba(23, 122, 77, 0.1)); --_soft-border: var(--sx-success-soft-border, rgba(23, 122, 77, 0.3));
  --_text: var(--sx-success-text, #136a42); --_on: var(--sx-text-on-status, #fff);
}
.sx-btn--t-warning, .sx-icon-btn--t-warning {
  --_base: var(--sx-warning, #a85d08); --_hover: var(--sx-warning-hover, #8a4b00); --_pressed: var(--sx-warning-pressed, #733e00);
  --_soft: var(--sx-warning-soft, rgba(168, 93, 8, 0.1)); --_soft-border: var(--sx-warning-soft-border, rgba(168, 93, 8, 0.3));
  --_text: var(--sx-warning-text, #8a4b00); --_on: var(--sx-text-on-status, #fff);
}
.sx-btn--t-danger, .sx-icon-btn--t-danger {
  --_base: var(--sx-danger, #c93a3a); --_hover: var(--sx-danger-hover, #b42f2f); --_pressed: var(--sx-danger-pressed, #9d2828);
  --_soft: var(--sx-danger-soft, rgba(201, 58, 58, 0.1)); --_soft-border: var(--sx-danger-soft-border, rgba(201, 58, 58, 0.3));
  --_text: var(--sx-danger-text, #b42f2f); --_on: var(--sx-text-on-status, #fff);
}
.sx-btn--t-info, .sx-icon-btn--t-info {
  --_base: var(--sx-info, #0b7a8f); --_hover: var(--sx-info-hover, #086a7c); --_pressed: var(--sx-info-pressed, #065a6a);
  --_soft: var(--sx-info-soft, rgba(11, 122, 143, 0.1)); --_soft-border: var(--sx-info-soft-border, rgba(11, 122, 143, 0.3));
  --_text: var(--sx-info-text, #086a7c); --_on: var(--sx-text-on-status, #fff);
}
.sx-btn--t-contrast, .sx-icon-btn--t-contrast {
  --_base: var(--sx-contrast-bg, #1f2533); --_hover: color-mix(in srgb, var(--sx-contrast-bg, #1f2533) 88%, var(--sx-contrast-text, #fff));
  --_pressed: color-mix(in srgb, var(--sx-contrast-bg, #1f2533) 78%, var(--sx-contrast-text, #fff));
  --_soft: color-mix(in srgb, var(--sx-contrast-bg, #1f2533) 12%, transparent); --_soft-border: color-mix(in srgb, var(--sx-contrast-bg, #1f2533) 32%, transparent);
  --_text: var(--sx-text-1, #151a24); --_on: var(--sx-contrast-text, #f3f5f9);
}

/* ---------------------------------------------------------------------------------------------
   TextStyle → type. One class per step. No colour here — Tone does colour.
   --------------------------------------------------------------------------------------------- */
.sx-text-display-lg { font-size: var(--sx-text-display-lg-size, 2.75rem);  line-height: var(--sx-text-display-lg-line, 1.1);  letter-spacing: var(--sx-text-display-lg-tracking, -0.02em);  font-weight: var(--sx-text-display-lg-weight, 600); }
.sx-text-display-md { font-size: var(--sx-text-display-md-size, 2.25rem);  line-height: var(--sx-text-display-md-line, 1.15); letter-spacing: var(--sx-text-display-md-tracking, -0.015em); font-weight: var(--sx-text-display-md-weight, 600); }
.sx-text-display-sm { font-size: var(--sx-text-display-sm-size, 1.875rem); line-height: var(--sx-text-display-sm-line, 1.2);  letter-spacing: var(--sx-text-display-sm-tracking, -0.01em);  font-weight: var(--sx-text-display-sm-weight, 600); }
.sx-text-title-lg   { font-size: var(--sx-text-title-lg-size, 1.5rem);     line-height: var(--sx-text-title-lg-line, 1.3);    letter-spacing: var(--sx-text-title-lg-tracking, -0.005em);   font-weight: var(--sx-text-title-lg-weight, 600); }
.sx-text-title-md   { font-size: var(--sx-text-title-md-size, 1.25rem);    line-height: var(--sx-text-title-md-line, 1.35);   letter-spacing: var(--sx-text-title-md-tracking, 0);          font-weight: var(--sx-text-title-md-weight, 600); }
.sx-text-title-sm   { font-size: var(--sx-text-title-sm-size, 1rem);       line-height: var(--sx-text-title-sm-line, 1.5);    letter-spacing: var(--sx-text-title-sm-tracking, 0);          font-weight: var(--sx-text-title-sm-weight, 600); }
.sx-text-label-lg   { font-size: var(--sx-text-label-lg-size, 0.875rem);   line-height: var(--sx-text-label-lg-line, 1.45);   letter-spacing: var(--sx-text-label-lg-tracking, 0.005em);    font-weight: var(--sx-text-label-lg-weight, 500); }
.sx-text-body       { font-size: var(--sx-text-body-size, 1rem);           line-height: var(--sx-text-body-line, 1.55);       letter-spacing: var(--sx-text-body-tracking, 0);              font-weight: var(--sx-text-body-weight, 400); }
.sx-text-body-sm    { font-size: var(--sx-text-body-sm-size, 0.875rem);    line-height: var(--sx-text-body-sm-line, 1.5);     letter-spacing: var(--sx-text-body-sm-tracking, 0);           font-weight: var(--sx-text-body-sm-weight, 400); }
.sx-text-caption    { font-size: var(--sx-text-caption-size, 0.75rem);     line-height: var(--sx-text-caption-line, 1.4);     letter-spacing: var(--sx-text-caption-tracking, 0.01em);      font-weight: var(--sx-text-caption-weight, 400); }
.sx-text-overline   { font-size: var(--sx-text-overline-size, 0.6875rem);  line-height: var(--sx-text-overline-line, 1.4);    letter-spacing: var(--sx-text-overline-tracking, 0.08em);     font-weight: var(--sx-text-overline-weight, 600); text-transform: uppercase; }
.sx-text-mono       { font-family: var(--sx-font-mono, monospace); font-size: var(--sx-text-mono-size, 0.8125rem); line-height: var(--sx-text-mono-line, 1.5); letter-spacing: var(--sx-text-mono-tracking, 0); font-weight: var(--sx-text-mono-weight, 400); font-variant-numeric: tabular-nums; }

/* Text colour ramps (type does the hierarchy work, not colour). */
.sx-text-1 { color: var(--sx-text-1, #151a24); }
.sx-text-2 { color: var(--sx-text-2, #4b5565); }
.sx-text-3 { color: var(--sx-text-3, #616a7d); }
.sx-text-disabled { color: var(--sx-text-disabled, #a3a9b8); }

/* ---------------------------------------------------------------------------------------------
   SxText
   --------------------------------------------------------------------------------------------- */
.sx-text { margin: 0; font-family: inherit; }
.sx-text--inline { display: inline; }
.sx-text--start  { text-align: start; }
.sx-text--center { text-align: center; }
.sx-text--end    { text-align: end; }

/* ---------------------------------------------------------------------------------------------
   SxIcon
   --------------------------------------------------------------------------------------------- */
.sx-icon {
  display: inline-block;
  vertical-align: middle;
  flex-shrink: 0;
  width: var(--sx-icon-size, var(--sx-icon-md, 22px));
  height: var(--sx-icon-size, var(--sx-icon-md, 22px));
  color: inherit;
}
.sx-icon--xs { --sx-icon-size: var(--sx-icon-xs, 14px); }
.sx-icon--sm { --sx-icon-size: var(--sx-icon-sm, 18px); }
.sx-icon--md { --sx-icon-size: var(--sx-icon-md, 22px); }
.sx-icon--lg { --sx-icon-size: var(--sx-icon-lg, 28px); }
.sx-icon--xl { --sx-icon-size: var(--sx-icon-xl, 36px); }

/* ---------------------------------------------------------------------------------------------
   SxButton
   --------------------------------------------------------------------------------------------- */
.sx-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  box-sizing: border-box;
  margin: 0;
  border: 1px solid transparent;
  border-radius: var(--sx-radius-sm, 10px);
  background: none;
  font-family: inherit;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.005em;
  text-decoration: none;
  white-space: nowrap;
  vertical-align: middle;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease),
    color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease),
    border-color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease),
    box-shadow var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-btn:hover { text-decoration: none; }

.sx-btn--xs { min-height: 24px; padding: 0 8px;  font-size: 0.75rem;   --_icon: 14px; }
.sx-btn--sm { min-height: 28px; padding: 0 10px; font-size: 0.8125rem; --_icon: 16px; }
.sx-btn--md { min-height: 34px; padding: 0 14px; font-size: 0.875rem;  --_icon: 18px; }
.sx-btn--lg { min-height: 40px; padding: 0 18px; font-size: 0.9375rem; --_icon: 20px; }
.sx-btn--xl { min-height: 48px; padding: 0 22px; font-size: 1rem;      --_icon: 22px; }

.sx-btn .sx-btn__icon { --sx-icon-size: var(--_icon); }
.sx-btn__label { display: inline-block; }

/* --sx-edge-on-fill, not --sx-edge: on a saturated fill the 0.65-white glass edge reads as a
   hard white bar across the top of the button rather than a lit edge. */
.sx-btn--solid { background: var(--_base); color: var(--_on); box-shadow: var(--sx-edge-on-fill, none), var(--sx-shadow-1, none); }
.sx-btn--solid:not(:disabled):hover { background: var(--_hover); }
.sx-btn--solid:not(:disabled):active { background: var(--_pressed); box-shadow: none; }

.sx-btn--soft { background: var(--_soft); color: var(--_text); }
.sx-btn--soft:not(:disabled):hover { border-color: var(--_soft-border); }
.sx-btn--soft:not(:disabled):active { background: color-mix(in srgb, var(--_soft), var(--_base) 12%); }

.sx-btn--outline { background: transparent; color: var(--_text); border-color: var(--_soft-border); }
.sx-btn--outline:not(:disabled):hover { background: var(--_soft); }
.sx-btn--outline:not(:disabled):active { background: color-mix(in srgb, var(--_soft), var(--_base) 12%); }

.sx-btn--ghost { background: transparent; color: var(--_text); }
.sx-btn--ghost:not(:disabled):hover { background: var(--_soft); }
.sx-btn--ghost:not(:disabled):active { background: color-mix(in srgb, var(--_soft), var(--_base) 12%); }

.sx-btn--full { display: flex; width: 100%; }

.sx-btn:disabled,
.sx-btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; box-shadow: none; }

.sx-btn:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }

.sx-btn--loading { color: transparent !important; cursor: progress; }
.sx-btn--loading .sx-btn__icon { visibility: hidden; }
.sx-btn__spinner {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 1.1em;
  height: 1.1em;
  border-radius: 50%;
  border: 2px solid transparent;
  border-top-color: var(--_text);
  border-right-color: var(--_text);
  animation: sx-spin 0.8s linear infinite;
}
.sx-btn--solid .sx-btn__spinner { border-top-color: var(--_on); border-right-color: var(--_on); }

@keyframes sx-spin { to { transform: rotate(360deg); } }

/* The one glowing element per view (dark theme). Add to a Solid Accent button. */
.sx-btn--glow { box-shadow: var(--sx-edge-on-fill, none), var(--sx-shadow-1, none), var(--sx-accent-glow, none); }

/* ---------------------------------------------------------------------------------------------
   SxIconButton — circular, ghost by default, 44px hit area on touch without changing layout.
   --------------------------------------------------------------------------------------------- */
.sx-icon-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 50%;
  background: none;
  color: var(--_text);
  font: inherit;
  line-height: 1;
  text-decoration: none;
  vertical-align: middle;
  cursor: pointer;
  user-select: none;
  flex-shrink: 0;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease),
    color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease),
    box-shadow var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-icon-btn--xs { width: 24px; height: 24px; --_icon: 14px; }
.sx-icon-btn--sm { width: 30px; height: 30px; --_icon: 18px; }
.sx-icon-btn--md { width: 36px; height: 36px; --_icon: 20px; }
.sx-icon-btn--lg { width: 42px; height: 42px; --_icon: 24px; }
.sx-icon-btn--xl { width: 48px; height: 48px; --_icon: 28px; }
.sx-icon-btn .sx-icon-btn__icon { --sx-icon-size: var(--_icon); }

.sx-icon-btn--ghost:not(:disabled):hover,
.sx-icon-btn--outline:not(:disabled):hover { background: var(--_soft); }
.sx-icon-btn--outline { border-color: var(--_soft-border); }
.sx-icon-btn--soft { background: var(--_soft); }
.sx-icon-btn--soft:not(:disabled):hover { border-color: var(--_soft-border); }
.sx-icon-btn--solid { background: var(--_base); color: var(--_on); box-shadow: var(--sx-edge-on-fill, none), var(--sx-shadow-1, none); }
.sx-icon-btn--solid:not(:disabled):hover { background: var(--_hover); }
.sx-icon-btn:not(:disabled):active { background: color-mix(in srgb, var(--_soft), var(--_base) 14%); }
.sx-icon-btn--solid:not(:disabled):active { background: var(--_pressed); }

.sx-icon-btn:disabled,
.sx-icon-btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; box-shadow: none; }
.sx-icon-btn:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }

@media (pointer: coarse) {
  .sx-icon-btn::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: max(100%, var(--sx-touch-min, 44px));
    height: max(100%, var(--sx-touch-min, 44px));
    transform: translate(-50%, -50%);
  }
}

/* ---------------------------------------------------------------------------------------------
   SxStack
   --------------------------------------------------------------------------------------------- */
.sx-stack { display: flex; flex-direction: column; gap: var(--sx-stack-gap, 12px); box-sizing: border-box; }
.sx-stack--row { flex-direction: row; }
.sx-stack--row-reverse { flex-direction: row-reverse; }
.sx-stack--column-reverse { flex-direction: column-reverse; }
.sx-stack--wrap { flex-wrap: wrap; }
.sx-stack--align-start    { align-items: flex-start; }
.sx-stack--align-center   { align-items: center; }
.sx-stack--align-end      { align-items: flex-end; }
.sx-stack--align-stretch  { align-items: stretch; }
.sx-stack--align-baseline { align-items: baseline; }
.sx-stack--justify-start   { justify-content: flex-start; }
.sx-stack--justify-center  { justify-content: center; }
.sx-stack--justify-end     { justify-content: flex-end; }
.sx-stack--justify-between { justify-content: space-between; }
.sx-stack--justify-around  { justify-content: space-around; }
.sx-stack--justify-evenly  { justify-content: space-evenly; }
.sx-stack--stretch-start  > :first-child { flex: 1 1 auto; }
.sx-stack--stretch-end    > :last-child  { flex: 1 1 auto; }
.sx-stack--stretch-middle > :not(:first-child):not(:last-child) { flex: 1 1 auto; }
.sx-stack--stretch-all    > * { flex: 1 1 auto; }

/* ---------------------------------------------------------------------------------------------
   SxGrid / SxGridItem — 12 columns, mobile-first spans at Mud's breakpoints.
   --------------------------------------------------------------------------------------------- */
.sx-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--sx-grid-gap, 24px);
  width: 100%;
  box-sizing: border-box;
}
.sx-grid--align-start    { align-items: start; }
.sx-grid--align-center   { align-items: center; }
.sx-grid--align-end      { align-items: end; }
.sx-grid--align-stretch  { align-items: stretch; }
.sx-grid--align-baseline { align-items: baseline; }

.sx-col { grid-column: span 12; min-width: 0; box-sizing: border-box; }
.sx-col-1  { grid-column: span 1; }  .sx-col-2  { grid-column: span 2; }  .sx-col-3  { grid-column: span 3; }
.sx-col-4  { grid-column: span 4; }  .sx-col-5  { grid-column: span 5; }  .sx-col-6  { grid-column: span 6; }
.sx-col-7  { grid-column: span 7; }  .sx-col-8  { grid-column: span 8; }  .sx-col-9  { grid-column: span 9; }
.sx-col-10 { grid-column: span 10; } .sx-col-11 { grid-column: span 11; } .sx-col-12 { grid-column: span 12; }
@media (min-width: 600px) {
  .sx-col-sm-1  { grid-column: span 1; }  .sx-col-sm-2  { grid-column: span 2; }  .sx-col-sm-3  { grid-column: span 3; }
  .sx-col-sm-4  { grid-column: span 4; }  .sx-col-sm-5  { grid-column: span 5; }  .sx-col-sm-6  { grid-column: span 6; }
  .sx-col-sm-7  { grid-column: span 7; }  .sx-col-sm-8  { grid-column: span 8; }  .sx-col-sm-9  { grid-column: span 9; }
  .sx-col-sm-10 { grid-column: span 10; } .sx-col-sm-11 { grid-column: span 11; } .sx-col-sm-12 { grid-column: span 12; }
}
@media (min-width: 960px) {
  .sx-col-md-1  { grid-column: span 1; }  .sx-col-md-2  { grid-column: span 2; }  .sx-col-md-3  { grid-column: span 3; }
  .sx-col-md-4  { grid-column: span 4; }  .sx-col-md-5  { grid-column: span 5; }  .sx-col-md-6  { grid-column: span 6; }
  .sx-col-md-7  { grid-column: span 7; }  .sx-col-md-8  { grid-column: span 8; }  .sx-col-md-9  { grid-column: span 9; }
  .sx-col-md-10 { grid-column: span 10; } .sx-col-md-11 { grid-column: span 11; } .sx-col-md-12 { grid-column: span 12; }
}
@media (min-width: 1280px) {
  .sx-col-lg-1  { grid-column: span 1; }  .sx-col-lg-2  { grid-column: span 2; }  .sx-col-lg-3  { grid-column: span 3; }
  .sx-col-lg-4  { grid-column: span 4; }  .sx-col-lg-5  { grid-column: span 5; }  .sx-col-lg-6  { grid-column: span 6; }
  .sx-col-lg-7  { grid-column: span 7; }  .sx-col-lg-8  { grid-column: span 8; }  .sx-col-lg-9  { grid-column: span 9; }
  .sx-col-lg-10 { grid-column: span 10; } .sx-col-lg-11 { grid-column: span 11; } .sx-col-lg-12 { grid-column: span 12; }
}
@media (min-width: 1920px) {
  .sx-col-xl-1  { grid-column: span 1; }  .sx-col-xl-2  { grid-column: span 2; }  .sx-col-xl-3  { grid-column: span 3; }
  .sx-col-xl-4  { grid-column: span 4; }  .sx-col-xl-5  { grid-column: span 5; }  .sx-col-xl-6  { grid-column: span 6; }
  .sx-col-xl-7  { grid-column: span 7; }  .sx-col-xl-8  { grid-column: span 8; }  .sx-col-xl-9  { grid-column: span 9; }
  .sx-col-xl-10 { grid-column: span 10; } .sx-col-xl-11 { grid-column: span 11; } .sx-col-xl-12 { grid-column: span 12; }
}

/* ---------------------------------------------------------------------------------------------
   SxSurface — the shared skeleton. Elevation is shadow on light and surface value on dark; both
   come from the tokens. Every raised step carries the glass edge (motif #1).
   No `position` here on purpose: MudPaper never set one and absolutely-positioned children
   rely on that. Add `.sx-grain` only to hosts that set position themselves.
   --------------------------------------------------------------------------------------------- */
.sx-surface {
  box-sizing: border-box;
  color: var(--sx-text-1, #151a24);
  background: var(--sx-surface-1, #fbfcfe);
  border-radius: var(--sx-radius-md, 14px);
  transition: box-shadow var(--sx-dur-base, 200ms) var(--sx-ease-out, ease), background-color var(--sx-dur-base, 200ms) var(--sx-ease-out, ease);
}
.sx-surface--e0 { background: var(--sx-surface-1, #fbfcfe); box-shadow: none; }
.sx-surface--e1 { background: var(--sx-surface-2, #ffffff); box-shadow: var(--sx-edge, none), var(--sx-shadow-1, none); }
.sx-surface--e2 { background: var(--sx-surface-2, #ffffff); box-shadow: var(--sx-edge, none), var(--sx-shadow-2, none); }
.sx-surface--e3 { background: var(--sx-surface-3, #ffffff); box-shadow: var(--sx-edge, none), var(--sx-shadow-3, none); }
.sx-surface--e4 { background: var(--sx-surface-3, #ffffff); box-shadow: var(--sx-edge, none), var(--sx-shadow-4, none); }
.sx-surface--e5 { background: var(--sx-surface-4, #ffffff); box-shadow: var(--sx-edge, none), var(--sx-shadow-5, none); }
.sx-surface--outline { background: var(--sx-surface-1, #fbfcfe); box-shadow: none; border: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08)); }
.sx-surface--sunken { background: var(--sx-surface-sunken, #eceff5); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.04); }
.sx-surface--square { border-radius: 0; }
.sx-surface--clickable { cursor: pointer; }
.sx-surface--clickable:hover { background-image: linear-gradient(var(--sx-surface-hover, rgba(20, 40, 80, 0.05)), var(--sx-surface-hover, rgba(20, 40, 80, 0.05))); }
.sx-surface--clickable:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }

/* Frosted glass. Opaque fallback where backdrop-filter is unsupported — never transparent-and-unreadable. */
.sx-glass {
  box-sizing: border-box;
  color: var(--sx-text-1, #151a24);
  border-radius: var(--sx-radius-md, 14px);
  background: var(--sx-glass-bg-fallback, #fbfcfe);
  border: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08));
  box-shadow: var(--sx-edge, none), var(--sx-shadow-2, none);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .sx-glass {
    background: var(--sx-glass-bg, rgba(255, 255, 255, 0.7));
    -webkit-backdrop-filter: var(--sx-glass-filter, blur(20px));
    backdrop-filter: var(--sx-glass-filter, blur(20px));
  }
}

/* Matte grain overlay — add to any large surface. Needs position: relative on the host. */
.sx-grain::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-image: var(--sx-grain, none);
  opacity: var(--sx-grain-opacity, 0.03);
  pointer-events: none;
  mix-blend-mode: multiply;
}
[data-sx-theme="dark"] .sx-grain::after,
[data-sx-theme="portal"] .sx-grain::after { mix-blend-mode: screen; }

/* Accent glow — the dark theme's frost. Exactly one per view. */
.sx-glow { box-shadow: var(--sx-edge, none), var(--sx-shadow-2, none), var(--sx-accent-glow, none); }

/* The soft double focus ring (motif #2) as a class, for elements that manage their own outline. */
.sx-focus-ring:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }

/* ---------------------------------------------------------------------------------------------
   SxDivider / SxSpacer
   --------------------------------------------------------------------------------------------- */
.sx-divider {
  flex-shrink: 0;
  margin: 0;
  border: 0;
  border-top: 1px solid var(--sx-divider, rgba(16, 24, 40, 0.07));
  width: 100%;
  box-sizing: border-box;
}
.sx-divider--vertical { width: 0; height: 100%; border-top: 0; border-left: 1px solid var(--sx-divider, rgba(16, 24, 40, 0.07)); }
.sx-divider--flex { height: auto; align-self: stretch; }
.sx-divider--inset { width: auto; margin-inline-start: 72px; }
.sx-divider--middle { width: auto; margin-inline: 16px; }

.sx-spacer { flex-grow: 1; }

/* =============================================================================================
   TIER 2 — services & overlays (Phase 2)
   ============================================================================================= */

body.sx-scroll-lock { overflow: hidden !important; }

/* ---------------------------------------------------------------------------------------------
   SxDialog — scrim + panel. The panel is surface-4 (the brightest step), radius xl, shadow-5 and
   the glass edge; the scrim is the theme's scrim colour with a light blur so the page recedes.
   z-index comes inline from the instance (SxZIndex.Dialog + order × 2).
   --------------------------------------------------------------------------------------------- */
.sx-dialog-host { display: contents; }

.sx-dialog-layer {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  box-sizing: border-box;
}
.sx-dialog-scrim {
  position: absolute;
  inset: 0;
  background: var(--sx-scrim, rgba(15, 20, 35, 0.45));
  animation: sx-fade-in var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease) both;
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .sx-dialog-scrim { -webkit-backdrop-filter: blur(var(--sx-scrim-blur, 2px)); backdrop-filter: blur(var(--sx-scrim-blur, 2px)); }
}

.sx-dialog {
  position: relative;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  max-width: 100%;
  max-height: calc(100dvh - 32px);
  color: var(--sx-text-1, #151a24);
  background: var(--sx-surface-4, #ffffff);
  border-radius: var(--sx-radius-xl, 24px);
  box-shadow: var(--sx-edge, none), var(--sx-shadow-5, 0 24px 56px -12px rgba(0, 0, 0, 0.3));
  outline: none;
  animation: sx-dialog-in var(--sx-dur-base, 200ms) var(--sx-ease-out, ease) both;
}
.sx-dialog--xs   { width: min(444px, 100%); }
.sx-dialog--sm   { width: min(600px, 100%); }
.sx-dialog--md   { width: min(960px, 100%); }
.sx-dialog--lg   { width: min(1280px, 100%); }
.sx-dialog--xl   { width: min(1920px, 100%); }
.sx-dialog--none { width: auto; }
.sx-dialog:not(.sx-dialog--full-width) { width: auto; }
.sx-dialog--xs:not(.sx-dialog--full-width)  { max-width: 444px; }
.sx-dialog--sm:not(.sx-dialog--full-width)  { max-width: 600px; }
.sx-dialog--md:not(.sx-dialog--full-width)  { max-width: 960px; }
.sx-dialog--lg:not(.sx-dialog--full-width)  { max-width: 1280px; }
.sx-dialog--xl:not(.sx-dialog--full-width)  { max-width: 1920px; }

.sx-dialog-layer--fullscreen { padding: 0; }
.sx-dialog--fullscreen {
  width: 100%;
  max-width: none;
  height: 100dvh;
  max-height: none;
  border-radius: 0;
}

.sx-dialog__header {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 20px 20px 8px 24px;
}
.sx-dialog__title {
  flex: 1 1 auto;
  min-width: 0;
  align-self: center;
  font-size: var(--sx-text-title-md-size, 1.125rem);
  line-height: var(--sx-text-title-md-line, 1.35);
  font-weight: var(--sx-text-title-md-weight, 600);
  letter-spacing: var(--sx-text-title-md-tracking, -0.005em);
}
.sx-dialog__title:empty { display: none; }
.sx-dialog__close { flex: 0 0 auto; margin: -4px -6px 0 0; }
.sx-dialog__content {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  padding: 8px 24px 20px;
  overscroll-behavior: contain;
}
.sx-dialog__header + .sx-dialog__content { padding-top: 4px; }
.sx-dialog__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding: 4px 20px 20px;
}

@media (max-width: 599.98px) {
  .sx-dialog-layer { padding: 12px; }
  .sx-dialog { max-height: calc(100dvh - 24px); border-radius: var(--sx-radius-lg, 18px); }
  .sx-dialog__header { padding: 16px 12px 6px 18px; }
  .sx-dialog__content { padding: 6px 18px 16px; }
  .sx-dialog__actions { padding: 4px 14px 16px; }
}

@keyframes sx-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes sx-dialog-in {
  from { opacity: 0; transform: translateY(10px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------------------------------------
   SxOverlay — hand-rolled modal panels. Scrim + centred content, rendered in place.
   --------------------------------------------------------------------------------------------- */
.sx-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  box-sizing: border-box;
}
.sx-overlay--absolute { position: absolute; }
.sx-overlay__scrim {
  position: absolute;
  inset: 0;
  background: var(--sx-scrim, rgba(15, 20, 35, 0.45));
  animation: sx-fade-in var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease) both;
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .sx-overlay__scrim { -webkit-backdrop-filter: blur(var(--sx-scrim-blur, 2px)); backdrop-filter: blur(var(--sx-scrim-blur, 2px)); }
}
.sx-overlay__content {
  position: relative;
  max-width: 100%;
  max-height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: sx-dialog-in var(--sx-dur-base, 200ms) var(--sx-ease-out, ease) both;
}
.sx-overlay__content > * { max-width: 100%; }

/* ---------------------------------------------------------------------------------------------
   Popover host — shared by menus, tooltips and popovers. Positioned by sx.js (left/top/z-index
   inline); starts hidden so it can be measured, then fades in.
   --------------------------------------------------------------------------------------------- */
.sx-popover {
  position: fixed;
  left: 0;
  top: 0;
  visibility: hidden;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease), transform var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
  outline: none;
  box-sizing: border-box;
  max-width: calc(100vw - 16px);
}
.sx-popover[data-side="top"]   { transform: translateY(4px); }
.sx-popover[data-side="left"]  { transform: translateX(4px); }
.sx-popover[data-side="right"] { transform: translateX(-4px); }
.sx-popover--open { opacity: 1; transform: none !important; }

/* Generic panel (SxPopover) — a raised surface with the glass edge. */
.sx-popover-anchor { display: inline-block; width: 0; height: 0; overflow: hidden; }
.sx-popover-panel {
  color: var(--sx-text-1, #151a24);
  background: var(--sx-surface-3, #ffffff);
  border-radius: var(--sx-radius-md, 14px);
  box-shadow: var(--sx-edge, none), var(--sx-shadow-4, 0 12px 32px -8px rgba(0, 0, 0, 0.2));
  border: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08));
}

/* ---------------------------------------------------------------------------------------------
   SxMenu — the list. Continuous radius: panel 14px, 6px padding → rows 8px.
   --------------------------------------------------------------------------------------------- */
.sx-menu-anchor { display: inline-flex; align-items: center; vertical-align: middle; }
.sx-menu__activator { display: inline-flex; align-items: center; cursor: pointer; }

.sx-menu {
  color: var(--sx-text-1, #151a24);
  background: var(--sx-surface-3, #ffffff);
  border-radius: var(--sx-radius-md, 14px);
  box-shadow: var(--sx-edge, none), var(--sx-shadow-4, 0 12px 32px -8px rgba(0, 0, 0, 0.2));
  border: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08));
  padding: 6px;
  min-width: 160px;
  overflow: auto;
  overscroll-behavior: contain;
}
.sx-menu__list { display: flex; flex-direction: column; gap: 1px; }
.sx-menu__list > .sx-divider { margin: 5px 6px; width: auto; }

.sx-menu-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 36px;
  padding: 6px 12px;
  margin: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  line-height: 1.3;
  text-align: start;
  white-space: nowrap;
  cursor: pointer;
  box-sizing: border-box;
  transition: background-color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-menu--dense .sx-menu-item { min-height: 30px; padding: 4px 10px; }
.sx-menu-item:hover { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); }
.sx-menu-item:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-menu-item:active { background: var(--sx-neutral-soft, rgba(16, 24, 40, 0.06)); }
.sx-menu-item:disabled { color: var(--sx-text-disabled, #a3a9b8); cursor: default; }
.sx-menu-item:disabled .sx-menu-item__icon { color: var(--sx-text-disabled, #a3a9b8); }
.sx-menu-item__icon { flex: 0 0 auto; }
.sx-menu-item__label { flex: 1 1 auto; min-width: 0; }
/* When any row carries an icon, align every label past the icon column. */
.sx-menu__list:has(.sx-menu-item__icon) .sx-menu-item { padding-inline-start: 40px; }
.sx-menu__list:has(.sx-menu-item__icon) .sx-menu-item__icon { position: absolute; inset-inline-start: 12px; top: 50%; transform: translateY(-50%); }
.sx-menu--dense .sx-menu__list:has(.sx-menu-item__icon) .sx-menu-item { padding-inline-start: 36px; }
.sx-menu--dense .sx-menu__list:has(.sx-menu-item__icon) .sx-menu-item__icon { inset-inline-start: 10px; }

/* ---------------------------------------------------------------------------------------------
   SxTooltip — contrast (inverse) surface, caption size, optional arrow.
   --------------------------------------------------------------------------------------------- */
.sx-tooltip-anchor { display: inline-flex; vertical-align: middle; max-width: 100%; }
.sx-tooltip-anchor--block { display: block; }

.sx-tooltip {
  pointer-events: none;
  max-width: min(320px, calc(100vw - 16px));
  padding: 6px 10px;
  border-radius: var(--sx-radius-sm, 10px);
  /* --sx-surface-2 / --sx-text-1, NOT --sx-contrast-*. tokens.css now hands this element the
     OPPOSITE theme's token set (see the `.sx-tooltip` pair in both theme blocks), so its own base
     surface already IS the inverted colour — and reading --sx-contrast-bg here would invert it a
     second time and hand back the page's own background. Everything inside the bubble now resolves
     from the same inverted set, which is what makes chips and muted text legible on it. */
  background: var(--sx-surface-2, #1f2533);
  color: var(--sx-text-1, #f3f5f9);
  font-size: var(--sx-text-caption-size, 0.75rem);
  line-height: var(--sx-text-caption-line, 1.4);
  font-weight: 500;
  letter-spacing: 0.005em;
  box-shadow: var(--sx-shadow-3, 0 6px 16px -4px rgba(0, 0, 0, 0.25));
  white-space: normal;
  overflow-wrap: anywhere;
}
.sx-tooltip--arrow::before {
  content: "";
  position: absolute;
  width: 10px;
  height: 10px;
  background: inherit;
  transform: rotate(45deg);
  border-radius: 2px;
}
.sx-tooltip--arrow[data-side="bottom"]::before { top: -5px;  left: calc(var(--sx-arrow-x, 50%) - 5px); }
.sx-tooltip--arrow[data-side="top"]::before    { bottom: -5px; left: calc(var(--sx-arrow-x, 50%) - 5px); }
.sx-tooltip--arrow[data-side="right"]::before  { left: -5px;  top: calc(var(--sx-arrow-y, 50%) - 5px); }
.sx-tooltip--arrow[data-side="left"]::before   { right: -5px; top: calc(var(--sx-arrow-y, 50%) - 5px); }

/* ---------------------------------------------------------------------------------------------
   SxSnackbar — top-right stack of frosted toasts. Severity shows as a soft icon disc, not a loud
   fill; the message stays in the surface's text colour. Danger uses role=alert.
   --------------------------------------------------------------------------------------------- */
.sx-snackbar-region {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: var(--sx-z-snackbar, 1500);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
  width: min(420px, calc(100vw - 32px));
  pointer-events: none;
}
.sx-snackbar {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  min-width: 0;
  padding: 10px 8px 10px 12px;
  box-sizing: border-box;
  color: var(--sx-text-1, #151a24);
  background: var(--sx-glass-bg-fallback, #fbfcfe);
  border: 1px solid var(--sx-glass-border, rgba(255, 255, 255, 0.6));
  border-radius: var(--sx-radius-lg, 18px);
  box-shadow: var(--sx-edge, none), var(--sx-shadow-4, 0 12px 32px -8px rgba(0, 0, 0, 0.2));
  animation: sx-toast-in var(--sx-dur-base, 200ms) var(--sx-ease-out, ease) both;
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .sx-snackbar {
    background: var(--sx-glass-bg, rgba(255, 255, 255, 0.7));
    -webkit-backdrop-filter: var(--sx-glass-filter, blur(20px));
    backdrop-filter: var(--sx-glass-filter, blur(20px));
  }
}
.sx-snackbar__icon {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: var(--sx-radius-full, 9999px);
  margin-top: 1px;
}
.sx-snackbar--info    .sx-snackbar__icon { background: var(--sx-info-soft, rgba(11, 122, 143, 0.1));    color: var(--sx-info-text, #086a7c); }
.sx-snackbar--success .sx-snackbar__icon { background: var(--sx-success-soft, rgba(23, 122, 77, 0.1));   color: var(--sx-success-text, #136a42); }
.sx-snackbar--warning .sx-snackbar__icon { background: var(--sx-warning-soft, rgba(168, 93, 8, 0.1));    color: var(--sx-warning-text, #8a4b00); }
.sx-snackbar--danger  .sx-snackbar__icon { background: var(--sx-danger-soft, rgba(201, 58, 58, 0.1));    color: var(--sx-danger-text, #b42f2f); }
.sx-snackbar__message {
  flex: 1 1 auto;
  min-width: 0;
  padding-top: 5px;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  line-height: 1.4;
  overflow-wrap: anywhere;
}
.sx-snackbar__action { flex: 0 0 auto; margin-top: 1px; }
.sx-snackbar__close { flex: 0 0 auto; margin-top: 2px; color: var(--sx-text-3, #616a7d); }

@keyframes sx-toast-in {
  from { opacity: 0; transform: translateX(16px); }
  to   { opacity: 1; transform: none; }
}

@media (max-width: 599.98px) {
  .sx-snackbar-region { top: 12px; right: 12px; left: 12px; width: auto; }
}

/* =============================================================================================
   TIER 3 — inputs (Phase 3)
   Every field in the old app was Outlined + Dense, so there is one look here, not a variant matrix.
   The label is stacked above the box rather than notched into the border: simpler, always legible,
   and identical for text, numeric, select and picker controls.
   ============================================================================================= */

/* A field fills its container by default. It used to be shrink-to-fit, which sized every field to
   its control's intrinsic width — a textarea's ~20 columns, an input's `size` — so fields in a grid
   cell or a form column came out stubby and unrelated to the space they were given, and the only
   way out was FullWidth="true" at the call site. The default is now the common case; the rare field
   that must size to its content (a toolbar row that reads as a sentence, a field sharing a line
   with buttons) opts out with FullWidth="false" → `.sx-field--auto` below. */
.sx-field {
  display: flex;
  width: 100%;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
  text-align: start;
}
/* Retained so FullWidth="true" keeps meaning what it says; identical to the default now. */
.sx-field--full { display: flex; width: 100%; }
/* The opt-out. Declared after the base rule — same specificity, so source order decides. In a flex
   row this restores content sizing, which is what lets `flex-grow-1` siblings share the line and
   what stops a wrapping row from breaking to one item per line. */
.sx-field--auto { display: inline-flex; width: auto; }

.sx-field__label {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: var(--sx-text-label-lg-size, 0.8125rem);
  line-height: 1.3;
  font-weight: var(--sx-text-label-lg-weight, 600);
  letter-spacing: 0.005em;
  color: var(--sx-text-2, #4b5565);
  cursor: pointer;
}
.sx-field__required { color: var(--sx-danger-text, #b42f2f); font-weight: 700; }

.sx-field__box {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 38px;
  padding: 0 10px;
  box-sizing: border-box;
  background: var(--sx-surface-2, #ffffff);
  border: 1px solid var(--sx-line-input, rgba(16, 24, 40, 0.48));
  border-radius: var(--sx-radius-sm, 10px);
  transition: border-color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease),
              box-shadow var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease),
              background-color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-field__box:hover { border-color: var(--sx-text-2, #4b5565); }

/* The soft double focus ring (motif #2) lands on the box, not the bare input. */
.sx-field__box:focus-within {
  border-color: var(--sx-accent, #1f6fc6);
  box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6);
}

.sx-field--multiline .sx-field__box { align-items: flex-start; padding-block: 8px; }

.sx-field--error .sx-field__box { border-color: var(--sx-danger, #c93a3a); }
.sx-field--error .sx-field__box:focus-within {
  border-color: var(--sx-danger, #c93a3a);
  box-shadow: 0 0 0 1.5px var(--sx-danger, #c93a3a), 0 0 0 6px var(--sx-danger-soft, rgba(201, 58, 58, 0.18));
}
.sx-field--error .sx-field__label { color: var(--sx-danger-text, #b42f2f); }

.sx-field--disabled { opacity: 0.6; }
.sx-field--disabled .sx-field__box { background: var(--sx-surface-sunken, #eceff5); border-style: dashed; }
.sx-field--disabled .sx-field__label { cursor: default; }

.sx-field--readonly .sx-field__box { background: var(--sx-surface-sunken, #eceff5); }

.sx-field__control { flex: 1 1 auto; display: flex; align-items: center; min-width: 0; }
.sx-field--multiline .sx-field__control { align-items: stretch; }

.sx-field__adornment {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--sx-text-3, #616a7d);
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  line-height: 1;
}
.sx-field__adornment-text { white-space: nowrap; }
.sx-field__adornment--button {
  margin: 0;
  padding: 4px;
  border: 0;
  border-radius: var(--sx-radius-xs, 6px);
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.sx-field__adornment--button:hover { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); }
.sx-field__adornment--button:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-field__adornment--button:disabled { cursor: default; }

.sx-field__message {
  font-size: var(--sx-text-caption-size, 0.75rem);
  line-height: var(--sx-text-caption-line, 1.4);
  color: var(--sx-text-3, #616a7d);
  padding-inline: 2px;
}
.sx-field__message--error { color: var(--sx-danger-text, #b42f2f); }

/* ---------------------------------------------------------------------------------------------
   The bare control. The box owns the border and background; the input owns nothing but the text.
   --------------------------------------------------------------------------------------------- */
.sx-input {
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
  margin: 0;
  padding: 8px 0;
  border: 0;
  background: transparent;
  color: var(--sx-text-1, #151a24);
  font-family: inherit;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  line-height: 1.4;
  outline: none;
  box-sizing: border-box;
}
/* reset.css applies the double focus ring to a BARE `:focus-visible`, which the inner control
   matches too — so a focused field drew the box's ring AND a second ring hugging just the input,
   inside the border. The box owns focus for the whole field (`:focus-within` above); the control
   contributes nothing. Do not add `outline: none` here alone — the ring is a box-shadow. */
.sx-input:focus-visible,
.sx-input:focus {
  outline: none;
  box-shadow: none;
  border-radius: 0;
}

.sx-input::placeholder { color: var(--sx-text-3, #616a7d); opacity: 0.8; }
.sx-input:disabled { color: var(--sx-text-disabled, #a3a9b8); -webkit-text-fill-color: var(--sx-text-disabled, #a3a9b8); cursor: default; }
.sx-input--multiline { padding-block: 0; resize: vertical; min-height: calc(1.4em * 2); }
/* An auto-growing textarea re-sizes itself to its content on every keystroke, so a manual drag is
   overwritten on the next character typed. Offering the grip there advertises a control that does
   not hold. Plain multiline fields keep `resize: vertical` from the rule above. */
.sx-input--autogrow { resize: none; }
.sx-input--numeric { text-align: end; font-variant-numeric: tabular-nums; }

.sx-input__clear,
.sx-input__spin-btn {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--sx-text-3, #616a7d);
  cursor: pointer;
}
.sx-input__clear {
  width: 20px;
  height: 20px;
  border-radius: var(--sx-radius-full, 9999px);
}
.sx-input__clear:hover { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); color: var(--sx-text-1, #151a24); }
.sx-input__clear:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }

.sx-input__counter {
  flex: 0 0 auto;
  font-size: var(--sx-text-caption-size, 0.75rem);
  color: var(--sx-text-3, #616a7d);
  font-variant-numeric: tabular-nums;
}

/* Our own spinner: type=number's native one cannot be styled and scroll-changes the value. */
.sx-input__spin { flex: 0 0 auto; display: flex; flex-direction: column; gap: 1px; }
.sx-input__spin-btn { height: 13px; width: 18px; border-radius: var(--sx-radius-xs, 6px); }
.sx-input__spin-btn:hover { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); color: var(--sx-text-1, #151a24); }
.sx-input__spin-btn:disabled { opacity: 0.4; cursor: default; }
/* Reveal on hover/focus only — a permanent pair of arrows on every money field is noise. */
.sx-input__spin { opacity: 0; transition: opacity var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease); }
.sx-field__box:hover .sx-input__spin,
.sx-field__box:focus-within .sx-input__spin { opacity: 1; }
@media (hover: none) { .sx-input__spin { opacity: 1; } }

/* ---------------------------------------------------------------------------------------------
   SxSelect — native <select>, custom chevron.
   --------------------------------------------------------------------------------------------- */
.sx-select {
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  padding-inline-end: 22px;
}
.sx-select[multiple] { padding-inline-end: 0; cursor: default; }
.sx-select option { color: var(--sx-text-1, #151a24); background: var(--sx-surface-2, #ffffff); }
.sx-select__chevron {
  position: absolute;
  inset-inline-end: 10px;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  color: var(--sx-text-3, #616a7d);
}
.sx-field--select .sx-field__box { padding-inline-end: 10px; }

/* ---------------------------------------------------------------------------------------------
   SxCheckbox / SxSwitch — real inputs, visually hidden, with a drawn control beside the label.
   The hit target is the whole label; the touch floor is 44px via padding, not size.
   --------------------------------------------------------------------------------------------- */
.sx-check,
.sx-switch {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 32px;
  padding-block: 2px;
  cursor: pointer;
  color: var(--sx-text-1, #151a24);
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  line-height: 1.4;
  -webkit-tap-highlight-color: transparent;
}
.sx-check--dense { min-height: 24px; gap: 6px; }
.sx-check--label-start,
.sx-switch--label-start { flex-direction: row-reverse; }
.sx-check--disabled,
.sx-switch--disabled { cursor: default; opacity: 0.6; }

.sx-check__input,
.sx-switch__input {
  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;
}

.sx-check__box {
  flex: 0 0 auto;
  display: inline-grid;
  place-items: center;
  box-sizing: border-box;
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--sx-line-input, rgba(16, 24, 40, 0.48));
  border-radius: var(--sx-radius-xs, 6px);
  background: var(--sx-surface-2, #ffffff);
  color: var(--sx-accent-on, #fff);
  transition: background-color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease),
              border-color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-check--sm .sx-check__box { width: 16px; height: 16px; }
.sx-check--lg .sx-check__box { width: 22px; height: 22px; }
.sx-check:hover .sx-check__box { border-color: var(--sx-text-2, #4b5565); }
.sx-check__input:checked + .sx-check__box,
.sx-check__input:indeterminate + .sx-check__box {
  background: var(--_check, var(--sx-accent, #1f6fc6));
  border-color: var(--_check, var(--sx-accent, #1f6fc6));
}
.sx-check__input:focus-visible + .sx-check__box { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-check--error .sx-check__box { border-color: var(--sx-danger, #c93a3a); }
.sx-check__label { min-width: 0; }

/* Tone drives the checked fill only — an unchecked box stays neutral. */
.sx-check--t-accent   { --_check: var(--sx-accent, #1f6fc6); }
.sx-check--t-accent2  { --_check: var(--sx-accent2, #6d5bd0); }
.sx-check--t-numeric  { --_check: var(--sx-numeric, #0c8068); }
.sx-check--t-success  { --_check: var(--sx-success, #177a4d); }
.sx-check--t-warning  { --_check: var(--sx-warning, #a85d08); }
.sx-check--t-danger   { --_check: var(--sx-danger, #c93a3a); }
.sx-check--t-info     { --_check: var(--sx-info, #0b7a8f); }
.sx-check--t-default  { --_check: var(--sx-text-1, #151a24); }
.sx-check--t-muted    { --_check: var(--sx-text-2, #4b5565); }
.sx-check--t-contrast { --_check: var(--sx-contrast-bg, #1f2533); }

.sx-switch__track {
  flex: 0 0 auto;
  position: relative;
  box-sizing: border-box;
  width: 34px;
  height: 20px;
  padding: 2px;
  border-radius: var(--sx-radius-full, 9999px);
  background: var(--sx-neutral-pressed, #c6ccd8);
  transition: background-color var(--sx-dur-base, 200ms) var(--sx-ease-out, ease);
}
.sx-switch--sm .sx-switch__track { width: 28px; height: 17px; }
.sx-switch--lg .sx-switch__track { width: 42px; height: 24px; }
.sx-switch__thumb {
  display: block;
  width: 16px;
  height: 16px;
  border-radius: var(--sx-radius-full, 9999px);
  background: #fff;
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.35);
  transition: transform var(--sx-dur-base, 200ms) var(--sx-ease-spring, ease);
}
.sx-switch--sm .sx-switch__thumb { width: 13px; height: 13px; }
.sx-switch--lg .sx-switch__thumb { width: 20px; height: 20px; }
.sx-switch__input:checked + .sx-switch__track { background: var(--_switch, var(--sx-accent, #1f6fc6)); }
.sx-switch__input:checked + .sx-switch__track .sx-switch__thumb { transform: translateX(14px); }
.sx-switch--sm .sx-switch__input:checked + .sx-switch__track .sx-switch__thumb { transform: translateX(11px); }
.sx-switch--lg .sx-switch__input:checked + .sx-switch__track .sx-switch__thumb { transform: translateX(18px); }
.sx-switch__input:focus-visible + .sx-switch__track { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-switch__label { min-width: 0; }

.sx-switch--t-accent   { --_switch: var(--sx-accent, #1f6fc6); }
.sx-switch--t-accent2  { --_switch: var(--sx-accent2, #6d5bd0); }
.sx-switch--t-numeric  { --_switch: var(--sx-numeric, #0c8068); }
.sx-switch--t-success  { --_switch: var(--sx-success, #177a4d); }
.sx-switch--t-warning  { --_switch: var(--sx-warning, #a85d08); }
.sx-switch--t-danger   { --_switch: var(--sx-danger, #c93a3a); }
.sx-switch--t-info     { --_switch: var(--sx-info, #0b7a8f); }
.sx-switch--t-default  { --_switch: var(--sx-text-1, #151a24); }
.sx-switch--t-muted    { --_switch: var(--sx-text-2, #4b5565); }
.sx-switch--t-contrast { --_switch: var(--sx-contrast-bg, #1f2533); }

@media (max-width: 599.98px) {
  /* 44px touch floor on phones without changing the drawn control. */
  .sx-check, .sx-switch { min-height: var(--sx-touch-min, 44px); }
  .sx-field__box { min-height: 42px; }
}

/* ---------------------------------------------------------------------------------------------
   SxRadioGroup / SxRadio
   --------------------------------------------------------------------------------------------- */
.sx-radio-group__label {
  font-size: var(--sx-text-label-lg-size, 0.8125rem);
  font-weight: var(--sx-text-label-lg-weight, 600);
  color: var(--sx-text-2, #4b5565);
  margin-bottom: 4px;
}
.sx-radio-group__list { display: flex; flex-direction: column; gap: 2px; }
.sx-radio-group__list--row { flex-direction: row; flex-wrap: wrap; gap: 16px; }

.sx-radio {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 32px;
  padding-block: 2px;
  cursor: pointer;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  line-height: 1.4;
  -webkit-tap-highlight-color: transparent;
}
.sx-radio--disabled { cursor: default; opacity: 0.6; }
.sx-radio__input {
  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;
}
.sx-radio__mark {
  flex: 0 0 auto;
  position: relative;
  box-sizing: border-box;
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--sx-line-input, rgba(16, 24, 40, 0.48));
  border-radius: var(--sx-radius-full, 9999px);
  background: var(--sx-surface-2, #ffffff);
  transition: border-color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-radio__mark::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: var(--sx-radius-full, 9999px);
  background: var(--_radio, var(--sx-accent, #1f6fc6));
  transform: scale(0);
  transition: transform var(--sx-dur-fast, 120ms) var(--sx-ease-spring, ease);
}
.sx-radio:hover .sx-radio__mark { border-color: var(--sx-text-2, #4b5565); }
.sx-radio__input:checked + .sx-radio__mark { border-color: var(--_radio, var(--sx-accent, #1f6fc6)); }
.sx-radio__input:checked + .sx-radio__mark::after { transform: scale(1); }
.sx-radio__input:focus-visible + .sx-radio__mark { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }

.sx-radio--t-accent   { --_radio: var(--sx-accent, #1f6fc6); }
.sx-radio--t-accent2  { --_radio: var(--sx-accent2, #6d5bd0); }
.sx-radio--t-numeric  { --_radio: var(--sx-numeric, #0c8068); }
.sx-radio--t-success  { --_radio: var(--sx-success, #177a4d); }
.sx-radio--t-warning  { --_radio: var(--sx-warning, #a85d08); }
.sx-radio--t-danger   { --_radio: var(--sx-danger, #c93a3a); }
.sx-radio--t-info     { --_radio: var(--sx-info, #0b7a8f); }
.sx-radio--t-default  { --_radio: var(--sx-text-1, #151a24); }
.sx-radio--t-muted    { --_radio: var(--sx-text-2, #4b5565); }
.sx-radio--t-contrast { --_radio: var(--sx-contrast-bg, #1f2533); }

/* ---------------------------------------------------------------------------------------------
   Shared dropdown surface for autocomplete, date picker and time picker.
   --------------------------------------------------------------------------------------------- */
.sx-autocomplete__list,
.sx-datepicker__popover,
.sx-timepicker__popover {
  color: var(--sx-text-1, #151a24);
  background: var(--sx-surface-3, #ffffff);
  border: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08));
  border-radius: var(--sx-radius-md, 14px);
  box-shadow: var(--sx-edge, none), var(--sx-shadow-4, 0 12px 32px -8px rgba(0, 0, 0, 0.2));
}

.sx-autocomplete__anchor,
.sx-datepicker__anchor,
.sx-timepicker__anchor { display: flex; flex: 1 1 auto; min-width: 0; }

.sx-autocomplete__list { padding: 6px; min-width: 220px; }
.sx-autocomplete__items { display: flex; flex-direction: column; gap: 1px; max-height: 280px; overflow: auto; overscroll-behavior: contain; }
.sx-autocomplete__item {
  display: block;
  width: 100%;
  padding: 7px 10px;
  margin: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  text-align: start;
  cursor: pointer;
}
.sx-autocomplete__item--active { background: var(--sx-accent-soft, rgba(31, 111, 198, 0.1)); }
.sx-autocomplete__empty {
  padding: 10px;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  color: var(--sx-text-3, #616a7d);
}
/* Indeterminate progress hairline while a lookup is in flight. */
.sx-autocomplete__busy {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  border-radius: var(--sx-radius-full, 9999px);
  border: 2px solid var(--sx-accent-soft-border, rgba(31, 111, 198, 0.28));
  border-top-color: var(--sx-accent, #1f6fc6);
  animation: sx-spin 700ms linear infinite;
}
/* sx-spin is defined once, in the SxButton block above. */
@media (prefers-reduced-motion: reduce) { .sx-autocomplete__busy { animation-duration: 2s; } }

/* ---------------------------------------------------------------------------------------------
   Calendar — shared by the popover and the Static variant.
   --------------------------------------------------------------------------------------------- */
.sx-datepicker--static,
.sx-timepicker--static {
  display: inline-block;
  background: var(--sx-surface-2, #ffffff);
  border: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08));
  border-radius: var(--sx-radius-md, 14px);
  box-shadow: var(--sx-edge, none), var(--sx-shadow-1, none);
}

.sx-cal { padding: 10px; width: 268px; box-sizing: border-box; }
.sx-cal__header { display: flex; align-items: center; justify-content: space-between; gap: 4px; margin-bottom: 6px; }
.sx-cal__title {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: 1 1 auto;
  justify-content: center;
  padding: 5px 8px;
  border: 0;
  border-radius: var(--sx-radius-sm, 10px);
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  font-weight: 600;
  cursor: pointer;
}
.sx-cal__title:hover { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); }
.sx-cal__title:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }

.sx-cal__grid { display: flex; flex-direction: column; gap: 2px; }
.sx-cal__row { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.sx-cal__weekday {
  display: grid;
  place-items: center;
  height: 26px;
  font-size: var(--sx-text-caption-size, 0.75rem);
  font-weight: 600;
  color: var(--sx-text-3, #616a7d);
}
.sx-cal__day {
  display: grid;
  place-items: center;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: var(--sx-radius-sm, 10px);
  background: transparent;
  color: var(--sx-text-1, #151a24);
  font: inherit;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.sx-cal__day:hover { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); }
.sx-cal__day:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-cal__day--outside { color: var(--sx-text-disabled, #a3a9b8); }
/* Today is a thin ring, not a fill — the filled state belongs to the selection alone. */
.sx-cal__day--today { box-shadow: inset 0 0 0 1px var(--sx-accent-soft-border, rgba(31, 111, 198, 0.28)); }
.sx-cal__day--selected {
  background: var(--sx-accent, #1f6fc6);
  color: var(--sx-accent-on, #fff);
  font-weight: 600;
}
.sx-cal__day--selected:hover { background: var(--sx-accent-hover, #1a63b3); }

.sx-cal__footer { display: flex; justify-content: space-between; gap: 8px; margin-top: 6px; }

/* The three steps (year → month → day) are pinned to one height: the panel is positioned once, on
   open, so a body that grew or shrank between steps would drift away from the field. */
.sx-cal__grid,
.sx-cal__months,
.sx-cal__years { min-height: 230px; }

/* Both drill-down steps are fixed-size pages, not scroll lists — the rows share the height evenly. */
.sx-cal__years,
.sx-cal__months {
  display: grid;
  grid-auto-rows: 1fr;
  gap: 2px;
}
.sx-cal__years { grid-template-columns: repeat(4, 1fr); }
.sx-cal__months { grid-template-columns: repeat(3, 1fr); }

.sx-cal__year,
.sx-cal__month {
  padding: 7px 4px;
  border: 0;
  border-radius: var(--sx-radius-sm, 10px);
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.sx-cal__year:hover,
.sx-cal__month:hover { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); }
.sx-cal__year:focus-visible,
.sx-cal__month:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
/* Years outside the selectable range keep the page's shape rather than leaving holes in the grid. */
.sx-cal__year:disabled { color: var(--sx-text-disabled, #a3a9b8); cursor: default; }
.sx-cal__year:disabled:hover { background: transparent; }
.sx-cal__year--current,
.sx-cal__month--current { background: var(--sx-accent, #1f6fc6); color: var(--sx-accent-on, #fff); font-weight: 600; }
.sx-cal__year--current:hover,
.sx-cal__month--current:hover { background: var(--sx-accent-hover, #1a63b3); }

/* ---------------------------------------------------------------------------------------------
   Time list — shared by the popover and the Static variant.
   --------------------------------------------------------------------------------------------- */
.sx-timelist {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px;
  min-width: 128px;
  max-height: 280px;
  overflow: auto;
  overscroll-behavior: contain;
}
.sx-timepicker--static .sx-timelist { max-height: 232px; }
.sx-timelist__item {
  padding: 7px 12px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  font-variant-numeric: tabular-nums;
  text-align: start;
  white-space: nowrap;
  cursor: pointer;
}
.sx-timelist__item:hover { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); }
.sx-timelist__item:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-timelist__item--selected { background: var(--sx-accent, #1f6fc6); color: var(--sx-accent-on, #fff); font-weight: 600; }
.sx-timelist__item:disabled { color: var(--sx-text-disabled, #a3a9b8); cursor: default; }

/* =============================================================================================
   TIER 4 — feedback & display (Phase 4)
   ============================================================================================= */

/* ---------------------------------------------------------------------------------------------
   SxChip — Soft is the default because 88% of these are quiet status labels.
   --------------------------------------------------------------------------------------------- */
.sx-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 100%;
  margin: 0;
  border: 1px solid transparent;
  border-radius: var(--sx-radius-full, 9999px);
  font-family: inherit;
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
  vertical-align: middle;
  box-sizing: border-box;
  transition: background-color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease),
              border-color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-chip--xs { min-height: 18px; padding: 0 7px;  font-size: 0.6875rem; --_chip-icon: 12px; }
.sx-chip--sm { min-height: 22px; padding: 0 9px;  font-size: 0.75rem;   --_chip-icon: 14px; }
.sx-chip--md { min-height: 26px; padding: 0 11px; font-size: 0.8125rem; --_chip-icon: 16px; }
.sx-chip--lg { min-height: 32px; padding: 0 14px; font-size: 0.875rem;  --_chip-icon: 18px; }
.sx-chip--xl { min-height: 38px; padding: 0 16px; font-size: 0.9375rem; --_chip-icon: 20px; }
.sx-chip .sx-chip__icon { --sx-icon-size: var(--_chip-icon, 14px); flex: 0 0 auto; }
.sx-chip__label { overflow: hidden; text-overflow: ellipsis; }

.sx-chip--soft    { background: var(--_chip-soft); color: var(--_chip-text); }
.sx-chip--outline { background: transparent; color: var(--_chip-text); border-color: var(--_chip-soft-border); }
.sx-chip--solid   { background: var(--_chip-base); color: var(--_chip-on); }

button.sx-chip { cursor: pointer; }
button.sx-chip:hover { filter: brightness(0.97); }
button.sx-chip:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-chip--selected { box-shadow: inset 0 0 0 1.5px var(--_chip-base); }
.sx-chip--disabled { opacity: 0.55; cursor: default; }
.sx-chip--disabled:hover { filter: none; }

.sx-chip__close {
  display: inline-grid;
  place-items: center;
  margin-inline-end: -3px;
  border-radius: var(--sx-radius-full, 9999px);
  cursor: pointer;
  opacity: 0.7;
}
.sx-chip__close:hover { opacity: 1; }
.sx-chip__close:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }

/* Tone ladder for chips. */
.sx-chip--t-default  { --_chip-base: var(--sx-neutral, #e3e7ee);      --_chip-soft: var(--sx-neutral-soft, rgba(16,24,40,0.06));       --_chip-soft-border: var(--sx-neutral-soft-border, rgba(16,24,40,0.16)); --_chip-text: var(--sx-text-1, #151a24);       --_chip-on: var(--sx-neutral-on, #151a24); }
.sx-chip--t-muted    { --_chip-base: var(--sx-neutral, #e3e7ee);      --_chip-soft: var(--sx-neutral-soft, rgba(16,24,40,0.06));       --_chip-soft-border: var(--sx-neutral-soft-border, rgba(16,24,40,0.16)); --_chip-text: var(--sx-text-2, #4b5565);       --_chip-on: var(--sx-neutral-on, #151a24); }
.sx-chip--t-accent   { --_chip-base: var(--sx-accent, #1f6fc6);       --_chip-soft: var(--sx-accent-soft, rgba(31,111,198,0.1));       --_chip-soft-border: var(--sx-accent-soft-border, rgba(31,111,198,0.28));  --_chip-text: var(--sx-accent-text, #1a63b3);  --_chip-on: var(--sx-accent-on, #fff); }
.sx-chip--t-accent2  { --_chip-base: var(--sx-accent2, #6d5bd0);      --_chip-soft: var(--sx-accent2-soft, rgba(109,91,208,0.1));      --_chip-soft-border: var(--sx-accent2-soft-border, rgba(109,91,208,0.28)); --_chip-text: var(--sx-accent2-text, #5b49c0); --_chip-on: var(--sx-accent2-on, #fff); }
.sx-chip--t-numeric  { --_chip-base: var(--sx-numeric, #0c8068);      --_chip-soft: var(--sx-numeric-soft, rgba(12,128,104,0.1));      --_chip-soft-border: var(--sx-numeric-soft-border, rgba(12,128,104,0.3));  --_chip-text: var(--sx-numeric-text, #0a6f5a); --_chip-on: var(--sx-text-on-status, #fff); }
.sx-chip--t-success  { --_chip-base: var(--sx-success, #177a4d);      --_chip-soft: var(--sx-success-soft, rgba(23,122,77,0.1));       --_chip-soft-border: var(--sx-success-soft-border, rgba(23,122,77,0.3));   --_chip-text: var(--sx-success-text, #136a42); --_chip-on: var(--sx-text-on-status, #fff); }
.sx-chip--t-warning  { --_chip-base: var(--sx-warning, #a85d08);      --_chip-soft: var(--sx-warning-soft, rgba(168,93,8,0.1));        --_chip-soft-border: var(--sx-warning-soft-border, rgba(168,93,8,0.3));    --_chip-text: var(--sx-warning-text, #8a4b00); --_chip-on: var(--sx-text-on-status, #fff); }
.sx-chip--t-danger   { --_chip-base: var(--sx-danger, #c93a3a);       --_chip-soft: var(--sx-danger-soft, rgba(201,58,58,0.1));        --_chip-soft-border: var(--sx-danger-soft-border, rgba(201,58,58,0.3));    --_chip-text: var(--sx-danger-text, #b42f2f);  --_chip-on: var(--sx-text-on-status, #fff); }
.sx-chip--t-info     { --_chip-base: var(--sx-info, #0b7a8f);        --_chip-soft: var(--sx-info-soft, rgba(11,122,143,0.1));         --_chip-soft-border: var(--sx-info-soft-border, rgba(11,122,143,0.3));     --_chip-text: var(--sx-info-text, #086a7c);    --_chip-on: var(--sx-text-on-status, #fff); }
.sx-chip--t-contrast { --_chip-base: var(--sx-contrast-bg, #1f2533);  --_chip-soft: var(--sx-neutral-soft, rgba(16,24,40,0.06));       --_chip-soft-border: var(--sx-neutral-soft-border, rgba(16,24,40,0.16)); --_chip-text: var(--sx-text-1, #151a24);       --_chip-on: var(--sx-contrast-text, #f3f5f9); }
.sx-chip--t-inherit  { --_chip-base: currentColor; --_chip-soft: transparent; --_chip-soft-border: currentColor; --_chip-text: inherit; --_chip-on: var(--sx-surface-1, #fff); }

.sx-chipset { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }

/* ---------------------------------------------------------------------------------------------
   SxAlert — compact by default (85 of 95 sites were Dense).
   --------------------------------------------------------------------------------------------- */
.sx-alert {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 9px 11px;
  border: 1px solid transparent;
  border-radius: var(--sx-radius-md, 14px);
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  line-height: 1.45;
  box-sizing: border-box;
}
.sx-alert--roomy { padding: 14px 16px; gap: 12px; }
.sx-alert__icon { flex: 0 0 auto; display: inline-flex; margin-top: 1px; }
.sx-alert__body { flex: 1 1 auto; min-width: 0; }
.sx-alert__close { flex: 0 0 auto; margin: -2px -4px 0 0; color: inherit; }

.sx-alert--soft    { background: var(--_alert-soft); color: var(--_alert-text); }
.sx-alert--outline { background: transparent; color: var(--_alert-text); border-color: var(--_alert-soft-border); }
.sx-alert--solid   { background: var(--_alert-base); color: var(--sx-text-on-status, #fff); }

.sx-alert--info    { --_alert-base: var(--sx-info, #0b7a8f);    --_alert-soft: var(--sx-info-soft, rgba(11,122,143,0.1));    --_alert-soft-border: var(--sx-info-soft-border, rgba(11,122,143,0.3));    --_alert-text: var(--sx-info-text, #086a7c); }
.sx-alert--success { --_alert-base: var(--sx-success, #177a4d); --_alert-soft: var(--sx-success-soft, rgba(23,122,77,0.1));   --_alert-soft-border: var(--sx-success-soft-border, rgba(23,122,77,0.3));  --_alert-text: var(--sx-success-text, #136a42); }
.sx-alert--warning { --_alert-base: var(--sx-warning, #a85d08); --_alert-soft: var(--sx-warning-soft, rgba(168,93,8,0.1));    --_alert-soft-border: var(--sx-warning-soft-border, rgba(168,93,8,0.3));   --_alert-text: var(--sx-warning-text, #8a4b00); }
.sx-alert--danger  { --_alert-base: var(--sx-danger, #c93a3a);  --_alert-soft: var(--sx-danger-soft, rgba(201,58,58,0.1));    --_alert-soft-border: var(--sx-danger-soft-border, rgba(201,58,58,0.3));   --_alert-text: var(--sx-danger-text, #b42f2f); }

/* ---------------------------------------------------------------------------------------------
   SxBanner — page-level, pinned. The layer is a token, not a number in a Style string.
   --------------------------------------------------------------------------------------------- */
.sx-banner {
  position: fixed;
  inset-inline: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 640px;
  margin-inline: auto;
  padding: 10px 12px;
  border: 1px solid var(--sx-glass-border, rgba(255, 255, 255, 0.6));
  border-radius: var(--sx-radius-lg, 18px);
  background: var(--sx-glass-bg-fallback, #fbfcfe);
  box-shadow: var(--sx-edge, none), var(--sx-shadow-4, 0 12px 32px -8px rgba(0, 0, 0, 0.2));
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  line-height: 1.4;
  box-sizing: border-box;
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .sx-banner {
    background: var(--sx-glass-bg, rgba(255, 255, 255, 0.7));
    -webkit-backdrop-filter: var(--sx-glass-filter, blur(20px));
    backdrop-filter: var(--sx-glass-filter, blur(20px));
  }
}
.sx-banner--top { top: 12px; }
/* Clear of MainLayout's bottom app bar, whose height is a token now rather than a hard-coded 48px. */
.sx-banner--bottom { bottom: calc(var(--sx-appbar-h, 48px) + 12px); }
.sx-banner__icon { flex: 0 0 auto; display: inline-flex; }
.sx-banner__body { flex: 1 1 auto; min-width: 0; }
.sx-banner__actions { flex: 0 0 auto; display: flex; gap: 6px; }
.sx-banner__close { flex: 0 0 auto; }
.sx-banner--info    .sx-banner__icon { color: var(--sx-info-text, #086a7c); }
.sx-banner--success .sx-banner__icon { color: var(--sx-success-text, #136a42); }
.sx-banner--warning .sx-banner__icon { color: var(--sx-warning-text, #8a4b00); }
.sx-banner--danger  .sx-banner__icon { color: var(--sx-danger-text, #b42f2f); }

/* ---------------------------------------------------------------------------------------------
   SxSpinner — CSS only. Reduced motion slows it; a stopped spinner reads as a hang.
   --------------------------------------------------------------------------------------------- */
.sx-spinner {
  display: inline-block;
  flex: 0 0 auto;
  box-sizing: border-box;
  border-radius: var(--sx-radius-full, 9999px);
  border-style: solid;
  border-color: var(--_spin-track);
  border-top-color: var(--_spin);
  animation: sx-spin 700ms linear infinite;
  vertical-align: middle;
}
.sx-spinner--xs { width: 12px; height: 12px; border-width: 1.5px; }
.sx-spinner--sm { width: 16px; height: 16px; border-width: 2px; }
.sx-spinner--md { width: 22px; height: 22px; border-width: 2.5px; }
.sx-spinner--lg { width: 32px; height: 32px; border-width: 3px; }
.sx-spinner--xl { width: 44px; height: 44px; border-width: 4px; }

.sx-spinner--t-accent   { --_spin: var(--sx-accent, #1f6fc6);   --_spin-track: var(--sx-accent-soft, rgba(31,111,198,0.18)); }
.sx-spinner--t-accent2  { --_spin: var(--sx-accent2, #6d5bd0);  --_spin-track: var(--sx-accent2-soft, rgba(109,91,208,0.18)); }
.sx-spinner--t-numeric  { --_spin: var(--sx-numeric, #0c8068);  --_spin-track: var(--sx-numeric-soft, rgba(12,128,104,0.18)); }
.sx-spinner--t-success  { --_spin: var(--sx-success, #177a4d);  --_spin-track: var(--sx-success-soft, rgba(23,122,77,0.18)); }
.sx-spinner--t-warning  { --_spin: var(--sx-warning, #a85d08);  --_spin-track: var(--sx-warning-soft, rgba(168,93,8,0.18)); }
.sx-spinner--t-danger   { --_spin: var(--sx-danger, #c93a3a);   --_spin-track: var(--sx-danger-soft, rgba(201,58,58,0.18)); }
.sx-spinner--t-info     { --_spin: var(--sx-info, #0b7a8f);     --_spin-track: var(--sx-info-soft, rgba(11,122,143,0.18)); }
.sx-spinner--t-default  { --_spin: var(--sx-text-2, #4b5565);   --_spin-track: var(--sx-neutral-soft, rgba(16,24,40,0.1)); }
.sx-spinner--t-muted    { --_spin: var(--sx-text-3, #616a7d);   --_spin-track: var(--sx-neutral-soft, rgba(16,24,40,0.1)); }
.sx-spinner--t-contrast { --_spin: var(--sx-contrast-bg, #1f2533); --_spin-track: var(--sx-neutral-soft, rgba(16,24,40,0.1)); }
.sx-spinner--t-inherit  { --_spin: currentColor; --_spin-track: color-mix(in srgb, currentColor 22%, transparent); }

@media (prefers-reduced-motion: reduce) { .sx-spinner { animation-duration: 2.4s; } }

/* ---------------------------------------------------------------------------------------------
   SxProgressBar
   --------------------------------------------------------------------------------------------- */
.sx-progress {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 4px;
  border-radius: var(--sx-radius-full, 9999px);
  background: var(--sx-neutral-soft, rgba(16, 24, 40, 0.08));
}
.sx-progress--thick { height: 8px; }
.sx-progress__fill {
  height: 100%;
  border-radius: inherit;
  background: var(--_bar, var(--sx-accent, #1f6fc6));
  transition: width var(--sx-dur-base, 200ms) var(--sx-ease-out, ease);
}
.sx-progress--indeterminate .sx-progress__fill {
  width: 40%;
  animation: sx-progress-sweep 1.4s var(--sx-ease-in-out, ease-in-out) infinite;
}
@keyframes sx-progress-sweep {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(300%); }
}
@media (prefers-reduced-motion: reduce) {
  .sx-progress--indeterminate .sx-progress__fill { animation-duration: 3.5s; }
}
.sx-progress--t-accent   { --_bar: var(--sx-accent, #1f6fc6); }
.sx-progress--t-accent2  { --_bar: var(--sx-accent2, #6d5bd0); }
.sx-progress--t-numeric  { --_bar: var(--sx-numeric, #0c8068); }
.sx-progress--t-success  { --_bar: var(--sx-success, #177a4d); }
.sx-progress--t-warning  { --_bar: var(--sx-warning, #a85d08); }
.sx-progress--t-danger   { --_bar: var(--sx-danger, #c93a3a); }
.sx-progress--t-info     { --_bar: var(--sx-info, #0b7a8f); }
.sx-progress--t-default  { --_bar: var(--sx-text-2, #4b5565); }
.sx-progress--t-muted    { --_bar: var(--sx-text-3, #616a7d); }
.sx-progress--t-contrast { --_bar: var(--sx-contrast-bg, #1f2533); }
.sx-progress--t-inherit  { --_bar: currentColor; }

/* ---------------------------------------------------------------------------------------------
   SxSkeleton — one animation (a sweep), settling to a static tint under reduced motion.
   --------------------------------------------------------------------------------------------- */
.sx-skeleton {
  display: block;
  width: 100%;
  background: var(--sx-skeleton, rgba(16, 24, 40, 0.07));
  border-radius: var(--sx-radius-sm, 10px);
}
.sx-skeleton--text { height: 1em; margin-block: 0.2em; border-radius: var(--sx-radius-xs, 6px); }
.sx-skeleton--rect { height: 100px; }
.sx-skeleton--circle { width: 40px; height: 40px; border-radius: var(--sx-radius-full, 9999px); }

.sx-skeleton--animate {
  position: relative;
  overflow: hidden;
}
.sx-skeleton--animate::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--sx-skeleton-shine, rgba(255, 255, 255, 0.6)), transparent);
  animation: sx-skeleton-sweep 1.5s ease-in-out infinite;
}
@keyframes sx-skeleton-sweep { 100% { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .sx-skeleton--animate::after { animation: none; } }

/* ---------------------------------------------------------------------------------------------
   SxAvatar — circular initials. No image variant exists in the app.
   --------------------------------------------------------------------------------------------- */
.sx-avatar {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  box-sizing: border-box;
  border-radius: var(--sx-radius-full, 9999px);
  background: var(--_av-bg);
  color: var(--_av-fg);
  font-weight: 600;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  overflow: hidden;
  user-select: none;
}
.sx-avatar--rounded { border-radius: var(--sx-radius-md, 14px); }
.sx-avatar--xs { width: 22px; height: 22px; font-size: 0.625rem; }
.sx-avatar--sm { width: 28px; height: 28px; font-size: 0.6875rem; }
.sx-avatar--md { width: 36px; height: 36px; font-size: 0.8125rem; }
.sx-avatar--lg { width: 46px; height: 46px; font-size: 1rem; }
.sx-avatar--xl { width: 58px; height: 58px; font-size: 1.25rem; }

.sx-avatar--t-default  { --_av-bg: var(--sx-neutral, #e3e7ee);     --_av-fg: var(--sx-text-1, #151a24); }
.sx-avatar--t-muted    { --_av-bg: var(--sx-neutral-soft, rgba(16,24,40,0.08)); --_av-fg: var(--sx-text-2, #4b5565); }
.sx-avatar--t-accent   { --_av-bg: var(--sx-accent, #1f6fc6);      --_av-fg: var(--sx-accent-on, #fff); }
.sx-avatar--t-accent2  { --_av-bg: var(--sx-accent2, #6d5bd0);     --_av-fg: var(--sx-accent2-on, #fff); }
.sx-avatar--t-numeric  { --_av-bg: var(--sx-numeric, #0c8068);     --_av-fg: var(--sx-text-on-status, #fff); }
.sx-avatar--t-success  { --_av-bg: var(--sx-success, #177a4d);     --_av-fg: var(--sx-text-on-status, #fff); }
.sx-avatar--t-warning  { --_av-bg: var(--sx-warning, #a85d08);     --_av-fg: var(--sx-text-on-status, #fff); }
.sx-avatar--t-danger   { --_av-bg: var(--sx-danger, #c93a3a);      --_av-fg: var(--sx-text-on-status, #fff); }
.sx-avatar--t-info     { --_av-bg: var(--sx-info, #0b7a8f);        --_av-fg: var(--sx-text-on-status, #fff); }
.sx-avatar--t-contrast { --_av-bg: var(--sx-contrast-bg, #1f2533); --_av-fg: var(--sx-contrast-text, #f3f5f9); }
.sx-avatar--t-inherit  { --_av-bg: transparent; --_av-fg: inherit; }

/* ---------------------------------------------------------------------------------------------
   SxBadge — counts cap at Max ("99+"), which MudBadge could not do.
   --------------------------------------------------------------------------------------------- */
.sx-badge { position: relative; display: inline-flex; vertical-align: middle; }
.sx-badge__mark {
  position: absolute;
  z-index: 1;
  display: inline-grid;
  place-items: center;
  min-width: 17px;
  height: 17px;
  padding: 0 5px;
  box-sizing: border-box;
  border-radius: var(--sx-radius-full, 9999px);
  background: var(--_badge, var(--sx-danger, #c93a3a));
  color: var(--sx-text-on-status, #fff);
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.sx-badge__mark--dot { min-width: 9px; width: 9px; height: 9px; padding: 0; }
.sx-badge__mark--bordered { box-shadow: 0 0 0 2px var(--sx-surface-2, #fff); }
.sx-badge__mark--top-end      { top: 0; inset-inline-end: 0; transform: translate(35%, -35%); }
.sx-badge__mark--top-start    { top: 0; inset-inline-start: 0; transform: translate(-35%, -35%); }
.sx-badge__mark--bottom-end   { bottom: 0; inset-inline-end: 0; transform: translate(35%, 35%); }
.sx-badge__mark--bottom-start { bottom: 0; inset-inline-start: 0; transform: translate(-35%, 35%); }

.sx-badge__mark--t-accent   { --_badge: var(--sx-accent, #1f6fc6); }
.sx-badge__mark--t-accent2  { --_badge: var(--sx-accent2, #6d5bd0); }
.sx-badge__mark--t-numeric  { --_badge: var(--sx-numeric, #0c8068); }
.sx-badge__mark--t-success  { --_badge: var(--sx-success, #177a4d); }
.sx-badge__mark--t-warning  { --_badge: var(--sx-warning, #a85d08); }
.sx-badge__mark--t-danger   { --_badge: var(--sx-danger, #c93a3a); }
.sx-badge__mark--t-info     { --_badge: var(--sx-info, #0b7a8f); }
.sx-badge__mark--t-default  { --_badge: var(--sx-neutral, #e3e7ee); color: var(--sx-text-1, #151a24); }
.sx-badge__mark--t-muted    { --_badge: var(--sx-text-3, #616a7d); }
.sx-badge__mark--t-contrast { --_badge: var(--sx-contrast-bg, #1f2533); color: var(--sx-contrast-text, #f3f5f9); }
.sx-badge__mark--t-inherit  { --_badge: currentColor; }

/* ---------------------------------------------------------------------------------------------
   Phase 5+ components are appended below this line.
   --------------------------------------------------------------------------------------------- */
/* =============================================================================================
   TIER 5 — containers & navigation (Phase 5)
   ============================================================================================= */

/* ---------------------------------------------------------------------------------------------
   SxLayout · SxContainer — the positioning root and the width cap.
   --------------------------------------------------------------------------------------------- */
.sx-layout {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  /* Deliberately NOT `isolation: isolate`. That would make the layout a stacking context, and
     MainLayout renders the employee-login SxOverlay at z 9999 INSIDE it precisely so it covers
     everything — including the dialog / snackbar / popover providers, which are siblings of the
     layout at z 1350-1600. Isolating here would cap that overlay at the layout's own level. */
}

.sx-container {
  width: 100%;
  margin-inline: auto;
  padding-inline: var(--sx-space-4, 16px);
}
.sx-container--xs   { max-width: 444px; }
.sx-container--sm   { max-width: 600px; }
.sx-container--md   { max-width: 960px; }
.sx-container--lg   { max-width: 1280px; }
.sx-container--xl   { max-width: 1920px; }
.sx-container--none { max-width: none; }

/* ---------------------------------------------------------------------------------------------
   SxCard — SxSurface plus the rhythm between header / content / actions. The zones divide
   themselves: a hairline only appears where two zones actually meet.
   --------------------------------------------------------------------------------------------- */
.sx-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;   /* so the zones' square corners are clipped by the card's radius */
}

.sx-card__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sx-space-3, 12px);
  padding: var(--sx-space-4, 16px) var(--sx-space-4, 16px) var(--sx-space-3, 12px);
}
.sx-card__header-main { min-width: 0; flex: 1 1 auto; }
.sx-card__header-actions { display: flex; align-items: center; gap: var(--sx-space-1, 4px); flex: 0 0 auto; }

.sx-card__content { padding: var(--sx-space-4, 16px); }
.sx-card__header + .sx-card__content { padding-top: 0; }

.sx-card__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--sx-space-2, 8px);
  padding: var(--sx-space-3, 12px) var(--sx-space-4, 16px);
  border-top: 1px solid var(--sx-divider, rgba(16, 24, 40, 0.07));
}
.sx-card__actions--start { justify-content: flex-start; }

/* ---------------------------------------------------------------------------------------------
   SxCollapse — height animation without measuring anything. grid-template-rows 0fr -> 1fr works
   on content of unknown height, which max-height cannot do without an arbitrary magic number.
   --------------------------------------------------------------------------------------------- */
.sx-collapse {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--sx-dur-base, 200ms) var(--sx-ease-out, ease);
}
.sx-collapse--open { grid-template-rows: 1fr; }

.sx-collapse__inner {
  overflow: hidden;
  min-height: 0;   /* required: a grid item's default min-height:auto defeats the 0fr row */
}

/* A collapsed panel must not be a tab stop. visibility:hidden takes its subtree out of the tab
   order; it is re-shown only once the row has finished opening so the content is never clipped
   mid-animation. */
.sx-collapse:not(.sx-collapse--open) > .sx-collapse__inner {
  visibility: hidden;
  transition: visibility 0s linear var(--sx-dur-base, 200ms);
}

@media (prefers-reduced-motion: reduce) {
  .sx-collapse { transition: none; }
  .sx-collapse:not(.sx-collapse--open) > .sx-collapse__inner { transition: none; }
}

/* ---------------------------------------------------------------------------------------------
   SxExpansionPanels / SxExpansionPanel — a disclosure list. The header is a real button, which
   MudExpansionPanel's div never was.
   --------------------------------------------------------------------------------------------- */
.sx-expansion {
  display: flex;
  flex-direction: column;
  border-radius: var(--sx-radius-md, 14px);
  background: var(--sx-surface-1, #fbfcfe);
  overflow: hidden;
}
.sx-expansion--outline { border: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08)); }
.sx-expansion--e0 { box-shadow: var(--sx-shadow-0, none); }
.sx-expansion--e1 { box-shadow: var(--sx-shadow-1); }
.sx-expansion--e2 { box-shadow: var(--sx-shadow-2); }
.sx-expansion--e3 { box-shadow: var(--sx-shadow-3); }
.sx-expansion--e4 { box-shadow: var(--sx-shadow-4); }
.sx-expansion--e5 { box-shadow: var(--sx-shadow-5); }

.sx-expansion__panel + .sx-expansion__panel {
  border-top: 1px solid var(--sx-divider, rgba(16, 24, 40, 0.07));
}

.sx-expansion__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sx-space-3, 12px);
  width: 100%;
  min-height: var(--sx-touch-min, 44px);
  padding: var(--sx-space-3, 12px) var(--sx-space-4, 16px);
  border: 0;
  background: transparent;
  color: var(--sx-text-1, #151a24);
  font: inherit;
  text-align: start;
  cursor: pointer;
  transition: background var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-expansion__header:hover { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); }
.sx-expansion__header:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-expansion__header:disabled { cursor: default; color: var(--sx-text-disabled, #a3a9b8); }

.sx-expansion__title { min-width: 0; flex: 1 1 auto; }
.sx-expansion__title-text { font-weight: 500; }

.sx-expansion__chevron {
  flex: 0 0 auto;
  color: var(--sx-text-3, #616a7d);
  transition: transform var(--sx-dur-base, 200ms) var(--sx-ease-out, ease);
}
.sx-expansion__panel--open .sx-expansion__chevron { transform: rotate(180deg); }

.sx-expansion__body-inner { padding: 0 var(--sx-space-4, 16px) var(--sx-space-4, 16px); }

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

/* ---------------------------------------------------------------------------------------------
   SxTabs — the strip, the hidden registry and the panel region.
   The registry holds every SxTabPanel component so the strip can enumerate them; none of them
   renders markup, so it collapses to nothing, but display:none keeps it out of layout regardless.
   --------------------------------------------------------------------------------------------- */
.sx-tabs { display: flex; flex-direction: column; min-height: 0; }
.sx-tabs--outline {
  border: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08));
  border-radius: var(--sx-radius-md, 14px);
  overflow: hidden;
}
.sx-tabs__registry { display: none; }

.sx-tabs__bar {
  display: flex;
  gap: var(--sx-space-1, 4px);
  padding-inline: var(--sx-space-1, 4px);
  border-bottom: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08));
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
}
.sx-tabs--full .sx-tabs__bar > .sx-tabs__tab { flex: 1 1 0; justify-content: center; }

.sx-tabs__tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--sx-space-2, 8px);
  flex: 0 0 auto;
  min-height: var(--sx-touch-min, 44px);
  padding: var(--sx-space-2, 8px) var(--sx-space-3, 12px);
  border: 0;
  background: transparent;
  color: var(--sx-text-2, #4b5565);
  font: inherit;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-tabs__tab:hover { color: var(--sx-text-1, #151a24); }
.sx-tabs__tab:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); border-radius: var(--sx-radius-xs, 6px); }
.sx-tabs__tab--disabled, .sx-tabs__tab:disabled { color: var(--sx-text-disabled, #a3a9b8); cursor: default; }
.sx-tabs__tab--active { color: var(--sx-accent-text, #1a5ea8); }

/* The active indicator is a thin, narrow underline rather than a full-width bar — the repo's
   stated preference for subtle active states (feedback_ui_subtlety). */
.sx-tabs__tab--active::after {
  content: "";
  position: absolute;
  inset-inline: var(--sx-space-3, 12px);
  bottom: -1px;
  height: 2px;
  border-radius: var(--sx-radius-full, 9999px);
  background: var(--sx-accent, #1f6fc6);
}

.sx-tabs__tab-icon { flex: 0 0 auto; }
.sx-tabs__tab-text { min-width: 0; }
.sx-tabs__panel { min-height: 0; flex: 1 1 auto; }

/* ---------------------------------------------------------------------------------------------
   SxTable / SxDataTable — one set of rules for both. Compact rows are the default because all 22
   MudSimpleTable sites and all 3 MudTable sites were Dense.
   --------------------------------------------------------------------------------------------- */
.sx-table-wrap {
  width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
}
.sx-table-wrap--sticky { overflow-y: auto; }

.sx-table {
  width: 100%;
  border-collapse: separate;   /* separate, not collapse: a sticky header needs its own borders */
  border-spacing: 0;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  color: var(--sx-text-1, #151a24);
}

.sx-table th,
.sx-table td {
  padding: var(--sx-space-2, 8px) var(--sx-space-3, 12px);
  text-align: start;
  vertical-align: middle;
  border-bottom: 1px solid var(--sx-divider, rgba(16, 24, 40, 0.07));
}
.sx-table--roomy th,
.sx-table--roomy td { padding: var(--sx-space-3, 12px) var(--sx-space-4, 16px); }

.sx-table thead th {
  font-size: var(--sx-text-caption-size, 0.75rem);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--sx-text-3, #616a7d);
  white-space: nowrap;
  background: var(--sx-surface-1, #fbfcfe);
  border-bottom-color: var(--sx-line, rgba(16, 24, 40, 0.08));
}

.sx-table-wrap--sticky .sx-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;   /* beats its own rows AND a pinned body cell (z 1); the pane's own layer is --sx-z-sticky */
}

.sx-table tfoot td {
  font-weight: 600;
  border-top: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08));
  border-bottom: 0;
  background: var(--sx-surface-1, #fbfcfe);
}

.sx-table tbody tr:last-child > td { border-bottom: 0; }

.sx-table--striped tbody tr:nth-child(even) > td { background: var(--sx-surface-sunken, #eceff5); }
.sx-table--hover tbody tr:hover > td { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); }
.sx-table--bordered th,
.sx-table--bordered td { border: 1px solid var(--sx-divider, rgba(16, 24, 40, 0.07)); }

.sx-table__cell--end { text-align: end; }
.sx-table__state > td { padding-block: var(--sx-space-6, 24px); text-align: center; color: var(--sx-text-3, #616a7d); }

.sx-table__pager {
  display: flex;
  justify-content: flex-end;
  padding: var(--sx-space-2, 8px) var(--sx-space-3, 12px);
}

/* Column sort control. A real button, so the column is keyboard-sortable — MudTableSortLabel
   rendered a div and was not. The chevron is always present so the header does not reflow when a
   column becomes the active sort. */
.sx-sort {
  display: inline-flex;
  align-items: center;
  gap: var(--sx-space-1, 4px);
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}
.sx-sort:hover { color: var(--sx-text-1, #151a24); }
.sx-sort:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); border-radius: var(--sx-radius-xs, 6px); }
.sx-sort__icon { opacity: 0.35; transition: opacity var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease); }
.sx-sort:hover .sx-sort__icon { opacity: 0.7; }
.sx-sort--active { color: var(--sx-accent-text, #1a5ea8); }
.sx-sort--active .sx-sort__icon { opacity: 1; }

/* Pager */
.sx-pager {
  display: flex;
  align-items: center;
  gap: var(--sx-space-3, 12px);
  font-size: var(--sx-text-caption-size, 0.75rem);
  color: var(--sx-text-3, #616a7d);
}
.sx-pager__size { display: inline-flex; align-items: center; gap: var(--sx-space-2, 8px); }
.sx-pager__select {
  padding: 2px var(--sx-space-2, 8px);
  border: 1px solid var(--sx-line-input, rgba(16, 24, 40, 0.48));
  border-radius: var(--sx-radius-xs, 6px);
  background: var(--sx-surface-2, #fff);
  color: var(--sx-text-1, #151a24);
  font: inherit;
}
.sx-pager__select:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-pager__range { white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Stacked mobile layout. Each row becomes a card and every cell is labelled from its data-label,
   which is exactly what MudTable's DataLabel did. Off when the table sets Responsive="false". */
@media (max-width: 599px) {
  .sx-table--responsive thead { display: none; }
  .sx-table--responsive tbody tr {
    display: block;
    margin-bottom: var(--sx-space-3, 12px);
    border: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08));
    border-radius: var(--sx-radius-sm, 10px);
    overflow: hidden;
  }
  .sx-table--responsive tbody td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sx-space-3, 12px);
    text-align: end;
  }
  .sx-table--responsive tbody td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    font-size: var(--sx-text-caption-size, 0.75rem);
    font-weight: 600;
    color: var(--sx-text-3, #616a7d);
    text-align: start;
  }
  .sx-table--responsive tbody td[data-label=""]::before,
  .sx-table--responsive tbody td:not([data-label])::before { content: none; }
}

/* ---------------------------------------------------------------------------------------------
   SxAppBar / SxToolbar
   --------------------------------------------------------------------------------------------- */
.sx-appbar {
  position: fixed;
  inset-inline: 0;
  z-index: var(--sx-z-appbar, 1300);
  display: flex;
  align-items: center;
  gap: var(--sx-space-1, 4px);
  height: var(--sx-appbar-h, 48px);
  padding-inline: var(--sx-space-2, 8px);
  /* Opaque, NOT the glass treatment. A bar that scrolling content passes under has to stay
     legible, and backdrop-filter on an always-on-screen fixed element stalls Chrome's screenshot
     capture outright (the same class of gotcha as the background-attachment: fixed one Phase 2
     removed) — which costs us the gallery as a review surface. */
  background: var(--sx-surface-2, #ffffff);
  color: var(--sx-text-1, #151a24);
  border-bottom: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08));
}
.sx-appbar--top { top: 0; }
.sx-appbar--bottom {
  top: auto;
  bottom: 0;
  border-bottom: 0;
  border-top: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08));
}
.sx-appbar--static { position: static; }
.sx-appbar--roomy { height: 64px; }
.sx-appbar--e0 { box-shadow: var(--sx-shadow-0, none); }
.sx-appbar--e1 { box-shadow: var(--sx-shadow-1); }
.sx-appbar--e2 { box-shadow: var(--sx-shadow-2); }
.sx-appbar--e3 { box-shadow: var(--sx-shadow-3); }
.sx-appbar--e4 { box-shadow: var(--sx-shadow-4); }
.sx-appbar--e5 { box-shadow: var(--sx-shadow-5); }

.sx-toolbar {
  display: flex;
  align-items: center;
  gap: var(--sx-space-2, 8px);
  min-height: var(--sx-touch-min, 44px);
  padding-inline: var(--sx-space-3, 12px);
}
.sx-toolbar--roomy { min-height: 60px; }
.sx-toolbar--wrap { flex-wrap: wrap; }
.sx-toolbar--flush { padding-inline: 0; }

/* ---------------------------------------------------------------------------------------------
   SxDrawer — temporary only: it overlays, it never pushes the page.
   --------------------------------------------------------------------------------------------- */
.sx-drawer { position: fixed; inset: 0; z-index: var(--sx-z-drawer, 1320); pointer-events: none; }
.sx-drawer--open { pointer-events: auto; }

.sx-drawer__scrim {
  position: absolute;
  inset: 0;
  background: var(--sx-scrim, rgba(15, 20, 35, 0.45));
  animation: sx-fade-in var(--sx-dur-base, 200ms) var(--sx-ease-out, ease);
}

.sx-drawer__panel {
  position: absolute;
  top: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  width: min(320px, 85vw);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--sx-surface-2, #fff);
  color: var(--sx-text-1, #151a24);
  transition: transform var(--sx-dur-base, 200ms) var(--sx-ease-out, ease);
  visibility: hidden;   /* closed: out of the tab order, not merely off-screen */
}
.sx-drawer__panel--left  { inset-inline-start: 0; transform: translateX(-100%); box-shadow: var(--sx-shadow-4); }
.sx-drawer__panel--right { inset-inline-end: 0;   transform: translateX(100%);  box-shadow: var(--sx-shadow-4); }
.sx-drawer--open .sx-drawer__panel { transform: translateX(0); visibility: visible; }

.sx-drawer__panel--e0 { box-shadow: var(--sx-shadow-0, none); }
.sx-drawer__panel--e1 { box-shadow: var(--sx-shadow-1); }
.sx-drawer__panel--e2 { box-shadow: var(--sx-shadow-2); }
.sx-drawer__panel--e3 { box-shadow: var(--sx-shadow-3); }
.sx-drawer__panel--e5 { box-shadow: var(--sx-shadow-5); }

.sx-drawer__header {
  display: flex;
  align-items: center;
  gap: var(--sx-space-3, 12px);
  min-height: var(--sx-appbar-h, 48px);
  padding: var(--sx-space-3, 12px) var(--sx-space-4, 16px);
  border-bottom: 1px solid var(--sx-divider, rgba(16, 24, 40, 0.07));
}

@keyframes sx-fade-in { from { opacity: 0; } to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .sx-drawer__panel { transition: none; }
  .sx-drawer__scrim { animation: none; }
}

/* ---------------------------------------------------------------------------------------------
   SxNavMenu / SxNavLink — a link and an action row have to look identical, so both selectors
   carry the whole rule set rather than relying on one element type.
   --------------------------------------------------------------------------------------------- */
.sx-navmenu { display: flex; flex-direction: column; padding-block: var(--sx-space-2, 8px); }

.sx-navlink {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sx-space-3, 12px);
  width: 100%;
  min-height: var(--sx-touch-min, 44px);
  padding: var(--sx-space-2, 8px) var(--sx-space-4, 16px);
  border: 0;
  background: transparent;
  color: var(--sx-text-2, #4b5565);
  font: inherit;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  text-align: start;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease),
              color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-navlink:hover { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); color: var(--sx-text-1, #151a24); }
.sx-navlink:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-navlink--disabled, .sx-navlink:disabled { color: var(--sx-text-disabled, #a3a9b8); cursor: default; background: transparent; }

.sx-navlink__icon { flex: 0 0 auto; color: var(--sx-text-3, #616a7d); }
.sx-navlink__text { min-width: 0; flex: 1 1 auto; }

/* Active: a thin, short rail on the leading edge and a faint tint — subtle by default, per
   feedback_ui_subtlety. The rail colour follows the menu's Tone. */
.sx-navlink--active { color: var(--_nav, var(--sx-accent-text, #1a5ea8)); font-weight: 600; }
.sx-navlink--active .sx-navlink__icon { color: inherit; }
.sx-navlink--active::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 50%;
  translate: 0 -50%;
  width: 3px;
  height: 55%;
  border-radius: 0 var(--sx-radius-full, 9999px) var(--sx-radius-full, 9999px) 0;
  background: var(--_nav, var(--sx-accent, #1f6fc6));
}

.sx-navlink--t-accent   { --_nav: var(--sx-accent-text, #1a5ea8); }
.sx-navlink--t-accent2  { --_nav: var(--sx-accent2-text, #5a49b8); }
.sx-navlink--t-numeric  { --_nav: var(--sx-numeric-text, #0a6f5a); }
.sx-navlink--t-success  { --_nav: var(--sx-success-text, #146b44); }
.sx-navlink--t-warning  { --_nav: var(--sx-warning-text, #8a4c06); }
.sx-navlink--t-danger   { --_nav: var(--sx-danger-text, #a83030); }
.sx-navlink--t-info     { --_nav: var(--sx-info-text, #096577); }
.sx-navlink--t-default  { --_nav: var(--sx-text-1, #151a24); }
.sx-navlink--t-muted    { --_nav: var(--sx-text-2, #4b5565); }
.sx-navlink--t-contrast { --_nav: var(--sx-contrast-bg, #1f2533); }
.sx-navlink--t-inherit  { --_nav: currentColor; }

/* ---------------------------------------------------------------------------------------------
   SxList / SxListItem — the row is a button when it has an OnClick, a div when it does not.
   --------------------------------------------------------------------------------------------- */
.sx-list { margin: 0; padding: var(--sx-space-1, 4px) 0; list-style: none; }
.sx-list--flush { padding: 0; }

.sx-list__item { display: block; }

.sx-list__row {
  display: flex;
  align-items: center;
  gap: var(--sx-space-3, 12px);
  width: 100%;
  min-height: 40px;
  padding: var(--sx-space-2, 8px) var(--sx-space-4, 16px);
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: start;
}
.sx-list--roomy .sx-list__row { min-height: var(--sx-touch-min, 44px); padding-block: var(--sx-space-3, 12px); }
.sx-list--flush .sx-list__row { padding-inline: 0; }

.sx-list__item--clickable > .sx-list__row {
  cursor: pointer;
  border-radius: var(--sx-radius-sm, 10px);
  transition: background var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-list__item--clickable > .sx-list__row:hover { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); }
.sx-list__item--clickable > .sx-list__row:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-list__item--disabled > .sx-list__row { color: var(--sx-text-disabled, #a3a9b8); cursor: default; background: transparent; }
.sx-list__item--disabled > .sx-list__row:hover { background: transparent; }

.sx-list__item--selected > .sx-list__row {
  background: var(--sx-accent-soft, rgba(31, 111, 198, 0.10));
  color: var(--sx-accent-text, #1a5ea8);
  font-weight: 600;
}

.sx-list__icon { flex: 0 0 auto; }
.sx-list__body { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.sx-list__text { min-width: 0; }
.sx-list__secondary { font-size: var(--sx-text-caption-size, 0.75rem); color: var(--sx-text-3, #616a7d); }

/* ---------------------------------------------------------------------------------------------
   SxPagination
   --------------------------------------------------------------------------------------------- */
.sx-pagination { display: flex; align-items: center; justify-content: center; gap: var(--sx-space-1, 4px); flex-wrap: wrap; }

.sx-pagination__page {
  min-width: 32px;
  height: 32px;
  padding-inline: var(--sx-space-2, 8px);
  border: 0;
  border-radius: var(--sx-radius-sm, 10px);
  background: transparent;
  color: var(--sx-text-2, #4b5565);
  font: inherit;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-pagination__page:hover { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); color: var(--sx-text-1, #151a24); }
.sx-pagination__page:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-pagination__page--current {
  background: var(--sx-accent-soft, rgba(31, 111, 198, 0.10));
  color: var(--sx-accent-text, #1a5ea8);
  font-weight: 600;
}
.sx-pagination__gap { padding-inline: var(--sx-space-1, 4px); color: var(--sx-text-3, #616a7d); }

/* ---------------------------------------------------------------------------------------------
   SxImage · SxLink · SxFab
   --------------------------------------------------------------------------------------------- */
.sx-image { display: block; max-width: 100%; height: auto; }

.sx-link {
  display: inline;
  padding: 0;
  border: 0;
  background: transparent;
  font: inherit;
  color: var(--_link, var(--sx-accent-text, #1a5ea8));
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
  cursor: pointer;
}
.sx-link:hover { text-decoration-thickness: 2px; }
.sx-link:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); border-radius: var(--sx-radius-xs, 6px); }
.sx-link--subtle { text-decoration: none; }
.sx-link--subtle:hover, .sx-link--subtle:focus-visible { text-decoration: underline; }
.sx-link--disabled { color: var(--sx-text-disabled, #a3a9b8); cursor: default; text-decoration: none; }

.sx-link--t-accent   { --_link: var(--sx-accent-text, #1a5ea8); }
.sx-link--t-accent2  { --_link: var(--sx-accent2-text, #5a49b8); }
.sx-link--t-numeric  { --_link: var(--sx-numeric-text, #0a6f5a); }
.sx-link--t-success  { --_link: var(--sx-success-text, #146b44); }
.sx-link--t-warning  { --_link: var(--sx-warning-text, #8a4c06); }
.sx-link--t-danger   { --_link: var(--sx-danger-text, #a83030); }
.sx-link--t-info     { --_link: var(--sx-info-text, #096577); }
.sx-link--t-default  { --_link: var(--sx-text-1, #151a24); }
.sx-link--t-muted    { --_link: var(--sx-text-2, #4b5565); }
.sx-link--t-contrast { --_link: var(--sx-contrast-bg, #1f2533); }
.sx-link--t-inherit  { --_link: currentColor; }

.sx-fab {
  display: inline-flex;
  align-items: center;
  gap: var(--sx-space-2, 8px);
  height: 48px;
  padding-inline: var(--sx-space-5, 20px);
  border: 0;
  border-radius: var(--sx-radius-full, 9999px);
  background: var(--_fab, var(--sx-accent, #1f6fc6));
  color: var(--_fab-on, #fff);
  font: inherit;
  font-weight: 600;
  box-shadow: var(--sx-shadow-3);
  cursor: pointer;
  transition: background var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease),
              box-shadow var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-fab:hover { box-shadow: var(--sx-shadow-4); }
.sx-fab:active { box-shadow: var(--sx-shadow-2); }
.sx-fab:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6), var(--sx-shadow-3); }
.sx-fab:disabled { background: var(--sx-neutral, #e3e7ee); color: var(--sx-text-disabled, #a3a9b8); box-shadow: none; cursor: default; }
.sx-fab--xs { height: 36px; padding-inline: var(--sx-space-3, 12px); }
.sx-fab--sm { height: 40px; padding-inline: var(--sx-space-4, 16px); }
.sx-fab--lg { height: 56px; padding-inline: var(--sx-space-6, 24px); }
.sx-fab--xl { height: 64px; padding-inline: var(--sx-space-7, 28px); }
.sx-fab--icon-only { padding-inline: 0; width: 48px; justify-content: center; }
.sx-fab--icon-only.sx-fab--sm { width: 40px; }
.sx-fab--icon-only.sx-fab--lg { width: 56px; }

.sx-fab--t-accent   { --_fab: var(--sx-accent, #1f6fc6);  --_fab-on: var(--sx-accent-on, #fff); }
.sx-fab--t-accent2  { --_fab: var(--sx-accent2, #6d5bd0); --_fab-on: var(--sx-accent2-on, #fff); }
.sx-fab--t-numeric  { --_fab: var(--sx-numeric, #0c8068); --_fab-on: #fff; }
.sx-fab--t-success  { --_fab: var(--sx-success, #177a4d); --_fab-on: var(--sx-text-on-status, #fff); }
.sx-fab--t-warning  { --_fab: var(--sx-warning, #a85d08); --_fab-on: var(--sx-text-on-status, #fff); }
.sx-fab--t-danger   { --_fab: var(--sx-danger, #c93a3a);  --_fab-on: var(--sx-text-on-status, #fff); }
.sx-fab--t-info     { --_fab: var(--sx-info, #0b7a8f);    --_fab-on: var(--sx-text-on-status, #fff); }
.sx-fab--t-default  { --_fab: var(--sx-neutral, #e3e7ee); --_fab-on: var(--sx-neutral-on, #151a24); }
.sx-fab--t-muted    { --_fab: var(--sx-neutral, #e3e7ee); --_fab-on: var(--sx-text-2, #4b5565); }
.sx-fab--t-contrast { --_fab: var(--sx-contrast-bg, #1f2533); --_fab-on: var(--sx-contrast-text, #f3f5f9); }
.sx-fab--t-inherit  { --_fab: currentColor; --_fab-on: var(--sx-surface-2, #fff); }

/* ---------------------------------------------------------------------------------------------
   SxStepper — no built-in Next / Back: the step bodies own their navigation (AUDIT.md §6.3).
   --------------------------------------------------------------------------------------------- */
.sx-stepper { display: flex; flex-direction: column; min-height: 0; }
.sx-stepper__registry { display: none; }

.sx-stepper__bar {
  display: flex;
  align-items: center;
  gap: var(--sx-space-2, 8px);
  margin: 0;
  padding: var(--sx-space-3, 12px) var(--sx-space-2, 8px);
  list-style: none;
  overflow-x: auto;
}
.sx-stepper__step { flex: 1 1 0; min-width: 0; }

/* The connector between markers. Drawn on the step, not between them, so it survives wrapping. */
.sx-stepper__step + .sx-stepper__step { position: relative; }
.sx-stepper__step + .sx-stepper__step::before {
  content: "";
  position: absolute;
  inset-inline-start: calc(var(--sx-space-2, 8px) * -1);
  top: 50%;
  width: var(--sx-space-2, 8px);
  height: 1px;
  background: var(--sx-line, rgba(16, 24, 40, 0.08));
}

.sx-stepper__marker {
  display: flex;
  align-items: center;
  gap: var(--sx-space-2, 8px);
  width: 100%;
  min-height: var(--sx-touch-min, 44px);
  padding: var(--sx-space-2, 8px) var(--sx-space-3, 12px);
  border: 1px solid transparent;
  border-radius: var(--sx-radius-sm, 10px);
  background: transparent;
  color: var(--sx-text-3, #616a7d);
  font: inherit;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  cursor: pointer;
}
.sx-stepper__marker:hover:not(:disabled) { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); }
.sx-stepper__marker:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-stepper__marker:disabled { cursor: default; color: var(--sx-text-disabled, #a3a9b8); }

.sx-stepper__step--current .sx-stepper__marker {
  border-color: var(--sx-accent-soft-border, rgba(31, 111, 198, 0.28));
  background: var(--sx-accent-soft, rgba(31, 111, 198, 0.10));
  color: var(--sx-accent-text, #1a5ea8);
  font-weight: 600;
}
.sx-stepper__step--done .sx-stepper__marker { color: var(--sx-text-2, #4b5565); }

.sx-stepper__number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: var(--sx-radius-full, 9999px);
  background: var(--sx-neutral, #e3e7ee);
  font-size: var(--sx-text-caption-size, 0.75rem);
  font-weight: 600;
}
.sx-stepper__title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sx-stepper__body { min-height: 0; flex: 1 1 auto; }

/* ---------------------------------------------------------------------------------------------
   SxChat — one sender's run of messages. Colour and side come from the run, so a bubble is stateless.
   --------------------------------------------------------------------------------------------- */
.sx-chat {
  display: flex;
  align-items: flex-end;
  gap: var(--sx-space-2, 8px);
  margin-bottom: var(--sx-space-3, 12px);
}
.sx-chat--end { flex-direction: row-reverse; }

.sx-chat__avatar { flex: 0 0 auto; }
.sx-chat__stack { display: flex; flex-direction: column; gap: 2px; min-width: 0; max-width: min(72ch, 80%); }
.sx-chat--end .sx-chat__stack { align-items: flex-end; }

.sx-chat__meta {
  display: flex;
  gap: var(--sx-space-2, 8px);
  font-size: var(--sx-text-caption-size, 0.75rem);
  color: var(--sx-text-3, #616a7d);
}
.sx-chat__name { font-weight: 600; }

.sx-chat__bubble {
  padding: var(--sx-space-2, 8px) var(--sx-space-3, 12px);
  border-radius: var(--sx-radius-md, 14px);
  background: var(--_chat, var(--sx-neutral, #e3e7ee));
  color: var(--_chat-on, var(--sx-text-1, #151a24));
  overflow-wrap: anywhere;
}
/* The tail: the corner nearest the sender squares off on the last bubble of the run. */
.sx-chat--start .sx-chat__bubble:last-child { border-end-start-radius: var(--sx-radius-xs, 6px); }
.sx-chat--end   .sx-chat__bubble:last-child { border-end-end-radius: var(--sx-radius-xs, 6px); }

.sx-chat--t-accent   { --_chat: var(--sx-accent, #1f6fc6);  --_chat-on: var(--sx-accent-on, #fff); }
.sx-chat--t-accent2  { --_chat: var(--sx-accent2, #6d5bd0); --_chat-on: var(--sx-accent2-on, #fff); }
.sx-chat--t-numeric  { --_chat: var(--sx-numeric, #0c8068); --_chat-on: #fff; }
.sx-chat--t-success  { --_chat: var(--sx-success, #177a4d); --_chat-on: var(--sx-text-on-status, #fff); }
.sx-chat--t-warning  { --_chat: var(--sx-warning, #a85d08); --_chat-on: var(--sx-text-on-status, #fff); }
.sx-chat--t-danger   { --_chat: var(--sx-danger, #c93a3a);  --_chat-on: var(--sx-text-on-status, #fff); }
.sx-chat--t-info     { --_chat: var(--sx-info, #0b7a8f);    --_chat-on: var(--sx-text-on-status, #fff); }
.sx-chat--t-default  { --_chat: var(--sx-neutral, #e3e7ee); --_chat-on: var(--sx-neutral-on, #151a24); }
.sx-chat--t-muted    { --_chat: var(--sx-neutral-soft, rgba(16, 24, 40, 0.06)); --_chat-on: var(--sx-text-2, #4b5565); }
.sx-chat--t-contrast { --_chat: var(--sx-contrast-bg, #1f2533); --_chat-on: var(--sx-contrast-text, #f3f5f9); }
.sx-chat--t-inherit  { --_chat: currentColor; --_chat-on: var(--sx-surface-2, #fff); }

/* =============================================================================================
   TIER 6 — the bespoke four (Phase 6)
   ============================================================================================= */

/* ---------------------------------------------------------------------------------------------
   Pinned columns · sticky footer · fill — the three things the two MudDataGrids needed on top of
   SxDataTable. A pinned cell paints its own background so scrolled content cannot show through;
   the striped / hover rules are more specific and still win on their rows.
   Layers inside one table: pinned body cell 1 · sticky header / footer 2 · pinned header corner 3.
   --------------------------------------------------------------------------------------------- */
.sx-table__cell--pin-start,
.sx-table__cell--pin-end {
  position: sticky;
  z-index: 1;
  background: var(--sx-surface-1, #fbfcfe);
}
.sx-table__cell--pin-start { border-inline-end: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08)); }
.sx-table__cell--pin-end   { border-inline-start: 1px solid var(--sx-line, rgba(16, 24, 40, 0.08)); }

.sx-table thead th.sx-table__cell--pin-start,
.sx-table thead th.sx-table__cell--pin-end,
.sx-table tfoot td.sx-table__cell--pin-start,
.sx-table tfoot td.sx-table__cell--pin-end { z-index: 3; }

.sx-table-wrap--sticky-foot { overflow-y: auto; }
.sx-table-wrap--sticky-foot .sx-table tfoot td {
  position: sticky;
  bottom: 0;
  z-index: 2;
}

/* The table takes whatever height its flex-column parent has left and scrolls inside it. */
.sx-table-wrap--fill {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
}

/* Visually hidden, still read by assistive tech — for a header cell over an actions column. */
.sx-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---------------------------------------------------------------------------------------------
   SxTree — the category rail. The chevron is the only thing that expands; the row body belongs
   to the caller and owns its own click. Leaves keep a chevron-width spacer so labels align.
   --------------------------------------------------------------------------------------------- */
.sx-tree,
.sx-tree__group {
  list-style: none;
  margin: 0;
  padding: 0;
}
.sx-tree {
  --sx-tree-indent: 16px;
  font-size: var(--sx-text-body-sm-size, 0.875rem);
  color: var(--sx-text-1, #151a24);
}
.sx-tree__group { padding-inline-start: var(--sx-tree-indent); }

.sx-tree__row {
  display: flex;
  align-items: center;
  min-height: 28px;
  padding-inline: 4px 6px;
  border-radius: var(--sx-radius-xs, 6px);
  transition: background-color var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-tree__row:hover { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); }

.sx-tree__toggle {
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: var(--sx-radius-xs, 6px);
  background: transparent;
  color: var(--sx-text-3, #616a7d);
  cursor: pointer;
}
.sx-tree__toggle:hover { color: var(--sx-text-1, #151a24); background: var(--sx-neutral-soft, rgba(16, 24, 40, 0.06)); }
.sx-tree__toggle:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-tree__toggle--leaf { cursor: default; }

.sx-tree__chevron { transition: transform var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease); }
.sx-tree__item--open > .sx-tree__row .sx-tree__chevron { transform: rotate(90deg); }

.sx-tree__body {
  flex: 1 1 auto;
  min-width: 0;
}

/* ---------------------------------------------------------------------------------------------
   SxPieChart — thin chrome, the data is the only loud thing. Slices carry a 2px seam in the
   surface colour so hues never touch; the selected slice lifts 2 viewBox units along its bisector
   and the rest recede. Legend keys are buttons and mirror the slices.
   --------------------------------------------------------------------------------------------- */
.sx-pie {
  --sx-pie-size: 220px;
  display: flex;
  align-items: center;
  gap: var(--sx-space-4, 16px);
  min-width: 0;
}
.sx-pie--legend-bottom { flex-direction: column; }
.sx-pie--legend-end    { flex-direction: row; flex-wrap: wrap; }
.sx-pie--legend-none   { justify-content: center; }

.sx-pie__svg {
  flex: 0 0 auto;
  width: var(--sx-pie-size);
  height: var(--sx-pie-size);
  max-width: 100%;
  overflow: visible;
}

.sx-pie__slice {
  stroke: var(--sx-chart-gap, #fbfcfe);
  stroke-width: 2;
  stroke-linejoin: round;
  cursor: pointer;
  transition: opacity var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease),
              transform var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease),
              filter var(--sx-dur-fast, 120ms) var(--sx-ease-out, ease);
}
.sx-pie__slice:hover { filter: brightness(1.06); }
.sx-pie__slice:focus-visible { outline: none; stroke: var(--sx-focus-ring-color, #1f6fc6); }
.sx-pie--has-selection .sx-pie__slice { opacity: 0.55; }
.sx-pie--has-selection .sx-pie__slice--selected {
  opacity: 1;
  transform: translate(calc(var(--_dx, 0) * 1px), calc(var(--_dy, 0) * 1px));
}

.sx-pie__empty {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--sx-pie-size);
  height: var(--sx-pie-size);
  max-width: 100%;
  border: 1px dashed var(--sx-line, rgba(16, 24, 40, 0.08));
  border-radius: 50%;
}

.sx-pie__legend {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sx-space-1, 4px) var(--sx-space-3, 12px);
  min-width: 0;
}
.sx-pie--legend-bottom .sx-pie__legend { justify-content: center; }
.sx-pie--legend-end .sx-pie__legend { flex-direction: column; flex: 1 1 140px; }

.sx-pie__key {
  display: inline-flex;
  align-items: center;
  gap: var(--sx-space-2, 8px);
  max-width: 100%;
  padding: 2px var(--sx-space-2, 8px);
  border: 0;
  border-radius: var(--sx-radius-xs, 6px);
  background: transparent;
  color: var(--sx-text-2, #4b5565);           /* text wears text tokens, never the series colour */
  font: inherit;
  font-size: var(--sx-text-caption-size, 0.75rem);
  line-height: 1.5;
  text-align: start;
  cursor: pointer;
}
.sx-pie__key:hover { background: var(--sx-surface-hover, rgba(20, 40, 80, 0.05)); color: var(--sx-text-1, #151a24); }
.sx-pie__key:focus-visible { outline: none; box-shadow: var(--sx-focus-shadow, 0 0 0 2px #1f6fc6); }
.sx-pie__key--selected { color: var(--sx-text-1, #151a24); font-weight: 600; }
.sx-pie--has-selection .sx-pie__key:not(.sx-pie__key--selected) { opacity: 0.6; }

.sx-pie__swatch {
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  border-radius: 3px;
}
.sx-pie__label { min-width: 0; overflow-wrap: anywhere; }
.sx-pie__pct {
  color: var(--sx-text-3, #616a7d);
  font-variant-numeric: tabular-nums;
}
