/* ==========================================================================
   COMPONENTS — Preline's admin-dashboard vocabulary in logical properties. Every value is a token.
   ========================================================================== */

/* ── App shell ────────────────────────────────────────────────────────────── */
.app-shell { min-height: 100vh; padding-inline-start: var(--sidebar-width); padding-block-start: var(--topbar-height); }
.app-sidebar { position: fixed; inset-block: 0; inset-inline-start: 0; width: var(--sidebar-width); z-index: 20;
  display: flex; flex-direction: column; background: var(--color-surface); border-inline-end: 1px solid var(--color-border); overflow-y: auto; }
.app-topbar { position: fixed; inset-block-start: 0; inset-inline: var(--sidebar-width) 0; height: var(--topbar-height); z-index: 10;
  display: flex; align-items: center; gap: var(--space-2); padding-inline: var(--space-5);
  background: var(--color-surface); border-block-end: 1px solid var(--color-border); }
.app-main { padding: var(--space-6); display: flex; flex-direction: column; gap: var(--space-5); }
@media (max-width: 991px) {
  .app-shell { padding-inline-start: 0; }
  .app-sidebar { position: static; width: auto; border-inline-end: 0; border-block-end: 1px solid var(--color-border); }
  .app-topbar { inset-inline: 0; }
}

/* ── Sidebar ──────────────────────────────────────────────────────────────── */
.nav-brand { display: flex; align-items: center; gap: var(--space-3); height: var(--topbar-height); flex: none;
  padding-inline: var(--space-5); color: var(--color-action-primary); font-size: var(--text-md); font-weight: var(--weight-semibold); text-decoration: none; }
.nav-list, .nav-sub { list-style: none; margin: 0; padding: 0; }
.nav-list { padding: var(--space-3); display: flex; flex-direction: column; gap: 2px; }
.nav-item { display: flex; align-items: center; gap: var(--space-3); height: var(--nav-item); padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md); color: var(--color-text-body); font-size: var(--text-sm); text-decoration: none; cursor: pointer; list-style: none; }
.nav-item::-webkit-details-marker { display: none; }
.nav-item > .nav-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-item svg { flex: none; color: var(--color-text-muted); }
.nav-item:hover, .nav-item.is-active, .nav-group[open] > .nav-item { background: var(--color-surface-sunken); text-decoration: none; }
.nav-item.is-active { font-weight: var(--weight-medium); }
.nav-item.is-active svg { color: var(--color-text-body); }
.nav-chevron { display: inline-flex; color: var(--color-text-muted); transition: transform var(--fast); }
.nav-group[open] > .nav-item .nav-chevron { transform: rotate(180deg); }
.nav-sub { margin-inline-start: 24px; padding-inline-start: var(--space-3); border-inline-start: 1px solid var(--color-border); padding-block: 2px 4px; }
.nav-sub-item { display: flex; align-items: center; height: var(--nav-sub-item); padding-inline: var(--space-3);
  border-radius: var(--radius-md); color: var(--color-text-body); font-size: var(--text-sm); text-decoration: none; }
.nav-sub-item:hover, .nav-sub-item.is-active { background: var(--color-surface-sunken); text-decoration: none; }
.nav-sub-item.is-active { font-weight: var(--weight-medium); }
.nav-label { padding: var(--space-2) var(--space-3); margin-block-start: var(--space-4); font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--color-text-muted); }
.nav-foot { margin-block-start: auto; flex: none; display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3); border-block-start: 1px solid var(--color-border); }
.identity { display: flex; align-items: center; gap: var(--space-3); flex: 1; min-width: 0; color: var(--color-text-body); text-decoration: none; }
.identity-text { display: flex; flex-direction: column; min-width: 0; }
.identity-name { font-weight: var(--weight-medium); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.identity-role { font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--color-text-muted); }

/* ── Topbar ───────────────────────────────────────────────────────────────── */
.search-field { display: flex; align-items: center; gap: var(--space-2); height: var(--control-md); width: min(400px, 100%);
  padding-inline: var(--space-3); border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-surface);
  color: var(--color-text-muted); font-size: var(--text-sm); text-decoration: none; }
.search-field:hover { border-color: var(--color-border-strong); text-decoration: none; }
.search-field > .search-text { flex: 1; }
.kbd { font: inherit; font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--color-text-muted);
  border: 1px solid var(--color-border); border-radius: var(--radius-sm); padding: 2px 6px; }
.topbar-end { margin-inline-start: auto; display: flex; align-items: center; gap: var(--space-2); }
.avatar { display: inline-grid; place-items: center; width: 32px; height: 32px; flex: none; border-radius: var(--radius-full);
  background: var(--color-surface-sunken); color: var(--color-text-body); font-size: var(--text-xs); font-weight: var(--weight-semibold); overflow: hidden; }
.avatar-lg { width: var(--control-md); height: var(--control-md); border: 2px solid var(--color-border); }
.notify-dot { position: absolute; inset-block-start: 4px; inset-inline-end: 4px; width: 8px; height: 8px; border-radius: var(--radius-full);
  background: var(--color-notify); border: 2px solid var(--color-surface); box-sizing: content-box; }

/* ── Page ─────────────────────────────────────────────────────────────────── */
.page-head { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.page-head h1 { margin-inline-end: auto; }
.page-lede { color: var(--color-text-muted); }
.page-center { max-width: var(--form-width); margin-inline: auto; width: 100%; display: flex; flex-direction: column; gap: var(--space-5); }
.page-center > .page-title { text-align: center; }
.page-center > .page-title h1 { font-size: var(--text-xl); }
.page-center > .page-title p { color: var(--color-text-muted); margin-block-start: var(--space-1); }
.crumbs { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--color-text-muted); }
.crumbs a { color: var(--color-text-muted); }
.crumbs .is-current { color: var(--color-text-heading); font-weight: var(--weight-medium); }

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: var(--control-md); padding: var(--space-2) var(--space-3);
  border: 1px solid transparent; border-radius: var(--radius-xs); font-size: var(--text-sm); font-weight: var(--weight-medium);
  cursor: pointer; text-decoration: none; white-space: nowrap; transition: background-color var(--fast), border-color var(--fast); }
.btn:hover { text-decoration: none; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }
.btn-primary { background: var(--color-action-primary); color: var(--color-action-primary-on); }
.btn-primary:hover:not(:disabled) { background: var(--color-action-primary-hover); }
.btn-secondary { background: var(--color-action-secondary); border-color: var(--color-border); color: var(--color-action-secondary-on); }
.btn-secondary:hover:not(:disabled) { background: var(--color-action-secondary-hover); }
.btn-ghost { background: transparent; color: var(--color-text-muted); }
.btn-ghost:hover:not(:disabled) { background: var(--color-surface-sunken); color: var(--color-text-body); }
.btn-danger { background: var(--color-danger); color: var(--color-text-inverse); }
.btn-danger:hover:not(:disabled) { background: var(--color-danger-on); }
.btn-danger-ghost { background: var(--color-action-secondary); border-color: var(--color-border); color: var(--color-danger-ghost); }
.btn-danger-ghost:hover:not(:disabled) { background: var(--color-danger-bg); }
.btn-sm { height: var(--control-sm); padding: var(--space-2) 10px; font-size: var(--text-xs); }
.btn-xs { height: var(--control-xs); padding: 6px var(--space-2); font-size: var(--text-xs); border-radius: var(--radius-full); }
.btn-icon { width: var(--control-md); padding: 0; }
.btn-icon.btn-sm { width: var(--control-sm); }
.btn-icon.btn-round { border-radius: var(--radius-full); }
.btn .count { display: inline-grid; place-items: center; min-width: 16px; height: 16px; padding-inline: 4px; border-radius: var(--radius-full);
  background: var(--color-badge-dark); color: var(--color-text-inverse); font-size: 10px; line-height: 1; font-weight: var(--weight-medium); }

/* ── Cards ────────────────────────────────────────────────────────────────── */
.card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-card); box-shadow: var(--shadow-card); }
.card-head { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-5) var(--space-5) var(--space-3); }
.card-head h2 { margin-inline-end: auto; }
.card-head .card-sub { flex-basis: 100%; color: var(--color-text-muted); font-size: var(--text-sm); }
.card-actions { display: flex; align-items: center; gap: var(--space-2); }
.card-body { padding: 0 var(--space-5) var(--space-5); }
.card-body-flush { padding: 0; }
.card-foot { border-block-start: 1px solid var(--color-border); padding: var(--space-3) var(--space-5); text-align: center; }
.card-foot a { color: var(--color-text-link); }
.card-grid { display: grid; gap: var(--space-5); grid-template-columns: repeat(3, minmax(0, 1fr)); }
.card-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 1279px) { .card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 767px)  { .card-grid, .card-grid-2 { grid-template-columns: minmax(0, 1fr); } }

/* ── Stats ────────────────────────────────────────────────────────────────── */
.stat-hero { display: block; font-size: var(--text-hero); line-height: var(--leading-hero); font-weight: var(--weight-medium);
  color: var(--color-action-primary); font-variant-numeric: tabular-nums; margin-block: var(--space-2); text-decoration: none; }
.stat-numeral { font-size: var(--text-2xl); line-height: var(--leading-2xl); font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; }
.stat-label { color: var(--color-text-muted); font-size: var(--text-sm); }
.stat-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); margin-block-start: var(--space-4); }
.stat-tile { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-3); border-radius: var(--radius-md);
  background: var(--color-surface-sunken); color: var(--color-text-body); text-decoration: none; }
.stat-tile:hover { background: var(--color-border); text-decoration: none; }
.stat-tile strong { font-size: var(--text-lg); line-height: var(--leading-lg); font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; }
.stat-card { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-5); color: var(--color-text-body); text-decoration: none; }
.trend { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--text-sm); }
.trend-up { color: var(--color-success); } .trend-down { color: var(--color-danger-ghost); } .trend-none { color: var(--color-text-disabled); }
.segments { display: flex; gap: 2px; height: 8px; border-radius: var(--radius-full); overflow: hidden; margin-block: var(--space-2) var(--space-4); }
.seg { flex: 1 1 0; min-width: 0; }
.seg-1, .swatch-1 { background: var(--color-data-1); } .seg-2, .swatch-2 { background: var(--color-data-2); }
.seg-3, .swatch-3 { background: var(--color-data-3); } .seg-4, .swatch-4 { background: var(--color-data-4); } .seg-5, .swatch-5 { background: var(--color-data-5); }
.legend, .rows { list-style: none; margin: 0; padding: 0; }
.legend li > a, .rows li { display: flex; align-items: center; gap: var(--space-3); height: 40px; color: var(--color-text-body); text-decoration: none; }
.legend li > a:hover { color: var(--color-text-link); text-decoration: none; }
.legend li > a > .legend-text, .rows li > .row-text { flex: 1; }
.swatch { width: 8px; height: 8px; border-radius: 2px; flex: none; }
.legend .num, .rows .num { color: var(--color-text-muted); font-variant-numeric: tabular-nums; }

/* ── Forms (users-add-user.html) ──────────────────────────────────────────── */
.form-card { padding: var(--space-6); }
.form-row { display: grid; grid-template-columns: var(--form-label-width) minmax(0, 1fr); gap: var(--space-3) var(--space-4); align-items: start; }
.form-row + .form-row { margin-block-start: var(--space-3); }
.form-label { padding-block-start: 9px; color: var(--color-text-muted); font-size: var(--text-sm); }
.form-required::after { content: " *"; color: var(--color-danger); }
.form-field { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.form-inline { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: var(--space-2); }
.form-inline-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); }
/* No `outline: none` here, deliberately. It was in the drafted recipe and it is the one defect
   the re-skin already shipped once: base.css's :focus-visible ring and this rule have equal
   specificity, this file loads second, so the suppression wins in every state and the ring painted
   on nothing. The blue border and 1px halo below are ADDED to the browser's outline, not offered
   in exchange for it. */
.form-control { width: 100%; height: var(--control-md); padding: var(--space-2) var(--space-3); border: 1px solid var(--color-border);
  border-radius: var(--radius-md); background: var(--color-surface); color: var(--color-text-body); font-size: var(--text-sm); }
.form-control::placeholder { color: var(--color-text-placeholder); }
.form-control:hover { border-color: var(--color-border-strong); }
.form-control:focus { border-color: var(--color-border-focus); box-shadow: var(--shadow-focus); }
textarea.form-control { height: auto; min-height: 96px; resize: vertical; }
.form-control.is-invalid, .form-control.input-validation-error { border-color: var(--color-danger); }
/* background-position has no logical keywords yet: this is the ONE allowed physical pair, mirrored below. */
.form-select { appearance: none; padding-inline-end: 36px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236a7282' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; background-size: 16px; }
[dir="rtl"] .form-select { background-position: left 12px center; }
.form-check { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); }
.form-check input { width: 16px; height: 16px; margin: 0; border: 1px solid var(--color-border-strong); border-radius: 4px; accent-color: var(--color-action-primary); }
.form-hint { font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--color-text-muted); }
.form-error, .field-validation-error { font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--color-danger); }
.form-actions { display: flex; justify-content: flex-end; gap: var(--space-2); padding-block-start: var(--space-5); }
.upload-avatar { display: flex; align-items: center; gap: var(--space-3); }
.upload-avatar .drop { display: grid; place-items: center; width: 80px; height: 80px; border: 2px dashed var(--color-border); border-radius: var(--radius-full); color: var(--color-text-muted); }
.field-machine { direction: ltr; unicode-bidi: isolate; font-family: var(--font-mono); }

/* ── Pills, badges, chips ─────────────────────────────────────────────────── */
.pill { display: inline-flex; align-items: center; gap: 6px; padding-block: var(--space-badge-block); padding-inline: var(--space-2-5);
  border: 1px solid var(--color-border); border-radius: var(--radius-full); background: var(--color-surface); color: var(--color-text-body);
  font-size: var(--text-xs); font-weight: var(--weight-medium); white-space: nowrap; }
a.pill { text-decoration: none; }
.pill svg { color: var(--color-success); }               /* the white "✓ Good" pill: green tick */
.pill-success svg, .pill-warning svg, .pill-danger svg, .pill-info svg, .pill-off svg, .pill-neutral svg { color: currentColor; }
.pill-success { background: var(--color-success-bg); border-color: var(--color-success-line); color: var(--color-success-on); }
.pill-warning { background: var(--color-warning-bg); border-color: var(--color-warning-line); color: var(--color-warning-on); }
.pill-danger  { background: var(--color-danger-bg);  border-color: var(--color-danger-line);  color: var(--color-danger-on); }
.pill-info    { background: var(--color-info-bg);    border-color: var(--color-info-line);    color: var(--color-info-on); }
/* pill-off is what markup actually reaches for ("Inactive", "Suspended", "Untrusted", …) under the
   name pill-neutral; nothing in the codebase uses the class pill-off itself. One rule for both
   names rather than two that drift apart — the off/neutral tone is a fourth status, not an error. */
.pill-off, .pill-neutral { background: var(--color-off-bg); border-color: var(--color-off-line); color: var(--color-off-on); }
.pill .dot { width: 6px; height: 6px; border-radius: var(--radius-full); background: currentColor; }
.chip { display: inline-flex; align-items: center; height: 24px; padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm);
  background: var(--color-surface-sunken); color: var(--color-text-body); font-size: var(--text-xs); line-height: var(--leading-xs); }
.table .cell-code bdi { display: inline-block; padding: var(--space-0-25) var(--space-1-75); border-radius: var(--radius-2xs);
  border: 1px solid var(--color-border); background: var(--color-surface-raised); color: var(--color-text-muted);
  font-family: var(--font-mono); font-weight: var(--weight-medium); font-size: var(--text-2xs); line-height: var(--leading-xs); }

/* ── Tables ───────────────────────────────────────────────────────────────── */
.table-card { overflow: hidden; }
.toolbar { display: flex; align-items: flex-end; gap: var(--space-3); flex-wrap: wrap; padding: var(--space-4); }
.toolbar .search-field { height: var(--control-sm); background: var(--color-surface-sunken); border-color: transparent; flex: 1 1 320px; max-width: 580px; }
.toolbar-end { margin-inline-start: auto; display: flex; align-items: center; gap: var(--space-2); }
.scroller { overflow-x: auto; }
.table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--text-sm); }
.table th { padding: var(--space-2-5) var(--space-3-5); font-size: var(--text-xs); line-height: var(--leading-xs); font-weight: var(--weight-semibold);
  color: var(--color-text-muted); background: var(--color-surface-raised); border-block-end: 1px solid var(--color-border);
  white-space: nowrap; vertical-align: middle; user-select: none; }
.table td { padding: var(--space-2-75) var(--space-3-5); border-block-end: 1px solid var(--color-border); vertical-align: middle; }
.table tbody tr:last-child td { border-block-end: 0; }
.table tbody tr:hover td { background: var(--color-cross); }
.table .cell-primary, .table .name { font-weight: var(--weight-semibold); font-size: var(--text-name); line-height: var(--leading-name);
  color: var(--color-text-heading); }
/* table-reference.html:187 pins the English subline to `text-align:right` under `direction:ltr` —
   the same `text-align:end` trick .date-abs uses below. The shared `[lang="en"]` rule (D6) sets
   `text-align: start`, which resolves to the physical LEFT under that same `direction:ltr` and is
   correct for a form input or a facts value, both full-width fields where English prose reads from
   its own left edge — but wrong here, where `.cell-sub` is ALSO a full-width block and the subline
   has to land on the Arabic name's own inline-start edge instead, which in this rtl document is the
   physical right. `.table .cell-sub` outranks `[lang="en"]` on class-count alone (0,2,0) > (0,1,0),
   so this needs no `!important` and no change to the shared rule — which stays correct for the ~40
   other `[lang="en"]` surfaces across the console (every Details page's bilingual `dd`/`span.en`,
   every `NameEn`/`TitleEn` form input) that are not table cells. `.bilingual .en` is listed beside
   `.cell-sub` only because it already shared this rule's other properties; `.bilingual` is an
   inline-flex wrapper shrunk to its own text, so text-align never moves it and this addition is a
   no-op there — the bug is exclusively `.cell-primary`/`.cell-sub`'s full-width block. */
.table .cell-sub, .table td .bilingual .en { display: block; font-size: var(--text-2xs); line-height: var(--leading-xs);
  font-weight: var(--weight-regular); color: var(--color-text-muted); margin-block-start: var(--space-0-25); text-align: end; }
/* Numbers read left-to-right even in an Arabic document, on the .cell-code precedent below — and
   the reference's own numeric column is set the same way (direction:ltr; text-align:left). Reading
   direction:ltr locally is what makes `text-align: start` below resolve to that, rather than to
   base.css's [dir="rtl"] branch. Scoped to `td` only: table-reference.html sets this treatment on
   the `<span class="num">` INSIDE a numeric cell, never on the header — its numeric `<th>` stays
   plain Arabic text (IBM Plex Sans Arabic, direction:rtl) with only its alignment forced left, on
   an inline style. `th.cell-num` therefore carries none of this and falls through to base.css's own
   `.cell-num` pin below, which resolves physically left there too, because the header's own
   direction stays rtl and "end" in rtl IS left — no ltr flip needed for a header that never
   switches face. IBM Plex Mono has no Arabic glyphs, so the old unscoped rule forced a system-font
   fallback onto the Arabic header and widened it. */
.table td.cell-num { font-variant-numeric: tabular-nums; font-family: var(--font-mono); font-size: var(--text-num); direction: ltr; unicode-bidi: isolate; }
/* base.css:41 pins .cell-num to `text-align: end` in BOTH directions, deliberately, at specificity
   (0,3,1) — matched here rather than fought, so the later file wins the tie instead of losing to
   the first-loaded one. `start` is `left` because of the ltr direction set above, not because this
   rule names a side; it is what the reference's own left-aligned numeric column asks for. */
[dir="rtl"] .table td.cell-num,
[dir="ltr"] .table td.cell-num { text-align: start; }
.table .cell-code { direction: ltr; unicode-bidi: isolate; }
/* Direct children only — an inline row action (<a class="btn …">), a <form class="row-action"> (already
   inline-flex) and the row's overflow <details class="menu"> (block by default, made inline-block
   here so it joins the same line). display:flex on the <td> itself used to compute the cell out of
   table layout — a real table-cell's own vertical-align:middle (above) then no longer centred it
   against the row's actual height once a neighbouring cell wrapped to two lines. Kept as a table
   cell; text-align:end places the group at the row's end the same way flex's justify-content did. */
.table :is(th, td).cell-actions { width: var(--size-cell-actions); text-align: end; white-space: nowrap; padding-inline-end: var(--space-4); }
.table .cell-actions > * { vertical-align: middle; }
.table .cell-actions > * + * { margin-inline-start: var(--space-1); }
.table .cell-actions > .menu { display: inline-block; }
.row-actions { display: flex; align-items: center; gap: var(--space-0-5); justify-content: flex-end;
  opacity: var(--opacity-row-actions); transition: opacity var(--fast); }
.table tbody tr:hover .row-actions, .row-actions:focus-within { opacity: 1; }
.icon-btn { display: inline-grid; place-items: center; width: var(--control-2xs); height: var(--control-2xs); border-radius: var(--radius-xs);
  border: 0; background: transparent; color: var(--color-text-muted); cursor: pointer;
  transition: background-color var(--fast), color var(--fast); }
.icon-btn:hover { background: var(--color-accent-soft); color: var(--color-action-primary-hover); }
.icon-btn .icon { width: var(--icon-btn); height: var(--icon-btn); }

/* Tooltips — reachable by mouse and by keyboard alike, so a row action with no visible label is
   never explained only to a pointer. */
[data-tip] { position: relative; }
[data-tip]:hover::after, [data-tip]:focus-visible::after {
  content: attr(data-tip); position: absolute; inset-block-end: calc(100% + var(--space-1-5)); inset-inline-end: 50%;
  translate: 50% 0; background: var(--color-text-heading); color: var(--color-canvas);
  font-size: var(--text-tip); line-height: var(--leading-xs); font-weight: var(--weight-medium);
  padding: var(--space-0-75) var(--space-2); border-radius: var(--radius-2xs); white-space: nowrap; z-index: 10; pointer-events: none; }
/* `translate` is a physical x-axis, not a logical one, so the 50% shift above re-centres correctly
   only in ltr; under the console's default dir="rtl" it has to shift back the other way. */
[dir="rtl"] [data-tip]:hover::after, [dir="rtl"] [data-tip]:focus-visible::after { translate: -50% 0; }

/* Cross-highlight: the hovered row and the hovered column read as one intersection, table-chrome.js
   toggles .col-hi on the td/th that share the pointed-at column. */
td.col-hi, th.col-hi { background: var(--color-cross); }
.table tbody tr:hover td.col-hi { background: var(--color-cross-strong); }
thead th.col-hi { background: var(--color-cross-strong); }

.sort-link { display: inline-flex; align-items: center; gap: var(--space-1); color: inherit; text-decoration: none; }
.sort-link:hover { color: var(--color-text-heading); text-decoration: none; }
.sort-link .icon { color: var(--color-text-placeholder); opacity: 0; transition: opacity var(--fast), transform var(--fast); }
.sort-link:hover .icon { opacity: .5; }
.table th[aria-sort]:not([aria-sort="none"]) { color: var(--color-text-heading); }
.table th[aria-sort]:not([aria-sort="none"]) .sort-link .icon { opacity: 1; color: var(--color-accent); }
.table th[aria-sort="descending"] .sort-link .icon { transform: rotate(180deg); }
.table-foot { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; padding: var(--space-3) var(--space-4); border-block-start: 1px solid var(--color-border); }
.results { color: var(--color-text-muted); font-size: var(--text-num); }
.results strong { color: var(--color-text-heading); font-weight: var(--weight-semibold); }
.pager { display: flex; align-items: center; gap: var(--space-0-75); margin-inline-start: auto; }
.pager a, .pager .page { display: inline-grid; place-items: center; min-width: var(--control-xs); height: var(--control-xs); padding-inline: var(--space-2);
  border-radius: var(--radius-xs); color: var(--color-text-body); text-decoration: none; font-variant-numeric: tabular-nums; font-size: var(--text-num); }
.pager .btn-icon { min-width: var(--control-xs); height: var(--control-xs); }
.pager a:hover { background: var(--color-accent-softer); text-decoration: none; }
.pager [aria-current="page"] { background: var(--color-accent); color: var(--color-action-primary-on); font-weight: var(--weight-semibold); }
.pager [aria-disabled="true"] { opacity: 0.35; cursor: default; }
.pager .ellipsis { padding: 0 var(--space-1); color: var(--color-text-placeholder); user-select: none; }
.pager a:focus-visible, .pager .page:focus-visible, .btn:focus-visible, .icon-btn:focus-visible { box-shadow: var(--shadow-focus-ring); }
.pager-size { width: auto; padding: var(--space-1-25) var(--space-2-5); font-size: var(--text-num); color: var(--color-text-muted); }

/* ── Menus (details-based, no script) ─────────────────────────────────────── */
.menu { position: relative; }
.menu > summary { list-style: none; }
.menu > summary::-webkit-details-marker { display: none; }
.menu-panel { position: absolute; inset-block-start: calc(100% + var(--space-1-5)); inset-inline-end: 0; z-index: 30; min-width: 168px; padding: var(--space-1-25);
  background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-menu); box-shadow: var(--shadow-card); }
.menu-panel.is-flipped { inset-block-start: auto; inset-block-end: calc(100% + var(--space-1-5)); }
.menu-item { display: flex; align-items: center; gap: var(--space-2-25); width: 100%; padding: var(--space-1-75) var(--space-2-5); border: 0;
  border-radius: var(--radius-xs); background: transparent; color: var(--color-text-body); font-size: var(--text-chrome); text-align: start; text-decoration: none; cursor: pointer; }
.menu-item:hover, .menu-item[aria-current] { background: var(--color-accent-softer); text-decoration: none; }
.menu-item:focus-visible { background: var(--color-accent-soft); }
.menu-item svg { color: var(--color-text-muted); }
/* A row action keeps its button colour inside the menu (RowAction.cs writes both classes on one
   element). Both selectors are one class, so file order alone decided the winner; the compound
   selector's higher specificity decides it instead, so a later edit to either rule can't flip it
   back by accident. */
.menu-item.btn-danger-ghost { color: var(--color-danger-ghost); }
.menu-item.btn-danger-ghost svg { color: var(--color-danger-ghost); }
.menu-item[disabled], .menu-item[aria-disabled="true"] { opacity: 0.4; }
.menu-item[disabled]:hover, .menu-item[aria-disabled="true"]:hover { background: transparent; }
.menu-sep { height: 1px; margin: var(--space-1-25) var(--space-1); background: var(--color-border); }

/* ── Alerts, toast ────────────────────────────────────────────────────────── */
.alert { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-3) var(--space-4); border: 1px solid; border-radius: var(--radius-md); font-size: var(--text-sm); }
.alert svg { flex: none; margin-block-start: 2px; }
.alert-info    { background: var(--color-info-bg);    border-color: var(--blue-200); color: var(--color-info-on); }
.alert-success { background: var(--color-success-bg); border-color: transparent; color: var(--color-success-on); }
.alert-warning { background: var(--color-warning-bg); border-color: transparent; color: var(--color-warning-on); }
.alert-danger  { background: var(--color-danger-bg);  border-color: transparent; color: var(--color-danger-on); }
.alert ul { margin: 0; padding-inline-start: var(--space-4); }
.toast { position: fixed; inset-block-end: var(--space-6); inset-inline: var(--space-5); margin-inline: auto; width: fit-content; z-index: 40; max-width: 26rem;
  box-shadow: var(--shadow-pop); animation: toast-in var(--fast), toast-out 0.3s var(--ease) 6s forwards; }
@keyframes toast-in { from { opacity: 0; transform: translateY(-4px); } }
@keyframes toast-out { to { opacity: 0; visibility: hidden; } }

/* ── Empty state ──────────────────────────────────────────────────────────── */
/* Rhythm as three distinct margins, not one flex `gap`: table-reference.html:275-282 gives the art,
   the heading and the body three different trailing margins (16px, 6px, 18px) rather than one
   uniform step, so each is set on the element whose OWN trailing space it is. */
.empty { display: flex; flex-direction: column; align-items: center; text-align: center; padding: var(--space-18) var(--space-6); }
.empty svg { color: var(--color-text-muted); }
.empty .art { width: var(--size-empty-art); height: var(--size-empty-art); display: grid; place-items: center;
  border-radius: var(--radius-card); background: var(--color-accent-soft); margin-block-end: var(--space-4); }
.empty .art svg { width: var(--icon-empty); height: var(--icon-empty); color: var(--color-accent); }
.empty h3 { font-size: var(--text-empty-h); line-height: var(--leading-md); font-weight: var(--weight-bold); margin-block-end: var(--space-1-5); }
.empty p { color: var(--color-text-muted); font-size: var(--text-chrome); max-width: var(--size-empty-copy); margin-block-end: var(--space-4-5); }

/* ── Loading skeleton ─────────────────────────────────────────────────────── */
.skel { height: 12px; border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--color-border) 25%, var(--color-surface-raised) 50%, var(--color-border) 75%);
  background-size: 200% 100%; animation: shimmer 1.4s infinite linear; }
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }

/* ── Dialog ───────────────────────────────────────────────────────────────── */
.dialog { width: min(480px, calc(100% - 2 * var(--space-5))); padding: var(--space-6); border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  background: var(--color-surface); color: var(--color-text-body); box-shadow: var(--shadow-pop); }
.dialog::backdrop { background: rgb(0 0 0 / 0.4); }
.dialog h2 { margin-block-end: var(--space-2); }
.dialog p { color: var(--color-text-muted); }
.dialog .form-actions { padding-block-start: var(--space-5); }

/* ── Facts (detail pages) ─────────────────────────────────────────────────── */
.facts { display: grid; grid-template-columns: var(--form-label-width) minmax(0, 1fr); gap: var(--space-2) var(--space-4); margin: 0; }
.facts dt { color: var(--color-text-muted); }
.facts dd { margin: 0; }

/* ── Charts (server-rendered SVG) ─────────────────────────────────────────── */
.chart { display: block; width: 100%; height: auto; }
.chart text { font-size: var(--text-xs); fill: var(--color-text-muted); }
.chart .grid { stroke: var(--color-border); stroke-dasharray: 2 4; }
.chart .line { fill: none; stroke: var(--color-data-1); stroke-width: 2; }
.chart .line-2 { stroke: var(--color-data-2); }
.chart .area { fill: var(--color-data-1); fill-opacity: 0.10; }
.chart .pt circle { fill: var(--color-surface); stroke: var(--color-data-1); stroke-width: 2; }

/* ── Icons ────────────────────────────────────────────────────────────────── */
/* The five paint declarations are NOT decoration. IconSet writes no fill, stroke, stroke-width,
   stroke-linecap or stroke-linejoin onto a glyph — deliberately, so that one rule decides the weight
   of all 44 and currentColor carries the colour from whatever the glyph sits in. Without them an
   outline path renders as a solid black silhouette, which is what this page showed the first time it
   was opened. --icon-stroke is declared in tokens.css for exactly this line. */
.icon { width: var(--icon-md); height: var(--icon-md); flex: none;
  fill: none; stroke: currentColor; stroke-width: var(--icon-stroke); stroke-linecap: round; stroke-linejoin: round; }
.icon-xs { width: var(--icon-xs); height: var(--icon-xs); } .icon-sm { width: var(--icon-sm); height: var(--icon-sm); }
.icon-lg { width: var(--icon-lg); height: var(--icon-lg); } .icon-xl { width: var(--icon-xl); height: var(--icon-xl); }
[dir="rtl"] .icon-mirror { transform: scaleX(-1); }

/* ── D4: list pages ────────────────────────────────────────────────────────────────────────── */
/* The toolbar, the table card and the footer are three siblings inside .app-main (a flex column
   with a 20px gap); the negative margins close that gap so the three read as ONE card, as Preline's. */
/* D4 deliberately zeroed this seam (border-block-end: 0) to read as one continuous card.
   table-reference.html draws a hairline under its own toolbar, so the seam is restored here by
   leaving the border shorthand's own bottom edge in place — a considered reversal of that
   decision, not an oversight. */
.toolbar:has(+ .table-card, + .bulk-bar) { margin-block-end: calc(var(--space-5) * -1); background: var(--color-surface); border: 1px solid var(--color-border);
  border-start-start-radius: var(--radius-card); border-start-end-radius: var(--radius-card); box-shadow: var(--shadow-card); }
.toolbar + .table-card, .toolbar + .bulk-bar { border-start-start-radius: 0; border-start-end-radius: 0; }
/* Bulk bar as a middle segment: it joins the toolbar above it via the rule above, and here it
   closes its own gap onto whatever comes after it — the table card. */
.bulk-bar:has(+ .table-card) { margin-block-end: calc(var(--space-5) * -1); }
.bulk-bar + .table-card { border-start-start-radius: 0; border-start-end-radius: 0; }
.table-card:has(+ .table-foot) { border-end-start-radius: 0; border-end-end-radius: 0; border-block-end: 0; }
.table-card + .table-foot { margin-block-start: calc(var(--space-5) * -1); background: var(--color-surface); border: 1px solid var(--color-border);
  border-end-start-radius: var(--radius-card); border-end-end-radius: var(--radius-card); box-shadow: var(--shadow-card); }
.toolbar > button[type="submit"] { margin-inline-start: auto; }  /* Search sits at the inline end, Clear beside it */

/* The table's own features, moved off the old .grid class: a scroll box with a sticky header, the
   serial column drawn from a counter, the primary cell, the bilingual sub-line, plain codes. */
/* table-reference.html:151 — `.table-wrap { overflow-x: auto; min-height: 340px }`: page-level
   scroll, the header sticks to the viewport. The viewport cap and overflow-y an earlier pass added
   here made the header stick inside this box instead; removed now that the reference is binding. */
.table-card .scroller { min-height: var(--size-table-min); }
.table th { position: sticky; inset-block-start: 0; z-index: 2; }
.table.is-serialised { counter-reset: row var(--row-start, 0); }
.table.is-serialised thead tr::before, .table.is-serialised tbody tr::before { display: table-cell; width: 1%; padding-block: var(--space-3);
  padding-inline: var(--space-4) var(--space-2); color: var(--color-text-muted); font-variant-numeric: tabular-nums; text-align: end; white-space: nowrap;
  vertical-align: middle; border-block-end: 1px solid var(--color-border); }
.table.is-serialised thead tr::before { content: "#"; position: sticky; inset-block-start: 0; z-index: 1; background: var(--color-surface);
  font-size: var(--text-xs); line-height: var(--leading-xs); font-weight: var(--weight-medium); }
.table.is-serialised tbody tr::before { counter-increment: row; content: counter(row); }
.table.is-serialised tbody tr:last-child::before { border-block-end: 0; }
.table.is-serialised tbody tr:hover::before { background: var(--color-cross); }
.table td > a:first-child { font-weight: var(--weight-medium); color: var(--color-text-heading); }
.table td code { padding: 0; background: none; border: 0; }
/* The relative-date pair ColumnDefinition.cs's RelativeDateTime() emits: a phrase over an isolated
   absolute stamp, on table-reference.html's own .date-rel/.date-abs recipe. */
.table .date-rel { display: block; font-size: var(--text-num); }
.table .date-abs { display: block; color: var(--color-text-placeholder); font-size: var(--text-tip); font-family: var(--font-mono);
  direction: ltr; unicode-bidi: isolate; text-align: end; margin-block-start: var(--space-0-25); }

/* Toolbar fields: label above control, on the reference's column layout. The margin/width/min-height
   resets beat operator.css's .field rules, which still load after this file until D6. */
.toolbar .field { display: flex; flex-direction: column; gap: var(--space-1-25); margin: 0; }
.toolbar .field label { margin: 0; font-size: var(--text-2xs); line-height: var(--leading-xs); font-weight: var(--weight-semibold);
  color: var(--color-text-muted); white-space: nowrap; }
/* Scoped away from .toolbar-search, whose input carries its own bordered-control recipe below — this
   rule used to outrank it by loading later in the file. */
.toolbar .field:not(.toolbar-search) input, .toolbar .field:not(.toolbar-search) select { width: auto; min-width: 150px; height: var(--control-sm); min-height: 0;
  padding: var(--space-1) var(--space-3); border: 1px solid var(--color-border-strong); border-radius: var(--radius-md);
  background-color: var(--color-surface); color: var(--color-text-body); font-size: var(--text-sm); }
/* background-color, not background: the shorthand was silently erasing .form-select's own chevron
   background-image/-position/-repeat/-size on every filter select. */
.toolbar .field input:focus, .toolbar .field select:focus { background-color: var(--color-surface); border-color: var(--color-border-focus); box-shadow: var(--shadow-focus-glow); }

/* Plain panels and the validation summary. */
.card-padded { padding: var(--space-5); }
.card-padded > h2 { margin-block-end: var(--space-3); }
.card-padded > .facts, .card-padded > form { margin-block-start: var(--space-2); }
.alert.validation-summary-valid { display: none; }               /* ASP.NET renders the summary div even when valid */

/* ── D5: forms (users-add-user.html) — the page-level .field markup, on the add-user model ── */
/* A page whose form IS the page: the main column narrows to the form width and centres, and the
   crumbs, title and lede centre with it. Nothing else on such a page. */
.app-main:has(> .form-card) { max-width: calc(var(--form-width) + var(--space-6) * 2); margin-inline: auto; }
.app-main:has(> .form-card) > :is(h1, .page-lede) { text-align: center; }
.app-main:has(> .form-card) > .crumbs { justify-content: center; }

/* The form card: a card when it stands on the page; flat inside a padded card, a details, or the gate. */
.form-card { display: flex; flex-direction: column; gap: var(--space-3); max-width: var(--form-width); }
.app-main > .form-card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); }
.card-padded .form-card, details .form-card, .gate .form-card { padding: 0; }
.form-card > .btn { align-self: flex-end; margin-block-start: var(--space-2); }
.form-card > .form-actions { flex-direction: row-reverse; justify-content: flex-start; } /* pages write the primary first; Preline shows it last */

/* One .field = one add-user row: the label column, then the control, its error and its hint stacked. */
.form-card .field { display: grid; grid-template-columns: var(--form-label-width) minmax(0, 1fr); column-gap: var(--space-4); row-gap: var(--space-2); align-items: start; margin: 0; }
.form-card .field > label { grid-column: 1; }
.form-card .field > :not(label) { grid-column: 2; }
.form-card .field > p { margin: 0; font-size: var(--text-xs); line-height: var(--leading-xs); color: var(--color-text-muted); }
.form-card .field:has(> [required]) > label::after { content: " *"; color: var(--color-danger); }
.form-card .field:is(.tick, .checkbox) { display: flex; align-items: flex-start; gap: var(--space-2); padding-inline-start: calc(var(--form-label-width) + var(--space-4)); }
.form-card .field:is(.tick, .checkbox) > input { width: 16px; height: 16px; margin-block-start: 2px; flex: none; accent-color: var(--color-action-primary); }
.form-card .field:is(.tick, .checkbox) > label { padding: 0; color: var(--color-text-body); font-size: var(--text-sm); }
.form-card fieldset.field { display: block; margin: 0; padding: 0; border: 0; }
.form-card .range { display: flex; flex-direction: column; gap: var(--space-3); }
.field-validation-valid { display: none; }                        /* ASP.NET renders the error span even when valid */

/* ── D6: what only operator.css still styled, carried over; then that file is gone ─────────── */
/* Bilingual pairs: Arabic first, the Latin line under it, isolated so it never reorders the Arabic. */
[lang="en"], .bilingual .en { direction: ltr; unicode-bidi: isolate; text-align: start; }
.bilingual { display: flex; flex-direction: column; align-items: start; gap: 1px; }
.bilingual .en { color: var(--color-text-muted); font-size: var(--text-xs); line-height: var(--leading-xs); }

/* Row-action forms: a control or two and a button, inline in a table cell or a cluster. */
.row-action { display: inline-flex; align-items: center; gap: var(--space-2); margin: 0; }
.row-action :is(input:not([type="checkbox"]):not([type="hidden"]), select) { height: var(--control-sm); width: auto; min-width: 0; padding: var(--space-1) var(--space-2);
  border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-surface); color: var(--color-text-body); font-size: var(--text-sm); }
.row-action :is(input, select):focus { border-color: var(--color-border-focus); box-shadow: var(--shadow-focus); }

/* Inside a padded card: the flow between children, a section head, a disclosure. */
.card-padded > * + * { margin-block-start: var(--space-3); }
.section-head { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; padding-block-end: var(--space-3); border-block-end: 1px solid var(--color-border); }
.section-head h2 { margin: 0; margin-inline-end: auto; }
.card-padded > details { padding-block-start: var(--space-3); border-block-start: 1px solid var(--color-border); }
.card-padded > details > summary { width: fit-content; color: var(--color-text-link); cursor: pointer; }

/* Figures: a row of labelled numbers (the import report). */
.figures { display: grid; grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); gap: var(--space-4); margin: 0; }
.figures dt { color: var(--color-text-muted); font-size: var(--text-xs); line-height: var(--leading-xs); }
.figures dd { margin: var(--space-1) 0 0; font-size: var(--text-2xl); line-height: var(--leading-2xl); font-weight: var(--weight-semibold); color: var(--color-text-heading); font-variant-numeric: tabular-nums; }

/* One muted line under a form or on a status page. */
.aside { margin-block-start: var(--space-4); color: var(--color-text-muted); font-size: var(--text-sm); }

/* The gate: the signed-out layout (login, status). One card in the middle of the canvas. */
body.bare { display: flex; min-height: 100vh; align-items: center; justify-content: center; padding: var(--space-5); background: var(--color-canvas); }
.gate { display: flex; flex-direction: column; gap: var(--space-4); width: 100%; max-width: 22rem; padding: var(--space-6);
  background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); }
.gate-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); }
.wordmark { margin: 0; color: var(--color-text-muted); font-size: var(--text-sm); font-weight: var(--weight-semibold); }
[dir="ltr"] .wordmark { letter-spacing: 0.04em; text-transform: uppercase; }

/* ── D7: the facts grid takes its wrappers; page-level facts sit on a card; a toast is clickable ── */
.facts > div { display: contents; }                     /* pages write <div><dt/><dd/></div>; the grid sees dt and dd */
.facts dd .pill { margin-inline-start: var(--space-2); }
.app-main > .facts { padding: var(--space-5); background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); }
.toast { cursor: pointer; }
.toast .btn { margin-inline-start: auto; }

.field-machine:placeholder-shown { direction: inherit; unicode-bidi: normal; font-family: inherit; }  /* an Arabic placeholder in a GUID box reads as Arabic until something is typed */

/* In the 22rem gate a 136px label column is too tight: label above field, as Preline's sign-in. */
.gate .form-card .field { grid-template-columns: minmax(0, 1fr); }
.gate .form-card .field > * { grid-column: 1; }
.gate .form-card .field > label { padding-block-start: 0; }

/* ── DT-2: the shared data table — what D4's recipes did not have ─────────────────────────── */
.table .cell-check { width: var(--size-cell-check); padding-inline-start: var(--space-4); }
.table .cell-check input { width: 15px; height: 15px; margin: 0; accent-color: var(--color-action-primary); vertical-align: middle; }
.table .cell-check input:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.table tr.is-selected td { background: var(--color-selected); }
/* Three classes (.table, tbody, tr.is-selected, :hover — (0,3,3)) beats the plain hover rule's two
   (0,2,3) structurally, so a selected row keeps its tint under a pointer that never left it — the
   normal case right after ticking its own checkbox — whichever rule happens to be written first. */
.table tbody tr.is-selected:hover td { background: var(--color-selected); }
.table.is-dense th { padding-block: var(--space-2); }
.table.is-dense td { padding-block: var(--space-2); }
/* The toolbar's search. NOT .search-field — that one is the topbar's, and is a link with a hint
   rather than a control. Like every other .field the label sits visibly above the control — this
   element is BOTH .field and .toolbar-search, so .toolbar .field's own column layout (D4, above)
   already stacks label over control; nothing here re-declares display/flex-direction, or it would
   fight that rule instead of relying on it. The magnifier and the clear glyph are siblings of the
   label and the input (Default.cshtml), not wrapped in a sub-element of their own, so they are taken
   out of that column with position:absolute and pinned to the input's own row by inset-block-end plus
   a height equal to the control's — deliberately not table-reference.html's own top:50%/translate
   trick on the .search wrapper, which resolves against the WHOLE field's height (label included) and
   only happens to land inside the input there; anchoring from the shared bottom edge holds regardless
   of how long the label is. */
.toolbar-search { position: relative; flex: 1 1 18rem; max-width: 28rem; }
.toolbar-search > .icon { position: absolute; inset-inline-start: var(--space-3);
  inset-block-end: calc((var(--control-sm) - var(--icon-btn)) / 2); width: var(--icon-btn); height: var(--icon-btn);
  color: var(--color-text-placeholder); pointer-events: none; }
.toolbar-search input { width: 100%; height: var(--control-sm); padding-inline: var(--space-8);
  border: 1px solid var(--color-border-strong); border-radius: var(--radius-md); background: var(--color-surface);
  color: var(--color-text-body); font: inherit; font-size: var(--text-sm); }
.toolbar-search input::placeholder { color: var(--color-text-placeholder); }
.toolbar-search input:focus { border-color: var(--color-border-focus); box-shadow: var(--shadow-focus-glow); }
.toolbar [data-auto-apply-hint] { color: var(--color-text-placeholder); }
.toolbar-search .search-clear { position: absolute; inset-inline-end: var(--space-3); inset-block-end: 0;
  height: var(--control-sm); display: inline-flex; align-items: center; color: var(--color-text-muted); }
.toolbar-search .search-clear:hover { color: var(--color-text-body); }
.toolbar-search .search-clear .icon { width: var(--icon-btn); height: var(--icon-btn); }
.field-pair { display: flex; align-items: center; gap: var(--space-2); }
.pager-size-form { display: inline-flex; align-items: center; gap: var(--space-2); }
.pager-size-form label { font-size: var(--text-num); color: var(--color-text-muted); }
.bulk-bar { display: flex; align-items: center; gap: var(--space-3-5); padding: var(--space-2-25) var(--space-4);
  background: var(--color-selected); border-block-end: 1px solid var(--color-border); font-size: var(--text-chrome); }
.bulk-bar[hidden] { display: none; }
.bulk-bar-count { font-weight: var(--weight-semibold); color: var(--color-accent-ink); }
/* The count digit sits in its own <strong> (Default.cshtml, for `data-bulk-count` to update); the
   UA stylesheet's `strong { font-weight: bolder }` then resolves against the 600 around it to 900
   (the bolder-keyword table: 600-699 -> 900), which is why the digit renders visibly heavier than
   "selected" beside it. table-reference.html carries no <strong> at all — its whole count string is
   one weight, 600 — so this un-does the UA rule rather than matching a rule that isn't there. */
.bulk-bar-count strong { font-weight: inherit; }
.spacer { flex: 1; }
/* Column priorities: the responsive rule. 1 always · 2 tablet and up · 3 desktop only. The key
   column and the actions cell are always 1. This is the responsive design — not a sideways
   scrollbar, which the .scroller already provides for whatever remains. */
@media (max-width: 991px) { .table .col-p3 { display: none; } }
@media (max-width: 767px) { .table .col-p2 { display: none; }
  .table-foot { flex-direction: column; align-items: stretch; }
  .table-foot .results { margin-inline-end: 0; }
  .toolbar-search { flex-basis: 100%; max-width: none; } }

/* ── SEL-1: the entity picker ─────────────────────────────────────────────── */
/* The field is a positioned box so the listbox can hang under it on the .menu-panel recipe. That
   is the one positioning decision here and it is only safe because pickers live in forms: an
   absolute panel inside .scroller would be clipped by the scroll box, which is why the table's
   menus are the only other user of the recipe and why no picker may be put in a cell. */
.picker { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.picker > input { flex: 1 1 240px; min-width: 0; }
.picker-find { flex: none; }
/* Width and scroll are this component's; surface, border, radius, shadow and z-index are the
   recipe's, so a menu and a suggestion list cannot drift apart. */
.picker-list { inset-inline: 0; max-height: 280px; overflow-y: auto; margin: 0; list-style: none; }
.picker-option { display: flex; flex-direction: column; align-items: start; gap: 2px;
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-md); cursor: pointer; }
.picker-option:hover, .picker-option.is-active { background: var(--color-surface-sunken); }
.picker-sub { color: var(--color-text-muted); font-size: var(--text-xs); line-height: var(--leading-xs); }
