/* Components Basecoat lacks, and our customisations of Basecoat's, in the order of js/ui.js. Each block says what it
   changes from stock; the gallery (#/components) says why. Written against Basecoat's theme variables and ours
   (tokens.css). In @layer components, so Basecoat's utilities and our page CSS still override it. */
@layer components {

  /* ---------- icon ---------- */
  .lucide { width: 1rem; height: 1rem; flex: none; }
  .lucide.spin { animation: ui-spin 1s linear infinite; }
  @keyframes ui-spin { to { transform: rotate(360deg); } }
  @media (prefers-reduced-motion: reduce) { .lucide.spin { animation: none; } }

  /* ---------- button (customised: a pressed toggle reads as selected; short colour transitions) and the favourite star ---------- */
  .btn { transition-property: color, background-color, border-color, box-shadow; transition-duration: var(--duration-hover); transition-timing-function: var(--ease-out); }
  /* A primary button's hover is a deeper accent, not Basecoat's see-through one, which loses 4.5:1 for its text. */
  :is(.btn:not([data-variant]), .btn[data-variant="primary"]):hover { background-color: var(--primary-hover); }
  .btn[data-variant="destructive"] { color: var(--destructive-text); }
  .btn[aria-pressed="true"] { background-color: var(--selected); color: var(--link); border-color: var(--selected-border); }
  a.btn[aria-disabled="true"] { pointer-events: none; opacity: 0.5; }
  /* A button disabled with its reason on hover and focus (ui.card's empty sections): it keeps pointer events. */
  button.btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }
  /* The star reads as on by its filled amber icon, not by the pressed ground. */
  .star-toggle[aria-pressed="true"] { background-color: transparent; border-color: var(--border); }
  .star-toggle[data-variant="ghost"][aria-pressed="true"] { border-color: transparent; }
  .star-toggle[aria-pressed="true"] .lucide { color: var(--warning); fill: currentColor; }

  /* ---------- badge (customised: tones) and status badge ---------- */
  .badge[data-tone] { border: 1px solid transparent; }
  .badge[data-tone="success"] { background-color: var(--success-surface); color: var(--success); }
  .badge[data-tone="warning"] { background-color: var(--warning-surface); color: var(--warning); }
  .badge[data-tone="info"] { background-color: var(--info-surface); color: var(--info); }
  .badge[data-tone="danger"] { background-color: var(--destructive-surface); color: var(--destructive-text); }
  .badge[data-tone="neutral"] { background-color: var(--secondary); color: var(--secondary-foreground); }
  .badge .lucide { width: 0.75rem; height: 0.75rem; }
  .status-badge[data-status="cancelled"] { border-style: dashed; border-color: var(--border); }
  /* The common, settled status is quiet, a dot and muted text, so results draw the eye and Failed, Running and Queued
     stand out (DESIGN-AUDIT M5). */
  .status-badge[data-status="completed"] { background: none; border-color: transparent; color: var(--muted-foreground); padding-inline: 0; font-weight: 500; }
  .status-dot { width: 0.4375rem; height: 0.4375rem; border-radius: 9999px; background: var(--success); flex: none; }
  /* A status that has just changed comes in (ui.js marks it). */
  [data-entering] { animation: ui-enter var(--duration-status) var(--ease-out) both; }
  .row-marker { margin-inline-start: 0.375rem; vertical-align: 1px; }
  .badge-below { display: flex; width: fit-content; margin-top: 0.25rem; }

  /* ---------- avatar (customised: initials on a tinted ground, as mockup 02) ---------- */
  .avatar > span:not(.avatar-badge) { background-color: var(--selected); color: var(--link); font-size: var(--text-label); font-weight: 600; }

  /* ---------- progress (customised: indeterminate) ---------- */
  .progress[data-indeterminate] > span { width: 38%; animation: ui-progress 1.6s ease-in-out infinite; }
  @keyframes ui-progress { from { margin-inline-start: -38%; } to { margin-inline-start: 100%; } }
  @media (prefers-reduced-motion: reduce) { .progress[data-indeterminate] > span { animation: none; } }

  /* ---------- skeleton (presets) ---------- */
  .skeleton { border-radius: var(--radius-sm); }
  .skeleton[data-shape="round"] { border-radius: 9999px; }
  .skeleton-stack { display: grid; gap: 0.5rem; }
  .tile .skeleton-value { margin: 0.5rem 0; }
  .skeleton-table { display: grid; grid-template-columns: 3fr repeat(calc(var(--cols) - 1), 1fr); gap: 0.875rem 1rem; padding-block: 0.5rem; }
  .skeleton-table .skeleton-head { opacity: 0.6; }
  .skeleton-chart { position: relative; height: 12rem; margin: 0.375rem 0 0 2.25rem; border-left: 1px solid var(--border); border-bottom: 1px solid var(--border); }
  .skeleton-chart > i { display: block; height: 25%; border-top: 1px dashed var(--border); }
  .skeleton-chart-body { position: absolute; left: 2%; right: 2%; top: 30%; }

  /* ---------- page header ---------- */
  /* The actions wrap under the title when the title needs the width (QUA-03). */
  .page-header { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.75rem 1rem; margin-bottom: var(--space-section); }
  /* Sticky: only the heading row is pinned; the breadcrumb above and the description under it are siblings that scroll. */
  .page-header[data-sticky] { position: sticky; top: var(--sticky-top); z-index: 5; background: var(--background); margin: 0 calc(-1 * var(--page-gutter));
    padding: 0.5rem var(--page-gutter); align-items: center; }
  /* Room for a breadcrumb link's focus ring above the sticky heading row, which is opaque and drawn over it. */
  .page-header-crumbs { padding-bottom: 0.25rem; }
  .page-header-more { display: grid; gap: 0.25rem; margin-bottom: var(--space-section); }
  .page-header-more > p { color: var(--muted-foreground); max-width: 42rem; }
  .page-header-main { flex: 1 1 24rem; min-width: 0; display: grid; gap: 0.375rem; }
  .page-header-main > h1 { display: flex; align-items: center; gap: 0.625rem; }
  .page-header-title { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.625rem; }
  .page-header-main > p { color: var(--muted-foreground); max-width: 42rem; }
  .page-header-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.625rem; color: var(--muted-foreground); font-size: var(--text-label); }
  /* Meta given as a list: a dot in the gap before each item, clipped away when the item starts a line. */
  .page-header-meta[data-dots] { overflow: hidden; }
  .page-header-meta[data-dots] > * { position: relative; }
  .page-header-meta[data-dots] > * + *::before { content: "·"; position: absolute; inset-inline-start: -0.45rem; }
  .page-header-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; justify-content: flex-end; }

  /* ---------- alert (customised: tones, compact, actions below) and note ---------- */
  .alert[data-tone="info"] { background-color: var(--info-surface); }
  .alert[data-variant="destructive"], .alert[data-variant="destructive"] > section { color: var(--destructive-text); }
  .alert[data-tone="warning"] { background-color: var(--warning-surface); border-color: color-mix(in oklab, var(--warning) 30%, transparent); }
  .alert[data-tone="warning"] > .lucide { color: var(--warning); }
  .alert[data-tone="success"] > .lucide { color: var(--success); }
  .alert[data-tone="privacy"] > .lucide { color: var(--muted-foreground); }
  .alert[data-compact] { padding-block: 0.5rem; }
  .alert > section > p > b:first-child { font-weight: 600; }
  .alert[data-actions="below"]:has(> footer) { padding-inline-end: calc(var(--spacing) * 4); }
  .alert[data-actions="below"] > footer { position: static; grid-column: 1 / -1; color: var(--foreground); display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.5rem; }
  .alert[data-actions="below"]:has(> svg) > footer { grid-column-start: 2; }
  .note { display: flex; align-items: flex-start; gap: 0.375rem; color: var(--muted-foreground); font-size: var(--text-label); }
  .note > .lucide { margin-top: 0.0625rem; width: 0.875rem; height: 0.875rem; }
  .note[data-tone="warning"] { color: var(--warning); }

  /* ---------- empty state (customised: outline, start alignment, small) and error state ---------- */
  .empty[data-variant="outline"] { border: 1px dashed var(--border); border-radius: var(--radius-lg); }
  .empty[data-size="sm"] { padding: 1.5rem; gap: 0.75rem; }
  .empty[data-align="start"] { align-items: flex-start; text-align: start; }
  .empty[data-align="start"] > :is(header, section, footer) { align-items: flex-start; max-width: none; }
  .empty > footer { flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 0.5rem; }
  .empty[data-align="start"] > footer { justify-content: flex-start; }
  .empty > section > * { align-self: stretch; }
  .empty > header > h1 { font-size: var(--text-title); }
  .error-state small { color: var(--muted-foreground); }

  /* An item whose title is a link (Home's favourites): Basecoat clamps the title to one line by hiding what
     overflows, which would cut the link's focus ring off; the title wraps instead (QUA-01). */
  .item :is(h2, h3, h4):has(a) { overflow: visible; display: flex; flex-wrap: wrap; }
  /* ---------- card (customised: media across the top) and report section (action buttons in the header, a note
     under the body) ---------- */
  /* Section headings are a step up from body text (DESIGN-AUDIT H3); a small card's stay at body size. */
  .card > header > :is(h2, h3) { font-size: var(--text-section); font-weight: 600; letter-spacing: -0.01em; }
  .card[data-size="sm"] > header > :is(h2, h3) { font-size: var(--text-body); }
  .card > header > p { color: var(--muted-foreground); }
  .card:has(> .card-media) { padding-top: 0; overflow: hidden; }
  .card-media { margin: 0; border-bottom: 1px solid var(--border); }
  .card[data-flush] { padding-block: 0.25rem; }
  .card[data-flush] > section { padding-inline: 0.5rem; }
  .card.report-section > header .card-action { display: flex; gap: 0.5rem; }
  .card.report-section > section { min-width: 0; }
  /* A section whose table is narrow is as wide as the table, not the page (fit; DESIGN-AUDIT M3). */
  .card.report-section[data-fit] { width: fit-content; min-width: min(100%, 30rem); max-width: 100%; }
  .out-table { overflow-x: auto; }
  /* A chart's View as table scrolls inside its own area, its headings and total row held in view (mockup 32 state 3,
     pin 8); they lie above the body's held first column, and the corner cells above both. */
  .out-chart ~ .out-table > .table-container { max-height: 26.875rem; overflow-y: auto; }
  .out-chart ~ .out-table :is(thead th, tfoot td, tfoot th) { position: sticky; z-index: 2; }
  .out-chart ~ .out-table thead th { top: 0; background: var(--card); }
  .out-chart ~ .out-table tfoot :is(td, th) { bottom: 0; background: var(--muted); }
  .out-chart ~ .out-table :is(thead th[data-naming], tfoot th[scope="row"]) { z-index: 3; }
  .report-section-note { margin-top: 0.75rem; display: grid; gap: 0.375rem; color: var(--muted-foreground); font-size: var(--text-label); }

  /* ---------- band ---------- */
  /* On the page, not in a card: hairlines above and below, a small label for a title, a smaller description list. */
  .band { display: grid; gap: 0.75rem; padding-block: 1rem 1.125rem; border-block: 1px solid var(--border); }
  .band-title { font-size: var(--text-label); font-weight: 600; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--muted-foreground); }
  .band .description-list { row-gap: 0.75rem; }
  .band .description-list dd { font-size: var(--text-label); line-height: 1.45; }

  /* ---------- tile and tile row ---------- */
  /* A tile alone is a small card; in a tile row (ui.tileRow) the tiles are one band of figures, divided by hairlines
     (each draws its own on its left and top, and the row clips the ones at its outer edges), so the row reads as one
     strip however it wraps (DESIGN-AUDIT M1). The figure is the largest text of a report page (H3). */
  .tile { border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--card); padding: 0.875rem 1rem; min-width: 0; }
  .tile[data-tone="danger"] { border-color: color-mix(in oklab, var(--destructive) 35%, transparent); }
  .tile-label { display: flex; align-items: center; gap: 0.25rem; color: var(--muted-foreground); font-size: var(--text-label); font-weight: 500; }
  .tile-value { font-size: var(--text-figure); font-weight: 600; letter-spacing: var(--tracking-figure); line-height: 1.1; margin: 0.375rem 0 0.25rem; font-variant-numeric: tabular-nums; }
  .tile[data-size="sm"] .tile-value { font-size: var(--text-figure-sm); }
  .tile-delta { font-size: var(--text-label); font-weight: 600; font-variant-numeric: tabular-nums; }
  .tile-delta-note { font-weight: 400; color: var(--muted-foreground); }
  .tile-sub { color: var(--muted-foreground); font-size: var(--text-label); font-variant-numeric: tabular-nums; }
  .tile-row { display: grid; grid-template-columns: repeat(var(--tiles, 4), minmax(0, 1fr)); gap: 0; overflow: hidden;
    border: 1px solid var(--border); border-radius: var(--radius-xl); background: var(--card); box-shadow: 0 1px 2px var(--shadow-color); }
  .tile-row > * { border: 0; border-radius: 0; background: none; box-shadow: -1px 0 0 var(--border), 0 -1px 0 var(--border); padding: 1.125rem 1.375rem 1.25rem; min-width: 0; }
  .tile-row > .empty { margin: 0; }

  /* ---------- figure (a tile's figure in a list row) ---------- */
  .figure { display: grid; gap: 0.0625rem; min-width: 0; }
  .figure-label { color: var(--muted-foreground); font-size: var(--text-label); }
  .figure-line { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 0.5rem; }
  .figure-value { font-size: var(--text-section); font-weight: 600; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; white-space: nowrap; }
  .figure-delta { font-size: var(--text-label); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }

  /* ---------- definition marker ---------- */
  .def-marker { display: inline-grid; place-items: center; width: 0.9375rem; height: 0.9375rem; border-radius: 9999px; border: 1px solid var(--muted-foreground);
    color: var(--muted-foreground); font: italic 600 var(--text-marker)/1 var(--font-sans); vertical-align: 1px; margin-inline-start: 0.25rem; cursor: help; background: transparent;
    transition: color var(--duration-hover) var(--ease-out), border-color var(--duration-hover) var(--ease-out); }
  .def-marker:hover { color: var(--link); border-color: var(--link); }
  /* Positioned, so it is drawn after the line under it (a wrapped heading's sort arrow), which would otherwise be
     drawn over its ring; with no z-index it stays under a held column or heading. */
  .def-marker { position: relative; }

  /* ---------- dash ---------- */
  .dash { color: var(--muted-foreground); cursor: help; border-radius: var(--radius-sm); padding: 0 0.125rem; }
  .dash-marker { display: inline-grid; place-items: center; width: 0.8125rem; height: 0.8125rem; margin-inline-start: 0.25rem; border-radius: 9999px; border: 1px solid currentColor; font: italic 600 calc(var(--text-marker) * 0.9)/1 var(--font-sans); vertical-align: 1px; }

  /* ---------- table (customised: density, numeric columns, sortable headings, wrap, total and pinned rows, bar cell) ---------- */
  .table th, .table td { padding: var(--table-cell-padding); height: var(--table-row-height); }
  .table th { color: var(--muted-foreground); font-size: var(--text-label); font-weight: 500; text-align: start; }
  .table :is(th, td).num { text-align: end; font-variant-numeric: tabular-nums; }
  .table thead th.wrap { white-space: normal; line-height: 1.2; max-width: 7rem; }
  /* A row's header (ui.table's naming column) reads as a header to assistive technology and looks like a cell. */
  .table :is(tbody, tfoot) th[scope="row"] { color: inherit; font-size: inherit; font-weight: inherit; text-align: start; }
  .table :is(td, th[scope="row"]).wrap { white-space: normal; }
  .table :is(td, th[scope="row"]) small { display: block; color: var(--muted-foreground); font-size: var(--text-label); }
  .table tbody tr > :is(td, th[scope="row"]) { transition: background-color var(--duration-hover) var(--ease-out); }
  .table tbody tr:hover > :is(td, th[scope="row"]) { background: color-mix(in oklab, var(--muted) 70%, transparent); }
  .table tr.total > :is(td, th[scope="row"]), .table tfoot :is(td, th[scope="row"]) { font-weight: 600; background: var(--muted); }
  .table tfoot { background: none; }
  .table tfoot tr[data-pinned] > :is(td, th[scope="row"]) { font-weight: 400; background: none; color: var(--muted-foreground); border-top: 2px solid var(--border); }
  table[data-ui-sortable] th[tabindex] { cursor: pointer; user-select: none; }
  /* The arrows are drawn, not read: aria-sort says how a column is sorted. */
  table[data-ui-sortable] th[tabindex]::after { content: "↕" / ""; margin-inline-start: 0.25rem; color: var(--border); }
  /* The order a table is in shows on its heading, sortable or not (History's fixed newest-first order). */
  /* As specific as the sortable heading's ↕ above, so a sorted heading shows its arrow. */
  :is(.table, table[data-ui-sortable]) th[aria-sort="ascending"][aria-sort]::after { content: "↑" / ""; margin-inline-start: 0.25rem; color: var(--foreground); }
  :is(.table, table[data-ui-sortable]) th[aria-sort="descending"][aria-sort]::after { content: "↓" / ""; margin-inline-start: 0.25rem; color: var(--foreground); }
  .table th[aria-sort] { color: var(--foreground); }
  /* A table wider than its area (ui.js markEdges): the column naming each row stays at the left edge while the others
     scroll under it, drawn opaque with a shadow once something is under it, and the edge with more fades out. */
  .table-container .table :is(th[scope="row"], th[data-naming]) { position: sticky; inset-inline-start: 0; z-index: 1; background: var(--card); }
  /* A control the focus scrolls to inside the area is kept clear of the held column and of held headings (ui.js
     markEdges measures both); and the area clips what is drawn outside it, so a heading's focus ring is drawn inside
     the heading, where the area's top edge cannot cut it off (QUA-01). */
  .table-container { scroll-padding-inline: calc(var(--held-width, 0px) + 0.5rem) var(--scroll-fade); }
  [data-more]:not(.table-container) { scroll-padding-inline: var(--scroll-fade); }
  /* A held cell is opaque and drawn over the cells after it; the one holding the focus is drawn over its neighbours,
     so its ring is not covered by the next row's. */
  .table-container .table :is(th[scope="row"], th[data-naming]):focus-within { z-index: 2; }
  .out-chart ~ .out-table > .table-container { scroll-padding-top: var(--head-height, 0px); }
  .table-container th:focus-visible { outline-offset: -2px; }
  .table-container .table tbody tr:hover > th[scope="row"] { background: color-mix(in oklab, var(--muted) 50%, var(--card)); }
  .table-container .table :is(tr.total, tfoot tr:not([data-pinned])) > th[scope="row"] { background: var(--muted); }
  .table-container[data-more~="start"] .table :is(th[scope="row"], th[data-naming]) { box-shadow: inset -1px 0 var(--border), 6px 0 6px -4px var(--shadow-color); }
  /* Any area that scrolls sideways (ui.js marks data-more on it): the edge with more fades out. A table's start edge
     does not, since its naming column is held there. */
  [data-more~="end"] { mask-image: linear-gradient(to left, transparent, var(--mask-opaque) min(var(--scroll-fade), var(--more-end, var(--scroll-fade)))); }
  [data-more~="start"]:not(.table-container) { mask-image: linear-gradient(to right, transparent, var(--mask-opaque) min(var(--scroll-fade), var(--more-start, var(--scroll-fade)))); }
  [data-more~="start"][data-more~="end"]:not(.table-container) { mask-image: linear-gradient(to right, transparent, var(--mask-opaque) min(var(--scroll-fade), var(--more-start, var(--scroll-fade))),
    var(--mask-opaque) calc(100% - min(var(--scroll-fade), var(--more-end, var(--scroll-fade)))), transparent); }
  .bar-cell { position: relative; }
  .bar-cell-bar { position: absolute; inset-inline-end: var(--table-cell-padding); bottom: 0.25rem; height: 0.25rem; border-radius: 2px; background: var(--chart-current-soft);
    width: calc((100% - 2 * var(--table-cell-padding)) * var(--fraction)); }

  /* ---------- pager (Basecoat pagination with rows per page, a count and Go to page) ---------- */
  /* Padded round, so a control's focus ring is not cut off by the table's scrolling area the pager sits in. */
  .pager { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; padding: 0.75rem 0.25rem 0.25rem; font-size: var(--text-sm); }
  .pager > ul { display: flex; align-items: center; gap: 0.25rem; }
  .pager-count { flex: 1; color: var(--muted-foreground); text-align: end; }
  .pager-gap { display: inline-grid; place-items: center; width: 2.25rem; color: var(--muted-foreground); }
  .pager-size, .pager-goto { display: inline-flex; align-items: center; gap: 0.5rem; color: var(--muted-foreground); white-space: nowrap; }
  .pager-goto .input { width: 4.5rem; }
  .pager-size .select { width: auto; }

  /* ---------- dropdown menu and popover (customised: menu header, item hints, floating beside any element) ---------- */
  .floating-anchor { position: absolute; z-index: 50; pointer-events: none; }
  /* A menu or popover opened beside any element comes in with a short fade. Opacity only: what is coming in can be
     pointed at and clicked at once, where it will stay. */
  .floating-anchor > [data-popover] { animation: ui-enter var(--duration-enter) var(--ease-out); }
  @keyframes ui-enter { from { opacity: 0; } }
  .floating-anchor > [data-popover] { pointer-events: auto; }
  .dropdown-header { margin: 0; font-size: inherit; display: grid !important; gap: 0.125rem; padding: 0.375rem 0.5rem; line-height: 1.3; }
  .dropdown-header b { font-weight: 600; color: var(--foreground); font-size: var(--text-sm); }
  .dropdown-header small { color: var(--muted-foreground); font-weight: 400; font-size: var(--text-label); }
  .dropdown-menu [role="menuitem"] > span { display: grid; text-align: start; }
  /* QUA-01: Basecoat draws a destructive button's ring, and an invalid field's, in red at 20% (about 1.3:1 on white).
     The button takes the ring every other control has (tokens.css); the field a full-strength red one. */
  .btn[data-variant=destructive]:focus-visible { --tw-ring-color: color-mix(in oklab, var(--ring) 50%, transparent); }
  [aria-invalid="true"]:focus-visible { --tw-ring-color: var(--destructive); }
  /* The focus follows the active item (ui.js), so it needs a visible ring as well as Basecoat's active ground. */
  .dropdown-menu [role^="menuitem"]:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; }
  .dropdown-menu [role="menuitem"] small { color: var(--muted-foreground); font-size: var(--text-label); }
  .popover [data-popover] { max-width: 22rem; }
  /* Kept inside the window (ui.js fitPopover): moved sideways by --fit-x, narrowed, or given its own scroll. As
     specific as Basecoat's centred placement, which it replaces while open. */
  [data-popover][data-fit][aria-hidden="false"] { translate: calc(var(--fit-base-x, 0px) + var(--fit-x, 0px)) var(--fit-base-y, 0px); }
  :is([data-popover]:not([data-side]), [data-popover][data-side="top"], [data-popover][data-side="bottom"])[data-align="center"][data-fit] { --fit-base-x: -50%; }
  :is([data-popover][data-side="left"], [data-popover][data-side="right"])[data-align="center"][data-fit] { --fit-base-y: -50%; }
  [data-popover][data-fit~="narrow"] { max-width: var(--fit-max-width) !important; overflow-x: auto; }
  [data-popover][data-fit~="short"] { max-height: var(--fit-max-height) !important; overflow-y: auto; }
  .popover [data-popover] > header > h4 { font-weight: 500; }
  /* The ✕ of a closable popover (a definition, mockup 40 pin 13) sits in its top corner, clear of the heading. */
  .popover [data-popover][data-closable] > header { padding-inline-end: 1.5rem; }
  .popover [data-popover] > .popover-close { position: absolute; top: 0.375rem; inset-inline-end: 0.375rem; }
  .popover [data-popover] > header > p { color: var(--muted-foreground); }

  /* ---------- tooltip (ours, for rich content and SVG; same look as Basecoat's) ---------- */
  .ui-tooltip { position: fixed; z-index: 60; pointer-events: none; max-width: 20rem; border-radius: var(--radius-md); background: var(--foreground); color: var(--background);
    padding: 0.375rem 0.75rem; font-size: var(--text-label); line-height: 1.4; }
  .floating-tip.chart-tooltip { translate: none; }

  /* ---------- dialog (customised: widths, a quieter second sentence) ---------- */
  :is(.dialog, .alert-dialog) .dialog-note { color: var(--muted-foreground); }
  /* Basecoat fixes the panel (the first child) in place, which leaves the <dialog> itself 0×0 and so "hidden" to
     assistive checks; the open dialog covers the window instead, transparent, as its backdrop does. */
  :is(.dialog, .alert-dialog):modal { width: 100%; height: 100%; }
  .dialog[data-width="sm"] > div, .alert-dialog[data-width="sm"] > div { max-width: 24rem; }
  .dialog[data-width="md"] > div { max-width: 28rem; }
  .dialog[data-width="lg"] > div { max-width: 42rem; }
  .dialog[data-width="xl"] > div { max-width: min(64rem, 92vw); max-height: 86vh; overflow: auto; }
  .dialog[data-width="full"] > div { width: 96vw; max-width: 96vw; max-height: 92vh; overflow: auto; }

  /* ---------- segmented control (customised button group: pressed button is the choice) ---------- */
  .segmented .btn[aria-pressed="true"] { background-color: var(--selected); color: var(--link); font-weight: 600; border-color: var(--selected-border); }

  /* ---------- field (customised: a warning message) and checkbox (customised: mixed) ---------- */
  .field > [role="alert"]:empty { display: none; }
  .field[data-warning] > [role="alert"] { color: var(--warning); }
  input[type="checkbox"]:not([role="switch"]):indeterminate { border-color: var(--primary); background-color: var(--primary); }
  input[type="checkbox"]:not([role="switch"]):indeterminate::after { content: ""; position: absolute; inset: 0; margin: auto; width: 0.5rem; height: 2px; border-radius: 1px; background-color: var(--primary-foreground); }

  /* ---------- choice card (customised Field choice card: aside, reason, checked and disabled states) ---------- */
  .choice-card { display: block; border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 0.75rem 0.875rem; cursor: pointer; background: var(--card);
    transition: background-color var(--duration-hover) var(--ease-out), border-color var(--duration-hover) var(--ease-out); }
  .choice-card:not([data-checked], [data-disabled]):hover { border-color: var(--input); }
  .choice-card[data-checked] { border-color: var(--selected-border); background: var(--selected); }
  .choice-card[data-disabled] { cursor: default; background: var(--muted); color: var(--muted-foreground); }
  .choice-card .field { align-items: flex-start; }
  .choice-card h3 { font-weight: 500; display: flex; gap: 0.375rem; align-items: center; }
  .choice-card p { color: var(--muted-foreground); font-size: var(--text-label); }
  .choice-card .choice-card-reason { color: var(--foreground); }
  .choice-card aside { margin-inline-start: auto; text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }

  /* ---------- search box (input group with a clear button) ---------- */
  .search-box input[type="search"]::-webkit-search-cancel-button { display: none; }
  .search-box > [data-align="start"] { padding-inline-start: 0.625rem; color: var(--muted-foreground); }

  /* ---------- faceted filter ---------- */
  .faceted-filter { min-width: 12rem; justify-content: space-between; font-weight: 400; }
  .faceted-filter-name { color: var(--muted-foreground); }
  .faceted-filter[data-active] { border-color: var(--selected-border); background-color: var(--selected); }
  .faceted-filter-options { display: grid; gap: 0.5rem; min-width: 12.5rem; margin-bottom: 0.5rem; border: 0; padding: 0; }

  /* ---------- filter chip ---------- */
  .filter-chip { cursor: pointer; gap: 0.375rem; max-width: 24rem; }
  .filter-chip:hover { background-color: var(--accent); }

  /* ---------- chip field ---------- */
  .chip-field { max-width: 48rem; }
  .chip-field-control { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem; min-height: 2.375rem; border: 1px solid var(--input); border-radius: var(--radius-md); padding: 0.25rem 0.375rem 0.25rem 0.625rem; }
  .chip-field-control[data-open] { border-color: var(--ring); box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); }
  .chip-field-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .chip-field-empty { color: var(--muted-foreground); }
  .chip-field-control > .btn { margin-inline-start: auto; }
  .chip-field .chip { gap: 0.25rem; padding-inline-end: 0.25rem; }
  .chip-field .chip button { display: inline-grid; place-items: center; border-radius: 9999px; }
  .chip-field .chip button:hover { background: var(--accent); }
  .chip-field-list { margin-top: 0.25rem; border: 1px solid var(--border); border-radius: var(--radius-md); padding: 0.5rem 0.75rem; display: grid; gap: 0.5rem; box-shadow: var(--shadow-raised); }
  .chip-field-actions { display: flex; align-items: center; gap: 0.5rem; border-bottom: 1px solid var(--border); padding-bottom: 0.375rem; }
  .chip-field-count { margin-inline-end: auto; color: var(--muted-foreground); font-size: var(--text-label); }

  /* ---------- stepper ---------- */
  .stepper ol { display: flex; border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; background: var(--card); }
  .stepper li { flex: 1; min-width: 0; display: flex; gap: 0.625rem; align-items: flex-start; padding: 0.625rem 0.875rem; border-inline-end: 1px solid var(--border); color: var(--muted-foreground); }
  .stepper li:last-child { border-inline-end: 0; }
  .stepper li > span { display: grid; min-width: 0; }
  /* CFG-01: a step's summary is shown whole, however long the selection makes it. */
  .stepper small { font-size: var(--text-label); overflow-wrap: anywhere; }
  .stepper-mark { flex: none; display: inline-grid; place-items: center; width: 1.375rem; height: 1.375rem; border-radius: 9999px; border: 1px solid var(--border); font-size: var(--text-label); }
  .stepper-mark .lucide { width: 0.75rem; height: 0.75rem; }
  .stepper li[data-state="current"] { background: var(--selected); color: var(--foreground); font-weight: 600; box-shadow: inset 0 -2px 0 var(--primary); }
  .stepper li[data-state="current"] .stepper-mark { background: var(--primary); border-color: var(--primary); color: var(--primary-foreground); }
  .stepper li[data-state="done"] { color: var(--foreground); }
  .stepper li[data-state="done"] .stepper-mark { background: var(--success-surface); border-color: transparent; color: var(--success); }
  .stepper-link { text-align: start; text-decoration: underline; text-decoration-color: var(--border); text-underline-offset: 3px; cursor: pointer; }
  .stepper-link:hover { text-decoration-color: currentColor; }

  /* ---------- checkbox tree ---------- */
  .tree { padding: 0.375rem 0; max-height: 40rem; overflow-y: auto; }
  /* QUA-03: a long row ("Other Frozen Appetizers & Snacks products") wraps rather than losing its end. */
  .tree-row { display: flex; align-items: center; gap: 0.375rem; min-height: 1.75rem; padding: 0.125rem 0.875rem 0.125rem calc(0.5rem + var(--depth) * 1.25rem); }
  .tree-row[data-selected] { background: var(--selected); }
  .tree-row[data-conflict] { background: var(--destructive-surface); }
  .tree-row > .field { flex: 0 1 auto; width: auto; min-width: 0; }
  .tree-row > .field label { overflow-wrap: anywhere; font-weight: 400; }
  .tree-spacer { width: 1.5rem; flex: none; }
  .tree-count { margin-inline-start: auto; color: var(--muted-foreground); font-size: var(--text-label); font-variant-numeric: tabular-nums; }

  /* ---------- week picker ---------- */
  .week-picker { display: grid; gap: 0.25rem; font-size: var(--text-label); font-weight: 600; }
  .week-picker > .popover > .btn { width: 14rem; justify-content: space-between; font-weight: 400; }
  .week-picker > .popover > .btn[aria-invalid="true"] { border-color: var(--destructive); }
  .week-picker [data-popover] { width: 32rem; max-width: calc(100vw - 2rem); padding: 0.75rem 0.875rem 0.625rem; }
  .week-picker-months { display: grid; grid-template-columns: 1fr 1fr; gap: 1.375rem; }
  .week-picker-month > header { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.25rem; }
  .week-picker-month h4 { flex: 1; text-align: center; font-weight: 600; }
  .week-picker-gap { width: 2rem; }
  .week-picker-weekdays, .week-picker-week { display: grid; grid-template-columns: repeat(7, 1fr); }
  .week-picker-weekdays span { padding: 0.1875rem 0; text-align: center; color: var(--muted-foreground); font-size: var(--text-label); font-weight: 600; }
  .week-picker-week { width: 100%; margin: 0.125rem 0; border-radius: var(--radius-md); font-size: var(--text-label); font-weight: 400; font-variant-numeric: tabular-nums; cursor: pointer; }
  .week-picker-week span { padding: 0.25rem 0; text-align: center; }
  .week-picker-week span[data-outside] { color: var(--muted-foreground); }
  .week-picker-week:hover, .week-picker-week:focus-visible { background: var(--selected); box-shadow: inset 0 0 0 2px var(--ring); outline: 0; font-weight: 600; }
  .week-picker-week[data-chosen] { background: var(--primary); color: var(--primary-foreground); }
  .week-picker-week[data-chosen] span[data-outside] { color: var(--week-outside-chosen); }
  .week-picker-week[data-marked] { background: var(--selected); font-weight: 600; }
  .week-picker-week:disabled { cursor: default; box-shadow: none; font-weight: 400; background: var(--muted); }
  .week-picker-week:disabled span { color: var(--muted-foreground); text-decoration: line-through; }
  .week-picker-note { margin-top: 0.5rem; padding-top: 0.5rem; border-top: 1px solid var(--border); color: var(--muted-foreground); font-size: var(--text-label); font-weight: 400; }
  .week-picker-note b { color: var(--foreground); font-weight: 600; }

  /* ---------- inline edit ---------- */
  .inline-edit-row { display: flex; gap: 0.375rem; align-items: center; }
  .inline-edit .input { flex: 1; min-width: 0; font-weight: 600; }
  .inline-edit[data-size="lg"] .inline-edit-row { width: 28rem; max-width: 100%; }
  .inline-edit[data-size="lg"] .input { font-size: var(--text-section); height: 2.375rem; }
  .inline-edit-hint { margin-top: 0.25rem; color: var(--muted-foreground); font-size: var(--text-label); }
  .inline-edit-hint[data-error] { color: var(--destructive-text); font-weight: 600; }

  /* ---------- description list ---------- */
  .description-list { display: grid; grid-template-columns: repeat(var(--columns), minmax(0, 1fr)); gap: 0.5rem 1.125rem; }
  .description-list > div[data-wide] { grid-column: 1 / -1; }
  .description-list dt { color: var(--muted-foreground); font-size: var(--text-label); }
  .description-list dd { overflow-wrap: anywhere; }
  .description-list + .note { margin-top: 0.75rem; }

  /* ---------- touch targets (customised: every control 44 px under a coarse pointer, a tablet; DESIGN-AUDIT M4) ---------- */
  @media (pointer: coarse) {
    :is(.btn, .input, .input-group, select.select, .faceted-filter, .pager a, .pager button) { min-height: var(--touch-target); }
    .btn:is([data-size^="icon"]) { min-width: var(--touch-target); }
    .sidebar > nav li > :is(a, button), .dropdown-menu [role^="menuitem"], .week-picker-week, .proto-dock > * { min-height: var(--touch-target); }
    .tree-row, .wz-facet-value { min-height: var(--touch-target); }
    input[type="checkbox"], input[type="radio"] { width: 1.25rem; height: 1.25rem; }
  }

  /* ---------- trend colours (used by Proto.fmt.delta) ---------- */
  .up { color: var(--trend-up); }
  .down { color: var(--trend-down); }
}
