/* Airgas Inventory — data-dense admin.
   Tokens mirror airgas.my so the two products feel like one company.
   Layer order: tokens → base → layout → components → utilities. */

/* ── tokens ─────────────────────────────────────────────────────────────── */
:root {
  /* raw scales (never referenced directly by components) */
  --white: #FFFFFF; --paper: #FAF8F5; --hairline: #ECE8E2;
  --orange-50: #FFF5EC; --orange-100: #FFE9D5; --orange-500: #F47B20;
  --orange-600: #D85F0A; --orange-700: #B04E07;
  --ink-50: #F5F5F7; --ink-200: #E3E5E8; --ink-300: #B9BDC4;
  --ink-500: #6B7079; --ink-700: #3A3D45; --ink-900: #1F2024;
  --green-600: #047857; --red-600: #DC2626; --red-50: #FEF2F2;

  /* semantic */
  --color-bg: var(--paper);
  --color-surface: var(--white);
  --color-heading: var(--ink-900);
  --color-text: var(--ink-700);
  --color-muted: var(--ink-500);
  --color-border: var(--hairline);
  --color-accent: var(--orange-500);
  --color-accent-hover: var(--orange-600);
  --color-accent-pressed: var(--orange-700);
  --color-accent-tint: var(--orange-100);
  --color-accent-wash: var(--orange-50);
  --color-focus: var(--orange-600);
  --color-danger: var(--red-600);
  --color-ok: var(--green-600);
  /* orange fails AA on white at body size — this is the accessible text orange */
  --color-accent-text: var(--orange-700);

  --space-2xs: 4px; --space-xs: 8px; --space-sm: 12px; --space-md: 16px;
  --space-lg: 24px; --space-xl: 32px; --space-2xl: 48px;
  --radius-sm: 4px; --radius-md: 8px; --radius-lg: 12px; --radius-pill: 999px;
  --shadow-sm: 0 1px 2px rgba(31,32,36,.06), 0 1px 3px rgba(31,32,36,.05);
  --shadow-md: 0 4px 12px rgba(31,32,36,.08);
  --dur: 180ms; --ease: cubic-bezier(.22,1,.36,1);
  --sidebar-w: 232px;
  --font: system-ui, -apple-system, 'Segoe UI', Roboto, Inter, sans-serif;
  --mono: ui-monospace, 'Cascadia Mono', 'SF Mono', Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-bg: #16171A; --color-surface: #1E2024;
    --color-heading: #F4F5F7; --color-text: #D6D8DC; --color-muted: #9AA0A8;
    --color-border: #2E3138; --color-accent-tint: #3A2410; --color-accent-wash: #241708;
    --color-accent-text: #FFA45C;  /* lighter tone for contrast on dark */
    --shadow-sm: 0 1px 2px rgba(0,0,0,.4); --shadow-md: 0 4px 14px rgba(0,0,0,.5);
  }
}

/* ── base ───────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
/* Author `display` rules (e.g. .nav a{display:flex}) beat the UA rule for [hidden],
   which would silently reveal admin-only links to viewers. Force it. */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; font-family: var(--font); font-size: 15px; line-height: 1.55;
  color: var(--color-text); background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3 { color: var(--color-heading); line-height: 1.25; margin: 0; font-weight: 650; }
h1 { font-size: 1.4rem; } h2 { font-size: 1.1rem; } h3 { font-size: .95rem; }
a { color: var(--color-accent-text); }

:where(a, button, input, select, [tabindex]):focus-visible {
  outline: 2px solid var(--color-focus); outline-offset: 2px; border-radius: var(--radius-sm);
}
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: var(--space-md); top: -60px; z-index: 100;
  background: var(--color-surface); color: var(--color-heading);
  padding: var(--space-sm) var(--space-md); border-radius: var(--radius-md);
  box-shadow: var(--shadow-md); transition: top var(--dur) var(--ease);
}
.skip-link:focus { top: var(--space-md); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ── login ──────────────────────────────────────────────────────────────── */
.login-wrap { min-height: 100dvh; display: grid; place-items: center; padding: var(--space-md); }
.login-card {
  width: 100%; max-width: 400px; background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  padding: var(--space-xl); box-shadow: var(--shadow-md);
}
.brand { display: flex; align-items: center; gap: var(--space-sm); margin-bottom: var(--space-lg); }
.brand-mark {
  width: 36px; height: 36px; border-radius: var(--radius-md); flex: none;
  background: var(--color-accent); color: #fff; display: grid; place-items: center;
  font-weight: 700; font-size: .95rem; letter-spacing: -.02em;
}
.brand-name { font-weight: 650; color: var(--color-heading); }
.brand-sub { font-size: .78rem; color: var(--color-muted); }

.field { margin-bottom: var(--space-md); }
.field label { display: block; font-size: .82rem; font-weight: 600; margin-bottom: var(--space-2xs); color: var(--color-heading); }
.field input, .field select {
  width: 100%; min-height: 44px; padding: 0 var(--space-sm);
  font: inherit; font-size: 16px;           /* 16px stops iOS zoom-on-focus */
  color: var(--color-text); background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.field input:focus { border-color: var(--color-accent); }
.hint { font-size: .78rem; color: var(--color-muted); margin-top: var(--space-2xs); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-xs);
  min-height: 44px; padding: 0 var(--space-md); font: inherit; font-weight: 600;
  border-radius: var(--radius-md); border: 1px solid transparent; cursor: pointer;
  background: var(--color-accent); color: #fff;
  transition: background var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.btn:hover { background: var(--color-accent-hover); }
.btn:active { background: var(--color-accent-pressed); transform: scale(.99); }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn--full { width: 100%; }
.btn--ghost { background: transparent; color: var(--color-text); border-color: var(--color-border); }
.btn--ghost:hover { background: var(--color-accent-wash); color: var(--color-accent-text); }
.btn--sm { min-height: 36px; font-size: .85rem; padding: 0 var(--space-sm); }
.btn--danger { background: var(--color-danger); }

.alert {
  display: flex; gap: var(--space-xs); padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md); font-size: .87rem; margin-bottom: var(--space-md);
  border: 1px solid; background: var(--red-50); color: var(--color-danger); border-color: currentColor;
}
.alert--ok { background: var(--color-accent-wash); color: var(--color-ok); }
@media (prefers-color-scheme: dark) { .alert { background: #2A1416; } .alert--ok { background: #10241C; } }

/* ── app shell ──────────────────────────────────────────────────────────── */
.shell { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100dvh; }

.sidebar {
  background: var(--color-surface); border-right: 1px solid var(--color-border);
  padding: var(--space-md); display: flex; flex-direction: column; gap: var(--space-md);
  position: sticky; top: 0; height: 100dvh; overflow-y: auto;
}
.nav { display: flex; flex-direction: column; gap: 2px; }
.nav a {
  display: flex; align-items: center; gap: var(--space-sm);
  min-height: 44px; padding: 0 var(--space-sm); border-radius: var(--radius-md);
  color: var(--color-text); text-decoration: none; font-size: .9rem; font-weight: 500;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.nav a:hover { background: var(--color-accent-wash); color: var(--color-accent-text); }
.nav a[aria-current="page"] {
  background: var(--color-accent-tint); color: var(--color-accent-text); font-weight: 650;
  box-shadow: inset 3px 0 0 var(--color-accent);   /* not colour alone */
}
.nav svg { width: 18px; height: 18px; flex: none; stroke-width: 1.75; }
.nav-group { font-size: .7rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--color-muted); font-weight: 700; padding: var(--space-sm) var(--space-sm) var(--space-2xs); }

.userbox { margin-top: auto; border-top: 1px solid var(--color-border); padding-top: var(--space-md); }
.userbox .who { font-size: .85rem; font-weight: 600; color: var(--color-heading); overflow-wrap: anywhere; }
.badge {
  display: inline-flex; align-items: center; gap: 4px; font-size: .7rem; font-weight: 700;
  padding: 2px 8px; border-radius: var(--radius-pill); text-transform: uppercase; letter-spacing: .04em;
  background: var(--color-accent-tint); color: var(--color-accent-text);
}
.badge--view { background: var(--ink-50); color: var(--color-muted); }
@media (prefers-color-scheme: dark) { .badge--view { background: #2A2D33; } }

.main { padding: var(--space-lg); min-width: 0; }
.page-head {
  display: flex; flex-wrap: wrap; gap: var(--space-md);
  align-items: baseline; justify-content: space-between; margin-bottom: var(--space-lg);
}
.page-head p { margin: 2px 0 0; color: var(--color-muted); font-size: .87rem; }

/* ── cards / KPIs ───────────────────────────────────────────────────────── */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-md); margin-bottom: var(--space-xl); }
.kpi {
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); padding: var(--space-md); box-shadow: var(--shadow-sm);
}
.kpi dt { font-size: .78rem; color: var(--color-muted); font-weight: 600; margin: 0 0 var(--space-2xs); }
.kpi dd { margin: 0; font-size: 1.6rem; font-weight: 700; color: var(--color-heading);
  font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.kpi .sub { font-size: .75rem; color: var(--color-muted); font-weight: 500; }

.panel {
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); overflow: hidden;
}
.panel-head {
  display: flex; flex-wrap: wrap; gap: var(--space-sm); align-items: center;
  padding: var(--space-sm) var(--space-md); border-bottom: 1px solid var(--color-border);
}
.panel-head .grow { flex: 1 1 200px; }
.search {
  width: 100%; min-height: 40px; padding: 0 var(--space-sm); font: inherit; font-size: 16px;
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  background: var(--color-bg); color: var(--color-text);
}

/* ── tables ─────────────────────────────────────────────────────────────── */
.table-scroll { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: .87rem; }
thead th {
  position: sticky; top: 0; z-index: 1; text-align: left; white-space: nowrap;
  background: var(--color-bg); color: var(--color-muted);
  font-size: .74rem; text-transform: uppercase; letter-spacing: .05em; font-weight: 700;
  padding: var(--space-sm) var(--space-md); border-bottom: 1px solid var(--color-border);
}
thead th button {
  all: unset; cursor: pointer; display: inline-flex; align-items: center; gap: 4px;
  min-height: 32px; color: inherit; font: inherit;
}
thead th button:hover { color: var(--color-accent-text); }
th[aria-sort] button::after { content: '↕'; opacity: .4; }
th[aria-sort="ascending"] button::after { content: '↑'; opacity: 1; }
th[aria-sort="descending"] button::after { content: '↓'; opacity: 1; }
tbody td { padding: var(--space-sm) var(--space-md); border-bottom: 1px solid var(--color-border); vertical-align: top; }
tbody tr:hover { background: var(--color-accent-wash); }
tbody tr:last-child td { border-bottom: 0; }
.num { text-align: right; font-variant-numeric: tabular-nums; }
.code { font-family: var(--mono); font-size: .82rem; color: var(--color-heading); }
.muted { color: var(--color-muted); }
.truncate { max-width: 380px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.pager {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md); border-top: 1px solid var(--color-border);
}
.pager .count { font-size: .82rem; color: var(--color-muted); font-variant-numeric: tabular-nums; }

.empty { padding: var(--space-2xl) var(--space-md); text-align: center; color: var(--color-muted); }
.skeleton {
  height: 14px; border-radius: var(--radius-sm); margin: var(--space-sm) 0;
  background: linear-gradient(90deg, var(--color-border) 25%, var(--color-bg) 37%, var(--color-border) 63%);
  background-size: 400% 100%; animation: shimmer 1.4s ease infinite;
}
@keyframes shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* ── actions in table rows ──────────────────────────────────────────────── */
.row-actions { display: flex; gap: var(--space-xs); flex-wrap: wrap; }
.note-chip {
  display: inline-flex; align-items: center; gap: 6px; margin-top: var(--space-2xs);
  padding: 4px 10px; border-radius: var(--radius-md); font-size: .78rem; line-height: 1.35;
  background: var(--color-accent-wash); color: var(--color-accent-text);
  border: 1px solid var(--color-accent-tint);
}
.note-chip svg { width: 14px; height: 14px; flex: none; }

/* ── bottom sheet (thumb-reachable on a phone, centred dialog on desktop) ── */
.sheet-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.55); z-index: 400; }
.sheet {
  position: fixed; z-index: 401; left: 0; right: 0; bottom: 0;
  background: var(--color-surface); border-top: 1px solid var(--color-border);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: var(--space-lg) var(--space-md) calc(var(--space-lg) + env(safe-area-inset-bottom));
  max-height: 92dvh; overflow-y: auto; box-shadow: var(--shadow-md);

}
/* Two @keyframes must NOT share a name — even inside a media query the later
   definition wins globally, which left the phone sheet parked at translateY(12px)
   (12px of it below the screen edge). Distinct names, and each variant pins its
   own settled transform with `forwards`. */
@keyframes sheet-up-mobile { from { transform: translateY(14px); opacity: .5; } to { transform: translateY(0); opacity: 1; } }
.sheet { animation: sheet-up-mobile 220ms var(--ease) forwards; }

@media (min-width: 720px) {
  .sheet {
    left: 50%; right: auto; bottom: auto; top: 50%;
    width: min(520px, calc(100vw - 2 * var(--space-lg)));
    border-radius: var(--radius-lg); border: 1px solid var(--color-border);
    animation: sheet-in-center 220ms var(--ease) forwards;
  }
  @keyframes sheet-in-center {
    from { transform: translate(-50%, -46%); opacity: .5; }
    to   { transform: translate(-50%, -50%); opacity: 1; }
  }
}
/* With reduced motion the animation is ~instant, so pin the end state directly. */
@media (prefers-reduced-motion: reduce) {
  .sheet { animation: none; transform: translateY(0); }
  @media (min-width: 720px) { .sheet { transform: translate(-50%, -50%); } }
}
.sheet h2 { margin-bottom: var(--space-2xs); }
.sheet .sub { color: var(--color-muted); font-size: .85rem; margin-bottom: var(--space-md); }
.sheet-actions { display: flex; gap: var(--space-sm); margin-top: var(--space-lg); }
.sheet-actions .btn { flex: 1; }

/* segmented control — big targets, works one-handed */
.seg { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2xs);
  background: var(--color-bg); padding: 4px; border-radius: var(--radius-md);
  border: 1px solid var(--color-border); }
.seg button {
  all: unset; text-align: center; min-height: 44px; line-height: 44px; cursor: pointer;
  border-radius: var(--radius-sm); font-size: .87rem; font-weight: 600; color: var(--color-muted);
}
.seg button[aria-pressed="true"] { background: var(--color-accent); color: #fff; }
.big-num { font-size: 1.5rem; font-weight: 700; font-variant-numeric: tabular-nums; text-align: center; }

/* ── responsive ─────────────────────────────────────────────────────────── */
.menu-btn { display: none; }

/* Phones: every data table becomes a stack of readable cards. The storekeeper is
   on a phone in the yard — a 7-column table is unusable there. Each cell keeps its
   header via data-label so nothing loses meaning. */
@media (max-width: 700px) {
  .table-scroll { overflow-x: visible; }
  table, tbody, tr, td { display: block; width: 100%; }
  thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  tbody tr {
    border: 1px solid var(--color-border); border-radius: var(--radius-lg);
    padding: var(--space-sm); margin-bottom: var(--space-sm); background: var(--color-surface);
  }
  tbody tr:hover { background: var(--color-surface); }
  tbody td {
    border: 0; padding: 5px 0; display: grid; grid-template-columns: 40% 1fr;
    gap: var(--space-sm); align-items: baseline;
  }
  tbody td::before {
    content: attr(data-label); font-size: .72rem; font-weight: 700; letter-spacing: .04em;
    text-transform: uppercase; color: var(--color-muted);
  }
  tbody td.num { text-align: left; }
  tbody td:empty { display: none; }
  .truncate { max-width: none; white-space: normal; overflow: visible; }
  .row-actions { grid-column: 1 / -1; margin-top: var(--space-xs); }
  .row-actions .btn { flex: 1; }
}
@media (max-width: 900px) {
  .shell { grid-template-columns: 1fr; }
  .sidebar {
    position: fixed; inset: 0 auto 0 0; width: 280px; z-index: 50; height: 100dvh;
    transform: translateX(-100%); transition: transform var(--dur) var(--ease);
    box-shadow: var(--shadow-md);
  }
  .sidebar.is-open { transform: none; }
  .menu-btn { display: inline-flex; }
  .scrim { position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 40; }
  .main { padding: var(--space-md); }
  .truncate { max-width: 200px; }
}

/* Description cell that can hold chips below the text. The text itself truncates
   (inner .truncate), but the cell must NOT clip — chips are block elements. */
.desc-cell { max-width: 420px; }
.desc-cell .truncate { max-width: 100%; }
@media (max-width: 700px) { .desc-cell { max-width: none; } }

/* ── phone touch targets ────────────────────────────────────────────────────
   Measured at 375px: 111 controls fell below the 44px minimum — mostly the
   per-row Adjust/Where buttons at 36px. A storekeeper taps these in the yard,
   often one-handed and sometimes with gloves, so on phones everything grows. */
@media (max-width: 700px) {
  .btn--sm { min-height: 44px; font-size: .9rem; padding: 0 var(--space-md); }
  .search  { min-height: 44px; font-size: 16px; }

  /* thead is already visually hidden and each cell carries its own label via
     data-label, so drop it from the layout entirely — otherwise its sort buttons
     linger as 32px phantom targets. */
  thead { display: none; }

  /* row actions: full-width, side by side, comfortably tappable */
  .row-actions { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-sm); }
  .row-actions .btn { width: 100%; }

  /* the sheet's own buttons and the segmented control */
  .sheet-actions .btn { min-height: 48px; }
  .seg button { min-height: 48px; line-height: 48px; }

  /* pager buttons sit side by side rather than cramped */
  .pager { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-sm); }
  .pager .count { grid-column: 1 / -1; text-align: center; }

  /* stop long item descriptions forcing a wide card */
  .code, td { overflow-wrap: anywhere; }
}

/* ── placement photos ───────────────────────────────────────────────────────
   The storekeeper photographs where he put things. Thumbnails are fetched from
   a PRIVATE bucket with the session token and shown as blob: URLs. */
.pl-row {
  display: flex; gap: var(--space-sm); align-items: flex-start;
  padding: var(--space-sm) 0; border-bottom: 1px solid var(--color-border);
}
.pl-thumb {
  width: 64px; height: 64px; flex: none; border-radius: var(--radius-md);
  background: var(--color-bg); border: 1px solid var(--color-border);
  display: grid; place-items: center; overflow: hidden;
}
.pl-thumb img { width: 100%; height: 100%; object-fit: cover; cursor: zoom-in; }
.pl-nophoto { font-size: .62rem; color: var(--color-muted); text-align: center; line-height: 1.2; }
.pl-row-actions { display: flex; flex-wrap: wrap; gap: var(--space-xs); margin-top: var(--space-xs); }
.pl-row-actions .btn { cursor: pointer; }

.pl-preview { display: flex; gap: var(--space-sm); align-items: center; margin-top: var(--space-xs); }
.pl-preview img {
  width: 84px; height: 84px; object-fit: cover;
  border-radius: var(--radius-md); border: 1px solid var(--color-border);
}

/* file input styled like the rest of the form, and big enough to tap */
.field input[type="file"] {
  padding: var(--space-xs); min-height: 44px; line-height: 1.4; font-size: .9rem;
}

/* full-screen photo viewer */
.photo-viewer {
  position: fixed; inset: 0; z-index: 500; background: rgba(0,0,0,.92);
  display: grid; place-items: center; gap: var(--space-md);
  grid-template-rows: 1fr auto; padding: var(--space-md);
  padding-bottom: calc(var(--space-md) + env(safe-area-inset-bottom));
}
.photo-viewer img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--radius-md); }
.photo-viewer .btn { background: rgba(255,255,255,.14); color: #fff; border-color: transparent; }

@media (max-width: 700px) {
  .pl-thumb { width: 76px; height: 76px; }
  .pl-row-actions { display: grid; grid-template-columns: 1fr 1fr; }
  .pl-row-actions .btn { width: 100%; }
}

/* negative balances need to stand out — the ERP data has many, and they signal
   an error worth chasing rather than a real quantity */
.qty-neg { color: var(--color-danger); font-weight: 650; }

/* stock count entry — the number field is the whole job, so make it big */
.count-input {
  width: 110px; min-height: 44px; padding: 0 var(--space-sm); font: inherit; font-size: 16px;
  text-align: right; font-variant-numeric: tabular-nums;
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  background: var(--color-surface); color: var(--color-text);
}
.count-input:focus { border-color: var(--color-accent); }
.count-input.saved { border-color: var(--color-ok); }
@media (max-width: 700px) { .count-input { width: 100%; } }

/* ── pickers (customer / item search results) ───────────────────────────── */
.picker { display: flex; flex-direction: column; gap: 2px; margin-top: var(--space-2xs); }
.picker-item {
  all: unset; cursor: pointer; display: flex; flex-direction: column; gap: 2px;
  min-height: 44px; justify-content: center;
  padding: var(--space-xs) var(--space-sm); border-radius: var(--radius-md);
  border: 1px solid var(--color-border); background: var(--color-surface);
}
.picker-item:hover, .picker-item:focus-visible { background: var(--color-accent-wash); border-color: var(--color-accent); }
.picker-item .code { font-size: .76rem; color: var(--color-muted); }
#isearch-results .picker { padding: var(--space-sm) var(--space-md) var(--space-md); }


/* ── item detail page + scanner ───────────────────────────────────────────── */
.code-link { color: var(--color-accent-text); text-decoration: none; }
.code-link:hover { text-decoration: underline; text-underline-offset: 2px; }

#nav-scan {
  display: none; align-items: center; gap: var(--space-sm); width: 100%;
  min-height: 44px; padding: 0 var(--space-sm); border-radius: var(--radius-md);
  color: var(--color-text); font: inherit; font-size: .9rem; font-weight: 500;
  background: none; border: 0; cursor: pointer; text-align: left;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
#nav-scan:not([hidden]) { display: flex; }
#nav-scan:hover { background: var(--color-accent-wash); color: var(--color-accent-text); }
#nav-scan svg { width: 18px; height: 18px; flex: none; stroke-width: 1.75; }

.it-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-md); margin-bottom: var(--space-md); }
@media (max-width: 800px) { .it-grid { grid-template-columns: 1fr; } }
.it-pad { padding: var(--space-md); margin-bottom: var(--space-md); }
.it-grid .it-pad { margin-bottom: 0; }
.it-pad h2 { margin-bottom: var(--space-sm); }

.it-gal { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: var(--space-xs); }
.it-galimg {
  padding: 0; border: 1px solid var(--color-border); border-radius: var(--radius-md);
  background: #fff; cursor: zoom-in; aspect-ratio: 1; overflow: hidden;
}
.it-galimg img { width: 100%; height: 100%; object-fit: contain; display: block; }
.it-galimg:first-child { grid-column: span 2; grid-row: span 2; }

.it-nums { display: flex; gap: var(--space-xl); margin-bottom: var(--space-md); }
.it-big { font-size: 1.8rem; font-weight: 700; color: var(--color-heading); font-variant-numeric: tabular-nums; }
.it-tbl { width: 100%; }
.it-notes .ab-thumb img { max-width: 160px; max-height: 120px; }

.lp-list { list-style: none; margin: 0 0 var(--space-md); padding: 0; display: grid; gap: var(--space-2xs); }
.lp-pick {
  display: flex; align-items: center; gap: var(--space-sm); width: 100%; text-align: left;
  padding: var(--space-2xs) var(--space-xs); font: inherit; font-size: .87rem;
  color: var(--color-text); background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius-md); cursor: pointer;
}
.lp-pick:hover { border-color: var(--color-accent); background: var(--color-accent-wash); }
.lp-pick img { width: 44px; height: 44px; object-fit: contain; background: #fff; border-radius: var(--radius-sm); flex: none; }
.lp-noimg { width: 44px; height: 44px; flex: none; display: grid; place-items: center;
  font-size: .62rem; color: var(--color-muted); border: 1px dashed var(--color-border); border-radius: var(--radius-sm); }

#scan-view {
  position: fixed; inset: 0; z-index: 200; background: #000;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
#scan-cam { width: 100%; height: 100%; object-fit: cover; position: absolute; inset: 0; }
.scan-frame {
  position: relative; width: min(70vw, 340px); aspect-ratio: 1;
  border: 3px solid #fff; border-radius: var(--radius-lg);
  box-shadow: 0 0 0 100vmax rgba(0, 0, 0, .45);
}
.scan-hint {
  position: relative; color: #fff; margin-top: var(--space-md);
  max-width: min(90vw, 420px); text-align: center; text-wrap: balance;
  padding: var(--space-xs) var(--space-md); border-radius: var(--radius-pill);
  background: rgba(0, 0, 0, .6); text-shadow: 0 1px 3px #000;
}
/* Result colour is never the ONLY cue — the wording says what happened, and a
   vibration pattern carries it when the phone is at arm's length on a rack. */
.scan-hint--good { background: rgba(21, 128, 61, .85); }
.scan-hint--bad  { background: rgba(153, 27, 27, .85); }
#scan-view #scan-close {
  position: absolute; top: max(var(--space-md), env(safe-area-inset-top, 0px)); right: var(--space-md);
  background: rgba(0, 0, 0, .55); color: #fff; border-color: rgba(255, 255, 255, .5);
}
#scan-view #scan-torch {
  position: absolute; bottom: max(var(--space-xl), env(safe-area-inset-bottom, 0px));
  left: 50%; transform: translateX(-50%); min-height: 44px;
  background: rgba(0, 0, 0, .55); color: #fff; border-color: rgba(255, 255, 255, .5);
}
/* Shown only when leading zeros make a scan genuinely ambiguous — "002" and
   "0002" are different products, so the person picks rather than the code
   guessing. Rare, so it may sit over the camera. */
.scan-pick-list {
  position: relative; z-index: 1; margin-top: var(--space-md);
  width: min(92vw, 420px); max-height: 45vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--space-2xs);
}
.scan-pick {
  display: flex; flex-direction: column; gap: 2px; text-align: left;
  min-height: 44px; padding: var(--space-xs) var(--space-md);
  background: rgba(255, 255, 255, .96); color: var(--color-text);
  border: 1px solid rgba(0, 0, 0, .15); border-radius: var(--radius-md);
  font: inherit; cursor: pointer;
}
.scan-pick .code { font-weight: 600; }
.scan-pick span:last-child { font-size: .82rem; color: var(--color-muted); }
.scan-pick:hover, .scan-pick:focus-visible { border-color: var(--color-accent); }
.scan-pick--cancel { align-items: center; background: rgba(0, 0, 0, .55); color: #fff;
  border-color: rgba(255, 255, 255, .5); }

/* ── printed quotation ───────────────────────────────────────────────────────
   Reproduces the SkyBiz "Quotation_AGTechnology" template Airgas customers
   already receive. Arial + 9pt matches the ERP's own print settings.
   Off-screen until body.printing so the app never flashes it.               */

#print-root { display: none; }

.pq {
  /* SkyBiz's PDF engine sets the document in DejaVu Sans; Verdana is the closest
     universally-installed match, so the two documents read as the same typeface */
  font-family: Verdana, 'DejaVu Sans', Arial, Helvetica, sans-serif;
  font-size: 9pt; line-height: 1.35;
  color: #000; background: #fff;
  width: 210mm; min-height: 297mm; margin: 0 auto;
  padding: 10mm 12mm 12mm;
  /* SkyBiz renders in fixed black-on-white; dark mode must not leak in */
  color-scheme: light;
}
.pq * { color: #000; }

/* The app's global table chrome — sticky dark headers, uppercase labels, a rule under
   every row, hover tint — must not leak onto a customer document. Reset here, then the
   rules below re-apply exactly the lines SkyBiz draws. Kept at the same specificity as
   those rules (one class + one element) so source order decides, not a specificity war. */
.pq table { width: auto; border-collapse: collapse; font-size: inherit; }
.pq th, .pq td {
  position: static; background: transparent; border: 0; padding: 0;
  color: #000; font-size: inherit; font-weight: inherit; letter-spacing: normal;
  text-transform: none; white-space: normal; text-align: left; vertical-align: top;
}
.pq tr:hover { background: transparent; }

/* ── letterhead ── */
.pq-head { display: table; width: 100%; table-layout: fixed; }
.pq-head-l {
  display: table-cell; vertical-align: top; width: 64%;
  /* the banner artwork is set in a condensed grotesque, not the document face */
  font-family: 'Arial Narrow', 'Roboto Condensed', 'Liberation Sans Narrow', Arial, sans-serif;
}
.pq-head-r { display: table-cell; vertical-align: top; text-align: right; }
.pq-logo { width: 54mm; height: auto; }
.pq-nameblock { display: inline-block; }
.pq-nameblock .pq-reg { text-align: right; }
.pq-tel { clear: both; }
.pq-mail-r { float: right; }

/* the five category badges, mirroring the SkyBiz banner. `.pq * { color:#000 }`
   would turn the SVGs black — this rule outranks it (two classes beat one). */
.pq .pq-icons { text-align: right; margin-top: 1.5mm; }
.pq .pq-ico { display: inline-block; vertical-align: top; text-align: left; width: 12.6mm; margin-left: .6mm; }
/* the colour must sit on the <svg> itself: `.pq *` matches it directly, and a direct
   match always beats a value inherited from .pq-ico, however specific that rule is. */
.pq .pq-ico svg { width: 9.5mm; height: 9.5mm; display: block; color: #F26522; }
/* `.pq *` also matches the shapes INSIDE the svg, so their own colour would be black and
   currentColor would resolve black on every stroke/fill. Let them inherit the orange. */
.pq .pq-ico svg * { color: inherit; }
.pq .pq-ico span {
  display: block; margin-top: .4mm; color: #000; text-align: left;
  font-size: 5.2pt; line-height: 1.1; letter-spacing: -.01em;
}

.pq-co   { font-size: 18pt; letter-spacing: .01em; line-height: 1.1; }
.pq-reg  { font-size: 8.5pt; margin-top: 1mm; }
.pq-tel,
.pq-mail { font-size: 8.5pt; }
.pq-web  {
  background: #58595B; color: #fff !important;
  font-family: 'Segoe UI', Verdana, Arial, sans-serif;
  font-size: 11pt; font-weight: 700;
  padding: 1mm 4mm; display: block; margin: 1.5mm 0 1mm;
  /* browsers drop backgrounds when printing unless told otherwise */
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.pq-addr { font-size: 8pt; margin-top: 1.5mm; }

/* ── title ── */
.pq-title {
  font-size: 15pt; font-weight: 700; text-align: center;
  margin: 6mm 0 1.5mm; letter-spacing: .03em;
}
.pq-bar { border-top: 1.6pt solid #000; margin-bottom: 3mm; }

/* ── customer + document meta ── */
.pq-parties { display: table; width: 100%; table-layout: fixed; margin-bottom: 4mm; }
.pq-party { display: table-cell; vertical-align: top; width: 55%; padding-right: 6mm; }
.pq-meta  { display: table-cell; vertical-align: top; }

.pq-cust { font-size: 12pt; font-weight: 700; margin-bottom: 2.5mm; }
.pq-attn td, .pq-meta td { font-size: 9pt; padding: .2mm 0; vertical-align: top; }
.pq .pq-ml { white-space: nowrap; padding-right: 3mm !important; font-weight: 700; }
.pq .pq-mc { width: 3mm; padding-right: 2mm !important; }
.pq-meta table { width: 100%; border-collapse: collapse; }
.pq .pq-mv { width: 100%; }
.pq .pq-b { font-weight: 700; }

.pq-intro { margin: 0 0 2.5mm; }

/* ── line table ── */
.pq-tbl { width: 100%; border-collapse: collapse; table-layout: fixed; }
.pq-tbl th {
  font-size: 9pt; font-weight: 400; text-align: left;
  border-top: .8pt solid #000; border-bottom: .8pt solid #000;
  padding: 1.2mm 2mm 1.2mm 0;
}
.pq-tbl td { padding: 1mm 2mm 1mm 0; vertical-align: top; word-wrap: break-word; }
.pq-tbl th:last-child, .pq-tbl td:last-child { padding-right: 0; }
.pq-tbl .pq-code { width: 24mm; }
.pq-tbl th:nth-child(3), .pq-tbl td:nth-child(3) { width: 16mm; }
.pq-tbl th:nth-child(4), .pq-tbl td:nth-child(4) { width: 14mm; }
.pq-tbl th:nth-child(5), .pq-tbl td:nth-child(5) { width: 24mm; }
.pq-tbl th:nth-child(6), .pq-tbl td:nth-child(6) { width: 26mm; }
.pq .pq-r { text-align: right; }
.pq .pq-c { text-align: center; }
/* a line must not be split across a page break */
.pq-tbl tr { break-inside: avoid; page-break-inside: avoid; }
.pq-tbl thead { display: table-header-group; }

.pq-rule { border-top: .8pt solid #000; margin-bottom: 3mm; }

/* ── settlement block ── */
.pq-foot { display: table; width: 100%; table-layout: fixed; break-inside: avoid; page-break-inside: avoid; }
.pq-foot-l { display: table-cell; vertical-align: top; padding-right: 8mm; }
.pq-foot-r { display: table-cell; vertical-align: top; width: 62mm; }

.pq-words { font-weight: 400; }
.pq-eoe   { margin: 1mm 0 4mm; font-weight: 700; font-style: italic; }
.pq-bank  { line-height: 1.45; }
.pq-payee { margin-top: 3.5mm; line-height: 1.45; }

.pq-total { border: .9pt solid #000; border-collapse: collapse; width: 100%; }
.pq-total td { padding: 1.5mm 2.5mm; }
.pq .pq-tl { font-weight: 700; white-space: nowrap; }
.pq .pq-tc { font-weight: 700; text-align: center; padding-top: 0; }
.pq .pq-tv { text-align: right; font-size: 10pt; font-weight: 700; white-space: nowrap; }

.pq-note { margin: 5mm 0 0; line-height: 1.45; }

.pq-sign { margin-top: 2mm; break-inside: avoid; page-break-inside: avoid; }
.pq-sig-line {
  border-bottom: .9pt solid #000; width: 78mm; margin-top: 14mm;
  text-align: center; line-height: 1;
}
.pq-sig-line span { font-size: 9pt; }

/* ── on-screen preview + the print pass itself ────────────────────────────── */
@media screen {
  body.printing { overflow: hidden; }
  body.printing > *:not(#print-root) { display: none !important; }
  body.printing #print-root {
    display: block; position: fixed; inset: 0; overflow: auto;
    background: #4a4a4a; padding: 8mm 0; z-index: 9999;
  }
  body.printing .pq { box-shadow: 0 2px 18px rgba(0,0,0,.45); }
}

@page { size: A4 portrait; margin: 0; }

@media print {
  /* only the document goes on paper */
  body > *:not(#print-root) { display: none !important; }
  #print-root { display: block; }
  html, body { background: #fff; margin: 0; padding: 0; }
  .pq { width: auto; min-height: 0; margin: 0; box-shadow: none; }
}

/* ── AirBot chat UI ─────────────────────────────────────────────────────────
   A shortcut to the data, never a replacement for it — every answer carries a
   link into the real table, and the panel gets out of the way when you take it. */

.ab-fab {
  position: fixed; right: var(--space-lg); bottom: var(--space-lg); z-index: 60;
  display: inline-flex; align-items: center; gap: var(--space-xs);
  min-height: 48px; padding: 0 var(--space-md);
  font: inherit; font-weight: 600; font-size: .9rem;
  color: #fff; background: var(--color-accent);
  border: 1px solid transparent; border-radius: var(--radius-pill);
  box-shadow: var(--shadow-md); cursor: pointer;
  transition: background var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.ab-fab:hover { background: var(--color-accent-hover); }
.ab-fab:active { transform: scale(.98); }
.ab-fab svg { width: 20px; height: 20px; flex: none; stroke-width: 1.75; }

.ab-panel {
  position: fixed; right: var(--space-lg); bottom: var(--space-lg); z-index: 61;
  width: min(410px, calc(100vw - 2 * var(--space-lg)));
  max-height: min(620px, calc(100dvh - 2 * var(--space-lg)));
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
.ab-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-sm); padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--color-border); background: var(--color-accent-wash);
}
.ab-head strong { color: var(--color-heading); }
.ab-dim { color: var(--color-muted); font-size: .78rem; }

.ab-log {
  flex: 1; min-height: 140px; overflow-y: auto; overscroll-behavior: contain;
  padding: var(--space-md); display: flex; flex-direction: column; gap: var(--space-sm);
}
.ab-msg {
  max-width: 92%; padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-md); font-size: .87rem; line-height: 1.5;
  overflow-wrap: anywhere;
}
.ab-msg p { margin: 0 0 var(--space-xs); }
.ab-msg p:last-child { margin-bottom: 0; }
.ab-bot { align-self: flex-start; background: var(--color-bg); border: 1px solid var(--color-border); }
.ab-me  { align-self: flex-end; background: var(--color-accent); color: #fff; }
.ab-me::selection, .ab-me *::selection { background: #fff; color: var(--color-accent-pressed); }

.ab-form {
  display: flex; gap: var(--space-xs); padding: var(--space-sm) var(--space-md) var(--space-md);
  border-top: 1px solid var(--color-border);
}
.ab-form input {
  flex: 1; min-width: 0; min-height: 44px; padding: 0 var(--space-sm);
  font: inherit; font-size: 16px;              /* 16px stops iOS zoom-on-focus */
  color: var(--color-text); background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
}
.ab-form input:focus { border-color: var(--color-accent); }
.ab-form .btn { flex: none; }

/* ── answer internals ── */
.ab-list { margin: var(--space-2xs) 0 0; padding-left: 1.15em; display: grid; gap: var(--space-2xs); }
.ab-list li { line-height: 1.5; }

.ab-code {
  font-family: var(--mono); font-size: .93em; font-weight: 600;
  color: var(--color-accent-text); text-decoration: underline;
  text-underline-offset: 2px;
}
.ab-verify { margin-top: var(--space-xs) !important; font-size: .82rem; }
.ab-neg { color: var(--color-danger); }

.ab-tag {
  display: inline-block; padding: 0 6px; border-radius: var(--radius-pill);
  background: var(--color-accent-tint); color: var(--color-accent-text);
  font-size: .72rem; font-weight: 600; white-space: nowrap;
}

.ab-chips { display: flex; flex-wrap: wrap; gap: var(--space-2xs); margin-top: var(--space-xs); }
.ab-chip {
  min-height: 32px; padding: 0 var(--space-sm); font: inherit; font-size: .78rem; font-weight: 600;
  color: var(--color-accent-text); background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius-pill); cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.ab-chip:hover { background: var(--color-accent-wash); border-color: var(--color-accent); }
.ab-chip--inline { min-height: 26px; padding: 0 var(--space-xs); font-size: .72rem; margin-left: var(--space-2xs); }

/* rows that lead with a product photo */
.ab-hasimg { display: flex; align-items: flex-start; gap: var(--space-xs); }
.ab-imgbody { flex: 1; min-width: 0; }
.ab-prodimg {
  width: 38px; height: 38px; flex: none; object-fit: contain;
  background: #fff; border: 1px solid var(--color-border); border-radius: var(--radius-sm);
}

.ab-place-group { margin-top: var(--space-xs); }
.ab-place-head { font-weight: 600; color: var(--color-heading); }
.ab-place-hint { margin-top: 2px; font-size: .8rem; color: var(--color-muted); }
.ab-remark {
  margin-top: 2px; padding-left: var(--space-xs); font-size: .82rem;
  color: var(--color-muted); border-left: 2px solid var(--color-accent-tint);
}
.ab-thumb { margin-top: var(--space-2xs); cursor: zoom-in; }
.ab-thumb img {
  max-width: 120px; max-height: 90px; border-radius: var(--radius-sm);
  border: 1px solid var(--color-border); display: block;
}

/* three-dot "thinking" indicator */
.ab-typing { display: inline-flex; gap: 4px; align-items: center; padding: 2px 0; }
.ab-typing span {
  width: 6px; height: 6px; border-radius: 50%; background: var(--color-muted);
  animation: ab-blink 1.2s infinite ease-in-out both;
}
.ab-typing span:nth-child(2) { animation-delay: .16s; }
.ab-typing span:nth-child(3) { animation-delay: .32s; }
@keyframes ab-blink { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .ab-typing span { animation: none; opacity: .55; } }

/* "Showing what AirBot found for X" banner above a filtered table */
.from-bot {
  margin: 0 0 var(--space-md); padding: var(--space-xs) var(--space-sm);
  background: var(--color-accent-wash); border: 1px solid var(--color-accent-tint);
  border-radius: var(--radius-md); font-size: .85rem;
}
.linkish {
  font: inherit; font-size: inherit; color: var(--color-accent-text);
  background: none; border: 0; padding: 0; cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}

/* on a phone the panel is a full-width sheet, and the FAB tucks in */
@media (max-width: 640px) {
  .ab-fab { right: var(--space-md); bottom: var(--space-md); }
  .ab-panel {
    right: 0; left: 0; bottom: 0; width: auto;
    max-height: 82dvh; border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    border-left: 0; border-right: 0; border-bottom: 0;
  }
  .ab-form { padding-bottom: calc(var(--space-md) + env(safe-area-inset-bottom, 0px)); }
}

/* ── AirBot answer rating ──────────────────────────────────────────────────
   Accuracy is unmeasured; this is the only honest source of truth. Kept quiet
   so it never nags, and "Not right" is the same one tap as "Yes". */
.ab-rate { display: flex; align-items: center; gap: var(--space-xs);
  flex-wrap: wrap; margin-top: var(--space-sm); padding-top: var(--space-xs);
  border-top: 1px solid var(--color-border); font-size: .78rem; }
.ab-rate .count-input { flex: 1; min-width: 140px; }

/* ── web product editor ──────────────────────────────────────────────────────
   Laid out like the WooCommerce "Add new product" screen the boss already
   knows: title + description in a wide main column, Publish / Categories /
   Product image / Gallery panels in a right-hand rail. Stacks on phones. */
.wp-grid { display: grid; grid-template-columns: minmax(0, 1fr) 300px;
  gap: var(--space-lg); align-items: start; }
.wp-main, .wp-side { display: grid; gap: var(--space-lg); min-width: 0; }
/* inner grid items must not inherit their children's intrinsic min-content
   (the title input's default size-20 floor forced a sideways scroll <375px) */
.wp-main > *, .wp-side > * { min-width: 0; }
.wp-title-input { min-width: 0; }
@media (max-width: 900px) { .wp-grid { grid-template-columns: 1fr; } }

.wp-title-input { width: 100%; min-height: 52px; font: inherit; font-size: 1.3rem;
  font-weight: 650; color: var(--color-heading); background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  padding: var(--space-sm) var(--space-md); }
.wp-title-input:focus { border-color: var(--color-accent); }
.wp-permalink { font-size: .8rem; color: var(--color-muted);
  margin: var(--space-2xs) 0 0; overflow-wrap: anywhere; }

.wp-panel { background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); }
.wp-panel > h2 { font-size: .88rem; padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--color-border); }
.wp-panel-body { padding: var(--space-md); }
.wp-panel-body textarea { width: 100%; font: inherit; font-size: 16px;
  color: var(--color-text); background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  padding: var(--space-sm); resize: vertical; }
.wp-panel-body textarea:focus { border-color: var(--color-accent); }

.wp-2col { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-md); }
@media (max-width: 640px) { .wp-2col { grid-template-columns: 1fr; } }

.wp-pubrow { display: flex; gap: var(--space-sm); flex-wrap: wrap;
  margin-bottom: var(--space-sm); }
.wp-pubrow .btn { flex: 1; }

.wp-cats { max-height: 220px; overflow-y: auto; display: grid;
  gap: var(--space-2xs); margin: 0 0 var(--space-xs); padding: 0; list-style: none; }
.wp-cats label { display: flex; align-items: center; gap: var(--space-xs);
  font-size: .9rem; min-height: 32px; cursor: pointer; }
.wp-cats input { width: 18px; height: 18px; accent-color: var(--color-accent); }

.wp-thumb { display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: contain;
  background: var(--ink-50); border: 1px solid var(--color-border);
  border-radius: var(--radius-md); margin-bottom: var(--space-sm); }
div.wp-thumb--none { display: grid; place-items: center; color: var(--color-muted);
  font-size: .85rem; }
@media (prefers-color-scheme: dark) { .wp-thumb { background: #2A2D33; } }

.wp-gal { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-xs);
  margin-bottom: var(--space-sm); }
.wp-gal figure { margin: 0; position: relative; }
.wp-gal img { display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover;
  border: 1px solid var(--color-border); border-radius: var(--radius-sm); }
.wp-gal button { position: absolute; top: 2px; right: 2px; width: 24px; height: 24px;
  display: grid; place-items: center; border: 0; border-radius: var(--radius-sm);
  background: rgba(31,32,36,.72); color: #fff; font-size: 1rem; line-height: 1;
  cursor: pointer; }
.wp-gal button:hover { background: var(--color-danger); }

.wp-filelink { display: inline-block; color: var(--color-accent-text);
  font-size: .85rem; font-weight: 600; text-decoration: underline; cursor: pointer; }
.wp-rmlink { display: block; margin-top: var(--space-2xs); font-size: .8rem; }

.wp-listthumb { display: block; width: 44px; height: 44px; object-fit: contain;
  background: var(--ink-50); border: 1px solid var(--color-border);
  border-radius: var(--radius-sm); }
span.wp-listthumb { display: grid; place-items: center; color: var(--color-muted); }
td.wp-cell-img { width: 56px; }

.badge--ok { background: rgba(4,120,87,.14); color: var(--color-ok); }
@media (prefers-color-scheme: dark) { .badge--ok { color: #34D399; } }

/* ── product documents (datasheets / catalogues) ── */
.wp-files { list-style: none; margin: 0 0 var(--space-sm); padding: 0;
  display: grid; gap: var(--space-2xs); }
.wp-files li { display: flex; align-items: center; gap: var(--space-sm);
  min-width: 0; min-height: 44px; padding: var(--space-2xs) var(--space-xs);
  border: 1px solid var(--color-border); border-radius: var(--radius-md); }
.wp-file-ext { flex: none; min-width: 42px; text-align: center; padding: 4px 6px;
  font-size: .68rem; font-weight: 700; letter-spacing: .04em;
  color: var(--color-accent-text); background: var(--color-accent-tint);
  border-radius: var(--radius-sm); }
.wp-file-name { flex: 1; min-width: 0; font-size: .9rem; font-weight: 550;
  color: var(--color-accent-text); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.wp-file-size { flex: none; font-size: .78rem; color: var(--color-muted); }
.wp-files button { flex: none; width: 36px; height: 36px; display: grid;
  place-items: center; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--color-muted); font-size: 1.1rem;
  line-height: 1; cursor: pointer; }
.wp-files button:hover, .wp-files button:focus-visible {
  background: var(--color-danger); color: #fff; }

/* ── drag & drop onto the editor's upload panels ── */
.wp-panel.is-dragover {
  border-color: var(--color-accent);
  border-style: dashed;
  background: var(--color-accent-wash);
}
.wp-drophint { margin: var(--space-2xs) 0 0; }
/* drag & drop needs a mouse — don't advertise it on touch screens */
@media (hover: none) { .wp-drophint { display: none; } }

/* ── mobile: Woo-app-style pinned save bar ── */
@media (max-width: 767px) {
  .wp-pubrow { position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
    margin: 0;
    padding: var(--space-sm) var(--space-md)
      calc(var(--space-sm) + env(safe-area-inset-bottom));
    background: var(--color-surface); border-top: 1px solid var(--color-border);
    box-shadow: 0 -4px 16px rgba(0,0,0,.12); }
  .wp-pubrow .btn { min-height: 48px; }
  /* keep the pinned bar from covering the last panels / the AirBot launcher */
  .wp-grid { padding-bottom: 88px; }
  body:has(.wp-pubrow) .ab-fab,
  body:has(.wp-pubrow) .ab-panel { bottom: calc(var(--space-lg) + 76px); }
  .wp-filelink { display: inline-flex; align-items: center; min-height: 44px; }
}

/* ── activity log (owners only) ── */
.al-filters { display: flex; flex-wrap: wrap; gap: var(--space-sm);
  align-items: center; padding: var(--space-md);
  border-bottom: 1px solid var(--color-border); }
.al-filters input[type="search"] { flex: 1 1 240px; min-width: 0; min-height: 44px;
  font: inherit; font-size: 16px; padding: 0 var(--space-sm);
  color: var(--color-text); background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius-md); }
.al-filters select { min-height: 44px; font: inherit; font-size: 16px;
  padding: 0 var(--space-sm); color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius-md); }
.al-count { margin-left: auto; font-size: .85rem; color: var(--color-muted); }

.al-table td { vertical-align: top; }
.al-when { white-space: nowrap; font-variant-numeric: tabular-nums;
  color: var(--color-muted); font-size: .85rem; }
.al-role { font-size: .72rem; color: var(--color-muted); text-transform: uppercase;
  letter-spacing: .04em; }
.al-sys { font-style: italic; color: var(--color-muted); }
.al-id { font-family: var(--mono); font-size: .75rem;
  color: var(--color-muted); }
.al-dim { color: var(--color-muted); }

.al-act { display: inline-block; padding: 1px 7px; border-radius: var(--radius-pill);
  font-size: .72rem; font-weight: 650; letter-spacing: .02em;
  background: var(--color-accent-tint); color: var(--color-accent-text); }
.al-act--insert { background: rgba(4,120,87,.14); color: var(--color-ok); }
.al-act--delete { background: rgba(190,18,60,.12); color: var(--color-danger); }
.al-act--login  { background: var(--ink-50); color: var(--color-muted); }
@media (prefers-color-scheme: dark) {
  .al-act--insert { color: #34D399; }
  .al-act--login  { background: #2A2D33; }
}

.al-diff { margin: 0; padding: 0; list-style: none; display: grid; gap: 2px; }
.al-diff li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px;
  font-size: .82rem; line-height: 1.4; }
.al-field { font-family: var(--mono); font-size: .74rem;
  color: var(--color-muted); }
.al-old { text-decoration: line-through; color: var(--color-muted);
  overflow-wrap: anywhere; }
.al-new { color: var(--color-text); overflow-wrap: anywhere; }
.al-arrow { color: var(--color-muted); }
.al-more { padding: var(--space-md); text-align: center; }

@media (max-width: 767px) {
  .al-count { margin-left: 0; width: 100%; }
  .al-table .al-when { font-size: .78rem; }
}

/* ── create staff account (owners, on Users & access) ── */
.ua-form-body { padding: var(--space-md); display: grid; gap: var(--space-md);
  max-width: 460px; }
.ua-pw { align-items: flex-start; }
.ua-pw-row { display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-sm); margin-top: var(--space-xs); }
.ua-pw-row code { font-family: var(--mono); font-size: 1rem; font-weight: 650;
  letter-spacing: .02em; padding: 6px 10px; border-radius: var(--radius-md);
  background: var(--color-surface); border: 1px solid var(--color-border);
  color: var(--color-heading); user-select: all; overflow-wrap: anywhere; }

/* link-words-to-document helper (2026-08-21) */
.wp-linkrow { margin: var(--space-xs) 0 0; }
.wp-linkpick-slot .linkish { margin-inline: 2px; }
