/* ===========================================================================
   ARDITO — components
   Built on ardito-tokens.css. Every value here is a token; there are no raw
   hexes below this line by design, so a re-skin is a token change, not a sweep.

   Written 2026-08-30. The audit found the same component existing in up to 15
   slightly different versions per app: 13 pill vocabularies with ~70 modifier
   classes in the PT portal alone, 12 button systems, 8 card implementations,
   19 names for "callout". This file is the one version.
   =========================================================================== */

/* ── Reset-ish base ─────────────────────────────────────────────────────── */
.ard * { box-sizing: border-box; }
.ard {
  font-family: var(--ard-font-body);
  font-size: var(--ard-fs-md);
  line-height: var(--ard-lh);
  color: var(--ard-ink);
  background: var(--ard-bg);
  -webkit-tap-highlight-color: transparent;
  text-rendering: optimizeLegibility;
}

/* Numerals line up in every column that holds a number. Non-negotiable for a
   product whose users compare figures down a page. */
.ard-num, .ard-table td.num, .ard-table th.num,
.ard-kpi__value, .ard-pill--count { font-variant-numeric: tabular-nums; }

/* ── Focus: one ring, everywhere, keyboard-only ─────────────────────────── */
.ard :focus-visible {
  outline: 2px solid var(--ard-accent);
  outline-offset: var(--ard-focus-offset);
  border-radius: var(--ard-r-sm);
}
.ard :focus:not(:focus-visible) { outline: none; }

/* ── Card ───────────────────────────────────────────────────────────────── */
.ard-card {
  background: var(--ard-surface);
  border: 1px solid var(--ard-border);
  border-radius: var(--ard-r-lg);
  box-shadow: var(--ard-sh-1);
  padding: var(--ard-sp-8);
}
.ard-card--flush { padding: 0; overflow: hidden; }
.ard-card--interactive {
  cursor: pointer;
  transition: transform var(--ard-dur-nav) var(--ard-ease-out),
              box-shadow var(--ard-dur-nav) var(--ard-ease-out),
              border-color var(--ard-dur-nav) var(--ard-ease-out);
}
.ard-card--interactive:hover {
  transform: translateY(-2px);
  box-shadow: var(--ard-sh-2);
  border-color: var(--ard-accent-border);
}
.ard-card--interactive:active { transform: scale(var(--ard-press-scale)); }
.ard-card__head {
  display: flex; align-items: baseline; gap: var(--ard-sp-6);
  margin-bottom: var(--ard-sp-6);
}
.ard-card__title {
  font-size: var(--ard-fs-xs); font-weight: 600; letter-spacing: var(--ard-tracking-label);
  text-transform: uppercase; color: var(--ard-ink-3); margin: 0;
}
.ard-card__meta { margin-left: auto; font-size: var(--ard-fs-sm); color: var(--ard-ink-3); }

/* ── Section header ─────────────────────────────────────────────────────── */
.ard-section {
  display: flex; align-items: center; gap: var(--ard-sp-6);
  margin: var(--ard-sp-12) 0 var(--ard-sp-6);
}
.ard-section__label {
  font-size: var(--ard-fs-xs); font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ard-ink-3);
}
.ard-section__rule { flex: 1; height: 1px; background: var(--ard-hairline); }

/* ── Button ─────────────────────────────────────────────────────────────── */
.ard-btn {
  --_bg: var(--ard-accent);
  --_ink: var(--ard-ink-on-accent);
  --_bd: transparent;
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--ard-sp-3);
  min-height: var(--ard-tap-min);
  padding: 0 var(--ard-sp-8);
  border: 1px solid var(--_bd);
  border-radius: var(--ard-r-sm);
  background: var(--_bg);
  color: var(--_ink);
  font: 600 var(--ard-fs-md)/1 var(--ard-font-body);
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: transform var(--ard-dur-feedback) var(--ard-ease-out),
              box-shadow var(--ard-dur-nav) var(--ard-ease-out),
              background var(--ard-dur-nav) var(--ard-ease-out);
}
.ard-btn:hover { background: var(--ard-accent-hover); box-shadow: var(--ard-sh-2); }
.ard-btn:active { transform: scale(var(--ard-press-scale)); box-shadow: none; }
.ard-btn[disabled], .ard-btn[aria-disabled="true"] {
  opacity: var(--ard-disabled-opacity); pointer-events: none;
}
.ard-btn--secondary {
  --_bg: var(--ard-surface); --_ink: var(--ard-ink); --_bd: var(--ard-border-strong);
}
.ard-btn--secondary:hover { background: var(--ard-surface-hover); }
.ard-btn--ghost { --_bg: transparent; --_ink: var(--ard-accent-ink); --_bd: transparent; }
.ard-btn--ghost:hover { background: var(--ard-accent-tint); }
.ard-btn--danger {
  --_bg: var(--ard-danger-tint); --_ink: var(--ard-danger-ink); --_bd: var(--ard-danger-border);
}
.ard-btn--danger:hover { background: var(--ard-danger); --_ink: #fff; }
.ard-btn--ok {
  --_bg: var(--ard-ok-tint); --_ink: var(--ard-ok-ink); --_bd: var(--ard-ok-border);
}
.ard-btn--ok:hover { background: var(--ard-ok); --_ink: #fff; }
.ard-btn--sm { min-height: 34px; padding: 0 var(--ard-sp-6); font-size: var(--ard-fs-sm); }
@media (pointer: coarse) { .ard-btn--sm { min-height: var(--ard-tap-min); } }
.ard-btn--block { width: 100%; }

/* Row actions: ONE primary, the rest behind an overflow menu. The no-show
   queue rendered three equal-weight buttons stacked per row, which set the row
   height to ~160px and turned 15 rows into a 2,400px scroll. */
.ard-actions { display: flex; align-items: center; gap: var(--ard-sp-3); }
.ard-actions__more {
  position: relative; display: inline-flex;
}
.ard-actions__more > summary {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 34px; min-height: 34px;
  border: 1px solid var(--ard-border-strong); border-radius: var(--ard-r-sm);
  background: var(--ard-surface); color: var(--ard-ink-2);
}
.ard-actions__more > summary::-webkit-details-marker { display: none; }
.ard-actions__more[open] > summary { background: var(--ard-surface-hover); }
.ard-actions__menu {
  position: absolute; right: 0; top: calc(100% + 4px);
  z-index: var(--ard-z-dropdown);
  min-width: 190px; padding: var(--ard-sp-2);
  background: var(--ard-surface);
  border: 1px solid var(--ard-border);
  border-radius: var(--ard-r-md);
  box-shadow: var(--ard-sh-3);
}
.ard-actions__menu button, .ard-actions__menu a {
  display: flex; align-items: center; gap: var(--ard-sp-4);
  width: 100%; min-height: 40px; padding: 0 var(--ard-sp-5);
  border: 0; border-radius: var(--ard-r-sm); background: transparent;
  color: var(--ard-ink); font: 500 var(--ard-fs-md)/1 var(--ard-font-body);
  text-align: left; text-decoration: none; cursor: pointer;
}
.ard-actions__menu button:hover, .ard-actions__menu a:hover { background: var(--ard-surface-hover); }
.ard-actions__menu .is-danger { color: var(--ard-danger-ink); }

/* ── Pill — 7 states replace ~45 variants ───────────────────────────────── */
.ard-pill {
  --_ink: var(--ard-neutral-ink); --_bg: var(--ard-neutral-tint); --_bd: var(--ard-neutral-border);
  display: inline-flex; align-items: center; gap: var(--ard-sp-2);
  padding: 3px var(--ard-sp-5);
  border: 1px solid var(--_bd); border-radius: var(--ard-r-pill);
  background: var(--_bg); color: var(--_ink);
  font-size: var(--ard-fs-xs); font-weight: 600; line-height: 1.5;
  white-space: nowrap;
}
.ard-pill--ok      { --_ink: var(--ard-ok-ink);     --_bg: var(--ard-ok-tint);     --_bd: var(--ard-ok-border); }
.ard-pill--warn    { --_ink: var(--ard-warn-ink);   --_bg: var(--ard-warn-tint);   --_bd: var(--ard-warn-border); }
.ard-pill--danger  { --_ink: var(--ard-danger-ink); --_bg: var(--ard-danger-tint); --_bd: var(--ard-danger-border); }
.ard-pill--info    { --_ink: var(--ard-info-ink);   --_bg: var(--ard-info-tint);   --_bd: var(--ard-info-border); }
.ard-pill--critical{ --_ink: var(--ard-critical-ink); --_bg: var(--ard-critical); --_bd: transparent; }
/* "no reading yet" must not look like "failed" */
.ard-pill--nodata  { --_ink: var(--ard-nodata-ink); --_bg: transparent; --_bd: var(--ard-nodata-border);
                     border-style: dashed; font-weight: 500; }
.ard-pill--count   { --_bg: var(--ard-accent-tint); --_ink: var(--ard-accent-ink);
                     --_bd: transparent; font-variant-numeric: tabular-nums; }
/* Identity, NOT status. A club is never an error. */
.ard-tag {
  display: inline-flex; align-items: center; gap: var(--ard-sp-2);
  padding: 2px var(--ard-sp-4);
  border-radius: var(--ard-r-sm);
  background: var(--ard-surface-3); color: var(--ard-ink-2);
  font-size: var(--ard-fs-xs); font-weight: 500; white-space: nowrap;
}
.ard-tag--ph { box-shadow: inset 3px 0 0 var(--ard-country-ph); }
.ard-tag--sg { box-shadow: inset 3px 0 0 var(--ard-country-sg); }
.ard-tag--my { box-shadow: inset 3px 0 0 var(--ard-country-my); }
.ard-tag--id { box-shadow: inset 3px 0 0 var(--ard-country-id); }

/* ── Table ──────────────────────────────────────────────────────────────── */
.ard-table-scroll {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--ard-border); border-radius: var(--ard-r-lg);
  background: var(--ard-surface);
}
.ard-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--ard-fs-md); }
.ard-table th, .ard-table td {
  text-align: left; padding: var(--ard-sp-5) var(--ard-sp-6);
  border-bottom: 1px solid var(--ard-hairline); vertical-align: middle;
}
.ard-table thead th {
  position: sticky; top: 0; z-index: var(--ard-z-raised);
  background: var(--ard-surface-2);
  color: var(--ard-ink-3);
  font-size: var(--ard-fs-xs); font-weight: 700;
  letter-spacing: var(--ard-tracking-label); text-transform: uppercase;
  border-bottom: 1px solid var(--ard-border);
  white-space: nowrap;
}
.ard-table tbody tr { transition: background var(--ard-dur-feedback) var(--ard-ease-out); }
.ard-table tbody tr:hover { background: var(--ard-surface-hover); }
.ard-table tbody tr:last-child td { border-bottom: 0; }
.ard-table td.num, .ard-table th.num { text-align: right; }
.ard-table__primary { font-weight: 600; color: var(--ard-ink); }
.ard-table__sub { display: block; font-size: var(--ard-fs-sm); color: var(--ard-ink-3); margin-top: 1px; }
/* sortable */
.ard-table th[aria-sort] { cursor: pointer; user-select: none; }
.ard-table th[aria-sort]:hover { color: var(--ard-ink); }
.ard-table th[aria-sort="ascending"]::after  { content: " ↑"; color: var(--ard-accent-ink); }
.ard-table th[aria-sort="descending"]::after { content: " ↓"; color: var(--ard-accent-ink); }

/* Mobile: stack rows into labelled blocks. Without data-label the columns
   become unlabelled numbers — the past-due page shipped exactly that, so
   months-owed and amount-owed were indistinguishable on a phone. */
@media (max-width: 640px) {
  .ard-table--stack thead { display: none; }
  .ard-table--stack tbody tr {
    display: block; padding: var(--ard-sp-5) var(--ard-sp-6);
    border-bottom: 1px solid var(--ard-border);
  }
  .ard-table--stack tbody td {
    display: flex; justify-content: space-between; gap: var(--ard-sp-6);
    padding: var(--ard-sp-2) 0; border: 0; text-align: right;
  }
  .ard-table--stack tbody td::before {
    content: attr(data-label);
    font-size: var(--ard-fs-xs); font-weight: 600; color: var(--ard-ink-3);
    text-transform: uppercase; letter-spacing: var(--ard-tracking-label);
    text-align: left; flex: 0 0 auto;
  }
}

/* ── KPI tile ───────────────────────────────────────────────────────────── */
.ard-kpis {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--ard-sp-6);
}
.ard-kpi {
  background: var(--ard-surface);
  border: 1px solid var(--ard-border);
  border-radius: var(--ard-r-md);
  padding: var(--ard-sp-7);
  min-width: 0;
}
.ard-kpi__label {
  font-size: var(--ard-fs-xs); font-weight: 600; color: var(--ard-ink-3);
  text-transform: uppercase; letter-spacing: var(--ard-tracking-label);
}
.ard-kpi__value {
  font-size: clamp(20px, 3.4vw, 28px); font-weight: 700; color: var(--ard-ink);
  line-height: var(--ard-lh-tight); margin-top: var(--ard-sp-3);
  overflow-wrap: anywhere;
}
.ard-kpi__delta { font-size: var(--ard-fs-sm); font-weight: 600; margin-top: var(--ard-sp-2); }
.ard-kpi__delta--up   { color: var(--ard-ok-ink); }
.ard-kpi__delta--down { color: var(--ard-danger-ink); }
.ard-kpi__delta--flat { color: var(--ard-ink-3); }
.ard-kpi--ok    .ard-kpi__value { color: var(--ard-ok-ink); }
.ard-kpi--warn  .ard-kpi__value { color: var(--ard-warn-ink); }
.ard-kpi--danger .ard-kpi__value { color: var(--ard-danger-ink); }
/* provenance — where this number came from */
.ard-source {
  display: inline-flex; align-items: center; gap: var(--ard-sp-2);
  margin-top: var(--ard-sp-3);
  font-size: var(--ard-fs-xs); color: var(--ard-ink-3);
}
.ard-source::before {
  content: ""; width: 5px; height: 5px; border-radius: 50%;
  background: var(--ard-accent); flex: none;
}

/* ── Empty state ────────────────────────────────────────────────────────── */
.ard-empty {
  display: flex; flex-direction: column; align-items: center; gap: var(--ard-sp-4);
  padding: var(--ard-sp-16) var(--ard-sp-8);
  border: 1px dashed var(--ard-border-strong);
  border-radius: var(--ard-r-lg);
  background: var(--ard-surface-2);
  text-align: center;
}
.ard-empty__title { font-size: var(--ard-fs-lg); font-weight: 600; color: var(--ard-ink-2); }
.ard-empty__body  { font-size: var(--ard-fs-md); color: var(--ard-ink-3); max-width: 46ch; }
.ard-empty--inline { padding: var(--ard-sp-10) var(--ard-sp-6); border-style: dashed; }

/* ── Callout ────────────────────────────────────────────────────────────── */
.ard-callout {
  --_ink: var(--ard-ink-2); --_bg: var(--ard-accent-tint); --_bd: var(--ard-accent-border);
  display: flex; gap: var(--ard-sp-5);
  padding: var(--ard-sp-6) var(--ard-sp-7);
  border: 1px solid var(--_bd); border-left-width: 3px;
  border-radius: var(--ard-r-md);
  background: var(--_bg); color: var(--_ink);
  font-size: var(--ard-fs-md);
}
.ard-callout--ok     { --_bg: var(--ard-ok-tint);     --_bd: var(--ard-ok-border);     --_ink: var(--ard-ok-ink); }
.ard-callout--warn   { --_bg: var(--ard-warn-tint);   --_bd: var(--ard-warn-border);   --_ink: var(--ard-warn-ink); }
.ard-callout--danger { --_bg: var(--ard-danger-tint); --_bd: var(--ard-danger-border); --_ink: var(--ard-danger-ink); }

/* ── Form ───────────────────────────────────────────────────────────────── */
.ard-field { display: flex; flex-direction: column; gap: var(--ard-sp-3); min-width: 0; }
.ard-label {
  font-size: var(--ard-fs-xs); font-weight: 600; color: var(--ard-ink-2);
  text-transform: uppercase; letter-spacing: var(--ard-tracking-label);
}
.ard-input, .ard-select, .ard-textarea {
  width: 100%; min-height: var(--ard-tap-min);
  padding: var(--ard-sp-5) var(--ard-sp-6);
  border: 1px solid var(--ard-border-strong);
  border-radius: var(--ard-r-sm);
  background: var(--ard-surface);
  color: var(--ard-ink);
  font: 400 var(--ard-fs-md)/1.4 var(--ard-font-body);
  transition: border-color var(--ard-dur-nav) var(--ard-ease-out),
              box-shadow var(--ard-dur-nav) var(--ard-ease-out);
}
.ard-input:focus-visible, .ard-select:focus-visible, .ard-textarea:focus-visible {
  outline: none; border-color: var(--ard-accent); box-shadow: var(--ard-focus-ring);
}
.ard-help  { font-size: var(--ard-fs-sm); color: var(--ard-ink-3); }
.ard-error { font-size: var(--ard-fs-sm); color: var(--ard-danger-ink); font-weight: 500; }
/* 16px on coarse pointers or iOS zooms the whole page on focus. */
@media (pointer: coarse) {
  .ard-input, .ard-select, .ard-textarea { font-size: 16px; }
}
.ard-form-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--ard-sp-6);
}
.ard-form-grid > .span-2 { grid-column: span 2; }
.ard-form-grid > .span-all { grid-column: 1 / -1; }
@media (max-width: 640px) {
  .ard-form-grid { grid-template-columns: 1fr; }
  .ard-form-grid > .span-2, .ard-form-grid > .span-all { grid-column: auto; }
}

/* ── Dialog — replaces native prompt()/confirm()/alert() ────────────────── */
.ard-dialog {
  width: min(520px, calc(100vw - 32px));
  padding: 0; border: 0; border-radius: var(--ard-r-lg);
  background: var(--ard-surface); color: var(--ard-ink);
  box-shadow: var(--ard-sh-3);
}
.ard-dialog::backdrop { background: var(--ard-scrim); backdrop-filter: blur(2px); }
.ard-dialog__head { padding: var(--ard-sp-8) var(--ard-sp-8) 0; }
.ard-dialog__title { font-size: var(--ard-fs-xl); font-weight: 700; margin: 0; }
.ard-dialog__body { padding: var(--ard-sp-6) var(--ard-sp-8); color: var(--ard-ink-2); }
.ard-dialog__foot {
  display: flex; justify-content: flex-end; gap: var(--ard-sp-4);
  padding: var(--ard-sp-6) var(--ard-sp-8) var(--ard-sp-8);
  border-top: 1px solid var(--ard-hairline);
}
@media (max-width: 480px) {
  .ard-dialog__foot { flex-direction: column-reverse; }
  .ard-dialog__foot .ard-btn { width: 100%; }
}

/* ── Toast ──────────────────────────────────────────────────────────────── */
.ard-toast {
  position: fixed; left: 50%; bottom: var(--ard-sp-10);
  transform: translateX(-50%);
  z-index: var(--ard-z-top);
  display: flex; align-items: center; gap: var(--ard-sp-5);
  max-width: min(560px, calc(100vw - 32px));
  padding: var(--ard-sp-6) var(--ard-sp-8);
  border-radius: var(--ard-r-md);
  background: var(--ard-ink); color: var(--ard-surface);
  box-shadow: var(--ard-sh-3);
  font-size: var(--ard-fs-md); font-weight: 500;
  animation: ard-toast-in var(--ard-dur-state) var(--ard-ease-expo) both;
}
.ard-toast--ok     { background: var(--ard-ok); color: #fff; }
.ard-toast--danger { background: var(--ard-danger); color: #fff; }
@keyframes ard-toast-in { from { opacity: 0; transform: translate(-50%, 12px); }
                          to   { opacity: 1; transform: translate(-50%, 0); } }

/* ── Skeleton — the dashboard shipped a complete implementation that zero
   templates ever used, so charts showed a blank 380px hole while loading. ── */
.ard-skeleton {
  position: relative; overflow: hidden;
  background: var(--ard-surface-3); border-radius: var(--ard-r-sm);
}
.ard-skeleton::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, var(--ard-surface-hover), transparent);
  animation: ard-shimmer 1.4s infinite;
}
@keyframes ard-shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.ard-skeleton--text  { height: 12px; margin: var(--ard-sp-3) 0; }
.ard-skeleton--chart { height: clamp(240px, 40vh, 380px); border-radius: var(--ard-r-md); }
.ard-skeleton--kpi   { height: 92px; border-radius: var(--ard-r-md); }

/* ── Entrance — capped at 4 so a long page does not cascade forever ─────── */
@keyframes ard-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.ard-rise { animation: ard-rise var(--ard-dur-layout) var(--ard-ease-expo) both; }
.ard-rise-1 { animation-delay: calc(var(--ard-stagger) * 1); }
.ard-rise-2 { animation-delay: calc(var(--ard-stagger) * 2); }
.ard-rise-3 { animation-delay: calc(var(--ard-stagger) * 3); }

/* ── Skip link ──────────────────────────────────────────────────────────── */
.ard-skip {
  position: absolute; left: -9999px; top: var(--ard-sp-4); z-index: var(--ard-z-top);
  padding: var(--ard-sp-5) var(--ard-sp-8);
  background: var(--ard-accent); color: var(--ard-ink-on-accent);
  border-radius: var(--ard-r-sm); font-weight: 600;
}
.ard-skip:focus { left: var(--ard-sp-4); }

/* ── Touch floor ────────────────────────────────────────────────────────── */
@media (pointer: coarse) {
  .ard button, .ard [role="button"], .ard a.ard-btn,
  .ard select, .ard input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  .ard textarea { min-height: var(--ard-tap-min); }
  /* checkbox/radio/range are excluded deliberately: a 44px min-height distorts
     them. Their hit area comes from a padded label instead. */
}

/* ── Reduced motion ─────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .ard *, .ard *::before, .ard *::after {
    animation-duration: 0.01ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important; scroll-behavior: auto !important;
  }
}

/* ── Print ──────────────────────────────────────────────────────────────── */
@media print {
  .ard { background: #fff; }
  .ard-no-print { display: none !important; }
  .ard-card { box-shadow: none; border-color: #999; break-inside: avoid; }
  .ard-table thead th { position: static; }
}
