/* Hallmark · SnapTap POS shared stylesheet
 * Base layer  — applies to every page (reset, type, focus, motion, utilities).
 * Chrome layer — scoped to `.app-shell` on <body>; the back-office pages opt in.
 *                The terminal (index.html) loads the base layer only and keeps
 *                its own component CSS, so class names cannot collide.
 *
 * Closes: #62 (one system) · #63 (focus + 8 states) · #64 (responsive + targets)
 *         #65 (contrast + non-colour status) · #66 (form errors) · #68 (dialog)
 *         #69 (motion) · #70 (tabular-nums + print)
 */

@import url("tokens.css");

/* ============================================================ 1. base ==== */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html, body {
  min-height: 100%;
  /* gate 34: clip, never hidden — hidden creates a scroll container that
     traps the page and kills position:sticky inside it. */
  overflow-x: clip;
}

body {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--color-ink);
  background: var(--color-page);
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-style: normal;           /* no italic headers, ever */
  line-height: var(--leading-tight);
  overflow-wrap: anywhere;
  min-width: 0;
}
h1 { font-size: var(--text-lg);  font-weight: var(--weight-bold); }
h2 { font-size: var(--text-md);  font-weight: var(--weight-bold); }
h3 { font-size: var(--text-sm);  font-weight: var(--weight-bold); }

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; }
button:disabled, [aria-disabled="true"] { cursor: not-allowed; }
a { color: var(--color-accent); }
img, svg, video { max-width: 100%; }
::placeholder { color: var(--color-placeholder); opacity: 1; }

/* Touch-target floor (#64). This is a till: fingers, not mice. Applied at
   :where() specificity 0 so any page rule can still opt a control out, and
   scoped away from checkbox/radio, whose box is intentionally small and whose
   real target is the label. */
:where(input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
       select,
       textarea) {
  min-height: var(--tap-min);
}

/* ==================================================== 2. focus (#63) ==== */
/* One ring, everywhere, instantly. Never animated, never removed without a
   replacement. Two-tone so it survives on both light and dark-maroon surfaces. */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--ring-width) solid var(--color-focus);
  outline-offset: var(--ring-offset);
  border-radius: var(--radius-xs);
}
.on-dark :focus-visible,
:where(.sidebar, .nav, .topbar-dark) :focus-visible {
  outline-color: var(--color-focus-contrast);
}
/* Never suppress the ring for keyboard users. */
:focus:not(:focus-visible) { outline: none; }

/* ==================================================== 3. motion (#69) ==== */

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

/* ====================================================== 4. utilities ==== */

.num, [data-num] {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.mono { font-family: var(--font-mono); }
.nowrap { white-space: nowrap; }

/* "Not configured" / "no value" in a data cell. This is real content stating
   an absence, not placeholder chrome, so it holds the 4.5:1 body floor -- it
   must never be styled with --color-placeholder. */
.dash {
  color: var(--color-muted);
  font-weight: var(--weight-medium);
  cursor: help;
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

/* Bounded horizontal scroll for wide tables — a deliberate, focusable region
   rather than a page that scrolls sideways. */
.table-scroll {
  overflow: auto;
  overscroll-behavior-x: contain;
  border-radius: var(--radius-lg);
}
.table-scroll:focus-visible { outline: var(--ring-width) solid var(--color-focus); }

/* ================================================ 5. chrome: shell ==== */

.app-shell { display: flex; min-height: 100vh; }

.app-shell .sidebar {
  width: 208px; flex: none;
  display: flex; flex-direction: column;
  background: var(--color-nav);
  color: var(--color-nav-ink-muted);
  position: sticky; top: 0; height: 100vh;
}
.app-shell .brand {
  padding: var(--space-lg) var(--space-lg) var(--space-md);
  background: var(--color-nav-2);
  border-bottom: 1px solid var(--color-nav-rule);
}
.app-shell .brand-row { display: flex; align-items: center; gap: var(--space-sm); }
.app-shell .brand-dot {
  width: 26px; height: 26px; border-radius: var(--radius-sm);
  background: var(--color-accent); color: var(--color-on-accent);
  display: grid; place-items: center;
}
.app-shell .brand-name {
  color: var(--color-nav-ink); font-weight: var(--weight-bold); font-size: var(--text-sm);
}
.app-shell .workspace-label {
  margin-top: var(--space-sm); font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps); text-transform: uppercase;
  color: var(--color-nav-label);
}
.app-shell nav.nav { flex: 1; overflow-y: auto; padding: var(--space-sm); }
.app-shell .nav-item {
  display: flex; align-items: center; gap: var(--space-sm);
  min-height: var(--tap-min);                     /* #64: 44px floor */
  padding: var(--space-sm) var(--space-md);
  color: var(--color-nav-ink-muted); font-size: var(--text-sm);
  border-radius: var(--radius-md); border-left: 3px solid transparent;
  text-decoration: none; white-space: nowrap;      /* gate 49 */
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.app-shell .nav-item:hover { background: var(--color-nav-hover); color: var(--color-nav-ink); }
.app-shell .nav-item.active,
.app-shell .nav-item[aria-current="page"] {
  background: var(--color-nav-2); color: var(--color-nav-ink);
  border-left-color: var(--color-accent);
}
.app-shell .nav-item.active .ic { color: var(--color-accent); }
.app-shell .nav-divider { height: 1px; background: var(--color-nav-rule); margin: var(--space-sm) var(--space-md); }
.app-shell .nav-section {
  padding: var(--space-md) var(--space-md) var(--space-2xs);
  font-size: var(--text-2xs); letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--color-nav-label);
}
.app-shell .signout { margin-top: auto; border-top: 1px solid var(--color-nav-rule); padding: var(--space-sm); }
.app-shell .ic {
  width: 18px; height: 18px; flex: none;
  stroke: currentColor; fill: none; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ------------------------------------------------------- main + topbar -- */

.app-shell .main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.app-shell .topbar {
  flex: none; min-height: 52px;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-sm) var(--space-lg);
  background: var(--color-topbar);
  border-bottom: 1px solid var(--color-border);
}
.app-shell .crumb { display: flex; align-items: center; gap: var(--space-md); min-width: 0; }
.app-shell .crumb h1 { font-size: var(--text-lg); font-weight: var(--weight-bold); color: var(--color-ink); }
.app-shell .crumb small { color: var(--color-muted); font-size: var(--text-xs); }
/* Bottom, not centre: .branch wears a caption above its select, so centring
   the stack leaves the select sitting ~8px below every bare button beside it.
   Aligning the ends puts every control on one line; each is >= --tap-min tall
   so their tops agree too. */
.app-shell .top-actions { display: flex; align-items: flex-end; gap: var(--space-sm); }
.app-shell .branch { display: flex; flex-direction: column; align-items: flex-start; }
.app-shell .branch small {
  font-size: var(--text-2xs); letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--color-muted);
}
.app-shell .branch select {
  min-height: var(--tap-min); border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  padding: var(--space-2xs) var(--space-xs); font-size: var(--text-xs);
  color: var(--color-ink); background: var(--color-surface);
}
.app-shell .avatar {
  display: flex; align-items: center; gap: var(--space-sm);
  min-height: var(--tap-min);
  padding-left: var(--space-sm); border-left: 1px solid var(--color-border);
}
.app-shell .avatar .circle {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--color-accent); color: var(--color-on-accent);
  display: grid; place-items: center; font-weight: var(--weight-bold); font-size: var(--text-xs);
}
.app-shell .avatar div small { display: block; font-size: var(--text-2xs); color: var(--color-muted); }
.app-shell .content { flex: 1; padding: var(--space-xl) var(--space-xl) var(--space-2xl); }

/* ================================= 6. buttons — all 8 states (#63) ==== */

.app-shell .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-xs);
  min-height: var(--tap-min); padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  background: var(--color-surface); color: var(--color-ink);
  font-size: var(--text-xs); font-weight: var(--weight-medium);
  white-space: nowrap;                              /* gate 49 */
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.app-shell .btn:hover               { background: var(--color-surface-3); border-color: var(--color-field-border); }
.app-shell .btn:active              { background: var(--color-border); }
.app-shell .btn:disabled,
.app-shell .btn[aria-disabled="true"] { opacity: .5; background: var(--color-surface-2); }
.app-shell .btn:disabled:hover      { background: var(--color-surface-2); border-color: var(--color-border); }

.app-shell .btn-primary {
  background: var(--color-accent); border-color: var(--color-accent); color: var(--color-on-accent);
}
.app-shell .btn-primary:hover  { background: var(--color-accent-hover); border-color: var(--color-accent-hover); }
.app-shell .btn-primary:active { background: var(--color-accent-active); border-color: var(--color-accent-active); }

.app-shell .btn-gray {
  background: var(--color-slate); border-color: var(--color-slate); color: var(--color-on-accent);
}
.app-shell .btn-gray:hover  { background: var(--color-ink); border-color: var(--color-ink); }

.app-shell .btn-danger {
  background: var(--color-danger); border-color: var(--color-danger); color: var(--color-on-accent);
}
.app-shell .btn-danger:hover { filter: brightness(0.9); }

/* loading · error · success — driven by data-state, never by ad-hoc classes */
.app-shell .btn[data-state="loading"] { pointer-events: none; opacity: .75; }
.app-shell .btn[data-state="loading"]::before {
  content: ""; width: 13px; height: 13px; flex: none;
  border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
  animation: btn-spin 700ms linear infinite;
}
.app-shell .btn[data-state="error"]   { border-color: var(--color-danger);  color: var(--color-danger);  background: var(--color-danger-bg); }
.app-shell .btn[data-state="success"] { border-color: var(--color-success); color: var(--color-success); background: var(--color-success-bg); }
@keyframes btn-spin { to { transform: rotate(360deg); } }

/* Icon-only row actions. 28px visual box, 44px hit area via a pseudo-element,
   so the table stays dense without failing the touch floor. */
.app-shell .mini-btn {
  position: relative;
  width: 28px; height: 28px; border-radius: var(--radius-sm);
  border: 1px solid var(--color-border); background: var(--color-surface);
  color: var(--color-muted); display: grid; place-items: center;
  transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.app-shell .mini-btn::after {
  content: ""; position: absolute; inset: 50% auto auto 50%;
  width: var(--tap-min); height: var(--tap-min); transform: translate(-50%, -50%);
}
.app-shell .mini-btn:hover  { border-color: var(--color-accent); color: var(--color-accent); }
.app-shell .mini-btn:active { background: var(--color-accent-tint); }
.app-shell .mini-btn:disabled { opacity: .45; border-color: var(--color-border); color: var(--color-muted); }
.app-shell .mini-btn.primary { background: var(--color-accent); border-color: var(--color-accent); color: var(--color-on-accent); }
.app-shell .mini-btn.primary:hover  { background: var(--color-accent-hover); }
.app-shell .mini-btn.danger:hover   { border-color: var(--color-danger); color: var(--color-danger); }
.app-shell .row-actions { display: flex; gap: var(--space-xs); justify-content: flex-end; }

/* ====================================================== 7. toolbar ==== */

.app-shell .toolbar {
  display: flex; align-items: center; gap: var(--space-md);
  margin-bottom: var(--space-md); flex-wrap: wrap;
}
.app-shell .search-box {
  flex: 1 1 240px; max-width: 380px; min-width: 0;
  display: flex; align-items: center; gap: var(--space-sm);
  /* the input carries the target; the wrapper's border adds the extra 2px */
  border: 1px solid var(--color-field-border); border-radius: var(--radius-md);
  background: var(--color-surface); padding: 0 var(--space-md);
}
.app-shell .search-box:focus-within { border-color: var(--color-accent); }
/* The input, not just its wrapper, must carry the 44px target — a click that
   lands on the wrapper's padding does not focus a field. */
.app-shell .search-box input {
  flex: 1; min-width: 0; align-self: stretch;
  min-height: var(--tap-min);
  border: 0; outline: 0; font-size: var(--text-sm); background: none;
}
.app-shell .search-box .ic { color: var(--color-muted); }

.app-shell .chips { display: flex; gap: var(--space-sm); overflow-x: auto; padding: var(--space-3xs) 0; }
.app-shell .chip {
  flex: none; min-height: var(--tap-min); min-width: var(--tap-min);
  justify-content: center;
  display: inline-flex; align-items: center;
  padding: var(--space-xs) var(--space-md); border-radius: var(--radius-pill);
  background: var(--color-neutral-bg); border: 1px solid var(--color-border);
  color: var(--color-slate); font-size: var(--text-xs); white-space: nowrap;
  transition: background var(--dur-fast) var(--ease-out);
}
.app-shell .chip:hover { background: var(--color-border); }
.app-shell .chip.on, .app-shell .chip[aria-pressed="true"] {
  background: var(--color-slate); border-color: var(--color-slate); color: var(--color-on-accent);
}

/* ======================================================== 8. stats ==== */

.app-shell .stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));   /* gate 50 */
  gap: var(--space-md); margin-bottom: var(--space-lg);
}
.app-shell .stat {
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); padding: var(--space-md) var(--space-lg);
  display: flex; align-items: center; gap: var(--space-md); min-width: 0;
  box-shadow: var(--shadow-card);
}
.app-shell .stat .ico {
  width: 40px; height: 40px; flex: none; border-radius: var(--radius-md);
  display: grid; place-items: center;
  background: var(--color-accent-tint); color: var(--color-accent);
}
.app-shell .stat.blue  .ico { background: var(--color-info-bg);   color: var(--color-info); }
.app-shell .stat.amber .ico { background: var(--color-warn-bg);   color: var(--color-warn); }
.app-shell .stat.red   .ico { background: var(--color-danger-bg); color: var(--color-danger); }
.app-shell .stat .num { font-size: var(--text-xl); font-weight: var(--weight-heavy); line-height: var(--leading-tight); }
.app-shell .stat .lbl { font-size: var(--text-2xs); color: var(--color-muted); margin-top: var(--space-3xs); }

/* ======================================================== 9. table ==== */

/* The wrap owns the border, radius and scrolling. The table must NOT create
   its own scroll container, or `position: sticky` on <th> silently dies. */
.app-shell .table-wrap {
  overflow: auto; overscroll-behavior-x: contain;
  border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  background: var(--color-surface);
}
.app-shell table {
  width: 100%; border-collapse: collapse; font-size: var(--text-sm);
  background: var(--color-surface);
}
.app-shell thead th {
  position: sticky; top: 0; z-index: 1;
  text-align: left; font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps); text-transform: uppercase;
  color: var(--color-muted); background: var(--color-surface-2);
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--color-border); white-space: nowrap;
}
.app-shell tbody td { padding: var(--space-sm) var(--space-md); border-bottom: 1px solid var(--color-hairline); vertical-align: middle; }
.app-shell tbody tr:hover { background: var(--color-surface-4); }
.app-shell tbody tr:last-child td { border-bottom: 0; }
.app-shell td.right, .app-shell th.right { text-align: right; }
.app-shell .empty-row { text-align: center; color: var(--color-muted); padding: var(--space-2xl) 0 !important; }

/* ------------------------------------------ badges: never colour alone -- */

.app-shell .badge {
  display: inline-flex; align-items: center; gap: var(--space-2xs);
  padding: var(--space-3xs) var(--space-sm); border-radius: var(--radius-pill);
  font-size: var(--text-2xs); font-weight: var(--weight-bold); white-space: nowrap;
  background: var(--color-neutral-bg); color: var(--color-slate);
}
.app-shell .badge::before { content: "•"; font-size: 1.1em; line-height: 1; }
.app-shell .b-active,    .app-shell .b-verified { background: var(--color-success-bg); color: var(--color-success); }
.app-shell .b-active::before,   .app-shell .b-verified::before  { content: "✓"; }
.app-shell .b-suspended, .app-shell .b-error    { background: var(--color-danger-bg);  color: var(--color-danger); }
.app-shell .b-suspended::before, .app-shell .b-error::before    { content: "✕"; }
.app-shell .b-pending,   .app-shell .b-draft    { background: var(--color-warn-bg);    color: var(--color-warn); }
.app-shell .b-pending::before,  .app-shell .b-draft::before     { content: "◷"; }
.app-shell .b-info,      .app-shell .b-exchange { background: var(--color-info-bg);    color: var(--color-info); }
.app-shell .b-info::before,     .app-shell .b-exchange::before  { content: "⇄"; }
.app-shell .b-refund::before { content: "↩"; }
.app-shell .b-credit::before { content: "★"; }

/* ================================== 10. forms — error/success (#66) ==== */

.app-shell .form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--space-md); }
.app-shell .form-row { margin-bottom: var(--space-md); min-width: 0; }
.app-shell .form-row.full { grid-column: 1 / -1; }
.app-shell .form-row label {
  display: block; font-size: var(--text-2xs); letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--color-muted); margin-bottom: var(--space-2xs);
}
.app-shell .form-row input,
.app-shell .form-row select,
.app-shell .form-row textarea {
  width: 100%; min-height: var(--tap-min);
  border: 1px solid var(--color-field-border); border-radius: var(--radius-md);
  padding: var(--space-sm) var(--space-md); font-size: var(--text-sm);
  color: var(--color-ink); background: var(--color-surface);
  transition: border-color var(--dur-fast) var(--ease-out);
}
.app-shell .form-row input:hover,
.app-shell .form-row select:hover { border-color: var(--color-accent); }
.app-shell .form-row input:disabled,
.app-shell .form-row select:disabled { background: var(--color-surface-2); opacity: .6; }

/* Reserved message slot — validation must not shift the layout. */
.app-shell .form-row .help {
  display: block; min-height: 1lh; margin-top: var(--space-2xs);
  font-size: var(--text-2xs); color: var(--color-muted);
}
.app-shell .form-row.error input,
.app-shell .form-row.error select,
.app-shell .form-row input[aria-invalid="true"] { border-color: var(--color-danger); }
.app-shell .form-row.error .help { color: var(--color-danger); font-weight: var(--weight-medium); }
.app-shell .form-row.success input { border-color: var(--color-success); }
.app-shell .form-row.success .help { color: var(--color-success); }
.app-shell .req { color: var(--color-danger); }

/* ================================= 11. dialog — native semantics (#68) == */

.app-shell dialog.modal {
  width: 460px; max-width: calc(100vw - 2 * var(--space-lg));
  max-height: calc(100dvh - 2 * var(--space-lg));
  overflow: auto;
  border: 1px solid var(--color-border); border-radius: var(--radius-xl);
  padding: var(--space-xl); background: var(--color-surface); color: var(--color-ink);
  box-shadow: var(--shadow-modal);
}
.app-shell dialog.modal::backdrop { background: var(--color-scrim); }
.app-shell dialog.modal h2 { font-size: var(--text-lg); margin-bottom: var(--space-2xs); }
.app-shell dialog.modal .sub { font-size: var(--text-xs); color: var(--color-muted); margin-bottom: var(--space-lg); }
.app-shell .modal-actions { display: flex; gap: var(--space-sm); justify-content: flex-end; margin-top: var(--space-sm); flex-wrap: wrap; }
.app-shell .note {
  font-size: var(--text-2xs); color: var(--color-muted);
  background: var(--color-accent-tint); border: 1px solid var(--color-accent-border);
  border-radius: var(--radius-md); padding: var(--space-sm) var(--space-md); margin-bottom: var(--space-md);
}
.app-shell .note.danger { background: var(--color-danger-bg); border-color: var(--color-danger-border); color: var(--color-danger); }

/* ======================================================= 12. toast ==== */

.app-shell .toast {
  position: fixed; bottom: var(--space-xl); left: 50%; z-index: 60;
  transform: translateX(-50%) translateY(var(--space-sm));
  background: var(--color-nav); color: var(--color-nav-ink);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  padding: var(--space-sm) var(--space-lg); border-radius: var(--radius-md);
  opacity: 0; pointer-events: none; box-shadow: var(--shadow-pop);
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
.app-shell .toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.app-shell .toast.error   { background: var(--color-danger); }
.app-shell .toast.success { background: var(--color-success); }

/* =============================================== 13. responsive (#64) == */

/* Collapsed rail */
@media (max-width: 1040px) {
  .app-shell .sidebar { width: 64px; }
  .app-shell .brand { padding: var(--space-md) var(--space-sm); }
  .app-shell .brand-name, .app-shell .workspace-label, .app-shell .nav-section { display: none; }
  .app-shell .nav-item { justify-content: center; padding: var(--space-sm); }
  .app-shell .nav-item span { display: none; }
  .app-shell .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Tablet / phone: sidebar becomes a horizontal rail, page scrolls normally */
@media (max-width: 768px) {
  .app-shell { display: block; }
  .app-shell .sidebar {
    width: 100%; height: auto; position: static;
    flex-direction: row; align-items: center; overflow-x: auto;
  }
  .app-shell .brand { display: none; }
  .app-shell nav.nav { display: flex; gap: var(--space-2xs); overflow-x: auto; padding: var(--space-sm); }
  .app-shell .nav-item { flex: none; border-left: 0; border-bottom: 3px solid transparent; }
  .app-shell .nav-item.active { border-left-color: transparent; border-bottom-color: var(--color-accent); }
  .app-shell .nav-divider, .app-shell .signout { display: none; }
  .app-shell .topbar { flex-wrap: wrap; padding: var(--space-sm) var(--space-md); }
  .app-shell .content { padding: var(--space-md) var(--space-md) var(--space-xl); }
  .app-shell .avatar div, .app-shell .branch small { display: none; }
  .app-shell .search-box { max-width: none; flex-basis: 100%; }
  .app-shell dialog.modal { width: 100%; }
  .app-shell .form-grid { grid-template-columns: minmax(0, 1fr); }

  .app-shell .table-wrap {
    border: 0; background: none; overflow: visible; border-radius: 0;
  }
  /* Tables become labelled cards. Each <td> carries data-label from markup. */
  .app-shell table, .app-shell thead, .app-shell tbody,
  .app-shell tr, .app-shell th, .app-shell td { display: block; }
  .app-shell thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .app-shell tbody tr {
    border: 1px solid var(--color-border); border-radius: var(--radius-lg);
    background: var(--color-surface); padding: var(--space-sm);
    margin-bottom: var(--space-sm);
  }
  .app-shell tbody td {
    display: flex; justify-content: space-between; gap: var(--space-md);
    padding: var(--space-2xs) var(--space-2xs); border-bottom: 0; text-align: right;
  }
  .app-shell tbody td::before {
    content: attr(data-label);
    font-size: var(--text-2xs); letter-spacing: var(--tracking-caps);
    text-transform: uppercase; color: var(--color-muted); text-align: left; flex: none;
  }
  .app-shell tbody td:empty { display: none; }
  .app-shell .row-actions { justify-content: flex-end; }
}

@media (max-width: 414px) {
  .app-shell .stats { grid-template-columns: minmax(0, 1fr); }
  .app-shell .toolbar { gap: var(--space-sm); }
}

/* ========================================================= 14. print == */

@page { margin: 12mm; }

@media print {
  :root { --color-page: #fff; }
  body { background: #fff; }
  .app-shell .sidebar, .app-shell .topbar, .app-shell .toolbar,
  .app-shell .toast, .no-print { display: none !important; }
  .app-shell .content { padding: 0; }
  .app-shell table { border: 0; font-size: 10pt; }
  .app-shell thead { display: table-header-group; }   /* repeat header per page */
  .app-shell tfoot { display: table-footer-group; }
  .app-shell tr, .app-shell .card, .app-shell .panel { break-inside: avoid; }
  .app-shell h1, .app-shell h2, .app-shell h3 { break-after: avoid; }
  .app-shell .badge, .app-shell .stat .ico { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
  a[href]::after { content: ""; }                      /* no URL noise on receipts */
}
