/* ==========================================================================
   Ecomsource — design system
   One stylesheet for every surface. Dark is the primary theme: near-black
   canvas, hairline borders, tabular numerals, restraint over decoration.
   Light theme is a token override at the bottom.
   Source of truth for tokens: design.md
   ========================================================================== */

/* --- tokens: dark (primary) ---------------------------------------------- */
:root,
[data-theme="dark"] {
  --canvas: #000000;
  --shell: #050506;
  --surface-1: #0e0e10;
  --surface-2: #16161a;
  --card: #0a0a0b;
  --card-hover: #101012;
  --grid: rgba(255, 255, 255, .022);

  --text: #f5f5f7;
  --text-muted: rgba(245, 245, 247, .58);
  --text-dim: rgba(245, 245, 247, .36);

  --border: rgba(255, 255, 255, .07);
  --border-strong: rgba(255, 255, 255, .14);
  --border-focus: rgba(226, 64, 47, .55);

  /* the mark has its own colour, so it does not move when the interface
     accent does */
  --brand-mark: #e2402f;

  --accent: #e2402f;
  --accent-ink: #ffffff;
  --accent-soft: rgba(226, 64, 47, .13);
  --accent-line: rgba(226, 64, 47, .32);

  /* the ink the temple on the auth panel is drawn in: the accent red taken
     down to a bordeaux that only just separates from the panel */
  --art-ink: #e2402f;
  --art-op: .1;

  /* a pane of glass: the light along its top edge, the sheen across its
     shoulder, the rim around it, and the fill a control on it takes */
  --glass-lip: rgba(255, 255, 255, .1);
  --glass-sheen: rgba(255, 255, 255, .16);
  --glass-rim: rgba(255, 255, 255, .13);
  --glass-fill: rgba(255, 255, 255, .07);
  --glass-fill-hover: rgba(255, 255, 255, .13);
  --glass-base: rgba(0, 0, 0, .35);
  --glass-shadow: 0 18px 40px -22px rgba(0, 0, 0, .9);

  /* the four steps a density cell can sit at before it turns red */
  --viz-cell-0: rgba(255, 255, 255, .035);
  --viz-cell-1: rgba(255, 255, 255, .075);
  --viz-cell-2: rgba(255, 255, 255, .14);
  --viz-cell-3: rgba(255, 255, 255, .22);

  --good: #22c07a;
  --good-soft: rgba(34, 192, 122, .12);
  /* Chosen. Darker than the good green, because this is a state a whole
     grid can be in at once and the good green at that count is a lot. */
  --picked: #2f8f63;
  --picked-line: #2b6f50;
  --picked-soft: rgba(47, 143, 99, .13);
  --warn: #f5a623;
  --warn-soft: rgba(245, 166, 35, .13);
  /* the accent is red now, so danger has to be told apart by lightness
     rather than hue, or every warning reads as a button */
  --bad: #ff9d8a;
  --bad-soft: rgba(255, 157, 138, .13);
  --info: #7ea1ff;
  --info-soft: rgba(126, 161, 255, .13);
  --shopify: #95bf47;

  --radius-lg: 18px;
  --radius: 13px;
  --radius-sm: 9px;
  --radius-pill: 980px;

  --shadow-card: none;
  --shadow-pop: 0 1px 2px rgba(0, 0, 0, .6), 0 24px 64px rgba(0, 0, 0, .7);
  --ring: 0 0 0 3px rgba(226, 64, 47, .28);

  --font-display: 'Poppins', -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Helvetica Neue', sans-serif;
  --font-accent: 'Montserrat', 'Poppins', -apple-system, 'Helvetica Neue', sans-serif;
  /* The label face. Not a monospace any more: the same family, set in capitals
     and tracked out, which is what carries a reference number here. */
  --font-mono: 'Poppins', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', sans-serif;

  --sidebar-w: 244px;
  --topbar-h: 60px;
  --gutter: 34px;

  /* Apple-ish easing: quick out, settled in. Never bounce. */
  --ease: cubic-bezier(.32, .72, 0, 1);
  --fast: 140ms var(--ease);
  --med: 260ms var(--ease);
}

/* Anything on the label face is uppercase and slightly tracked, so a code
   reads as a code. Set once here rather than on forty selectors. */
[class*="mono"],
.eyebrow, .ngroup, .brandblock .bs, .userrow .ur, .kpi .klabel,
thead th, .pager .meta, .sla, .badge, .pill, .chip, .tcount, .searchtrigger kbd,
.msg .mrole, .msg .mchan, .msg .mtime, .throw .ttime, .feedrow .ftime,
.feedrow .fname, .feedrow .fmeta, .prodcell .ps, .store-id .sdomain,
.leg .lrole, .parcel .pmeta, .lastmile,
.mpill .mno, .rolerow .rtxt span,
.defrow .dt, .barcol .blabel, .rrow .rl, .filerow .fname, .msg .att,
.qhead b.mono, .codebox {
  text-transform: uppercase;
  letter-spacing: .04em;
}
/* an address someone has to type back is not a label, and neither is an
   email address somebody has to read out or copy */
.addr, .mpill b, .prodcell .pt, .composer textarea, .msg .mbody,
.ps.is-email { text-transform: none; }
.ps.is-email { letter-spacing: 0; }

/* a face on every name: photo when there is one, initials on a tone from the
   id when there is not */
.avat {
  display: inline-grid; place-items: center; flex: none;
  font-family: var(--font-display); font-weight: 600; letter-spacing: .01em;
  color: color-mix(in srgb, var(--av, var(--text-muted)) 70%, var(--text));
  background: color-mix(in srgb, var(--av, var(--text-dim)) 22%, var(--surface-2));
  background-size: cover; background-position: center;
  overflow: hidden; user-select: none;
}
.avat.is-photo { color: transparent; background-color: var(--surface-2); }
.avat.is-ring { box-shadow: 0 0 0 1px var(--border-strong); }
.avstack { display: inline-flex; align-items: center; }
.avstack .avat + .avat { margin-left: -8px; box-shadow: 0 0 0 2px var(--card); }
.avname { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.avname b { font-weight: 500; }
.avname > span { min-width: 0; }
.avname .ps { margin-top: 1px; }

.photopick { display: flex; align-items: flex-start; gap: 16px; }
.photopick .ppside { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.photopick .ppside .hint { font-size: 12px; max-width: 34ch; }

/* --- reset --------------------------------------------------------------- */
* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font-display);
  font-size: 14px;
  color: var(--text);
  background-color: var(--canvas);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "cv11", "ss01";
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
button { font-family: inherit; }

::selection { background: var(--accent-soft); color: var(--text); }

/* keyboard focus only. Never kill the ring, never show it on mouse clicks. */
:focus { outline: none; }
:focus-visible {
  outline: none;
  box-shadow: var(--ring);
  border-radius: var(--radius-sm);
}

/* thin, unobtrusive scrollbars */
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 999px;
  border: 3px solid transparent;
  background-clip: content-box;
}

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

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

.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: var(--shell);
  border-right: 1px solid var(--border);
  padding: 20px 12px 24px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
}

/* the gap between the work and the account block, which the beams show through */
.sidespace {
  flex: 1;
  min-height: 40px;
  position: relative;
  overflow: hidden;
}
/* Beams of light drifting up behind the menu, in the one red this product
   already uses. The blur lives here rather than on the canvas: a canvas
   filter is the sort of thing a browser can be late to, and a missing blur
   would read as a mistake rather than as a plain page.

   Faded at both ends, hardest in the middle, so it is ground under the menu
   and never a thing competing with it. */
/* --- the light behind the menu --------------------------------------------
   Two soft masses of the one red this product already uses, crossing each
   other at a fiftieth of lava lamp speed. Twenty seven seconds and thirty
   nine: they share no factor worth noticing, so they never quite line up and
   the column is never the same twice.

   Masked away at both ends, because a wash that runs into the brand at the
   top or the account block at the foot stops being weather and starts being
   a panel with a tint on it.
   -------------------------------------------------------------------------- */
.sidedrift {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
  opacity: .5;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 10%, #000 91%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 10%, #000 91%, transparent 100%);
}
.sidedrift i {
  position: absolute;
  display: block;
  left: -35%;
  width: 170%;
  height: 40%;
  border-radius: 50%;
  filter: blur(58px);
}
.sidedrift i:first-child {
  background: radial-gradient(closest-side, rgba(226, 64, 47, .22), transparent 100%);
  animation: sidedrift-a 27s ease-in-out infinite;
}
.sidedrift i:last-child {
  background: radial-gradient(closest-side, rgba(143, 31, 22, .30), transparent 100%);
  animation: sidedrift-b 39s ease-in-out infinite;
}
/* Travelling the same way rather than past each other. Two masses starting
   at opposite ends spent most of the cycle at opposite ends, which read as
   two separate lights. Overlapping ranges and different periods keep them
   near one another: they slide together into one larger mass, come apart by
   half a column, and go back, without ever repeating. */
@keyframes sidedrift-a {
  0%, 100% { top: 2%;  transform: translateX(-6%); }
  50%      { top: 48%; transform: translateX(7%); }
}
@keyframes sidedrift-b {
  0%, 100% { top: 18%; transform: translateX(8%); }
  50%      { top: 62%; transform: translateX(-6%); }
}
/* Everything in the menu sits above it. Without this the light would be
   drawn over the nav rather than behind it. */
.sidebar > *:not(.sidedrift) { position: relative; z-index: 1; }

/* Light is paper, and light added to paper is a stain rather than a glow.
   Multiplying darkens instead, so the shape survives on white. */
html[data-theme="light"] .sidedrift {
  opacity: .18;
  mix-blend-mode: multiply;
}

/* Somebody who asked their machine to stop moving things gets the wash and
   none of the travel. Two masses standing still still read as light. */
@media (prefers-reduced-motion: reduce) {
  .sidedrift i { animation: none; }
  .sidedrift i:first-child { top: 6%; }
  .sidedrift i:last-child { top: 58%; }
}

.sidebottom { flex-shrink: 0; }
.sidebottom .ngroup { padding-top: 10px; }

.brandblock {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: 10px;
  padding: 4px 10px 2px;
  /* It is a button in the sidebar so the mark can draw itself when somebody
     presses it, and nothing else about it changes. */
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  text-align: left;
  width: 100%;
  cursor: pointer;
}
button.brandblock:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 10px; }
.brandblock .mark { overflow: visible; }

/* A store wears its own mark wherever it is listed. */
.rolerow .av .storelogo {
  width: 100%; height: 100%;
  object-fit: contain;
  border-radius: 6px;
  display: block;
}
.brandblock .mark { width: 26px; height: 26px; color: var(--brand-mark); flex: none; }
.authside .brandblock .mark { width: 30px; height: 30px; }
.brandblock .bn {
  font-weight: 700;
  font-size: 15px;
  letter-spacing: .04em;
}
.brandblock .bs {
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--text-dim);
  letter-spacing: .12em;
  text-transform: uppercase;
  margin-top: 2px;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .35; }
}

/* connected store identity card */
.store-id {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  margin: 0 2px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--card);
  transition: border-color var(--fast), background var(--fast);
}
.store-id:hover { border-color: var(--border-strong); background: var(--card-hover); }
.store-id .sg {
  width: 26px; height: 26px;
  border-radius: 7px;
  display: grid;
  place-items: center;
  flex-shrink: 0;
}
/* No logo of its own yet, so it wears ours rather than Shopify's green */
.sg { background: var(--accent); color: #fff; overflow: hidden; }
.sg.has-logo { background: var(--card-hover); border: 1px solid var(--border); }
.sg img { width: 100%; height: 100%; object-fit: cover; }
.store-id .sname {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.2;
}
.store-id .snm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* the connection, said in one dot rather than a chip of its own */
.sdot {
  width: 6px; height: 6px;
  border-radius: 50%;
  flex: none;
  background: var(--good);
  animation: pulse 2.4s var(--ease) infinite;
}
.sdot.is-wait { background: var(--warn); animation: none; }
.sdot.is-bad { background: var(--bad); animation: none; }
.store-id .sdomain {
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--text-dim);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.store-id.is-disconnected { border-color: var(--warn-soft); }
.store-id.is-disconnected .sg { background: var(--surface-2); }

/* nav */
.ngroup {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-dim);
  padding: 16px 12px 7px;
}
.navitem {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 11px;
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  font-weight: 450;
  color: var(--text-muted);
  margin-bottom: 1px;
  position: relative;
  transition: background var(--fast), color var(--fast);
}
.navitem svg { width: 16px; height: 16px; flex-shrink: 0; opacity: .8; }
.navitem:hover { background: var(--surface-1); color: var(--text); }
.navitem:hover svg { opacity: 1; }
.navitem.active {
  background: var(--surface-2);
  color: var(--text);
  font-weight: 600;
}
.navitem.active svg { color: var(--accent); opacity: 1; }
.navitem.active::before {
  content: "";
  position: absolute;
  left: -12px;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 17px;
  border-radius: 0 3px 3px 0;
  background: var(--accent);
}
.navitem .nvalue {
  margin-left: auto;
  display: inline-flex; align-items: baseline; gap: 5px;
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .01em;
  color: var(--text-muted); white-space: nowrap;
}
.navitem.active .nvalue { color: var(--text); }
/* a top-up still being checked: nearly yours, so it sits a step back */
.navitem .nvalue i { font-style: normal; color: var(--text-dim); }
.navitem .nvalue + .nbadge { margin-left: 6px; }

.navitem .nbadge {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 8.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: var(--surface-2);
  border: 1px solid var(--border);
  padding: 2px 6px;
  border-radius: var(--radius-pill);
}
.navitem .nbadge.hot { color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft); }

.sidefoot {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  padding: 12px 11px 0;
  border-top: 1px solid var(--border);
}
.sidefoot .userrow { flex: 1; min-width: 0; }
.sidefoot .iconbtn { width: 30px; height: 30px; flex: none; }
.userrow { display: flex; align-items: center; gap: 10px; min-width: 0; }
.userrow .uname {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px; min-width: 0;
  background: none; border: 0; padding: 0; cursor: pointer; color: var(--text); font: inherit; text-align: left;
}
.userrow .un { font-size: 12.5px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 130px; }
.userrow .ur { font-family: var(--font-mono); font-size: 9px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .08em; }

/* the face doubles as the way to change it */
.facebtn {
  position: relative; flex: none; padding: 0; border: 0; background: none; cursor: pointer;
  line-height: 0; border-radius: 11px;
}
.facebtn .fcam {
  position: absolute; inset: 0; display: grid; place-items: center;
  border-radius: inherit; color: #fff; background: rgba(0, 0, 0, .55);
  opacity: 0; transition: opacity var(--fast);
}
.facebtn:hover .fcam, .facebtn:focus-visible .fcam { opacity: 1; }
.facebtn:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
.tb-face { margin-left: 2px; }

/* main + topbar */
.main { flex: 1; min-width: 0; }

.topbar {
  display: flex;
  align-items: center;
  gap: 14px;
  height: var(--topbar-h);
  padding: 0 var(--gutter);
  border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--canvas) 72%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  position: sticky;
  top: 0;
  z-index: 40;
}
.topbar .tb-sub { font-size: 12.5px; color: var(--text-muted); }
.topbar .tb-right { margin-left: auto; display: flex; align-items: center; gap: 10px; }

.searchtrigger {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  padding: 0 10px 0 11px;
  min-width: 190px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--card);
  color: var(--text-dim);
  font-size: 12.5px;
  cursor: pointer;
  transition: border-color var(--fast), color var(--fast);
}
.searchtrigger:hover { border-color: var(--border-strong); color: var(--text-muted); }
.searchtrigger kbd {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 9.5px;
  padding: 2px 5px;
  border: 1px solid var(--border);
  border-radius: 5px;
  color: var(--text-dim);
}

/* sits in front of a Sync now button, written by the shell */
.syncstate {
  display: flex;
  white-space: nowrap;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  color: var(--text-muted);
}
.syncstate b { color: var(--good); font-weight: 600; }
.syncstate .sep { color: var(--text-dim); }

.iconbtn {
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--text-muted);
  cursor: pointer;
  transition: color var(--fast), border-color var(--fast), background var(--fast);
}
.iconbtn:hover { color: var(--text); border-color: var(--border-strong); background: var(--card-hover); }
.iconbtn svg { width: 15px; height: 15px; }
.iconbtn.spinning svg { animation: spin 700ms linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* content */
.content {
  padding: 28px var(--gutter) 72px;
  /* Wide enough to fill a large screen rather than leaving a third of it
     black. Not unlimited: prose is capped separately, but a table that runs
     to the edge of a 27 inch monitor is a table nobody can read across.
     1420 stopped short of a 1920 screen by three hundred pixels, which read
     as a page that had not finished loading. */
  max-width: 1680px;
}
.content.narrow { max-width: 880px; }

.crumb {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 14px;
}
.crumb b { color: var(--text-muted); font-weight: 400; }

.pagehead {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: 26px;
}
.pagetitle {
  font-size: clamp(30px, 3.6vw, 44px);
  font-weight: 800;
  letter-spacing: -.035em;
  line-height: 1.02;
  margin: 0 0 10px;
}
.pagesub {
  font-size: 14.5px;
  color: var(--text-muted);
  margin: 0;
  max-width: 640px;
  line-height: 1.55;
}
.pagesub em { font-family: var(--font-accent); font-style: italic; color: var(--text); }
.statusline {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  color: var(--text-muted);
  margin: 0 0 8px;
}
.statusline .lbl {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--good);
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.statusline .lbl::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentColor;
}
.statusline em { font-family: var(--font-accent); font-style: italic; color: var(--text-muted); }

.eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.eyebrow .right { margin-left: auto; text-transform: none; letter-spacing: .04em; }
.eyebrow .right b { color: var(--good); font-weight: 500; }

/* --- layout helpers ------------------------------------------------------ */
.grid { display: grid; gap: 14px; }
.grid-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.split { display: grid; grid-template-columns: minmax(0, 1.32fr) minmax(0, 1fr); gap: 14px; }
/* Four figures that belong together: four across while there is room for them,
   then two by two, then one. Never three, which leaves one tile orphaned on a
   row of its own. */
.grid-fit { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 1340px) {
  .grid-fit { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 1240px) {
  .grid-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .split { grid-template-columns: 1fr; }
}
@media (max-width: 1040px) {
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 680px) {
  .grid-5, .grid-4, .grid-3, .grid-2, .grid-fit { grid-template-columns: 1fr; }
}

/* --- cards --------------------------------------------------------------- */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  position: relative;
  box-shadow: var(--shadow-card);
}
.card.pad-0 { padding: 0; overflow: hidden; }
.card.tall { display: flex; flex-direction: column; }
a.card { transition: border-color var(--fast), background var(--fast), transform var(--fast); }
a.card:hover { border-color: var(--border-strong); background: var(--card-hover); }
a.card:active { transform: scale(.995); }

.cardhead {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}
.cardhead h3 { margin: 0; font-size: 13.5px; font-weight: 600; }
.cardhead .right { margin-left: auto; display: flex; align-items: center; gap: 8px; }

.scroller { overflow-y: auto; overscroll-behavior: contain; }
.scroller.h-560 { max-height: 560px; }

/* --- KPI ----------------------------------------------------------------- */
.kpi { padding: 18px; }
.kpi .klabel {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-dim);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 14px;
}
.kpi .knum {
  font-size: clamp(28px, 3vw, 40px);
  font-weight: 800;
  letter-spacing: -.04em;
  line-height: 1;
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.kpi .knum .unit { font-size: .55em; font-weight: 600; letter-spacing: -.02em; color: var(--text-muted); }
.kpi .knum.empty { color: var(--text-dim); font-weight: 500; }
.kpi .kfoot {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--text-dim);
  margin-top: 12px;
  display: flex;
  align-items: center;
  gap: 7px;
}
.kpi .kfoot b { color: var(--text-muted); font-weight: 500; }

/* --- pills, badges, chips ------------------------------------------------ */
.pill {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .04em;
  padding: 3px 8px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
.pill.up { background: var(--good-soft); color: var(--good); }
.pill.down { background: var(--bad-soft); color: var(--bad); }
.pill.flat { background: var(--surface-1); color: var(--text-dim); }
/* Money in flight: neither good news nor bad, but not something to read past. */
.pill.warn { background: var(--warn-soft); color: var(--warn); }

/* --- what happened, in order ---------------------------------------------
   The step that has not happened yet is drawn as still to come rather than
   left off, because a timeline that stops at today does not say what today is
   waiting for.
   -------------------------------------------------------------------------- */
.tline { display: flex; flex-direction: column; gap: 2px; margin-top: 8px; }
.tstep {
  display: grid;
  grid-template-columns: 14px minmax(0, 1fr);
  gap: 12px;
  padding: 0 0 14px;
  position: relative;
}
.tstep:last-child { padding-bottom: 0; }
/* The line between the dots, drawn from each step down to the next. */
.tstep:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 6px;
  top: 14px;
  bottom: 0;
  width: 1px;
  background: var(--border);
}
.tdot {
  width: 9px; height: 9px;
  margin-top: 4px;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: var(--card);
}
.tstep.is-done .tdot { background: var(--good); border-color: var(--good); }
.ttxt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ttxt b { font-size: 12.5px; font-weight: 500; }
.tstep:not(.is-done) .ttxt b { color: var(--text-muted); }
.ttxt span { font-size: 11.5px; color: var(--text-dim); line-height: 1.5; }
.ttxt em {
  font-style: normal;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-dim);
}

/* Proof of payment on hover. Below the overlay layer and above everything
   else: it appears over a table row and has to go away the moment a real
   sheet opens on top of it. */
.proofpop {
  position: fixed;
  z-index: 90;
  padding: 6px;
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, .55);
  pointer-events: none;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity .12s ease, transform .12s ease;
}
.proofpop.is-on { opacity: 1; transform: translateY(0); }
.proofpop img {
  display: block;
  max-width: 300px;
  max-height: 220px;
  border-radius: 6px;
}
.proofpop .pfile {
  display: block;
  padding: 10px 12px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-dim);
  white-space: nowrap;
}

.badge {
  font-family: var(--font-mono);
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: .07em;
  padding: 4px 9px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.badge.good, .badge.paid, .badge.fulfilled, .badge.live { background: var(--good-soft); color: var(--good); }
.badge.warn, .badge.unfulfilled, .badge.unpaid, .badge.waiting { background: var(--warn-soft); color: var(--warn); }
.badge.bad, .badge.failed { background: var(--bad-soft); color: var(--bad); }
.badge.info, .badge.process, .badge.shipped { background: var(--info-soft); color: var(--info); }
.badge.neutral, .badge.soon { background: var(--surface-2); color: var(--text-dim); }
.badge.accent { background: var(--accent-soft); color: var(--accent); }

.chip {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: var(--radius-pill);
  background: var(--surface-1);
  color: var(--text-dim);
  border: 1px solid var(--border);
}
.chip.sample { color: var(--warn); border-color: var(--warn-soft); background: var(--warn-soft); }

.dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.dot.good { background: var(--good); }
.dot.warn { background: var(--warn); }
.dot.bad { background: var(--bad); }
.dot.accent { background: var(--accent); }
.dot.dim { background: var(--text-dim); }

/* --- buttons ------------------------------------------------------------- */
.btn {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  padding: 0 16px;
  height: 34px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  border: 1px solid transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  white-space: nowrap;
  transition: transform var(--fast), background var(--fast), border-color var(--fast), color var(--fast), opacity var(--fast);
}
.btn:active { transform: scale(.97); }
.btn svg { width: 14px; height: 14px; }
.btn.accent { background: var(--accent); color: var(--accent-ink); }
.btn.accent:hover { background: color-mix(in srgb, var(--accent) 88%, white); }
.btn.solid { background: var(--text); color: var(--canvas); }
.btn.ghost { background: var(--card); color: var(--text); border-color: var(--border-strong); }
.btn.ghost:hover { background: var(--card-hover); border-color: var(--text-dim); }
.btn.quiet { background: transparent; color: var(--text-muted); }
.btn.quiet:hover { background: var(--surface-1); color: var(--text); }
.btn.danger { background: var(--bad-soft); color: var(--bad); border-color: transparent; }
.btn.sm { height: 28px; font-size: 12px; padding: 0 12px; }
.btn.lg { height: 42px; font-size: 14px; padding: 0 22px; }
.btn.block { width: 100%; }
.btn:disabled, .btn.is-disabled { opacity: .42; cursor: not-allowed; transform: none; }
.btn.is-loading { color: transparent; position: relative; pointer-events: none; }
.btn.is-loading::after {
  content: "";
  position: absolute;
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-top-color: transparent;
  color: var(--accent-ink);
  animation: spin 600ms linear infinite;
}

.action-btn {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .04em;
  padding: 5px 11px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-strong);
  background: var(--card);
  color: var(--text);
  cursor: pointer;
  transition: background var(--fast), border-color var(--fast);
}
.action-btn:hover { background: var(--surface-2); }
.action-btn.primary { background: var(--accent); color: var(--accent-ink); border-color: transparent; font-weight: 600; }
.action-btn.done { background: transparent; color: var(--text-dim); border-color: var(--border); cursor: default; }

/* segmented control (1D / 7D / 30D / MTD) */
.segmented {
  display: inline-flex;
  padding: 2px;
  gap: 2px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.segmented button {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 4px 10px;
  border: none;
  background: transparent;
  color: var(--text-dim);
  border-radius: 6px;
  cursor: pointer;
  transition: background var(--fast), color var(--fast);
}
.segmented button:hover { color: var(--text-muted); }
.segmented button[aria-selected="true"] { background: var(--accent); color: var(--accent-ink); font-weight: 600; }

/* tabs */
.tabbar { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; margin-bottom: 16px; }
.tabb {
  padding: 6px 13px;
  border-radius: var(--radius-pill);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  border: 1px solid transparent;
  color: var(--text-muted);
  background: transparent;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  transition: background var(--fast), color var(--fast);
}
.tabb:hover { background: var(--surface-1); color: var(--text); }
.tabb[aria-selected="true"] { background: var(--surface-2); color: var(--text); font-weight: 600; border-color: var(--border); }
.tcount {
  font-family: var(--font-mono);
  font-size: 9px;
  background: var(--surface-2);
  color: var(--text-dim);
  padding: 2px 6px;
  border-radius: var(--radius-pill);
}
.tabb[aria-selected="true"] .tcount { background: var(--accent); color: var(--accent-ink); }
.tab-actions { margin-left: auto; display: flex; gap: 8px; }

/* --- forms --------------------------------------------------------------- */
label {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
  display: block;
  margin-bottom: 6px;
}
.field { margin-bottom: 14px; }
.field .hint { font-size: 11.5px; color: var(--text-dim); margin-top: 6px; }

input, select, textarea {
  width: 100%;
  font-family: var(--font-display);
  font-size: 13.5px;
  height: 36px;
  padding: 0 11px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface-1);
  color: var(--text);
  transition: border-color var(--fast), background var(--fast);
}
textarea { height: auto; min-height: 76px; padding: 10px 11px; resize: vertical; line-height: 1.5; }
input::placeholder, textarea::placeholder { color: var(--text-dim); }
input:hover, select:hover, textarea:hover { border-color: var(--text-dim); }
input:focus-visible, select:focus-visible, textarea:focus-visible { border-color: var(--border-focus); background: var(--surface-2); }
input[type="checkbox"], input[type="radio"] { width: auto; height: auto; accent-color: var(--accent); cursor: pointer; }
input[type="date"] { color-scheme: dark; }
select {
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat: no-repeat;
  background-position: right 9px center;
  background-size: 14px;
  padding-right: 30px;
}
.filterbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; }
.filterbar .search { flex: 1; min-width: 200px; }
.filterbar input[type="date"], .filterbar select { width: auto; min-width: 150px; }

/* --- tables -------------------------------------------------------------- */
.tablewrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 13px; }
thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  text-align: left;
  font-family: var(--font-mono);
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--text-dim);
  font-weight: 400;
  padding: 11px 14px;
  background: var(--card);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
thead th.sortable { cursor: pointer; user-select: none; }
thead th.sortable:hover { color: var(--text-muted); }
thead th[aria-sort] { color: var(--text); }
thead th .arrow { opacity: .5; margin-left: 4px; }
td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--text-muted);
  vertical-align: middle;
}
td.num { text-align: right; }
th.num { text-align: right; }
tbody tr:last-child td { border-bottom: none; }
tbody tr.clickable { cursor: pointer; transition: background var(--fast); }
tbody tr.clickable:hover td { background: var(--surface-1); color: var(--text); }
tbody tr.is-open td { background: var(--surface-1); }
tr.detail td { background: var(--surface-1); padding: 0; }

.mono { font-family: var(--font-mono); font-size: 11.5px; }
.strong { color: var(--text); font-weight: 600; }
.thumb {
  width: 34px; height: 34px;
  border-radius: 8px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  font-family: var(--font-mono);
  font-size: 8.5px;
  color: rgba(255, 255, 255, .8);
  font-weight: 600;
}
/* the drawn stand-in for a product photo, and the frame it sits in */
.pthumb {
  flex: none;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: linear-gradient(180deg, var(--card-hover), var(--card));
  overflow: hidden;
}
.pthumb svg {
  width: 27px;
  height: 27px;
  fill: none;
  stroke: var(--tint, var(--text-muted));
  stroke-width: 1.35;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.pthumb img { width: 100%; height: 100%; object-fit: cover; }
.pthumb.is-lg { width: 64px; height: 64px; border-radius: 13px; }
.pthumb.is-lg svg { width: 46px; height: 46px; stroke-width: 1.2; }
html[data-density="compact"] .prodcell .pthumb:not(.is-lg) { width: 32px; height: 32px; border-radius: 8px; }
html[data-density="compact"] .prodcell .pthumb:not(.is-lg) svg { width: 23px; height: 23px; }

.prodcell { display: flex; align-items: center; gap: 11px; }
.prodcell .pt { color: var(--text); font-weight: 500; }
.prodcell .ps { font-family: var(--font-mono); font-size: 10px; color: var(--text-dim); margin-top: 2px; }
/* the same cell, sized for the top of a form rather than a row in a table */
.prodcell.is-lg { gap: 14px; margin-bottom: 12px; }
.prodhead { display: flex; align-items: center; gap: 15px; }
.prodcell.is-lg .pt { font-size: 15px; font-weight: 600; letter-spacing: -.01em; }
.prodcell.is-lg .ps { font-size: 10.5px; margin-top: 4px; }

.pager { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 14px; flex-wrap: wrap; }
.pager .meta { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-dim); }
.pager .pages { display: flex; gap: 4px; }
.pager .pg {
  min-width: 30px; height: 30px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--text-muted);
  font-size: 12.5px;
  cursor: pointer;
  transition: background var(--fast), color var(--fast);
}
.pager .pg:hover { background: var(--surface-1); color: var(--text); }
.pager .pg[aria-current="page"] { background: var(--accent); color: var(--accent-ink); border-color: transparent; font-weight: 600; }

/* --- activity feed ------------------------------------------------------- */
.feed { display: flex; flex-direction: column; }
.feedrow {
  display: grid;
  grid-template-columns: 62px 14px 1fr;
  gap: 10px;
  align-items: start;
  padding: 11px 18px;
  border-bottom: 1px solid var(--border);
  transition: background var(--fast);
}
.feedrow:hover { background: var(--surface-1); }
.feedrow:last-child { border-bottom: none; }
.feedrow .ftime { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-dim); padding-top: 2px; }
.feedrow .fdot { padding-top: 4px; min-width: 20px; }
.feedrow .fbody { min-width: 0; }
.feedrow .fname { font-family: var(--font-mono); font-size: 11.5px; color: var(--text); }
.feedrow .fmsg { font-size: 12.5px; color: var(--text-muted); }
.feedrow .fmeta { font-family: var(--font-mono); font-size: 10px; color: var(--text-dim); margin-top: 3px; }

/* sparkline bars */
.spark { display: flex; align-items: flex-end; gap: 2px; height: 34px; }
.spark i {
  flex: 1;
  min-width: 2px;
  border-radius: 1px;
  background: var(--good);
  opacity: .55;
  transition: opacity var(--fast);
}
.spark i.hi { opacity: 1; }
.spark.accent i { background: var(--accent); }
.card:hover .spark i { opacity: .8; }
.card:hover .spark i.hi { opacity: 1; }

/* bar chart */
.bars { display: flex; align-items: flex-end; gap: 8px; height: 130px; }
.barcol { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; gap: 8px; align-items: center; }
.barcol .bar {
  width: 100%;
  border-radius: 5px 5px 2px 2px;
  background: linear-gradient(180deg, var(--accent), color-mix(in srgb, var(--accent) 45%, transparent));
  transition: filter var(--fast);
}
.barcol:hover .bar { filter: brightness(1.25); }
.barcol .blabel { font-family: var(--font-mono); font-size: 9.5px; color: var(--text-dim); }

/* progress */
.prog { height: 5px; border-radius: 4px; background: var(--surface-2); overflow: hidden; }
.prog i { display: block; height: 100%; background: var(--accent); border-radius: 4px; transition: width var(--med); }
.prog i.good { background: var(--good); }
.prog i.bad { background: var(--bad); }

/* rail (key/value column) */
.rail { border-left: 1px solid var(--border); padding: 4px 20px; display: flex; flex-direction: column; justify-content: center; }
.rrow { padding: 11px 0; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.rrow:last-child { border-bottom: none; }
.rrow .rl { font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--text-dim); }
.rrow .rv { font-size: 16px; font-weight: 700; letter-spacing: -.02em; }
.linerow { display: flex; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 12.5px; color: var(--text-muted); }
.linerow:last-child { border-bottom: none; }
.linerow b { color: var(--text); font-weight: 600; }

/* --- Shopify connection states ------------------------------------------ */
.connbar {
  --bt: var(--text-muted);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 16px;
  margin-bottom: 20px;
  flex-wrap: wrap;
  border-radius: 17px;
  border: 1px solid color-mix(in srgb, var(--bt) 17%, transparent);
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--bt) 8%, transparent),
      color-mix(in srgb, var(--bt) 2%, transparent)),
    color-mix(in srgb, var(--card) 62%, transparent);
  backdrop-filter: blur(24px) saturate(190%);
  -webkit-backdrop-filter: blur(24px) saturate(190%);
  box-shadow:
    inset 0 1px 0 var(--glass-lip),
    0 1px 2px rgba(0, 0, 0, .22),
    0 10px 26px -16px rgba(0, 0, 0, .7);
}
.connbar .cicon {
  width: 30px; height: 30px;
  border-radius: 50%;
  display: grid; place-items: center;
  flex-shrink: 0;
  color: var(--bt);
  background: color-mix(in srgb, var(--bt) 13%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--bt) 20%, transparent);
}
.connbar .ctext { min-width: 0; flex: 1; }
.connbar .ct { font-size: 13px; font-weight: 600; letter-spacing: -.01em; }
.connbar .cs { font-size: 12.5px; color: var(--text-muted); margin-top: 1px; line-height: 1.45; }
.connbar .cact { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }

.connbar.state-connected { --bt: var(--good); }
.connbar.state-connected .cicon { color: var(--shopify); }
.connbar.state-syncing { --bt: var(--info); }
.connbar.state-syncing .cicon svg { animation: spin 900ms linear infinite; }
.connbar.state-disconnected { --bt: var(--warn); }
.connbar.state-error, .connbar.state-reauth { --bt: var(--bad); }
.connbar.state-scopes { --bt: var(--accent); }

/* scope list, shown before the merchant authorises */
.scopelist { display: flex; flex-direction: column; gap: 1px; }
.scoperow {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
}
.scoperow:last-child { border-bottom: none; }
.scoperow .sk { font-family: var(--font-mono); font-size: 11.5px; color: var(--accent); flex-shrink: 0; min-width: 148px; }
.scoperow .sw { font-size: 12.5px; color: var(--text-muted); line-height: 1.5; }
.scoperow .sw b { color: var(--text); font-weight: 600; }

/* --- empty / skeleton / error states ------------------------------------ */
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 8px;
  padding: 54px 24px;
}
.empty .eicon {
  width: 42px; height: 42px;
  border-radius: 12px;
  background: var(--surface-2);
  color: var(--text-dim);
  display: grid; place-items: center;
  margin-bottom: 6px;
}
.empty h3 { margin: 0; font-size: 15px; font-weight: 600; }
.empty p { margin: 0; font-size: 13px; color: var(--text-muted); max-width: 380px; line-height: 1.55; }
.empty .eact { margin-top: 12px; display: flex; gap: 8px; }

.skel {
  border-radius: 6px;
  background: linear-gradient(90deg, var(--surface-1) 25%, var(--surface-2) 37%, var(--surface-1) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
}
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }
.skel.line { height: 11px; margin-bottom: 8px; }
.skel.num { height: 32px; width: 60%; }
.skel.w-40 { width: 40%; } .skel.w-60 { width: 60%; } .skel.w-80 { width: 80%; }

/* --- command palette ---------------------------------------------------- */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .62);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: none;
  z-index: 100;
  padding: 20px;
}
.overlay.open { display: flex; align-items: center; justify-content: center; animation: fade var(--fast) both; }
.overlay.top.open { align-items: flex-start; padding-top: 12vh; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

.palette {
  width: 100%;
  max-width: 560px;
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-pop);
  overflow: hidden;
  animation: rise var(--med) both;
}
@keyframes rise { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }
.palette input {
  border: none;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  height: 50px;
  font-size: 15px;
  background: transparent;
  padding: 0 18px;
}
.palette input:focus-visible { box-shadow: none; background: transparent; }
.palette .plist { max-height: 340px; overflow-y: auto; padding: 6px; }
.palette .pgroup {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-dim);
  padding: 10px 12px 6px;
}
.palette .pitem {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  color: var(--text-muted);
  cursor: pointer;
}
.palette .pitem svg { width: 15px; height: 15px; opacity: .7; }
.palette .pitem .phint { margin-left: auto; font-family: var(--font-mono); font-size: 10px; color: var(--text-dim); }
.palette .pitem.sel { background: var(--surface-2); color: var(--text); }
.palette .pitem.sel svg { color: var(--accent); opacity: 1; }
.palette .pempty { padding: 26px; text-align: center; font-size: 13px; color: var(--text-dim); }

/* --- modal --------------------------------------------------------------- */
.modal {
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  max-width: 560px;
  width: 100%;
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-pop);
  animation: rise var(--med) both;
}
.modal .mhead { display: flex; align-items: center; gap: 12px; padding: 18px 22px; border-bottom: 1px solid var(--border); }
.modal .mhead h3 { margin: 0; font-size: 16px; font-weight: 650; letter-spacing: -.01em; }
.modal .mbody { padding: 22px; overflow-y: auto; }
.modal .mfoot { padding: 14px 22px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: 9px; }
.mclose { margin-left: auto; }

/* --- toast --------------------------------------------------------------- */
.toaster {
  position: fixed;
  bottom: 22px;
  right: 22px;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-end;
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
  padding: 12px 16px;
  border-radius: 15px;
  font-size: 13px;
  border: 1px solid color-mix(in srgb, var(--text) 12%, transparent);
  background: color-mix(in srgb, var(--surface-1) 76%, transparent);
  backdrop-filter: blur(24px) saturate(190%);
  -webkit-backdrop-filter: blur(24px) saturate(190%);
  box-shadow: inset 0 1px 0 var(--glass-lip), var(--shadow-pop);
  animation: toastin var(--med) both;
  pointer-events: auto;
  max-width: 380px;
}
.toast.out { animation: toastout 180ms var(--ease) both; }
@keyframes toastin { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes toastout { to { opacity: 0; transform: translateY(6px) scale(.98); } }

/* --- reveal on scroll ----------------------------------------------------
   Content is visible by default. Only when the shell has confirmed a working
   observer (html.reveal-on) does it start hidden, so a dead observer can
   never leave the dashboard blank. */
.reveal { transition: opacity 460ms var(--ease), transform 460ms var(--ease); }
html.reveal-on .reveal:not(.in) { opacity: 0; transform: translateY(14px); }

/* --- mobile -------------------------------------------------------------- */
.mobilebar { display: none; }
@media (max-width: 900px) {
  :root { --gutter: 18px; }
  .sidebar {
    position: fixed;
    z-index: 60;
    transform: translateX(-100%);
    transition: transform var(--med);
    box-shadow: var(--shadow-pop);
  }
  .sidebar.open { transform: none; }
  .mobilebar { display: grid; place-items: center; }
  .topbar .searchtrigger { min-width: 0; }
  .topbar .searchtrigger span { display: none; }
}

/* --- light theme override ----------------------------------------------- */
[data-theme="light"] {
  --canvas: #fbfbfd;
  --shell: #f6f6f8;
  --surface-1: #f1f1f4;
  --surface-2: #e9e9ee;
  --card: #ffffff;
  --card-hover: #fafafc;
  --grid: rgba(0, 0, 0, .028);

  --text: #1d1d1f;
  --text-muted: rgba(29, 29, 31, .64);
  --text-dim: rgba(29, 29, 31, .42);

  --border: rgba(0, 0, 0, .09);
  --border-strong: rgba(0, 0, 0, .16);

  --accent: #cf3a29;
  --accent-ink: #ffffff;
  --accent-soft: rgba(207, 58, 41, .10);
  --accent-line: rgba(207, 58, 41, .32);

  --art-ink: #7d1f16;
  --art-op: .085;

  --glass-lip: rgba(255, 255, 255, .85);
  --glass-sheen: rgba(255, 255, 255, .75);
  --glass-rim: rgba(0, 0, 0, .09);
  --glass-fill: rgba(255, 255, 255, .55);
  --glass-fill-hover: rgba(255, 255, 255, .8);
  --glass-base: rgba(0, 0, 0, .05);
  --glass-shadow: 0 10px 26px -20px rgba(18, 18, 24, .5);

  --viz-cell-0: rgba(0, 0, 0, .04);
  --viz-cell-1: rgba(0, 0, 0, .09);
  --viz-cell-2: rgba(0, 0, 0, .16);
  --viz-cell-3: rgba(0, 0, 0, .26);

  --good: #17915a;
  --good-soft: rgba(23, 145, 90, .11);
  --warn: #b57500;
  --warn-soft: rgba(181, 117, 0, .12);
  /* on white the accent red is dark, so danger goes cooler and deeper to
     stay a different signal */
  --bad: #b0203f;
  --bad-soft: rgba(176, 32, 63, .10);
  --info: #3f6ae0;
  --info-soft: rgba(63, 106, 224, .11);

  --shadow-card: 0 1px 2px rgba(0, 0, 0, .04);
  --shadow-pop: 0 1px 2px rgba(0, 0, 0, .06), 0 18px 48px rgba(0, 0, 0, .12);
}
[data-theme="light"] input[type="date"] { color-scheme: light; }
[data-theme="light"] .btn.solid { background: var(--text); color: #fff; }

/* ==========================================================================
   Components used by every screen. Rendered by assets/ui.js.
   ========================================================================== */

/* --- table extras: selection, bulk bar ------------------------------------ */
.cbcell { width: 38px; }
.cbcell input[type="checkbox"] {
  width: 15px; height: 15px;
  accent-color: var(--accent);
  cursor: pointer;
}
.bulkbar {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 14px;
  margin-bottom: 10px;
  border: 1px solid var(--accent-line);
  background: var(--accent-soft);
  border-radius: var(--radius);
  animation: fade var(--fast) both;
}
.bulkbar b { font-size: 12.5px; color: var(--text); margin-right: 4px; }
.bulkbar .btn:last-child { margin-left: auto; }
.pager .pg.is-gap { border: none; background: none; color: var(--text-dim); cursor: default; }

/* --- skeleton rows -------------------------------------------------------- */
/* --- a list filling up ---------------------------------------------------
   Rows land from the right, one after another, and then a pulse runs down
   them for as long as the reading takes. A sweep of light across a grey
   block says something is busy; this says rows are arriving, which is what
   is actually happening.
   ------------------------------------------------------------------------ */
.skelwrap { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }

.skelwrap .skelrow {
  animation: skel-land 420ms cubic-bezier(.2, .8, .2, 1) backwards;
  animation-delay: calc(var(--i, 0) * 65ms);
}
@keyframes skel-land {
  from { opacity: 0; transform: translateX(22px); }
  to { opacity: 1; transform: translateX(0); }
}

/* Then a band of light crosses the block, and each row comes up as it
   passes. One thing moving over the rows rather than every row pulsing on
   its own: a list where all of it throbs at once says nothing about order,
   and rows arrive in an order. */
.skelwrap { position: relative; }

.skelwrap::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 42%;
  pointer-events: none;
  background: linear-gradient(180deg,
    transparent 0,
    var(--accent-soft) 45%,
    var(--accent-soft) 55%,
    transparent 100%);
  animation: skel-sweep 1500ms linear infinite;
}
@keyframes skel-sweep {
  from { transform: translateY(-100%); }
  to { transform: translateY(238%); }
}

.skelwrap .skel.line {
  /* The row itself warms as the band reaches it and cools behind it, which is
     what makes the band look like it is touching the rows rather than
     floating over them. The delay is the band's own arrival time at this row,
     handed down from the markup. */
  animation: skel-pass 1500ms ease-in-out infinite;
  animation-delay: var(--sweep, 0ms);
  background: var(--surface-1);
}
@keyframes skel-pass {
  0%, 100% { background-color: var(--surface-1); }
  12% { background-color: var(--surface-2); }
  22% { background-color: var(--accent-soft); }
  40% { background-color: var(--surface-2); }
}

/* Somebody who asked for less movement gets the rows and no sweep. */
@media (prefers-reduced-motion: reduce) {
  .skelwrap::after { display: none; }
  .skelwrap .skel.line { animation: none; }
  .skelwrap .skelrow { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
  .skelwrap .skelrow, .skelwrap .skel.line { animation: none; opacity: 1; transform: none; }
}
.skelrow {
  display: flex; gap: 18px; align-items: center;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
}
.skelrow:last-child { border-bottom: none; }
.skelrow .skel.line { margin: 0; min-width: 0; }
.empty.is-error .eicon { color: var(--bad); background: var(--bad-soft); }

/* --- banner --------------------------------------------------------------- */
/* A notice is a pane of tinted glass laid on the page: the tone shows in the
   tint and the rim, the top edge catches a highlight, and the type sits on it
   without a coloured slab behind the icon. --bt is the tone's colour and the
   whole thing is mixed from it. */
.banner {
  --bt: var(--text-muted);
  position: relative;
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 14px 16px;
  margin-bottom: 12px;
  border-radius: 19px;
  border: 1px solid var(--glass-rim);
  /* the sheen across the shoulder is what makes it read as glass rather than
     as a tinted box: light catches the top left and falls away */
  background:
    /* the specular: a soft catch of light in the top corner, not a wash */
    radial-gradient(130% 320% at 0% -40%, var(--glass-sheen), transparent 58%),
    color-mix(in srgb, var(--bt) 8%, transparent),
    color-mix(in srgb, var(--surface-2) 92%, transparent);
  backdrop-filter: blur(30px) saturate(200%);
  -webkit-backdrop-filter: blur(30px) saturate(200%);
  box-shadow:
    inset 0 1px 0 var(--glass-lip),
    inset 0 -1px 0 var(--glass-base),
    var(--glass-shadow);
}
.banner .bico {
  width: 30px; height: 30px; flex-shrink: 0;
  border-radius: 50%;
  display: grid; place-items: center;
  color: var(--bt);
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--bt) 26%, transparent),
    color-mix(in srgb, var(--bt) 11%, transparent));
  box-shadow:
    inset 0 1px 0 var(--glass-lip),
    inset 0 0 0 1px color-mix(in srgb, var(--bt) 20%, transparent),
    0 0 14px -6px color-mix(in srgb, var(--bt) 70%, transparent);
}
.banner .btxt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.banner .btxt b { font-size: 13.5px; font-weight: 600; letter-spacing: -.012em; }
.banner .btxt span { font-size: 12.5px; color: var(--text-muted); line-height: 1.45; }
/* a control on glass is glass too, not a solid pill sitting on top of it */
.banner .btn {
  margin-left: auto;
  flex-shrink: 0;
  border-radius: var(--radius-pill);
  border-color: var(--glass-rim);
  background: var(--glass-fill);
  box-shadow: inset 0 1px 0 var(--glass-lip);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.banner .btn:hover { background: var(--glass-fill-hover); border-color: var(--glass-rim); }
.banner .btn.danger { background: color-mix(in srgb, var(--bad) 16%, transparent); }

.banner.tone-warn { --bt: var(--warn); }
.banner.tone-bad { --bt: var(--bad); }
.banner.tone-good { --bt: var(--good); }
.banner.tone-accent { --bt: var(--accent); }
.banner.tone-info { --bt: var(--text-muted); }

/* --- SLA marker ----------------------------------------------------------- */
.sla {
  font-family: var(--font-mono);
  font-size: 10.5px;
  padding: 2px 7px;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  color: var(--text-dim);
  white-space: nowrap;
}
.sla.is-close { background: var(--warn-soft); color: var(--warn); }
.sla.is-late { background: var(--bad-soft); color: var(--bad); }
.sla.is-met { background: var(--good-soft); color: var(--good); }

/* --- modal and drawer ----------------------------------------------------- */
.sheet {
  width: min(560px, calc(100vw - 32px));
  max-height: min(84vh, 860px);
  display: flex; flex-direction: column;
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-pop);
  animation: pop var(--med) both;
}
.sheet.is-wide { width: min(880px, calc(100vw - 32px)); }
.sheethead {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 16px 18px 12px;
  border-bottom: 1px solid var(--border);
}
.sheethead h3 { margin: 0; font-size: 15px; font-weight: 600; }
.sheethead p { margin: 3px 0 0; font-size: 12.5px; color: var(--text-muted); }
.sheethead .iconbtn { margin-left: auto; }
.sheetbody { padding: 16px 18px; overflow-y: auto; }
.sheetbody .ctext { margin: 0 0 4px; font-size: 13px; color: var(--text-muted); line-height: 1.6; }
.sheetfoot {
  display: flex; gap: 8px; justify-content: flex-end;
  padding: 12px 18px;
  border-top: 1px solid var(--border);
  background: var(--shell);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
.overlay.is-side { align-items: stretch; justify-content: flex-end; }
.drawer {
  width: min(520px, 100vw);
  display: flex; flex-direction: column;
  background: var(--surface-1);
  border-left: 1px solid var(--border-strong);
  animation: slidein var(--med) both;
}
.drawerbody { padding: 16px 18px; overflow-y: auto; flex: 1; }
@keyframes slidein { from { transform: translateX(24px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pop { from { transform: scale(.985); opacity: 0; } to { transform: none; opacity: 1; } }

/* --- thread --------------------------------------------------------------- */
.threadwrap { display: flex; flex-direction: column; min-height: 0; }
.msglist { display: flex; flex-direction: column; gap: 10px; overflow-y: auto; max-height: 420px; padding-right: 4px; }
.msgempty { padding: 24px; text-align: center; font-size: 12.5px; color: var(--text-dim); }
.msg {
  display: flex; gap: 10px; align-items: flex-start;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  padding: 10px 12px;
}
.msg .mcol { min-width: 0; flex: 1; }
.msg.is-mine { background: var(--surface-2); border-color: var(--border-strong); }
.msg .mhead { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; flex-wrap: wrap; }
.msg .mhead b { font-size: 12.5px; }
.msg .mrole,
.msg .mchan,
.msg .mtime { font-family: var(--font-mono); font-size: 9.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--text-dim); }
.msg .mchan { color: var(--info); }
.msg .mtime { margin-left: auto; }
.msg .mbody { font-size: 13px; color: var(--text-muted); line-height: 1.55; white-space: pre-wrap; }
.msg .matt { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.msg .att {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-mono); font-size: 10.5px;
  padding: 3px 8px; border-radius: var(--radius-pill);
  background: var(--surface-2); color: var(--text-muted);
}
.msg .att svg { width: 12px; height: 12px; }
.composer { margin-top: 12px; border-top: 1px solid var(--border); padding-top: 12px; }
.composer textarea { width: 100%; resize: vertical; }
.composer .crow { display: flex; gap: 8px; margin-top: 8px; }
.composer .crow .btn:last-child { margin-left: auto; }
/* the top edge tints when the answer is yours to give */
.composer.is-owed { border-top-color: var(--accent-line); box-shadow: inset 0 2px 0 -1px var(--accent-line); }
.composer .cnotice { font-size: 11.5px; color: var(--text-dim); margin-top: 8px; }
.composer .crefslot { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.composer .crefslot .mref { flex: 1; margin-top: 0; }

/* the offer to move this thread to a phone: the same glass as a notice, one
   step quieter, because it is an offer and not an instruction */
.cinvite {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 14px; margin-bottom: 12px;
  border: 1px solid var(--glass-rim); border-radius: 16px;
  background:
    radial-gradient(130% 300% at 0% -50%, var(--glass-sheen), transparent 58%),
    color-mix(in srgb, var(--info) 7%, transparent),
    color-mix(in srgb, var(--surface-2) 90%, transparent);
  backdrop-filter: blur(28px) saturate(190%);
  -webkit-backdrop-filter: blur(28px) saturate(190%);
  box-shadow: inset 0 1px 0 var(--glass-lip), inset 0 -1px 0 var(--glass-base);
}
.cinvite .ciico {
  width: 28px; height: 28px; flex: none; border-radius: 50%;
  display: grid; place-items: center;
  color: var(--info); background: color-mix(in srgb, var(--info) 14%, transparent);
}
.cinvite .citxt { min-width: 0; flex: 1; }
.cinvite .citxt b { display: block; font-size: 13px; font-weight: 600; margin-bottom: 2px; }
.cinvite .citxt span { font-size: 12.5px; color: var(--text-muted); line-height: 1.5; }
.cinvite .ciact { display: flex; align-items: center; gap: 8px; flex: none; }
.composer .csent {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-dim); align-self: center;
}
@media (max-width: 720px) {
  .cinvite { flex-wrap: wrap; }
  .cinvite .ciact { width: 100%; justify-content: flex-end; }
}

/* what a message points at: the object screen, one click away, without the
   conversation moving there */
.mref {
  display: flex; align-items: center; gap: 10px; margin-top: 9px;
  padding: 7px 9px; border-radius: 12px; text-decoration: none; color: inherit;
  border: 1px solid var(--border); background: var(--surface-1);
  transition: border-color var(--fast), background var(--fast);
}
a.mref:hover { border-color: var(--border-strong); background: var(--card-hover); }
.mref .thumb { width: 34px; height: 34px; flex: none; }
.mref .mrl { min-width: 0; display: block; }
.mref .mrl b { display: block; font-size: 12.5px; font-weight: 600; }
.mref .mrl span { font-size: 11px; color: var(--text-dim); }
.mref .mrgo { margin-left: auto; font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim); }

/* what happened to a message after Send */
.msg .mstate { font-family: var(--font-mono); font-size: 9px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim); margin-top: 6px; }
.msg .mstate.is-ok { color: color-mix(in srgb, var(--good) 78%, var(--text)); }

/* both clocks, and what they mean for an answer */
.mclocks {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 11px; margin-bottom: 12px;
  border: 1px solid var(--border); border-radius: 11px;
  background: var(--surface-1);
  font-size: 11.5px; color: var(--text-dim);
}
.mclock { display: inline-flex; align-items: center; gap: 6px; }
.mclock b { font-family: var(--font-mono); font-size: 11.5px; font-weight: 500; color: var(--text-muted); }
.cdot { width: 6px; height: 6px; border-radius: 50%; flex: none; background: var(--text-dim); }
.cdot.on { background: var(--good); box-shadow: 0 0 0 3px var(--good-soft); }
.csep { width: 1px; height: 12px; background: var(--border); }
.cnote { color: var(--text-muted); }

/* the room and who is in it. The line this replaces was a group chat, so the
   header says group rather than person. */
.teamstrip { display: flex; align-items: center; gap: 12px; min-width: 0; }
.teamstrip .avstack { gap: 4px; }
.teamstrip .avstack .avat + .avat { margin-left: 0; }
.teamstrip .tstxt { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.teamstrip .tstxt b { font-size: 14px; font-weight: 600; letter-spacing: -.01em; }
.teamstrip .tstxt span { font-size: 11.5px; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.deskteam { padding: 0 16px 12px; }
.deskteam .teamstrip { padding-top: 2px; }

/* --- the desk ------------------------------------------------------------ */
/* The conversations, on the home screen. The rail is the same glass as the
   notices: a capsule with the light catching its top left, and the selected
   segment lifted out of it on a lozenge of its own. */
.deskhead {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 14px 16px 12px;
}
.deskhead .btn { margin-left: auto; }
.glassrail {
  display: inline-flex; gap: 3px; padding: 3px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--glass-rim);
  background:
    radial-gradient(130% 300% at 0% -60%, var(--glass-sheen), transparent 60%),
    color-mix(in srgb, var(--surface-2) 88%, transparent);
  backdrop-filter: blur(30px) saturate(200%);
  -webkit-backdrop-filter: blur(30px) saturate(200%);
  box-shadow: inset 0 1px 0 var(--glass-lip), inset 0 -1px 0 var(--glass-base);
}
.grpill {
  display: inline-flex; align-items: center; gap: 7px;
  font: inherit; font-size: 12.5px; font-weight: 500;
  color: var(--text-muted); cursor: pointer;
  padding: 6px 14px; border: 1px solid transparent; border-radius: var(--radius-pill);
  background: none;
  transition: color var(--fast), background var(--fast), border-color var(--fast);
}
.grpill:hover { color: var(--text); }
.grpill.is-on {
  color: var(--text);
  border-color: var(--glass-rim);
  background:
    radial-gradient(120% 240% at 0% -40%, var(--glass-sheen), transparent 62%),
    var(--glass-fill);
  box-shadow: inset 0 1px 0 var(--glass-lip), 0 6px 14px -10px #000;
}
.grpill:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
.grcount {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .04em;
  padding: 1px 6px; border-radius: var(--radius-pill);
  background: var(--glass-fill); color: var(--text-dim);
}
.grcount.hot { background: var(--accent); color: var(--accent-ink); }

.deskthread { padding: 0 16px 16px; }
.deskempty { padding: 22px 18px 26px; font-size: 13px; color: var(--text-dim); max-width: 60ch; }
.deskback { display: flex; align-items: center; gap: 10px; padding: 0 16px 12px; }
.deskback .btn:last-child { margin-left: auto; }

.desklist { display: flex; flex-direction: column; border-top: 1px solid var(--border); }
.deskrow {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 12px 16px; border: 0; border-bottom: 1px solid var(--border);
  background: none; color: var(--text); cursor: pointer;
  transition: background var(--fast);
}
.deskrow:last-child { border-bottom: 0; }
.deskrow:hover { background: var(--surface-1); }
.deskrow .thumb { width: 34px; height: 34px; flex: none; }
.deskrow .dtxt { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.deskrow .dtop { display: flex; align-items: baseline; gap: 10px; }
.deskrow .dtop b { font-size: 12.5px; font-weight: 600; }
.deskrow .dwhen { margin-left: auto; font-family: var(--font-mono); font-size: 9.5px; color: var(--text-dim); flex: none; }
.deskrow .dprev { font-size: 12px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.deskrow .dflag {
  flex: none; font-family: var(--font-mono); font-size: 9px; letter-spacing: .12em; text-transform: uppercase;
  padding: 3px 8px; border-radius: var(--radius-pill);
  background: var(--accent); color: var(--accent-ink);
}
@media (max-width: 720px) {
  .deskhead { padding: 12px 12px 10px; }
  .deskhead .btn { margin-left: 0; }
  .glassrail { width: 100%; justify-content: space-between; }
}

/* picking the order a message points at */
.picklist { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; max-height: 300px; overflow-y: auto; }
.pickrow {
  display: grid; grid-template-columns: 96px 1fr auto; gap: 12px; align-items: baseline;
  width: 100%; text-align: left; cursor: pointer;
  padding: 9px 11px; border: 1px solid var(--border); border-radius: 11px;
  background: var(--card); color: var(--text); font: inherit; font-size: 13px;
  transition: border-color var(--fast), background var(--fast);
}
.pickrow:hover { border-color: var(--border-strong); background: var(--card-hover); }
.pickrow .pn { font-size: 11px; color: var(--text-muted); }
.pickrow .pt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pickrow .pm { font-size: 11.5px; color: var(--text-dim); }

/* who owes a reply */
.mowed {
  display: flex; align-items: center; gap: 10px; margin: 2px 0 0;
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
  color: color-mix(in srgb, var(--accent) 82%, var(--text));
}
.mowed i { flex: 1; height: 1px; background: linear-gradient(90deg, var(--accent-line), transparent); }
.mowed i:first-child { background: linear-gradient(270deg, var(--accent-line), transparent); }

/* --- uploader ------------------------------------------------------------- */
/* a file the warehouse sent, shown as a file */
.filechips { display: flex; flex-wrap: wrap; gap: 6px; }
.filechip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px 4px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--card-hover);
  font-size: 11.5px;
  color: var(--text-muted);
}
.filechip svg { color: var(--text-dim); flex: none; }

/* Not found sits at the end of the label line, in the quietest grey the
   interface has, because it is an escape hatch and not an invitation. */
.fieldwrap { position: relative; }
.fieldwrap.is-file { grid-column: 1 / -1; }
.nfbtn {
  position: absolute;
  top: 0;
  right: 0;
  padding: 0 2px;
  border: 0;
  background: none;
  font: inherit;
  font-size: 10.5px;
  line-height: 1.5;
  color: var(--text-dim);
  cursor: pointer;
  opacity: .7;
  transition: color var(--fast), opacity var(--fast);
}
.nfbtn:hover { color: var(--text-muted); opacity: 1; }
.nfbtn:focus-visible { outline: 1px solid var(--border-strong); outline-offset: 2px; border-radius: 4px; }
.fieldwrap.is-nf .nfbtn { color: var(--text-muted); opacity: 1; }
.fieldwrap.is-nf input,
.fieldwrap.is-nf .uploader { opacity: .4; pointer-events: none; }
.fieldwrap.is-nf .field > label::after {
  content: " · not found";
  color: var(--text-dim);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
}

/* a file field in a form: the label above, the drop zone under it, and it
   takes the full width of the grid rather than half a column */
.field.is-file { grid-column: 1 / -1; }
.field.is-file > label { display: block; margin-bottom: 6px; }
.field.is-file .uploader { padding: 12px; }
.field.is-file .filelist { margin-top: 8px; }

.uploader {
  display: flex; align-items: center; gap: 12px;
  padding: 14px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  background: var(--card);
  cursor: pointer;
  transition: border-color var(--fast), background var(--fast);
}
.uploader:hover, .uploader.is-over { border-color: var(--accent-line); background: var(--accent-soft); }
.uploader .uico { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; background: var(--surface-2); color: var(--text-muted); }
.uploader .utxt { display: flex; flex-direction: column; gap: 2px; }
.uploader .utxt b { font-size: 13px; }
.uploader .utxt span { font-size: 12px; color: var(--text-dim); }
.filelist { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.filerow {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--card);
}
.filerow .fname { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-muted); }
.filerow .iconbtn { margin-left: auto; width: 24px; height: 24px; }

/* --- switch --------------------------------------------------------------- */
.switch { display: flex; align-items: flex-start; gap: 11px; cursor: pointer; padding: 9px 0; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .track {
  width: 38px; height: 22px; flex-shrink: 0;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  border: 1px solid var(--border);
  position: relative;
  transition: background var(--fast), border-color var(--fast);
}
.switch .track::after {
  content: '';
  position: absolute; top: 2px; left: 2px;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--text-dim);
  transition: transform var(--fast), background var(--fast);
}
.switch input:checked + .track { background: var(--accent-soft); border-color: var(--accent-line); }
.switch input:checked + .track::after { transform: translateX(16px); background: var(--accent); }
.switch input:focus-visible + .track { box-shadow: var(--ring); }
.switch .slabel { display: flex; flex-direction: column; gap: 2px; }
.switch .slabel b { font-size: 13px; font-weight: 500; }
.switch .slabel span { font-size: 12px; color: var(--text-dim); line-height: 1.5; }

.is-plus { color: var(--good); }

.checklist { display: flex; flex-direction: column; gap: 6px; }
.checklist .pick { align-items: center; }
.notebox {
  margin-top: 10px;
  padding: 9px 11px;
  border-left: 2px solid var(--warn);
  background: var(--warn-soft);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: 12.5px;
  color: var(--text-muted);
}
.pkgcard .linerow { font-size: 12.5px; }

/* --- impersonation bar ---------------------------------------------------- */
.imperbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 60;
  display: flex; align-items: center; gap: 14px;
  padding: 10px 18px;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 12.5px;
  box-shadow: 0 -8px 24px rgba(0, 0, 0, .4);
}
.imperbar .imico { display: inline-flex; align-items: center; }
.imperbar .imtxt { line-height: 1.4; }
.imperbar svg { width: 14px; height: 14px; }
.imperbar b { font-weight: 700; }
.imperbar .btn { margin-left: auto; background: var(--accent-ink); color: var(--text); border-color: transparent; }
body.has-imper .content { padding-bottom: 70px; }

/* --- settings ------------------------------------------------------------- */
.storerow {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  grid-template-areas: "ico txt badge" ". rail rail";
  gap: 10px 12px;
  align-items: center;
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
}
.storerow:last-of-type { border-bottom: none; }
.storerow .sg {
  grid-area: ico;
  width: 30px; height: 30px;
  border-radius: 9px;
  display: grid; place-items: center;
}
.storerow .stxt { grid-area: txt; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.storerow .stxt b { font-size: 13.5px; }
.storerow .stxt span { font-size: 10.5px; color: var(--text-dim); }
.storerow .badge { grid-area: badge; }
.storerow .srail { grid-area: rail; display: flex; gap: 20px; align-items: center; flex-wrap: wrap; }
.storerow .srail .field { max-width: 150px; }
.pick.is-soon { opacity: .55; }
.codebox {
  margin: 12px 0;
  padding: 14px;
  border: 1px dashed var(--accent-line);
  border-radius: var(--radius);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 18px;
  letter-spacing: .12em;
  text-align: center;
}

.lastmile {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent);
  background: var(--accent-soft);
  padding: 1px 5px; border-radius: var(--radius-pill);
}

/* --- parcel block --------------------------------------------------------- */
.parcel { padding: 12px 16px; border-bottom: 1px solid var(--border); }
.parcel:last-child { border-bottom: none; }
.parcel .prow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.parcel .prow b { font-size: 13px; }
.parcel .pmeta { margin-left: auto; font-family: var(--font-mono); font-size: 10.5px; color: var(--text-dim); }
.parcel .legs .leg:first-child { border-top: none; }

.flag { font-size: 15px; line-height: 1; margin-right: 2px; }

/* --- merchant pill -------------------------------------------------------- */
.mpill { display: inline-flex; align-items: baseline; gap: 7px; min-width: 0; }
.mpill b { font-weight: 500; color: var(--text); }
.mpill .mno {
  font-size: 9.5px;
  letter-spacing: .06em;
  color: var(--text-dim);
  background: var(--surface-2);
  padding: 1px 6px;
  border-radius: var(--radius-pill);
  flex-shrink: 0;
}
.mpill.is-block { flex-direction: column; align-items: flex-start; gap: 3px; }

/* --- category cards ------------------------------------------------------- */
.catcard { transition: border-color var(--fast), background var(--fast); }
.catcard.is-on { border-color: var(--accent-line); }
.catcard .switch { gap: 0; }
.fieldchips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 10px; }
.fchip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 6px 3px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--card);
  font-size: 11.5px;
  color: var(--text-muted);
}
.fchip.is-base { color: var(--text-dim); border-style: dashed; }
.fchip button {
  border: none; background: none; cursor: pointer;
  color: var(--text-dim); font-size: 13px; line-height: 1;
  padding: 0 2px; border-radius: 50%;
}
.fchip button:hover { color: var(--bad); background: var(--bad-soft); }
.catcard:not(.is-on) .fchip { opacity: .55; }
.chip.is-pick { cursor: pointer; border-color: var(--border-strong); }
.chip.is-pick:hover { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent); }

/* --- carrier chain -------------------------------------------------------- */
.legs { display: flex; flex-direction: column; gap: 1px; margin-top: 6px; }
.leg {
  display: grid;
  grid-template-columns: 74px 130px 150px minmax(0, 1fr);
  gap: 10px;
  align-items: baseline;
  padding: 7px 0;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
}
.leg .lrole {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-dim);
}
.leg.is-last .lrole { color: var(--accent); }
.leg .lname { font-weight: 500; }
.leg .lno { font-size: 11.5px; color: var(--text-muted); }
.leg .lwhen { color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.leg.is-pending .lname, .leg.is-pending .lno { font-style: normal; }
@media (max-width: 760px) {
  .leg { grid-template-columns: 1fr; gap: 2px; padding: 9px 0; }
}

/* --- inbox ---------------------------------------------------------------- */
.inboxgrid { display: grid; grid-template-columns: 340px minmax(0, 1fr); gap: 14px; align-items: start; }
.thlist { display: flex; flex-direction: column; max-height: 640px; overflow-y: auto; }
.throw {
  display: flex; gap: 10px; align-items: flex-start;
  width: 100%;
  padding: 12px 14px;
  border: none;
  border-bottom: 1px solid var(--border);
  background: none;
  color: var(--text);
  text-align: left;
  cursor: pointer;
  transition: background var(--fast);
}
.throw:hover { background: var(--surface-1); }
.throw.is-active { background: var(--surface-2); }
.throw.is-active::before {
  content: ''; position: absolute; left: 0; width: 2px; height: 34px; background: var(--accent);
}
.throw > .avat { margin-top: 1px; }
.throw.is-unread > .avat { box-shadow: 0 0 0 1px var(--accent-line); }
.throw .ttxt { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.throw .ttop { display: flex; align-items: baseline; gap: 8px; }
.throw .ttop b { font-size: 12.5px; }
.throw .tmer { font-size: 11.5px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.throw .ttime { margin-left: auto; font-family: var(--font-mono); font-size: 9.5px; color: var(--text-dim); flex-shrink: 0; }
.throw .tprev { font-size: 12px; color: var(--text-dim); line-height: 1.45; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.throw.is-unread .tprev { color: var(--text-muted); }
@media (max-width: 900px) { .inboxgrid { grid-template-columns: 1fr; } }

/* --- dispute cards -------------------------------------------------------- */
.dcard { cursor: pointer; transition: border-color var(--fast), background var(--fast); }
.dcard:hover { border-color: var(--border-strong); background: var(--card-hover); }
.drow { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 20px; }
.dmain .dtext { margin: 8px 0; font-size: 13px; color: var(--text-muted); line-height: 1.55; }
.dside { border-left: 1px solid var(--border); padding-left: 18px; }
.evgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin: 8px 0; }
.ev {
  display: flex; align-items: center; gap: 8px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--card);
  font-size: 11px;
}
.ev svg { color: var(--text-dim); flex-shrink: 0; }
/* A tile that opens the photo is a button, and has to feel like one. */
button.ev {
  width: 100%; text-align: left; color: inherit;
  font-family: inherit; font-size: 11px; cursor: pointer;
  transition: border-color var(--fast), background var(--fast);
}
button.ev:hover { border-color: var(--border-strong); background: var(--card-hover); }
@media (max-width: 900px) {
  .drow { grid-template-columns: 1fr; }
  .dside { border-left: none; border-top: 1px solid var(--border); padding: 12px 0 0; }
}
.proofbox {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 28px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  background: var(--card);
  margin-bottom: 14px;
  text-align: center;
}
.proofbox svg { color: var(--text-dim); }
.proofbox b { font-family: var(--font-mono); font-size: 12px; }
.proofbox span { font-size: 11.5px; color: var(--text-dim); }

/* --- upload row ----------------------------------------------------------- */
.uploadrow { margin-bottom: 12px; }
.uploadrow input[type="file"] {
  width: 100%;
  padding: 10px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--text-muted);
  font-size: 12.5px;
}
.uploadrow input[type="file"]::file-selector-button {
  margin-right: 12px;
  padding: 6px 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}

/* --- console bits --------------------------------------------------------- */
.metric { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 6px; font-size: 12.5px; color: var(--text-muted); }
.metric b { font-size: 15px; color: var(--text); }
.qhead {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  margin-bottom: 12px;
}
.qhead .eyebrow { margin: 0 0 3px; }
.qhead b { font-size: 13px; }
.shiptable input { height: 30px; padding: 0 8px; text-align: right; max-width: 120px; }
.cellwrap { position: relative; display: inline-block; }
.cellwrap input.is-sel { border-color: var(--accent-line); background: var(--accent-soft); }
.cellwrap input.is-filled { animation: fillflash 500ms var(--ease); }
@keyframes fillflash {
  from { background: var(--accent-soft); border-color: var(--accent); }
  to { background: var(--surface-1); border-color: var(--border); }
}
.fillgrip {
  position: absolute;
  right: -3px; bottom: -3px;
  width: 8px; height: 8px;
  border-radius: 2px;
  background: var(--accent);
  opacity: 0;
  cursor: crosshair;
  transition: opacity var(--fast);
}
.cellwrap:hover .fillgrip,
.cellwrap:focus-within .fillgrip { opacity: 1; }
.shiptable td { padding: 6px 10px; }
@media (max-width: 720px) { .qhead { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* --- definition list for product details ---------------------------------- */
.deflist { display: flex; flex-direction: column; }
.defrow {
  display: grid; grid-template-columns: 190px minmax(0, 1fr);
  gap: 14px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--border);
  font-size: 12.5px;
}
.defrow:last-child { border-bottom: none; }
.defrow .dt { font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim); padding-top: 2px; }
.defrow .dd { color: var(--text); line-height: 1.55; }
@media (max-width: 720px) { .defrow { grid-template-columns: 1fr; gap: 4px; } }

.addr { font-size: 13px; color: var(--text-muted); line-height: 1.65; margin: 6px 0 12px; }
.crumb a:hover { color: var(--accent); }

/* --- attention list ------------------------------------------------------- */
.attlist { display: flex; flex-direction: column; }
.attrow {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 13px 16px;
  border: none;
  border-bottom: 1px solid var(--border);
  background: none;
  color: var(--text);
  text-align: left;
  cursor: pointer;
  transition: background var(--fast);
}
.attrow:last-child { border-bottom: none; }
.attrow:hover { background: var(--surface-1); }
.attrow .aico {
  width: 30px; height: 30px; flex-shrink: 0;
  border-radius: 9px;
  display: grid; place-items: center;
  background: var(--warn-soft); color: var(--warn);
}
.attrow .atxt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.attrow .atxt b { font-size: 13px; font-weight: 500; }
.attrow .atxt span { font-size: 12px; color: var(--text-dim); }
.attrow .acount {
  margin-left: auto;
  font-family: var(--font-mono); font-size: 12px; font-weight: 600;
  color: var(--text);
  background: var(--surface-2);
  padding: 3px 9px;
  border-radius: var(--radius-pill);
}
.attrow svg:last-child { width: 14px; height: 14px; color: var(--text-dim); flex-shrink: 0; }

.bigmoney {
  font-size: 30px; font-weight: 700; letter-spacing: -.03em;
  margin: 4px 0 12px;
}
.bigmoney.is-bad { color: var(--bad); }
.btn.block { width: 100%; }

/* --- flow bits: mini order list, pick grids, comparison -------------------- */
.ordermini { display: flex; flex-direction: column; margin-bottom: 12px; }
.omrow {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  font-size: 12.5px;
}
.omrow:last-child { border-bottom: none; }
.omrow .muted { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.omrow b { margin-left: auto; color: var(--text); }
.omrow.dim { color: var(--text-dim); }
.linerow b.is-short { color: var(--bad); }

/* A line that does not match is the one worth looking at, so it is the only
   one that carries any colour. The rest of the comparison stays quiet. */
tr.is-off td { background: var(--bad-soft); }
td.is-short, .num.is-short { color: var(--bad); }

/* A chip that opens the file is a button, and has to say so. */
button.filechip { cursor: pointer; font-family: inherit; }
button.filechip:hover { border-color: var(--border-strong); color: var(--text); }

/* what was quoted next to what was measured */
.qctable td { vertical-align: middle; }
.qctable input[type="text"] {
  width: 100%;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--card);
  color: var(--text);
  font: inherit;
  font-size: 12.5px;
}
.qctable input[type="text"]:focus { outline: none; border-color: var(--border-focus); }

/* the ladder as the merchant reads it: a step per quantity */
.tierrow { display: flex; gap: 8px; flex-wrap: wrap; }
.tiercell {
  display: flex; align-items: baseline; gap: 7px;
  padding: 9px 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--card-hover);
}
.tiercell .tq { font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim); }
.tiercell b { font-size: 14px; }
.tiercell .tu { font-size: 11px; color: var(--text-dim); }

/* the volume ladder, three short steps side by side */
.tiergrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 640px) { .tiergrid { grid-template-columns: 1fr; } }

/* --- who is waiting, per merchant ------------------------------------------ */
/* The console works for several merchants at once, so the inbox says up front
   how many messages each of them is still waiting on an answer to. */
.mstrip { display: flex; gap: 7px; flex-wrap: wrap; margin-bottom: 12px; }
.mchip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 10px 7px 13px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--text-muted);
  font: inherit; font-size: 12.5px; cursor: pointer;
  transition: color var(--fast), border-color var(--fast), background var(--fast);
}
.mchip:hover { color: var(--text); border-color: var(--border-strong); }
.mchip.is-on { color: var(--text); border-color: var(--border-strong); background: var(--card-hover); }
.mchip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.mcount {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em;
  padding: 2px 7px; border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--text) 8%, transparent);
  color: var(--text-dim);
}
.mcount.hot { background: var(--accent); color: #fff; letter-spacing: .02em; }

/* the same count on the thread it belongs to */
.tmiss {
  font-family: var(--font-mono); font-size: 9.5px;
  min-width: 16px; text-align: center;
  padding: 1px 5px; border-radius: var(--radius-pill);
  background: var(--accent); color: #fff;
}

/* --- waiting on a reply ---------------------------------------------------- */
/* Not a banner: a banner tells you something, this hands you the four people
   who are waiting and how long they have been. */
.pingbar {
  padding: 14px 16px 16px;
  margin-bottom: 20px;
  border-radius: 19px;
  border: 1px solid color-mix(in srgb, var(--accent) 24%, transparent);
  background:
    radial-gradient(130% 320% at 0% -40%, var(--glass-sheen), transparent 58%),
    color-mix(in srgb, var(--accent) 9%, transparent),
    color-mix(in srgb, var(--surface-2) 92%, transparent);
  backdrop-filter: blur(30px) saturate(200%);
  -webkit-backdrop-filter: blur(30px) saturate(200%);
  box-shadow: inset 0 1px 0 var(--glass-lip), inset 0 -1px 0 var(--glass-base), var(--glass-shadow);
}
.pinghead { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; }
.pinghead b { font-size: 13.5px; letter-spacing: -.012em; }
.pinghead .hint { margin: 0; }
.pinghead .btn { margin-left: auto; }
.pingdot {
  width: 9px; height: 9px; border-radius: 50%; flex: none;
  background: var(--accent);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 60%, transparent);
  animation: ping 2s var(--ease) infinite;
}
@keyframes ping {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent); }
  70% { box-shadow: 0 0 0 9px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
.pingrow { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 8px; margin-top: 12px; }
.pingcard {
  display: flex; flex-direction: column; gap: 3px;
  padding: 11px 13px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: color-mix(in srgb, var(--text) 3%, transparent);
  color: var(--text);
  font: inherit; text-align: left; cursor: pointer;
  min-width: 0;
  transition: background var(--fast), border-color var(--fast), transform var(--fast);
}
.pingcard:hover { background: color-mix(in srgb, var(--text) 6%, transparent); border-color: var(--border-strong); transform: translateY(-2px); }
.pingcard:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.pctop { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; font-weight: 600; }
.pcage { margin-left: auto; font-family: var(--font-mono); font-size: 9.5px; color: var(--accent); white-space: nowrap; }
.pcbody { font-size: 12px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pckind { font-family: var(--font-mono); font-size: 9px; letter-spacing: .11em; text-transform: uppercase; color: var(--text-dim); }
@media (prefers-reduced-motion: reduce) { .pingdot { animation: none; } }
@media (max-width: 900px) { .pingrow { grid-template-columns: 1fr; } }

/* --- the fulfil sheet ------------------------------------------------------ */
/* What it costs and what it leaves, said once, before any of the detail. */
.payhead {
  padding: 16px 16px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--card-hover), var(--card));
  margin-bottom: 12px;
}
.payhead .ph-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.payhead .ph-num { font-size: 30px; font-weight: 600; letter-spacing: -.035em; line-height: 1.1; margin-top: 6px; }
.payhead .ph-count {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-dim); padding: 4px 10px; border: 1px solid var(--border); border-radius: var(--radius-pill);
}
.paybar { display: flex; height: 10px; margin-top: 16px; border-radius: 6px; overflow: hidden; background: var(--surface-1); }
.paybar > div { min-width: 3px; }
.pb-spent { background: linear-gradient(180deg, var(--accent), color-mix(in srgb, var(--accent) 70%, #000)); }
.pb-left { background: color-mix(in srgb, var(--good) 42%, transparent); }
.pb-missing {
  background:
    repeating-linear-gradient(135deg, color-mix(in srgb, var(--bad) 55%, transparent) 0 2px, transparent 2px 7px),
    color-mix(in srgb, var(--bad) 14%, transparent);
}
.pb-legend { display: flex; gap: 18px; flex-wrap: wrap; margin-top: 11px; font-size: 12px; color: var(--text-muted); }
.pb-legend span { display: flex; align-items: center; gap: 7px; }
.pb-legend i { width: 9px; height: 9px; border-radius: 3px; display: block; }
.pb-legend i.spent { background: var(--accent); }
.pb-legend i.left { background: color-mix(in srgb, var(--good) 42%, transparent); }
.pb-legend i.missing { background: color-mix(in srgb, var(--bad) 55%, transparent); }

/* the split of the charge, kept apart from the list it came from */
.receipt { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.receipt > div {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 10px 14px;
  font-size: 13px;
  border-bottom: 1px solid var(--border);
}
.receipt > div:last-child { border-bottom: 0; }
.receipt span { color: var(--text-muted); }
.receipt b { font-variant-numeric: tabular-nums; }
.receipt .is-total { background: color-mix(in srgb, var(--text) 3%, transparent); }
.receipt .is-total span { color: var(--text); font-weight: 500; }
.receipt .is-total b { font-size: 15px; }

/* every order that is about to leave, with the thing itself beside it */
/* a list longer than the sheet scrolls, and says so by fading out */
.ordwrap { position: relative; }
.ordwrap.is-more::after {
  content: ""; position: absolute; left: 1px; right: 1px; bottom: 1px; height: 42px;
  border-radius: 0 0 var(--radius) var(--radius);
  background: linear-gradient(180deg, transparent, var(--surface-1));
  pointer-events: none;
}
.ordlist { max-height: 236px; overflow: auto; border: 1px solid var(--border); border-radius: var(--radius); }
.ordrow {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
}
.ordrow:last-child { border-bottom: 0; }
.ordrow .or-txt { min-width: 0; flex: 1; }
.ordrow .or-who { font-size: 13px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ordrow .or-meta { font-size: 11px; color: var(--text-dim); margin-top: 1px; }
.ordrow .or-amt { font-variant-numeric: tabular-nums; font-size: 13px; }
.ordlist .pthumb { width: 30px; height: 30px; border-radius: 8px; }
.ordlist .pthumb svg { width: 21px; height: 21px; }

/* Two states of one product, side by side. The card stays neutral: the amber
   belongs on the field that moved, not on the whole thing. */
.cmprow {
  padding: 12px 13px 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--card-hover), var(--card));
  margin-bottom: 8px;
}
.cmprow .cmphead { display: flex; align-items: center; gap: 11px; }
.cmprow .cmptitle { font-size: 13px; font-weight: 600; }
.cmprow .cmpsub { font-family: var(--font-mono); font-size: 10px; color: var(--text-dim); letter-spacing: .08em; margin-top: 2px; }
.cmprow .cmphead .vpill { margin-left: auto; }
.cmprow .cmpcols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 28px minmax(0, 1fr);
  align-items: center;
  gap: 0;
  margin-top: 11px;
}
.cmprow .cmpside {
  display: flex; flex-direction: column; gap: 2px;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--text) 3%, transparent);
  min-width: 0;
}
.cmprow .cmpside.is-now {
  border-color: color-mix(in srgb, var(--warn) 30%, transparent);
  background: color-mix(in srgb, var(--warn) 7%, transparent);
}
.cmprow .cmpside .dim { font-family: var(--font-mono); font-size: 9px; letter-spacing: .11em; text-transform: uppercase; }
.cmprow .cmpside b { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; }
.cmprow .cmpside.is-now b { color: var(--warn); }
/* the arrow is drawn rather than typed, so it lines up with the two panes */
.cmprow .cmparrow { position: relative; height: 1px; background: var(--border-strong); }
.cmprow .cmparrow::after {
  content: ""; position: absolute; right: 0; top: -3px;
  width: 6px; height: 6px;
  border-top: 1px solid var(--border-strong);
  border-right: 1px solid var(--border-strong);
  transform: rotate(45deg);
}
@media (max-width: 640px) {
  .cmprow .cmpcols { grid-template-columns: 1fr; gap: 8px; }
  .cmprow .cmparrow { display: none; }
}

.pickgrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.pickgrid.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.pick {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 9px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--card);
  font-size: 12.5px;
  cursor: pointer;
  transition: border-color var(--fast), background var(--fast);
}
.pick:hover { border-color: var(--border-strong); }
.pick.is-on { border-color: var(--accent-line); background: var(--accent-soft); }
/* Picking a country is not an action, it is an answer, and red is the colour
   this product spends on the one thing worth doing something about. Green
   says chosen without asking to be looked at, and the ones left grey stay
   plainly unchosen rather than merely quieter. */
.pickgrid.is-choice .pick.is-on {
  border-color: var(--picked-line);
  background: var(--picked-soft);
}
.pickgrid.is-choice .pick.is-on input { accent-color: var(--picked); }
.pick input { accent-color: var(--accent); margin-top: 1px; }
.pick span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pick b { font-weight: 600; }
.pick em { font-style: normal; font-size: 11.5px; color: var(--text-dim); line-height: 1.45; }
.chiprow { display: flex; gap: 6px; flex-wrap: wrap; }
.cmpgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
@media (max-width: 720px) {
  .pickgrid, .pickgrid.two, .cmpgrid { grid-template-columns: 1fr; }
}


/* a parcel's line sits between its header and its carriers */
.parcel .prail { margin: 14px 2px 16px; }

/* --- instruments ---------------------------------------------------------- */
/* Charts share one ink: the series is drawn in the text colour at low opacity
   and red is kept for the one mark that is worth looking at. */
.viz-spark, .viz-area { color: var(--text); }
/* The hard guarantee, whatever the numbers turn out to be. An instrument
   drawing outside its own box is the one failure that makes a whole screen
   look broken, and no amount of care about scales is a substitute for the
   box actually holding. */
.viz-spark, .viz-area, .viz-dial { overflow: hidden; }
.vline { stroke: color-mix(in srgb, currentColor 72%, transparent); }
.vline.is-accent { stroke: var(--accent); }
.vdot { fill: currentColor; }
.vdot.is-faint { fill: color-mix(in srgb, currentColor 34%, transparent); }
.vdot.is-accent { fill: var(--accent); }
.vdot.is-peak { fill: var(--text); stroke: var(--accent); stroke-width: 1.5; }
.vring { fill: none; stroke: color-mix(in srgb, var(--accent) 48%, transparent); stroke-width: 1; }
.vhatch { stroke: color-mix(in srgb, currentColor 16%, transparent); }
.vgrid { stroke: color-mix(in srgb, currentColor 7%, transparent); stroke-width: 1; }
.vaxis { fill: var(--text-dim); font-size: 10.5px; font-family: var(--font-display); }

/* figure with its own shape behind it */
.viz-tile {
  display: flex; flex-direction: column;
  padding: 16px 16px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--card-hover), var(--card));
}
.viz-tile.is-link { cursor: pointer; transition: border-color var(--fast), background var(--fast); }
.viz-tile.is-link:hover { border-color: var(--border-strong); }

.vt-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.vt-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: .13em; text-transform: uppercase; color: var(--text-dim); }
.vt-num { font-size: 30px; font-weight: 600; letter-spacing: -.035em; line-height: 1.08; margin-top: 10px; }
.vt-unit { font-size: 14px; font-weight: 400; color: var(--text-muted); letter-spacing: 0; margin-left: 5px; }
.vt-spark { margin-top: 12px; }
.vt-foot { display: flex; justify-content: space-between; gap: 10px; margin-top: 10px; font-size: 11.5px; color: var(--text-muted); }
.vt-foot span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vt-foot span:last-child { color: var(--text-dim); flex: none; }
.vt-num { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vpill {
  font-size: 10.5px; font-weight: 600; padding: 2px 8px; border-radius: var(--radius-pill);
  border: 1px solid color-mix(in srgb, var(--vc, var(--text-muted)) 24%, transparent);
  background: color-mix(in srgb, var(--vc, var(--text-muted)) 12%, transparent);
  color: var(--vc, var(--text-muted));
  white-space: nowrap;
}
.vpill.up { --vc: var(--good); }
.vpill.down { --vc: var(--bad); }
.vpill.warn { --vc: var(--warn); }
.vpill.hot { --vc: var(--accent); }

/* period chart */
.viz-plot { position: relative; }
.viz-note {
  position: absolute;
  display: flex; flex-direction: column; gap: 1px;
  padding: 8px 11px;
  border-radius: 13px;
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  background: color-mix(in srgb, var(--card) 74%, transparent);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  box-shadow: inset 0 1px 0 var(--glass-lip), 0 10px 26px -16px #000;
  pointer-events: none;
}
.viz-note b { font-size: 14.5px; font-weight: 600; letter-spacing: -.02em; }
.viz-note span { font-size: 10.5px; color: var(--text-dim); }

/* pipeline */
.viz-flow { display: flex; gap: 4px; }
.viz-step {
  display: flex; flex-direction: column; gap: 2px;
  position: relative; min-width: 0;
  padding: 13px 13px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--text);
  font: inherit; text-align: left; cursor: pointer;
  transition: background var(--fast), border-color var(--fast), transform var(--fast);
}
.viz-step:disabled { cursor: default; }
.viz-step:not(:disabled):hover { background: var(--card-hover); border-color: var(--border-strong); transform: translateY(-2px); }
.viz-step:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.viz-step::before {
  content: ""; position: absolute; left: 13px; right: 13px; top: 0; height: 2px;
  border-radius: 2px; background: color-mix(in srgb, var(--text) 16%, transparent);
}
.viz-step .vs-n { font-size: 21px; font-weight: 600; letter-spacing: -.03em; }
.viz-step .vs-l { font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .09em; text-transform: uppercase; color: var(--text-dim); line-height: 1.3; }
.viz-step .vs-v { font-size: 11px; color: var(--text-dim); margin-top: 3px; }
.viz-step.tone-bad { background: color-mix(in srgb, var(--accent) 9%, var(--card)); border-color: color-mix(in srgb, var(--accent) 26%, transparent); }
.viz-step.tone-bad::before { background: var(--accent); }
.viz-step.tone-warn::before { background: var(--warn); }
.viz-step.tone-good::before { background: var(--good); }
.viz-step.is-active { border-color: var(--accent); }

/* runway */
.viz-runway { display: flex; height: 24px; border-radius: 8px; overflow: hidden; border: 1px solid var(--border); }
.vr-fill { background: linear-gradient(180deg, color-mix(in srgb, var(--good) 62%, transparent), color-mix(in srgb, var(--good) 34%, transparent)); }
.vr-short {
  background:
    repeating-linear-gradient(135deg, color-mix(in srgb, var(--accent) 52%, transparent) 0 2px, transparent 2px 7px),
    color-mix(in srgb, var(--accent) 12%, transparent);
}
.viz-legend { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 11px; font-size: 12px; color: var(--text-muted); }
.viz-legend span { display: flex; align-items: center; gap: 7px; }
.viz-legend i { width: 9px; height: 9px; border-radius: 3px; display: block; }
.viz-legend i.ok { background: color-mix(in srgb, var(--good) 62%, transparent); }
.viz-legend i.bad { background: color-mix(in srgb, var(--accent) 55%, transparent); }

/* dial */
.viz-dial { width: 100%; max-width: 220px; margin: 0 auto; display: block; }
.viz-dial .vtrack { stroke: color-mix(in srgb, var(--text) 8%, transparent); }
.viz-dial .vglow { stroke: color-mix(in srgb, var(--accent) 20%, transparent); }
.viz-dial .varc { stroke: var(--accent); }
.viz-dial .vd-num { fill: var(--text); font-size: 34px; font-weight: 600; font-family: var(--font-display); letter-spacing: -1.2px; }
.viz-dial .vd-cap { fill: var(--text-dim); font-size: 9.5px; font-family: var(--font-display); letter-spacing: 1.3px; }
.vd-foot { text-align: center; font-size: 12px; color: var(--text-muted); margin-top: 2px; }

/* stall ladder */
.viz-ladder { display: flex; align-items: flex-end; gap: 5px; height: 112px; }
.vl-col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: 6px; height: 100%; }
.vl-bar { width: 100%; border-radius: 4px 4px 2px 2px; background: color-mix(in srgb, var(--text) 14%, transparent); animation: vrise .7s var(--ease) both; }
.vl-col.p1 .vl-bar { background: color-mix(in srgb, var(--warn) 55%, transparent); }
.vl-col.p2 .vl-bar { background: color-mix(in srgb, var(--warn) 85%, transparent); }
.vl-col.p3 .vl-bar { background: var(--accent); }
.vl-d { font-family: var(--font-mono); font-size: 9.5px; color: var(--text-dim); }
@keyframes vrise { from { transform: scaleY(0); transform-origin: bottom; } }
.viz-marks { display: flex; gap: 15px; flex-wrap: wrap; margin-top: 13px; font-size: 11.5px; color: var(--text-muted); }
.viz-marks span { display: flex; align-items: center; gap: 6px; }
.viz-marks i { width: 9px; height: 9px; border-radius: 3px; display: block; }
.viz-marks i.p1 { background: color-mix(in srgb, var(--warn) 55%, transparent); }
.viz-marks i.p2 { background: color-mix(in srgb, var(--warn) 85%, transparent); }
.viz-marks i.p3 { background: var(--accent); }

/* shipment rail */
.viz-rail { position: relative; padding-top: 2px; }
.viz-rail .vr-line { position: absolute; left: 0; right: 0; top: 7px; height: 1px; background: var(--border-strong); }
.viz-rail .vr-done { position: absolute; left: 0; top: 7px; height: 1px; background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 35%, transparent)); }
.viz-rail .vr-nodes { position: relative; display: flex; justify-content: space-between; }
.vr-node { display: flex; flex-direction: column; align-items: center; gap: 9px; flex: 1; min-width: 0; }
.vr-dot { width: 15px; height: 15px; border-radius: 50%; border: 1px solid var(--border-strong); background: var(--card); display: grid; place-items: center; }
.vr-dot i { width: 5px; height: 5px; border-radius: 50%; background: color-mix(in srgb, var(--text) 20%, transparent); display: block; }
.vr-node.is-done .vr-dot { border-color: color-mix(in srgb, var(--accent) 60%, transparent); background: color-mix(in srgb, var(--accent) 18%, transparent); }
.vr-node.is-done .vr-dot i { background: var(--accent); }
.vr-node.is-now .vr-dot { box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 13%, transparent); }
.vr-l { font-size: 11.5px; text-align: center; color: var(--text-muted); line-height: 1.35; padding: 0 4px; }
.vr-t { display: block; font-family: var(--font-mono); font-size: 9.5px; color: var(--text-dim); }

/* density grid */
.viz-heat { display: grid; gap: 4px; }
.vh-day { font-family: var(--font-mono); font-size: 9px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-dim); display: flex; align-items: center; }
.vh-cell { aspect-ratio: 1; border-radius: 4px; }
.viz-heatfoot { display: flex; align-items: center; gap: 8px; margin-top: 13px; font-size: 11px; color: var(--text-dim); }
.vh-ramp { display: flex; gap: 3px; }
.vh-ramp i { width: 13px; height: 9px; border-radius: 3px; display: block; }
.vh-note { margin-left: auto; text-align: right; }

/* share list */
.viz-share { display: grid; grid-template-columns: 22px 1fr auto 46px; align-items: center; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--border); }
.viz-share:last-child { border-bottom: 0; }
.viz-share.is-link { cursor: pointer; }
.viz-share.is-link:hover .vsh-name { color: var(--accent); }
.vsh-icon { font-size: 15px; line-height: 1; }
.vsh-body { min-width: 0; }
.vsh-name { display: block; font-size: 13px; font-weight: 500; transition: color var(--fast); }
.vsh-track { display: block; height: 5px; border-radius: 4px; background: color-mix(in srgb, var(--text) 7%, transparent); overflow: hidden; margin-top: 6px; }
.vsh-track i { display: block; height: 100%; border-radius: 4px; background: color-mix(in srgb, var(--text) 34%, transparent); transform-origin: left; animation: vgrow .8s var(--ease) both; }
.viz-share.is-top .vsh-track i { background: var(--accent); }
.viz-share.is-top .vsh-pct { color: var(--accent); }
.vsh-meta { font-size: 12.5px; color: var(--text-muted); text-align: right; white-space: nowrap; }
.vsh-pct { font-size: 13px; font-weight: 600; text-align: right; }
@keyframes vgrow { from { transform: scaleX(0); } }

@media (prefers-reduced-motion: reduce) {
  .vl-bar, .vsh-track i { animation: none; }
}
@media (max-width: 720px) {
  .viz-flow { flex-wrap: wrap; }
  .viz-step { flex: 1 1 40% !important; }
}

/* --- auth pages ----------------------------------------------------------- */
.authwrap {
  min-height: 100vh;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
.authside {
  position: relative;
  overflow: hidden;
  border-right: 1px solid var(--border);
  background:
    radial-gradient(900px 500px at 20% 10%, var(--accent-soft), transparent 60%),
    var(--shell);
  padding: 44px;
  display: flex;
  flex-direction: column;
}
.authside > *:not(.authart) { position: relative; z-index: 1; }
.authside .brandblock { padding: 0; }
/* the line above the headline and the headline itself are set from one
   size, so they cannot drift apart as the panel narrows */
.authside .pitch { margin: auto 0; max-width: 620px; --pitch-type: clamp(23px, 2.25vw, 30px); }
/* the standfirst keeps a readable measure even though the line above it
   is allowed to run the full width of the panel */
.authside .pitch p:not(.pitchline) { max-width: 460px; }

/* The trade named back at the merchant, one word at a time. The selector
   carries the panel because .authside .pitch p sets the standfirst size, and
   this line is a paragraph too. */
.authside .pitch .pitchline {
  /* a hair under the headline at full width, and it gives way faster than the
     headline does as the panel narrows, because this line has to hold a
     country and a category on one row */
  font-size: clamp(16px, 1.92vw, 27.6px);
  font-weight: 500;
  line-height: 1.65;
  letter-spacing: -.02em;
  color: var(--text-muted);
  margin: 0 0 26px;
}
/* the promise always sits on its own line, whatever the panel is doing */
.authside .pitch .pitchline .pl { display: block; }
.authside .pitch .pitchline .fx { font-style: normal; }

/* Each changing word sits in a slot you can see: a pill with a rule under it
   that fills up to the moment it changes, so the line reads as something that
   is running rather than something that was printed. */
.authside .pitch .pitchline .tok {
  position: relative;
  display: inline-grid;
  /* the two words share one cell, and neither may stretch to it: a stretched
     word measures the slot it is already in, which is how a short word ended
     up in a pill cut for a long one */
  justify-items: start;
  overflow: hidden;
  vertical-align: middle;
  padding: .12em .28em .16em;
  margin: 0 .04em;
  border-radius: .42em;
  border: 1px solid var(--border);
  background: rgba(127, 127, 127, .06);
  color: var(--text);
  font-weight: 600;
  /* a touch of overshoot, so the slot springs to its new width instead of
     easing politely into it */
  transition: width .44s cubic-bezier(.34, 1.42, .38, 1), border-color .25s var(--ease),
    background .25s var(--ease), box-shadow .35s var(--ease);
}
.authside .pitch .pitchline .tok::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0; height: 2px; width: 0;
  background: var(--accent);
  opacity: .55;
}
.authside .pitch .pitchline .tok.is-next {
  border-color: color-mix(in srgb, var(--accent) 34%, transparent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}
.authside .pitch .pitchline .tok.is-next::after { animation: tokfill var(--tokspan, 2000ms) linear both; }
.authside .pitch .pitchline .tok.is-swap {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 10%, transparent);
}
@keyframes tokfill { from { width: 0; } to { width: 100%; } }

.authside .pitch .pitchline .tin {
  grid-area: 1 / 1;
  white-space: nowrap;
  transition: transform .42s cubic-bezier(.22, 1.2, .36, 1), opacity .26s ease, filter .26s ease;
}
.authside .pitch .pitchline .tin i {
  font-style: normal;
  margin-left: 4px;
  display: inline-block;
}
.authside .pitch .pitchline .tin:not(.is-next):not(.is-out) i { animation: tokpop .5s cubic-bezier(.22, 1.4, .36, 1) both; }
.authside .pitch .pitchline .tin.is-next { transform: translateY(120%) scale(.94); opacity: 0; }
.authside .pitch .pitchline .tin.is-out { transform: translateY(-120%) scale(.94); opacity: 0; filter: blur(2px); }
@keyframes tokpop {
  0% { transform: scale(.5) rotate(-14deg); opacity: 0; }
  60% { transform: scale(1.18) rotate(4deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .pitchline .tok, .authside .pitch .pitchline .tin { transition: none; }
  .authside .pitch .pitchline .tok::after, .authside .pitch .pitchline .tin i { animation: none; }
}
.authside .pitch h2 {
  font-size: var(--pitch-type, 30px);
  letter-spacing: -.03em;
  line-height: 1.15;
  margin: 0 0 14px;
}
.authside .pitch h2 em { font-family: var(--font-accent); font-style: italic; color: var(--accent); }
.authside .pitch p { font-size: 14px; color: var(--text-muted); line-height: 1.6; margin: 0 0 22px; }
.authside .points { display: flex; flex-direction: column; gap: 10px; }
.authside .point { display: flex; gap: 10px; align-items: flex-start; font-size: 13px; color: var(--text-muted); }
.authside .point svg { width: 15px; height: 15px; color: var(--accent); flex-shrink: 0; margin-top: 2px; }
/* the temple, bottom left, running off both edges of the panel */
.authart {
  position: absolute;
  left: 0;
  bottom: 0;
  z-index: 0;
  /* big enough to read as background rather than ornament: it sits on the
     bottom left corner of the panel with roughly half of it running off */
  width: clamp(460px, 82%, 820px);
  transform: translate(-27%, 21%);
  height: auto;
  fill: none;
  stroke: var(--art-ink);
  stroke-width: .7;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: var(--art-op);
  pointer-events: none;
  /* let the base dissolve before it reaches the line of type at the bottom */
  -webkit-mask-image: linear-gradient(180deg, #000 72%, transparent 99%);
  mask-image: linear-gradient(180deg, #000 72%, transparent 99%);
}
.authart .caps { stroke-width: .9; }
.authart .lantern { stroke-width: 1.15; }
@media (max-height: 760px) { .authart { width: clamp(380px, 66%, 560px); transform: translate(-38%, 30%); } }

.authside .foot { font-family: var(--font-mono); font-size: 10px; color: var(--text-dim); letter-spacing: .1em; text-transform: uppercase; }

.authmain { display: grid; place-items: center; padding: 44px 24px; }
.authcard { width: min(400px, 100%); }
.authcard h1 { font-size: 24px; letter-spacing: -.02em; margin: 0 0 6px; }
.authcard .sub { font-size: 13.5px; color: var(--text-muted); margin: 0 0 24px; line-height: 1.55; }
.authcard .altrow { margin-top: 18px; font-size: 12.5px; color: var(--text-muted); text-align: center; }
.authcard .altrow a { color: var(--accent); }
.authcard .divider {
  display: flex; align-items: center; gap: 12px;
  margin: 22px 0 16px;
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-dim);
}
.authcard .divider::before, .authcard .divider::after {
  content: ''; flex: 1; height: 1px; background: var(--border);
}
/* on a narrow window the panel spends too much of itself on margin, which is
   what pushed the trade line onto a third row */
@media (max-width: 1040px) {
  .authside { padding: 34px 26px; }
}
@media (max-width: 880px) {
  .authwrap { grid-template-columns: 1fr; }
  .authside { display: none; }
}

/* --- role and store picker ------------------------------------------------ */
.rolelist { display: flex; flex-direction: column; gap: 6px; }
.rolerow {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  color: inherit;
  cursor: pointer;
  text-align: left;
  transition: border-color var(--fast), background var(--fast);
}
.rolerow:hover { border-color: var(--border-strong); background: var(--card-hover); }
.rolerow.is-current { border-color: var(--accent-line); background: var(--accent-soft); }
.rolerow .av {
  width: 30px; height: 30px; flex-shrink: 0;
  border-radius: 9px;
  display: grid; place-items: center;
  background: var(--surface-2);
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 600;
  color: var(--text-muted);
}
.rolerow .rtxt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.rolerow .rtxt b { font-size: 13px; font-weight: 500; }
.rolerow .rtxt span { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: .07em; color: var(--text-dim); }
.userrow { border: none; background: none; padding: 0; cursor: pointer; width: 100%; text-align: left; color: var(--text); }
.userrow:hover .un { color: var(--accent); }
.store-id { border: 1px solid var(--border); width: 100%; text-align: left; font: inherit; color: var(--text); cursor: pointer; }

/* --- misc ----------------------------------------------------------------- */
.field textarea.is-bad, .field input.is-bad { border-color: var(--bad); }
.field.is-wide { grid-column: 1 / -1; }
.formgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 14px; }
.formgrid.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.stack { display: flex; flex-direction: column; gap: 14px; }
.rowline { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rowline.end { justify-content: flex-end; }
.muted { color: var(--text-muted); }
.dim { color: var(--text-dim); }
.nowrap { white-space: nowrap; }

@media (max-width: 860px) {
  .formgrid, .formgrid.three { grid-template-columns: 1fr; }
  .drawer { width: 100vw; }
}

/* --- density: the warehouse console works in this all day ------------------ */
/* Same tokens, same black, tighter rhythm. Set html[data-density="compact"]. */
html[data-density="compact"] {
  --gutter: 22px;
  --sidebar-w: 218px;
  --topbar-h: 52px;
  --radius-lg: 14px;
  --radius: 10px;
}
html[data-density="compact"] body { font-size: 13px; }
html[data-density="compact"] .content { padding: 18px var(--gutter) 40px; max-width: 1560px; }
html[data-density="compact"] .card { padding: 14px; }
html[data-density="compact"] .cardhead { padding: 11px 14px; }
html[data-density="compact"] .kpi { padding: 13px; }
html[data-density="compact"] .kpi .knum { font-size: 26px; }
html[data-density="compact"] .pagetitle { font-size: 21px; }
html[data-density="compact"] table { font-size: 12.5px; }
html[data-density="compact"] thead th { padding: 8px 11px; }
html[data-density="compact"] td { padding: 8px 11px; }
html[data-density="compact"] .grid { gap: 10px; }
html[data-density="compact"] .btn { height: 30px; padding: 0 12px; }
html[data-density="compact"] .btn.sm { height: 26px; }
html[data-density="compact"] .navitem { padding: 7px 10px; }
html[data-density="compact"] .pagehead { margin-bottom: 14px; }

/* --- print --------------------------------------------------------------- */
@media print {
  .sidebar, .topbar, .toaster, .overlay { display: none !important; }
  .content { padding: 0; max-width: none; }
  body { background: #fff; color: #000; }
}

/* The ground a screen stands on, said once in the sidebar. A demonstration
   that cannot be told from the real thing is one somebody will quote back
   at you. */
.samplemark {
  margin: 0 0 10px;
  padding: 5px 10px;
  border-radius: 7px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-align: center;
}

/* --- connecting: the few things we need before anything works ------------
   Asked for while a merchant connects rather than left in a settings page,
   because neither the logo nor the countries is a preference. The logo goes
   on the box their customer opens; the countries are what the warehouse has
   to price before a first order can move.
   ------------------------------------------------------------------------ */

.obcard { width: min(560px, 100%); }

.obrail {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 26px; padding: 0; list-style: none;
}
.obrail li {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; color: var(--text-dim);
}
.obrail li + li::before {
  content: ""; width: 18px; height: 1px; background: var(--border-strong);
}
.obrail .dot {
  width: 20px; height: 20px; border-radius: 999px;
  border: 1px solid var(--border-strong);
  display: grid; place-items: center;
  font-size: 11px; font-variant-numeric: tabular-nums;
}
.obrail li.is-now { color: var(--text); }
.obrail li.is-now .dot { border-color: var(--accent); color: var(--accent); }
.obrail li.is-done .dot {
  background: var(--accent); border-color: var(--accent); color: var(--accent-ink);
}

.obchips { display: flex; flex-wrap: wrap; gap: 7px; margin: 0 0 6px; }
.obchip {
  font: inherit; font-size: 13px;
  color: var(--text-muted);
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 6px 13px;
  cursor: pointer;
  transition: color .14s ease, background-color .14s ease, border-color .14s ease;
}
.obchip:hover { color: var(--text); border-color: var(--border-strong); }
.obchip[aria-pressed="true"] {
  color: var(--accent-ink); background: var(--accent); border-color: var(--accent);
}
.obchip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.obcount { font-size: 12.5px; color: var(--text-dim); margin: 10px 0 0; }

.obbox { display: grid; place-items: center; padding: 6px 0 14px; }
.obbox svg { width: 190px; height: 190px; overflow: visible; }

.obshop {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px; margin: 0 0 18px;
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--surface-1);
}
.obshop .tick {
  width: 22px; height: 22px; border-radius: 999px; flex: 0 0 auto;
  background: var(--accent); color: var(--accent-ink);
  display: grid; place-items: center; font-size: 12px;
}
.obshop .who { min-width: 0; }
.obshop .who b { display: block; font-size: 14px; font-weight: 600; }
.obshop .who span { font-size: 12.5px; color: var(--text-dim); word-break: break-all; }

/* A logo is previewed square, because that is the shape it is printed in. */
.ppsquare {
  width: 72px; height: 72px; border-radius: 12px;
  border: 1px solid var(--border-strong);
  background: var(--surface-2);
  display: grid; place-items: center;
  overflow: hidden;
}
.ppsquare img { width: 100%; height: 100%; object-fit: contain; display: block; }
.ppempty { font-size: 20px; font-weight: 600; color: var(--text-dim); letter-spacing: .02em; }

/* The mark on a sync button. It draws itself for as long as the reading
   takes, and sits there whole when nothing is happening. */
.btn.has-tmark { display: inline-flex; align-items: center; gap: 7px; }
.tmark { width: 14px; height: 14px; flex: 0 0 auto; overflow: visible; }
.btn.has-tmark .tmark { color: var(--accent); }
