/* Princy — industrial utility SaaS
   Light theme by default; theme accents switchable via CSS vars. */

:root {
  /* Warm neutral surface palette */
  --bg:          #F3F0EA;    /* bone/paper */
  --surface:    #FFFFFF;
  --surface-1:  #FFFFFF;
  --surface-2:  #FAF7F1;
  --surface-3:  #EDE8DF;
  --ink:        #141210;
  --ink-2:      #2A2621;
  --muted:      #6B6358;
  --muted-2:    #94897B;
  --line:       #D9D2C4;
  --line-2:     #E7E1D3;
  --hairline:   #C9C1B1;

  /* Accent — the chapter's brand red, #C91C2E, everywhere. There is no
     accent picker: one colour across admin, member panel and public site. */
  --accent:        #C91C2E;
  --accent-ink:    #ffffff;
  --accent-soft:   #FBE8EA;
  --accent-2:      #A11524;

  /* Status */
  --ok:      oklch(0.62 0.14 150);
  --ok-soft: oklch(0.94 0.05 150);
  --warn:    oklch(0.72 0.16 60);
  --warn-soft: oklch(0.94 0.06 75);
  --err:     oklch(0.58 0.19 25);
  --err-soft: oklch(0.94 0.06 25);
  --info:    oklch(0.58 0.11 240);
  --info-soft: oklch(0.94 0.04 240);
  --slate:    #6B6358;
  --slate-soft: #EDE8DF;

  /* Typography */
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* Density (comfortable default) */
  --row-pad-y: 12px;
  --row-pad-x: 14px;
  --cell-pad-y: 10px;
  --cell-pad-x: 12px;
  --btn-pad-y: 8px;
  --btn-pad-x: 14px;
  --card-pad: 18px;
  --radius: 6px;
  --radius-sm: 4px;

  color-scheme: light;
}

:root[data-density="compact"] {
  --row-pad-y: 7px;
  --row-pad-x: 10px;
  --cell-pad-y: 6px;
  --cell-pad-x: 10px;
  --btn-pad-y: 6px;
  --btn-pad-x: 11px;
  --card-pad: 13px;
}

/* ===== Dark mode ===== */
:root[data-mode="dark"] {
  --bg:        #0c1017;
  --surface:   #131920;
  --surface-1: #131920;
  --surface-2: #1a2230;
  --surface-3: #1f2937;
  --ink:       #dde6f0;
  --ink-2:     #b8c8da;
  --muted:     #6b7f96;
  --muted-2:   #4a5e72;
  --line:      #1e2d3e;
  --line-2:    #192536;
  --hairline:  #253848;
  --slate:     #6b7f96;
  --slate-soft: #1a2230;

  --ok-soft:   oklch(0.22 0.06 150);
  --warn-soft: oklch(0.22 0.07 65);
  --err-soft:  oklch(0.22 0.06 25);
  --info-soft: oklch(0.22 0.04 240);

  color-scheme: dark;
}
/* On a dark ground the deep red reads poorly as text, so the second accent
   lifts; the soft tint darkens to sit behind it. */
:root[data-mode="dark"] { --accent-soft: #3A1519; --accent-2: #E34A57; }

* { box-sizing: border-box; }
html, body, #root { height: 100%; }
body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.4;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "cv11","ss01","ss03";
}
code, .mono, .num { font-family: var(--font-mono); font-feature-settings: "tnum","zero"; letter-spacing: -0.01em; }
.num { font-variant-numeric: tabular-nums; }

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; padding: 0; }
input, select, textarea { font: inherit; color: inherit; }

/* ----- App shell ----- */
.app {
  display: grid;
  /* Set by dragging the sidebar's border; 236px until it is. */
  grid-template-columns: var(--sbw, 236px) 1fr;
  grid-template-rows: 56px 1fr;
  grid-template-areas: "sidebar topbar" "sidebar main";
  height: 100vh;
  background: var(--bg);
  transition: grid-template-columns 0.22s cubic-bezier(0.4, 0, 0.2, 1);
}
:root[data-sidebar="collapsed"] .app {
  grid-template-columns: 52px 1fr;
}
.sidebar {
  grid-area: sidebar;
  background: #0f1623;
  color: #dde4ef;
  border-right: 1px solid #060d18;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  width: var(--sbw, 236px);
  transition: width 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  flex-shrink: 0;
  position: relative;
}
/* Collapsed: thin 52px rail */
:root[data-sidebar="collapsed"] .sidebar {
  width: 52px;
}
/* Hover on collapsed rail: expand as overlay over content */
:root[data-sidebar="collapsed"] .sidebar.hovering {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: var(--sbw, 236px);
  z-index: 250;
  box-shadow: 6px 0 32px rgba(0, 0, 0, 0.5);
}
/* Center the JJ mark in the 52px rail */
:root[data-sidebar="collapsed"] .sidebar:not(.hovering) .brand {
  justify-content: center;
  padding: 0;
  border-bottom-color: #1a2535;
}
:root[data-sidebar="collapsed"] .sidebar:not(.hovering) .brand .brand-text,
:root[data-sidebar="collapsed"] .sidebar:not(.hovering) .brand .sidebar-toggle {
  display: none;
}
.sidebar .brand {
  height: 56px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 18px;
  border-bottom: 1px solid #1a2535;
}
.sidebar .brand .brand-home {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  text-decoration: none;
  color: inherit;
}
.sidebar .brand .mark {
  width: 28px; height: 28px;
  background: oklch(0.52 0.22 25);
  border-radius: 4px;
  display: grid; place-items: center;
  color: #ffffff;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: -0.03em;
}
.sidebar .brand .name {
  font-weight: 700;
  letter-spacing: 0.02em;
  font-size: 13px;
  text-transform: uppercase;
}
.sidebar .brand .sub {
  font-family: var(--font-mono);
  font-size: 10px;
  color: #7a8fa8;
  letter-spacing: 0.04em;
}
.sidebar-toggle {
  margin-left: auto;
  flex-shrink: 0;
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 4px;
  color: #7a8fa8;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.sidebar-toggle:hover { background: #1a2535; color: #c8d4e3; }
.sidebar nav {
  padding: 14px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-height: 0;        /* allow the flex child to shrink so it can scroll */
  overflow-y: auto;     /* vertical scroll when the menu is taller than the viewport */
  overflow-x: hidden;
  scrollbar-width: thin;
  scrollbar-color: #2a3650 transparent;
}
.sidebar nav::-webkit-scrollbar { width: 8px; }
.sidebar nav::-webkit-scrollbar-thumb { background: #2a3650; border-radius: 4px; }
.sidebar nav::-webkit-scrollbar-thumb:hover { background: #364465; }
.sidebar nav::-webkit-scrollbar-track { background: transparent; }
.sidebar .section-label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  color: #7a8fa8;
  padding: 14px 10px 6px;
  text-transform: uppercase;
}
/* Collapsible section header */
.sidebar .section-toggle {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: none;
  border: 0;
  cursor: pointer;
}
.sidebar .section-toggle:hover { color: #c8d4e3; }
.sidebar .section-toggle .nav-caret {
  width: 10px;
  height: 10px;
  color: #7a8fa8;
  flex-shrink: 0;
  transition: transform 0.15s ease;
}
.sidebar .section-toggle .nav-caret.collapsed { transform: rotate(-90deg); }
.sidebar .nav-group { display: flex; flex-direction: column; gap: 2px; }
[x-cloak] { display: none !important; }

/* Autocomplete dropdown input (partials/autocomplete) — styled the same
   inside or outside a .field wrapper. */
.ac-input,
.field .ac-input {
  width: 100%;
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 4px;
  padding: 8px 28px 8px 10px;
  font-size: 13px;
  outline: none;
  color: inherit;
}
.ac-input:focus,
.field .ac-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 20%, transparent);
}

/* Multi-select control + dropdown panel (reused by PO form & filters) */
.po-ms-control {
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 4px;
  padding: 6px 8px;
  min-height: 36px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
  cursor: pointer;
}
.po-ms-panel {
  position: absolute;
  z-index: 60;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(20, 18, 16, .15);
  max-height: 260px;
  overflow: auto;
  padding: 6px;
}
.po-ms-opt {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 5px 6px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 13px;
}
.po-ms-opt:hover { background: var(--surface-2); }

/* Transaction form layout helpers (shared by PO form + transaction engine) */
.po-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px 16px; }
.po-grid .span-all { grid-column: 1 / -1; }
@media (max-width: 760px) { .po-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .po-grid { grid-template-columns: 1fr; } }
.po-add {
  flex: 0 0 auto;
  width: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  color: #fff;
  border: 0;
  border-radius: 4px;
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
}
.po-add:hover { filter: brightness(1.06); }
.po-err { font-size: 11px; color: var(--err); margin-top: 3px; }
.req { color: var(--err); }

/* Role-permission toggle buttons */
.perm-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 66px;
  padding: 6px 14px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  border: 1px solid var(--accent);
  background: transparent;
  color: var(--accent);
  transition: background 0.12s, color 0.12s, filter 0.12s;
}
.perm-btn.on { background: var(--accent); color: #fff; }
.perm-btn:hover { filter: brightness(1.08); }

/* Urgent order row highlight (light red) */
.tbl tbody tr.tr-urgent { background: rgba(239, 68, 68, 0.28); }
.tbl tbody tr.tr-urgent:hover { background: rgba(239, 68, 68, 0.38); }
.navitem {
  position: relative;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 10px;
  border-radius: 4px;
  color: #c8d4e3;
  font-weight: 500;
  font-size: 13px;
  cursor: pointer;
  user-select: none;
  text-decoration: none;
}
.navitem:hover { background: #1a2535; color: #e8eef8; }
.navitem.active { background: #1a2535; color: #ffffff; }
.navitem.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px; height: 16px;
  background: var(--accent);
  border-radius: 2px;
}
.nav-icon {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  color: #7a8fa8;
  transition: color 0.12s;
}
.navitem:hover .nav-icon,
.navitem.active .nav-icon { color: inherit; }
.nav-label { flex: 1; }
.navitem .count {
  font-family: var(--font-mono);
  font-size: 11px;
  color: #7a8fa8;
}
.navitem.active .count { color: var(--accent); }

/* Collapsed rail: icon only, centred */
:root[data-sidebar="collapsed"] .sidebar:not(.hovering) .navitem {
  justify-content: center;
  padding: 9px 0;
  gap: 0;
}
:root[data-sidebar="collapsed"] .sidebar:not(.hovering) .nav-label,
:root[data-sidebar="collapsed"] .sidebar:not(.hovering) .navitem .count,
:root[data-sidebar="collapsed"] .sidebar:not(.hovering) .section-label {
  display: none;
}
:root[data-sidebar="collapsed"] .sidebar:not(.hovering) .nav-icon {
  color: #8a9fc0;
}
:root[data-sidebar="collapsed"] .sidebar:not(.hovering) .navitem:hover .nav-icon,
:root[data-sidebar="collapsed"] .sidebar:not(.hovering) .navitem.active .nav-icon {
  color: #e8eef8;
}

.sidebar .foot {
  padding: 12px 14px;
  border-top: 1px solid #1a2535;
  font-family: var(--font-mono);
  font-size: 10px;
  color: #7a8fa8;
  letter-spacing: 0.04em;
}

/* ----- Topbar ----- */
.topbar {
  grid-area: topbar;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  padding: 0 18px;
  gap: 16px;
}
.topbar .crumbs {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.topbar .crumbs b { color: var(--ink); font-weight: 600; }
.topbar .grow { flex: 1; }
.topbar .search {
  display: flex; align-items: center; gap: 8px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 6px 10px;
  width: 280px;
}
.topbar .search input {
  border: 0; background: transparent; outline: none;
  flex: 1; font-size: 13px;
}
.topbar .search kbd {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--muted);
  border: 1px solid var(--line);
  padding: 1px 5px;
  border-radius: 3px;
  background: var(--surface);
}
.topbar .tz {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
  border-left: 1px solid var(--line);
  padding-left: 16px;
}
.topbar .whoami {
  display: flex; align-items: center; gap: 10px;
  padding-left: 12px;
  border-left: 1px solid var(--line);
}
.avatar {
  width: 28px; height: 28px;
  background: var(--ink);
  color: #F5EFDF;
  border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
}

/* ----- Main ----- */
.main {
  grid-area: main;
  overflow: auto;
  padding: 22px 26px 60px;
}
.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 18px;
}
.page-head h1 {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0 0 4px;
}
.page-head .sub {
  color: var(--muted);
  font-size: 13px;
}
.page-head .actions { display: flex; gap: 8px; }

/* ----- Buttons ----- */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: var(--btn-pad-y) var(--btn-pad-x);
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 4px;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.12s, border 0.12s;
}
.btn:hover { background: var(--surface-2); border-color: var(--hairline); }
.btn.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}
.btn.primary:hover { filter: brightness(0.96); }
.btn.ghost { background: transparent; border-color: transparent; }
.btn.ghost:hover { background: var(--surface-2); }
/* Tinted accent — for secondary actions that still need to be found quickly
   (e.g. "Add Row" under a line-items grid). Lighter weight than .primary, so
   it doesn't compete with the form's Save button. */
.btn.accent {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent-2);
  font-weight: 600;
}
.btn.accent:hover { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn.danger { color: var(--err); }
.btn.sm { padding: 4px 8px; font-size: 12px; }
.btn.icon { padding: 6px 8px; }

/* ----- Cards ----- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.card .card-head {
  padding: 14px 18px;
  border-bottom: 1px solid var(--line-2);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.card .card-head h3 {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin: 0;
}
.card .card-body { padding: var(--card-pad); }
.card .card-body.flush { padding: 0; }

/* ----- KPI ----- */
.kpi-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 18px; }
.kpi {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 18px;
  position: relative;
  overflow: hidden;
}
.kpi::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px; background: var(--line-2);
}
.kpi.accent::before { background: var(--accent); }
.kpi .label {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.kpi .val {
  font-family: var(--font-mono);
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin-top: 6px;
  color: var(--ink);
}
.kpi .val.sm { font-size: 22px; }
.kpi .delta {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
  margin-top: 4px;
}
.kpi .delta.up { color: var(--ok); }
.kpi .delta.dn { color: var(--err); }

/* Interactive KPI cards — colour-invert + bouncy lift + shine on hover */
.kpi.kpi-hover {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: transform .32s cubic-bezier(.34,1.56,.64,1),
              box-shadow .32s ease, background-color .32s ease, border-color .32s ease;
}
.kpi.kpi-hover::before { display: none; }          /* remove the left accent bar */
.kpi.kpi-hover .label,
.kpi.kpi-hover .val { position: relative; z-index: 1; transition: color .32s ease; }
/* diagonal shine that sweeps across on hover */
.kpi.kpi-hover::after {
  content: "";
  position: absolute; top: 0; bottom: 0; left: -75%;
  width: 50%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.45), transparent);
  transform: skewX(-20deg);
  opacity: 0;
  pointer-events: none;
}
.kpi.kpi-hover:hover {
  transform: translateY(-7px) scale(1.035);
  box-shadow: 0 18px 34px rgba(0,0,0,.24);
}
.kpi.kpi-hover:hover .label,
.kpi.kpi-hover:hover .val { color: #fff !important; }
.kpi.kpi-hover:hover::after { opacity: 1; animation: kpiShine .75s ease; }
@keyframes kpiShine {
  0%   { left: -75%; }
  100% { left: 125%; }
}
.kpi.kpi-warn:hover   { background: var(--warn);   border-color: var(--warn); }
.kpi.kpi-err:hover    { background: var(--err);    border-color: var(--err); }
.kpi.kpi-accent:hover { background: var(--accent); border-color: var(--accent); }
@media (prefers-reduced-motion: reduce) {
  .kpi.kpi-hover { transition: background-color .2s ease, border-color .2s ease; }
  .kpi.kpi-hover:hover { transform: none; }
  .kpi.kpi-hover:hover::after { animation: none; opacity: 0; }
}

/* ----- Tables ----- */
.tbl { width: 100%; border-collapse: collapse; }
.tbl th, .tbl td {
  padding: var(--cell-pad-y) var(--cell-pad-x);
  text-align: left;
  border-bottom: 1px solid var(--line-2);
  font-size: 13px;
  vertical-align: middle;
}
.tbl th {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 1;
}
.tbl tbody tr { cursor: pointer; }
.tbl tbody tr:hover { background: var(--surface-2); }
.tbl tbody tr.selected { background: var(--accent-soft); }
.tbl td.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; text-align: right; }
.tbl th.num { text-align: right; }
/* Inline-edit inputs/selects inside tables — match the project's .field controls */
.tbl td input[type="text"], .tbl td input[type="number"], .tbl td input[type="date"], .tbl td select {
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 4px;
  padding: 6px 8px;
  font-size: 13px;
  color: var(--ink);
  outline: none;
  transition: border 0.12s, box-shadow 0.12s;
}
.tbl td input[type="text"]:focus, .tbl td input[type="number"]:focus, .tbl td input[type="date"]:focus, .tbl td select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 20%, transparent);
}
.tbl td.id { font-family: var(--font-mono); font-size: 12px; color: var(--ink-2); }
.tbl td.dim { color: var(--muted); }

/* ----- Master listing: click-to-sort headers + per-column filter row ----- */
.tbl th.th-sort { cursor: pointer; user-select: none; white-space: nowrap; }
.tbl th.th-sort:hover { color: var(--ink); }
.tbl th.th-sort .sort-ind { margin-left: 4px; font-family: var(--font-sans); font-size: 9px; }
.tbl th.th-sort .sort-ind.on { color: var(--accent); }
.tbl th.th-sort .sort-ind.off { color: var(--muted); opacity: 0.4; }

.tbl thead tr.col-filter-row th {
  position: static;               /* the heading row stays sticky, not this one */
  background: var(--surface-2);
  padding: 5px 8px;
  border-bottom: 1px solid var(--line);
}
.tbl thead tr.col-filter-row input.col-filter,
.tbl thead tr.col-filter-row select.col-filter {
  width: 100%;
  min-width: 70px;
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 4px;
  padding: 5px 8px;
  /* Reset the inherited mono/uppercase heading font. */
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  outline: none;
  transition: border 0.12s, box-shadow 0.12s;
}
.tbl thead tr.col-filter-row input.col-filter::placeholder {
  color: var(--muted);
  text-transform: none;
  letter-spacing: 0;
  font-size: 12px;
}
.tbl thead tr.col-filter-row input.col-filter:focus,
.tbl thead tr.col-filter-row select.col-filter:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 20%, transparent);
}

/* ----- Status pills ----- */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 8px;
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border: 1px solid transparent;
  white-space: nowrap;
}
.pill::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
}
.pill.ok      { color: var(--ok);    background: var(--ok-soft);    border-color: color-mix(in oklab, var(--ok) 25%, transparent); }
.pill.warn    { color: var(--warn-2, #8a5a00); background: var(--warn-soft);  border-color: color-mix(in oklab, var(--warn) 30%, transparent); }
.pill.err     { color: var(--err);   background: var(--err-soft);   border-color: color-mix(in oklab, var(--err) 25%, transparent); }
.pill.info    { color: var(--info);  background: var(--info-soft);  border-color: color-mix(in oklab, var(--info) 25%, transparent); }
.pill.slate   { color: var(--slate); background: var(--slate-soft); border-color: var(--line); }
.pill.accent  { color: var(--accent-2); background: var(--accent-soft); border-color: color-mix(in oklab, var(--accent) 40%, transparent); }
.pill.plain::before { display: none; }

/* ----- Two-column layouts ----- */
.two-col { display: grid; grid-template-columns: 2fr 1fr; gap: 16px; }
.three-col { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }

/* ----- Forms ----- */
.field { display: flex; flex-direction: column; gap: 6px; }
.field label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  color: var(--muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.field input, .field select, .field textarea {
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 4px;
  padding: 8px 10px;
  font-size: 13px;
  outline: none;
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 20%, transparent);
}
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.field-row.three { grid-template-columns: 1fr 1fr 1fr; }

/* Key-value grid used in detail pages */
.kv { display: grid; grid-template-columns: 130px 1fr; row-gap: 8px; column-gap: 16px; font-size: 13px; }
.kv .k {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  align-self: center;
}
.kv .v { color: var(--ink); }
.kv .v .mono { font-size: 12px; }

/* ----- Tabs ----- */
.tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--line);
  margin-bottom: 16px;
}
.tab {
  padding: 10px 16px;
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.tab:hover { color: var(--ink); }
.tab.active { color: var(--ink); border-bottom-color: var(--accent); font-weight: 600; }
.tab .count {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
  margin-left: 6px;
}

/* ----- Dispatch board ----- */
.board {
  display: grid;
  grid-template-columns: 300px 1fr;
  gap: 16px;
  height: calc(100vh - 220px);
}
.board .col { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); display: flex; flex-direction: column; min-height: 0; }
.board .col-head {
  padding: 12px 14px;
  border-bottom: 1px solid var(--line-2);
  display: flex; justify-content: space-between; align-items: center;
}
.board .col-head h3 {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin: 0;
}
.board .col-body { overflow: auto; padding: 10px; display: flex; flex-direction: column; gap: 8px; }

.driver-card, .load-card {
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  font-size: 13px;
  cursor: grab;
}
.driver-card.selected, .load-card.selected { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.driver-card .name { font-weight: 600; }
.driver-card .meta { font-family: var(--font-mono); font-size: 11px; color: var(--muted); margin-top: 4px; }

.assign-grid {
  display: grid;
  grid-template-columns: 1fr 32px 1fr;
  gap: 10px;
  align-items: center;
}
.assign-grid .arrow {
  text-align: center;
  color: var(--muted);
  font-family: var(--font-mono);
}
.assign-grid .assign-slot {
  min-height: 80px;
  border: 1px dashed var(--hairline);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  font-size: 12px;
  color: var(--muted);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.assign-grid .assign-slot.filled {
  border-style: solid;
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--ink);
}

/* ----- Activity feed ----- */
.feed { display: flex; flex-direction: column; }
.feed .row {
  display: grid;
  grid-template-columns: 72px 8px 1fr;
  gap: 12px;
  padding: 10px 18px;
  border-bottom: 1px solid var(--line-2);
  font-size: 13px;
}
.feed .row:last-child { border-bottom: none; }
.feed .when { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
.feed .dot { width: 6px; height: 6px; background: var(--accent); border-radius: 50%; margin-top: 7px; }
.feed .row[data-kind="invoice"] .dot { background: var(--ok); }
.feed .row[data-kind="expense"] .dot { background: var(--warn); }
.feed .row[data-kind="truck"] .dot { background: var(--err); }
.feed .row[data-kind="settlement"] .dot { background: var(--info); }

/* ----- Route strip ----- */
.route {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 14px;
}
.route .node {
  display: flex; flex-direction: column; gap: 2px;
}
.route .node .where {
  font-weight: 600;
  font-size: 14px;
}
.route .node .when {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
}
.route .node .addr {
  font-size: 12px; color: var(--muted-2);
}
.route .bar {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.route .bar .line {
  height: 2px;
  width: 120px;
  background: repeating-linear-gradient(90deg, var(--hairline) 0 6px, transparent 6px 10px);
}
.route .bar .miles {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
}

/* ----- Progress bar ----- */
.progress {
  height: 6px;
  background: var(--line-2);
  border-radius: 3px;
  overflow: hidden;
  position: relative;
}
.progress > span {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: 3px;
}

/* ----- Drawer / Modal ----- */
.drawer-backdrop {
  position: fixed; inset: 0;
  background: rgba(20, 18, 16, 0.35);
  z-index: 90;
  animation: fadein 0.15s ease-out;
}
.drawer {
  position: fixed; right: 0; top: 0; bottom: 0;
  width: 520px;
  background: var(--surface);
  border-left: 1px solid var(--line);
  box-shadow: -12px 0 32px rgba(20,18,16,0.08);
  z-index: 100;
  display: flex; flex-direction: column;
  animation: slidein 0.2s ease-out;
}
.drawer.wide { width: 640px; }
.drawer .head {
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
  display: flex; justify-content: space-between; align-items: center;
}
.drawer .head h2 {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
}
.drawer .body { padding: 18px 20px; overflow: auto; flex: 1; }
.drawer .foot {
  padding: 12px 20px;
  border-top: 1px solid var(--line);
  display: flex; justify-content: space-between; gap: 8px;
}

@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }
@keyframes slidein { from { transform: translateX(100%); } to { transform: translateX(0); } }
@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

/* ----- Tweaks panel ----- */
.tweaks {
  /* Always-dark glass palette — these variables cascade to every child
     control, so the panel stays dark even in light mode. */
  --bg:         #0c1017;
  --surface:    #131920;
  --surface-1:  #131920;
  --surface-2:  #1b2433;
  --surface-3:  #1f2937;
  --ink:        #e6edf6;
  --ink-2:      #b8c8da;
  --muted:      #8a9bb1;
  --muted-2:    #56697e;
  --line:       #2c3c50;
  --line-2:     #202e3f;
  --hairline:   #354860;
  --slate:      #8a9bb1;
  --slate-soft: #1b2433;
  color-scheme: dark;

  position: fixed;
  bottom: 20px; right: 20px;
  width: 268px;
  background: linear-gradient(160deg, rgba(30,41,58,0.74), rgba(14,20,30,0.70));
  border: 1px solid rgba(255,255,255,0.10);
  border-radius: 16px;
  box-shadow:
    0 24px 60px rgba(0,0,0,0.55),
    0 6px 18px rgba(0,0,0,0.38),
    inset 0 1px 0 rgba(255,255,255,0.09);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  backdrop-filter: blur(20px) saturate(160%);
  z-index: 200;
  overflow: hidden;

  /* Animated open / close */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(14px) scale(0.96);
  transform-origin: bottom right;
  transition: opacity 0.26s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.28s cubic-bezier(0.16, 1, 0.3, 1),
              visibility 0.28s linear;
}
.tweaks.on {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0) scale(1);
}

/* Frosted backdrop behind the panel */
.tweaks-backdrop {
  position: fixed;
  inset: 0;
  z-index: 199;
  background: rgba(8, 12, 20, 0.34);
  -webkit-backdrop-filter: blur(3px) saturate(105%);
  backdrop-filter: blur(3px) saturate(105%);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.28s ease, visibility 0.28s linear;
}
.tweaks-backdrop.on {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* Staggered fade-in of each row when the panel opens */
@keyframes tweakRowIn {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: translateY(0); }
}
.tweaks .body > .row,
.tweaks .body > .reset-btn { opacity: 0; }
.tweaks.on .body > .row,
.tweaks.on .body > .reset-btn {
  animation: tweakRowIn 0.32s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.tweaks.on .body > *:nth-child(1) { animation-delay: 0.05s; }
.tweaks.on .body > *:nth-child(2) { animation-delay: 0.09s; }
.tweaks.on .body > *:nth-child(3) { animation-delay: 0.13s; }
.tweaks.on .body > *:nth-child(4) { animation-delay: 0.17s; }
.tweaks.on .body > *:nth-child(5) { animation-delay: 0.21s; }
.tweaks.on .body > *:nth-child(6) { animation-delay: 0.25s; }
.tweaks.on .body > *:nth-child(7) { animation-delay: 0.29s; }
.tweaks.on .body > *:nth-child(8) { animation-delay: 0.33s; }
.tweaks .head {
  padding: 11px 14px;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  display: flex; justify-content: space-between; align-items: center;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.tweaks .body { padding: 14px; display: flex; flex-direction: column; gap: 14px; }
.tweaks .row { display: flex; flex-direction: column; gap: 6px; }
.tweaks .row > .lbl {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.swatches { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.swatch {
  width: 100%; height: 28px; border-radius: 4px;
  border: 1px solid var(--line);
  cursor: pointer;
  display: grid; place-items: center;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--accent-ink);
  transition: transform 0.1s, box-shadow 0.12s;
}
.swatch:not(.active):hover { transform: translateY(-1px); }
.swatch.active {
  outline: 3px solid var(--ink);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--surface);
  font-weight: 700;
}
.seg {
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 4px;
  overflow: hidden;
}
.seg.seg-3 { grid-template-columns: repeat(3, 1fr); }
.tweaks .reset-btn {
  width: 100%; justify-content: center;
  border: 1px solid var(--line); color: var(--muted);
}
.tweaks .reset-btn:hover { color: var(--err); border-color: color-mix(in oklab, var(--err) 40%, var(--line)); }
.seg button {
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  transition: background 0.12s, color 0.12s;
}
.seg button:not(.active):hover {
  color: var(--ink);
  background: color-mix(in oklab, var(--ink) 7%, transparent);
}
.seg button.active {
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}

/* ----- Misc ----- */
.empty {
  text-align: center;
  color: var(--muted);
  padding: 40px 20px;
  font-size: 13px;
}
.empty .big {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-2);
  margin-bottom: 8px;
}

.divider { height: 1px; background: var(--line-2); margin: 14px 0; }

.scrollbox { overflow: auto; max-height: 360px; }

.tag {
  display: inline-block;
  padding: 1px 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  border: 1px solid var(--line);
  border-radius: 3px;
  color: var(--muted);
}

.doc-chip {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 4px;
  font-size: 13px;
}
.doc-chip .thumb {
  width: 36px; height: 44px;
  background: repeating-linear-gradient(45deg, var(--surface-2) 0 4px, var(--surface-3) 4px 8px);
  border: 1px solid var(--line);
  border-radius: 2px;
  display: grid; place-items: center;
  font-family: var(--font-mono); font-size: 9px; color: var(--muted);
}
.doc-chip .meta { flex: 1; }
.doc-chip .name { font-weight: 500; }
.doc-chip .when { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }

.placeholder-box {
  background: repeating-linear-gradient(135deg, var(--surface-2) 0 6px, var(--surface-3) 6px 12px);
  border: 1px dashed var(--hairline);
  border-radius: 4px;
  padding: 24px;
  display: grid; place-items: center;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-align: center;
}

/* print-like section headings */
.section-heading {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 6px 0 10px;
  display: flex; align-items: center; gap: 10px;
}
.section-heading::after {
  content: ""; flex: 1; height: 1px; background: var(--line-2);
}

.mini-stat {
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px 14px;
  border-right: 1px solid var(--line-2);
}
.mini-stat:last-child { border-right: none; }
.mini-stat .k { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.mini-stat .v { font-family: var(--font-mono); font-size: 16px; font-weight: 600; }

.stat-strip {
  display: flex;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}

/* Simple bar chart */
.chart-tip {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: #0f1623;
  color: #e8eef8;
  font-size: 11px;
  font-family: var(--font-mono);
  padding: 4px 8px;
  border-radius: 4px;
  white-space: nowrap;
  z-index: 10;
  pointer-events: none;
}
.chart-bars {
  display: flex; align-items: flex-end; gap: 6px;
  height: 140px;
  padding: 10px 2px;
}
.chart-bars .bar {
  flex: 1;
  background: var(--accent);
  border-radius: 2px 2px 0 0;
  position: relative;
  min-width: 12px;
}
.chart-bars .bar.off { background: var(--line-2); }
.chart-bars .bar .lbl {
  position: absolute; top: -18px; left: 50%; transform: translateX(-50%);
  font-family: var(--font-mono); font-size: 10px; color: var(--muted);
}
.chart-x {
  display: flex; gap: 6px; padding: 6px 2px 0;
  font-family: var(--font-mono); font-size: 10px; color: var(--muted);
}
.chart-x span { flex: 1; text-align: center; }

/* ----- Filter bar ----- */
.filter-bar {
  margin-bottom: 18px;
}
.filters-inner {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 14px;
  box-shadow: 0 1px 0 rgba(20, 18, 16, 0.02);
}
.filters-inner > svg:first-child {
  color: var(--muted);
  margin-right: 2px;
}
.filters-inner .filters-lbl {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-2);
  font-weight: 600;
  padding-right: 10px;
  margin-right: 4px;
  border-right: 1px solid var(--line-2);
  align-self: stretch;
  display: flex;
  align-items: center;
}
.filter-field {
  display: inline-flex;
  align-items: stretch;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
  height: 30px;
}
.filter-field:hover {
  border-color: var(--line-strong, var(--muted-2));
}
.filter-field .lbl {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0 10px;
  display: flex;
  align-items: center;
  background: var(--surface-3, rgba(0, 0, 0, 0.025));
  border-right: 1px solid var(--line-2);
  white-space: nowrap;
}
.filter-field select,
.filter-field input {
  border: 0;
  background: transparent;
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  color: var(--ink);
  padding: 0 26px 0 10px;
  outline: none;
  cursor: pointer;
  min-width: 110px;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 16 16' fill='none' stroke='%236B6358' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M4 6l4 4 4-4'/></svg>");
  /* dark mode arrow applied below */
  background-repeat: no-repeat;
  background-position: right 10px center;
}
.filter-field input[type="date"] {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  min-width: 130px;
  padding: 0 10px;
  background-image: none;
  cursor: text;
}
.filter-field input[type="date"]::-webkit-calendar-picker-indicator {
  opacity: 0.55;
  cursor: pointer;
}
.filter-field:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent) 18%, transparent);
}
.filter-field:focus-within .lbl {
  color: var(--accent);
}
.filters-inner .btn {
  height: 30px;
  padding: 0 12px;
  margin-left: 2px;
}

/* ============ Auth screens ============ */
.auth-screen {
  position: fixed; inset: 0; z-index: 1000;
  display: grid; grid-template-columns: 1fr 1fr;
  background: var(--bg);
  font-family: var(--font-sans);
}
.auth-left {
  position: relative;
  background:
    radial-gradient(circle at 30% 20%, color-mix(in oklch, var(--accent) 20%, transparent), transparent 55%),
    radial-gradient(circle at 70% 80%, color-mix(in oklch, var(--accent-2) 25%, transparent), transparent 55%),
    linear-gradient(180deg, #0d1829, #060e1b);
  color: #f5efe2;
  padding: 56px 64px;
  display: flex; flex-direction: column; justify-content: space-between;
  overflow: hidden;
}
.auth-left::before {
  content: "";
  position: absolute; inset: 0;
  background-image:
    linear-gradient(to right, rgba(255,255,255,0.03) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,0.03) 1px, transparent 1px);
  background-size: 48px 48px;
  pointer-events: none;
}
.auth-left > * { position: relative; z-index: 1; }

.auth-brand {
  display: flex; align-items: center; gap: 14px;
}
.auth-brand .mark {
  width: 44px; height: 44px; border-radius: 8px;
  background: oklch(0.52 0.22 25); color: #ffffff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 16px; letter-spacing: 0.05em;
}
.auth-brand .name { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
.auth-brand .mc { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.06em; color: rgba(245,239,226,0.55); margin-top: 2px; }

.auth-headline {
  font-size: 56px; font-weight: 800; letter-spacing: -0.03em; line-height: 1.05;
  margin: 0 0 12px; max-width: 540px;
}
.auth-sub {
  font-size: 18px; line-height: 1.5; color: rgba(245,239,226,0.72);
  max-width: 480px; margin-bottom: 36px;
}
.auth-facts {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px;
  padding-top: 32px; border-top: 1px solid rgba(245,239,226,0.12);
  max-width: 600px;
}
.auth-facts .fact .lbl {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.12em;
  text-transform: uppercase; color: rgba(245,239,226,0.5); margin-bottom: 6px;
}
.auth-facts .fact .val {
  font-family: var(--font-mono); font-size: 15px; font-weight: 600; color: #f5efe2;
}

.auth-footline {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; color: rgba(245,239,226,0.4);
}
.auth-pwtips { margin-top: 32px; max-width: 440px; }
.auth-pwtips .lbl {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.1em;
  text-transform: uppercase; color: rgba(245,239,226,0.55); margin-bottom: 8px;
}
.auth-pwtips ul {
  margin: 0; padding-left: 18px; color: rgba(245,239,226,0.82); line-height: 1.7; font-size: 14px;
}

.auth-right {
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  padding: 48px;
  background: var(--bg);
  position: relative;
}
.auth-form {
  width: 100%; max-width: 400px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 32px;
  box-shadow: 0 2px 14px rgba(20,18,16,0.04);
}
.auth-title { font-size: 24px; font-weight: 700; letter-spacing: -0.02em; margin-bottom: 4px; color: var(--ink); }
.auth-subtitle { font-size: 14px; color: var(--muted); margin-bottom: 24px; }

.auth-field {
  display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px;
}
.auth-field > span {
  font-size: 12px; font-weight: 600; color: var(--ink); letter-spacing: -0.005em;
}
.auth-field > span.row { display: flex; align-items: center; justify-content: space-between; }
.auth-field input {
  height: 40px; padding: 0 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 6px;
  font-family: var(--font-sans); font-size: 14px; color: var(--ink);
  outline: none;
  transition: border 0.12s, box-shadow 0.12s;
}
.auth-field input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent) 18%, transparent);
}
.auth-field input::placeholder { color: var(--muted); }
/* Password field with show/hide toggle */
.pw-wrap { position: relative; display: block; width: 100%; }
.pw-wrap input { width: 100%; padding-right: 44px; }
/* Hide the browser's native reveal/clear icons (Edge/IE) so only our toggle shows */
.pw-wrap input::-ms-reveal,
.pw-wrap input::-ms-clear { display: none; }
.pw-toggle {
  position: absolute; top: 0; right: 2px;
  height: 40px; width: 40px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 0; padding: 0;
  color: var(--muted); cursor: pointer;
  transition: color 0.12s;
}
.pw-toggle:hover, .pw-toggle:focus-visible { color: var(--accent); outline: none; }

/* Toggle switch — for boolean fields (e.g. Active). Wraps a visually-hidden
   checkbox; the .track + .knob render the switch. Themed via design tokens. */
.switch { position: relative; display: inline-flex; align-items: center; gap: 10px; cursor: pointer; user-select: none; }
.switch > input { position: absolute; opacity: 0; width: 0; height: 0; margin: 0; }
.switch .track {
  flex: 0 0 auto; width: 38px; height: 22px; border-radius: 999px;
  background: var(--surface-3); border: 1px solid var(--line);
  transition: background 0.18s ease, border-color 0.18s ease;
}
.switch .knob {
  position: absolute; top: 50%; left: 3px; transform: translateY(-50%);
  width: 16px; height: 16px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  transition: left 0.18s ease;
}
.switch > input:checked ~ .track { background: var(--accent); border-color: var(--accent); }
.switch > input:checked ~ .knob { left: 19px; }
.switch > input:focus-visible ~ .track { outline: 2px solid var(--accent); outline-offset: 2px; }
.switch > input:disabled ~ .track { opacity: 0.5; }
.switch > input:disabled ~ .knob { opacity: 0.5; }

/* Drag-and-drop image upload (BaseMaster 'images' field) */
.dropzone {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  padding: 22px 16px; text-align: center; cursor: pointer;
  border: 1.5px dashed var(--hairline); border-radius: 8px;
  background: var(--surface-2); color: var(--muted);
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.dropzone:hover { border-color: var(--accent); color: var(--ink-2); }
.dropzone.dragover {
  border-color: var(--accent); color: var(--accent);
  background: var(--accent-soft);
}
.dropzone .dz-input { display: none; }
.dropzone .dz-text { font-size: 12px; }
.dropzone .dz-link { color: var(--accent); font-weight: 600; }
.dropzone .dz-hint { font-size: 11px; color: var(--accent); font-family: var(--font-mono); }
/* What the file should be — quieter than the invitation above it, because it
   is read once and then only when something is rejected. */
.dropzone .dz-note { font-size: 11px; color: var(--muted-2); }
.dz-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(76px, 1fr));
  gap: 8px; margin-top: 10px;
}
.dz-thumb {
  position: relative; aspect-ratio: 1 / 1; border-radius: 6px; overflow: hidden;
  border: 1px solid var(--line); background: var(--surface-3);
}
.dz-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dz-remove {
  position: absolute; top: 3px; right: 3px;
  width: 18px; height: 18px; border-radius: 50%; border: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.6); color: #fff; font-size: 11px; line-height: 1;
}
.dz-remove:hover { background: var(--err); }

/* Transaction forms — sticky action bar at the bottom (Cancel / Save+ / Save) */
.txn-actions {
  position: sticky;
  bottom: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 16px;
  padding: 11px 14px;
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.08);
}

/* The transaction form fills the scroll area so the action bar sits flush at the
   bottom of the viewport even when the form is short (and still sticks while a
   long form scrolls). */
.main:has(.txn-form-page) { padding-bottom: 0; }
.txn-form-page { display: flex; flex-direction: column; min-height: 100%; }
.txn-form-page .txn-actions { margin-top: auto; }

/* Bill summary — the discount / tax / expenses panel under the line grid.
   Sits to the right, under the amount column it carries forward. Captions use
   the project's .field label treatment; boxes match the .tbl inline-edit
   controls, right-aligned with tabular figures like the grid's amount column. */
.bill-card { margin-top: 16px; }
.bill-summary { margin-left: auto; width: min(100%, 430px); display: flex; flex-direction: column; gap: 10px; }
.bs-row { display: grid; grid-template-columns: 1fr 92px 150px; gap: 12px; align-items: center; }
.bs-label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  color: var(--muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: right;
}
.bs-row input {
  width: 100%;
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 4px;
  padding: 6px 8px;
  font-size: 13px;
  color: var(--ink);
  outline: none;
  text-align: right;
  font-feature-settings: "tnum", "zero";
  transition: border 0.12s, box-shadow 0.12s;
}
.bs-row input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 20%, transparent);
}
.bs-row input[readonly] {
  font-family: var(--font-mono);
  font-weight: 700;
  background: var(--surface-2);
  cursor: default;
}
.bs-bill .bs-label { color: var(--ink-2); }
.bs-bill { padding-top: 12px; border-top: 1px solid var(--line); }
.bs-bill input[readonly] { border-color: var(--accent); background: var(--accent-soft); }
.bs-err { font-size: 11px; color: var(--err); text-align: right; margin-top: -6px; }
@media (max-width: 520px) { .bs-row { grid-template-columns: 1fr 74px 110px; gap: 8px; } }

/* Quick Add buttons (transaction forms) — themed 3D (accent gradient, presses on click) */
.qa-add {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  border: none;
  border-radius: 9px;
  color: var(--accent-ink);
  background: linear-gradient(180deg, var(--accent), var(--accent-2));
  box-shadow: 0 2px 5px color-mix(in oklab, var(--accent) 42%, transparent), inset 0 1px 0 color-mix(in oklab, #fff 35%, transparent);
  cursor: pointer;
  transition: transform 0.14s ease, box-shadow 0.14s ease, filter 0.14s ease;
}
.qa-add:hover {
  transform: translateY(-2px);
  filter: brightness(1.06);
  box-shadow: 0 6px 14px color-mix(in oklab, var(--accent) 50%, transparent), inset 0 1px 0 color-mix(in oklab, #fff 45%, transparent);
}
.qa-add:active {
  transform: translateY(1px);
  box-shadow: 0 1px 3px color-mix(in oklab, var(--accent) 45%, transparent), inset 0 1px 0 color-mix(in oklab, #fff 22%, transparent);
}
/* Line-grid column-header variant — no adjacent input to stretch against
   (unlike the header-field quick-adds), so give the pill a proper height. */
.entry-lines th .qa-add { min-height: 28px; }

/* Browse Items — image grid of item cards */
.browse-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; }
.browse-card {
  display: flex; flex-direction: column; gap: 8px;
  border: 1px solid var(--line); border-radius: 10px; padding: 10px; background: var(--surface-1);
}
.browse-thumb {
  aspect-ratio: 1 / 1; border-radius: 8px; overflow: hidden; background: var(--surface-3);
  display: flex; align-items: center; justify-content: center;
}
.browse-thumb.clickable { cursor: pointer; }
.browse-thumb.clickable:hover { outline: 2px solid var(--accent); outline-offset: -2px; }
.browse-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.2s ease; }
.browse-thumb.clickable:hover img { transform: scale(1.04); }
.browse-noimg { color: var(--muted); }
.browse-name { font-size: 13px; font-weight: 600; text-align: center; line-height: 1.3; text-decoration: none; color: var(--ink); transition: color 0.12s ease; }
a.browse-name:hover { color: var(--accent); text-decoration: underline; }

/* Segmented toggle — multi-state filter control */
/* Report filter bar (renamed from .seg — that class belongs to the Appearance
   panel's segmented control and was being overridden by this block). */
.segbar { display: flex; width: 100%; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; background: var(--surface-2); }
.seg-btn {
  flex: 1;
  border: 0;
  border-left: 1px solid var(--line);
  background: transparent;
  height: 36px;
  padding: 0 12px;
  font-size: 13px;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.12s ease, color 0.12s ease;
}
.seg-btn:first-child { border-left: 0; }
.seg-btn:hover:not(.on) { background: var(--surface-3); color: var(--ink); }
.seg-btn.on { background: var(--accent); color: var(--accent-ink); font-weight: 600; }

/* Stock Statement — item-group grouping rows */
.tbl tr.grp-head td {
  background: var(--accent-soft);
  color: var(--ink);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding-top: 9px;
  padding-bottom: 9px;
}
.tbl tr.grp-sub td {
  background: var(--surface-2);
  color: var(--muted);
  font-weight: 600;
  border-top: 1px solid var(--line);
}

/* ── Print: A4 report output (Stock Statement / Stock Ledger) ───────────── */
.print-only { display: none; }

@media print {
  @page { size: A4; margin: 12mm; }
  html, body, .app, .main { background: #fff !important; }
  .sidebar, .topbar, .sidebar-backdrop, .tweaks-backdrop, .cmdk-backdrop, .no-print { display: none !important; }
  .app { display: block !important; }
  .main { margin: 0 !important; padding: 0 !important; width: 100% !important; max-width: none !important; }
  .print-only { display: block !important; }
  .card { border: none !important; box-shadow: none !important; background: #fff !important; margin: 0 !important; }
  .card-body { padding: 0 !important; }

  .print-head { margin: 0 0 10px; }
  .print-head .ph-co { font-size: 15px; font-weight: 700; color: #000; }
  .print-head .ph-ti { font-size: 12px; font-weight: 700; color: #000; margin-top: 2px; text-transform: uppercase; letter-spacing: 0.4px; }
  .print-head .ph-me { font-size: 10px; color: #333; margin-top: 3px; }

  .tbl { width: 100% !important; font-size: 9px !important; border-collapse: collapse !important; }
  .tbl th, .tbl td { color: #000 !important; background: #fff !important; border: 0.5px solid #999 !important; padding: 3px 5px !important; }
  .tbl thead th { background: #ededed !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .tbl tfoot td { font-weight: 700 !important; background: #f5f5f5 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .tbl tr { page-break-inside: avoid; }
  .tbl tr.grp-head td { background: #e6e6e6 !important; color: #000 !important; font-weight: 700 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .tbl tr.grp-sub td { background: #f3f3f3 !important; color: #000 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .act-btn { display: none !important; }
  /* Collapse the image-preview column (keep colspans aligned — don't display:none). */
  .col-img { width: 0 !important; max-width: 0 !important; padding: 0 !important; border-left: 0 !important; border-right: 0 !important; overflow: hidden; }

  /* Wide report tables: NO scroll container may survive into print — the whole
     table must flow onto the (landscape) page with no scrollbar. Neutralise the
     on-screen scroll box and every ancestor that can scroll, and let the headers
     wrap so all columns fit the page width. */
  .main, .card, .card-body, .card-body.flush, .print-wide { overflow: visible !important; }
  .print-wide .tbl th { white-space: normal !important; }
  .report-landscape { page: wide; }
}

/* Wide report tables scroll horizontally on screen, print full-width (landscape). */
.print-wide { overflow-x: auto; }
@page wide { size: A4 landscape; margin: 10mm; }

/* Data-entry save toast — prominent, centred near the top. A single 3s CSS
   animation slides it in, holds, then fades out and hides it (fill-mode
   forwards). pointer-events:none so it never blocks clicks beneath it. */
.txn-toast {
  position: fixed;
  top: 22px;
  left: 50%;
  z-index: 600;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 22px;
  font-size: 15px;
  font-weight: 700;
  color: #fff;
  background: var(--ok, #16a34a);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.22);
  pointer-events: none;
  animation: txnToast 3s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
.txn-toast-ico {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.22);
}
@keyframes txnToast {
  0%   { opacity: 1; transform: translate(-50%, -14px); }
  5%   { opacity: 1; transform: translate(-50%, 0); }
  88%  { opacity: 1; transform: translate(-50%, 0); }
  100% { opacity: 0; transform: translate(-50%, -10px); visibility: hidden; }
}
:root[data-motion="reduced"] .txn-toast {
  transform: translateX(-50%);
  animation: txnToastReduced 3s steps(1) forwards;
}
@keyframes txnToastReduced {
  0%, 92% { opacity: 1; }
  100%    { opacity: 0; visibility: hidden; }
}

/* Master sort drawer — records as compact drag-drop chips flowing inline */
.sort-chips { display: flex; flex-wrap: wrap; gap: 6px; align-content: flex-start; }
.sort-chip {
  padding: 5px 12px; font-size: 12.5px; font-weight: 600; color: var(--ink);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 6px;
  cursor: grab; user-select: none; white-space: nowrap;
}
.sort-chip:hover { border-color: var(--accent); }
.sort-chip:active { cursor: grabbing; }
.chip-dragging { opacity: 0.4; background: var(--accent); color: #fff; }

/* Purchase Book — purchase-return rows in light red */
.tbl tr.pb-return td { background-color: color-mix(in oklab, var(--err) 14%, transparent); }

/* Stock Statement — reorder-level row highlights (below min = red, above max = green) */
.tbl tr.stock-below td { background-color: color-mix(in oklab, var(--err) 14%, transparent); }
.tbl tr.stock-above td { background-color: color-mix(in oklab, var(--ok) 16%, transparent); }

/* Transaction line-items grid (Purchases / Issue to Production) */
.line-items { display: flex; flex-direction: column; gap: 8px; }
.li-head, .li-row, .li-foot {
  display: grid;
  grid-template-columns: 34px minmax(0, 2.6fr) minmax(0, 1.8fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.2fr);
  gap: 8px; align-items: center;
}
/* With a Lot No column (Issue to Production): delete, item, color, lot, qty, rate, amount */
.line-items.with-lot .li-head, .line-items.with-lot .li-row, .line-items.with-lot .li-foot {
  grid-template-columns: 34px minmax(0, 2.2fr) minmax(0, 1.5fr) minmax(0, 1.4fr) minmax(0, 0.9fr) minmax(0, 0.9fr) minmax(0, 1.1fr);
}
.li-head {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--muted); padding: 0 2px;
}
.li-head .li-num { text-align: right; }
.li-row input {
  width: 100%;
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 4px;
  padding: 8px 10px;
  font-size: 13px;
  outline: none;
}
.li-row input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 20%, transparent);
}
.li-num input { text-align: right; }
/* Drop the native number spinners so qty/rate match the plain text inputs */
.li-num input[type="number"] { -moz-appearance: textfield; }
.li-num input[type="number"]::-webkit-outer-spin-button,
.li-num input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.li-amt { font-family: var(--font-mono); text-align: right; padding-right: 4px; color: var(--ink); }
.li-foot {
  border-top: 1px solid var(--line); margin-top: 2px; padding-top: 10px;
  font-weight: 700;
}
@media (max-width: 640px) {
  .li-head { display: none; }
  .li-row, .li-foot,
  .line-items.with-lot .li-row, .line-items.with-lot .li-foot {
    grid-template-columns: 1fr 1fr; gap: 6px;
    border: 1px solid var(--line-2); border-radius: 8px; padding: 10px;
  }
}

/* Clickable image-count badge (Items listing) */
.img-badge { border: 0; cursor: pointer; }
.img-badge:hover { background: var(--accent); color: var(--accent-ink); }

/* Image gallery lightbox (big image + thumbnail strip, ecommerce style) */
.gallery { position: fixed; inset: 0; z-index: 400; display: flex; align-items: center; justify-content: center; padding: 24px; }
.gallery-backdrop { position: absolute; inset: 0; background: rgba(8, 10, 14, 0.72); backdrop-filter: blur(2px); }
.gallery-panel {
  position: relative; z-index: 1; width: min(880px, 96vw); max-height: 92vh;
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface-1); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
}
.gallery-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--line-2); }
.gallery-title { font-weight: 600; color: var(--ink); font-size: 14px; }
.gallery-count { font-size: 12px; color: var(--muted); font-family: var(--font-mono); }
.gallery-x {
  margin-left: auto; border: 0; background: var(--surface-3); color: var(--ink-2);
  width: 28px; height: 28px; border-radius: 7px; cursor: pointer; font-size: 13px;
}
.gallery-x:hover { background: var(--err-soft); color: var(--err); }
.gallery-stage {
  position: relative; flex: 1; min-height: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); padding: 16px;
}
.gallery-main { max-width: 100%; max-height: 58vh; object-fit: contain; border-radius: 6px; }
.gallery-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 38px; height: 38px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--surface-1); color: var(--ink); font-size: 22px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
.gallery-nav:hover { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.gallery-nav.prev { left: 12px; }
.gallery-nav.next { right: 12px; }
.gallery-thumbs { display: flex; gap: 8px; padding: 12px 14px; overflow-x: auto; border-top: 1px solid var(--line-2); }
.gallery-thumb {
  flex: 0 0 auto; width: 60px; height: 60px; padding: 0; cursor: pointer; overflow: hidden;
  border: 2px solid transparent; border-radius: 8px; background: var(--surface-3);
}
.gallery-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gallery-thumb.active { border-color: var(--accent); }

.auth-link {
  font-size: 11px; color: var(--accent); text-decoration: none; font-weight: 600;
}
.auth-link:hover { text-decoration: underline; }
.auth-hint { font-size: 11px; color: var(--muted); font-family: var(--font-mono); letter-spacing: 0.03em; }
.auth-hint.ok { color: var(--ok); }
.auth-hint.bad { color: var(--err); }

.auth-check {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--ink); cursor: pointer;
  margin: 8px 0 18px;
}
.auth-check input { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }

.auth-submit {
  width: 100%; height: 44px;
  background: var(--accent); color: var(--accent-ink);
  border: 0; border-radius: 6px;
  font-family: var(--font-sans); font-size: 15px; font-weight: 600;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  transition: filter 0.12s, transform 0.04s;
}
.auth-submit:hover:not(:disabled) { filter: brightness(0.96); }
.auth-submit:active:not(:disabled) { transform: translateY(1px); }
.auth-submit:disabled { opacity: 0.5; cursor: not-allowed; }
.auth-submit .arrow { font-size: 18px; }

.auth-ghost {
  width: 100%; height: 38px; margin-top: 8px;
  background: transparent; color: var(--muted);
  border: 1px solid var(--line); border-radius: 6px;
  font-family: var(--font-sans); font-size: 13px; font-weight: 500;
  cursor: pointer;
}
.auth-ghost:hover { background: var(--surface-2); color: var(--ink); }

.auth-err {
  display: flex; align-items: center; gap: 6px;
  padding: 10px 12px; margin-bottom: 14px;
  background: color-mix(in oklch, var(--err) 8%, var(--surface-2));
  border: 1px solid color-mix(in oklch, var(--err) 30%, var(--line));
  border-radius: 6px;
  color: var(--err); font-size: 13px; font-weight: 500;
}

.auth-divider {
  display: flex; align-items: center; gap: 12px;
  margin: 22px 0 14px;
  font-size: 11px; color: var(--muted); font-family: var(--font-mono);
  letter-spacing: 0.08em; text-transform: uppercase;
}
.auth-divider::before,
.auth-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--line);
}
.auth-divider span { flex: 0 0 auto; }

.auth-demos {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 10px;
}
.auth-demo {
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 6px; padding: 10px 12px;
  text-align: left; cursor: pointer;
  font-family: var(--font-sans);
  transition: border-color 0.12s, background 0.12s;
}
.auth-demo:hover { border-color: var(--accent); background: var(--surface); }
.auth-demo .lbl { font-size: 13px; font-weight: 600; color: var(--ink); margin-bottom: 2px; }
.auth-demo .sub { font-size: 11px; color: var(--muted); font-family: var(--font-mono); letter-spacing: 0.02em; }
.auth-demo-note {
  font-size: 11px; color: var(--muted); text-align: center;
  font-family: var(--font-mono); letter-spacing: 0.02em; line-height: 1.5;
}
.auth-demo-note code {
  background: var(--surface-3); padding: 1px 5px; border-radius: 3px; color: var(--ink);
}

.auth-copyright {
  position: absolute; bottom: 24px;
  font-size: 11px; color: var(--muted); font-family: var(--font-mono); letter-spacing: 0.04em;
}

/* Password strength */
.pw-strength { margin-top: 4px; }
.pw-strength .bar { display: flex; gap: 3px; }
.pw-strength .seg { flex: 1; height: 4px; border-radius: 2px; transition: background 0.2s; }
.pw-strength .lbl { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; margin-top: 4px; font-weight: 600; }

/* OTP input */
.auth-otp {
  display: flex; gap: 8px; justify-content: center; margin: 4px 0 10px;
}
.auth-otp input {
  width: 46px; height: 54px;
  text-align: center;
  font-family: var(--font-mono); font-size: 22px; font-weight: 600;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--ink);
  outline: none;
}
.auth-otp input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent) 18%, transparent);
}

/* Auth modal (forgot password / change password) */
.auth-modal-backdrop {
  position: fixed; inset: 0; z-index: 1100;
  background: rgba(20,18,16,0.5);
  display: flex; align-items: center; justify-content: center;
  backdrop-filter: blur(2px);
}
.auth-modal {
  width: 92%; max-width: 420px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.3);
  overflow: hidden;
}
.auth-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 18px;
  border-bottom: 1px solid var(--line);
  font-size: 15px; font-weight: 600; color: var(--ink);
}
.auth-modal-head .x {
  background: none; border: 0; cursor: pointer;
  font-size: 18px; color: var(--muted);
  padding: 4px 8px; border-radius: 4px;
}
.auth-modal-head .x:hover { background: var(--surface-2); color: var(--ink); }
.auth-modal-body { padding: 20px; }

/* Mobile brand header: hidden on desktop, shown on mobile when left panel disappears */
.auth-mobile-header { display: none; }

/* Responsive: stack on narrow screens */
@media (max-width: 960px) {
  .auth-screen { grid-template-columns: 1fr; }
  .auth-left { padding: 40px; min-height: auto; }
  .auth-headline { font-size: 36px; }
  .auth-right { padding: 32px 20px; }
}

/* ----- Global search dropdown ----- */
.gs-wrap {
  position: relative;
}
.gs-dropdown {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 400px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 8px 28px rgba(20,18,16,0.12), 0 2px 6px rgba(20,18,16,0.06);
  z-index: 500;
  overflow: hidden;
  animation: fadein 0.1s ease-out;
}
.gs-group {
  border-top: 1px solid var(--line-2);
}
.gs-group:first-child { border-top: 0; }
.gs-group-label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-2);
  padding: 8px 12px 3px;
}
.gs-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 7px 12px;
  text-align: left;
  text-decoration: none;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.08s;
}
.gs-item:hover { background: var(--surface-2); }
.gs-item-title {
  font-weight: 500;
  font-size: 13px;
  white-space: nowrap;
  flex-shrink: 0;
}
.gs-item-sub {
  font-size: 12px;
  color: var(--muted);
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.gs-empty {
  padding: 18px 12px;
  font-size: 13px;
  color: var(--muted);
  text-align: center;
}

/* ----- Command palette (⌘K / Ctrl-K) — centered popup ----- */
.cmdk-backdrop {
  position: fixed; inset: 0; z-index: 1200;
  background: rgba(10, 14, 22, 0.55);
  backdrop-filter: blur(3px);
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 12vh;
  animation: fadein 0.12s ease-out;
}
.cmdk {
  width: min(600px, 92vw);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.35);
  overflow: hidden;
  display: flex; flex-direction: column;
  max-height: 64vh;
}
.cmdk-input {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line-2);
}
.cmdk-input svg { color: var(--muted); flex: 0 0 auto; }
.cmdk-input input {
  flex: 1; border: 0; outline: none; background: transparent;
  font-size: 15px; color: var(--ink); padding: 0;
}
.cmdk-input input:focus { box-shadow: none; }
.cmdk-input kbd {
  font-family: var(--font-mono); font-size: 10px; color: var(--muted);
  border: 1px solid var(--line); border-radius: 4px; padding: 2px 6px; background: var(--surface-2);
}
.cmdk-list { list-style: none; margin: 0; padding: 6px; overflow-y: auto; }
.cmdk-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border-radius: 8px; cursor: pointer;
  font-size: 13.5px; color: var(--ink);
}
.cmdk-item.active { background: var(--accent); color: var(--accent-ink); }
.cmdk-item.active .cmdk-group { color: var(--accent-ink); opacity: 0.85; }
.cmdk-group {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted-2);
  min-width: 56px; flex: 0 0 auto;
}
.cmdk-empty { padding: 22px 12px; text-align: center; color: var(--muted); font-size: 13px; }

/* ----- Print styles ----- */
@media print {
  /* Reset app shell to plain block flow */
  .app       { display: block; height: auto; background: #fff; }
  .main      { padding: 0; overflow: visible; }

  /* Hide everything except the report content */
  .sidebar,
  .topbar,
  .page-head,
  .tabs,
  .filter-bar { display: none !important; }

  /* Cards flush to page edge */
  .card         { border: none; box-shadow: none; border-radius: 0; }
  .card-body    { padding: 0; }

  @page { margin: 16mm 14mm; }
}

/* ===== Responsive / Mobile ===== */

/* Hamburger hidden on desktop; backdrop inert */
.topbar .menu-btn { display: none; }
.sidebar-backdrop { display: none; }

/* ----- Tablet (769px – 1100px) ----- */
@media (min-width: 769px) and (max-width: 1100px) {
  .app { grid-template-columns: 200px 1fr; }
  .kpi-row { grid-template-columns: repeat(2, 1fr); }
  .two-col { grid-template-columns: 1fr; }
  .three-col { grid-template-columns: repeat(2, 1fr); }
  .drawer.wide { width: 560px; }
  .topbar .search { width: 200px; }
}

/* ----- Mobile (≤ 768px) ----- */
@media (max-width: 768px) {
  /* Switch to document-scroll so .main never has an empty shell below content */
  html, body { height: auto; min-height: 100%; }

  /* App shell: single column, rows auto-size to content */
  .app {
    grid-template-columns: 1fr;
    grid-template-areas: "topbar" "main";
    grid-template-rows: 56px auto;
    height: auto;
    min-height: 100dvh;
  }

  /* Topbar: sticky instead of grid-fixed */
  .topbar { position: sticky; top: 0; z-index: 200; }

  /* Main: flow with document instead of scrolling in a fixed box */
  .main { overflow: visible; }

  /* Sidebar: off-canvas overlay */
  .sidebar {
    position: fixed;
    left: 0; top: 0; bottom: 0;
    z-index: 300;
    transform: translateX(-100%);
    transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1);
    width: 260px;
  }
  .sidebar.open { transform: translateX(0); }

  /* Backdrop */
  .sidebar-backdrop {
    display: block;
    position: fixed; inset: 0;
    background: rgba(20, 18, 16, 0.5);
    z-index: 299;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s;
  }
  .sidebar-backdrop.open { opacity: 1; pointer-events: auto; }

  /* Show hamburger, hide desktop collapse btn */
  .topbar .menu-btn { display: flex; }
  .topbar .collapse-btn { display: none; }

  /* On mobile the collapsed state is completely ignored —
     sidebar is always a full-width fixed off-canvas panel */
  :root[data-sidebar="collapsed"] .app { grid-template-columns: 1fr; }
  :root[data-sidebar="collapsed"] .sidebar {
    position: fixed;
    width: 260px;
    box-shadow: none;
    transform: translateX(-100%);
  }
  :root[data-sidebar="collapsed"] .sidebar.open { transform: translateX(0); }

  /* Match desktop specificity (0,4,0) by using :not(.hovering) so these rules
     override the icon-only collapsed rules via source order */
  :root[data-sidebar="collapsed"] .sidebar:not(.hovering) .navitem { justify-content: flex-start; gap: 9px; padding: 8px 10px; }
  :root[data-sidebar="collapsed"] .sidebar:not(.hovering) .nav-label,
  :root[data-sidebar="collapsed"] .sidebar:not(.hovering) .navitem .count,
  :root[data-sidebar="collapsed"] .sidebar:not(.hovering) .section-label { display: block; }
  :root[data-sidebar="collapsed"] .sidebar:not(.hovering) .nav-icon { color: #7a8fa8; }
  :root[data-sidebar="collapsed"] .sidebar:not(.hovering) .navitem:hover .nav-icon,
  :root[data-sidebar="collapsed"] .sidebar:not(.hovering) .navitem.active .nav-icon { color: inherit; }
  /* Restore brand */
  :root[data-sidebar="collapsed"] .sidebar:not(.hovering) .brand { justify-content: flex-start; padding: 0 18px; }
  :root[data-sidebar="collapsed"] .sidebar:not(.hovering) .brand .brand-text { display: block; }
  :root[data-sidebar="collapsed"] .sidebar:not(.hovering) .brand .sidebar-toggle { display: flex; }
  /* Safety net: hovering must never change sidebar position on mobile */
  :root[data-sidebar="collapsed"] .sidebar.hovering {
    position: fixed !important;
    width: 260px !important;
    box-shadow: none !important;
    transform: translateX(-100%);
  }
  :root[data-sidebar="collapsed"] .sidebar.hovering.open { transform: translateX(0); }

  /* Topbar: tighten, hide desktop-only items */
  .topbar { padding: 0 10px; gap: 6px; }
  .topbar .crumbs { display: none; }
  .topbar .tz { display: none; }
  .topbar .search { flex: 1; width: auto; max-width: none; }

  /* Global search dropdown: don't let its 400px min-width overflow the screen */
  .gs-dropdown {
    position: fixed;
    top: 54px;
    left: 10px;
    right: 10px;
    min-width: 0;
    width: auto;
  }

  /* Main */
  .main { padding: 14px 12px 80px; }

  /* Page head */
  .page-head { flex-wrap: wrap; gap: 10px; margin-bottom: 12px; }
  .page-head h1 { font-size: 18px; }
  .page-head .actions { flex-wrap: wrap; gap: 6px; }

  /* KPI row: 2-up */
  .kpi-row { grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 12px; }
  .kpi .val { font-size: 20px; }

  /* Multi-column layouts → single column */
  .two-col, .three-col { grid-template-columns: 1fr; }

  /* Tables: allow horizontal scroll inside cards */
  .card-body.flush { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .tbl { min-width: 560px; }

  /* Tabs: scroll horizontally */
  .tabs { overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; }
  .tab { white-space: nowrap; flex-shrink: 0; }

  /* Filter bar: scroll horizontally */
  .filters-inner { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .filters-inner .filters-lbl { display: none; }

  /* Drawers: full-width bottom-anchored sheet */
  .drawer, .drawer.wide {
    width: 100%;
    border-left: 0;
    top: auto;
    border-radius: 14px 14px 0 0;
    box-shadow: 0 -8px 32px rgba(20, 18, 16, 0.14);
    max-height: 92dvh;
  }
  @keyframes slidein { from { transform: translateY(100%); } to { transform: translateY(0); } }

  /* Dispatch board: stacked */
  .board { grid-template-columns: 1fr; height: auto; }

  /* Form field rows: single column */
  .field-row, .field-row.three { grid-template-columns: 1fr; }

  /* Tweaks panel */
  .tweaks { right: 10px; bottom: 10px; width: calc(100vw - 20px); }

  /* Auth: hide left panel, show compact brand above form */
  .auth-screen {
    grid-template-columns: 1fr;
    /* The screen is position:fixed, so anything taller than the viewport had
       no way to be reached — and with the on-screen keyboard up there is
       barely 300px of it, leaving Sign in below the fold and unscrollable. */
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .auth-left { display: none; }
  .auth-right {
    padding: 24px 16px 32px;
    /* Start at the top rather than centring: centred content that overflows is
       clipped at BOTH ends, taking the heading with it. */
    justify-content: flex-start;
    align-items: center;
    min-height: 100%;
  }

  /* iOS zooms the page in when a focused field is under 16px, and will not
     zoom back out — the usual reason a login feels broken on a phone. */
  .auth-field input,
  .auth-form input,
  .auth-form select,
  .auth-form textarea { font-size: 16px; }
  .auth-mobile-header {
    display: flex;
    width: 100%;
    max-width: 400px;
    margin-bottom: 20px;
  }
  .auth-form { padding: 24px 20px; }
  .auth-copyright { position: static; margin-top: 20px; text-align: center; }

  /* Route strip: stack nodes */
  .route { grid-template-columns: 1fr; gap: 6px; }
  .route .bar { flex-direction: row; justify-content: flex-start; }
  .route .bar .line { width: 40px; }

  /* KV grid: tighten */
  .kv { grid-template-columns: 100px 1fr; }

  /* Assign grid in board */
  .assign-grid { grid-template-columns: 1fr; }
  .assign-grid .arrow { display: none; }
}

/* ===== Dark mode overrides for hardcoded values ===== */
:root[data-mode="dark"] .filter-field select,
:root[data-mode="dark"] .filter-field input {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 16 16' fill='none' stroke='%236b7f96' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M4 6l4 4 4-4'/></svg>");
}
:root[data-mode="dark"] .drawer-backdrop {
  background: rgba(0, 0, 0, 0.55);
}
/* --accent-2 is a *darker* accent, which disappears against the dark tinted
   --accent-soft background; use the normal ink colour instead. */
:root[data-mode="dark"] .btn.accent { color: var(--ink); }

/* ===== CRM responsive grids (stat cards, reports) ===== */
.stat-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px; margin-bottom: 18px; }
.report-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.kanban-ghost { opacity: 0.4; }
@media (min-width: 769px) and (max-width: 1100px) {
  .stat-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 768px) {
  .stat-grid { grid-template-columns: repeat(2, 1fr); }
  .report-grid { grid-template-columns: 1fr; }
}
.donut-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 16px; }
@media (max-width: 768px) { .donut-grid { grid-template-columns: 1fr; } }

/* ===== Communication action buttons — solid color + pulse ===== */
.comm-btn { display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto; flex-shrink:0; padding:7px; border-radius:9px;
  border:none; cursor:pointer; color:#fff; text-decoration:none; line-height:0;
  transition:filter .15s ease, transform .15s ease; }
.comm-btn svg { display:block; transition:transform .5s ease; }
.comm-btn:hover { filter:brightness(1.1); transform:translateY(-1px); }
.comm-btn:hover svg { transform:rotate(360deg); }
.copy-btn svg { transition:transform .5s ease; }
.copy-btn:hover svg { transform:rotate(360deg); }
.comm-call  { background:#2f6df6; animation:commPulseBlue 1.8s infinite; }
.comm-wa    { background:#25d366; animation:commPulseGreen 1.8s infinite; }
.comm-email { background:#ea4335; animation:commPulseRed 1.8s infinite; }
@keyframes commPulseBlue   { 0%{box-shadow:0 0 0 0 rgba(47,109,246,.5)}  70%{box-shadow:0 0 0 8px rgba(47,109,246,0)}  100%{box-shadow:0 0 0 0 rgba(47,109,246,0)} }
@keyframes commPulseGreen  { 0%{box-shadow:0 0 0 0 rgba(37,211,102,.5)}  70%{box-shadow:0 0 0 8px rgba(37,211,102,0)}  100%{box-shadow:0 0 0 0 rgba(37,211,102,0)} }
@keyframes commPulseRed { 0%{box-shadow:0 0 0 0 rgba(234,67,53,.5)} 70%{box-shadow:0 0 0 8px rgba(234,67,53,0)} 100%{box-shadow:0 0 0 0 rgba(234,67,53,0)} }

/* Solid, icon-only action buttons (edit / delete / print / new) — rotate on hover,
   styled like the contact comm buttons. */
.act-btn { display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto; padding:7px; border-radius:9px;
  border:none; cursor:pointer; color:#fff; text-decoration:none; line-height:0; vertical-align:middle; }
.act-btn + .act-btn { margin-left:4px; }
.act-btn svg { display:block; transition:transform .5s ease; }
.act-btn { transition:filter .15s ease, transform .15s ease, box-shadow .15s ease; }
.act-btn:hover { filter:brightness(1.1); transform:translateY(-1px); box-shadow:0 4px 10px rgba(0,0,0,.16); }
.act-btn:hover svg { transform:rotate(360deg); }
.act-btn:disabled { opacity:.45; cursor:default; transform:none; box-shadow:none; filter:none; }
.act-edit  { background:#2f6df6; }
.act-print { background:#0ea5e9; }
.act-del   { background:#ef4444; }
.act-new   { background:#16a34a; }

/* Quotation line-item inputs — match the standard .field input look */
.qline td { vertical-align:middle; }
.qline input, .qline select {
  width:100%; border:1px solid var(--line); background:var(--surface);
  border-radius:4px; padding:7px 9px; font-size:13px; outline:none;
}
.qline input:focus, .qline select:focus {
  border-color:var(--accent);
  box-shadow:0 0 0 3px color-mix(in oklab, var(--accent) 20%, transparent);
}
.qline input.num { text-align:right; }

/* ===== Bare form controls inside drawers use the standard field styling ===== */
.drawer input:not([type="checkbox"]):not([type="radio"]),
.drawer select,
.drawer textarea {
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  border-radius: 4px;
  padding: 8px 10px;
  font-size: 13px;
  outline: none;
}
.drawer input:not([type="checkbox"]):not([type="radio"]):focus,
.drawer select:focus,
.drawer textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 20%, transparent);
}

/* ===== Text size (UI scale on the content area) ===== */
:root[data-text="sm"] .main { zoom: 0.93; }
:root[data-text="lg"] .main { zoom: 1.08; }

/* ===== Boxed content width (centered on wide screens) ===== */
:root[data-width="boxed"] .main {
  max-width: 1180px;
  width: 100%;
  margin-inline: auto;
}

/* ===== Reduce motion (manual override of all animation/transition) ===== */
:root[data-motion="reduced"] *,
:root[data-motion="reduced"] *::before,
:root[data-motion="reduced"] *::after {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
  scroll-behavior: auto !important;
}

/* ===== Horizontal navigation (top menu bar) — desktop/tablet only =====
   Adapted to the CRM's flat sidebar: the sidebar becomes a single
   scrollable top strip of nav items. On mobile (≤768px) the off-canvas
   vertical drawer always wins. */
@media (min-width: 769px) {
  :root[data-nav="horizontal"] .app {
    grid-template-columns: 1fr;
    grid-template-rows: 48px 56px 1fr;
    grid-template-areas: "sidebar" "topbar" "main";
  }
  :root[data-nav="horizontal"] .sidebar {
    width: 100%;
    flex-direction: row;
    align-items: center;
    height: 48px;
    border-right: 0;
    border-bottom: 1px solid #060d18;
    overflow-x: auto;
    overflow-y: hidden;
  }
  :root[data-nav="horizontal"] .sidebar .brand {
    height: 48px;
    border-bottom: 0;
    border-right: 1px solid #1a2535;
    padding: 0 16px 0 14px;
    flex-shrink: 0;
  }
  :root[data-nav="horizontal"] .sidebar .brand .sub { display: none; }
  :root[data-nav="horizontal"] .sidebar .sidebar-toggle { display: none; }
  :root[data-nav="horizontal"] .sidebar .foot { display: none; }

  :root[data-nav="horizontal"] .sidebar nav {
    flex-direction: row;
    align-items: center;
    padding: 0 8px;
    gap: 2px;
    overflow: visible;
    min-height: 0;
  }
  :root[data-nav="horizontal"] .sidebar .navitem {
    width: auto;
    padding: 8px 10px;
    border-radius: 6px;
    white-space: nowrap;
    flex: 0 0 auto;
  }
  :root[data-nav="horizontal"] .sidebar .navitem .nav-label { display: inline; }
  :root[data-nav="horizontal"] .sidebar .navitem .count { display: none; }

  /* Menu-based horizontal nav: each section is a top-level button that opens a
     dropdown panel containing its items. */
  /* Allow dropdowns to escape the 48px-tall strip (only a few menu buttons,
     so horizontal scrolling is no longer needed). */
  :root[data-nav="horizontal"] .sidebar { overflow: visible; }
  :root[data-nav="horizontal"] .sidebar .nav-section { position: relative; flex: 0 0 auto; }
  :root[data-nav="horizontal"] .sidebar nav .section-toggle {
    display: inline-flex;
    width: auto;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    border-radius: 6px;
    color: #c8d4e3;
    font-family: var(--font-sans);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    white-space: nowrap;
  }
  :root[data-nav="horizontal"] .sidebar nav .section-toggle:hover { background: #1a2535; color: #e8eef8; }
  :root[data-nav="horizontal"] .sidebar .section-toggle .nav-caret { width: 9px; height: 9px; }
  :root[data-nav="horizontal"] .sidebar .nav-group {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    min-width: 210px;
    flex-direction: column;
    gap: 2px;
    padding: 6px;
    background: #0d1726;
    border: 1px solid #1a2535;
    border-radius: 8px;
    box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
    z-index: 200;
  }
  /* Transparent bridge over the 4px gap so moving the mouse from the section
     label into the dropdown doesn't leave the .nav-section and close it. */
  :root[data-nav="horizontal"] .sidebar .nav-group::before {
    content: "";
    position: absolute;
    top: -6px;
    left: 0;
    right: 0;
    height: 6px;
  }

  /* In horizontal mode the collapsed rail never applies */
  :root[data-nav="horizontal"][data-sidebar="collapsed"] .app { grid-template-columns: 1fr; }
  :root[data-nav="horizontal"][data-sidebar="collapsed"] .sidebar { width: 100%; }
}

/* ── Company picker (sign-in screens) ───────────────────────────────────────
   The list of companies a user may open. Styled off the auth card, using the
   same brand mark as the sidebar so a company reads the same in both places. */
.company-list { display: flex; flex-direction: column; gap: 8px; margin-top: 18px; }
.company-pick {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 14px;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--ink);
  font: inherit;
  cursor: pointer;
  transition: border-color 0.14s ease, box-shadow 0.14s ease, transform 0.14s ease;
}
.company-pick:hover {
  border-color: var(--accent);
  box-shadow: 0 4px 14px color-mix(in oklab, var(--accent) 18%, transparent);
  transform: translateY(-1px);
}
.company-pick:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 20%, transparent);
}
.company-pick[disabled] { opacity: 0.6; cursor: progress; }
.company-pick .mark {
  flex: 0 0 auto;
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 9px;
  background: linear-gradient(180deg, var(--accent), var(--accent-2));
  color: var(--accent-ink);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 13px;
}
.company-pick .body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.company-pick .name {
  font-size: 14px; font-weight: 600; line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.company-pick .meta {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.company-pick .go { margin-left: auto; color: var(--muted); flex: 0 0 auto; }
.company-pick.current { border-color: var(--accent); background: var(--accent-soft); }

/* Sidebar switcher — sits beside the brand when a user has more than one company */
.brand-switch {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--surface-1);
  color: var(--muted);
  cursor: pointer;
  transition: color 0.12s ease, border-color 0.12s ease;
}
.brand-switch:hover { color: var(--accent); border-color: var(--accent); }

/* ── Day Book ────────────────────────────────────────────────────────────────
   Rows are read, not clicked, so they keep the default cursor; each day's
   total sits on the surface tint so the page reads as a run of days. */
.daybook-tbl tbody tr { cursor: default; }
.daybook-tbl tbody tr.day-total,
.daybook-tbl tbody tr.day-total:hover { background: var(--surface-2); }
.daybook-tbl tbody tr.day-total td { border-top: 1px solid var(--line); }
@media print { .daybook-tbl tbody tr.day-total { background: transparent; } }

/* ── Primary action beside the title on small screens ────────────────────────
   The page header justifies its actions to the far right, which is fine on a
   desktop but puts the Add button at the end of a wide page on a phone — a
   sideways scroll to reach the one control you came for. Below desktop width
   the actions sit straight after the title instead. If the two do not fit,
   .page-head already wraps and the button lands on its own line at the left. */
@media (max-width: 1100px) {
  .page-head { justify-content: flex-start; align-items: center; column-gap: 12px; }
  .page-head > :first-child { min-width: 0; }
  .page-head .actions { flex: 0 0 auto; }
}

/* ── Line-item grid column widths ────────────────────────────────────────────
   Auto table layout sizes columns by content, which starved the Item picker:
   the one column with no declared width collapsed to ~100px while the numeric
   ones stretched to 209px each. Fixed layout makes the declared widths hold,
   and Item — the only column left to size itself — takes all the room over. */
/* min-width keeps the boxes usable when the window is narrow; the card
   scrolls sideways rather than crushing five inputs into nothing. */
.entry-lines { table-layout: fixed; min-width: 720px; }
/* The inputs were sizing themselves — a number box defaults to about 189px —
   so under auto layout the columns grew to fit them, and under fixed layout
   they spilled past their cell. Filling the cell is what makes the declared
   widths actually govern the grid. */
.entry-lines td input { width: 100%; }
/* No overflow clipping on the cells: the item picker opens its list inside one,
   and hidden overflow cut it off at the cell edge. Fixed layout alone holds the
   widths, and every cell here contains a full-width input, so nothing spills. */

/* Master forms: a duplicate name flagged while typing, before Save is pressed.
   Amber rather than red — nothing is wrong yet, but saving will be refused. */
.dup-warn {
  display: flex; align-items: center; gap: 6px;
  font-size: 11px; margin-top: 2px;
  color: oklch(0.55 0.14 70);
}

/* Cash Voucher header: the running Cash in Hand balance, read not typed. */
.cash-balance {
  font-family: var(--font-mono);
  font-weight: 700;
  text-align: right;
  background: var(--surface-2);
  cursor: default;
}

/* The row a report was left from, on coming back to it. Fades out on its own —
   long enough to find, short enough not to look like a selection. */
.row-returned > td {
  background: var(--accent-soft);
  transition: background 1.2s ease-out;
}

/* The ledger names each document by its initials — "JV#1" — so the column is
   thin and the particulars get the room. The full name is on the row's title. */
@media print {
  /* Paper is narrower than a screen, and the narration is the only column
     whose length is not known in advance — so every other one is pinned to
     what it actually needs and the particulars keep the remainder. */
  .vch-col  { width: 44px !important; }
  .lg-date  { width: 62px !important; }
  .lg-amt   { width: 74px !important; }
  .lg-bal   { width: 88px !important; }
  .lg-date, .lg-amt, .lg-bal { white-space: nowrap; }
}

/* Opening Balance (Accounts). The name and the group are both typed into, so
   they take the width; the three figures need only what a number takes. The
   boxes fill their cells — a select left to size itself chopped the longer
   group names. */
.oba-tbl { table-layout: fixed; }
.oba-tbl th.oba-no    { width: 56px; }
.oba-tbl th.oba-acct  { width: 26%; }
.oba-tbl th.oba-group { width: 22%; }
.oba-tbl th.oba-amt   { width: 130px; }
.oba-tbl th.oba-bal   { width: 160px; }
.oba-tbl td input,
.oba-tbl td select { width: 100%; }

/* Same breakpoint the cards start scrolling at — a wider table below that
   width would spill out of the card instead of scrolling inside it. */
@media (max-width: 768px) {
  /* Six columns, two of them typed into: on a narrow screen the card scrolls
     sideways rather than squeezing a name and a group into slivers. */
  .oba-tbl { min-width: 860px; }
  .oba-tbl th.oba-acct  { width: 230px; }
  .oba-tbl th.oba-group { width: 200px; }
}

/* Purchase and Despatch listings: a document settled in cash, tinted the same
   green its Cash/Credit pill carries. Soft enough to skim past, plain enough
   to pick out. Follows light and dark through the token. */
.tbl tr.row-cash > td { background: var(--ok-soft); }
.tbl tr.row-cash:hover > td { background: var(--ok-soft); filter: brightness(0.98); }

/* ----- Sidebar resize handle ----- */
/* The border itself is the grip: drag it to set the sidebar's width, double
   click to put it back. Only where there is a border to drag — the vertical
   nav, open, on a screen wide enough that the sidebar is not an overlay. */
.sidebar-resize {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 6px;
  cursor: col-resize;
  z-index: 260;
  background: transparent;
  transition: background 0.15s;
}
.sidebar-resize:hover,
.sidebar-resize.dragging { background: var(--accent); }

:root[data-nav="horizontal"] .sidebar-resize,
:root[data-sidebar="collapsed"] .sidebar:not(.hovering) .sidebar-resize { display: none; }

/* Mid-drag the width follows the pointer, so the easing that makes the collapse
   look smooth would only make this feel like rubber. */
:root.sb-resizing .app,
:root.sb-resizing .sidebar { transition: none; }
:root.sb-resizing { cursor: col-resize; user-select: none; }

@media (max-width: 768px) {
  /* The sidebar slides in over the page here; there is no border to drag. */
  .sidebar-resize { display: none; }
}

/* ----- Shortcuts ----- */
/* Pinned modules on the dashboard: solid chips, a colour each so the row is
   read by shape and colour rather than by re-reading six names. The colours
   are their own — not the theme accent — so the row stays the same whatever
   theme is on, and they carry white type at any of them. */
.sc-tiles {
  display: flex; flex-wrap: wrap; gap: 10px;
  margin-top: 16px;
}
.sc-tile {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 18px;
  border: 0; border-radius: 9px;
  color: #fff; background: var(--sc-color, oklch(0.55 0.16 255));
  font-size: 13px; font-weight: 600; letter-spacing: 0.1px;
  text-decoration: none; white-space: nowrap;
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.18);
  transition: transform 0.12s ease, box-shadow 0.15s ease, filter 0.15s ease;
}
.sc-tile:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(16, 24, 40, 0.22);
  filter: brightness(1.06);
}
.sc-tile:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(16, 24, 40, 0.18); }

.sc-c1 { --sc-color: oklch(0.55 0.16 255); }  /* blue   */
.sc-c2 { --sc-color: oklch(0.53 0.14 152); }  /* green  */
.sc-c3 { --sc-color: oklch(0.60 0.15 62);  }  /* amber  */
.sc-c4 { --sc-color: oklch(0.55 0.18 25);  }  /* red    */
.sc-c5 { --sc-color: oklch(0.52 0.17 300); }  /* violet */
.sc-c6 { --sc-color: oklch(0.55 0.12 200); }  /* teal   */

/* The way back to the picker is not one of the shortcuts, so it does not
   dress as one. */
.sc-tile-edit {
  background: transparent; color: var(--muted);
  border: 1px dashed var(--line-2, var(--line));
  font-weight: 500; box-shadow: none;
}
.sc-tile-edit:hover {
  background: var(--surface-2); color: var(--ink);
  border-color: var(--accent); box-shadow: none; filter: none;
}

.sc-empty {
  margin-top: 16px; font-size: 12px; color: var(--muted);
}
/* The picker: every module the user may open, grouped as the sidebar groups them. */
.sc-sections { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 22px; }
.sc-section-label {
  font-size: 11px; font-weight: 700; letter-spacing: 0.6px; text-transform: uppercase;
  color: var(--muted); margin-bottom: 10px;
}
.sc-list { display: flex; flex-direction: column; gap: 10px; }
.sc-pick { font-size: 13px; }

@media (max-width: 768px) {
  /* One per line on a phone, where a row of them would wrap to nothing legible. */
  .sc-tiles { flex-direction: column; }
  .sc-tile { justify-content: space-between; }
}

/* ----- Dashboard charts ----- */
/* Two charts side by side, each in a card of its own; one above the other on
   a narrow screen. The box gives the canvas a height, which Chart.js will not
   take from its own content. */
.chart-row {
  display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
  margin-top: 16px;
}
.chart-box { position: relative; height: 260px; }
.chart-wide { grid-column: 1 / -1; }

@media (max-width: 1100px) {
  .chart-row { grid-template-columns: 1fr; }
}

/* ============================================================================
   BNI Directory
   ----------------------------------------------------------------------------
   Everything the chapter directory adds on top of the admin shell above: the
   extra action buttons, the admin screens' layout pieces, the public
   directory, and the member panel.

   All of it is built from the same tokens as the shell — --accent, --line,
   --surface, --ink — so a theme or colour-mode change carries through here
   without a second palette to maintain.
   ========================================================================= */

/* ── Action buttons: the same rotate-on-hover family as edit / delete / new ── */
.act-view { background:#64748b; }
.act-call { background:#16a34a; }
.act-wa   { background:#25d366; }
.act-key  { background:#f59e0b; }

/* ── Small shared bits the admin screens use ───────────────────────────────── */
.lnk { color: var(--accent); text-decoration: none; }
.lnk:hover { text-decoration: underline; }

.grow { flex: 1 1 auto; }

.filter-count {
  font-size: 12px; color: var(--muted); font-family: var(--font-mono);
  white-space: nowrap;
}

.fld-err  { font-size: 11px; color: var(--err); margin-top: 3px; }
.fld-hint { font-size: 11px; color: var(--muted); margin-top: 3px; }
.fld-ro {
  border: 1px dashed var(--line); background: var(--surface-2); color: var(--muted);
  border-radius: var(--radius-sm); padding: 8px 10px; font-size: 13px; min-height: 34px;
}
.fld-block {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px; background: var(--surface-2);
}
.fld-block-head {
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 10px;
}

.avatar-sm {
  width: 30px; height: 30px; border-radius: 50%; object-fit: cover;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent-2);
  font-size: 11px; font-weight: 700; flex: 0 0 auto;
}
.avatar-initials { letter-spacing: .02em; }

/* An archived record still shows, but reads as set aside. */
.row-muted td { opacity: .55; }

.mini-head {
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); margin: 18px 0 8px;
}

/* ── The member form's two-column grid ─────────────────────────────────────── */
.form-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 18px;
}
.form-grid .span-2 { grid-column: 1 / -1; }

@media (max-width: 760px) {
  .form-grid { grid-template-columns: 1fr; }
  .form-grid .span-2 { grid-column: auto; }
}

/* ── Section tabs across the top of a long form ────────────────────────────── */
.seg-tabs {
  display: flex; gap: 2px; margin-bottom: 14px; overflow-x: auto;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 3px;
}
.seg-tabs button {
  flex: 1 1 auto; white-space: nowrap; border: 0; background: none; cursor: pointer;
  padding: 8px 14px; border-radius: var(--radius-sm); font: inherit; font-size: 13px;
  color: var(--muted); transition: background .15s ease, color .15s ease;
}
.seg-tabs button:hover { color: var(--ink); }
.seg-tabs button.active { background: var(--accent); color: var(--accent-ink); font-weight: 600; }

/* A row of choices, for the filters that have more options than the two or
   three `.seg` is built for — it is a two-column grid, so six options in it
   land as a 3x2 block rather than a row. These are pills instead: they wrap
   naturally and the chosen one is unmistakable. */
.chip-row { display: flex; gap: 7px; flex-wrap: wrap; align-items: center; }
.chip-row button {
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
  border-radius: 999px; padding: 7px 14px; cursor: pointer;
  font: inherit; font-size: 12px; font-weight: 500; white-space: nowrap;
  transition: background .13s ease, color .13s ease, border-color .13s ease;
}
.chip-row button:hover { color: var(--ink); border-color: var(--hairline); }
.chip-row button.on {
  background: var(--accent); border-color: var(--accent);
  color: var(--accent-ink); font-weight: 600;
}

/* ── Headline number tiles ─────────────────────────────────────────────────── */
.stat-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px; margin-bottom: 16px;
}
.stat-tile {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px 16px; text-decoration: none; color: inherit; display: block;
  transition: border-color .15s ease, transform .15s ease;
}
a.stat-tile:hover { border-color: var(--accent); transform: translateY(-1px); }
.stat-tile .k { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; }
.stat-tile .v { font-size: 26px; font-weight: 700; font-family: var(--font-mono); margin-top: 4px; }
.stat-tile.good .v { color: var(--ok); }
.stat-tile.bad  .v { color: var(--err); }

/* ── Dashboard ─────────────────────────────────────────────────────────────── */
/* Two sections to a row. Wider cards than an auto-fit grid would give, which
   these need: every one of them is a list of names and dates, and three or four
   to a row squeezes them to nothing. */
.dash-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px; align-items: start;
}
@media (max-width: 900px) {
  .dash-grid { grid-template-columns: 1fr; }
}

/* "3 months", beside the joining date on the newest-members list. */
.mini-ago {
  display: block; font-size: 10px; font-weight: 600;
  color: var(--accent-2); font-family: var(--font-sans);
}

.mini-row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px var(--row-pad-x); border-bottom: 1px solid var(--line-2); font-size: 13px;
}
.mini-row:last-child { border-bottom: 0; }
.mini-date {
  font-family: var(--font-mono); font-size: 11px; color: var(--muted);
  white-space: nowrap; flex: 0 0 auto;
}
.mini-name { font-weight: 600; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mini-meta {
  font-size: 12px; color: var(--muted); flex: 0 1 auto; min-width: 0;
  display: inline-flex; align-items: center; justify-content: flex-end;
  white-space: nowrap;
}
/* The business name is the part that gives way on a narrow row … */
.mini-biz { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
/* … so the category, which is what the row is being read for, always shows. */
.mini-cat {
  flex: 0 0 auto; margin-left: 6px; padding: 1px 7px; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-2);
  font-size: 11px; font-weight: 600;
}

.bar-track { height: 7px; border-radius: 4px; background: var(--surface-3); overflow: hidden; }
.bar-fill  { height: 100%; border-radius: 4px; background: var(--accent); }
.bar-fill.ok    { background: var(--ok); }
.bar-fill.warn  { background: var(--warn); }
.bar-fill.err   { background: var(--err); }
.bar-fill.info  { background: var(--info); }
.bar-fill.slate { background: var(--slate); }

.tbl.compact td { padding: 7px var(--cell-pad-x); }

/* The meeting countdown, on the admin dashboard */
.meet-card { margin-bottom: 16px; border-color: var(--accent); }
.meet-body { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.meet-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--accent); font-weight: 700;
}
.meet-title { font-size: 14px; font-weight: 600; margin-top: 3px; }
.meet-count { display: flex; gap: 14px; margin-left: auto; }
.meet-count > div { text-align: center; min-width: 44px; }
.meet-count b {
  display: block; font-family: var(--font-mono); font-size: 22px; font-weight: 700;
  color: var(--accent); line-height: 1.1;
}
.meet-count span { font-size: 10px; color: var(--muted); text-transform: uppercase; }
.meet-now { margin-left: auto; font-weight: 700; color: var(--ok); }

/* ── Status pill with a menu behind it (the member listing) ────────────────── */
.status-pick { position: relative; display: inline-block; }
.status-menu {
  position: absolute; top: calc(100% + 4px); left: 0; z-index: 40; min-width: 140px;
  background: var(--surface-1); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: 0 6px 20px rgba(20,18,16,.14); padding: 4px;
}
.status-menu button {
  display: block; width: 100%; text-align: left; border: 0; background: none;
  padding: 7px 10px; border-radius: var(--radius-sm); cursor: pointer;
  font: inherit; font-size: 13px; color: var(--ink);
}
.status-menu button:hover { background: var(--accent); color: #fff; }
.status-menu button.on { font-weight: 700; background: var(--accent-soft); }

/* The one-time password readout */
.pw-reveal {
  font-size: 30px; font-weight: 700; letter-spacing: .16em; text-align: center;
  padding: 20px; border: 2px dashed var(--accent); border-radius: var(--radius);
  background: var(--accent-soft); color: var(--ink); user-select: all;
}

/* ── The import wizard ─────────────────────────────────────────────────────── */
.steps { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.step {
  display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px; padding: 6px 14px 6px 6px;
}
.step-n {
  width: 20px; height: 20px; border-radius: 50%; display: inline-flex;
  align-items: center; justify-content: center; font-size: 11px; font-weight: 700;
  background: var(--surface-3); color: var(--muted);
}
.step.on { border-color: var(--accent); color: var(--ink); font-weight: 600; }
.step.on .step-n { background: var(--accent); color: var(--accent-ink); }
.step.past .step-n { background: var(--ok); color: #fff; }

.pick-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 12px; }
.pick-card {
  display: block; cursor: pointer; padding: 14px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--surface);
  transition: border-color .15s ease, background .15s ease;
}
.pick-card:hover { border-color: var(--accent); }
.pick-card.on { border-color: var(--accent); background: var(--accent-soft); }
.pick-card input { position: absolute; opacity: 0; pointer-events: none; }
.pick-title { display: block; font-weight: 600; font-size: 13px; }
.pick-hint  { display: block; font-size: 12px; color: var(--muted); margin-top: 4px; }

/* ── Birthdays / anniversaries, grouped by date ────────────────────────────── */
.occ-day { margin-bottom: 18px; }
.occ-date {
  display: flex; align-items: baseline; gap: 10px; margin-bottom: 8px;
  padding-bottom: 6px; border-bottom: 2px solid var(--line);
}
.occ-dm { font-size: 15px; font-weight: 700; }
.occ-away { font-size: 12px; color: var(--muted); }
.occ-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(310px, 1fr)); gap: 10px; }
.occ-card {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
}
.occ-avatar { flex: 0 0 auto; }
.occ-avatar img, .occ-avatar .avatar-initials {
  width: 40px; height: 40px; border-radius: 50%; object-fit: cover;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent-2); font-weight: 700; font-size: 13px;
}
.occ-who { flex: 1 1 auto; min-width: 0; }
.occ-name { font-weight: 600; font-size: 14px; display: flex; align-items: center; gap: 8px; }
.occ-meta { font-size: 12px; color: var(--muted); margin-top: 2px; }
.occ-acts { flex: 0 0 auto; display: flex; }


/* ============================================================================
   PUBLIC DIRECTORY
   ========================================================================= */

.pub-body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--font-sans); font-size: 14px; line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

.pub-wrap { max-width: 1160px; margin: 0 auto; padding: 0 20px; }

.pub-head {
  background: var(--surface); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 30;
}
.pub-head-in { display: flex; align-items: center; gap: 16px; height: 62px; }
.pub-brand { display: flex; align-items: center; gap: 11px; text-decoration: none; color: inherit; }
.pub-mark {
  width: 36px; height: 36px; border-radius: 9px; background: var(--accent);
  color: var(--accent-ink); display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 14px; letter-spacing: .02em; flex: 0 0 auto;
}
.pub-mark.lg { width: 52px; height: 52px; border-radius: 14px; font-size: 19px; }
/* The chapter's mark: wider than it is tall, so height is what is fixed. */
.pub-logo { height: 38px; width: auto; flex: 0 0 auto; display: block; }
@media (max-width: 560px) { .pub-logo { height: 32px; } }
.pub-name { display: block; font-weight: 700; font-size: 15px; line-height: 1.2; }
.pub-sub  { display: block; font-size: 11px; color: var(--muted); }
.pub-nav { margin-left: auto; display: flex; gap: 18px; align-items: center; }
.pub-nav a {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  color: var(--accent); text-decoration: none; font-size: 13px; font-weight: 600;
  border: 1px solid color-mix(in oklab, var(--accent) 35%, transparent);
  background: var(--surface); padding: 7px 14px; border-radius: 999px;
  transition: background .14s ease, color .14s ease, transform .14s ease, box-shadow .14s ease;
}
/* "Install app": an outline beside the solid Login, since installing is the
   lesser of the two things a visitor might do here. */
.pub-install {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  font: inherit; font-size: 13px; font-weight: 600;
  color: var(--accent); background: var(--surface);
  border: 1px solid color-mix(in oklab, var(--accent) 35%, transparent);
  padding: 7px 14px; border-radius: 999px;
  transition: background .14s ease, color .14s ease, transform .14s ease, box-shadow .14s ease;
}
.pub-install:hover {
  background: var(--accent); color: var(--accent-ink); border-color: var(--accent);
  transform: translateY(-1px); box-shadow: 0 4px 14px color-mix(in oklab, var(--accent) 30%, transparent);
}
/* On a phone the icon carries it; the word would crowd the header. */
@media (max-width: 560px) {
  .pub-install span { display: none; }
  .pub-install { width: 36px; height: 36px; padding: 0; justify-content: center; }
}
/* The way back is an icon alone, so it is a circle rather than a pill. */
.pub-nav a.pub-back { width: 36px; height: 36px; padding: 0; }
.pub-nav a:hover {
  background: var(--accent); color: var(--accent-ink); border-color: var(--accent);
  transform: translateY(-1px); box-shadow: 0 4px 14px color-mix(in oklab, var(--accent) 30%, transparent);
}
/* The arrow leans back on hover, the way the link does. */
.pub-nav a svg { transition: transform .14s ease; }
.pub-nav a:hover .pub-back-arrow { transform: translateX(-2px); }
.pub-nav a.pub-login {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  background: var(--accent); color: var(--accent-ink);
  width: 36px; height: 36px; padding: 0; border-radius: 999px; font-weight: 600;
  box-shadow: 0 2px 8px color-mix(in oklab, var(--accent) 30%, transparent);
  transition: transform .14s ease, box-shadow .14s ease;
}
.pub-nav a.pub-login:hover {
  color: var(--accent-ink); transform: translateY(-1px);
  box-shadow: 0 4px 14px color-mix(in oklab, var(--accent) 38%, transparent);
}

.pub-main { min-height: 60vh; padding: 26px 0 50px; }

.pub-hero { text-align: center; padding: 20px 0 26px; }

/* What the chapter amounts to, in numbers. It replaces a headline that told a
   visitor what a directory is for — which they already knew by the time they
   arrived. */
.pub-stats {
  display: inline-flex; flex-wrap: wrap; justify-content: center; gap: 0;
  margin: 0 auto 24px; padding: 6px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 16px; box-shadow: 0 4px 18px rgba(20, 18, 16, .05);
}
.pub-stat {
  padding: 14px 26px; position: relative; min-width: 116px;
}
/* Hairlines between, not around — the card is one object. */
.pub-stat + .pub-stat::before {
  content: ''; position: absolute; left: 0; top: 18%; bottom: 18%;
  border-left: 1px solid var(--line-2);
}
/* All three read as one set — same size, weight and colour. Singling the first
   out in a larger accent made the row look like three unrelated numbers rather
   than one card; the labels carry the hierarchy instead. */
.pub-stat-n {
  display: block; font-size: 32px; font-weight: 700;
  letter-spacing: -.03em; line-height: 1.05; color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.pub-stat-l {
  display: block; margin-top: 4px; font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}

@media (max-width: 520px) {
  .pub-stats { display: grid; grid-template-columns: 1fr 1fr; width: 100%; }
  .pub-stat { padding: 12px 10px; min-width: 0; }
  .pub-stat + .pub-stat::before { display: none; }
  .pub-stat-n { font-size: 27px; }
  /* An odd one out — Cities, with two stats above it — takes the whole row
     rather than sitting in the left-hand column looking abandoned. */
  .pub-stat:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

.pub-search {
  position: relative; max-width: 620px; margin: 0 auto;
  display: flex; align-items: center;
}
/* The magnifier only — a child selector, or the cross inside the clear button
   is dragged over to the left edge too and the button renders empty. */
.pub-search > svg { position: absolute; left: 16px; color: var(--muted); pointer-events: none; }
.pub-search input {
  width: 100%; padding: 14px 44px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  font: inherit; font-size: 15px; outline: none;
  box-shadow: 0 2px 10px rgba(20,18,16,.05);
}
/* type=search draws a clear button of its own in WebKit, which sat beside ours
   and gave the box two crosses. Ours stays: it also clears the Livewire value. */
.pub-search input::-webkit-search-cancel-button,
.pub-search input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
.pub-search input::-ms-clear { display: none; width: 0; height: 0; }

.pub-search input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--accent) 18%, transparent);
}
.pub-search button {
  position: absolute; right: 14px; background: none; border: 0; cursor: pointer;
  color: var(--muted); display: flex; padding: 4px;
}

.pub-filters {
  display: flex; gap: 10px; flex-wrap: wrap; justify-content: center;
  margin: 22px 0 6px;
}
.pub-filters select {
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  border-radius: 999px; padding: 8px 14px; font: inherit; font-size: 13px;
  outline: none; cursor: pointer;
}
.pub-filters select:focus { border-color: var(--accent); }

/* The category and city filters are autocompletes (partials/autocomplete), so
   the pill shape lives on the input rather than on a <select>. */
.pub-filter { position: relative; flex: 0 1 210px; min-width: 170px; }
.pub-filters .ac-input {
  border-radius: 999px; padding: 8px 30px 8px 14px; background: var(--surface);
  cursor: pointer;
}
.pub-filters .ac-input:focus { cursor: text; }
.pub-clear {
  border: 1px solid var(--line); background: none; color: var(--muted);
  border-radius: 999px; padding: 8px 14px; font: inherit; font-size: 13px; cursor: pointer;
}
.pub-clear:hover { color: var(--err); border-color: var(--err); }

@media (max-width: 560px) {
  .pub-filters { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 14px 0 16px; }
  .pub-filter { flex: none; min-width: 0; }
  .pub-clear { grid-column: 1 / -1; justify-self: center; }
}

/* A phone has less room to spare above the fold, so the hero is tighter. */
@media (max-width: 560px) {
  .pub-main { padding: 14px 0 40px; }
  .pub-hero { padding: 6px 0 16px; }
  .pub-stats { margin-bottom: 16px; }
}

.pub-count { text-align: center; font-size: 12px; color: var(--muted); margin: 14px 0 18px; }

/* Two members to a row at every width — on a phone too, where a visitor scrolls
   through faces and two at a time halves the scrolling. */
.pub-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px;
}

/* A compact card for a phone, where each column is about 170px wide. The rules
   are scoped under .pub-grid so they outrank the full-size card rules that
   follow, without leaning on !important. The photo still leads, just smaller;
   the introduction is held to two lines so the two cards in a row stay a
   similar height; and "View profile" goes, because the whole card is the link. */
@media (max-width: 680px) {
  .pub-grid { gap: 10px; }
  .pub-grid .pub-card { padding: 14px 10px 12px; gap: 8px; border-radius: 14px; }
  .pub-grid .pub-card-top { gap: 9px; }
  .pub-grid .pub-avatar img, .pub-grid .pub-avatar > span {
    width: 92px; height: 92px; font-size: 28px;
  }
  .pub-grid .pub-card-name { font-size: 14px; gap: 4px; }
  .pub-grid .pub-badge { font-size: 11px; }
  .pub-grid .pub-card-biz { font-size: 12px; }
  .pub-grid .pub-card-cat {
    font-size: 10px; padding: 3px 8px; max-width: 100%;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .pub-grid .pub-card-intro {
    font-size: 12px; line-height: 1.4;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  .pub-grid .pub-card-foot { justify-content: center; padding-top: 8px; font-size: 11px; }
  .pub-grid .pub-card-go { display: none; }
}
.pub-card {
  display: flex; flex-direction: column; gap: 10px; padding: 18px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  text-decoration: none; color: inherit;
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.pub-card:hover {
  transform: translateY(-2px); border-color: var(--accent);
  box-shadow: 0 8px 24px rgba(20,18,16,.09);
}
/* The photo leads the card, centred, with the name and business beneath it —
   a face is what a visitor scans a directory by, so it gets the room. */
.pub-card-top {
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  text-align: center; width: 100%;
}
.pub-avatar { flex: 0 0 auto; }
.pub-avatar img, .pub-avatar > span {
  width: 160px; height: 160px; border-radius: 50%; object-fit: cover;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent-2); font-weight: 700; font-size: 48px;
}
.pub-card-id { min-width: 0; max-width: 100%; }
.pub-card-name {
  font-weight: 700; font-size: 16px; display: flex; align-items: center;
  justify-content: center; gap: 6px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pub-badge {
  color: var(--ok); font-size: 12px; font-weight: 700;
}
.pub-card-biz { font-size: 13px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pub-card-cat {
  display: inline-block; align-self: center; font-size: 11px; font-weight: 600;
  background: var(--accent-soft); color: var(--accent-2);
  padding: 3px 9px; border-radius: 999px;
}
.pub-card-intro { font-size: 13px; color: var(--muted); margin: 0; flex: 1 1 auto; text-align: center; }
.pub-card-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding-top: 10px; border-top: 1px solid var(--line-2); font-size: 12px;
}
.pub-card-city { color: var(--muted); display: inline-flex; align-items: center; gap: 4px; }
.pub-card-go { color: var(--accent); font-weight: 600; }

.pub-empty { grid-column: 1 / -1; text-align: center; padding: 60px 20px; color: var(--muted); }
.pub-empty-ico { font-size: 34px; margin-bottom: 10px; }
.pub-empty h2 { margin: 0 0 6px; font-size: 17px; color: var(--ink); }
.pub-btn {
  display: inline-block; margin-top: 14px; padding: 10px 20px; border: 0; cursor: pointer;
  border-radius: 999px; background: var(--accent); color: var(--accent-ink);
  font: inherit; font-size: 13px; font-weight: 600; text-decoration: none;
}
.pub-pager { margin-top: 24px; display: flex; justify-content: center; }

.pub-foot {
  border-top: 1px solid var(--line); background: var(--surface);
  padding: 20px 0; font-size: 12px; color: var(--muted);
}
.pub-foot-in { display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.pub-foot a { color: var(--accent); text-decoration: none; }

/* ── Public member profile ─────────────────────────────────────────────────── */
.pub-crumbs { display: flex; gap: 8px; font-size: 12px; color: var(--muted); margin-bottom: 18px; flex-wrap: wrap; }
.pub-crumbs a { color: var(--accent); text-decoration: none; }

.prof-head {
  display: flex; gap: 22px; align-items: flex-start; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 24px;
}
.prof-avatar { flex: 0 0 auto; }
/* The photo opens into the lightbox, so it says so on hover: a magnifier badge
   in the corner and a lift, rather than a caption nobody would read twice. */
button.prof-avatar.zoom {
  position: relative; padding: 0; border: 0; background: none; cursor: zoom-in;
  border-radius: 20px; line-height: 0;
  transition: transform .16s ease, box-shadow .16s ease;
}
button.prof-avatar.zoom:hover { transform: translateY(-2px); box-shadow: 0 8px 22px rgba(20,18,16,.16); }
button.prof-avatar.zoom:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.prof-zoom-hint {
  position: absolute; right: 6px; bottom: 6px;
  width: 26px; height: 26px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(20, 18, 16, .62); color: #fff;
  opacity: 0; transition: opacity .16s ease;
}
button.prof-avatar.zoom:hover .prof-zoom-hint,
button.prof-avatar.zoom:focus-visible .prof-zoom-hint { opacity: 1; }
/* On a touch screen there is no hover, so the badge is simply always there. */
@media (hover: none) {
  .prof-zoom-hint { opacity: 1; }
}
/* The photo, or the initials that stand in for it. The magnifier badge is a
   span inside the same element, so it is excluded by name — without that it
   inherits the full 104px tile and covers the photo it is meant to sit on. */
.prof-avatar img, .prof-avatar > span:not(.prof-zoom-hint) {
  width: 104px; height: 104px; border-radius: 20px; object-fit: cover;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent-2); font-weight: 700; font-size: 32px;
}
.prof-id { flex: 1 1 300px; min-width: 0; }
.prof-id h1 { margin: 0 0 4px; font-size: 26px; font-weight: 700; letter-spacing: -.015em; }
.prof-role { font-size: 14px; color: var(--muted); margin-bottom: 10px; }
.prof-pills { display: flex; gap: 7px; flex-wrap: wrap; }
.prof-pill {
  font-size: 12px; padding: 4px 11px; border-radius: 999px;
  background: var(--surface-3); color: var(--ink-2); text-decoration: none;
}
.prof-pill.accent { background: var(--accent-soft); color: var(--accent-2); font-weight: 600; }
/* "4 years 2 months", riding inside the "Member since" pill. */
.prof-pill-dur {
  margin-left: 6px; padding-left: 7px; font-weight: 700;
  color: var(--accent-2); border-left: 1px solid var(--hairline);
}
.prof-pill.ok { background: var(--ok-soft); color: var(--ok); font-weight: 600; }
a.prof-pill:hover { background: var(--accent); color: #fff; }
.prof-intro { margin: 12px 0 0; font-size: 14px; }

.prof-actions {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
  gap: 10px; margin: 16px 0 10px;
}
.prof-act {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 14px 8px; border-radius: 12px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); text-decoration: none; cursor: pointer;
  font: inherit; font-size: 12px; font-weight: 600;
  transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.prof-act:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(20,18,16,.1); }
/* Every contact button wears the brand colour — Call and WhatsApp included,
   which used to carry their own green. Share stays filled, as the one action
   that is not about reaching this member directly. */
.prof-act.call,
.prof-act.wa,
.prof-act.mail,
.prof-act.web,
.prof-act.map,
.prof-act.save  { border-color: var(--accent); color: var(--accent); }
.prof-act.share { border-color: var(--accent); background: var(--accent); color: var(--accent-ink); }

.prof-share-row {
  display: flex; gap: 12px; flex-wrap: wrap; align-items: center;
  font-size: 12px; color: var(--muted); margin-bottom: 22px;
}
.prof-share-row a { color: var(--accent); text-decoration: none; }
.prof-share-row a:hover { text-decoration: underline; }

.prof-body { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 16px; align-items: start; }
.prof-col, .prof-side { display: flex; flex-direction: column; gap: 14px; }

.prof-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 18px;
}
.prof-card h2 {
  margin: 0 0 10px; font-size: 12px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted);
}
.prof-card p { margin: 0; font-size: 14px; }

.prof-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.prof-list li { font-size: 14px; }
.prof-list li strong { display: block; }
.prof-list li span { font-size: 13px; color: var(--muted); }

.prof-dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; font-size: 13px; }
.prof-dl dt { color: var(--muted); white-space: nowrap; }
.prof-dl dd { margin: 0; }
.prof-dl dd a { color: var(--accent); text-decoration: none; }

.prof-address { font-style: normal; font-size: 13px; line-height: 1.6; }
/* The map pin under the address: the one place on the page where the address
   becomes something a visitor can act on. */
.prof-map-link {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 10px;
  font-size: 13px; font-weight: 600; text-decoration: none;
  color: var(--accent); background: var(--accent-soft);
  border-radius: 999px; padding: 7px 13px 7px 11px;
  transition: background .14s ease, color .14s ease;
}
.prof-map-link:hover { background: var(--accent); color: var(--accent-ink); }
.prof-tags { display: flex; gap: 7px; flex-wrap: wrap; }
.prof-back { margin-top: 26px; font-size: 13px; }
.prof-back a { color: var(--accent); text-decoration: none; }

.pub-gone { text-align: center; padding: 70px 20px; }
.pub-gone-ico { font-size: 40px; margin-bottom: 12px; }
.pub-gone h1 { font-size: 22px; margin: 0 0 8px; }
.pub-gone p { color: var(--muted); margin: 0 0 8px; }

@media (max-width: 860px) {
  .prof-body { grid-template-columns: 1fr; }
  .pub-hero h1 { font-size: 24px; }
  .prof-id h1 { font-size: 22px; }
  .prof-avatar img, .prof-avatar > span:not(.prof-zoom-hint) { width: 80px; height: 80px; font-size: 26px; }
}


/* ============================================================================
   MEMBER PANEL — mobile first, and app-shaped
   ========================================================================= */

.mp-body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--font-sans); font-size: 15px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* Room for the fixed header and the bottom bar, plus the phone's own
     safe areas so nothing sits under the notch or the home indicator. */
  padding-top: 56px;
  padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px));
}

.mp-head {
  position: fixed; inset: 0 0 auto 0; z-index: 40; height: 56px;
  background: var(--surface); border-bottom: 1px solid var(--line);
  padding-top: env(safe-area-inset-top, 0px);
}
.mp-head-in {
  display: flex; align-items: center; gap: 12px; height: 56px;
  max-width: 720px; margin: 0 auto; padding: 0 14px;
}
.mp-brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: inherit; min-width: 0; }
.mp-mark {
  width: 32px; height: 32px; border-radius: 9px; background: var(--accent); color: var(--accent-ink);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 13px; flex: 0 0 auto;
}
.mp-mark.lg { width: 56px; height: 56px; border-radius: 16px; font-size: 20px; }
.mp-title { font-weight: 700; font-size: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mp-me { margin-left: auto; flex: 0 0 auto; text-decoration: none; }
.mp-me img, .mp-me > span {
  width: 32px; height: 32px; border-radius: 50%; object-fit: cover;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent-2); font-weight: 700; font-size: 11px;
}

.mp-main { max-width: 720px; margin: 0 auto; }
.mp-page { padding: 14px; display: flex; flex-direction: column; gap: 14px; }

/* Bottom navigation */
.mp-nav {
  position: fixed; inset: auto 0 0 0; z-index: 40;
  display: flex; background: var(--surface); border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.mp-nav-item {
  flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 9px 4px 10px; text-decoration: none; color: var(--muted);
  font-size: 10px; font-weight: 600; min-width: 0;
}
.mp-nav-item.on { color: var(--accent); }
.mp-nav-item.on svg { transform: translateY(-1px); }

/* ── The member's own card, which the panel opens on ───────────────────────── */
.mp-hero {
  display: flex; align-items: center; gap: 14px; padding: 18px;
  border-radius: 18px; color: #fff;
  /* The theme's accent, deepened — the one place in the panel that carries a
     full-bleed colour, so the app opens on something with presence. */
  background:
    radial-gradient(120% 140% at 100% 0%, color-mix(in oklab, var(--accent) 55%, #ffffff) 0%, transparent 60%),
    linear-gradient(135deg, var(--accent) 0%, var(--accent-2) 100%);
  box-shadow: 0 8px 22px color-mix(in oklab, var(--accent) 28%, transparent);
}
.mp-hero-av { flex: 0 0 auto; }
.mp-hero-av img, .mp-hero-av > span {
  width: 58px; height: 58px; border-radius: 50%; object-fit: cover;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .22); color: #fff;
  font-weight: 700; font-size: 19px;
  border: 2px solid rgba(255, 255, 255, .5);
}
.mp-hero-txt { min-width: 0; }
.mp-hero-greet { font-size: 13px; opacity: .85; }
.mp-hero-name { font-size: 23px; font-weight: 700; letter-spacing: -.02em; line-height: 1.15; }
.mp-hero-biz {
  font-size: 12px; opacity: .85; margin-top: 3px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.mp-notice {
  background: var(--accent-soft); color: var(--ink); border-radius: 12px;
  padding: 12px 14px; font-size: 13px; font-weight: 500;
}
/* The iPhone install hint: quieter than a notice, since it is advice rather
   than news, and it carries its own way of being dismissed for good. */
.mp-ios-hint {
  display: flex; align-items: center; gap: 9px;
  background: var(--surface); border: 1px dashed color-mix(in oklab, var(--accent) 40%, var(--line));
  border-radius: 12px; padding: 10px 12px; font-size: 12.5px; color: var(--ink-2);
}
.mp-ios-hint b { font-weight: 700; color: var(--ink); }
.mp-ios-ico {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent);
}
.mp-ios-hint button {
  margin-left: auto; flex: 0 0 auto; border: 0; background: none; cursor: pointer;
  color: var(--muted-2); font: inherit; font-size: 13px; padding: 2px 4px; line-height: 1;
}
.mp-ios-hint button:hover { color: var(--err); }
.mp-saved {
  background: var(--ok-soft); color: var(--ok); border-radius: 12px;
  padding: 11px 14px; font-size: 13px; font-weight: 600;
}


/* ── Upcoming strip ───────────────────────────────────────────────────────── */
.mp-upcoming { display: flex; gap: 10px; }
.mp-up {
  flex: 1 1 0; text-align: center; text-decoration: none; color: inherit;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 14px; padding: 13px 6px;
  transition: transform .14s ease, box-shadow .14s ease, border-color .14s ease;
}
.mp-up:active { transform: scale(.97); }
.mp-up-ico { display: block; font-size: 17px; line-height: 1; }
.mp-up-n { display: block; font-size: 20px; font-weight: 700; letter-spacing: -.02em; margin-top: 4px; }
.mp-up-l { display: block; font-size: 11px; color: var(--muted); margin-top: 1px; }

/* ── Quick actions ────────────────────────────────────────────────────────── */
.mp-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.mp-action {
  display: flex; align-items: center; gap: 11px; padding: 14px;
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid var(--mp-tone, var(--accent));
  border-radius: 14px; text-decoration: none; color: inherit;
  transition: transform .14s ease, box-shadow .14s ease;
}
.mp-action:active { transform: scale(.985); }
.mp-action:hover { box-shadow: 0 6px 16px rgba(20, 18, 16, .08); }
/* One colour each, so the four are told apart by position and hue together. */
.mp-action.a1 { --mp-tone: var(--accent); }
.mp-action.a2 { --mp-tone: oklch(0.53 0.14 152); }
.mp-action.a3 { --mp-tone: oklch(0.60 0.15 62);  }
.mp-action.a4 { --mp-tone: oklch(0.52 0.17 300); }
.mp-action-ico {
  font-size: 18px; flex: 0 0 auto;
  width: 38px; height: 38px; border-radius: 11px;
  display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in oklab, var(--mp-tone) 12%, transparent);
}
.mp-action-txt { min-width: 0; }
.mp-action-txt b { display: block; font-size: 13px; line-height: 1.25; }
.mp-action-txt span { display: block; font-size: 11px; color: var(--muted); margin-top: 2px; }

/* Blocks (announcements, events) */
.mp-block { display: flex; flex-direction: column; gap: 9px; }
.mp-block-head { display: flex; justify-content: space-between; align-items: baseline; }
.mp-block-head h2 { margin: 0; font-size: 13px; font-weight: 700; }
.mp-block-head a { font-size: 12px; color: var(--accent); text-decoration: none; }

.mp-ann {
  background: var(--surface); border: 1px solid var(--line); border-left-width: 3px;
  border-radius: 12px; padding: 13px 14px;
}
.mp-ann.important { border-left-color: var(--warn); }
.mp-ann.urgent    { border-left-color: var(--err); }
.mp-ann.normal    { border-left-color: var(--line); }
.mp-ann-top { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.mp-ann-top b { font-size: 14px; }
.mp-ann p { margin: 6px 0 0; font-size: 13px; color: var(--muted); }
.mp-ann footer, .mp-ann time { display: block; margin-top: 8px; font-size: 11px; color: var(--muted-2); }
.mp-ann-img { width: 100%; border-radius: 9px; margin-top: 10px; }

.mp-event {
  display: flex; gap: 13px; background: var(--surface);
  border: 1px solid var(--line); border-radius: 12px; padding: 13px 14px;
}
.mp-event-date {
  flex: 0 0 auto; width: 46px; text-align: center; background: var(--accent-soft);
  border-radius: 9px; padding: 7px 0; align-self: flex-start;
}
.mp-event-date b { display: block; font-size: 19px; font-weight: 700; color: var(--accent-2); line-height: 1; }
.mp-event-date span { font-size: 10px; text-transform: uppercase; color: var(--accent-2); }
.mp-event-body { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.mp-event-body b { font-size: 14px; }
.mp-event-body span { font-size: 12px; color: var(--muted); }
.mp-event-body p { margin: 6px 0 0; font-size: 13px; }
.mp-event-body .pill { align-self: flex-start; }

/* Search + filter */
.mp-search { position: relative; display: flex; align-items: center; }
/* The magnifier only: a child selector, or the cross inside the clear button is
   dragged over to the left edge as well and the button renders empty. */
.mp-search > svg { position: absolute; left: 14px; color: var(--muted); pointer-events: none; }
/* type=search draws a clear button of its own; ours stays, since it also clears
   the Livewire value. */
.mp-search input::-webkit-search-cancel-button,
.mp-search input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
.mp-search input::-ms-clear { display: none; width: 0; height: 0; }
.mp-search input {
  width: 100%; padding: 12px 40px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  font: inherit; font-size: 15px; outline: none;
}
.mp-search input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 18%, transparent);
}
.mp-search button { position: absolute; right: 12px; background: none; border: 0; cursor: pointer; color: var(--muted); display: flex; }
.mp-search.big input { padding-top: 15px; padding-bottom: 15px; font-size: 16px; }

.mp-filter { display: flex; align-items: center; gap: 10px; }
.mp-filter select {
  flex: 1 1 auto; border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  border-radius: 999px; padding: 9px 14px; font: inherit; font-size: 13px; outline: none;
}
/* The category filter is an autocomplete, so the pill shape lives on its input. */
.mp-filter-ac { position: relative; flex: 1 1 auto; min-width: 0; }
.mp-filter .ac-input {
  border-radius: 999px; padding: 9px 30px 9px 14px; font-size: 13px;
  background: var(--surface); cursor: pointer;
}
.mp-filter .ac-input:focus { cursor: text; }
.mp-filter-count { font-size: 12px; color: var(--muted); font-family: var(--font-mono); }

.mp-chips { display: flex; gap: 7px; flex-wrap: wrap; }
.mp-chips button {
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
  border-radius: 999px; padding: 7px 13px; font: inherit; font-size: 12px; cursor: pointer;
}
.mp-chips button.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 600; }
.mp-chips.tabs { overflow-x: auto; flex-wrap: nowrap; padding-bottom: 2px; }
.mp-chips.tabs button { white-space: nowrap; }

.mp-seg {
  display: flex; gap: 3px; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 999px; padding: 3px;
}
.mp-seg button {
  flex: 1 1 0; border: 0; background: none; cursor: pointer; font: inherit; font-size: 13px;
  padding: 8px; border-radius: 999px; color: var(--muted);
}
.mp-seg button.on { background: var(--accent); color: var(--accent-ink); font-weight: 600; }

/* Member cards */
.mp-card {
  display: flex; align-items: center; gap: 10px; padding: 11px 13px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
}
.mp-card-who { display: flex; align-items: center; gap: 11px; flex: 1 1 auto; min-width: 0; text-decoration: none; color: inherit; }
.mp-card-av { flex: 0 0 auto; }
.mp-card-av img, .mp-card-av > span {
  width: 42px; height: 42px; border-radius: 50%; object-fit: cover;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent-2); font-weight: 700; font-size: 13px;
}
.mp-card-txt { min-width: 0; display: flex; flex-direction: column; }
.mp-card-txt b { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mp-card-txt > span { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mp-card-cat { color: var(--accent-2) !important; font-weight: 600; font-size: 11px !important; }
.mp-card-match { font-size: 10px !important; color: var(--muted-2) !important; font-style: italic; }
.mp-card-acts { display: flex; gap: 7px; flex: 0 0 auto; }
.mp-act {
  width: 36px; height: 36px; border-radius: 50%; display: inline-flex;
  align-items: center; justify-content: center; color: #fff; text-decoration: none;
}
.mp-act.call { background: var(--accent); }
.mp-act.wa   { background: var(--accent-2); }

/* "Who can help" */
.mp-ask-head h1 { margin: 0 0 5px; font-size: 20px; font-weight: 700; }
.mp-ask-head p { margin: 0; font-size: 13px; color: var(--muted); }
.mp-examples { display: flex; gap: 7px; flex-wrap: wrap; align-items: center; font-size: 12px; color: var(--muted); }
.mp-examples button {
  border: 1px solid var(--line); background: var(--surface); color: var(--accent);
  border-radius: 999px; padding: 6px 12px; font: inherit; font-size: 12px; cursor: pointer;
}
.mp-result-count { font-size: 12px; color: var(--muted); }

/* Day groupings */
.mp-day { display: flex; flex-direction: column; gap: 9px; }
.mp-day-head {
  display: flex; align-items: baseline; gap: 9px;
  padding-bottom: 5px; border-bottom: 2px solid var(--line);
}
.mp-day-head b { font-size: 15px; }
.mp-day-head span { font-size: 11px; color: var(--muted); }
.mp-occ { display: flex; flex-direction: column; gap: 4px; }
.mp-occ-years { font-size: 11px; color: var(--accent-2); font-weight: 600; padding-left: 13px; }

/* Member profile, inside the panel */
.mp-prof-head { text-align: center; padding: 6px 0 4px; }
.mp-prof-head.compact { padding-bottom: 0; }
.mp-prof-av { display: flex; justify-content: center; margin-bottom: 10px; }
.mp-prof-av img, .mp-prof-av > span {
  width: 84px; height: 84px; border-radius: 24px; object-fit: cover;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent-2); font-weight: 700; font-size: 27px;
}
.mp-prof-head h1 { margin: 0 0 3px; font-size: 20px; font-weight: 700; }
.mp-prof-role { font-size: 13px; color: var(--muted); margin-bottom: 9px; }
.mp-prof-pills { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; }
.mp-prof-intro { font-size: 13px; margin: 10px 0 0; }

.mp-prof-acts { display: grid; grid-template-columns: repeat(auto-fit, minmax(88px, 1fr)); gap: 8px; }
.mp-pact {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 12px 6px; border-radius: 12px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); text-decoration: none; cursor: pointer;
  font: inherit; font-size: 11px; font-weight: 600;
}
.mp-pact span:first-child { font-size: 17px; }
.mp-pact.call,
.mp-pact.wa,
.mp-pact.mail,
.mp-pact.web,
.mp-pact.map,
.mp-pact.save { border-color: var(--accent); color: var(--accent); }
.mp-pact.share { border-color: var(--accent); background: var(--accent); color: var(--accent-ink); }

.mp-pcard { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 15px; }
.mp-pcard h2 {
  margin: 0 0 8px; font-size: 11px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted);
}
.mp-pcard p { margin: 0; font-size: 14px; }
.mp-plist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.mp-plist li b { display: block; font-size: 14px; }
.mp-plist li span { font-size: 12px; color: var(--muted); }
.mp-pdl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 5px 12px; font-size: 13px; }
.mp-pdl dt { color: var(--muted); white-space: nowrap; }
.mp-pdl dd { margin: 0; }
.mp-pdl dd a { color: var(--accent); text-decoration: none; }
.mp-ptags { display: flex; gap: 6px; flex-wrap: wrap; }
.mp-back { text-align: center; font-size: 13px; padding-top: 4px; }
.mp-back a { color: var(--accent); text-decoration: none; }

/* More menu */
.mp-me-card {
  display: flex; align-items: center; gap: 13px; padding: 15px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
}
.mp-me-av img, .mp-me-av > span {
  width: 52px; height: 52px; border-radius: 50%; object-fit: cover;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent-2); font-weight: 700; font-size: 16px;
}
.mp-me-card b { display: block; font-size: 16px; }
.mp-me-card span { display: block; font-size: 12px; color: var(--muted); }

.mp-menu {
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px; overflow: hidden;
}
.mp-menu-item {
  display: flex; align-items: center; gap: 12px; padding: 13px 15px; width: 100%;
  border: 0; border-bottom: 1px solid var(--line-2); background: none; cursor: pointer;
  text-decoration: none; color: inherit; font: inherit; text-align: left;
}
.mp-menu-item:last-child { border-bottom: 0; }
.mp-menu-item:active { background: var(--surface-2); }
.mp-menu-ico { font-size: 18px; flex: 0 0 auto; width: 24px; text-align: center; }
.mp-menu-txt { flex: 1 1 auto; min-width: 0; }
.mp-menu-txt b { display: block; font-size: 14px; }
.mp-menu-txt span { display: block; font-size: 11px; color: var(--muted); }
.mp-menu-go { color: var(--muted-2); font-size: 18px; flex: 0 0 auto; }

.mp-logout { display: flex; }
.mp-foot { text-align: center; font-size: 11px; color: var(--muted-2); padding: 6px 0 4px; }

.mp-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  width: 100%; padding: 13px 18px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface); color: var(--ink); font: inherit; font-size: 15px; font-weight: 600;
  cursor: pointer; text-decoration: none;
}
.mp-btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.mp-btn.ghost { color: var(--muted); }
.mp-btn:disabled { opacity: .6; cursor: default; }

.mp-empty { text-align: center; padding: 46px 20px; color: var(--muted); }
.mp-empty > div:first-child { font-size: 32px; margin-bottom: 8px; }
.mp-empty p { margin: 0 0 6px; font-size: 14px; }
.mp-empty .dim { font-size: 12px; color: var(--muted-2); }
.mp-pager { display: flex; justify-content: center; padding-top: 6px; }
.dim { color: var(--muted); }

/* Member profile editor */
.mp-form { display: flex; flex-direction: column; gap: 14px; }
.mp-form .field label { display: flex; align-items: center; gap: 8px; }
.mp-form .field input:not([type="checkbox"]),
.mp-form .field select,
.mp-form .field textarea {
  width: 100%; border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  border-radius: 9px; padding: 11px 12px; font: inherit; font-size: 15px; outline: none;
}
.mp-form .field input:focus, .mp-form .field select:focus, .mp-form .field textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 18%, transparent);
}
.vis {
  font-size: 9px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px;
}
.vis.pub  { background: var(--ok-soft); color: var(--ok); }
.vis.priv { background: var(--surface-3); color: var(--muted); }
.mp-form-foot {
  position: sticky; z-index: 20;
  /* Above the fixed bottom bar (64px + the phone's own inset), not behind it. */
  bottom: calc(72px + env(safe-area-inset-bottom, 0px));
  /* Its own ground and a hairline, so a long form scrolling underneath passes
     behind a bar rather than behind a button floating over the fields. The
     negative margins let it span the page's own padding. */
  margin: 6px -14px -14px; padding: 12px 14px;
  background: var(--bg); border-top: 1px solid var(--line);
}
/* `.entry-lines` carries a 720px floor, from the inventory grids it was built
   for — those had eight columns and were meant to scroll sideways. This one has
   three and has to fit a phone, so the floor is lifted. */
.mp-lines { background: var(--surface); min-width: 0 !important; width: 100%; }
.mp-lines input { font-size: 14px !important; padding: 9px 10px !important; }
/* A product is two fields: its name, and a line about it. On a phone they stack
   rather than sitting side by side, so the second is set in behind a rule and
   toned down — otherwise it reads as a second, unrelated product. */
.mp-lines .li-desc {
  margin-top: 6px; margin-left: 12px; width: calc(100% - 12px);
  /* Smaller and set in behind a rule. The text itself stays full strength —
     it is being typed, and muting what somebody is editing only makes it
     harder to read. */
  font-size: 13px !important;
  border-left: 2px solid var(--line) !important;
  border-top-left-radius: 0 !important; border-bottom-left-radius: 0 !important;
}
.mp-lines .li-desc:focus { border-left-color: var(--accent) !important; }
.mp-lines-hint {
  display: block; font-weight: 400; text-transform: none; letter-spacing: 0;
  font-size: 10px; color: var(--muted-2); margin-top: 1px;
}

/* Member sign-in */
.mp-auth { display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 0; }
.mp-auth-wrap { width: 100%; max-width: 400px; padding: 24px 18px; }
.mp-auth-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: 18px; padding: 26px 22px;
}
.mp-auth-brand { text-align: center; margin-bottom: 20px; }
.mp-auth-brand .mp-mark { margin: 0 auto 12px; }
.mp-auth-brand h1 { margin: 0 0 4px; font-size: 21px; font-weight: 700; }
.mp-auth-brand p { margin: 0; font-size: 13px; color: var(--muted); }
.mp-auth-form { display: flex; flex-direction: column; gap: 14px; }
.mp-auth-form .field { display: flex; flex-direction: column; gap: 5px; }
.mp-auth-form label { font-size: 12px; font-weight: 600; color: var(--muted); }
.mp-auth-form input:not([type="checkbox"]) {
  width: 100%; border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  border-radius: 10px; padding: 12px 13px; font: inherit; font-size: 16px; outline: none;
}
.mp-auth-form input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 18%, transparent);
}
.mp-pw { position: relative; display: flex; align-items: center; }
.mp-pw button {
  position: absolute; right: 12px; background: none; border: 0; cursor: pointer;
  color: var(--accent); font: inherit; font-size: 12px; font-weight: 600;
}
.mp-auth-err {
  background: var(--err-soft); color: var(--err); border-radius: 10px;
  padding: 11px 13px; font-size: 13px; margin-bottom: 14px;
}
.mp-auth-help { font-size: 12px; color: var(--muted); text-align: center; margin: 16px 0 0; }
.mp-auth-foot { text-align: center; margin-top: 16px; font-size: 13px; }
.mp-auth-foot a { color: var(--accent); text-decoration: none; }

.pw-meter { margin-top: 7px; }
.pw-bar { height: 5px; border-radius: 3px; background: var(--surface-3); overflow: hidden; }
.pw-bar span { display: block; height: 100%; background: var(--err); transition: width .2s ease, background .2s ease; }
.pw-bar span.s3 { background: var(--warn); }
.pw-bar span.s4, .pw-bar span.s5 { background: var(--ok); }
.pw-hint { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 6px; font-size: 10px; color: var(--muted-2); }
.pw-hint .ok { color: var(--ok); font-weight: 600; }

@media (min-width: 720px) {
  .mp-actions { grid-template-columns: repeat(4, 1fr); }
}

/* The filter row above a listing.
   The older screens wrap their controls in `.filters-inner`; the chapter
   directory's screens put them straight into `.filter-bar`, so the bar itself
   lays out as a wrapping row and an inner panel simply takes the full width. */
.filter-bar { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }
.filter-bar > .filters-inner { flex: 1 1 100%; }
.filter-bar > .field { margin-bottom: 0; }

/* ============================================================================
   MEMBER PROFILE EDITOR
   ----------------------------------------------------------------------------
   A long form on a phone. Left as one list of labels and boxes it reads as a
   wall, so it is broken into six cards, each with a tinted header and a tone of
   its own — colour and an icon give the eye landmarks that a heading alone
   does not.

   The tones are their own colours rather than the theme accent, so the six stay
   distinguishable whichever theme is on.
   ========================================================================= */

.mpf { gap: 16px; }

.mpf [data-tone="blue"]   { --mpf-tone: var(--accent); }
.mpf [data-tone="green"]  { --mpf-tone: oklch(0.53 0.14 152); }
.mpf [data-tone="amber"]  { --mpf-tone: oklch(0.58 0.14 62);  }
.mpf [data-tone="violet"] { --mpf-tone: oklch(0.52 0.17 300); }
.mpf [data-tone="teal"]   { --mpf-tone: oklch(0.52 0.11 200); }
.mpf [data-tone="rose"]   { --mpf-tone: oklch(0.55 0.17 15);  }

/* ── Hero ─────────────────────────────────────────────────────────────────── */
.mpf-hero {
  border-radius: 18px; padding: 18px; color: #fff;
  background:
    radial-gradient(120% 140% at 100% 0%, color-mix(in oklab, var(--accent) 55%, #ffffff) 0%, transparent 60%),
    linear-gradient(135deg, var(--accent) 0%, var(--accent-2) 100%);
  box-shadow: 0 8px 22px color-mix(in oklab, var(--accent) 28%, transparent);
}
.mpf-hero-top { display: flex; align-items: center; gap: 14px; }
.mpf-hero-av { flex: 0 0 auto; }
.mpf-hero-av img, .mpf-hero-av > span {
  width: 64px; height: 64px; border-radius: 50%; object-fit: cover;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .22); color: #fff;
  font-weight: 700; font-size: 21px;
  border: 2px solid rgba(255, 255, 255, .5);
}
.mpf-hero-id { min-width: 0; }
.mpf-hero-id h1 {
  margin: 0; font-size: 21px; font-weight: 700; letter-spacing: -.02em; line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mpf-hero-cat { font-size: 12px; opacity: .88; margin-top: 2px; }
.mpf-hero-link {
  display: inline-flex; align-items: center; gap: 5px; margin-top: 8px;
  padding: 5px 11px; border-radius: 999px;
  background: rgba(255, 255, 255, .2); color: #fff; text-decoration: none;
  font-size: 11px; font-weight: 600;
}
.mpf-hero-link:hover { background: rgba(255, 255, 255, .32); }

/* The completeness meter — the one number that says whether there is still
   work to do on this page. */
.mpf-meter { margin-top: 16px; }
.mpf-meter-top {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  font-size: 12px; font-weight: 700; margin-bottom: 6px;
}
.mpf-meter-count { font-weight: 500; opacity: .8; font-size: 11px; }
.mpf-meter-track {
  height: 7px; border-radius: 999px; overflow: hidden;
  background: rgba(255, 255, 255, .28);
}
.mpf-meter-fill {
  height: 100%; border-radius: 999px; background: #fff;
  transition: width .4s ease;
}
.mpf-meter-next { font-size: 11px; opacity: .85; margin-top: 7px; }
.mpf-meter-next.done { opacity: 1; font-weight: 600; }

/* ── Section tabs ─────────────────────────────────────────────────────────── */
.mpf-tabs {
  display: flex; gap: 7px; overflow-x: auto; padding-bottom: 3px;
  scrollbar-width: none;
}
.mpf-tabs::-webkit-scrollbar { display: none; }
.mpf-tab {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border-radius: 999px; cursor: pointer; white-space: nowrap;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
  font: inherit; font-size: 13px; font-weight: 500;
  transition: background .14s ease, color .14s ease, border-color .14s ease;
}
.mpf-tab-ico { font-size: 13px; line-height: 1; }
.mpf-tab:hover { color: var(--ink); border-color: var(--hairline); }
.mpf-tab.on {
  background: var(--mpf-tone); border-color: var(--mpf-tone);
  color: #fff; font-weight: 600;
  box-shadow: 0 3px 10px color-mix(in oklab, var(--mpf-tone) 34%, transparent);
}

/* ── Section cards ────────────────────────────────────────────────────────── */
.mpf-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 18px; overflow: hidden;
  box-shadow: 0 2px 10px rgba(20, 18, 16, .04);
}
.mpf-card-head {
  display: flex; align-items: center; gap: 12px; padding: 15px 16px;
  /* A wash of the section's own colour, so the card is placed before a word of
     it is read. */
  background: color-mix(in oklab, var(--mpf-tone) 9%, var(--surface));
  border-bottom: 1px solid color-mix(in oklab, var(--mpf-tone) 22%, var(--line));
}
.mpf-card-ico {
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: 13px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 19px; background: var(--surface);
  border: 1px solid color-mix(in oklab, var(--mpf-tone) 26%, var(--line));
  box-shadow: 0 1px 3px rgba(20, 18, 16, .06);
}
.mpf-card-head h2 {
  margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -.01em;
  color: color-mix(in oklab, var(--mpf-tone) 72%, var(--ink));
}
.mpf-card-head p { margin: 2px 0 0; font-size: 11px; color: var(--muted); }

.mpf-card-body { padding: 16px; display: flex; flex-direction: column; gap: 15px; }

/* ── Fields ───────────────────────────────────────────────────────────────── */
.mpf-field { display: flex; flex-direction: column; gap: 6px; }
.mpf-label {
  display: flex !important; align-items: center; justify-content: space-between;
  gap: 10px; margin: 0;
}
.mpf-label > span:first-child {
  font-size: 11px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted);
}
/* A field the chapter owns is dimmed as a whole, so it is obvious at a glance
   which boxes are the member's to fill in. */
.mpf-field.locked .mpf-label > span:first-child { color: var(--muted-2); }
.mpf-field .fld-hint { display: flex; align-items: center; gap: 5px; }

/* ── The save bar ─────────────────────────────────────────────────────────── */
.mpf .mp-form { display: flex; flex-direction: column; gap: 16px; }

/* ── Member tags ──────────────────────────────────────────────────────────────
   Each chip is drawn in the tag's own accent (--tag) with black or white ink
   (--tag-ink) picked by the model for contrast. The row wraps, so a member with
   several recognitions never pushes a card wider. */
.tag-row { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.tag-chip {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--tag, var(--accent)); color: var(--tag-ink, #fff);
  font-size: 11px; font-weight: 700; line-height: 1; letter-spacing: .01em;
  padding: 5px 10px 5px 8px; border-radius: 999px; white-space: nowrap;
  box-shadow: 0 1px 2px color-mix(in oklab, var(--tag, #000) 35%, transparent);
}
.tag-chip::before {
  content: '★'; font-size: 9px; opacity: .85;
}
.tag-row.sm { gap: 4px; margin-top: 3px; }
.tag-row.sm .tag-chip { font-size: 10px; padding: 3px 7px 3px 6px; }
/* Inside the member-panel card the text column clips its spans; tags wrap. */
.mp-card-txt > .tag-row { white-space: normal; overflow: visible; }
.mp-card-txt > .tag-row .tag-chip { color: var(--tag-ink, #fff); }
.pub-card-tags, .mp-prof-tags { justify-content: center; }
.prof-tags { margin-bottom: 10px; }
.prof-tags .tag-chip { font-size: 12px; padding: 6px 12px 6px 10px; }
.mp-prof-tags { margin: 4px 0 8px; }

/* The colour field on a master form: picker, hex, and a live chip preview. */
.color-field { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.color-field input[type="color"] {
  width: 42px; height: 34px; padding: 2px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface);
}
.color-field input[type="text"] { width: 100px; text-transform: uppercase; }

/* ============================================================================
   PUBLIC SITE — the editorial layer
   ----------------------------------------------------------------------------
   A directory is a register of people, so it is set like one: a serif for the
   names and the numbers, paper rather than screen-grey underneath, and motion
   that carries the reader from the list to a member and back.

   Everything here is scoped to .pub-body, so the admin shell and the member
   panel are untouched. Motion is opt-out twice over: the appearance preference
   (data-motion="reduced") and the system setting, both at the foot of the block.
   ========================================================================= */

.pub-body {
  --serif: "Newsreader", Georgia, "Times New Roman", serif;
  /* Two barely-there washes of the accent, so the page has depth without a
     picture behind it. */
  background:
    radial-gradient(1100px 520px at 12% -8%, color-mix(in oklab, var(--accent) 7%, transparent), transparent 70%),
    radial-gradient(900px 480px at 100% 0%, color-mix(in oklab, var(--accent) 5%, transparent), transparent 66%),
    var(--bg);
  background-attachment: fixed;
}

/* ── The page arrives ─────────────────────────────────────────────────────── */
@keyframes pubRise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
@keyframes pubRule {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
@keyframes pubAura {
  0%, 100% { transform: translate(-50%, -50%) scale(1);    opacity: .55; }
  50%      { transform: translate(-50%, -50%) scale(1.07); opacity: .85; }
}
@keyframes pubHalo {
  0%, 100% { opacity: .5;  transform: scale(1); }
  50%      { opacity: .85; transform: scale(1.05); }
}

/* Each block rises a beat after the one above it. --i is set in the markup for
   the cards, the one run long enough to need counting. */
.pub-rise {
  animation: pubRise .55s cubic-bezier(.2, .7, .3, 1) both;
  animation-delay: calc(var(--i, 0) * 45ms + var(--d, 0ms));
}

/* ── Masthead ─────────────────────────────────────────────────────────────── */
.pub-hero { position: relative; }

.pub-stats {
  position: relative; border: 0; background: none; box-shadow: none;
  padding: 0; margin-bottom: 18px; display: block; text-align: center;
}
/* The glow behind the count — the one flourish on the page, and it breathes. */
.pub-stats::before {
  content: ''; position: absolute; left: 50%; top: 52%;
  width: 280px; height: 170px;
  background: radial-gradient(closest-side, color-mix(in oklab, var(--accent) 17%, transparent), transparent);
  filter: blur(4px); pointer-events: none; z-index: 0;
  animation: pubAura 7s ease-in-out infinite;
}
.pub-stat { position: relative; z-index: 1; padding: 6px 0 0; min-width: 0; }
.pub-stat + .pub-stat::before { display: none; }
.pub-stat-n {
  font-family: var(--serif); font-weight: 500; font-size: clamp(56px, 11vw, 88px);
  line-height: .92; letter-spacing: -.02em; color: var(--ink);
}
.pub-stat-l {
  margin-top: 2px; font-size: 11px; font-weight: 600; letter-spacing: .22em;
  text-transform: uppercase; color: var(--accent);
}

/* ── Search ───────────────────────────────────────────────────────────────── */
.pub-search input {
  padding: 16px 46px; border-radius: 999px; font-size: 15px;
  border-color: color-mix(in oklab, var(--accent) 18%, var(--line));
  transition: border-color .18s ease, box-shadow .25s ease, transform .18s ease;
}
.pub-search input:focus {
  transform: translateY(-1px);
  box-shadow: 0 0 0 5px color-mix(in oklab, var(--accent) 12%, transparent),
              0 10px 26px color-mix(in oklab, var(--accent) 14%, transparent);
}
.pub-search > svg { transition: color .18s ease, transform .18s ease; }
.pub-search:focus-within > svg { color: var(--accent); transform: scale(1.08); }

/* ── Cards ────────────────────────────────────────────────────────────────── */
/* Two to a row on a phone (a visitor scrolls through faces, and two at a time
   halves the scrolling), three on a tablet, four on a desktop — at two, a wide
   screen left the cards marooned. */
.pub-grid { gap: 18px; }
@media (min-width: 860px)  { .pub-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1180px) { .pub-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
/* The photo scales with the column rather than staying at its phone size. */
@media (min-width: 860px) {
  .pub-avatar img, .pub-avatar > span { width: 128px; height: 128px; font-size: 40px; }
}

.pub-card {
  position: relative; overflow: hidden; border-radius: 16px; padding: 22px 18px 16px;
  background: var(--surface);
  border-color: color-mix(in oklab, var(--accent) 10%, var(--line));
  transition: transform .28s cubic-bezier(.2, .7, .3, 1),
              box-shadow .28s ease, border-color .2s ease;
}
/* A crimson rule that draws itself along the foot of the card on hover. */
.pub-card::after {
  content: ''; position: absolute; inset: auto 0 0 0; height: 3px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  transform: scaleX(0); transform-origin: left;
  transition: transform .34s cubic-bezier(.2, .7, .3, 1);
}
.pub-card:hover, .pub-card:focus-visible {
  transform: translateY(-6px);
  border-color: color-mix(in oklab, var(--accent) 40%, var(--line));
  box-shadow: 0 18px 40px color-mix(in oklab, var(--accent) 12%, transparent),
              0 4px 10px rgba(20, 18, 16, .05);
}
.pub-card:hover::after, .pub-card:focus-visible::after { transform: scaleX(1); }

.pub-avatar { position: relative; }
/* A ring that opens out from the photo, like a stone dropped in water. */
.pub-avatar::before {
  content: ''; position: absolute; inset: -7px; border-radius: 50%;
  border: 1px solid color-mix(in oklab, var(--accent) 35%, transparent);
  opacity: 0; transform: scale(.94);
  transition: opacity .3s ease, transform .4s cubic-bezier(.2, .7, .3, 1);
}
.pub-card:hover .pub-avatar::before { opacity: 1; transform: scale(1); }
.pub-avatar img, .pub-avatar > span {
  transition: transform .4s cubic-bezier(.2, .7, .3, 1);
}
.pub-card:hover .pub-avatar img { transform: scale(1.04); }
.pub-avatar > span { font-family: var(--serif); font-weight: 500; }

.pub-card-name {
  font-family: var(--serif); font-weight: 600; font-size: 19px; letter-spacing: -.01em;
}
.pub-card-biz { font-family: var(--serif); font-style: italic; font-size: 14px; }
.pub-card-intro { line-height: 1.5; }
.pub-card-go { display: inline-flex; align-items: center; gap: 5px; }
.pub-card:hover .pub-card-go { color: var(--accent-2); }
.pub-card-go::after { content: '\2192'; transition: transform .28s cubic-bezier(.2, .7, .3, 1); }
.pub-card:hover .pub-card-go::after { transform: translateX(4px); }

/* The card the visitor just chose lifts out of the page while the profile
   loads behind it, so the two pages read as one movement, not a cut. */
@keyframes pubChosen {
  to {
    transform: translateY(-10px) scale(1.03);
    box-shadow: 0 26px 60px color-mix(in oklab, var(--accent) 22%, transparent);
  }
}
.pub-card.is-chosen { animation: pubChosen .3s cubic-bezier(.2, .7, .3, 1) forwards; z-index: 2; }
.pub-grid.is-leaving .pub-card:not(.is-chosen) {
  opacity: .4; transform: scale(.985);
  transition: opacity .26s ease, transform .26s ease;
}

/* ── Member profile ───────────────────────────────────────────────────────── */
/* The halo sits between the card and the photo, so it needs its own stacking
   context — behind the image but in front of the card it is drawn on. */
.prof-avatar { position: relative; isolation: isolate; }
.prof-avatar::after {
  content: ''; position: absolute; inset: -14px; border-radius: 30px; z-index: 0;
  background: radial-gradient(closest-side, color-mix(in oklab, var(--accent) 26%, transparent), transparent);
  animation: pubHalo 8s ease-in-out infinite; pointer-events: none;
}
.prof-avatar img, .prof-avatar > span { position: relative; z-index: 1; }
/* The header itself sits on paper, with the accent breathing behind the name. */
.prof-head {
  background:
    radial-gradient(420px 220px at 8% 0%, color-mix(in oklab, var(--accent) 6%, transparent), transparent 70%),
    var(--surface);
  border-radius: 18px; padding: 26px;
}
.prof-id h1 {
  font-family: var(--serif); font-weight: 600; font-size: clamp(28px, 4.4vw, 40px);
  line-height: 1.08; letter-spacing: -.015em;
}
.prof-role { font-family: var(--serif); font-style: italic; font-size: 16px; }
.prof-intro { font-size: 15px; line-height: 1.6; }

.prof-card { border-radius: 16px; }
.prof-card h2 { position: relative; padding-bottom: 9px; }
/* The heading draws its own rule as the card arrives. */
.prof-card h2::after {
  content: ''; position: absolute; left: 0; bottom: 0; width: 26px; height: 2px;
  background: var(--accent); transform-origin: left;
  animation: pubRule .5s cubic-bezier(.2, .7, .3, 1) both; animation-delay: .2s;
}
.prof-list li strong { font-family: var(--serif); font-weight: 600; font-size: 15px; }

/* The profile arrives in sequence: header, actions, then each card. */
.prof-reveal {
  animation: pubRise .55s cubic-bezier(.2, .7, .3, 1) both;
  animation-delay: calc(var(--i, 0) * 70ms);
}

.prof-act svg { transition: transform .22s cubic-bezier(.2, .7, .3, 1); }
.prof-act:hover svg { transform: translateY(-2px) scale(1.06); }

.tag-chip { transition: transform .2s ease; }
.tag-chip:hover { transform: translateY(-1px); }

/* ── Footer ───────────────────────────────────────────────────────────────── */
/* The footer is dark in both modes — a graphite band that closes the page and
   sets the paper above it off, rather than fading into it. */
.pub-foot {
  background: #14110F; border-top: 0; color: color-mix(in oklab, #FFFFFF 62%, transparent);
  padding: 22px 0;
}
.pub-foot strong { color: #FFFFFF; font-weight: 600; }
.pub-foot a { color: color-mix(in oklab, var(--accent) 55%, #FFFFFF); }
.pub-foot a:hover { color: #FFFFFF; }
/* On a phone the two halves stack, and a stacked row reads better centred. */
@media (max-width: 560px) {
  .pub-foot-in { flex-direction: column; align-items: center; text-align: center; gap: 6px; }
}

/* ── Anyone who would rather sit still ────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .pub-body *, .pub-body *::before, .pub-body *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}
:root[data-motion="reduced"] .pub-stats::before,
:root[data-motion="reduced"] .prof-avatar::after { animation: none; }

/* ── The paper drifts ──────────────────────────────────────────────────────
   The accent washes move out of the body and into a fixed layer of their own,
   so they can drift against the scroll. A background cannot be transformed;
   an element behind everything can. */
.pub-body { background: var(--bg); }
.pub-drift {
  position: fixed; inset: -12% -5%; z-index: 0; pointer-events: none;
  background:
    radial-gradient(1100px 520px at 12% 4%, color-mix(in oklab, var(--accent) 8%, transparent), transparent 70%),
    radial-gradient(900px 480px at 100% 10%, color-mix(in oklab, var(--accent) 6%, transparent), transparent 66%);
  transform: translate3d(0, var(--drift, 0px), 0);
  will-change: transform;
}
.pub-head, .pub-main, .pub-foot { position: relative; z-index: 1; }

/* ── Cards arriving on scroll ──────────────────────────────────────────────
   Anything below the fold waits until it is looked at. The class is added by
   the script, so a visitor with JS off simply sees the cards. */
.pub-observe { opacity: 0; transform: translateY(18px); }
.pub-observe.is-in {
  animation: pubRise .55s cubic-bezier(.2, .7, .3, 1) both;
  animation-delay: calc(var(--i, 0) * 60ms);
}

/* ── While the list is being refetched ─────────────────────────────────────
   Searching and paging both leave a gap where nothing happens; the grid dims,
   steps back and a light sweeps across it until the answer arrives. */
.pub-grid { position: relative; transition: opacity .2s ease, transform .3s ease, filter .3s ease; }
.pub-grid.is-busy { opacity: .45; transform: translateY(6px) scale(.995); filter: saturate(.7); pointer-events: none; }
.pub-grid.is-busy::before {
  content: ''; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: linear-gradient(100deg, transparent 20%,
              color-mix(in oklab, var(--accent) 10%, transparent) 45%, transparent 70%);
  background-size: 220% 100%;
  animation: pubSweep 1.1s linear infinite;
}
@keyframes pubSweep {
  from { background-position: 140% 0; }
  to   { background-position: -60% 0; }
}

/* ── Tags land one after another ───────────────────────────────────────────── */
@keyframes chipPop {
  from { opacity: 0; transform: translateY(5px) scale(.9); }
  60%  { transform: translateY(0) scale(1.04); }
  to   { opacity: 1; transform: none; }
}
.pub-body .tag-chip { animation: chipPop .42s cubic-bezier(.2, .7, .3, 1) both; }
.pub-body .tag-row .tag-chip:nth-child(2) { animation-delay: .09s; }
.pub-body .tag-row .tag-chip:nth-child(3) { animation-delay: .18s; }
.pub-body .tag-row .tag-chip:nth-child(n+4) { animation-delay: .27s; }

/* ── The count climbs to its number ────────────────────────────────────────── */
.pub-stat-n { font-variant-numeric: tabular-nums lining-nums; }

/* ── The photo opens from where it sits ────────────────────────────────────
   --gx / --gy are the distance from the middle of the screen to the middle of
   the photo that was clicked, set by the script as the lightbox opens. */
@keyframes galleryIn {
  from { opacity: 0; transform: translate3d(var(--gx, 0px), var(--gy, 0px), 0) scale(var(--gs, .35)); }
  to   { opacity: 1; transform: none; }
}
.pub-body .gallery-panel.from-origin {
  animation: galleryIn .34s cubic-bezier(.2, .7, .3, 1) both;
}
.pub-body .gallery-backdrop { animation: pubFadeIn .3s ease both; }
@keyframes pubFadeIn { from { opacity: 0; } to { opacity: 1; } }

/* ── "Link copied" ─────────────────────────────────────────────────────────── */
@keyframes pubPop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.12); }
  100% { transform: scale(1); }
}
.share-label.is-copied { display: inline-block; animation: pubPop .38s cubic-bezier(.2, .7, .3, 1); }
.prof-act.share.is-copied, .mp-pact.share.is-copied { background: var(--ok); border-color: var(--ok); }

/* ── Still, for anyone who asked ───────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .pub-observe { opacity: 1; transform: none; }
  .pub-drift { transform: none !important; }
  .pub-grid.is-busy::before { animation: none; }
}
:root[data-motion="reduced"] .pub-observe { opacity: 1; transform: none; }
:root[data-motion="reduced"] .pub-grid.is-busy::before { animation: none; }
