/* ═══════════════════════════════════════════════════
   JACQUARD DESIGN SYSTEM — Web Kit Components
   Version 2.1 · April 2026
   Every value references a token from tokens.css. No hex,
   no arbitrary px, no arbitrary durations or easings.
   ═══════════════════════════════════════════════════ */

/* ── Eyebrow / Section / Numeric primitives ── */
.j-eyebrow {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--type-nano);
  letter-spacing: var(--track-label-loose);
  text-transform: uppercase;
  color: var(--fg-3);
}

.j-eyebrow-kicker {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: var(--type-nano);
  letter-spacing: var(--track-compact);
  text-transform: uppercase;
  color: var(--fg-brand);
}

.j-display-num {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--type-title);
  line-height: var(--lh-tight);
  letter-spacing: var(--track-display);
  color: var(--fg-1);
  font-feature-settings: 'tnum' 1;
}

.j-section-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-md);
  margin-bottom: var(--sp-md);
}

.j-section-header > .j-section-header-main > .j-eyebrow-kicker {
  margin-bottom: var(--sp-xs);
}

/* ── Buttons ──────────────────────────────────────── */
.j-btn {
  font-family: var(--font-body);
  font-weight: 500;
  letter-spacing: var(--track-compact);
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-xs);
  cursor: pointer;
  border: var(--bw-hairline) solid transparent;
  transition:
    background var(--dur-pop) var(--ease-snap),
    color var(--dur-pop) var(--ease-snap),
    border-color var(--dur-pop) var(--ease-snap),
    transform var(--dur-micro) var(--ease-snap);
}

.j-btn:disabled {
  cursor: not-allowed;
  opacity: var(--op-dimmed);
}

/* Tap feedback — scale down briefly on press. The transform transition is
   already registered on .j-btn; this just declares the target state. */
.j-btn:not(:disabled):active {
  transform: scale(0.97);
}

.j-btn:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* Sizes — every variant meets at least --touch-compact (32px) so even the
   "extra-small" button stays tappable. xs/sm are intended for inline /
   compact contexts (filter chips, table actions). */
.j-btn-xs { padding: var(--sp-xs) var(--sp-sm-p); font-size: var(--type-label); border-radius: var(--r-compact); min-height: var(--touch-compact); }
.j-btn-sm { padding: var(--sp-xs) var(--sp-sm-p); font-size: var(--type-caption); border-radius: var(--r-image);   min-height: var(--touch-compact); }
.j-btn-md { padding: var(--sp-sm) var(--sp-md);   font-size: var(--type-small);   border-radius: var(--r-control); min-height: var(--sp-2xl); }
.j-btn-lg { padding: var(--sp-sm-p) var(--sp-lg); font-size: var(--type-compact-body); border-radius: var(--r-button); min-height: var(--touch-min); }

.j-btn-primary { background: var(--encre); color: var(--blanc); border-color: var(--encre); }
.j-btn-primary:hover:not(:disabled) { background: var(--fumee); border-color: var(--fumee); }

.j-btn-secondary { background: var(--craie); color: var(--encre); }
.j-btn-secondary:hover:not(:disabled) { background: var(--pierre); }

.j-btn-ghost { background: transparent; color: var(--encre); border-color: var(--pierre); }
.j-btn-ghost:hover:not(:disabled) { background: var(--craie); }

.j-btn-glycine { background: var(--glycine-pale); color: var(--glycine-deep); }
.j-btn-glycine:hover:not(:disabled) { background: var(--glycine); color: var(--blanc); }

.j-btn-destructive { background: var(--rose-sakura-deep); color: var(--blanc); }
.j-btn-destructive:hover:not(:disabled) {
  /* Token-only hover: composite a dimming wash of --encre over the rose
     base so we don't need a one-off filter or a magic brightness number. */
  background:
    linear-gradient(
      color-mix(in srgb, var(--encre) calc(var(--op-wash) * 100%), transparent),
      color-mix(in srgb, var(--encre) calc(var(--op-wash) * 100%), transparent)
    ),
    var(--rose-sakura-deep);
}

.j-btn-link { background: transparent; color: var(--glycine-deep); }
.j-btn-link:hover:not(:disabled) { text-decoration: underline; }

/* Compact square icon button used for nav arrows, modal close, etc. */
.j-icon-btn {
  width: var(--touch-min); height: var(--touch-min);
  border-radius: var(--r-image);
  background: transparent;
  border: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--fumee);
  transition:
    background var(--dur-pop) var(--ease-snap),
    color var(--dur-pop) var(--ease-snap),
    transform var(--dur-micro) var(--ease-snap);
}

.j-icon-btn:hover:not(:disabled) { background: var(--craie); color: var(--encre); }
.j-icon-btn:not(:disabled):active { transform: scale(0.93); }

.j-icon-btn:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.j-icon-btn-sm { width: var(--sp-xl); height: var(--sp-xl); border-radius: var(--r-image); }
.j-icon-btn-round { border-radius: var(--r-pill); }

/* ── Badge ────────────────────────────────────────── */
.j-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
  border-radius: var(--r-pill);
  font-family: var(--font-body);
  font-weight: 600;
  line-height: var(--lh-heading);
  white-space: nowrap;
  letter-spacing: var(--track-compact);
}

.j-badge-sm { padding: var(--r-micro) var(--sp-sm); font-size: var(--type-micro); }
.j-badge-md { padding: var(--r-tiny) var(--sp-sm-p); font-size: var(--type-label); }

.j-badge-dot {
  width: var(--sp-xs); height: var(--sp-xs);
  border-radius: var(--r-pill);
  display: inline-block;
}

.j-badge-glycine { background: var(--glycine-pale); color: var(--glycine-deep); }
.j-badge-glycine .j-badge-dot { background: var(--glycine); }
.j-badge-vert { background: var(--vert-menthe-pale); color: var(--vert-menthe-deep); }
.j-badge-vert .j-badge-dot { background: var(--vert-menthe); }
.j-badge-rose { background: var(--rose-sakura-pale); color: var(--rose-sakura-deep); }
.j-badge-rose .j-badge-dot { background: var(--rose-sakura); }
.j-badge-jaune { background: var(--jaune-poussin-pale); color: var(--jaune-poussin-deep); }
.j-badge-jaune .j-badge-dot { background: var(--jaune-poussin); }
.j-badge-bleu { background: var(--bleu-ciel-pale); color: var(--bleu-ciel-deep); }
.j-badge-bleu .j-badge-dot { background: var(--bleu-ciel); }
.j-badge-neutral { background: var(--craie); color: var(--fumee); }
.j-badge-neutral .j-badge-dot { background: var(--gris); }

/* ── Card ─────────────────────────────────────────── */
.j-card {
  background: var(--surface-0);
  border-radius: var(--r-card);
  padding: var(--sp-lg);
  border: var(--bw-hairline) solid transparent;
  box-shadow: var(--shadow-rest);
  transition:
    transform var(--dur-snap) var(--ease-snap),
    box-shadow var(--dur-snap) var(--ease-snap),
    border-color var(--dur-snap) var(--ease-snap);
}

.j-card-interactive { cursor: pointer; }
.j-card-interactive:hover {
  border-color: var(--pierre);
  box-shadow: var(--shadow-floating);
  transform: translateY(calc(-1 * var(--bw-selection)));
}

/* ── Input / Select / Textarea ────────────────────── */
.j-field {
  display: flex;
  align-items: center;
  gap: var(--sp-xs);
  background: var(--surface-0);
  border: var(--bw-standard) solid var(--pierre);
  border-radius: var(--r-control);
  padding: var(--sp-xs) var(--sp-sm-p);
  transition: border-color var(--dur-pop) var(--ease-snap);
  font-family: var(--font-body);
}

.j-field:focus-within { border-color: var(--encre); }

/* Keyboard-only focus ring: only paint the ring when the focused descendant
   was focused via keyboard (`:focus-visible`). Mouse clicks keep the quieter
   border-only treatment. Requires `:has()` (Chrome 105+, Safari 15.4+,
   Firefox 121+). */
.j-field:focus-within:has(:focus-visible) {
  box-shadow: var(--focus-ring);
}

.j-field[data-disabled="true"],
.j-field.is-disabled { background: var(--craie); cursor: not-allowed; }

.j-field-prefix,
.j-field-suffix {
  color: var(--fg-2);
  font-size: var(--type-small);
  font-family: var(--font-body);
  display: inline-flex;
  align-items: center;
}

.j-input,
.j-textarea,
.j-select {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--type-small);
  color: var(--fg-1);
  padding: 0;
  width: 100%;
}

.j-input::placeholder,
.j-textarea::placeholder { color: var(--fg-3); }

.j-textarea {
  resize: vertical;
  line-height: var(--lh-caption);
  min-height: var(--sp-4xl);
  padding: var(--sp-sm) 0;
}

/* Standalone select (no wrapper field) */
.j-select-standalone {
  font-family: var(--font-body);
  font-size: var(--type-small);
  color: var(--fg-1);
  background: var(--surface-0);
  border: var(--bw-standard) solid var(--pierre);
  border-radius: var(--r-control);
  padding: var(--sp-xs) var(--sp-sm-p);
  outline: none;
  cursor: pointer;
  width: 100%;
  min-height: var(--touch-min);
}

.j-select-standalone:focus { border-color: var(--encre); }
.j-select-standalone:focus-visible {
  outline: none;
  border-color: var(--encre);
  box-shadow: var(--focus-ring);
}

/* ── Checkbox ─────────────────────────────────────── */
.j-checkbox-label {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-sm);
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--type-small);
  color: var(--fg-1);
}

.j-checkbox-box {
  width: var(--checkbox-sz);
  height: var(--checkbox-sz);
  border-radius: var(--r-checkbox);
  border: var(--bw-standard) solid var(--pierre);
  background: var(--surface-0);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background var(--dur-pop) var(--ease-snap), border-color var(--dur-pop) var(--ease-snap);
}

.j-checkbox-label input:checked ~ .j-checkbox-box,
.j-checkbox-box[data-checked="true"] {
  background: var(--encre);
  border-color: var(--encre);
}

/* The native input is visually hidden but still receives focus for keyboard
   users. Surface that focus state on the styled box via :focus-visible so
   we don't trip the ring on mouse clicks. */
.j-checkbox-label input {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}

.j-checkbox-label input:focus-visible ~ .j-checkbox-box {
  box-shadow: var(--focus-ring);
}

/* ── Modal ────────────────────────────────────────── */
@keyframes j-fade { from { opacity: 0 } to { opacity: 1 } }
@keyframes j-pop {
  from { opacity: 0; transform: translateY(calc(-1 * var(--sp-xs))) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.j-modal-overlay {
  position: fixed; inset: 0;
  background: color-mix(in srgb, var(--encre) calc(var(--op-scrim) * 100%), transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 200;
  padding: var(--sp-lg);
  animation: j-fade var(--dur-pop) var(--ease-out);
}

.j-modal-sheet {
  background: var(--surface-0);
  border-radius: var(--r-sheet);
  width: 100%;
  max-width: var(--max-modal-width);
  max-height: calc(100vh - var(--sp-3xl));
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-modal);
  animation: j-pop var(--dur-snap) var(--ease-snap);
}

.j-modal-header {
  padding: var(--sp-lg) var(--sp-xl) var(--sp-md);
  border-bottom: var(--bw-hairline) solid var(--craie);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-md);
}

.j-modal-body {
  /* Explicit overflow-y so long content always scrolls inside the
     sheet. `min-height: 0` is required for a flex child with
     overflow — without it, a very tall body would force the sheet
     past its max-height and clip against .j-modal-sheet's
     `overflow: hidden`. `overscroll-behavior: contain` prevents
     scroll-chaining into the page behind the modal. */
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  flex: 1;
  overscroll-behavior: contain;
}

.j-modal-close {
  flex-shrink: 0;
  width: var(--sp-xl);
  height: var(--sp-xl);
  border-radius: var(--r-pill);
  border: none;
  background: var(--craie);
  color: var(--fumee);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--dur-pop) var(--ease-snap);
}

.j-modal-close:hover { background: var(--pierre); color: var(--encre); }
.j-modal-close:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* ── Divider ──────────────────────────────────────── */
.j-divider {
  height: var(--bw-hairline);
  background: var(--rule);
  width: 100%;
  border: none;
}

/* ── Progress ─────────────────────────────────────── */
.j-progress {
  position: relative;
  width: 100%;
  border-radius: var(--r-pill);
  overflow: hidden;
  height: var(--sp-sm);
}

.j-progress-fill {
  height: 100%;
  border-radius: var(--r-pill);
  transition: width var(--dur-snap) var(--ease-snap);
}

.j-progress-marker {
  position: absolute;
  top: calc(-1 * var(--r-micro));
  width: var(--r-micro);
  background: var(--encre);
  transform: translateX(-50%);
}

.j-progress-glycine { background: var(--glycine-pale); }
.j-progress-glycine > .j-progress-fill { background: var(--glycine); }
.j-progress-vert    { background: var(--vert-menthe-pale); }
.j-progress-vert    > .j-progress-fill { background: var(--vert-menthe); }
.j-progress-rose    { background: var(--rose-sakura-pale); }
.j-progress-rose    > .j-progress-fill { background: var(--rose-sakura); }
.j-progress-jaune   { background: var(--jaune-poussin-pale); }
.j-progress-jaune   > .j-progress-fill { background: var(--jaune-poussin); }
.j-progress-bleu    { background: var(--bleu-ciel-pale); }
.j-progress-bleu    > .j-progress-fill { background: var(--bleu-ciel); }

/* Overflow state: fill flips to success when value > max */
.j-progress-fill[data-overflow="true"] { background: var(--vert-menthe) !important; }

/* ── Thumb ────────────────────────────────────────── */
.j-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--pierre), var(--craie));
  color: var(--fumee);
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: var(--track-heading);
  text-transform: uppercase;
  border-radius: var(--r-image);
  box-shadow: var(--shadow-thumb);
}

.j-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.j-thumb[data-image-mode="cutout"] img { object-fit: contain; }

.j-thumb-glycine { background: var(--glycine-pale); color: var(--glycine-deep); }
.j-thumb-vert    { background: var(--vert-menthe-pale); color: var(--vert-menthe-deep); }
.j-thumb-rose    { background: var(--rose-sakura-pale); color: var(--rose-sakura-deep); }
.j-thumb-jaune   { background: var(--jaune-poussin-pale); color: var(--jaune-poussin-deep); }
.j-thumb-bleu    { background: var(--bleu-ciel-pale); color: var(--bleu-ciel-deep); }

/* ── Data row (grid-based tables) ─────────────────── */
.j-table-header {
  display: grid;
  gap: var(--sp-sm-p);
  padding: var(--sp-sm) var(--sp-md);
  align-items: center;
  border-bottom: var(--bw-hairline) solid var(--craie);
}

.j-table-cell-label {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--type-micro);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--fg-3);
  user-select: none;
}

.j-table-cell-sort { margin-left: var(--sp-xs); color: var(--fg-1); }

.j-table-row {
  display: grid;
  gap: var(--sp-sm-p);
  padding: 0 var(--sp-md);
  min-height: var(--touch-min);
  align-items: center;
  border-bottom: var(--bw-hairline) solid var(--craie);
  transition: background var(--dur-pop) var(--ease-snap);
}

.j-table-row[data-clickable="true"] { cursor: pointer; }
.j-table-row[data-clickable="true"]:hover { background: var(--craie); }
.j-table-row[data-dim="true"] { opacity: var(--op-dimmed); }

/* ── Empty state ──────────────────────────────────── */
.j-empty {
  padding: var(--sp-4xl) var(--sp-lg);
  text-align: center;
  color: var(--fg-2);
  font-family: var(--font-body);
}

.j-empty-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--type-compact);
  color: var(--fg-1);
  margin-bottom: var(--sp-xs);
  letter-spacing: var(--track-compact);
}

.j-empty-hint {
  font-size: var(--type-small);
  color: var(--fg-2);
  line-height: var(--lh-compact-body);
}

/* ── Form field / Stat cell ───────────────────────── */
.j-form-field { display: flex; flex-direction: column; gap: var(--sp-xs); }
.j-form-field-label { /* alias .j-eyebrow used inline */ }

.j-stat-cell { display: flex; flex-direction: column; gap: var(--sp-xs); }
.j-stat-cell-value {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--type-compact-body);
  color: var(--fg-1);
}
.j-stat-cell-value-mono {
  font-family: var(--font-mono);
  font-size: var(--type-small);
}

/* ── ID tag ──────────────────────────────────────── */
.j-id-tag {
  /* Reset the UA button styling since kit.jsx now renders IdTag as a
     <button> for keyboard accessibility. Every visual comes from the
     rules below; border / font inheritance come from the reset. */
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--type-micro);
  color: var(--fg-3);
  padding: 0 var(--sp-xs);
  border: none;
  border-radius: var(--r-tiny);
  background: transparent;
  cursor: pointer;
  user-select: none;
  letter-spacing: var(--track-compact);
  transition: color var(--dur-pop) var(--ease-snap), background var(--dur-pop) var(--ease-snap);
  min-height: var(--sp-md);
}

.j-id-tag[data-copied="true"] {
  color: var(--vert-menthe-deep);
  background: var(--vert-menthe-pale);
}

.j-id-tag:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* ── Segmented Control / Toggle Pill ─────────────── */
.j-segmented {
  display: inline-flex;
  gap: var(--sp-xs);
  padding: var(--sp-xs);
  background: var(--craie);
  border-radius: var(--r-pill);
}

.j-segmented-option {
  font-family: var(--font-body);
  font-size: var(--type-caption);
  /* Hold font-weight stable across inactive + active states. Browsers
     don't interpolate weight smoothly, so animating it produces a pop;
     the active pill now earns its emphasis from the surface shift and
     ring, not a weight jump. */
  font-weight: 500;
  color: var(--fg-2);
  padding: var(--sp-xs) var(--sp-sm-p);
  border: none;
  background: transparent;
  border-radius: var(--r-pill);
  cursor: pointer;
  /* Explicit property list so width / layout never animates. The active
     pill slides in via box-shadow + background crossfade, same duration
     and easing as every other interactive surface. */
  transition:
    background var(--dur-pop) var(--ease-snap),
    color var(--dur-pop) var(--ease-snap),
    box-shadow var(--dur-pop) var(--ease-snap),
    transform var(--dur-micro) var(--ease-snap);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
  min-height: var(--sp-lg);
}

.j-segmented-option:hover { color: var(--fg-1); }
.j-segmented-option:not([disabled]):active { transform: scale(0.97); }

.j-segmented-option[data-active="true"] {
  background: var(--surface-0);
  color: var(--fg-1);
  box-shadow: var(--shadow-rest);
}

.j-segmented-option:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.j-segmented-option[data-active="true"]:focus-visible {
  box-shadow: var(--shadow-rest), var(--focus-ring);
}

/* ── Search input (preset) ───────────────────────── */
.j-search {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  background: var(--surface-0);
  border: var(--bw-standard) solid var(--pierre);
  border-radius: var(--r-control);
  padding: var(--sp-xs) var(--sp-sm-p);
  transition: border-color var(--dur-pop) var(--ease-snap);
}

.j-search:focus-within { border-color: var(--encre); }
.j-search:focus-within:has(:focus-visible) {
  box-shadow: var(--focus-ring);
}
.j-search > svg { color: var(--fg-2); flex-shrink: 0; }
.j-search input {
  flex: 1; min-width: 0; border: none; outline: none; background: transparent;
  font-family: var(--font-body); font-size: var(--type-small); color: var(--fg-1);
}

/* ── Toast ────────────────────────────────────────── */
.j-toast {
  position: fixed;
  left: 50%;
  bottom: var(--sp-xl);
  transform: translateX(-50%);
  z-index: 300;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-sm);
  background: var(--encre);
  color: var(--blanc);
  font-family: var(--font-body);
  font-size: var(--type-small);
  padding: var(--sp-sm) var(--sp-md);
  border-radius: var(--r-control);
  box-shadow: var(--shadow-floating);
  animation: j-pop var(--dur-snap) var(--ease-snap);
}

.j-toast-dot {
  width: var(--sp-xs);
  height: var(--sp-xs);
  border-radius: var(--r-pill);
  background: var(--vert-menthe);
}

.j-toast[data-tone="error"] .j-toast-dot { background: var(--rose-sakura); }
.j-toast[data-tone="warning"] .j-toast-dot { background: var(--jaune-poussin); }

/* ── Accordion / Collapsible ──────────────────────── */
.j-accordion-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
  background: transparent;
  border: none;
  color: var(--fg-3);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--type-micro);
  letter-spacing: var(--track-label-loose);
  text-transform: uppercase;
  cursor: pointer;
  padding: 0;
}

.j-accordion-chevron {
  transition: transform var(--dur-pop) var(--ease-snap);
}

.j-accordion-trigger[data-open="true"] > .j-accordion-chevron,
.j-accordion-trigger[aria-expanded="true"] > .j-accordion-chevron {
  transform: rotate(90deg);
}

.j-accordion-trigger:focus-visible {
  outline: none;
  border-radius: var(--r-tiny);
  box-shadow: var(--focus-ring);
}

/* ── Form grid utilities (responsive) ─────────────── */
.j-form-grid      { display: grid; gap: var(--sp-sm-p); }
.j-form-grid-2    { display: grid; gap: var(--sp-sm-p); grid-template-columns: repeat(2, minmax(0, 1fr)); }
.j-form-grid-3    { display: grid; gap: var(--sp-sm-p); grid-template-columns: repeat(3, minmax(0, 1fr)); }
.j-form-grid-4    { display: grid; gap: var(--sp-sm-p); grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Literal mirror of --bp-mobile (820px). CSS @media queries can't
   consume var() in their conditions, so the source of truth stays in
   tokens/primitive/dimension.json#bp.mobile and this condition is
   hand-mirrored. Update both when the breakpoint moves. */
@media (max-width: 820px) {
  .j-form-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .j-form-grid-2,
  .j-form-grid-3,
  .j-form-grid   { grid-template-columns: 1fr; }
  .j-modal-overlay { padding: 0; }
  .j-modal-sheet {
    width: 100%; max-width: 100%;
    max-height: 100vh; max-height: 100dvh;
    height: 100vh; height: 100dvh;
    border-radius: 0;
  }
  .j-modal-header { padding: var(--sp-sm-p) var(--sp-md) var(--sp-sm); }
}

/* ── Reduced motion respects ──────────────────────── */
/* Catch-all rule: anything that animates or transitions inside the kit
   collapses to a near-instant change AND drops the entrance transforms
   entirely — WCAG 2.3.3 (Animation from Interactions) considers
   translate/scale entrances as motion, not just duration. A reduce-
   motion user still gets the opacity fade (to signal the state change)
   but never the y-translate / scale pop. */
@media (prefers-reduced-motion: reduce) {
  [class^="j-"], [class*=" j-"],
  .j-modal-overlay, .j-modal-sheet,
  .j-progress-fill, .j-accordion-chevron {
    transition-duration: var(--dur-micro) !important;
    animation-duration: var(--dur-micro) !important;
    animation-iteration-count: 1 !important;
  }

  /* Drop all kit-originated transforms. Applies to the modal sheet's
     y-translate entrance, the pop keyframes (scale 0.98 → 1), and the
     segmented / btn tap-scale feedback. The !important is intentional
     and scoped to kit selectors so app-level transforms aren't affected. */
  .j-modal-sheet,
  .j-btn:not(:disabled):active,
  .j-icon-btn:not(:disabled):active,
  .j-segmented-option:not([disabled]):active,
  .j-comp-pop-animate {
    transform: none !important;
    animation-name: j-fade !important;
  }
}
