/* components.css — the component library (specs/design/frontend-property.md).
   Banking components are lifted from specs/design/reference/css/components.css;
   back-office components are new, in the same token language. */

/* ---------- Buttons (banking §5.1) ---------------------------------------
   Deviation: width is auto by default (a back office has many inline
   buttons); .btn--block restores the banking full width. */
.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  min-height:44px; padding:0 18px; border-radius:var(--radius-md);
  font-size:15px; font-weight:600; line-height:1.2; text-decoration:none;
  white-space:nowrap; border:1px solid transparent;
  transition: transform var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.btn:active { transform: scale(.98); }
.btn[disabled], .btn[aria-disabled="true"] { opacity:.45; pointer-events:none; }
.btn--primary     { background:var(--brand); color:var(--on-brand); }
.btn--primary:hover { background:var(--brand-hover); }
.btn--secondary   { background:var(--surface); color:var(--text); border-color:var(--border-strong); }
.btn--secondary:hover { background:var(--surface-2); }
.btn--ghost       { background:transparent; color:var(--brand); padding:0 10px; }
.btn--ghost:hover { background:var(--brand-subtle); }
.btn--destructive { background:var(--danger-bg); color:var(--danger); border-color:var(--danger); }
.btn--sm    { min-height:36px; padding:0 12px; font-size:14px; }
.btn--block { width:100%; }
.btn__spinner {
  width:16px; height:16px; border:2px solid currentColor; border-top-color:transparent;
  border-radius:50%; animation: spin .7s linear infinite; flex:none;
}
@keyframes spin { to { transform: rotate(360deg); } }
.btn-row { display:flex; flex-wrap:wrap; gap:var(--space-3); align-items:center; }

/* Shared 44px circular icon button (banking). */
.icon-btn, .banner__dismiss {
  width:44px; height:44px; display:inline-flex; align-items:center; justify-content:center;
  border-radius:var(--radius-full); flex:none; color:var(--text-muted);
}
.icon-btn:hover { background:var(--surface-2); }

/* ---------- Amounts (banking §5.2). Sign is in the text; colour adds. --- */
.amount { font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1; white-space:nowrap; font-weight:600; }
.amount--lg { font-size:22px; line-height:1.2; }
.amount--credit { color:var(--credit); }
.amount--debit  { color:var(--debit); }

/* ---------- Chips (banking §5.4). Always carry a text label. ----------- */
.chip {
  display:inline-block; padding:3px 10px; border-radius:var(--radius-full);
  font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  background:var(--surface-2); color:var(--text-muted); white-space:nowrap; line-height:1.5;
}
.chip--ok     { background:var(--ok-bg);     color:var(--ok); }
.chip--warn   { background:var(--warn-bg);   color:var(--warn); }
.chip--danger { background:var(--danger-bg); color:var(--danger); }
.chip--info   { background:var(--info-bg);   color:var(--brand); }
.chip--muted  { background:var(--surface-2); color:var(--text-muted); }

/* ---------- Switch and segmented control (banking §7.6) ----------------- */
.switch { width:44px; height:26px; border-radius:var(--radius-full); background:var(--border-strong); padding:2px; flex-shrink:0; }
.switch[aria-checked="true"] { background:var(--brand); }
.switch__thumb { display:block; width:22px; height:22px; border-radius:50%; background:var(--surface);
  transition:transform var(--dur-fast) var(--ease); }
.switch[aria-checked="true"] .switch__thumb { transform:translateX(18px); }
.segmented { display:inline-flex; background:var(--surface-2); border-radius:var(--radius-md); padding:2px; gap:2px; }
.segmented__option { min-height:36px; padding:0 14px; border-radius:calc(var(--radius-md) - 2px);
  font-size:14px; font-weight:600; color:var(--text-muted); }
.segmented__option[aria-checked="true"], .segmented__option[aria-pressed="true"] { background:var(--surface); color:var(--text); }

/* ---------- Grouped list and rows (banking §5.5) ----------------------- */
.list { background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg); overflow:hidden; }
.row {
  display:flex; align-items:center; gap:12px; min-height:60px;
  padding:12px var(--space-4); position:relative; width:100%; text-align:left;
  background:none; color:inherit; text-decoration:none;
  transition: background-color var(--dur-fast) var(--ease);
}
.row + .row::before { content:""; position:absolute; top:0; left:var(--space-4); right:0; height:1px; background:var(--border); }
a.row:hover, button.row:hover { background:var(--surface-2); }
.row__icon { width:40px; height:40px; border-radius:10px; display:flex; align-items:center; justify-content:center;
  background:var(--brand-subtle); color:var(--brand); flex:none; }
.row__main { flex:1 1 auto; min-width:0; }
.row__title { display:block; font-size:15px; font-weight:600; line-height:1.4; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.row__meta { display:block; font-size:13px; line-height:1.4; color:var(--text-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.row__end { flex:none; color:var(--text-subtle); display:flex; align-items:center; gap:8px; }

/* A list inside a card: the card already draws the edge and shadow. */
.list.list--flush { border:0; border-radius:0 0 var(--radius-lg) var(--radius-lg); box-shadow:none; }

/* Rules and defaults rows (F04): label + note, then value and source. */
.rule-row__value { display:flex; align-items:center; justify-content:flex-end; gap:10px; flex:none; max-width:45%; min-width:0; }
.rule-row__text { font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; font-variant-numeric:tabular-nums; }
@media (max-width: 767.98px) {
  .rule-row { flex-wrap:wrap; }
  .rule-row .row__main { flex-basis:calc(100% - 40px); }
  .rule-row__value { order:3; max-width:none; width:100%; justify-content:flex-start; }
}

/* ---------- Inline banner (banking §5.11) ------------------------------ */
.banner {
  display:flex; gap:12px; align-items:flex-start; padding:12px 14px; border-radius:var(--radius-md);
  border:1px solid var(--border); background:var(--surface-2); font-size:15px; line-height:1.45;
}
.banner--info    { background:var(--info-bg);   border-color:color-mix(in oklab,var(--brand),transparent 70%); }
.banner--success { background:var(--ok-bg);     border-color:color-mix(in oklab,var(--ok),transparent 70%); color:var(--ok); }
.banner--warn    { background:var(--warn-bg);   border-color:color-mix(in oklab,var(--warn),transparent 70%); color:var(--warn); }
.banner--danger  { background:var(--danger-bg); border-color:color-mix(in oklab,var(--danger),transparent 70%); color:var(--danger); }
.banner > .icon { margin-top:2px; }
.banner__body { flex:1 1 auto; min-width:0; }
.banner__body p { margin:0; }
.banner__dismiss { margin:-10px -10px -10px auto; color:inherit; }
.banner__dismiss:hover { background:rgba(0,0,0,.06); }
.messages { display:flex; flex-direction:column; gap:var(--space-2); margin-bottom:var(--space-4); }

/* ---------- Empty state and skeleton (banking §5.9, §5.10) ------------- */
.empty { text-align:center; padding:40px 24px; }
.empty .icon { width:40px; height:40px; color:var(--text-subtle); margin-bottom:12px; }
.empty__title { font-size:17px; font-weight:600; margin:0 0 4px; }
.empty__body { font-size:15px; color:var(--text-muted); margin:0 auto 16px; max-width:40ch; }
.empty + .btn-row { justify-content:center; padding:0 24px 32px; }
.skeleton {
  background: linear-gradient(90deg, var(--surface-2) 25%, color-mix(in oklab, var(--surface-2), var(--text) 6%) 37%, var(--surface-2) 63%);
  background-size:400% 100%; animation: shimmer 1.4s ease infinite; border-radius:var(--radius-sm);
}
@keyframes shimmer { 0%{background-position:100% 0} 100%{background-position:0 0} }
.skeleton--line { height:14px; }
.skeleton--short { width:60%; }

/* ---------- Page header and breadcrumbs (new) -------------------------- */
.page-head { margin-bottom:var(--space-5); }
.page-head__row { display:flex; flex-wrap:wrap; align-items:flex-end; justify-content:space-between; gap:var(--space-3) var(--space-6); }
.page-head__text { min-width:0; }
.page-head__title { font-size:24px; font-weight:700; letter-spacing:-.01em; }
.page-head__lede { margin:4px 0 0; color:var(--text-muted); font-size:15px; }
.page-head__actions { display:flex; flex-wrap:wrap; gap:var(--space-2); }
.breadcrumbs ol { display:flex; flex-wrap:wrap; gap:6px; list-style:none; margin:0 0 6px; padding:0; font-size:13px; color:var(--text-muted); }
.breadcrumbs li + li::before { content:"/"; margin-right:6px; color:var(--text-subtle); }
.breadcrumbs a { color:inherit; text-decoration:none; }
.breadcrumbs a:hover { color:var(--brand); text-decoration:underline; }

/* ---------- Card (new; CRM .card) ------------------------------------- */
.card { background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg); }
.card + .card, .card + .stack, .stack + .card { margin-top:var(--space-5); }
.card__head { display:flex; align-items:center; justify-content:space-between; gap:var(--space-3);
  padding:var(--space-4) var(--space-5); border-bottom:1px solid var(--border); }
.card__title { font-size:16px; font-weight:700; }
.card__body { padding:var(--space-5); }
.card__foot { padding:var(--space-3) var(--space-5); border-top:1px solid var(--border); }
.input--num { text-align:right; font-variant-numeric:tabular-nums; max-width:11rem; margin-left:auto; }
.stack { display:flex; flex-direction:column; gap:var(--space-5); }
/* The gap spaces them. Same specificity as .card + .card above, and later, so it wins. */
.stack > .card, .stack > .stack, .grid-2 > .card, .grid-2 > .stack { margin-top:0; }
.grid-2 { display:grid; gap:var(--space-5); }
@media (min-width: 1200px) { .grid-2 { grid-template-columns:repeat(2, minmax(0,1fr)); } }

/* Definition rows: label / value pairs on detail screens. */
.dl { display:grid; grid-template-columns:minmax(120px, 40%) 1fr; gap:10px var(--space-4); margin:0; font-size:15px; }
.dl dt { color:var(--text-muted); }
.dl dd { margin:0; font-weight:500; overflow-wrap:anywhere; }

/* ---------- Stat tiles (banking desktop .kpi, made responsive) --------- */
.kpis { display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:var(--space-3); }
@media (min-width: 1200px) { .kpis { grid-template-columns:repeat(4, minmax(0,1fr)); gap:var(--space-4); } }
.kpi {
  display:grid; grid-template-columns:auto 1fr; grid-template-areas:"icon label" "value value" "meta meta";
  align-items:center; column-gap:10px; row-gap:8px; padding:16px; min-width:0;
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg);
  border-top:3px solid var(--brand);
}
.kpi--alert { border-top-color:var(--warn); }
a.kpi--link { color:inherit; text-decoration:none; transition:background-color var(--dur-fast) var(--ease); }
a.kpi--link:hover { background:var(--surface-2); }
.kpi__icon { grid-area:icon; width:36px; height:36px; border-radius:10px; display:flex; align-items:center; justify-content:center;
  background:var(--brand-subtle); color:var(--brand); }
.kpi--alert .kpi__icon { background:var(--warn-bg); color:var(--warn); }
.kpi__label { grid-area:label; font-size:12px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--text-muted); min-width:0; }
.kpi__value { grid-area:value; font-size:22px; font-weight:700; line-height:1.2; font-variant-numeric:tabular-nums; overflow-wrap:anywhere; }
.kpi__meta { grid-area:meta; font-size:13px; color:var(--text-muted); }
.kpi .kpi__value--sm { font-size:17px; } /* names and date ranges rather than figures */
/* Money tiles hold "KES 1,234,567.00": one per row on phones so it never wraps. */
@media (max-width: 599.98px) { .kpis--money { grid-template-columns:minmax(0,1fr); } }

/* ---------- Tabs (new) ------------------------------------------------- */
.tabs { display:flex; gap:4px; border-bottom:1px solid var(--border); margin-bottom:var(--space-5); overflow-x:auto; scrollbar-width:none; }
.tabs__item { padding:10px 14px; font-size:14px; font-weight:600; color:var(--text-muted); text-decoration:none;
  border-bottom:3px solid transparent; margin-bottom:-1px; white-space:nowrap; }
.tabs__item:hover { color:var(--text); }
.tabs__item[aria-current="page"] { color:var(--brand); border-bottom-color:var(--brand); }
.tabs__count { margin-left:6px; padding:1px 7px; border-radius:var(--radius-full); background:var(--surface-2);
  font-size:12px; color:var(--text-muted); font-variant-numeric:tabular-nums; }
.property-settings__lede { margin:0 0 var(--space-4); }

/* ---------- Filter bar (banking .stmt-filter, generalised) ------------- */
.filter-bar { display:flex; flex-wrap:wrap; align-items:flex-end; gap:var(--space-3); padding:var(--space-4);
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg); margin-bottom:var(--space-4); }
.filter-bar__field { flex:1 1 160px; min-width:0; display:flex; flex-direction:column; gap:6px; }
.filter-bar__field--search { flex:2 1 240px; }
.filter-bar label { font-size:12px; font-weight:600; color:var(--text); }
.filter-bar .btn-row { flex:none; }
.search { position:relative; }
.search .icon { position:absolute; left:12px; top:50%; transform:translateY(-50%); color:var(--text-subtle); pointer-events:none; }
.search .input { padding-left:40px; }

/* ---------- Data table (banking .ledger, extended) --------------------- */
.table-wrap { background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg); overflow-x:auto; }
.card > .table-wrap { border:0; border-radius:0 0 var(--radius-lg) var(--radius-lg); }
.data-table { width:100%; border-collapse:collapse; font-size:14px; }
.data-table th, .data-table td { padding:12px 16px; text-align:left; vertical-align:middle; border-bottom:1px solid var(--border); }
.data-table tbody tr:last-child td { border-bottom:0; }
.data-table thead th { font-size:11px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--text-muted);
  background:var(--surface-2); white-space:nowrap; }
.data-table tbody tr:hover { background:color-mix(in oklab, var(--surface-2), transparent 40%); }
.data-table .num { text-align:right; white-space:nowrap; font-variant-numeric:tabular-nums; }
.data-table .actions { text-align:right; white-space:nowrap; }
.data-table__primary { font-weight:600; }
.cell-link { color:var(--text); font-weight:600; text-decoration:none; }
.cell-link:hover { color:var(--brand); text-decoration:underline; }
.cell-meta { display:block; font-size:12px; color:var(--text-muted); font-weight:400; }
.sort { display:inline-flex; align-items:center; gap:4px; color:inherit; text-decoration:none; }
.sort:hover { color:var(--text); }
.sort .icon { width:14px; height:14px; opacity:.35; }
th[aria-sort] .sort { color:var(--text); }
th[aria-sort] .sort .icon { opacity:1; }
th[aria-sort="descending"] .sort .icon { transform:rotate(180deg); }
.data-table__empty td { padding:0; }
.data-table tfoot td, .data-table tfoot th { font-weight:700; background:var(--surface-2); border-top:1px solid var(--border-strong); }

/* Phones: each row becomes a card; labels come from data-label. */
@media (max-width: 767.98px) {
  .table-wrap { background:transparent; border:0; overflow:visible; }
  .card > .table-wrap { padding:var(--space-3); }
  .data-table--stack thead { display:none; }
  .data-table--stack, .data-table--stack tbody, .data-table--stack tr, .data-table--stack td { display:block; width:100%; }
  .data-table--stack tr { background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-md);
    padding:12px 14px; margin-bottom:10px; }
  .data-table--stack tbody tr:hover { background:var(--surface); }
  .data-table--stack td { display:flex; justify-content:space-between; align-items:baseline; gap:12px;
    padding:4px 0; border:0; text-align:right; }
  .data-table--stack td::before { content:attr(data-label); color:var(--text-muted); font-size:13px; font-weight:600; text-align:left; flex:none; }
  .data-table--stack td.data-table__primary { display:block; font-size:15px; text-align:left; padding-bottom:8px; }
  .data-table--stack td.data-table__primary::before, .data-table--stack td:not([data-label])::before { display:none; }
  .data-table--stack td.actions { justify-content:flex-end; padding-top:8px; }
  .data-table--stack tfoot { display:block; }
  .data-table--stack tfoot tr { background:var(--surface-2); }
  .data-table--stack tfoot th { display:block; padding:0 0 6px; border:0; background:none; text-align:left; }
  .data-table--stack tfoot td { background:none; }
  .data-table--stack tfoot td:empty { display:none; }
  .data-table--stack .data-table__empty { border:0; background:transparent; padding:0; }
}

/* ---------- Pagination (new) ------------------------------------------- */
.pagination { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:var(--space-3);
  margin-top:var(--space-4); font-size:14px; color:var(--text-muted); }
.pagination__links { display:flex; gap:var(--space-2); }

/* ---------- Forms (new; inputs from banking .field) -------------------- */
.form { max-width:880px; }
.form-grid { display:grid; grid-template-columns:minmax(0,1fr); gap:var(--space-4) var(--space-5); }
@media (min-width: 768px) { .form-grid { grid-template-columns:repeat(2, minmax(0,1fr)); } }
.form-field { display:flex; flex-direction:column; gap:6px; min-width:0; }
.form-field--full, .form-field:has(textarea) { grid-column:1 / -1; }
.form-field > label, .form-field legend { font-size:14px; font-weight:600; color:var(--text); }
.form-field__req { color:var(--danger); margin-left:2px; }
.form-field__help { margin:0; font-size:13px; color:var(--text-muted); }
.form-field__error { margin:0; font-size:13px; font-weight:600; color:var(--danger); }
.form-field fieldset { border:0; padding:0; margin:0; min-width:0; }
.input,
.form-field :is(input:not([type=checkbox], [type=radio], [type=hidden], [type=file]), select, textarea) {
  width:100%; min-height:48px; padding:12px 14px;
  border:1px solid var(--border-strong); border-radius:var(--radius-md);
  background:var(--surface); color:var(--text); font-size:16px;
}
.form-field textarea { min-height:104px; height:8.5em; resize:vertical; }
.input::placeholder, .form-field ::placeholder { color:var(--text-subtle); }
.input:focus,
.form-field :is(input, select, textarea):focus { outline:none; border-color:var(--brand); box-shadow:0 0 0 1px var(--brand); }
.form-field.form-field--error :is(input, select, textarea) { border-color:var(--danger); }
select.input, .form-field select {
  appearance:none; padding-right:40px; background-repeat:no-repeat; background-position:right 12px center; background-size:16px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748B' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}
.form-field input[type=checkbox], .form-field input[type=radio] { width:20px; height:20px; accent-color:var(--brand); margin:0; flex:none; }
.form-field--check { flex-direction:row; flex-wrap:wrap; align-items:center; gap:10px; }
.form-field--check > label { font-weight:500; }
.form-field--check .form-field__help, .form-field--check .form-field__error { flex-basis:100%; padding-left:30px; }
/* Radio and checkbox groups: Django 5 renders <div><div><label><input> text</label></div>…</div>. */
.form-field fieldset > div { display:flex; flex-direction:column; gap:4px; margin-top:8px; }
.form-field fieldset label { display:flex; align-items:center; gap:10px; min-height:32px; font-size:15px; font-weight:500; cursor:pointer; }
.form-field input[type=file] { font-size:14px; }
.form-section { border:0; padding:0; margin:0 0 var(--space-6); }
.form-section__title { font-size:16px; font-weight:700; margin-bottom:var(--space-3); padding:0; }
.form-actions { display:flex; flex-wrap:wrap; gap:var(--space-3); margin-top:var(--space-6); }
.form-errors { margin-bottom:var(--space-4); }
.formset-row + .formset-row { margin-top:var(--space-4); padding-top:var(--space-4); border-top:1px dashed var(--border); }
@media (min-width: 768px) { .formset-row .form-grid { grid-template-columns:2fr 1fr 2fr; } }
.plain-list { margin:8px 0 0; padding-left:18px; font-size:14px; color:var(--text-muted); }
@media (max-width: 767.98px) {
  .form-actions { flex-direction:column-reverse; }
  .form-actions .btn { width:100%; }
}

/* ---------- Menus: native <details> with a list panel (banking D62) ---- */
.menu { position:relative; }
.menu > summary { list-style:none; cursor:pointer; }
.menu > summary::-webkit-details-marker { display:none; }
.menu__panel { position:absolute; top:100%; right:0; margin-top:8px; min-width:200px; padding:6px 0; z-index:25;
  background:var(--surface); color:var(--text); border:1px solid var(--border); border-radius:var(--radius-md); box-shadow:var(--shadow-dialog); }
.menu__head { margin:0; padding:8px 16px 6px; font-size:11px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--text-muted); }
.menu__item { display:flex; align-items:center; gap:10px; width:100%; min-height:40px; padding:8px 16px; font-size:14px;
  color:var(--text); text-decoration:none; text-align:left; }
.menu__item:hover { background:var(--surface-2); }
.menu__check { margin-left:auto; visibility:hidden; color:var(--brand); }
.menu__item[aria-checked="true"] { font-weight:600; }
.menu__item[aria-checked="true"] .menu__check { visibility:visible; }
.menu__sep { border:0; border-top:1px solid var(--border); margin:6px 0; }
.menu__user { display:flex; flex-direction:column; padding:8px 16px; min-width:220px; }
.menu__user-name { font-weight:700; font-size:15px; }
.menu__user-meta { font-size:13px; color:var(--text-muted); }
.menu form { margin:0; }

/* Initials avatar in the top bar (F03). */
.avatar { width:32px; height:32px; border-radius:50%; display:inline-flex; align-items:center; justify-content:center;
  font-size:13px; font-weight:700; letter-spacing:.02em; background:rgba(255,255,255,.16); color:inherit; }

/* A secret shown once (temporary passwords): large, monospace, selectable. */
.secret { margin:6px 0 0; padding:14px 16px; border-radius:var(--radius-md); background:var(--surface-2);
  font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:24px; font-weight:700;
  letter-spacing:.06em; user-select:all; overflow-wrap:anywhere; }
/* A long address to copy (F27: the M-Pesa receiving address in the console). */
.address { font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:14px;
  user-select:all; overflow-wrap:anywhere; }
.logo-preview { display:flex; align-items:center; gap:12px; margin-top:var(--space-4); }
.logo-preview img { border-radius:var(--radius-sm); border:1px solid var(--border); background:#FFFFFF; object-fit:contain; }

/* ---------- Confirmation dialog (new; native <dialog>) ----------------- */
.dialog { border:0; padding:0; border-radius:var(--radius-lg); background:var(--surface); color:var(--text);
  width:min(440px, calc(100vw - 32px)); box-shadow:var(--shadow-dialog); }
.dialog::backdrop { background:rgba(15,23,42,.55); }
.dialog__body { padding:var(--space-6); margin:0; }
.dialog__title { font-size:18px; font-weight:700; margin-bottom:8px; }
.dialog__text { margin:0 0 var(--space-6); color:var(--text-muted); white-space:pre-line; }
.dialog__actions { display:flex; justify-content:flex-end; gap:var(--space-3); flex-wrap:wrap; }

/* ---------- HTMX request indicator (htmx's own styles are off: CSP) ---- */
.htmx-indicator { opacity:0; transition:opacity var(--dur) var(--ease); }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { opacity:1; }
.htmx-request.table-wrap, .htmx-request .table-wrap { opacity:.6; transition:opacity var(--dur) var(--ease); }

/* ---------- Gallery-only helpers -------------------------------------- */
.swatches { display:flex; flex-wrap:wrap; gap:var(--space-3); }
.swatch { width:120px; font-size:12px; color:var(--text-muted); }
.swatch__chip { height:44px; border-radius:var(--radius-md); border:1px solid var(--border); margin-bottom:6px; }
.swatch--brand .swatch__chip { background:var(--brand); }
.swatch--surface .swatch__chip { background:var(--surface); }
.swatch--surface-2 .swatch__chip { background:var(--surface-2); }
.swatch--bg .swatch__chip { background:var(--bg); }
.swatch--ok .swatch__chip { background:var(--ok); }
.swatch--warn .swatch__chip { background:var(--warn); }
.swatch--danger .swatch__chip { background:var(--danger); }
.swatch--text .swatch__chip { background:var(--text); }

/* ---------- Print (F10 receipts): the page, not the app around it ------ */
@media print {
  .skip-link, .app-bar, .nav, .app-footer, .breadcrumbs, .page-head, .messages, .no-print { display:none !important; }
  html, body, .app-shell, .content, .page { background:#fff !important; color:#000 !important; }
  .app-shell { display:block !important; }
  .content, .page { padding:0 !important; margin:0 !important; max-width:none !important; }
  .card { box-shadow:none !important; border:0 !important; }
}

/* ---------- Water readings (F13) ---------------------------------------- */
.readings-table .correction { margin-top:6px; text-align:left; }
.readings-table .correction summary { cursor:pointer; color:var(--text-muted); }
.readings-table .correction .input { margin:2px 0 6px; }
.readings-table .row--error td { background:var(--danger-bg); }

/* SMS log (F18) */
.sms-text { display:block; max-width:46ch; font-size:13px; color:var(--text-muted); }

/* ---------- Reports (F20) --------------------------------------------- */
.report-notes { margin:0; padding-left:20px; color:var(--text-muted); font-size:14px; }
.report-notes li + li { margin-top:6px; }
.audit-value { overflow-wrap:anywhere; font-variant-numeric:tabular-nums; }

/* ---------- Picker: a dropdown with a search box (F25, picker.js) ------ */
.picker { position:relative; min-width:0; }
.picker__trigger { display:flex; align-items:center; gap:8px; text-align:left; cursor:pointer; }
.picker__value { flex:1 1 auto; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.picker__value--placeholder { color:var(--text-subtle); }
.picker__chevron { flex:none; color:var(--text-subtle); transition:transform .15s ease; }
.picker.is-open .picker__chevron { transform:rotate(180deg); }
.picker.is-open .picker__trigger { border-color:var(--brand); box-shadow:0 0 0 1px var(--brand); }
.picker__trigger:disabled { cursor:not-allowed; opacity:.6; }
.form-field.form-field--error .picker__trigger { border-color:var(--danger); }
.picker__panel { position:absolute; left:0; right:0; top:100%; margin-top:6px; z-index:30; min-width:min(320px, 92vw);
  display:flex; flex-direction:column; padding:8px; background:var(--surface); color:var(--text);
  border:1px solid var(--border); border-radius:var(--radius-md); box-shadow:var(--shadow-dialog); }
.picker__panel[hidden], .picker__backdrop[hidden] { display:none; }
.picker__panel--up { top:auto; bottom:100%; margin:0 0 6px; }
.picker__head { display:none; }
/* Beats the form-field input rule, which would undo the icon's padding. */
.picker .picker__search input.input { min-height:42px; padding:9px 14px 9px 40px; }
.picker__search .input::-webkit-search-cancel-button { cursor:pointer; }
.picker__status { margin:8px 6px 4px; font-size:12px; color:var(--text-muted); }
.picker__status--empty { font-size:14px; color:var(--text); padding:8px 0; }
.picker__list { list-style:none; margin:0; padding:0; max-height:288px; overflow-y:auto; overscroll-behavior:contain; }
.picker__option { display:flex; align-items:center; gap:10px; min-height:42px; padding:8px 10px; border-radius:var(--radius-sm);
  font-size:14px; line-height:1.35; cursor:pointer; }
.picker__option:hover { background:var(--surface-2); }
/* The keyboard cursor: a bar as well as a tint, so it never relies on colour. */
.picker__option.is-active { background:var(--surface-2); box-shadow:inset 3px 0 0 var(--brand); }
.picker__option[aria-selected="true"] { font-weight:600; }
.picker__option[aria-disabled="true"] { color:var(--text-subtle); cursor:not-allowed; }
.picker__text { flex:1 1 auto; min-width:0; overflow-wrap:anywhere; }
.picker__check { visibility:hidden; color:var(--brand); }
.picker__option[aria-selected="true"] .picker__check { visibility:visible; }
.picker__box { display:inline-flex; align-items:center; justify-content:center; flex:none; width:20px; height:20px;
  border:1.5px solid var(--border-strong); border-radius:5px; color:var(--on-brand); }
.picker__box .icon { visibility:hidden; width:14px; height:14px; }
.picker__option[aria-selected="true"] .picker__box { background:var(--brand); border-color:var(--brand); }
.picker__option[aria-selected="true"] .picker__box .icon { visibility:visible; }
.picker__foot { display:flex; justify-content:flex-end; margin-top:6px; padding-top:8px; border-top:1px solid var(--border); }
.picker__chips { display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
.picker__chips:empty { display:none; }
.picker__chip { display:inline-flex; align-items:center; gap:2px; max-width:100%; padding:2px 2px 2px 10px;
  border-radius:var(--radius-full); background:var(--info-bg); color:var(--brand); font-size:13px; font-weight:600; }
.picker__chip-text { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.picker__chip-remove { display:inline-flex; align-items:center; justify-content:center; flex:none; width:28px; height:28px;
  border-radius:50%; color:inherit; }
.picker__chip-remove:hover { background:var(--surface-2); }
.picker__chip-remove .icon { width:14px; height:14px; }
.picker__error { margin:6px 0 0; }
.picker__backdrop { display:none; }

/* Phones: the list is a sheet from the bottom, search box at its top. */
@media (max-width: 767.98px) {
  .picker__backdrop:not([hidden]) { display:block; position:fixed; inset:0; z-index:60; background:rgba(15,23,42,.5); }
  .picker__panel, .picker__panel--up { position:fixed; left:0; right:0; top:auto; bottom:0; margin:0; z-index:61;
    min-width:0; max-height:85vh; max-height:85dvh; padding:6px 16px calc(12px + env(safe-area-inset-bottom));
    border:0; border-radius:var(--radius-xl) var(--radius-xl) 0 0; }
  .picker__head { display:flex; align-items:center; justify-content:space-between; gap:8px; min-height:48px; }
  .picker__title { font-size:16px; font-weight:700; }
  .picker__list { flex:1 1 auto; min-height:0; max-height:none; }
  .picker__option { min-height:48px; font-size:15px; }
  html.picker-open .content { overflow:hidden; }
}

/* Simulate data (F28): counts and a native progress bar (text carries the meaning too). */
.sim-counts { display:grid; grid-template-columns:repeat(auto-fit, minmax(110px, 1fr)); gap:var(--space-3); margin:0; }
.sim-counts div { background:var(--surface-2); border-radius:var(--radius-md); padding:10px 12px; }
.sim-counts dt { font-size:13px; color:var(--text-muted); }
.sim-counts dd { margin:2px 0 0; font-size:22px; font-weight:700; font-variant-numeric:tabular-nums; }
.sim-progress__label { font-weight:600; }
.sim-progress { width:100%; height:12px; appearance:none; border:0; border-radius:var(--radius-full); background:var(--surface-2); overflow:hidden; }
.sim-progress::-webkit-progress-bar { background:var(--surface-2); border-radius:var(--radius-full); }
.sim-progress::-webkit-progress-value { background:var(--brand); border-radius:var(--radius-full); }
.sim-progress::-moz-progress-bar { background:var(--brand); border-radius:var(--radius-full); }

/* Simulation in the console (F29): one block per demo organisation. */
.sim-demo + .sim-demo { border-top:1px solid var(--border); padding-top:var(--space-4); }
.sim-demo h3 { display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-2); margin:0; }
