/* =====================================================================
   design-system/components.css  ·  DS v2 = design v4 (Aus approved 2026-10-24) · VSchat + VisionX
   ---------------------------------------------------------------------
   - Every class starts with ds- (no collision with vx-* / vs-* / legacy CSS).
   - Colours, radii, type, motion: tokens only (var(--...)). No hex, rgb(),
     hsl() or colour names in this file (tests/ds_package_test.php).
   - Private per-component knobs are --_name (never set them from pages).
   - Interactive states: rest · :hover (hover devices) · :active / .is-pressed ·
     :focus-visible · :disabled / [aria-disabled] · [aria-busy] (loading).
     .is-hover / .is-focus exist for the gallery and QA screenshots.
   - Only transform and opacity animate. Every motion has a reduced-motion path
     through the tokens (--motion-shift, --press-scale, durations).
   - v4 language: flat white / light-grey surfaces, one blue accent, hairline
     separators and card rings, status as coloured text, a 36px control family
     on desktop (44px targets on mobile), glass only behind bars.
   Class reference and the v1 -> v2 migration table: design-system/README.md
   ===================================================================== */

/* ---------- 0. Base (opt-in: put ds-body on <body>) ---------- */
.ds-body { margin: 0; font: var(--type-body); background: var(--color-bg); color: var(--color-text);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; -webkit-text-size-adjust: 100%; overflow-wrap: anywhere; }
.ds-body:lang(en) { letter-spacing: var(--track-body); }
.ds-body :lang(lo), .ds-body :lang(th) { letter-spacing: 0; }
.ds-body *, .ds-body *::before, .ds-body *::after { box-sizing: border-box; }
.ds-body--grouped { background: var(--color-bg-secondary); }

/* ---------- 1. Type, money, links, icons, utilities ---------- */
.ds-largetitle { font: var(--type-largetitle); margin: 0; }
.ds-title1 { font: var(--type-title1); margin: 0; }
.ds-title2 { font: var(--type-title2); margin: 0; }
.ds-title3 { font: var(--type-title3); margin: 0; }
:lang(en) .ds-largetitle, :lang(en).ds-largetitle, :lang(en) .ds-title1, :lang(en) .ds-title2, :lang(en) .ds-title3 { letter-spacing: var(--track-large); }
.ds-headline { font: var(--type-headline); margin: 0; }
.ds-callout { font: var(--type-callout); }
.ds-subhead { font: var(--type-subhead); }
.ds-footnote { font: var(--type-footnote); }
.ds-caption { font: var(--type-caption); }
.ds-text-secondary { color: var(--color-text-secondary); }
.ds-text-tertiary { color: var(--color-text-tertiary); }
.ds-num { font-variant-numeric: tabular-nums; letter-spacing: 0; }
.ds-code { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-feature-settings: "zero" 1; letter-spacing: 0; }
/* Money: <span class="ds-money"><span class="ds-money__cur">{shop symbol}</span><span class="ds-money__amt">{vx_money / Money::format}</span></span>
   v4: tabular sans, the symbol tight against the amount */
.ds-money { white-space: nowrap; font-weight: 600; font-variant-numeric: tabular-nums; }
.ds-money__cur { font-weight: inherit; margin-inline-end: 0.04em; }
.ds-money__amt { font-variant-numeric: tabular-nums; letter-spacing: 0; }
.ds-money--neg .ds-money__amt, .ds-num--neg { color: var(--color-danger); }

.ds-link { color: var(--color-tint); text-decoration: none; border-radius: var(--radius-xs); transition: color var(--dur-micro-out) linear; }
@media (hover: hover) { .ds-link:hover { color: var(--color-tint-hover); text-decoration: underline; text-underline-offset: 3px; } }
.ds-link:active { color: var(--color-tint-pressed); }
.ds-link:focus-visible { outline: 2px solid transparent; box-shadow: var(--focus-ring); }

.ds-icon { width: 20px; height: 20px; flex: none; display: inline-block; vertical-align: middle; fill: currentColor; }
.ds-icon--14 { width: 14px; height: 14px; } .ds-icon--16 { width: 16px; height: 16px; } .ds-icon--18 { width: 18px; height: 18px; }
.ds-icon--22 { width: 22px; height: 22px; } .ds-icon--24 { width: 24px; height: 24px; }
.ds-icon--32 { width: 32px; height: 32px; } .ds-icon--48 { width: 48px; height: 48px; }
/* active/inactive pair: put both icons in the item, the state shows the right one */
.ds-icon--on { display: none; }
:is([aria-current="page"], [aria-current="true"], [aria-selected="true"], [aria-pressed="true"]) > .ds-icon--on,
:is([aria-current="page"], [aria-current="true"], [aria-selected="true"], [aria-pressed="true"]) > * > .ds-icon--on { display: inline-block; }
:is([aria-current="page"], [aria-current="true"], [aria-selected="true"], [aria-pressed="true"]) > .ds-icon--off,
:is([aria-current="page"], [aria-current="true"], [aria-selected="true"], [aria-pressed="true"]) > * > .ds-icon--off { display: none; }

.ds-sr-only { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.ds-kbd { font: var(--type-caption); font-family: var(--font-mono); padding: 0 var(--space-1); border-radius: var(--radius-xs); box-shadow: inset 0 0 0 1px currentColor; opacity: 0.85; }
.ds-divider { height: 0; margin: 0; border: 0; border-top: 1px solid var(--color-separator); }
.ds-vdivider { width: 1px; height: 20px; flex: none; background: var(--color-separator-mid); margin: 0 2px; }
.ds-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-block: 1px; min-width: 0; }
.ds-section-title { font: var(--type-footnote); font-weight: 600; color: var(--color-text-secondary); margin: 0 0 var(--space-2); }

/* ---------- 2. Materials (v4: almost no glass; only a quiet backdrop behind bars) ---------- */
.ds-glass { position: relative; color: var(--color-text); background: var(--glass-bg); -webkit-backdrop-filter: var(--glass-filter); backdrop-filter: var(--glass-filter);
  box-shadow: var(--glass-rim); }
.ds-glass--strong { background: var(--glass-bg-strong); }
/* a container whose background is a photo / media: buttons inside become real glass (image viewers) */
.ds-on-media { position: relative; isolation: isolate; color: var(--color-on-media); }

/* ---------- 3. Buttons (v4): 36px desktop / 44px mobile, radius 10, weight 500, flat ----------
   primary = blue (one per area) · secondary = grey fill · plain = blue text · tinted = blue on blue-tint
   danger = red · ink = dark (onboarding only) · icon / icon-sm = square, grey glyph */
.ds-btn { --_bg0: var(--btn-neutral-bg); --_bgh: var(--color-fill-hover); --_bgp: var(--color-fill-hover); --_fg: var(--color-text); --_fgh: var(--_fg); --_ring: inset 0 0 0 0 transparent;
  --_bg: var(--_bg0);
  appearance: none; border: 0; margin: 0; position: relative; display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: var(--hit); min-width: var(--hit); padding: 0 14px; border-radius: var(--radius-control);
  background: var(--_bg); color: var(--_fg); box-shadow: var(--_ring);
  font: var(--type-label); text-decoration: none; white-space: nowrap; cursor: pointer; user-select: none; -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  transform: scale(1);
  transition: transform var(--dur-release) var(--ease-press-release), background-color var(--dur-micro-out) linear, color var(--dur-micro-out) linear, box-shadow var(--dur-micro-out) linear; }
.ds-btn > * { pointer-events: none; }
.ds-btn .ds-icon { width: 18px; height: 18px; }
/* each kind sets its rest (--_bg0), hover (--_bgh / --_fgh) and pressed (--_bgp) values; these state rules apply them */
@media (hover: hover) { .ds-btn:hover:not(:disabled):not([aria-disabled="true"]):not([aria-busy="true"]) { --_bg: var(--_bgh); color: var(--_fgh); } }
.ds-btn.is-hover { --_bg: var(--_bgh); color: var(--_fgh); }
/* press (MOTION_V2 §6): 180ms down to 0.96, held at least --press-hold, soft spring back over --dur-release (400ms).
   The click fires at once; nothing waits for the animation. ds-speed: 80 / 150ms, no hold. */
.ds-btn:active:not(:disabled):not([aria-disabled="true"]):not([aria-busy="true"]), .ds-btn.is-pressed {
  transform: scale(var(--press-scale)); --_bg: var(--_bgp);
  transition: transform var(--dur-press) var(--ease-press), background-color var(--dur-press) linear, color var(--dur-press) linear; }
.ds-btn:focus-visible, .ds-btn.is-focus { outline: 2px solid transparent; outline-offset: 2px; box-shadow: var(--focus-ring); }
.ds-btn:disabled, .ds-btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; transform: none; }
.ds-btn[aria-busy="true"] { cursor: progress; }
.ds-btn[aria-busy="true"] > * { opacity: 0; }
.ds-btn[aria-busy="true"]::after { content: ""; position: absolute; inset: 0; margin: auto; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid currentColor; border-right-color: transparent; animation: ds-spin 0.8s linear infinite; }
/* kinds (after the base: equal specificity, order decides) */
.ds-btn--primary { --_bg0: var(--color-tint-fill); --_bgh: var(--color-tint-fill-hover); --_bgp: var(--color-tint-fill-pressed); --_fg: var(--color-on-tint); }
.ds-btn--secondary { --_bg0: var(--color-fill); --_bgh: var(--color-fill-hover); --_bgp: var(--color-fill-hover); --_fg: var(--color-text); }
.ds-btn--plain { --_bg0: transparent; --_bgh: var(--color-tint-soft); --_bgp: var(--color-tint-soft); --_fg: var(--color-tint); --_fgh: var(--color-tint-hover); padding: 0 10px; }
.ds-btn--tinted { --_bg0: var(--color-tint-soft); --_bgh: var(--color-tint-soft); --_bgp: var(--color-tint-soft); --_fg: var(--color-tint); --_fgh: var(--color-tint-hover); }
.ds-btn--danger { --_bg0: var(--color-danger); --_bgh: var(--color-danger-hover); --_bgp: var(--color-danger-pressed); --_fg: var(--color-on-danger); }
.ds-btn--ink { --_bg0: var(--color-surface-inverse); --_bgh: var(--color-surface-inverse); --_bgp: var(--color-surface-inverse); --_fg: var(--color-text-inverse); }
/* sizes and shapes */
.ds-btn--sm { min-height: 32px; min-width: 32px; padding: 0 12px; font: var(--type-label-sm); }
.ds-btn--sm::before, .ds-btn--icon-sm::before { content: ""; position: absolute; inset: min(0px, calc((32px - var(--hit)) / 2)); }
.ds-btn--lg { min-height: 44px; padding: 0 20px; border-radius: calc(var(--radius-control) + 2px); font: var(--type-label); font-weight: 600; }
.ds-btn--xl { min-height: 56px; padding: 0 24px; border-radius: var(--radius-card); font: var(--type-headline); font-size: 18px; }   /* POS pay */
.ds-btn--block { display: flex; width: 100%; }
.ds-btn--icon { padding: 0; width: var(--hit); --_fg: var(--color-text-secondary); --_bg0: transparent; --_bgh: var(--color-fill); --_bgp: var(--color-fill-hover); }
.ds-btn--icon-sm { padding: 0; width: 32px; min-width: 32px; min-height: 32px; --_fg: var(--color-text-secondary); --_bg0: transparent; --_bgh: var(--color-fill); --_bgp: var(--color-fill-hover); }
.ds-btn--icon.ds-btn--tint, .ds-btn--icon-sm.ds-btn--tint { --_fg: var(--color-tint); --_fgh: var(--color-tint); --_bgh: var(--color-tint-soft); }
.ds-btn--icon.ds-btn--primary, .ds-btn--icon-sm.ds-btn--primary { --_bg0: var(--color-tint-fill); --_bgh: var(--color-tint-fill-hover); --_bgp: var(--color-tint-fill-pressed); --_fg: var(--color-on-tint); --_fgh: var(--color-on-tint); }
.ds-btn--icon.ds-btn--secondary, .ds-btn--icon-sm.ds-btn--secondary { --_bg0: var(--color-fill); --_bgh: var(--color-fill-hover); --_fg: var(--color-text-secondary); --_fgh: var(--color-text-secondary); }
.ds-btn--icon.ds-btn--tinted, .ds-btn--icon-sm.ds-btn--tinted { --_bg0: var(--color-tint-soft); --_bgh: var(--color-tint-soft); --_fg: var(--color-tint); --_fgh: var(--color-tint); }
.ds-btn--round { border-radius: 50%; }
.ds-btn--capsule { border-radius: var(--radius-pill); }
.ds-btn--rect { border-radius: var(--radius-control); }
.ds-btn--glass { --_ring: var(--glass-rim); }   /* v1 class kept: now a quiet ring only (v4 has no glass buttons) */
.ds-btn__kbd { font: var(--type-caption); font-family: var(--font-mono); padding: 0 var(--space-1); border-radius: var(--radius-xs); box-shadow: inset 0 0 0 1px currentColor; opacity: 0.85; }
.ds-btn-row { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
/* over media (image viewers): translucent, white label, dimmed lens */
.ds-on-media .ds-btn { --_bg0: var(--glass-media-bg); --_bgh: var(--glass-media-bg-hover); --_bgp: var(--glass-media-bg); --_fg: var(--color-on-media); --_fgh: var(--color-on-media); --_ring: var(--glass-media-rim);
  -webkit-backdrop-filter: var(--glass-media-filter); backdrop-filter: var(--glass-media-filter); text-shadow: 0 1px 2px var(--color-text-shadow-media); }
.ds-on-media .ds-btn--primary { --_bg0: var(--glass-media-tint-bg); --_bgh: var(--glass-media-tint-bg); --_bgp: var(--glass-media-tint-bg); }
.ds-on-media .ds-btn--danger { --_bg0: var(--glass-media-danger-bg); --_bgh: var(--glass-media-danger-bg); --_bgp: var(--glass-media-danger-bg); }
.ds-on-media .ds-btn:focus-visible, .ds-on-media .ds-btn.is-focus { box-shadow: var(--focus-ring-media); }

/* icon tiles (v4 Call / Order / History): big, simple, blue glyph over a grey tile */
.ds-icon-tiles { display: grid; grid-template-columns: repeat(var(--ds-tiles, 3), minmax(0, 1fr)); gap: 10px; }
.ds-icon-tile { appearance: none; border: 0; margin: 0; position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-1);
  min-height: 60px; padding: var(--space-2); border-radius: var(--radius-group); background: var(--color-fill); color: var(--color-tint);
  font: var(--type-caption); font-weight: 500; text-decoration: none; cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  transform: scale(1); transition: transform var(--dur-release) var(--ease-press-release), background-color var(--dur-micro-out) linear; }
.ds-icon-tile .ds-icon { width: 22px; height: 22px; }
@media (hover: hover) { .ds-icon-tile:hover:not(:disabled) { background: var(--color-fill-hover); } }
.ds-icon-tile.is-hover { background: var(--color-fill-hover); }
.ds-icon-tile:active:not(:disabled), .ds-icon-tile.is-pressed { transform: scale(var(--press-scale)); background: var(--color-fill-hover);
  transition-duration: var(--dur-press); transition-timing-function: var(--ease-press); }
.ds-icon-tile:focus-visible, .ds-icon-tile.is-focus { outline: 2px solid transparent; box-shadow: var(--focus-ring); }
.ds-icon-tile:disabled, .ds-icon-tile[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }

/* bell (v4): a 36px icon button with an offset count badge */
.ds-bell { appearance: none; border: 0; margin: 0; position: relative; display: grid; place-items: center; width: var(--hit); height: var(--hit); border-radius: var(--radius-control);
  background: transparent; color: var(--color-text-secondary); cursor: pointer; -webkit-tap-highlight-color: transparent;
  transform: scale(1); transition: transform var(--dur-release) var(--ease-press-release), background-color var(--dur-micro-out) linear; }
@media (hover: hover) { .ds-bell:hover { background: var(--color-fill); } }
.ds-bell.is-hover { background: var(--color-fill); }
.ds-bell:active, .ds-bell.is-pressed { transform: scale(var(--press-scale-icon)); background: var(--color-fill); transition-duration: var(--dur-press); transition-timing-function: var(--ease-press); }
.ds-bell:focus-visible, .ds-bell.is-focus { outline: 2px solid transparent; box-shadow: var(--focus-ring); }
.ds-bell__badge { position: absolute; top: 1px; right: -2px; min-width: 18px; height: 18px; padding: 0 5px; line-height: 18px; box-shadow: 0 0 0 2px var(--color-bg); }

/* ---------- 4. Fields (v4): 36px desktop / 44px mobile, radius 10 ---------- */
.ds-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.ds-label { font: var(--type-footnote); font-weight: 500; color: var(--color-text-secondary); }
.ds-label__opt { font-weight: 400; color: var(--color-text-tertiary); }
.ds-help { font: var(--type-caption); color: var(--color-text-secondary); margin: 0; }
.ds-error { font: var(--type-caption); font-weight: 500; color: var(--color-danger); display: flex; gap: 6px; align-items: flex-start; margin: 0; }
.ds-error .ds-icon { width: 16px; height: 16px; margin-top: 1px; }
.ds-input, .ds-select, .ds-textarea, .ds-input-group {
  appearance: none; -webkit-appearance: none; box-sizing: border-box; width: 100%; min-width: 0; min-height: var(--control-h); margin: 0;
  padding: 0 12px; border: 0; border-radius: var(--radius-control);
  background-color: var(--color-surface); color: var(--color-text); font: var(--type-input);
  box-shadow: inset 0 0 0 1px var(--color-separator-strong);
  transition: box-shadow var(--dur-micro-in) var(--ease-out), background-color var(--dur-micro-in) linear; }
.ds-input::placeholder, .ds-textarea::placeholder, .ds-input-group__input::placeholder, .ds-search__input::placeholder { color: var(--color-text-tertiary); opacity: 1; }
@media (hover: hover) {
  .ds-input:hover:not(:focus):not(:disabled), .ds-select:hover:not(:focus):not(:disabled), .ds-textarea:hover:not(:focus):not(:disabled), .ds-input-group:hover:not(:focus-within) {
    box-shadow: inset 0 0 0 1px var(--color-text-secondary); }
}
.ds-input.is-hover, .ds-select.is-hover, .ds-textarea.is-hover { box-shadow: inset 0 0 0 1px var(--color-text-secondary); }
.ds-input:focus, .ds-select:focus, .ds-textarea:focus, .ds-input-group:focus-within, .ds-input.is-focus, .ds-select.is-focus, .ds-textarea.is-focus {
  outline: 2px solid transparent; box-shadow: inset 0 0 0 2px var(--color-focus), 0 0 0 3px var(--color-tint-soft); }
.ds-input[aria-invalid="true"], .ds-select[aria-invalid="true"], .ds-textarea[aria-invalid="true"], .ds-input-group:has([aria-invalid="true"]) {
  box-shadow: inset 0 0 0 2px var(--color-danger); }
.ds-input:disabled, .ds-select:disabled, .ds-textarea:disabled { background-color: var(--color-fill); color: var(--color-text-secondary); cursor: not-allowed; box-shadow: inset 0 0 0 1px var(--color-separator-mid); }
.ds-input:read-only:not(:disabled), .ds-textarea:read-only:not(:disabled) { background-color: var(--color-fill); }
.ds-input--num { font-variant-numeric: tabular-nums; text-align: end; }
.ds-select { padding-inline-end: 34px; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--color-text-secondary) 50%), linear-gradient(135deg, var(--color-text-secondary) 50%, transparent 50%);
  background-position: calc(100% - 18px) 52%, calc(100% - 13px) 52%; background-size: 5px 5px; background-repeat: no-repeat; }
.ds-textarea { min-height: 88px; padding: 10px 12px; resize: vertical; display: block; }
.ds-input-group { display: flex; align-items: center; gap: var(--space-2); padding: 0 12px; }
.ds-input-group__input { all: unset; flex: 1; min-width: 0; min-height: calc(var(--control-h) - 2px); font: var(--type-input); color: var(--color-text); }
.ds-input-group__affix { flex: none; color: var(--color-text-secondary); font-weight: 500; }
.ds-input-group .ds-icon { color: var(--color-text-secondary); }
/* search (v4): a filled field, no border; the magnifier and the placeholder identify it */
.ds-search { position: relative; display: flex; align-items: center; gap: var(--space-2); min-height: var(--control-h); padding: 0 var(--space-1) 0 12px;
  border-radius: var(--radius-control); background: var(--color-fill); color: var(--color-text-tertiary);
  transition: background-color var(--dur-micro-in) linear, box-shadow var(--dur-micro-in) var(--ease-out); }
.ds-search:focus-within, .ds-search.is-focus { box-shadow: inset 0 0 0 2px var(--color-focus), 0 0 0 3px var(--color-tint-soft); }
.ds-search__input { all: unset; flex: 1; min-width: 0; min-height: calc(var(--control-h) - 4px); font: var(--type-input); color: var(--color-text); }
.ds-search__input::-webkit-search-cancel-button { display: none; }
.ds-search__clear { appearance: none; border: 0; margin: 0; padding: 0; background: transparent; color: var(--color-text-tertiary); cursor: pointer;
  width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; position: relative; flex: none; }
.ds-search__clear::before { content: ""; position: absolute; inset: min(0px, calc((32px - var(--hit)) / 2)); }
.ds-search__clear:focus-visible { outline: 2px solid transparent; box-shadow: var(--focus-ring); }
.ds-search__input:placeholder-shown ~ .ds-search__clear { display: none; }

/* choice controls: checkbox · radio · switch (wrap in label.ds-choice so the whole row is the target) */
.ds-choice { display: inline-flex; align-items: center; gap: var(--space-3); min-height: var(--hit); cursor: pointer; font: var(--type-body); }
.ds-choice--block { display: flex; justify-content: space-between; }
.ds-check, .ds-radio { appearance: none; -webkit-appearance: none; margin: 0; flex: none; position: relative; width: 20px; height: 20px; cursor: pointer;
  background: var(--color-surface); box-shadow: inset 0 0 0 1.5px var(--color-separator-strong);
  transition: background-color var(--dur-micro-in) linear, box-shadow var(--dur-micro-in) var(--ease-out), transform var(--dur-release) var(--ease-press-release); }
.ds-check { border-radius: var(--radius-xs); }
.ds-radio { border-radius: 50%; }
.ds-check::before, .ds-radio::before { content: ""; position: absolute; inset: min(0px, calc((20px - var(--hit)) / 2)); }
@media (hover: hover) { .ds-check:hover:not(:disabled):not(:checked), .ds-radio:hover:not(:disabled):not(:checked) { box-shadow: inset 0 0 0 1.5px var(--color-text-secondary); } }
.ds-check:active:not(:disabled), .ds-radio:active:not(:disabled) { transform: scale(var(--press-scale-icon)); transition-duration: var(--dur-press); transition-timing-function: var(--ease-press); }
.ds-check:focus-visible, .ds-radio:focus-visible, .ds-check.is-focus, .ds-radio.is-focus { outline: 2px solid transparent; box-shadow: inset 0 0 0 1.5px var(--color-separator-strong), var(--focus-ring); }
.ds-check:checked, .ds-check:indeterminate { background: var(--color-tint-fill); box-shadow: none; }
.ds-radio:checked { box-shadow: inset 0 0 0 6px var(--color-tint-fill); }   /* v4 radio: a thick blue ring */
.ds-check:checked:focus-visible { box-shadow: var(--focus-ring); }
.ds-radio:checked:focus-visible { box-shadow: inset 0 0 0 6px var(--color-tint-fill), var(--focus-ring); }
.ds-check::after { content: ""; position: absolute; left: 7px; top: 3px; width: 6px; height: 11px; border: solid var(--color-on-tint); border-width: 0 2.25px 2.25px 0;
  transform: rotate(45deg) scale(0); opacity: 0; transition: transform var(--dur-pop) var(--ease-spring-pop), opacity var(--dur-micro-out) linear; }
.ds-check:checked::after { transform: rotate(45deg) scale(1); opacity: 1; }
.ds-check:indeterminate::after { left: 4px; top: 9px; width: 12px; height: 0; border-width: 2.25px 0 0 0; transform: none; opacity: 1; }
.ds-check:disabled, .ds-radio:disabled, .ds-switch:disabled { opacity: 0.45; cursor: not-allowed; }
.ds-check[aria-invalid="true"], .ds-radio[aria-invalid="true"] { box-shadow: inset 0 0 0 2px var(--color-danger); }
/* switch (v4): 40x24, green when on; the off track keeps a 3:1 edge (rule book) */
.ds-switch { appearance: none; -webkit-appearance: none; margin: 0; flex: none; position: relative; width: 40px; height: 24px; border-radius: var(--radius-pill); cursor: pointer;
  background: var(--color-switch-off); box-shadow: inset 0 0 0 1px var(--color-separator-strong);
  transition: background-color var(--dur-micro-in) linear, box-shadow var(--dur-micro-in) linear; }
.ds-switch::before { content: ""; position: absolute; inset: min(0px, calc((24px - var(--hit)) / 2)) -4px; }
.ds-switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: var(--radius-pill); background: var(--color-knob);
  box-shadow: 0 1px 3px var(--color-cast); transform-origin: 0 50%; transform: translateX(0); transition: transform var(--dur-pop) var(--ease-spring-pop); }
.ds-switch:checked { background: var(--color-switch-on); box-shadow: none; }
.ds-switch:checked::after { transform: translateX(16px); }
.ds-switch:active:not(:disabled)::after, .ds-switch.is-pressed::after { transform: translateX(0) scaleX(1.2); transition-duration: var(--dur-press); transition-timing-function: var(--ease-press); }
.ds-switch:checked:active:not(:disabled)::after, .ds-switch:checked.is-pressed::after { transform: translateX(12px) scaleX(1.2); }
@media (hover: hover) { .ds-switch:hover:not(:disabled) { box-shadow: inset 0 0 0 1px var(--color-text-secondary); } .ds-switch:checked:hover:not(:disabled) { box-shadow: none; } }
.ds-switch.is-hover { box-shadow: inset 0 0 0 1px var(--color-text-secondary); }
.ds-switch:focus-visible, .ds-switch.is-focus { outline: 2px solid transparent; box-shadow: inset 0 0 0 1px var(--color-separator-strong), var(--focus-ring); }
.ds-switch--sm { width: 34px; height: 20px; }
.ds-switch--sm::after { width: 16px; height: 16px; }
.ds-switch--sm:checked::after { transform: translateX(14px); }

/* ---------- 5. Badge (small soft label) · status text · filter chip · count badge ---------- */
/* ds-chip = v4's small badge / tag: soft tone background, sentence case */
.ds-chip { --_bg: var(--chip-neutral-bg); --_fg: var(--chip-neutral-fg);
  display: inline-flex; align-items: center; gap: 6px; min-height: 28px; padding: 0 11px; border-radius: var(--radius-pill); background: var(--_bg); color: var(--_fg);
  font: var(--type-footnote); white-space: nowrap; letter-spacing: 0; vertical-align: middle; }
.ds-chip .ds-icon { width: 14px; height: 14px; }
.ds-chip__dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.ds-chip--sm { min-height: 22px; padding: 0 8px; font: var(--type-caption); font-weight: 500; }
.ds-chip--info { --_bg: var(--chip-info-bg); --_fg: var(--chip-info-fg); }
.ds-chip--success { --_bg: var(--chip-success-bg); --_fg: var(--chip-success-fg); }
.ds-chip--warning { --_bg: var(--chip-warning-bg); --_fg: var(--chip-warning-fg); }
.ds-chip--danger { --_bg: var(--chip-danger-bg); --_fg: var(--chip-danger-fg); }
.ds-chip--accent { --_bg: var(--chip-accent-bg); --_fg: var(--chip-accent-fg); }
.ds-chip--add { --_bg: transparent; --_fg: var(--color-tint); box-shadow: inset 0 0 0 1px var(--color-separator-mid); }
/* status (v4): coloured TEXT with a dot, no pill. The label still morphs in place (DS.morph); ::before stays transparent */
.ds-status { --_fg: var(--color-text-secondary); --_sx: 1;
  position: relative; isolation: isolate; display: inline-grid; grid-template-columns: auto auto; align-items: center; column-gap: 6px; clip-path: inset(0 -100vw);
  color: var(--_fg); font: var(--type-footnote); white-space: nowrap; letter-spacing: 0; vertical-align: middle;
  transition: color var(--dur-micro-in) linear; }
/* tones after the base rule (equal specificity: order decides) */
.ds-status--info { --_fg: var(--color-tint); }
.ds-status--success { --_fg: var(--color-success); }
.ds-status--warning { --_fg: var(--color-warning); }
.ds-status--danger { --_fg: var(--color-danger); }
.ds-status--accent { --_fg: var(--color-accent); }
.ds-status--plain::after { display: none; }   /* v4 inbox lines: text only */
.ds-status--plain { grid-template-columns: auto; }
.ds-status--plain .ds-status__label { grid-column: 1; }
.ds-status::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: transparent; transform-origin: 0 50%; transform: scaleX(var(--_sx)); }
.ds-status::after { content: ""; grid-row: 1; grid-column: 1; width: 7px; height: 7px; border-radius: 50%; background: currentColor; transition: transform var(--dur-pop) var(--ease-spring-pop); }
.ds-status.is-bump::after { transform: scale(1.6); }
.ds-status__label { grid-row: 1; grid-column: 2; transition: transform var(--dur-enter) var(--ease-spring), opacity var(--dur-micro-in) linear; }
.ds-status__label.is-leaving { position: absolute; transform: translateY(calc(-100% * var(--motion-shift))); opacity: 0; transition: transform var(--dur-exit) var(--ease-in), opacity var(--dur-micro-out) linear; }
.ds-status__label.is-entering { transform: translateY(calc(100% * var(--motion-shift))); opacity: 0; transition: none; }
/* online dot (v4 "Active now", "Available") */
.ds-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--color-online); flex: none; vertical-align: middle; }
.ds-dot--tint { background: var(--color-tint-fill); width: 8px; height: 8px; }
/* filter chip (v4): grey pill, the selected one inverts */
.ds-fchip { appearance: none; border: 0; margin: 0; position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 32px; min-width: var(--hit); padding: 0 13px;
  border-radius: var(--radius-pill); font: var(--type-label-sm); white-space: nowrap; cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  background: var(--color-fill); color: var(--color-text);
  transform: scale(1); transition: transform var(--dur-release) var(--ease-press-release), background-color var(--dur-micro-out) linear, color var(--dur-micro-out) linear; }
.ds-fchip::before { content: ""; position: absolute; inset: min(0px, calc((32px - var(--hit)) / 2)) 0; }
.ds-fchip .ds-icon { width: 16px; height: 16px; }
.ds-fchip__count { font-weight: 400; font-variant-numeric: tabular-nums; color: var(--color-text-secondary); }
@media (hover: hover) { .ds-fchip:hover:not(:disabled):not([aria-pressed="true"]) { background: var(--color-fill-hover); } }
.ds-fchip.is-hover { background: var(--color-fill-hover); }
.ds-fchip:active:not(:disabled), .ds-fchip.is-pressed { transform: scale(var(--press-scale)); transition-duration: var(--dur-press); transition-timing-function: var(--ease-press); }
.ds-fchip:focus-visible, .ds-fchip.is-focus { outline: 2px solid transparent; box-shadow: var(--focus-ring); }
.ds-fchip[aria-pressed="true"] { background: var(--color-surface-inverse); color: var(--color-text-inverse); }
.ds-fchip[aria-pressed="true"] .ds-fchip__count { color: var(--color-text-inverse); }
.ds-fchip:disabled { opacity: 0.45; cursor: not-allowed; }
.ds-chips { display: flex; gap: var(--space-2); overflow-x: auto; scrollbar-width: none; padding-block: var(--space-1); }
.ds-chips::-webkit-scrollbar { display: none; }
/* count badge (v4): red for alerts, blue for counts in the nav */
.ds-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--radius-pill);
  background: var(--color-badge); color: var(--color-on-badge); font: var(--type-caption); font-weight: 600; line-height: 20px; font-variant-numeric: tabular-nums; letter-spacing: 0; }
.ds-badge--tint { background: var(--color-tint-fill); color: var(--color-on-tint); }
.ds-badge--neutral { background: var(--color-fill); color: var(--color-text); }
.ds-badge--dot { min-width: 0; width: 8px; height: 8px; padding: 0; }
.ds-badge--ring { box-shadow: 0 0 0 2px var(--color-bg); }

/* ---------- 6. Avatar (v4: 36px, initials on a soft fill) ---------- */
.ds-avatar { --_size: 36px; position: relative; flex: none; width: var(--_size); height: var(--_size); border-radius: 50%; display: inline-grid; place-items: center;
  background: var(--color-fill); color: var(--color-text); font: var(--type-label); font-weight: 600; font-size: calc(var(--_size) * 0.38); line-height: 1.4; }
.ds-avatar > img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
.ds-avatar--xs { --_size: 22px; } .ds-avatar--sm { --_size: 28px; } .ds-avatar--lg { --_size: 44px; } .ds-avatar--xl { --_size: 72px; }
.ds-avatar--xs, .ds-avatar--sm { font-size: 12px; }
.ds-avatar--info { background: var(--chip-info-bg); color: var(--chip-info-fg); }
.ds-avatar--success { background: var(--chip-success-bg); color: var(--chip-success-fg); }
.ds-avatar--warning { background: var(--chip-warning-bg); color: var(--chip-warning-fg); }
.ds-avatar--accent { background: var(--chip-accent-bg); color: var(--chip-accent-fg); }
.ds-avatar__channel { position: absolute; right: -2px; bottom: -2px; width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center;
  box-shadow: 0 0 0 2px var(--color-surface); }
.ds-avatar__channel .ds-icon { width: 12px; height: 12px; }
.ds-avatar__channel--facebook { background: var(--channel-facebook); color: var(--channel-on-facebook); }
.ds-avatar__channel--whatsapp { background: var(--channel-whatsapp); color: var(--channel-on-whatsapp); }
.ds-avatar__channel--instagram { background: var(--channel-instagram); color: var(--channel-on-instagram); }
.ds-avatar__channel--tiktok { background: var(--channel-tiktok); color: var(--channel-on-tiktok); }

/* ---------- 7. Card · KPI (v4: a hairline ring, no heavy shadow) ---------- */
.ds-card { --ds-card-pad: 20px; position: relative; display: block; padding: 18px var(--ds-card-pad); border-radius: var(--radius-card);
  background: var(--color-surface); color: var(--color-text); box-shadow: var(--elev-1); text-decoration: none; }
.ds-card--flush { --ds-card-pad: 0px; padding: 0; overflow: hidden; }
.ds-card--raised { box-shadow: var(--elev-2); }
.ds-card--quiet { background: var(--color-bg-tertiary); }
/* concentric: anything inset by the card padding uses this radius */
.ds-card__inset { border-radius: max(0px, calc(var(--radius-card) - var(--ds-card-pad))); overflow: hidden; }
.ds-card__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-3); }
.ds-card__title { font: var(--type-headline); margin: 0; }
:lang(en) .ds-card__title { letter-spacing: -0.01em; }
.ds-card__action { font: var(--type-footnote); font-weight: 500; color: var(--color-tint); text-decoration: none; border-radius: var(--radius-xs); }
.ds-card__meta { font: var(--type-footnote); color: var(--color-text-secondary); }
.ds-card--interactive { cursor: pointer; transform: scale(1); transition: transform var(--dur-release) var(--ease-press-release), background-color var(--dur-micro-in) linear; -webkit-tap-highlight-color: transparent; }
@media (hover: hover) { .ds-card--interactive:hover { background: var(--color-bg-tertiary); } }
.ds-card--interactive.is-hover { background: var(--color-bg-tertiary); }
.ds-card--interactive:active, .ds-card--interactive.is-pressed { transform: scale(var(--press-scale-row)); transition-duration: var(--dur-press); transition-timing-function: var(--ease-press); }
.ds-card--interactive:focus-visible, .ds-card--interactive.is-focus { outline: 2px solid transparent; box-shadow: var(--focus-ring), var(--elev-1); }
.ds-kpi { display: flex; flex-direction: column; gap: 2px; padding: 16px 18px; border-radius: var(--radius-card); background: var(--color-surface); box-shadow: var(--elev-1); min-width: 0; }
.ds-kpi__label { font: var(--type-footnote); color: var(--color-text-secondary); display: flex; gap: 7px; align-items: center; }
.ds-kpi__value { font: var(--type-numeral); margin-top: 4px; font-variant-numeric: tabular-nums; white-space: nowrap; }
:lang(en) .ds-kpi__value { letter-spacing: -0.025em; }
.ds-kpi__value .ds-money__cur { font: var(--type-numeral); }
.ds-kpi__delta { font: var(--type-caption); color: var(--color-text-secondary); display: flex; gap: var(--space-1); align-items: center; }
.ds-kpi__delta--up { color: var(--color-success); } .ds-kpi__delta--down { color: var(--color-danger); }

/* ---------- 8. Lists (v4) ----------
   .ds-list         = grouped list (settings, contact info, orders): radius 14, hairline ring, full-width separators
   .ds-list--plain  = inbox-style rows: rounded 14px rows with hover fill, unread dot, the selected row turns blue */
.ds-list { list-style: none; margin: 0; padding: 0; border-radius: var(--radius-group); background: var(--color-surface); box-shadow: var(--elev-1); overflow: hidden; }
.ds-list--plain { border-radius: 0; background: transparent; box-shadow: none; overflow: visible; padding: 0 var(--space-2); }
.ds-list__heading { font: var(--type-footnote); font-weight: 600; color: var(--color-text-secondary); padding: 0 var(--space-1) var(--space-2); margin: 0; }
.ds-row { --ds-row-inset: 0px; position: relative; display: flex; align-items: center; gap: var(--space-3); min-height: 44px; padding: 11px 14px;
  color: var(--color-text); text-decoration: none; background: transparent; width: 100%; border: 0; margin: 0; font: var(--type-body); text-align: start;
  -webkit-tap-highlight-color: transparent; transition: background-color var(--dur-micro-out) linear; }
.ds-list > li + li > .ds-row::before, .ds-list > .ds-row + .ds-row::before { content: ""; position: absolute; top: 0; right: 0; left: var(--ds-row-inset); border-top: 1px solid var(--color-separator); }
.ds-list--plain > li + li > .ds-row::before, .ds-list--plain > .ds-row + .ds-row::before { display: none; }
.ds-list--plain .ds-row { align-items: flex-start; padding: 12px 12px 12px 22px; border-radius: var(--radius-group); }
.ds-row--lead { --ds-row-inset: 62px; }
a.ds-row, button.ds-row { cursor: pointer; }
@media (hover: hover) { a.ds-row:hover, button.ds-row:hover { background: var(--color-fill); } }
.ds-row.is-hover { background: var(--color-fill); }
a.ds-row:active, button.ds-row:active, .ds-row.is-pressed { background: var(--color-fill-hover); transition-duration: var(--dur-press); }
a.ds-row:focus-visible, button.ds-row:focus-visible, .ds-row.is-focus { outline: 2px solid transparent; box-shadow: var(--focus-ring-inset); }
/* selected (v4 inbox): blue row, everything inside turns white */
.ds-row[aria-current="true"], .ds-row[aria-current="page"], .ds-row[aria-selected="true"] { background: var(--color-tint-fill); color: var(--color-on-tint); }
.ds-row:is([aria-current="true"], [aria-current="page"], [aria-selected="true"]) :is(.ds-row__sub, .ds-row__trail, .ds-row__chev, .ds-status, .ds-row__lead) { color: var(--color-on-tint); }
.ds-row:is([aria-current="true"], [aria-current="page"], [aria-selected="true"]) .ds-row__dot { background: var(--color-on-tint); }
.ds-row:is([aria-current="true"], [aria-current="page"], [aria-selected="true"]) .ds-avatar { background: var(--color-on-tint); color: var(--color-tint-fill); }
.ds-row:is([aria-current="true"], [aria-current="page"], [aria-selected="true"]):focus-visible { box-shadow: var(--focus-ring); }
.ds-row__dot { position: absolute; left: 8px; top: 28px; width: 8px; height: 8px; border-radius: 50%; background: var(--color-tint-fill); }
.ds-row__lead { flex: none; display: flex; align-items: center; color: var(--color-text-secondary); }
.ds-row__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.ds-row__title { font: var(--type-body); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-block: 1px; }
.ds-row__sub { font: var(--type-subhead); color: var(--color-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-block: 1px; }
.ds-row__meta { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); font: var(--type-caption); min-height: 22px; }
.ds-row__trail { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-1); font: var(--type-caption); color: var(--color-text-tertiary); }
.ds-row__chev { flex: none; color: var(--color-text-tertiary); }
.ds-row--unread .ds-row__sub { color: var(--color-text); font-weight: 500; }
.ds-row--unread .ds-row__trail { color: var(--color-text); font-weight: 600; }
/* key / value row (v4 contact panel) */
.ds-kv__k { font: var(--type-caption); color: var(--color-text-secondary); }
.ds-kv__v { font: var(--type-body); margin-top: 1px; }

/* ---------- 9. Table (v4: quiet header, hairlines, tabular numbers) ---------- */
.ds-table-wrap { max-width: 100%; overflow-x: auto; overscroll-behavior-x: contain; border-radius: var(--radius-card); background: var(--color-surface); box-shadow: var(--elev-1); padding: var(--space-1) var(--space-4) var(--space-2); }
.ds-table-wrap--bare { border-radius: 0; background: transparent; box-shadow: none; padding: 0; }
.ds-table { width: 100%; border-collapse: separate; border-spacing: 0; font: var(--type-body); font-variant-numeric: tabular-nums; color: var(--color-text); }
.ds-table th { position: sticky; top: 0; z-index: 1; background: var(--color-surface); text-align: start; font: var(--type-caption); font-weight: 500; color: var(--color-text-secondary);
  padding: var(--space-2) 10px; border-bottom: 1px solid var(--color-separator); white-space: nowrap; }
.ds-table td { padding: 11px 10px; border-bottom: 1px solid var(--color-separator); vertical-align: middle; white-space: nowrap; }
.ds-table tbody tr:last-child td { border-bottom: 0; }
.ds-table th:first-child, .ds-table td:first-child { padding-inline-start: 4px; }
.ds-table__num { text-align: end; font-variant-numeric: tabular-nums; letter-spacing: 0; white-space: nowrap; }
.ds-table__code { font-weight: 600; letter-spacing: 0.01em; white-space: nowrap; }
@media (hover: hover) { .ds-table--hover tbody tr:hover:not([aria-selected="true"]) td { background: var(--color-veil); } }
.ds-table tbody tr[aria-selected="true"] td { background: var(--color-tint-soft); }
.ds-table tbody tr[aria-selected="true"] td:first-child { border-radius: var(--radius-control) 0 0 var(--radius-control); }
.ds-table tbody tr[aria-selected="true"] td:last-child { border-radius: 0 var(--radius-control) var(--radius-control) 0; }
.ds-table--dense td { padding-block: 7px; }
.ds-table a { color: inherit; text-decoration: none; border-radius: var(--radius-xs); }
.ds-table a:focus-visible { outline: 2px solid transparent; box-shadow: var(--focus-ring); }
@media (hover: hover) { .ds-table a:hover { color: var(--color-tint); } }
/* < 768px: rows become cards (td needs data-label) */
@media (max-width: 767px) {
  .ds-table--stack thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .ds-table--stack, .ds-table--stack tbody, .ds-table--stack tr, .ds-table--stack td { display: block; width: 100%; }
  .ds-table--stack tr { padding: var(--space-2) 0; border-top: 1px solid var(--color-separator); }
  .ds-table--stack tbody tr:first-child { border-top: 0; }
  .ds-table--stack td { display: flex; justify-content: space-between; gap: var(--space-3); border-bottom: 0; padding: var(--space-1) var(--space-1); text-align: end; white-space: normal; }
  .ds-table--stack td::before { content: attr(data-label); font: var(--type-footnote); color: var(--color-text-secondary); text-align: start; }
}

/* ---------- 10. Tabs (v4 underline) · segmented control (v4 period picker) ---------- */
.ds-tabs { display: flex; gap: var(--space-6); overflow-x: auto; scrollbar-width: none; box-shadow: inset 0 -1px 0 var(--color-separator); }
.ds-tabs::-webkit-scrollbar { display: none; }
.ds-tab { appearance: none; border: 0; margin: 0; background: transparent; position: relative; display: inline-flex; align-items: center; gap: 6px;
  min-height: 42px; padding: 0; font: var(--type-body); font-weight: 500; color: var(--color-text-secondary); white-space: nowrap; cursor: pointer; text-decoration: none;
  -webkit-tap-highlight-color: transparent; transition: color var(--dur-micro-in) linear; }
.ds-tab::before { content: ""; position: absolute; inset: min(0px, calc((42px - var(--hit)) / 2)) calc(var(--space-3) * -1); }
.ds-tab__count { font: var(--type-caption); font-weight: 500; color: var(--color-text-tertiary); }
.ds-tab::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; border-radius: 1px; background: var(--color-tint-fill);
  transform: scaleX(0); opacity: 0; transition: transform var(--dur-micro-out) var(--ease-in), opacity var(--dur-micro-out) linear; }
@media (hover: hover) { .ds-tab:hover { color: var(--color-text); } }
.ds-tab.is-hover { color: var(--color-text); }
.ds-tab:active { color: var(--color-text); }
.ds-tab:focus-visible, .ds-tab.is-focus { outline: 2px solid transparent; box-shadow: var(--focus-ring); border-radius: var(--radius-xs); }
.ds-tab[aria-selected="true"], .ds-tab[aria-current="page"] { color: var(--color-text); font-weight: 600; }
.ds-tab[aria-selected="true"]::after, .ds-tab[aria-current="page"]::after { transform: scaleX(1); opacity: 1; transition: transform var(--dur-pop) var(--ease-spring-pop), opacity var(--dur-micro-in) linear; }
.ds-tabpanels { position: relative; display: grid; overflow: hidden; }
.ds-tabpanel { grid-area: 1 / 1; min-width: 0; transition: transform var(--dur-enter) var(--ease-spring), opacity var(--dur-micro-in) linear; }
.ds-tabpanel[hidden] { display: block; visibility: hidden; opacity: 0; pointer-events: none; transition: transform var(--dur-exit) var(--ease-in), opacity var(--dur-micro-out) linear, visibility 0s linear var(--dur-exit); }
.ds-tabpanel.is-from-right { transform: translateX(calc(30% * var(--motion-shift))); opacity: 0; transition: none; }
.ds-tabpanel.is-from-left { transform: translateX(calc(-30% * var(--motion-shift))); opacity: 0; transition: none; }
.ds-tabpanel[hidden].is-to-left { transform: translateX(calc(-30% * var(--motion-shift))); }
.ds-tabpanel[hidden].is-to-right { transform: translateX(calc(30% * var(--motion-shift))); }
/* segmented (v4): grey track, the selected segment is a white thumb that slides (DS.seg sets --i / --n) */
.ds-seg { --i: 0; --n: 2; position: relative; isolation: isolate; display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; padding: 2px;
  border-radius: calc(var(--radius-control) - 1px); background: var(--color-fill); max-width: 100%; }
.ds-seg--block { display: grid; width: 100%; }
.ds-seg--auto { grid-auto-columns: auto; }   /* unequal widths (v4 "Today · 7 days · This month · 1–15 Oct"): no sliding thumb */
.ds-seg__thumb { position: absolute; z-index: -1; top: 2px; bottom: 2px; left: 2px; width: calc((100% - 4px) / var(--n)); border-radius: calc(var(--radius-control) - 3px);
  background: var(--color-seg-thumb); box-shadow: 0 1px 2px var(--color-cast), 0 0 0 0.5px var(--color-separator); transform: translateX(calc(100% * var(--i)));
  transition: transform var(--dur-enter) var(--ease-spring-pop); }
.ds-seg--auto > .ds-seg__thumb { display: none; }
.ds-seg > button { appearance: none; border: 0; margin: 0; background: transparent; position: relative; min-height: 28px; min-width: 44px; padding: 0 12px;
  border-radius: calc(var(--radius-control) - 3px); font: var(--type-label-sm); color: var(--color-text-secondary); cursor: pointer; white-space: nowrap;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; -webkit-tap-highlight-color: transparent;
  transform: scale(1); transition: color var(--dur-micro-in) linear, transform var(--dur-release) var(--ease-press-release), background-color var(--dur-micro-in) linear; }
.ds-seg > button::before { content: ""; position: absolute; inset: min(0px, calc((28px - var(--hit)) / 2)) 0; }
@media (hover: hover) { .ds-seg > button:hover:not([aria-pressed="true"]) { color: var(--color-text); } }
.ds-seg > button:active { transform: scale(var(--press-scale)); transition-duration: var(--dur-press); transition-timing-function: var(--ease-press); }
.ds-seg > button:focus-visible, .ds-seg > button.is-focus { outline: 2px solid transparent; box-shadow: var(--focus-ring); }
.ds-seg > button[aria-pressed="true"], .ds-seg > button[aria-selected="true"] { color: var(--color-text); font-weight: 600; }
.ds-seg--auto > button[aria-pressed="true"], .ds-seg--auto > button[aria-selected="true"] { background: var(--color-seg-thumb); box-shadow: 0 1px 2px var(--color-cast), 0 0 0 0.5px var(--color-separator); }

/* ---------- 11. Dialogs: modal · sheet · drawer (native <dialog>, DS.open / DS.close) · menu ---------- */
.ds-modal, .ds-sheet, .ds-drawer { border: 0; padding: 0; color: var(--color-text); background: var(--color-surface-elevated); overflow: auto; overscroll-behavior: contain; max-width: none; max-height: none; }
.ds-modal::backdrop, .ds-sheet::backdrop, .ds-drawer::backdrop { background: var(--color-overlay); animation: ds-fade-in var(--dur-enter) linear; }
.ds-modal.is-closing::backdrop, .ds-sheet.is-closing::backdrop, .ds-drawer.is-closing::backdrop { animation: ds-fade-out var(--dur-exit) linear forwards; }
/* modal (v4 sheet card): centred, 480px, radius 20 */
.ds-modal { width: min(480px, calc(100vw - 32px)); max-height: calc(100dvh - 32px); margin: auto; padding: 22px 24px 24px; border-radius: var(--radius-sheet); box-shadow: var(--elev-5); }
.ds-modal[open] { animation: ds-modal-in var(--dur-enter) var(--ease-spring); }
.ds-modal.is-closing { animation: ds-modal-out var(--dur-exit) var(--ease-in) forwards; }
.ds-modal__icon { width: 48px; height: 48px; border-radius: 50%; display: grid; place-items: center; background: var(--color-danger-soft); color: var(--color-danger); margin-bottom: var(--space-3); }
.ds-modal__title { font: var(--type-title3); margin: 0 0 var(--space-1); }
.ds-modal__text { font: var(--type-subhead); color: var(--color-text-secondary); margin: 0; }
.ds-modal__impact { list-style: none; margin: var(--space-4) 0 0; padding: var(--space-3) var(--space-4); display: grid; gap: var(--space-2); border-radius: var(--radius-group);
  background: var(--color-fill); font: var(--type-subhead); }
.ds-modal__impact li { display: flex; justify-content: space-between; gap: var(--space-3); }
.ds-dialog-actions { display: flex; gap: var(--space-2); justify-content: flex-end; margin-top: var(--space-6); flex-wrap: wrap-reverse; }
@media (max-width: 480px) { .ds-dialog-actions > .ds-btn { flex: 1 1 100%; } }
/* selectable option card inside a sheet (v4 top-up packs) */
.ds-option { display: flex; align-items: center; gap: 14px; padding: 14px 16px; border-radius: var(--radius-group); box-shadow: inset 0 0 0 1px var(--color-separator-mid); cursor: pointer; }
.ds-option:has(:checked) { box-shadow: inset 0 0 0 2px var(--color-tint-fill); background: var(--color-tint-soft); }
.ds-option:focus-within { outline: 2px solid transparent; box-shadow: inset 0 0 0 2px var(--color-tint-fill), var(--focus-ring); }
.ds-option__end { margin-inline-start: auto; font: var(--type-headline); font-weight: 600; font-variant-numeric: tabular-nums; }
/* sheet (inserted task from the bottom on phones; a centred card on desktop) */
.ds-sheet { --_drag: 0px; position: fixed; inset: auto 0 0 0; margin: 0 auto; width: auto; max-width: 560px;
  max-height: calc(100dvh - 48px); padding: var(--space-2) var(--space-5) max(var(--space-5), env(safe-area-inset-bottom));
  border-radius: var(--radius-sheet) var(--radius-sheet) 0 0; box-shadow: var(--elev-4); transform: translateY(var(--_drag)); touch-action: pan-y; }
@media (min-width: 768px) { .ds-sheet { inset: auto var(--space-4) var(--space-4) var(--space-4); max-width: 480px; border-radius: var(--radius-sheet); box-shadow: var(--elev-5); } }
.ds-sheet[open] { animation: ds-sheet-in var(--dur-enter) var(--ease-spring); }
.ds-sheet.is-closing { animation: ds-sheet-out var(--dur-exit) var(--ease-in) forwards; }
.ds-sheet.is-dragging { transition: none; cursor: grabbing; }
.ds-sheet.is-settling { transition: transform var(--dur-enter) var(--ease-spring); }
.ds-sheet--glass { background: var(--glass-bg-strong); -webkit-backdrop-filter: var(--glass-filter); backdrop-filter: var(--glass-filter); }
.ds-sheet__grabber { appearance: none; border: 0; margin: 0 auto; padding: 0; display: block; position: relative; width: 36px; height: 5px; border-radius: var(--radius-pill);
  background: var(--color-separator-strong); cursor: grab; touch-action: none; }
.ds-sheet__grabber::before { content: ""; position: absolute; inset: -16px -40px; }
.ds-sheet__grabber:focus-visible { outline: 2px solid transparent; box-shadow: var(--focus-ring); }
.ds-sheet__head, .ds-drawer__head { display: flex; align-items: center; gap: var(--space-3); min-height: 48px; margin-bottom: var(--space-2); }
.ds-sheet__title, .ds-drawer__title { font: var(--type-title3); margin: 0; flex: 1; min-width: 0; }
.ds-sheet__foot, .ds-drawer__foot { display: flex; gap: var(--space-2); margin-top: var(--space-5); }
.ds-sheet__foot > .ds-btn, .ds-drawer__foot > .ds-btn { flex: 1; }
/* drawer (side panel, e.g. VisionX order detail). < 768px it is a full-screen push from the right */
.ds-drawer { position: fixed; inset: 0 0 0 auto; margin: 0; width: min(420px, 100vw); height: 100dvh; max-height: 100dvh; padding: 22px 24px max(var(--space-5), env(safe-area-inset-bottom));
  border-radius: 0; box-shadow: var(--elev-5); }
.ds-drawer[open] { animation: ds-drawer-in var(--dur-enter) var(--ease-spring); }
.ds-drawer.is-closing { animation: ds-drawer-out var(--dur-exit) var(--ease-in) forwards; }
.ds-drawer--left { inset: 0 auto 0 0; }
.ds-drawer--left[open] { animation-name: ds-drawer-in-left; }
.ds-drawer--left.is-closing { animation-name: ds-drawer-out-left; }
@media (max-width: 767px) { .ds-drawer:not(.ds-drawer--left) { width: 100vw; } .ds-drawer--left { width: min(320px, 86vw); } }
/* menu (v4 attach menu / overflow): a popover panel of 40px rows with blue icons */
.ds-menu { min-width: 220px; padding: 6px; border-radius: var(--radius-group); background: var(--color-surface-elevated); color: var(--color-text); box-shadow: var(--elev-3); }
.ds-menu__item { appearance: none; border: 0; margin: 0; width: 100%; display: flex; align-items: center; gap: var(--space-3); min-height: 40px; padding: 0 10px; border-radius: 9px;
  background: transparent; color: inherit; font: var(--type-body); text-align: start; text-decoration: none; cursor: pointer; transition: background-color var(--dur-micro-out) linear; }
.ds-menu__item .ds-icon { color: var(--color-tint); }
@media (hover: hover) { .ds-menu__item:hover { background: var(--color-fill); } }
.ds-menu__item.is-hover { background: var(--color-fill); }
.ds-menu__item:active { background: var(--color-fill-hover); }
.ds-menu__item:focus-visible { outline: 2px solid transparent; box-shadow: var(--focus-ring-inset); }
.ds-menu__sep { height: 1px; background: var(--color-separator); margin: 5px 8px; border: 0; }

/* ---------- 12. Toast with undo (DS.toast) · v4: a dark pill with a light-blue action ---------- */
.ds-toast-host { position: fixed; left: 0; right: 0; bottom: max(var(--space-4), env(safe-area-inset-bottom), var(--ds-toast-offset, 0px)); top: auto; z-index: var(--z-toast);
  display: grid; justify-items: center; gap: var(--space-2); padding: 0 var(--edge); pointer-events: none; }
.ds-toast-host[popover] { inset: auto 0 max(var(--space-4), env(safe-area-inset-bottom), var(--ds-toast-offset, 0px)) 0; margin: 0; border: 0; width: auto; height: auto; background: transparent; overflow: visible; color: inherit; }
.ds-toast { pointer-events: auto; display: flex; align-items: center; gap: var(--space-3); max-width: min(440px, 100%); min-height: 44px; padding: 6px 6px 6px 18px;
  border-radius: 22px; color: var(--color-on-toast); background: var(--color-toast); font: var(--type-body); box-shadow: var(--elev-5);
  transform: translateY(calc(24px * var(--motion-shift))) scale(calc(1 - 0.04 * var(--motion-shift))); opacity: 0;
  transition: transform var(--dur-micro-out) var(--ease-in), opacity var(--dur-micro-out) linear; }
.ds-toast.is-in { transform: none; opacity: 1; transition: transform var(--dur-enter) var(--ease-spring-pop), opacity var(--dur-micro-in) linear; }
.ds-toast__icon { display: grid; place-items: center; flex: none; color: var(--color-on-toast); margin-inline-start: -4px; }
.ds-toast__icon .ds-icon { width: 18px; height: 18px; }
.ds-toast__msg { flex: 1; min-width: 0; }
.ds-toast .ds-btn { --_bg0: transparent; --_bgh: color-mix(in srgb, var(--color-on-toast) 12%, transparent); --_bgp: color-mix(in srgb, var(--color-on-toast) 16%, transparent);
  --_fg: var(--color-toast-action); --_fgh: var(--color-toast-action); font-weight: 600; border-radius: var(--radius-pill); }
.ds-toast .ds-btn.ds-btn--icon-sm { --_fg: var(--color-on-toast); --_fgh: var(--color-on-toast); }
.ds-toast .ds-btn:focus-visible { box-shadow: 0 0 0 2px var(--color-toast-action); }

/* ---------- 13. Mobile tab bar (v4: docked, quiet backdrop, labels always at 12px) ---------- */
.ds-tabbar { position: fixed; z-index: var(--z-tabbar); left: 0; right: 0; bottom: 0;
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); padding: 6px var(--space-2) max(var(--space-1), env(safe-area-inset-bottom));
  background: var(--glass-bg); -webkit-backdrop-filter: var(--glass-filter); backdrop-filter: var(--glass-filter); box-shadow: inset 0 1px 0 var(--color-separator); }
.ds-tabbar--static { position: relative; left: auto; right: auto; bottom: auto; }
@media (min-width: 768px) { .ds-tabbar:not(.ds-tabbar--always) { display: none; } }
.ds-tabbar__item { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 3px; min-width: 0; min-height: 44px; padding: 2px 2px var(--space-1);
  border-radius: var(--radius-control); color: var(--color-text-secondary); text-decoration: none; font: var(--type-tab); -webkit-tap-highlight-color: transparent;
  transition: color var(--dur-micro-in) linear; }
.ds-tabbar__item .ds-icon { width: 24px; height: 24px; transform: scale(1); transition: transform var(--dur-release) var(--ease-press-release); }
.ds-tabbar__label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-block: 1px; }
.ds-tabbar__item:active .ds-icon, .ds-tabbar__item.is-pressed .ds-icon { transform: scale(var(--press-scale-icon)); transition-duration: var(--dur-press); transition-timing-function: var(--ease-press); }
@media (hover: hover) { .ds-tabbar__item:hover:not([aria-current="page"]) { color: var(--color-text); } }
.ds-tabbar__item:focus-visible, .ds-tabbar__item.is-focus { outline: 2px solid transparent; box-shadow: var(--focus-ring-inset); }
.ds-tabbar__item[aria-current="page"] { color: var(--color-tint); }
.ds-tabbar__badge { position: absolute; top: -2px; left: calc(50% + 6px); box-shadow: 0 0 0 2px var(--color-bg); }

/* ---------- 14. Desktop sidebar · app rail · shop switcher (v4) ---------- */
.ds-sidebar { display: flex; flex-direction: column; gap: 2px; width: 232px; min-height: 100%; padding: 16px 12px 12px; background: var(--color-bg-secondary);
  box-shadow: inset -1px 0 0 var(--color-separator); }
.ds-sidebar__brand { display: flex; align-items: center; gap: 10px; min-height: 36px; padding: 0 6px; margin-bottom: 18px; font: var(--type-headline); font-size: 15px; color: var(--color-text); text-decoration: none; border-radius: var(--radius-control); }
.ds-sidebar__brand:focus-visible { outline: 2px solid transparent; box-shadow: var(--focus-ring); }
.ds-logo { width: 28px; height: 28px; flex: none; border-radius: var(--radius-sm); display: grid; place-items: center; background: var(--color-tint-fill); color: var(--color-on-tint); font: var(--type-caption); font-weight: 700; }
.ds-logo--ink { background: var(--color-surface-inverse); color: var(--color-text-inverse); }
.ds-sidebar__heading { font: var(--type-caption); font-weight: 600; color: var(--color-text-secondary); padding: 18px 10px 6px; margin: 0; }
.ds-sidebar__foot { margin-top: auto; display: flex; align-items: center; gap: 10px; padding: 12px 6px 0; box-shadow: inset 0 1px 0 var(--color-separator); }
.ds-sidebar__who { flex: 1; min-width: 0; }
.ds-sidebar__who-name { display: block; font: var(--type-body); font-weight: 600; }
.ds-sidebar__who-status { display: flex; align-items: center; gap: 5px; font: var(--type-caption); color: var(--color-text-secondary); }
.ds-navitem { position: relative; display: flex; align-items: center; gap: 11px; min-height: 38px; padding: 0 10px; border-radius: var(--radius-control);
  color: var(--color-text); text-decoration: none; font: var(--type-body); -webkit-tap-highlight-color: transparent;
  transition: background-color var(--dur-micro-in) linear, color var(--dur-micro-in) linear; }
.ds-navitem::before { content: ""; position: absolute; inset: min(0px, calc((38px - var(--hit)) / 2)) 0; }
.ds-navitem > .ds-icon { color: var(--color-tint); }
.ds-navitem__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-block: 1px; }
.ds-navitem__count { font: var(--type-footnote); font-variant-numeric: tabular-nums; color: var(--color-text-secondary); }
@media (hover: hover) { .ds-navitem:hover:not([aria-current="page"]) { background: var(--color-nav-hover); } }
.ds-navitem.is-hover { background: var(--color-nav-hover); }
.ds-navitem:active:not([aria-current="page"]), .ds-navitem.is-pressed { background: var(--color-nav-selected); }
.ds-navitem:focus-visible, .ds-navitem.is-focus { outline: 2px solid transparent; box-shadow: var(--focus-ring-inset); }
.ds-navitem[aria-current="page"] { background: var(--color-nav-selected); font-weight: 600; }
/* rail: icon over a 12px label (VSchat narrow nav) */
.ds-rail { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); width: 80px; min-height: 100%; padding: var(--space-3) var(--space-2);
  background: var(--color-bg-secondary); box-shadow: inset -1px 0 0 var(--color-separator); }
.ds-rail__item { position: relative; display: flex; flex-direction: column; align-items: center; gap: 4px; width: 100%; padding: var(--space-1) 0; color: var(--color-text-secondary);
  text-decoration: none; font: var(--type-tab); border-radius: var(--radius-control); -webkit-tap-highlight-color: transparent; transition: color var(--dur-micro-in) linear; }
.ds-rail__pill { display: grid; place-items: center; width: 52px; height: 32px; border-radius: var(--radius-control); color: var(--color-tint); transform: scale(1);
  transition: background-color var(--dur-micro-in) linear, transform var(--dur-release) var(--ease-press-release); }
.ds-rail__pill .ds-icon { width: 22px; height: 22px; }
.ds-rail__label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-block: 1px; }
@media (hover: hover) { .ds-rail__item:hover:not([aria-current="page"]) { color: var(--color-text); } .ds-rail__item:hover:not([aria-current="page"]) .ds-rail__pill { background: var(--color-nav-hover); } }
.ds-rail__item:active .ds-rail__pill { transform: scale(var(--press-scale)); transition-duration: var(--dur-press); }
.ds-rail__item:focus-visible, .ds-rail__item.is-focus { outline: 2px solid transparent; box-shadow: var(--focus-ring-inset); }
.ds-rail__item[aria-current="page"] { color: var(--color-text); font-weight: 600; }
.ds-rail__item[aria-current="page"] .ds-rail__pill { background: var(--color-nav-selected); }
.ds-rail__badge { position: absolute; top: 0; left: calc(50% + 8px); }
/* shop switcher (v4): opens in place and pushes the nav down (DS.disclosure / [data-ds-disclosure]) */
.ds-switcher { display: block; }
.ds-switcher__btn { appearance: none; border: 0; margin: 0; position: relative; display: flex; align-items: center; gap: 10px; width: 100%; min-height: 44px; padding: var(--space-2);
  border-radius: 12px; background: transparent; color: var(--color-text); font: inherit; text-align: start; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background-color var(--dur-micro-in) linear; }
@media (hover: hover) { .ds-switcher__btn:hover { background: var(--color-nav-hover); } }
.ds-switcher__btn.is-hover, .ds-switcher__btn[aria-expanded="true"] { background: var(--color-nav-hover); }
.ds-switcher__btn:active { background: var(--color-nav-selected); }
.ds-switcher__btn:focus-visible { outline: 2px solid transparent; box-shadow: var(--focus-ring); }
.ds-switcher__text { flex: 1; min-width: 0; }
.ds-switcher__name { display: block; font: var(--type-body); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-block: 1px; }
.ds-switcher__sub { display: block; font: var(--type-caption); color: var(--color-text-secondary); }
.ds-switcher__chev { color: var(--color-text-tertiary); transform: rotate(0deg); transition: transform var(--dur-micro-in) var(--ease-out); }
.ds-switcher__btn[aria-expanded="true"] .ds-switcher__chev { transform: rotate(180deg); }
.ds-switcher__list { margin: 6px 0 4px; padding: var(--space-1); border-radius: 12px; background: var(--color-surface-elevated); box-shadow: var(--elev-2); }
.ds-switcher__list[hidden] { display: none; }
.ds-switcher__list:not([hidden]) { animation: ds-fade-in var(--dur-micro-in) linear; }
.ds-switcher__item { appearance: none; border: 0; margin: 0; display: flex; align-items: center; gap: 10px; width: 100%; min-height: 44px; padding: 0 10px; border-radius: 9px;
  background: transparent; color: var(--color-text); font: var(--type-body); text-align: start; text-decoration: none; cursor: pointer; transition: background-color var(--dur-micro-out) linear; }
@media (hover: hover) { .ds-switcher__item:hover { background: var(--color-fill); } }
.ds-switcher__item:active { background: var(--color-fill-hover); }
.ds-switcher__item:focus-visible { outline: 2px solid transparent; box-shadow: var(--focus-ring-inset); }
.ds-switcher__item-sub { display: block; font: var(--type-caption); color: var(--color-text-secondary); }
.ds-switcher__check { margin-inline-start: auto; color: var(--color-tint); visibility: hidden; }
.ds-switcher__item[aria-current="true"] .ds-switcher__check { visibility: visible; }

/* ---------- 15. Toolbar (v4 top bar with the h1) · 36px controls row · breadcrumb ---------- */
.ds-toolbar { position: sticky; top: 0; z-index: var(--z-bar); color: var(--color-text); display: flex; align-items: center; gap: 10px; min-height: 56px; padding: var(--space-2) var(--edge);
  background: var(--color-bg); box-shadow: inset 0 -1px 0 var(--color-separator); transition: background-color var(--dur-micro-in) linear; }
.ds-toolbar__title { font: var(--type-title3); font-weight: 700; margin: 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-block: 1px; }
:lang(en) .ds-toolbar__title { letter-spacing: var(--track-title); }
.ds-toolbar__sub { font: var(--type-footnote); color: var(--color-text-secondary); margin-inline-start: 6px; white-space: nowrap; }
@media (min-width: 768px) { .ds-toolbar { min-height: 60px; padding: 0 24px 0 32px; } }
.ds-toolbar__actions { display: flex; align-items: center; gap: var(--space-2); margin-inline-start: auto; }
.ds-toolbar.is-scrolled { box-shadow: inset 0 -1px 0 var(--color-separator); }
/* glass: no hairline at rest, a quiet backdrop + hairline once content scrolls under it (DS.scrollEdge) */
.ds-toolbar--glass { background: transparent; box-shadow: none; }
.ds-toolbar--glass.is-scrolled { background: var(--glass-bg); -webkit-backdrop-filter: var(--glass-filter); backdrop-filter: var(--glass-filter); box-shadow: inset 0 -1px 0 var(--color-separator); }
.ds-toolbar--float { position: sticky; top: var(--space-3); margin: 0 var(--space-3); padding: 0 var(--space-2) 0 var(--space-4); border-radius: var(--radius-group);
  background: var(--glass-bg); -webkit-backdrop-filter: var(--glass-filter); backdrop-filter: var(--glass-filter); box-shadow: var(--glass-rim); }
/* the 36px controls family (v4): search, segmented, buttons, bell on one line */
.ds-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.ds-controls > .ds-search { flex: 1 1 240px; max-width: 320px; }
.ds-breadcrumb { display: flex; flex-wrap: wrap; gap: var(--space-1); align-items: center; font: var(--type-footnote); color: var(--color-text-secondary); list-style: none; margin: 0; padding: 0; }
.ds-breadcrumb a { position: relative; display: inline-flex; align-items: center; justify-content: center; min-height: 32px; min-width: 32px; padding: 0 var(--space-1);
  color: var(--color-tint); text-decoration: none; border-radius: var(--radius-xs); -webkit-tap-highlight-color: transparent;
  transition: color var(--dur-micro-out) linear, background-color var(--dur-micro-out) linear; }
.ds-breadcrumb a::before { content: ""; position: absolute; inset: min(0px, calc((32px - var(--hit)) / 2)); }
@media (hover: hover) { .ds-breadcrumb a:hover { color: var(--color-tint-hover); text-decoration: underline; text-underline-offset: 3px; } }
.ds-breadcrumb a.is-hover { color: var(--color-tint-hover); text-decoration: underline; text-underline-offset: 3px; }
.ds-breadcrumb a:active, .ds-breadcrumb a.is-pressed { color: var(--color-tint-pressed); background: var(--color-fill); }
.ds-breadcrumb a:focus-visible, .ds-breadcrumb a.is-focus { outline: 2px solid transparent; box-shadow: var(--focus-ring); }

/* ---------- 15b. Date-range picker (v4 custom range; DS.datepicker) ---------- */
.ds-datepicker { --_cell: var(--hit); display: inline-block; padding: var(--space-4); border-radius: var(--radius-card); background: var(--color-surface-elevated); color: var(--color-text); box-shadow: var(--elev-3); }
/* (2026-10-26) tip ชี้กลางปุ่มที่เปิด (DS.datepicker(...).tip(button) · กติกา popover Aus 10-25) — สี่เหลี่ยม 13px หมุน 45° สีเดียวกับกล่อง */
.ds-datepicker--tip { --ds-tip-x: 24px; position: relative; }   /* --ds-tip-x: ตั้งจาก JS (inline) ตามปุ่มที่เปิด */
.ds-datepicker--tip::before { content: ""; position: absolute; left: calc(var(--ds-tip-x) - 6.5px); width: 13px; height: 13px; transform: rotate(45deg);
  background: inherit; border: 0 solid var(--color-separator); pointer-events: none; }
.ds-datepicker--tip[data-tip="up"]::before { top: -7px; border-left-width: 1px; border-top-width: 1px; border-radius: 3px 0 0 0; }
.ds-datepicker--tip[data-tip="down"]::before { bottom: -7px; border-right-width: 1px; border-bottom-width: 1px; border-radius: 0 0 3px 0; }
.ds-datepicker__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); margin-bottom: var(--space-2); }
.ds-datepicker__title { font: var(--type-headline); font-size: 15px; margin: 0; }
.ds-datepicker__grid { display: grid; grid-template-columns: repeat(7, var(--_cell)); row-gap: 2px; text-align: center; font: var(--type-footnote); font-variant-numeric: tabular-nums; }
.ds-datepicker__wd { font: var(--type-caption); font-weight: 500; color: var(--color-text-tertiary); line-height: 24px; }
.ds-datepicker__day { appearance: none; border: 0; margin: 0; padding: 0; width: var(--_cell); height: var(--_cell); border-radius: 50%; background: transparent; color: var(--color-text);
  font: inherit; cursor: pointer; transition: background-color var(--dur-micro-out) linear; }
@media (hover: hover) { .ds-datepicker__day:hover:not(:disabled):not(.is-start):not(.is-end) { background: var(--color-fill); } }
.ds-datepicker__day:active:not(:disabled) { background: var(--color-fill-hover); }
.ds-datepicker__day:focus-visible { outline: 2px solid transparent; box-shadow: var(--focus-ring-inset); }
.ds-datepicker__day.is-today { font-weight: 700; }
.ds-datepicker__day.is-in { background: var(--color-tint-soft); color: var(--color-tint); border-radius: 0; }
.ds-datepicker__day.is-start, .ds-datepicker__day.is-end { background: var(--color-tint-fill); color: var(--color-on-tint); font-weight: 600; }
.ds-datepicker__day.is-start { border-radius: 50% 0 0 50%; }
.ds-datepicker__day.is-end { border-radius: 0 50% 50% 0; }
.ds-datepicker__day.is-start.is-end { border-radius: 50%; }
.ds-datepicker__day:disabled { color: var(--color-text-tertiary); opacity: 0.6; cursor: default; }
.ds-datepicker__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-top: var(--space-3); padding-top: var(--space-3);
  box-shadow: inset 0 1px 0 var(--color-separator); font: var(--type-caption); color: var(--color-text-secondary); }

/* ---------- 16. Empty / error state · skeleton ---------- */
.ds-empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--space-2); padding: var(--space-10) var(--space-5); max-width: 420px; margin: 0 auto; }
.ds-empty__art { width: 72px; height: 72px; border-radius: 50%; display: grid; place-items: center; background: var(--color-fill); color: var(--color-text-secondary); margin-bottom: var(--space-2); }
.ds-empty__art .ds-icon { width: 36px; height: 36px; }
.ds-empty--error .ds-empty__art { background: var(--color-warning-soft); color: var(--color-warning); }
.ds-empty--success .ds-empty__art { background: var(--color-success-soft); color: var(--color-success); }
.ds-empty__title { font: var(--type-headline); margin: 0; }
.ds-empty__text { font: var(--type-subhead); color: var(--color-text-secondary); margin: 0; }
.ds-empty__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: center; margin-top: var(--space-3); }
/* skeleton: the only looping animation in the system (loading indicator) */
.ds-skel { position: relative; overflow: hidden; display: block; background: var(--color-skeleton); border-radius: var(--radius-xs); }
.ds-skel::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--color-skeleton-shine), transparent); animation: ds-shimmer 1.4s ease-in-out infinite; }
.ds-skel--text { height: 12px; margin-block: 5px; width: var(--w, 100%); border-radius: var(--radius-pill); }
.ds-skel--title { height: 18px; margin-block: 4px; width: var(--w, 60%); border-radius: var(--radius-pill); }
.ds-skel--circle { width: var(--s, 36px); height: var(--s, 36px); border-radius: 50%; flex: none; }
.ds-skel--block { height: var(--h, 96px); border-radius: var(--radius-card); }

/* ---------- 17. Motion helpers (motion.js) ---------- */
/* rolling digits: each digit is a 0-9 strip; tabular figures keep the width stable */
.ds-roll { display: inline-flex; align-items: baseline; white-space: nowrap; font-variant-numeric: tabular-nums; }
.ds-roll__d { display: inline-block; height: 1.3em; line-height: 1.3em; overflow: hidden; vertical-align: bottom; }
.ds-roll__s { display: flex; flex-direction: column; transform: translateY(calc(var(--d, 0) * -1.3em));
  transition: transform var(--dur-roll) var(--ease-spring); transition-delay: min(calc(var(--k, 0) * var(--roll-stagger)), var(--roll-stagger-max)); }
.ds-roll__s > span { display: block; height: 1.3em; line-height: 1.3em; text-align: center; }
.ds-roll__x { display: inline-block; line-height: 1.3em; }
/* the reels are decoration: copy and screen readers get the real value from the hidden text */
.ds-roll__d, .ds-roll__x { -webkit-user-select: none; user-select: none; }
/* reply entrance: the composer / reply panel rises from where the Reply button was */
.ds-reply-enter { animation: ds-rise var(--dur-enter) var(--ease-spring) both; transform-origin: 50% 100%; }
/* list entrance ("rise & settle"): --stagger 20ms, max 8 items (7 x 20 + 354 = 494ms <= 500), item 9 and later appear in place */
.ds-stagger > * { animation: ds-rise var(--dur-enter) var(--ease-spring) both; animation-delay: calc(var(--i, 0) * var(--stagger)); }
.ds-stagger > :nth-child(n+9) { animation: none; }
.ds-stagger > :nth-child(1) { --i: 0; } .ds-stagger > :nth-child(2) { --i: 1; } .ds-stagger > :nth-child(3) { --i: 2; } .ds-stagger > :nth-child(4) { --i: 3; }
.ds-stagger > :nth-child(5) { --i: 4; } .ds-stagger > :nth-child(6) { --i: 5; } .ds-stagger > :nth-child(7) { --i: 6; } .ds-stagger > :nth-child(8) { --i: 7; }
/* Origin (MOTION_V2 "arrives from where it came from"). DS.land() adds these classes, so without JS nothing is hidden.
   Max 6 beats, --origin-stagger 28ms: 5 x 28 + 360 = 500ms. Item 7 and later get .ds-land--now (no motion). */
.ds-land { opacity: 0; transform: translate(var(--_ox, 0px), var(--_oy, 0px)) scale(var(--land-scale)); transform-origin: var(--_oo, 50% 100%); }
.ds-land.is-in { opacity: 1; transform: none; transition: transform var(--dur-land) var(--ease-land), opacity calc(var(--dur-land) * 0.4) linear;
  transition-delay: calc(min(var(--i, 0), 5) * var(--origin-stagger)); }
.ds-land.ds-land--now { transition: none; }
.ds-from-customer { --_ox: calc(-1 * var(--land-shift) * var(--motion-shift)); --_oo: 0% 100%; }
.ds-from-composer { --_oy: calc(var(--land-shift) * var(--motion-shift)); --_oo: 100% 100%; }
.ds-from-top { --_oy: calc(-8px * var(--motion-shift)); --_oo: 50% 0%; }
.ds-along-line { --_ox: calc(-1 * var(--land-shift) * var(--motion-shift)); --_oo: 0% 50%; }
/* the one "delivered" beat at the end of a sequence (tick, dot) */
.ds-delivered { animation: ds-pop var(--dur-parcel) var(--ease-parcel); }

/* pull to refresh (DS.ptr): the list follows the finger at 0.5x, the ring spins only while loading */
.ds-ptr { position: relative; overflow-y: auto; overscroll-behavior-y: contain; }
.ds-ptr__ring { position: absolute; top: var(--space-3); left: 50%; z-index: 2; width: 28px; height: 28px; margin-left: -14px; border-radius: 50%; pointer-events: none;
  border: 2.5px solid var(--color-separator-strong); border-top-color: var(--color-tint); opacity: 0;
  transform: translateY(calc(var(--_pull, 0px) * 0.5 - 40px)) rotate(var(--_turn, 0deg)); }
.ds-ptr__content { transform: translateY(var(--_pull, 0px)); }
.ds-ptr.is-pulling .ds-ptr__ring { opacity: 1; }
.ds-ptr.is-settling .ds-ptr__content, .ds-ptr.is-settling .ds-ptr__ring { transition: transform var(--dur-enter) var(--ease-spring), opacity var(--dur-micro-out) linear; }
.ds-ptr.is-loading .ds-ptr__ring { opacity: 1; transform: translateY(0); animation: ds-spin 0.8s linear infinite; }

/* ---------- 17b. Meter (v4 credit / channel bars): role="meter" + aria-valuenow/min/max, DS.meter() ---------- */
.ds-meter { --_fill: var(--chart-1); --_h: 8px; display: grid; gap: var(--space-2); align-content: start; min-width: 0; }
.ds-meter__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); font: var(--type-footnote); }
.ds-meter__label { color: var(--color-text-secondary); min-width: 0; }
.ds-meter__value { color: var(--color-text); font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: 0; white-space: nowrap; }
.ds-meter__track { position: relative; overflow: hidden; height: var(--_h); border-radius: var(--radius-pill); background: var(--chart-track); }
.ds-meter__bar { position: absolute; inset: 0; border-radius: inherit; background: var(--_fill); transform-origin: 0 50%;
  transform: scaleX(clamp(0, var(--ds-meter, 0), 1)); transition: transform var(--dur-enter) var(--ease-spring); }
.ds-meter--sm { --_h: 6px; } .ds-meter--lg { --_h: 10px; }
.ds-meter--success { --_fill: var(--color-success); }
.ds-meter--warning { --_fill: var(--color-warning); }
.ds-meter--danger { --_fill: var(--color-danger); }
.ds-meter--neutral { --_fill: var(--color-text-secondary); }

/* ---------- 17c. Chart (charts.js: DS.chart / [data-ds-chart]): sparkline, bars, line + area · v4 blue bars ---------- */
.ds-chart { position: relative; display: block; min-width: 0; color: var(--color-text); font: var(--type-caption); font-variant-numeric: tabular-nums; border-radius: var(--radius-sm); }
.ds-chart:focus-visible { outline: 2px solid transparent; box-shadow: var(--focus-ring); }
.ds-chart > svg { display: block; width: 100%; overflow: visible; }
.ds-chart__grid { stroke: var(--chart-grid); stroke-width: 1; shape-rendering: crispEdges; }
.ds-chart__tick { fill: var(--color-text-tertiary); font: var(--type-caption); font-variant-numeric: tabular-nums; }
.ds-chart__line { fill: none; stroke: var(--chart-1); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.ds-chart__area { fill: var(--chart-area); stroke: none; }
.ds-chart__bar { fill: var(--chart-bar); }
.ds-chart__bar.is-end, .ds-chart__bar.is-active { fill: var(--chart-1); }
.ds-chart__bar.is-active { opacity: 0.85; }
.ds-chart__dot { fill: var(--chart-1); stroke: var(--color-surface); stroke-width: 2; }
.ds-chart__cross { stroke: var(--color-separator-strong); stroke-width: 1; stroke-dasharray: 2 3; shape-rendering: crispEdges; }
.ds-chart__hover { opacity: 0; transition: opacity var(--dur-micro-out) linear; }
.ds-chart.is-tip .ds-chart__hover { opacity: 1; }
/* the data arrives once: series rise and settle (reduced motion: --motion-shift 0 = fade only) */
.ds-chart__series { animation: ds-rise var(--dur-enter) var(--ease-spring) both; }
.ds-chart__tip { position: absolute; top: 0; left: 0; z-index: 2; pointer-events: none; padding: 2px var(--space-2); border-radius: var(--radius-xs);
  background: var(--color-toast); color: var(--color-on-toast); font: var(--type-caption); font-variant-numeric: tabular-nums; white-space: nowrap;
  transform: translate(calc(var(--_x, 0px) - 50%), calc(var(--_y, 0px) - 100% - 8px)); opacity: 0; transition: opacity var(--dur-micro-out) linear; }
.ds-chart.is-tip .ds-chart__tip { opacity: 1; }

/* ---------- 18. Danger zone (destructive settings live apart, always behind a confirmation) ---------- */
.ds-danger-zone { border-radius: var(--radius-group); background: var(--color-surface); box-shadow: var(--elev-1), inset 0 0 0 1px color-mix(in srgb, var(--color-danger) 35%, transparent); overflow: hidden; }
.ds-danger-zone__title { font: var(--type-headline); color: var(--color-danger); padding: var(--space-4) var(--space-4) var(--space-1); margin: 0; display: flex; gap: var(--space-2); align-items: center; }
.ds-danger-zone .ds-row { flex-wrap: wrap; }

/* ---------- 19. Continuous corners: native superellipse only, surfaces only (ADR-001 §5) ---------- */
@supports (corner-shape: superellipse(2)) {
  .ds-card:not(.ds-card--repeat), .ds-kpi:not(.ds-card--repeat), .ds-modal, .ds-sheet, .ds-drawer, .ds-datepicker, .ds-menu, .ds-switcher__list, .ds-icon-tile,
  .ds-input, .ds-select, .ds-textarea, .ds-input-group, .ds-table-wrap, .ds-list:not(.ds-list--plain), .ds-danger-zone { corner-shape: superellipse(2); }
}

/* ---------- 20. Keyframes ---------- */
@keyframes ds-spin { to { transform: rotate(360deg); } }
@keyframes ds-shimmer { to { transform: translateX(100%); } }
@keyframes ds-fade-in { from { opacity: 0; } }
@keyframes ds-fade-out { to { opacity: 0; } }
@keyframes ds-modal-in { from { opacity: 0; transform: scale(calc(1 - 0.06 * var(--motion-shift))); } }
@keyframes ds-modal-out { to { opacity: 0; transform: scale(calc(1 - 0.04 * var(--motion-shift))); } }
@keyframes ds-sheet-in { from { transform: translateY(calc(110% * var(--motion-shift))); opacity: 0; } }
@keyframes ds-sheet-out { to { transform: translateY(calc(var(--_drag, 0px) + 110% * var(--motion-shift))); opacity: 0; } }
@keyframes ds-drawer-in { from { transform: translateX(calc(100% * var(--motion-shift))); opacity: 0; } }
@keyframes ds-drawer-out { to { transform: translateX(calc(100% * var(--motion-shift))); opacity: 0; } }
@keyframes ds-drawer-in-left { from { transform: translateX(calc(-100% * var(--motion-shift))); opacity: 0; } }
@keyframes ds-drawer-out-left { to { transform: translateX(calc(-100% * var(--motion-shift))); opacity: 0; } }
@keyframes ds-pop { from { transform: scale(calc(1 - 0.4 * var(--motion-shift))); opacity: calc(1 - 0.6 * var(--motion-shift)); } }
@keyframes ds-rise { from { opacity: 0; transform: translateY(calc(12px * var(--motion-shift))) scale(calc(1 - 0.02 * var(--motion-shift))); } }

/* ---------- 21. Reduced motion: no travel, no shimmer; loading spinners slow down but stay ---------- */
@media (prefers-reduced-motion: reduce) {
  .ds-skel::after { animation: none; opacity: 0; }
  .ds-btn[aria-busy="true"]::after, .ds-ptr.is-loading .ds-ptr__ring { animation-duration: 2.4s; }
  .ds-roll__s { transition: none; }
  .ds-meter__bar { transition: none; }
}
:root.ds-rm .ds-skel::after { animation: none; opacity: 0; }
:root.ds-rm .ds-btn[aria-busy="true"]::after, :root.ds-rm .ds-ptr.is-loading .ds-ptr__ring { animation-duration: 2.4s; }
:root.ds-rm .ds-roll__s { transition: none; }
:root.ds-rm .ds-meter__bar { transition: none; }

/* forced colours (Windows High Contrast): keep edges and focus visible */
@media (forced-colors: active) {
  .ds-btn, .ds-fchip, .ds-input, .ds-select, .ds-textarea, .ds-input-group, .ds-search, .ds-card, .ds-toast, .ds-tabbar, .ds-check, .ds-radio, .ds-switch, .ds-icon-tile, .ds-datepicker { border: 1px solid CanvasText; }
  .ds-navitem[aria-current="page"], .ds-tabbar__item[aria-current="page"], .ds-rail__item[aria-current="page"], .ds-datepicker__day.is-start, .ds-datepicker__day.is-end { outline: 2px solid Highlight; }
}
