/* DibbleTech AgriDirectory console — a registry, not a dashboard.
   Dense, tabular, keyboard-friendly. Same identity as the status report:
   olive-biased neutrals, ochre accent (regulatory label), verdigris for
   confirmed states, New York serif for headings on Apple platforms.

   THEME. Warm paper is the default on every machine, because this console is
   read for long stretches against printed price lists and a near-black page
   beside a white PDF is the tiring combination. The OS preference is NOT
   followed automatically for that reason; dark is a deliberate choice, stored
   per browser, and its paper is a warm dark olive rather than black — pure
   black plus a light serif is the other tiring combination. */

:root {
  --ink:#22261F; --paper:#FBFAF6; --panel:#F4F2EB; --panel2:#ECEAE0;
  --rule:#E0DDD1; --hair:#EBE8DE; --muted:#71756B; --accent:#8F5C13;
  --verdigris:#2C6E5B; --alarm:#A33A28; --focus:#8F5C13;
  --radius:5px;
  --shadow:0 1px 2px rgba(34,38,31,.05), 0 1px 8px rgba(34,38,31,.04);
  --serif:ui-serif,"New York",Georgia,serif;
  --sans:ui-sans-serif,-apple-system,"SF Pro Text","Segoe UI",sans-serif;
  --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
}
:root[data-theme="dark"] {
  --ink:#E4E6DD; --paper:#1C1F18; --panel:#23271F; --panel2:#2B2F26;
  --rule:#383D32; --hair:#2F3429; --muted:#9AA093; --accent:#D8A24A;
  --verdigris:#63BC9C; --alarm:#E0806C; --focus:#D8A24A;
  --shadow:0 1px 2px rgba(0,0,0,.28), 0 1px 8px rgba(0,0,0,.22);
}

* { box-sizing:border-box; }
html,body { margin:0; }
body {
  color:var(--ink); font-family:var(--sans);
  font-size:14px; line-height:1.55; -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
a { color:inherit; text-decoration:none; }
a:hover { text-decoration:underline; text-underline-offset:2px; }
:focus-visible { outline:2px solid var(--focus); outline-offset:2px; }

/* chrome ------------------------------------------------------------------ */
header.top {
  display:flex; align-items:center; gap:26px; padding:0 24px;
  border-bottom:1px solid var(--rule); position:sticky; top:0; z-index:20;
  background:color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter:saturate(140%) blur(8px); box-shadow:var(--shadow);
  flex-wrap:wrap;
}
.brand { font-family:var(--serif); font-size:18px; font-weight:400;
  letter-spacing:-.01em; padding:10px 0; white-space:nowrap; color:var(--muted); }
.brand a { color:inherit; }
.brand em { font-style:normal; font-weight:600; color:var(--ink); }
.brand small { font-family:var(--mono); font-size:10px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted); display:block; font-weight:400;
  margin-top:-2px; }
/* Subject strip: what you are working on. */
nav.entities { display:flex; gap:3px; margin-left:auto; }
nav.entities a { font-size:13px; padding:5px 14px; border-radius:999px;
  color:var(--muted); border:1px solid transparent;
  transition:background .12s ease, color .12s ease; }
nav.entities a:hover { color:var(--ink); background:var(--panel); text-decoration:none; }
nav.entities a.on { color:var(--paper); background:var(--ink); font-weight:500; }

/* Screens within the selected subject. */
nav.top { display:flex; gap:2px; flex-wrap:wrap; padding:0 24px;
  border-bottom:1px solid var(--rule); position:sticky; top:53px; z-index:19;
  background:color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter:saturate(140%) blur(8px); }
nav.top a { padding:11px 12px; font-size:13px; color:var(--muted);
  border-bottom:2px solid transparent; margin-bottom:-1px;
  transition:color .12s ease, border-color .12s ease; }
nav.top a:hover { color:var(--ink); text-decoration:none; border-bottom-color:var(--rule); }
nav.top a.on { color:var(--ink); border-bottom-color:var(--accent); font-weight:500; }

main { padding:26px 24px 80px; max-width:1400px; margin:0 auto; }
h1 { font-family:var(--serif); font-size:26px; font-weight:600; margin:0 0 4px;
  letter-spacing:-.015em; }
h2 { font-family:var(--serif); font-size:18px; font-weight:600; margin:0 0 10px; }
h3 { font-family:var(--serif); font-size:16px; font-weight:600; margin:0 0 8px; }
.lede { color:var(--muted); margin:0 0 20px; max-width:70ch; font-size:13.5px; }
.eyebrow { font-family:var(--mono); font-size:10.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted); }

/* stats ------------------------------------------------------------------- */
.stats { display:grid; grid-template-columns:repeat(auto-fit,minmax(130px,1fr));
  gap:22px; margin:0 0 30px; }
.stat b { display:block; font-family:var(--serif); font-size:29px; line-height:1;
  font-variant-numeric:tabular-nums; letter-spacing:-.02em; font-weight:600; }
.stat span { font-size:12px; color:var(--muted); display:block; margin-top:5px; }

/* panels ------------------------------------------------------------------ */
.grid2 { display:grid; grid-template-columns:1fr 1fr; gap:26px; align-items:start; }
@media (max-width:900px) { .grid2 { grid-template-columns:1fr; } }
.panel { border:1px solid var(--rule); background:var(--panel); padding:17px 19px;
  border-radius:var(--radius); box-shadow:var(--shadow); }

/* queues ------------------------------------------------------------------ */
.queue { display:flex; align-items:center; gap:14px; padding:11px 0;
  border-bottom:1px solid var(--rule); }
.queue:last-child { border-bottom:0; }
.queue .n { font-family:var(--mono); font-size:19px; font-variant-numeric:tabular-nums;
  min-width:62px; text-align:right; color:var(--accent); font-weight:600; }
.queue .n.zero { color:var(--muted); }
.queue .l { flex:1; }

/* tables ------------------------------------------------------------------ */
/* THE GRID IS ITS OWN SCROLLPORT, and that is what freezes the header.

   A sticky <th> anchors to the nearest scrolling ancestor. `overflow-x:auto`
   for wide tables already made .scroll one — but an unconstrained one, which
   never actually scrolls, so the header rode away with the page instead of
   sticking to anything. `overflow-y:clip` does not help: with the other axis
   set to auto it computes to hidden, and hidden is still a scrollport.
   The box has to be given a height for its own sticky header to mean
   anything, so the grid scrolls internally and the header parks at its top.
   Tables shorter than the cap are untouched. */
/* NOT overscroll-behavior:contain. It was here to keep a long table's scroll
   from running on into the page, which sounds tidy and is a trap: `contain`
   stops the wheel chaining to the parent even when this box has nothing to
   scroll. Most of these tables fit inside the cap, so the box never scrolls at
   all — and with the cursor anywhere over it the page would not move either.
   That is the bug where scrolling up did nothing unless you moved the pointer
   off the table first. Default chaining is what a reader expects: this box
   scrolls while it has somewhere to go, then the page takes over. */
.scroll { overflow:auto; max-height:calc(100vh - var(--chrome, 106px) - 96px);
  min-height:180px;
  border:1px solid var(--rule); border-radius:var(--radius);
  background:var(--paper); box-shadow:var(--shadow); }
table { border-collapse:collapse; width:100%; font-size:13px; }
/* Offset by the sticky chrome above it — the brand header plus the screen nav
   — so the row parks under them rather than behind them. --chrome is measured
   at runtime because both wrap on narrow viewports. The background must stay
   opaque: rows scrolling underneath a translucent header are unreadable. */
/* top:0 — the grid is the scrollport now, so the header parks at the top of
   its own box. The background must stay fully opaque: rows sliding under a
   translucent header are unreadable. */
th { text-align:left; font-size:10.5px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--muted); font-weight:600; padding:9px 12px; background:var(--panel);
  white-space:nowrap; position:sticky; top:0; z-index:5;
  box-shadow:inset 0 -1px 0 var(--rule), 0 2px 6px rgba(0,0,0,.06); }
td { padding:9px 12px; border-bottom:1px solid var(--hair); vertical-align:top; }
tbody tr { transition:background .1s ease; }
tbody tr:hover { background:var(--panel); }
tbody tr:last-child td { border-bottom:0; }
td.num, th.num { text-align:right; font-variant-numeric:tabular-nums; font-family:var(--mono); }
.mono { font-family:var(--mono); font-size:12px; }
.dim { color:var(--muted); }

/* controls ---------------------------------------------------------------- */
.bar { display:flex; gap:10px; flex-wrap:wrap; align-items:center; margin:0 0 16px; }
input[type=search], input[type=text], select {
  font:inherit; font-size:13.5px; padding:8px 11px; border:1px solid var(--rule);
  background:var(--paper); color:var(--ink); min-width:0;
  border-radius:var(--radius); transition:border-color .12s ease, box-shadow .12s ease;
}
input:hover, select:hover { border-color:var(--muted); }
input:focus, select:focus { outline:none; border-color:var(--accent);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent); }
input[type=search] { flex:1; min-width:220px; }
input::placeholder { color:var(--muted); }
button, .btn { font:inherit; font-size:13px; padding:8px 14px; border:1px solid var(--ink);
  background:var(--ink); color:var(--paper); cursor:pointer;
  border-radius:var(--radius); transition:opacity .12s ease, background .12s ease; }
button.ghost, .btn.ghost { background:transparent; color:var(--ink); border-color:var(--rule); }
button.ghost:hover, .btn.ghost:hover { background:var(--panel); opacity:1; }
button:hover, .btn:hover { opacity:.86; text-decoration:none; }

/* theme toggle ------------------------------------------------------------ */
#theme { background:transparent; border:1px solid var(--rule); color:var(--muted);
  font-family:var(--mono); font-size:10.5px; letter-spacing:.1em;
  text-transform:uppercase; padding:5px 10px; margin-left:14px;
  align-self:center; border-radius:999px; }
#theme:hover { color:var(--ink); border-color:var(--muted); background:var(--panel);
  opacity:1; }

/* facets ------------------------------------------------------------------ */
.layout { display:grid; grid-template-columns:212px 1fr; gap:26px; align-items:start; }
/* A grid item will not shrink below its content, so a wide table in the second
   column pushed the whole page sideways instead of scrolling inside its own
   box — 166px of horizontal overflow on Scraped at 1024px. min-width:0 lets
   the column be narrower than what is in it; the table's own .scroll then does
   the scrolling, which is where it belongs. */
.layout > * { min-width: 0; }
@media (max-width:900px) { .layout { grid-template-columns:1fr; } }
.facet { margin-bottom:22px; }
.facet h3 { font-family:var(--mono); font-size:10.5px; letter-spacing:.12em;
  text-transform:uppercase; color:var(--muted); margin:0 0 7px; font-weight:600; }
.facet a { display:flex; justify-content:space-between; gap:8px;
  padding:4px 7px; margin:0 -7px; border-radius:var(--radius);
  font-size:12.5px; color:var(--muted); transition:background .1s ease; }
.facet a:hover, .facet a.on { color:var(--ink); text-decoration:none; background:var(--panel); }
.facet a.on { font-weight:600; }
.facet a .c { font-family:var(--mono); font-size:11px; font-variant-numeric:tabular-nums; }

/* BRAND PAGE: the record, and a panel to think in. */
.brandpage { display:grid; grid-template-columns:1fr 0fr; height:calc(100vh - var(--chrome,106px)); }
.brandpage:has(#panel:not(:empty)) { grid-template-columns:1fr 380px; }
.brandmain { overflow-y:auto; padding:22px 26px 60px; min-width:0; }
.panel-rail { border-left:1px solid var(--rule); background:var(--panel);
  overflow-y:auto; padding:0; }
.panel-rail:empty { border-left:0; }
.panelhead { display:flex; justify-content:space-between; align-items:flex-start;
  gap:12px; padding:16px 18px 12px; border-bottom:1px solid var(--rule); }
.panelval { font-size:16px; color:var(--ink); margin-top:3px; word-break:break-word; }
.panelwhy { margin:0; padding:12px 18px; font-size:12.5px; color:var(--muted);
  border-bottom:1px solid var(--rule); line-height:1.5; }
.panelsec { padding:14px 18px; border-bottom:1px solid var(--rule); }
.panelsec h4 { margin:0 0 8px; font-family:var(--mono); font-size:10px;
  letter-spacing:.1em; text-transform:uppercase; color:var(--muted); font-weight:600; }
.panelsec form { display:flex; flex-direction:column; gap:8px; }
.panelsec input[type=text], .panelsec select { width:100%; font-size:13px; }
.scopelbl { font-family:var(--mono); font-size:9.5px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--muted); margin-top:2px; }
table.mini { width:100%; font-size:12px; border-collapse:collapse; }
table.mini td { padding:4px 6px; border-bottom:1px solid var(--hair); }
/* Our own suggestion list: always directly under the input, always themed. */
tr.decided { opacity:.62; }
.rowerr { color:var(--alarm); font-size:11.5px; line-height:1.45; margin-bottom:5px;
  max-width:34ch; }

.was { text-decoration:line-through; color:var(--muted); }

.cellbtn { background:none; border:0; border-bottom:1px dashed var(--rule);
  border-radius:0; padding:1px 0; font:inherit; color:var(--ink); cursor:pointer;
  text-align:left; }
.cellbtn:hover { border-bottom-color:var(--accent); color:var(--accent); opacity:1; }

.sgwrap { position:relative; }
.sglist { position:absolute; left:0; right:0; top:calc(100% + 3px); z-index:60;
  margin:0; padding:4px; list-style:none; max-height:230px; overflow-y:auto;
  background:var(--paper); border:1px solid var(--accent);
  border-radius:var(--radius); box-shadow:0 8px 26px rgba(0,0,0,.18); }
.sglist li { display:flex; justify-content:space-between; gap:10px; padding:6px 9px;
  font-size:12.5px; border-radius:4px; cursor:pointer; color:var(--ink); }
.sglist li:hover, .sglist li.on { background:var(--panel2); }
.sglist .sgn { font-family:var(--mono); font-size:10.5px; color:var(--muted); }

.molblock { border:1px solid var(--rule); border-radius:var(--radius);
  background:var(--paper); padding:10px 12px; margin-bottom:9px; }
.molname { font-size:13px; margin-bottom:7px; }
.molbtns { display:flex; gap:5px; }
.molbtns button { padding:5px 9px; font-size:11.5px; flex:1; }

.warnline { color:var(--alarm); margin:8px 0 0; line-height:1.45; }
.willhappen { border:1px solid var(--rule); border-radius:var(--radius);
  background:var(--paper); padding:10px 12px; font-size:12px; color:var(--muted); }
.willhappen b { color:var(--ink); font-size:11px; text-transform:uppercase;
  letter-spacing:.08em; font-family:var(--mono); }
.willhappen ul { margin:6px 0 0; padding-left:16px; line-height:1.6; }

/* Every value on the record is a button that opens the panel. */
.brandhead { display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; margin-bottom:14px; }
.brandhead h1 { margin:0; }
.brandhead .crumb { margin:0; }
.brandhead .headacts { margin-left:auto; display:flex; gap:7px; }
.brandhead .headacts form { margin:0; }
.brandhead .headacts button { padding:5px 11px; font-size:12px; }
.factline { font-size:13px; margin:-6px 0 18px; }
.factline b { color:var(--ink); }
td.mismatch { color:var(--alarm); font-weight:600; }
.mismatch-mark { font-weight:700; }

.fieldgrid { display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  gap:10px; margin:0 0 18px; }
.fieldcell { display:flex; flex-direction:column; gap:3px; align-items:flex-start;
  text-align:left; border:1px solid var(--rule); border-radius:var(--radius);
  background:var(--panel); padding:10px 13px; cursor:pointer; color:var(--ink);
  font:inherit; transition:border-color .12s ease, background .12s ease; }
.fieldcell:hover { border-color:var(--accent); background:var(--panel2); opacity:1; }
.fieldcell.static { cursor:default; background:transparent; }
.fieldcell .fl { font-family:var(--mono); font-size:9.5px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--muted); }
.fieldcell .fv { font-size:14px; word-break:break-word; }

.rtabs { display:flex; gap:2px; flex-wrap:wrap; position:sticky; top:0; z-index:8;
  background:var(--paper); border-bottom:1px solid var(--rule); margin:6px 0 14px;
  padding-top:4px; }
.rtabs [role=tab] { background:none; border:0; border-bottom:2px solid transparent;
  border-radius:0; color:var(--muted); font:inherit; font-size:13px; padding:9px 13px;
  cursor:pointer; display:flex; gap:7px; align-items:center; }
.rtabs [role=tab]:hover { color:var(--ink); opacity:1; }
.rtabs [role=tab].on { color:var(--ink); border-bottom-color:var(--accent); font-weight:600; }
.rtabs .c { font-family:var(--mono); font-size:10.5px; background:var(--panel2);
  color:var(--muted); border-radius:999px; padding:1px 7px; }
.rtabs [role=tab].on .c { background:var(--accent); color:var(--paper); }
.rpane[hidden] { display:none; }

details.section { border:1px solid var(--rule); border-radius:var(--radius);
  margin-top:12px; background:var(--panel); }
details.section > summary { cursor:pointer; padding:11px 15px; font-weight:600;
  font-size:13.5px; list-style:none; display:flex; gap:9px; align-items:center; }
details.section > summary::-webkit-details-marker { display:none; }
details.section > summary::before { content:'▸'; color:var(--muted); font-size:11px; }
details.section[open] > summary::before { content:'▾'; }
details.section > summary .c { font-family:var(--mono); font-size:11px;
  background:var(--panel2); color:var(--muted); border-radius:999px; padding:1px 7px; }
details.section > *:not(summary) { padding:0 15px 15px; }
details.rawdoc { margin:8px 0; }
details.rawdoc > summary { cursor:pointer; font-size:12.5px; padding:5px 0; }

/* WORKSPACE: a left rail of controls and a grid that owns the rest.
   Everything that is not data goes in the rail, so the grid gets the page and
   there is ONE scroll — on the grid. A steward checking a thousand brands
   should not scroll a page header past first. */
main.workspace-page { max-width:none; padding:0; }
.workspace { display:grid; grid-template-columns:262px 1fr;
  height:calc(100vh - var(--chrome, 106px)); }
.rail { border-right:1px solid var(--rule); background:var(--panel);
  padding:18px 16px; overflow-y:auto; display:flex; flex-direction:column; gap:14px; }
.railtop h1 { font-size:22px; margin:2px 0 4px; }
.rail form { display:flex; flex-direction:column; gap:10px; }
.rail input[type=search] { width:100%; font-size:13px; }
.railf { display:flex; flex-direction:column; gap:4px; font-family:var(--mono);
  font-size:9.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); }
.railf select { font-family:var(--sans); font-size:12.5px; letter-spacing:0;
  text-transform:none; width:100%; }
.railfoot { margin-top:auto; padding-top:14px; border-top:1px solid var(--rule);
  line-height:1.5; }

/* The grid pane is the scrollport, so its header sticks with top:0. */
.gridpane { overflow:auto; min-width:0; }
table.fullgrid { border-collapse:collapse; width:100%; font-size:13px; }
table.fullgrid th { position:sticky; top:0; z-index:5; background:var(--panel);
  text-align:left; font-size:10px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--muted); font-weight:600; padding:9px 12px; white-space:nowrap;
  box-shadow:inset 0 -1px 0 var(--rule), 0 2px 6px rgba(0,0,0,.06); }
table.fullgrid .gid { margin-left:8px; }
table.fullgrid td { padding:6px 12px; border-bottom:1px solid var(--hair);
  vertical-align:top; }
table.fullgrid tr.clickable { cursor:pointer; }
table.fullgrid tbody tr:hover { background:var(--panel); }
.gridpane .pager { padding:14px 16px; }

/* queue info, search and sorting ------------------------------------------ */
/* Search, filter and the info disclosure share the tab row, pushed right, so
   the grid starts immediately under one line of chrome instead of three. */
.subtabs { flex-wrap:wrap; row-gap:6px; }
.subtabs .tabtools { margin-left:auto; display:flex; gap:7px; align-items:center;
  padding-bottom:5px; flex:1 1 320px; justify-content:flex-end; min-width:0; }
.subtabs .tabtools input[type=search] { flex:1 1 200px; max-width:420px;
  min-width:130px; font-size:13px; padding:6px 10px; }
.subtabs .tabtools select { font-size:12.5px; padding:6px 8px; }
.gridcount { font-size:12.5px; margin:0 0 10px; }

/* A page heading and its explanation on one line. The panel opens over the
   content instead of pushing every row down. */
.pagehead { display:flex; align-items:baseline; gap:14px; flex-wrap:wrap;
  margin:0 0 16px; }
.pagehead h1, .pagehead h2 { margin:0; }
.pagehead details.info { margin-left:auto; align-self:center; }
.pagehead details.info .info-body { right:0; left:auto; }
.gridcount b { color:var(--ink); }
details.info { position:relative; }
details.info .info-body { position:absolute; right:0; top:calc(100% + 8px);
  z-index:30; width:min(78ch, calc(100vw - 60px)); background:var(--panel);
  box-shadow:0 6px 28px rgba(0,0,0,.14); }
details.info > summary { list-style:none; cursor:pointer; display:inline-flex;
  gap:7px; align-items:center; font-size:12.5px; color:var(--muted);
  border:1px solid var(--rule); border-radius:999px; padding:3px 11px 3px 4px; }
details.info > summary::-webkit-details-marker { display:none; }
details.info > summary:hover { color:var(--ink); border-color:var(--muted); }
details.info > summary > span[aria-hidden] { display:inline-flex; width:19px;
  height:19px; align-items:center; justify-content:center; border-radius:50%;
  background:var(--panel2); color:var(--muted); font-family:var(--serif);
  font-style:italic; font-size:12px; font-weight:600; }
details.info[open] > summary { color:var(--ink); border-color:var(--accent); }
.info-body { margin-top:10px; padding:15px 17px; border:1px solid var(--rule);
  border-radius:var(--radius); background:var(--panel); max-width:82ch;
  font-size:13px; color:var(--muted); }
.info-body p { margin:0 0 9px; }
.info-body p:last-child { margin-bottom:0; }
.info-body b, .info-body strong { color:var(--ink); }
.info-body pre { margin-top:10px; }

.queuebar { align-items:center; }
.queuebar .count { margin-left:auto; font-size:12.5px; }
.queuebar select { min-width:118px; }

a.sorth { display:inline-flex; gap:5px; align-items:center; color:inherit;
  white-space:nowrap; }
a.sorth:hover { color:var(--ink); text-decoration:none; }
a.sorth .arrow { font-size:10px; opacity:.35; }
a.sorth.on { color:var(--ink); }
a.sorth.on .arrow { opacity:1; color:var(--accent); }
th .sorth { font: inherit; letter-spacing:inherit; text-transform:inherit; }

.pager { display:flex; gap:8px; align-items:center; margin-top:14px; }

/* create forms ------------------------------------------------------------ */
.recform { display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:14px 20px; max-width:960px; margin-bottom:28px; }
.recform label { display:flex; flex-direction:column; gap:5px; font-size:13px; }
.recform label.inline { flex-direction:row; align-items:center; gap:7px; }
.recform fieldset { border:1px solid var(--rule); border-radius:var(--radius);
  padding:9px 12px; display:flex; gap:14px; flex-wrap:wrap; }
.recform legend { font-size:12px; color:var(--muted); padding:0 5px; }
.recform > div { grid-column:1/-1; display:flex; gap:9px; }

.results-col { min-width:0; }
.brandrow { cursor:pointer; }
.brandrow .disc { color:var(--muted); font-size:11px; transition:transform .12s ease; }
.brandrow.open .disc { transform:rotate(90deg); display:inline-block; }
tr.packs > td { background:var(--panel); padding:10px 14px; }
table.inner { width:100%; font-size:12.5px; background:var(--paper);
  border:1px solid var(--rule); border-radius:var(--radius); }
table.inner th { position:static; background:var(--panel2); box-shadow:none;
  font-size:9.5px; }
table.inner td { padding:7px 10px; }

.resolved { color:var(--verdigris); margin-top:2px; }

.applybar.quiet { background:var(--panel); font-size:12.5px; padding:6px 24px; }
.applybar.quiet button { padding:3px 10px; font-size:11.5px; }
.applybar { display:flex; gap:12px; align-items:center; flex-wrap:wrap;
  padding:9px 24px; font-size:13px; background:color-mix(in srgb, var(--accent) 10%, var(--paper));
  border-bottom:1px solid var(--rule); position:relative; z-index:2; }
.applybar form { margin:0; }
.applybar button { padding:5px 13px; font-size:12.5px; }
#rebuild:empty { display:none; }
#rebuild { padding:0 24px; position:relative; z-index:2; }

.applied { border:1px solid var(--verdigris); border-radius:var(--radius);
  background:color-mix(in srgb, var(--verdigris) 8%, transparent);
  color:var(--ink); font-size:13px; padding:9px 14px; margin-bottom:12px; }

/* lock + quarantine ------------------------------------------------------- */
.govern { display:flex; gap:10px; align-items:center; flex-wrap:wrap;
  border:1px solid var(--rule); border-radius:var(--radius);
  background:var(--panel); padding:11px 14px; margin-bottom:6px; }
.govern form { display:flex; gap:5px; align-items:center; margin:0; }
.govern input[type=text] { width:150px; font-size:12px; padding:5px 8px; }
.govern select { font-size:12px; padding:5px 8px; }
.govern button { padding:5px 10px; font-size:12px; }
.govern .lvl { font-family:var(--mono); font-size:10px; letter-spacing:.09em;
  text-transform:uppercase; color:var(--muted); min-width:118px; }

.elev { position:relative; }
.elev > summary { list-style:none; cursor:pointer; }
.elev > summary::-webkit-details-marker { display:none; }
.elevform { position:absolute; right:0; top:calc(100% + 8px); z-index:40;
  width:270px; background:var(--panel); border:1px solid var(--rule);
  border-radius:var(--radius); box-shadow:0 6px 28px rgba(0,0,0,.16);
  padding:14px; display:flex; flex-direction:column; gap:8px; }
.elevform label { font-family:var(--mono); font-size:9.5px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--muted); }
.elevform input { width:100%; font-size:13px; }
.elevform p { margin:0; line-height:1.5; }
.rolechip.on { color:var(--paper); background:var(--accent); border-color:var(--accent); }

.rolechip { font-family:var(--mono); font-size:10px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--muted); border:1px solid var(--rule);
  border-radius:999px; padding:2px 9px; }

/* record corrections ------------------------------------------------------ */
.corrections { display:grid; grid-template-columns:repeat(auto-fit,minmax(330px,1fr));
  gap:12px; margin:0 0 24px; }
.cfield { border:1px solid var(--rule); border-radius:var(--radius);
  background:var(--panel); padding:12px 14px; }
.cfield label { display:block; font-family:var(--mono); font-size:10px;
  letter-spacing:.1em; text-transform:uppercase; color:var(--muted); margin-bottom:4px; }
.cval { font-size:13px; margin-bottom:8px; word-break:break-word; }
.cform { display:flex; gap:5px; flex-wrap:wrap; align-items:center; }
.cform input[type=text] { flex:1 1 130px; min-width:0; font-size:12.5px; padding:5px 8px; }
.cform select { flex:1 1 100%; font-size:12px; padding:5px 8px; }
.cform button { padding:5px 11px; font-size:12px; }
.cruling { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.cruling form { margin:0; }

/* review sub-tabs --------------------------------------------------------- */
.subtabs { display:flex; gap:4px; margin:0 0 22px; border-bottom:1px solid var(--rule); }
.subtabs a { padding:8px 14px; font-size:13.5px; color:var(--muted);
  border-bottom:2px solid transparent; margin-bottom:-1px; display:flex;
  align-items:center; gap:7px; transition:color .12s ease, border-color .12s ease; }
.subtabs a:hover { color:var(--ink); text-decoration:none; }
.subtabs a.on { color:var(--ink); border-bottom-color:var(--accent); font-weight:600; }
.subtabs .c { font-family:var(--mono); font-size:11px; font-variant-numeric:tabular-nums;
  background:var(--panel2); color:var(--muted); border-radius:999px; padding:1px 7px; }
.subtabs a.on .c { background:var(--accent); color:var(--paper); }

/* decisions taken while the grid is filtered to Undecided ----------------- */
.recent:empty { display:none; }
.recent { display:flex; flex-wrap:wrap; gap:8px; margin:0 0 14px; }
.chip { display:inline-flex; align-items:center; gap:8px; font-size:12.5px;
  border:1px solid var(--rule); border-radius:999px; padding:5px 13px;
  background:var(--panel); color:var(--muted); }
.chip .mono { color:var(--ink); font-size:12px; }
.chip .tick { color:var(--verdigris); font-weight:700; }
.chip.restored { opacity:.65; }
.chip form { display:inline; margin:0; }
.linkbtn { background:none; border:0; padding:0; color:var(--accent);
  font:inherit; font-size:12.5px; text-decoration:underline;
  text-underline-offset:2px; cursor:pointer; border-radius:0; }
.linkbtn:hover { opacity:1; color:var(--ink); }

/* review decisions -------------------------------------------------------- */
.tiny { font-size:11.5px; margin-top:3px; }
.bulkbar { align-items:center; padding:9px 12px; border:1px solid var(--rule);
  border-radius:var(--radius); background:var(--panel); margin-bottom:10px; }
.bulkbar label { display:flex; gap:7px; align-items:center; font-size:13px; }
input[type=checkbox] { accent-color:var(--accent); width:15px; height:15px; }
/* One line, always. Wrapping put the third button under the other two and
   doubled every row's height, which costs more vertical space than the
   horizontal space it saved. */
form.decide { display:flex; gap:4px; align-items:center; flex-wrap:nowrap; }
form.decide input[type=text] { width:118px; font-size:12px; padding:5px 8px; }
form.decide select { font-size:12px; padding:5px 8px; max-width:190px; }
form.decide button { padding:5px 8px; font-size:11.5px; white-space:nowrap; }
td .pill { font-size:9.5px; padding:1px 6px; }
.scroll td { max-width:260px; }
.btn.on { border-color:var(--accent); color:var(--ink); background:var(--panel); }
td form { margin:0; }

/* pills ------------------------------------------------------------------- */
.pill { display:inline-block; font-family:var(--mono); font-size:10px;
  letter-spacing:.06em; text-transform:uppercase; padding:2px 7px;
  border:1px solid color-mix(in srgb, currentColor 35%, transparent);
  background:color-mix(in srgb, currentColor 9%, transparent);
  border-radius:999px; white-space:nowrap; }
.pill.ok { color:var(--verdigris); }
.pill.warn { color:var(--accent); }
.pill.bad { color:var(--alarm); }
.pill.mute { color:var(--muted); }
.mods { color:var(--accent); font-family:var(--mono); font-size:11px; }

/* match ------------------------------------------------------------------- */
.cand { border:1px solid var(--rule); margin-bottom:13px; background:var(--panel);
  border-radius:var(--radius); box-shadow:var(--shadow); overflow:hidden; }
.cand.blocked { opacity:.72; border-style:dashed; }
.cand-h { display:flex; gap:14px; align-items:baseline; padding:12px 16px;
  border-bottom:1px solid var(--rule); flex-wrap:wrap; }
.cand-h .name { font-family:var(--serif); font-size:17px; font-weight:600; }
.cand-h .sc { font-family:var(--mono); font-size:15px; font-variant-numeric:tabular-nums;
  margin-left:auto; }
.cand-b { padding:12px 16px; display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:12px 22px; }
.f label { display:block; font-family:var(--mono); font-size:10px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--muted); margin-bottom:2px; }
.f div { font-size:13px; word-break:break-word; }
.why { padding:10px 16px; background:var(--panel2); font-size:13px;
  border-top:1px solid var(--rule); }
.trace { font-family:var(--mono); font-size:11.5px; }
.trace .row { display:flex; gap:10px; padding:3px 0; }
.trace .row.off { color:var(--muted); }
.trace .r { min-width:190px; }
.trace .v { min-width:52px; text-align:right; font-variant-numeric:tabular-nums; }

/* detail ------------------------------------------------------------------ */
.fields { display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
  gap:14px 24px; margin-bottom:22px; }
pre { font-family:var(--mono); font-size:11.5px; background:var(--panel);
  border:1px solid var(--rule); padding:12px; overflow-x:auto; margin:0;
  max-height:420px; border-radius:var(--radius); }
details summary { cursor:pointer; padding:9px 0; font-weight:500; }
details summary:hover { color:var(--accent); }
.crumb { font-size:12.5px; color:var(--muted); margin-bottom:10px; }
.empty { color:var(--muted); font-style:italic; padding:14px 0; }
.htmx-request .spin { visibility:visible; }
.spin { visibility:hidden; font-family:var(--mono); font-size:11px; color:var(--muted); }
@media (prefers-reduced-motion:reduce) { * { transition:none !important; } }

/* Sortable grid headers. The whole cell is the target, not just the word — a
   10.5px uppercase label is a small thing to hit. The arrow slot is reserved at
   all times so the header row does not reflow by a few pixels when a column
   becomes sorted. */
th.sort { padding:0; }
th.sort a { display:block; padding:9px 12px; color:inherit; text-decoration:none;
  white-space:nowrap; }
th.sort a:hover { background:var(--hair); color:var(--ink); }
th.sort .arw { display:inline-block; min-width:11px; margin-left:5px;
  font-size:11px; color:var(--accent); }
th.sort.on a { color:var(--ink); }
.crumb kbd.esc { font-family:var(--mono); font-size:10px; letter-spacing:.04em;
  border:1px solid var(--rule); border-radius:4px; padding:1px 5px; margin-left:6px;
  color:var(--muted); }

/* PAPER.
   Purely aesthetic — nothing about layout or behaviour depends on it.

   Two tiles at very different scales, because one alone reads as digital
   noise: the fine one is the tooth of the sheet, the coarse one the
   unevenness of the pulp.

   The opacity is baked into each tile rather than applied with a blend mode.
   Two earlier attempts failed on that: noise at full strength blended with
   `multiply` washed the whole page flat grey, and a fixed overlay using
   `mix-blend-mode` did not blend with the page canvas at all and was simply
   invisible. A translucent image layered over the background colour needs
   neither, and is what actually shows.

   Fixed attachment, so the sheet stays still and the content moves over it.

   Held low deliberately — this is a dense table tool, and grain that competes
   with 10px type is worse than no grain. Lighter still in dark, where the same
   noise on a dark ground reads about twice as loud, and inverted so the specks
   catch the light rather than smudging it.

   Off for anyone who has asked for MORE CONTRAST: grain slightly lowers the
   contrast between text and ground, and somebody who asked for more of it
   should not be given less. (`prefers-reduced-transparency` was the wrong
   guard — that setting is about translucent, see-through surfaces.) */
body {
  background-color: var(--paper);
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27170%27%20height%3D%27170%27%3E%0A%3Cfilter%20id%3D%27t%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.8%27%20numOctaves%3D%274%27%20stitchTiles%3D%27stitch%27%2F%3E%0A%3CfeColorMatrix%20type%3D%27saturate%27%20values%3D%270%27%2F%3E%3C%2Ffilter%3E%0A%3Crect%20width%3D%27170%27%20height%3D%27170%27%20filter%3D%27url%28%23t%29%27%20opacity%3D%270.16%27%2F%3E%3C%2Fsvg%3E"), url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27620%27%20height%3D%27620%27%3E%0A%3Cfilter%20id%3D%27t%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.009%27%20numOctaves%3D%272%27%20stitchTiles%3D%27stitch%27%2F%3E%0A%3CfeColorMatrix%20type%3D%27saturate%27%20values%3D%270%27%2F%3E%3C%2Ffilter%3E%0A%3Crect%20width%3D%27620%27%20height%3D%27620%27%20filter%3D%27url%28%23t%29%27%20opacity%3D%270.1%27%2F%3E%3C%2Fsvg%3E");
  background-size: 170px 170px, 620px 620px;
  background-attachment: fixed, fixed;
}
:root[data-theme="dark"] body {
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27170%27%20height%3D%27170%27%3E%0A%3Cfilter%20id%3D%27t%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.8%27%20numOctaves%3D%274%27%20stitchTiles%3D%27stitch%27%2F%3E%0A%3CfeColorMatrix%20type%3D%27saturate%27%20values%3D%270%27%2F%3E%3CfeComponentTransfer%3E%3CfeFuncR%20type%3D%27table%27%20tableValues%3D%271%200%27%2F%3E%3CfeFuncG%20type%3D%27table%27%20tableValues%3D%271%200%27%2F%3E%3CfeFuncB%20type%3D%27table%27%20tableValues%3D%271%200%27%2F%3E%3C%2FfeComponentTransfer%3E%3C%2Ffilter%3E%0A%3Crect%20width%3D%27170%27%20height%3D%27170%27%20filter%3D%27url%28%23t%29%27%20opacity%3D%270.1%27%2F%3E%3C%2Fsvg%3E"), url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27620%27%20height%3D%27620%27%3E%0A%3Cfilter%20id%3D%27t%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.009%27%20numOctaves%3D%272%27%20stitchTiles%3D%27stitch%27%2F%3E%0A%3CfeColorMatrix%20type%3D%27saturate%27%20values%3D%270%27%2F%3E%3CfeComponentTransfer%3E%3CfeFuncR%20type%3D%27table%27%20tableValues%3D%271%200%27%2F%3E%3CfeFuncG%20type%3D%27table%27%20tableValues%3D%271%200%27%2F%3E%3CfeFuncB%20type%3D%27table%27%20tableValues%3D%271%200%27%2F%3E%3C%2FfeComponentTransfer%3E%3C%2Ffilter%3E%0A%3Crect%20width%3D%27620%27%20height%3D%27620%27%20filter%3D%27url%28%23t%29%27%20opacity%3D%270.07%27%2F%3E%3C%2Fsvg%3E");
}
@media (prefers-contrast: more) { body { background-image: none; } }

/* The moderator set is the only one that is a call to action, so it is the
   only one that carries the alarm colour. Clean and unconfirmed are states,
   not warnings — colouring them too would make the whole rail shout. */
.facet a.warn .c { color:var(--alarm); font-weight:600; }
.setpick { border-bottom:1px solid var(--rule); padding-bottom:14px; }

/* Where dealers disagree about the same product. Stated above the table, and
   the columns in question tinted — not the individual cells, because with two
   dealers and two values there is no odd one out to point at. */
.disagree { border-left:3px solid var(--alarm); padding:8px 12px; margin:0 0 12px;
            background:var(--panel); }
.disagree h4 { margin:0 0 6px; font-size:12px; letter-spacing:.02em; }
.disagree p { margin:2px 0; font-size:12px; }
.disagree .claim { display:inline-flex; gap:6px; align-items:baseline; margin:0 4px; }
.disagree .vs { color:var(--muted); font-size:10px; margin:0 4px; }
.agree { color:var(--verdigris); font-size:12px; margin:0 0 12px; }
th.contested, td.contested { background:color-mix(in srgb, var(--alarm) 7%, transparent); }

/* A field whose dealers hold more than one value. The badge carries the count
   so the card says what is wrong, not merely that something is. */
.fieldcell .badge { margin-left:6px; padding:0 5px; border-radius:8px;
  background:color-mix(in srgb, var(--alarm) 14%, transparent);
  color:var(--alarm); font-size:9.5px; letter-spacing:.04em; font-weight:600; }
.fieldcell.conflict { border-color:color-mix(in srgb, var(--alarm) 40%, var(--rule)); }

/* Brands and Manufacturers are one tab. The toggle says which reading you are
   looking at, and is a link pair so the state is visible without opening it. */
.viewtoggle { display:inline-flex; gap:2px; margin:0 0 10px; padding:2px;
  border:1px solid var(--rule); border-radius:7px; background:var(--panel); }
.viewtoggle a { padding:3px 10px; border-radius:5px; font-size:11px;
  color:var(--muted); text-decoration:none; white-space:nowrap; }
.viewtoggle a:hover { color:var(--ink); }
.viewtoggle a.on { background:var(--bg); color:var(--ink); font-weight:600;
  box-shadow:0 1px 2px rgba(0,0,0,.06); }

/* Compact page head: toggle, title, search and ⓘ on one line. The top of a
   screen is overhead — every row it costs is a row of data not shown. */
.pagebar { display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  margin:0 0 8px; }
.pagebar h1 { margin:0; font-size:20px; white-space:nowrap; }
.pagebar .viewtoggle { margin:0; }
.pagebar .bar.inline { margin:0; flex:1 1 260px; }
.pagebar details.info { margin-left:auto; }
.gridnote { margin:0 0 6px; }
.crumb { font-size:11px; color:var(--muted); text-decoration:none; }
.crumb:hover { color:var(--ink); }
.kbd { font-family:var(--mono); font-size:9.5px; border:1px solid var(--rule);
  border-radius:3px; padding:0 3px; }
/* Global trim: these margins were set when pages had fewer controls stacked. */
.pagehead { margin-bottom:8px; }
.bar { margin-bottom:8px; }
.eyebrow { margin-bottom:2px; }

/* The rebuild strip sits in the header beside the title. It reports the state
   of the whole database, not of the current screen, so it belongs with the
   masthead — and as a full-width band it charged every page a row of data to
   say that nothing was waiting. */
header.top .applybar { margin:0 0 0 18px; padding:4px 10px; border-radius:6px;
  font-size:11.5px; gap:8px; border:1px solid var(--rule); background:var(--panel); }
header.top .applybar button { padding:2px 9px; font-size:11px; }
header.top .applybar b { font-weight:600; }

/* One pending product: what it is, what it might already be, and the answers. */
.newprod { border:1px solid var(--rule); border-radius:8px; padding:10px 12px;
  margin:0 0 10px; background:var(--panel); }
.newprod .npnear { margin:8px 0; padding:8px 0 0; border-top:1px solid var(--hair); }
.newprod .npactions { display:flex; gap:8px; align-items:center; flex-wrap:wrap;
  padding-top:8px; border-top:1px solid var(--hair); }
.newprod .mini td { padding:2px 6px 2px 0; }

/* Why a defect-free record is still not clean. Quiet: it is an explanation,
   not a call to action — there is nothing here for a steward to do. */
.corrob { border-left:2px solid var(--rule); padding-left:10px; margin-top:6px; }

/* --------------------------------------------------------------------------
   Sign-in.

   The form must be reachable without scrolling. An earlier version stacked the
   explanation above it and pushed the password field and the Sign in button
   below the fold on a 1280x800 laptop — a returning moderator had to scroll
   past four paragraphs they had already read to do the one thing they came for.

   So it is two columns on a wide screen, form on the right; and on a narrow one
   the form comes first, which is also its order in the source.
   -------------------------------------------------------------------------- */
body.signin { display: grid; place-items: center; min-height: 100vh; }
body.signin main { width: min(62rem, 92vw); padding: 2rem 0; }

.signwrap { display: grid; gap: 3rem; align-items: center;
            grid-template-columns: minmax(0, 1fr) 20rem; }
/* Source order is form-then-prose so the keyboard and a screen reader reach the
   fields first. The grid puts the prose visually left on desktop. */
.signwrap .signcard { grid-column: 2; }
.signwrap .signabout { grid-column: 1; grid-row: 1; }

.signabout .brand { margin-bottom: 1.4rem; }
.signabout h1 { margin: 0 0 .8rem; font-size: 26px; line-height: 1.25; }
.signabout p { margin: 0 0 .7rem; font-size: 13.5px; line-height: 1.6;
               color: var(--muted); max-width: 34rem; }

.signcard { padding: 1.4rem 1.5rem 1.5rem; border-radius: var(--radius);
            background: var(--paper); border: 1px solid var(--rule);
            box-shadow: var(--shadow); }
.signcard h2 { margin: 0 0 1rem; font-size: 17px; }
.signcard label { display: block; margin-bottom: .9rem; font-size: 13px; }
.signcard input[type=text], .signcard input:not([type]),
.signcard input[type=password] { width: 100%; margin-top: .3rem; }
.signcard button { width: 100%; margin-top: .2rem; }
.signcard .warnline { margin: 0 0 .9rem; }
.signcard p { margin: .8rem 0 0; }
.signcard pre { padding: .6rem .7rem; border-radius: 4px; overflow-x: auto;
                background: var(--panel); font-size: 11px; }

@media (max-width: 820px) {
  /* One column, and the form is already first in the source — so it is first
     on screen too, with the explanation underneath for whoever wants it. */
  .signwrap { grid-template-columns: 1fr; gap: 2rem; }
  .signwrap .signcard, .signwrap .signabout { grid-column: 1; grid-row: auto; }
  body.signin { place-items: start center; }
  body.signin main { width: min(26rem, 92vw); }
}

/* The identity control mirrors .elev so the two read as siblings: one says who
   you are, the other says what you are permitted to do right now. */
.who { position: relative; }
.who > summary { list-style: none; cursor: pointer; }
.who > summary::-webkit-details-marker { display: none; }
.whopanel { position: absolute; right: 0; top: 1.8rem; z-index: 40;
            min-width: 15rem; padding: .75rem; border-radius: 6px;
            display: grid; gap: .4rem; text-align: left;
            background: var(--bg, #fff); border: 1px solid var(--line, #ddd);
            box-shadow: 0 6px 20px rgba(0,0,0,.14); }
.whopanel p { margin: 0 0 .2rem; }
.whopanel form { margin: .2rem 0 0; }

/* Users (/admin/users) ------------------------------------------------------

   THE ACCOUNTS LIST IS NOT A TABLE. Seven columns — two of them holding a
   form — do not fit in half of a 1280px window, so the identity columns
   scrolled out of view inside .scroll and the reader was left looking at a
   grid whose first visible column was "May verify". Nothing on this screen is
   compared down a column anyway: an account is read across, one person at a
   time. So each account is a card, and the two things actually changed here —
   the role, and the fields they may verify — sit side by side in it.

   Every column is minmax(_, ...) with a floor well under its share of 1024px,
   and the whole grid collapses to one column on a narrow window: no axis of
   this screen scrolls sideways at any width. */
.roleguide { display:grid; grid-template-columns:repeat(auto-fit,minmax(215px,1fr));
  gap:8px; margin:0 0 14px; align-items:start; }
.rolecard { border:1px solid var(--rule); border-radius:var(--radius);
  background:var(--panel); padding:8px 12px; }
.rolecard h3 { font-size:13.5px; margin:0; display:flex; gap:8px;
  align-items:baseline; justify-content:space-between; }
.rolecard p { margin:0 0 4px; }
/* The sentence and the "opens n of m" disclosure share a line while they fit;
   opened, the screen list takes the width of the card. */
.rolebody { display:flex; flex-wrap:wrap; gap:3px 8px; align-items:baseline; }
.rolebody > details { flex:0 1 auto; }
.rolebody > details[open] { flex:1 1 100%; }
.rolecard summary { display:inline; }
.rolewhat { margin-top:6px; border-top:1px solid var(--rule); padding-top:6px; }
.rolewhat p { margin:0 0 3px; }
.subjectline { margin:0 0 4px; }
.subjectline b { margin-right:3px; }
/* A screen name a super admin can switch. It reads as a line of text until it
   is hovered — a card of 34 buttons would otherwise be louder than the account
   list it sits above — and the box in front of it says which way it is set
   whether or not anybody is pointing at it. */
.pgrant { display:inline; margin:0; }
.tickbtn { font:inherit; font-size:11.5px; line-height:1.5; cursor:pointer;
  background:none; border:1px solid transparent; border-radius:20px;
  padding:0 6px; margin:0 1px 2px 0; color:var(--muted); }
.tickbtn.on { color:var(--ink); }
.tickbtn.on span { color:var(--verdigris); }
.tickbtn:hover { border-color:var(--rule); background:var(--paper); color:var(--ink); }
.tickbtn:disabled { cursor:default; }

.listhead { display:flex; align-items:baseline; gap:8px 16px; margin:0 0 10px;
  flex-wrap:wrap; }
.listhead h2 { margin:0; }
.listhead .caption { flex:1 1 420px; max-width:66ch; margin:0; }
/* Closed it is a link at the end of the heading row; opened it takes a row of
   its own, so the form is as wide as the list it adds to rather than squeezed
   into whatever was left beside the count. */
.addbox { margin-left:auto; }
.addbox[open] { flex:1 1 100%; margin-left:0; }
.addbox > summary { cursor:pointer; }
.addbox .panel { margin-top:10px; }
.addbox .recform { margin-bottom:0; }
.addbox .recform > div { align-items:center; flex-wrap:wrap; }

.accts { display:grid; gap:8px; }
.acct { display:grid; align-items:start; gap:8px 20px;
  grid-template-columns:minmax(190px,1.3fr) minmax(150px,.9fr) minmax(190px,1.4fr) minmax(110px,.6fr);
  border:1px solid var(--rule); border-radius:var(--radius);
  background:var(--paper); box-shadow:var(--shadow); padding:8px 14px; }
@media (max-width:980px) { .acct { grid-template-columns:1fr 1fr; } }
@media (max-width:620px) { .acct { grid-template-columns:1fr; } }
.acct.off { opacity:.62; }
.acct .nameline { display:flex; flex-wrap:wrap; align-items:center; gap:7px; }
.acct .nameline b { font-size:14.5px; }
.acct .fld { min-width:0; display:flex; flex-direction:column; gap:4px;
  align-items:flex-start; }
.acct .fld .eyebrow { display:block; }
.acct .fld p { margin:0; }
.acct .fld select { max-width:100%; font-size:12.5px; padding:4px 7px; }
.acct .caps { display:flex; flex-wrap:wrap; gap:5px; }
.acct .caps form { margin:0; }
/* In flow, not floating: the old "add…" opened an absolutely positioned panel
   over the row beneath it, which put an Allow button on top of somebody else's
   account. Opening it grows the card instead. */
.acct details { width:100%; }
.acct details summary { cursor:pointer; }
.acct details form { display:flex; flex-wrap:wrap; gap:6px; margin-top:6px; }
.acct details input, .acct details select { font-size:12.5px; padding:4px 7px;
  max-width:100%; }
.acct details button { font-size:12px; padding:4px 10px; }
.acct .acts form { margin:0; }
.acct .fixed { font-size:13px; }
.chip.drop { cursor:pointer; }
.chip.drop:hover { border-color:var(--alarm); color:var(--alarm); }

/* What this portal is, said before anyone is asked to sign in to it. Sits
   above the form rather than beside it: at 30rem there is no second column,
   and a moderator on a phone should read the purpose first either way. */
.signin .about { margin: 0 0 1.6rem; }
.signin .about p { margin: 0 0 .7rem; font-size: 13.5px; line-height: 1.55;
                   color: var(--muted); }
.signin .about p b { color: var(--ink); }

/* --------------------------------------------------------------------------
   API reference (/api-docs).

   Public, so it does not get the console chrome — no subject strip, no pending
   -decisions bar, nothing that would query the database for a reader who has
   no account. Its own two-column layout: a sticky contents list that a
   developer scans, and a measured column of prose they read.
   -------------------------------------------------------------------------- */
body.docs { display: block; }
body.docs main { padding: 0; }
.docwrap { display: grid; grid-template-columns: 16rem minmax(0, 1fr);
           gap: 40px; max-width: 68rem; margin: 0 auto; padding: 28px 24px 80px; }

.docnav { position: sticky; top: 24px; align-self: start; display: grid;
          gap: 1px; max-height: calc(100vh - 48px); overflow-y: auto; }
.docnav .brand { margin-bottom: 14px; }
/* The console strip on a page that has no console chrome. Set apart by a rule
   rather than by colour: these links leave the document, and the ones under
   them only move within it. */
/* Pinned to the top of the rail's own scrollport: the rail is taller than the
   window and scrolls inside itself, which took the way out with it. */
.docback { display: grid; gap: 2px; padding-bottom: 10px; margin-bottom: 8px;
  border-bottom: 1px solid var(--rule);
  position: sticky; top: 0; z-index: 1; background: var(--paper); }
.docback.signin { border-bottom: 0; border-top: 1px solid var(--rule);
  margin: 12px 0 0; padding: 10px 0 0; position: static; }
.docback .out { color: var(--accent); font-weight: 500; }
.docback a { padding: 3px 8px; border-radius: 4px; font-size: 13px;
  color: var(--muted); }
.docback a:hover { background: var(--panel); color: var(--ink); text-decoration: none; }
.docnav a { padding: 4px 8px; border-radius: 4px; font-size: 13px;
            text-decoration: none; color: var(--muted); }
.docnav a:hover { background: var(--panel); color: var(--ink); }
.docnav a.grp { margin-top: 12px; font-family: var(--mono); font-size: 10px;
                letter-spacing: .1em; text-transform: uppercase;
                color: var(--muted); pointer-events: none; opacity: .75; }

/* A measured column. Prose set to the full width of a 68rem page is read by
   nobody; code blocks get the whole width because wrapping a curl line is
   worse than a long one. */
.docbody { max-width: 46rem; min-width: 0; }
.docbody h1 { margin: 0 0 8px; }
.docbody h2 { margin: 40px 0 10px; scroll-margin-top: 24px; }
.docbody h2 .verb { font-size: 12px; font-weight: normal; color: var(--muted);
                    margin-left: 8px; white-space: nowrap; }
.docbody p, .docbody li { line-height: 1.6; }
.docbody ul { padding-left: 20px; }
.docbody li { margin-bottom: 6px; }
.docbody hr { border: 0; border-top: 1px solid var(--rule); margin: 44px 0; }
.docbody .lede { font-size: 15px; color: var(--muted); margin-bottom: 28px; }
.docbody .end { margin-top: 48px; }

/* Wide by design, and scrolling inside itself rather than pushing the page
   sideways — a JSON sample is the one thing here that will not fit. */
pre.code { background: var(--panel); border: 1px solid var(--rule);
           border-radius: var(--radius); padding: 12px 14px; overflow-x: auto;
           font-family: var(--mono); font-size: 12px; line-height: 1.55;
           margin: 12px 0 18px; }

table.dt { width: 100%; border-collapse: collapse; font-size: 13px;
           margin: 12px 0 18px; }
table.dt th { text-align: left; font-family: var(--mono); font-size: 10px;
              letter-spacing: .08em; text-transform: uppercase;
              color: var(--muted); border-bottom: 1px solid var(--rule);
              padding: 6px 10px 6px 0; }
table.dt td { border-bottom: 1px solid var(--rule); padding: 8px 10px 8px 0;
              vertical-align: top; line-height: 1.5; }

/* Two weights of aside: something to know, and something that has already gone
   wrong for somebody. */
.docbody .note { border-left: 3px solid var(--rule); background: var(--panel);
                 padding: 10px 14px; margin: 18px 0; font-size: 13px;
                 line-height: 1.55; border-radius: 0 var(--radius) var(--radius) 0; }
.docbody .note.warn { border-left-color: var(--accent); }

@media (max-width: 900px) {
  .docwrap { grid-template-columns: 1fr; gap: 20px; }
  .docnav { position: static; max-height: none;
            grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); }
  .docnav a.grp { display: none; }
}

/* A table's min-content width wins over `width:100%`, so the parameter tables
   pushed the whole page sideways on a phone rather than scrolling. Making the
   table its own scrolling block below the breakpoint keeps the page still —
   measured at 390px, where it overflowed by 15px. */
@media (max-width: 900px) {
  table.dt { display: block; overflow-x: auto; white-space: nowrap; }
  table.dt td, table.dt th { white-space: normal; min-width: 7rem; }
}
.signabout .signlink { margin-top: 1.1rem; }

/* The product photograph, on the left where the eye starts. A recognition aid,
   not the subject of the page — it must not push the fields below the fold. */
.brandshot { float:left; width:140px; margin:0 16px 10px 0; }
.brandshot img { width:100%; height:auto; border:1px solid var(--rule);
  border-radius:var(--radius); background:var(--paper); display:block; }
.brandshot img.candidate { border-style:dashed; opacity:.85; }
.brandshot .shotcap { margin-top:4px; line-height:1.35; }
.brandshot .noshot { border:1px dashed var(--rule); border-radius:var(--radius);
  height:96px; display:grid; place-items:center; background:var(--panel); }
.brandshot .shotform { display:flex; gap:8px; align-items:center; margin-top:6px; }
/* The file input is hidden behind its own label, so the control reads as one
   button rather than a browser's 'Choose file / no file chosen'. */
.shotpick { cursor:pointer; }
/* A dead external URL must not leave a broken-image glyph on the record — but
   the upload control has to survive it, so only the picture is hidden. */
.brandshot.broken img { display:none; }
.brandshot.broken .shotcap { display:none; }
.fieldgrid { overflow:hidden; }
@media (max-width: 900px) { .brandshot { float:none; width:100%; max-width:180px; } }

/* The rows behind a queue count, on hover. Positioned over the page rather than
   in the table, so a popover cannot widen the column it belongs to. */
.molcount { position:relative; }
.molcount .molpop:empty { display:none; }
/* FIXED, not absolute. The queue table lives inside .scroll, which is
   overflow:auto — and an overflow container CLIPS an absolutely positioned
   descendant however high its z-index. The panel kept disappearing behind the
   edge of the table for that reason, not because it was ordered wrongly.
   Fixed positioning leaves the clipping context entirely; the coordinates are
   set from the button's rect when the content arrives. */
.molcount .molpop { position:fixed; z-index:200;
  min-width:420px; max-width:560px; padding:10px 12px; text-align:left;
  border:1px solid var(--rule); border-radius:var(--radius);
  background:var(--paper); box-shadow:var(--shadow); }
.molrows .mini td { padding:2px 8px 2px 0; }
.renameas { display:inline-flex; flex-direction:column; gap:2px; }

/* Old → new on a change row. The field name alone said which field moved and
   not what it moved to, which is the only thing a steward wants from this. */
.wasnow s { color:var(--muted); }
.wasnow { margin-left:6px; }

/* Overview. The work first, then what is held, then the summaries. */
.attention { margin-bottom:20px; }
.attention h2 a { margin-left:10px; font-weight:400; }
.queuegrid { display:grid; gap:10px; grid-template-columns:repeat(auto-fill, minmax(210px, 1fr)); }
.queuecard { display:block; padding:11px 13px; text-decoration:none;
  border:1px solid var(--rule); border-radius:var(--radius); background:var(--panel); }
.queuecard:hover { border-color:var(--muted); }
.queuecard .n { font-family:var(--mono); font-size:22px; line-height:1.1; color:var(--alarm); }
.queuecard .l { font-size:12px; color:var(--ink); margin-top:3px; line-height:1.35; }
/* Nothing waiting is not an alarm, and should not be coloured like one. */
.queuecard.zero .n { color:var(--muted); }
.queuecard.zero { background:transparent; }
.segrow { display:flex; gap:10px; flex-wrap:wrap; }
.segcard { display:flex; flex-direction:column; gap:2px; min-width:132px;
  padding:9px 12px; text-decoration:none; border:1px solid var(--rule);
  border-radius:var(--radius); background:var(--panel); }
.segcard:hover { border-color:var(--muted); }
.segcard b { font-family:var(--mono); font-size:18px; }
.segcard span { font-size:12px; color:var(--muted); }

/* How many ways dealers spell one manufacturer. Folded away in the rail: it is
   evidence the merge rules worked, checked occasionally, never scanned. */
.spellings { margin-top:6px; }
.spellings summary { cursor:pointer; }
.spellings ul { margin:5px 0 0; padding-left:14px; line-height:1.5; }

/* Overview: three lists across, not three grids of cards. A number needs a
   line, not a box the size of a headline — as cards these pushed the dealer
   table off the screen entirely. */
.threeup { display:grid; gap:22px; grid-template-columns:repeat(3, 1fr);
  margin-bottom:20px; align-items:start; }
.threeup h2 { margin:0 0 7px; }
.threeup h2 a { margin-left:8px; font-weight:400; }
.minilist { list-style:none; margin:0; padding:0;
  border:1px solid var(--rule); border-radius:var(--radius); background:var(--panel); }
.minilist li + li { border-top:1px solid var(--hair); }
.minilist a { display:flex; justify-content:space-between; align-items:baseline;
  gap:12px; padding:6px 11px; text-decoration:none; font-size:12.5px; }
.minilist a:hover { background:var(--paper); }
.minilist b { font-family:var(--mono); font-size:14px; color:var(--alarm);
  white-space:nowrap; }
/* Nothing waiting is not an alarm. Counts that are not work are plain ink. */
.minilist b.zero { color:var(--muted); }
.threeup section:not(:nth-child(2)) .minilist b { color:var(--ink); }
@media (max-width: 1100px) { .threeup { grid-template-columns:1fr 1fr; } }
@media (max-width: 720px)  { .threeup { grid-template-columns:1fr; } }

/* Defect filters. Chips rather than a select: which defect you are working is
   the shape of the session, and the counts are the reason you pick one. */
.facetrow { display:flex; gap:6px; flex-wrap:wrap; margin:0 0 10px; }
.chip { padding:3px 10px; border:1px solid var(--rule); border-radius:20px;
  font-size:11.5px; text-decoration:none; color:var(--muted); background:var(--panel); }
.chip:hover { color:var(--ink); border-color:var(--muted); }
.chip.on { background:var(--ink); color:var(--paper); border-color:var(--ink); }
.chip .c { font-family:var(--mono); margin-left:4px; }

/* The profile menu. Appearance and elevation moved inside it, so it is a panel
   with sections rather than a list of links. */
.whorow { display:flex; justify-content:space-between; align-items:baseline;
  gap:12px; padding:6px 0; border-top:1px solid var(--hair); }
.whosec { padding:8px 0; border-top:1px solid var(--hair); }
.whosec .elevform input[type=password] { width:100%; margin:4px 0 6px; }
.who summary .rolechip.tiny { font-size:9.5px; margin-left:4px; }

/* Why a brand is in the moderator queue. Stated on the record, because the
   queue that put it there is a different screen. */
.blocking { border-left:3px solid var(--alarm); padding-left:10px; margin-top:8px; }
.blocking a { text-decoration:underline; }

/* What a flagged cluster actually disagrees about. Beneath the reason, because
   naming the two values is what tells you whether to fix or confirm. */
.clusterwhy { border-left:3px solid var(--rule); padding:2px 0 2px 10px;
  margin:4px 0 0; line-height:1.6; }
.clusterwhy .claim { display:inline-flex; gap:6px; margin:0 4px; }
.clusterwhy .vs { color:var(--muted); font-size:10px; }

/* The strength of one active, corrected where it is read. Its own labelled row
   rather than a bare box beside the name: a number with no label next to a
   number is not a control, it is a second copy of the value. */
.strength { margin:6px 0 2px; }
.strength .srow { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
/* The label takes the whole line, so the wrap happens where it was intended
   and the box and its button stay together rather than the button dropping
   away from the number it saves. */
.strength label { flex-basis:100%; font-size:11px; letter-spacing:.04em;
                  text-transform:uppercase; color:var(--dim); }
.strength .sfield { display:inline-flex; align-items:baseline; gap:2px; color:var(--fg); }
.strength .sfield input { width:5.5em; padding:2px 6px; font-size:12.5px; }
.strength button { padding:3px 12px; font-size:12px; }
.strength .spreview { margin:6px 0 0; line-height:1.5; }
.strength .spreview .out { color:var(--fg); }

/* A suggestion drawn from the reference that does not cover this row's segment
   keeps its checkbox and is skipped by "select all". That used to be marked
   with a dashed outline on the box, which reads as a rendering fault rather
   than as meaning — the bulk bar says it in words now, and the row names the
   reference beside the suggestion. Nothing is left to decode.

   The note sits on its own line when the bar runs out of room, rather than
   squeezing the controls. */
.bulkbar .skipnote { flex-basis: 100%; line-height: 1.5; }

/* Evidence the directory already holds for a category decision. Sits under the
   "filed as" cell, because it is about the same question: what this is. */
.suggestion { margin-top: 5px; display: flex; gap: 6px; align-items: baseline;
  flex-wrap: wrap; }

/* The pack label and the leaflet, beside the record they describe. Two slots
   side by side because they are a pair — a product has one of each, and an
   empty slot is the prompt to go and photograph it. */
.proddocs { display:grid; grid-template-columns:1fr 1fr; gap:14px; margin:16px 0 4px; }
@media (max-width:760px) { .proddocs { grid-template-columns:1fr; } }
.docslot { border:1px solid var(--line); border-radius:var(--radius); padding:9px 11px; }
.docrow { display:flex; gap:7px; align-items:baseline; flex-wrap:wrap;
  padding:3px 0; border-bottom:1px dotted var(--line); }
.docrow:last-of-type { border-bottom:0; }
.docrow form { display:inline; }
.docup { display:flex; gap:6px; align-items:center; margin-top:7px; flex-wrap:wrap; }
.docup input[type=file] { font-size:11px; max-width:100%; }
.docup button { padding:3px 11px; font-size:12px; }

/* REVIEW: queues down the side, the work filling the rest.
   The six queues were a horizontal strip beneath a page heading, which spent
   two rows of height on every review screen and put the queue you are NOT
   working on directly above the rows you are. In a column they cost no height,
   the counts line up as a readable backlog, and the table starts at the top. */
.reviewlayout { display:grid; grid-template-columns:182px 1fr; gap:22px;
  align-items:start; }
.reviewlayout > * { min-width:0; }
@media (max-width:900px) { .reviewlayout { grid-template-columns:1fr; } }

.queuerail { display:flex; flex-direction:column; gap:1px; position:sticky; top:12px; }
.queuerail a { display:flex; justify-content:space-between; align-items:baseline;
  gap:8px; padding:6px 9px; border-radius:var(--radius); font-size:13px;
  color:var(--muted); }
.queuerail a:hover { background:var(--panel); color:var(--ink); text-decoration:none; }
.queuerail a.on { background:var(--ink); color:var(--paper); font-weight:600; }
.queuerail a .c { font-family:var(--mono); font-size:11px; opacity:.85; }
@media (max-width:900px) {
  .queuerail { flex-direction:row; flex-wrap:wrap; position:static; }
}

/* The search box and the page's own help sit with the data, not with the
   navigation — what you are searching is on the right. */
.reviewbar { display:flex; gap:9px; align-items:center; flex-wrap:wrap;
  margin-bottom:12px; }
.reviewbar input[type=search] { flex:1; min-width:200px; }

/* The filter rail: queues, then search, then what to show. One column for
   everything that narrows the list, because three places to look for "how do I
   see less of this" is two too many. */
.filterrail { display:flex; flex-direction:column; gap:16px; position:sticky; top:12px; }
.railsec h3 { font-family:var(--mono); font-size:10px; letter-spacing:.12em;
  text-transform:uppercase; color:var(--muted); margin:0 0 5px; font-weight:600; }
/* min-width:0 overrides the global `input[type=search] { min-width:220px }`,
   which is wider than this 182px rail: the box ran out of its column and over
   the first column of the grid. border-box so padding does not add to the
   100% either. */
.railsec input[type=search], .railsec select { width:100%; min-width:0;
  max-width:100%; box-sizing:border-box; }
.filterrail, .railsec { min-width:0; }
@media (max-width:900px) {
  .filterrail { position:static; flex-direction:row; flex-wrap:wrap; align-items:flex-end; }
  .railsec { flex:1; min-width:160px; }
}

/* Segment tabs, directly above the grid: the filter and the answer to "where
   is the work" in the same control. */
.segtabs { display:flex; gap:3px; flex-wrap:wrap; margin-bottom:10px;
  border-bottom:1px solid var(--line); }
.segtabs a,
.segtabs button { background:none; border:0; border-bottom:2px solid transparent;
  padding:5px 11px; margin-bottom:-1px; border-radius:0; font-size:13px;
  color:var(--muted); cursor:pointer; display:flex; gap:6px; align-items:baseline; }
.segtabs a:hover,
.segtabs button:hover { color:var(--ink); text-decoration:none; }
.segtabs a.on,
.segtabs button.on { color:var(--ink); border-bottom-color:var(--ink); font-weight:600; }
.segtabs a .c,
.segtabs button .c { font-family:var(--mono); font-size:11px; opacity:.7; }

/* The tabs and the bulk controls on one line. Stacked, they put 139px between
   the top of the working area and the first row of work — two full-width bars
   to say "which segment" and "act on the selection". */
.gridtop { display:flex; gap:16px; align-items:flex-end; justify-content:space-between;
  flex-wrap:wrap; margin-bottom:10px; border-bottom:1px solid var(--line); }
.gridtop .segtabs { border-bottom:0; margin-bottom:0; }
.gridtop .bulkbar { display:flex; gap:10px; align-items:center; flex-wrap:wrap;
  background:none; border:0; padding:0 0 6px; margin:0; }
.gridnote { margin:0 0 9px; line-height:1.5; }

/* Publishing in progress: a small breathing dot rather than a spinner — it is
   background work the steward need not watch. */
.applybar .pulse { width:7px; height:7px; border-radius:50%; background:var(--accent);
  display:inline-block; animation:agpulse 1.4s ease-in-out infinite; }
@keyframes agpulse { 0%,100% { opacity:.25; } 50% { opacity:1; } }
@media (prefers-reduced-motion: reduce) { .applybar .pulse { animation:none; } }

/* Contribute data: one column a person fills top to bottom, not a grid of
   fields to hunt through. */
.contribform { display:flex; flex-direction:column; gap:14px; max-width:620px; }
.contribform label { display:flex; flex-direction:column; gap:5px; font-size:13px; }
.contribform label.inline { flex-direction:row; align-items:center; gap:8px; }
.contribform fieldset { border:1px solid var(--rule); border-radius:var(--radius);
  padding:10px 14px; margin:0; display:flex; flex-direction:column; gap:7px; }
.contribform legend { font-size:12.5px; color:var(--muted); padding:0 5px; }
.contribform input[type=url], .contribform input[name] { min-width:0; max-width:100%; box-sizing:border-box; }
.contribform input[type=radio] { min-width:auto; }
.contribform button { align-self:flex-start; padding:8px 22px; }
.contriberr { border:1px solid var(--alarm); border-radius:var(--radius);
  padding:9px 12px; max-width:620px; }
.thanks { max-width:560px; margin:40px auto; text-align:center; }
.thanks h1 { margin:10px 0 8px; }
.thanksmark { width:48px; height:48px; line-height:48px; margin:0 auto; border-radius:50%;
  font-size:24px; color:var(--paper); background:var(--verdigris, var(--accent)); }
.thanksact { display:flex; gap:10px; justify-content:center; flex-wrap:wrap; margin-top:18px; }

/* More: the steward's instruments, behind one tab. Opens on hover for a mouse,
   and on a tap or Enter (base.html) — a menu that needs hover is a menu a
   phone cannot open. */
nav.top .navmore { position:relative; display:flex; }
nav.top .navmore > button { background:none; border:0; border-bottom:2px solid transparent;
  margin-bottom:-1px; padding:11px 12px; font:inherit; font-size:13px; color:var(--muted);
  cursor:pointer; border-radius:0; }
nav.top .navmore > button.on { color:var(--ink); border-bottom-color:var(--accent); font-weight:500; }
nav.top .navmore > button:hover { color:var(--ink); }
nav.top .navmenu { display:none; position:absolute; top:100%; left:0; min-width:180px;
  flex-direction:column; padding:5px; background:var(--paper); border:1px solid var(--rule);
  border-radius:var(--radius); box-shadow:0 8px 24px rgba(0,0,0,.12); z-index:30; }
nav.top .navmore:hover .navmenu,
nav.top .navmore.open .navmenu { display:flex; }
nav.top .navmenu a { border-bottom:0; margin:0; padding:8px 11px; border-radius:5px; }
nav.top .navmenu a:hover { background:var(--panel); border-bottom:0; }
nav.top .navmenu a.on { background:var(--panel); }

/* Knowledge facts: the statement is the thing being judged, so it gets the
   width; three lines show, focus or hover reveals the rest in place. */
table.facts td.factval { min-width:280px; max-width:560px; }
.factclamp { display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical;
  overflow:hidden; line-height:1.45; font-size:13px; }
.factclamp:hover, .factclamp:focus { -webkit-line-clamp:unset; outline:none; }
table.facts td.factact { white-space:nowrap; min-width:150px; }
table.facts td.factact form { display:inline; margin:0; }
table.facts tr.decided td { opacity:.8; }
.rejectbox { display:inline-block; margin-left:6px; vertical-align:middle; }
.rejectbox summary { cursor:pointer; font-size:12px; color:var(--muted); list-style:none; }
.rejectbox summary::-webkit-details-marker { display:none; }
.rejectbox[open] form { display:flex !important; flex-direction:column; gap:5px; margin-top:6px;
  white-space:normal; }
.rejectbox select, .rejectbox input { min-width:0; max-width:220px; font-size:12px; }
.factgroup { margin:0 0 14px; max-width:80ch; }
.factgroup h3 { font-size:14px; margin:0 0 4px; }
.factgroup ul { margin:0; padding-left:18px; }
.factgroup li { margin:0 0 5px; line-height:1.5; }
.bulkbar select[form=kbulk] { width:auto; max-width:220px; min-width:0; }
.editbox, .origbox { margin-top:4px; }
.editbox summary, .origbox summary { cursor:pointer; color:var(--muted); list-style:none; }
.editbox summary::-webkit-details-marker, .origbox summary::-webkit-details-marker { display:none; }
.editbox textarea { width:100%; box-sizing:border-box; font:inherit; font-size:13px;
  margin-top:5px; min-width:0; }
.editbtns { display:flex; gap:6px; margin-top:5px; }

/* Image review: cards, so a moderator compares a subject's candidates side by
   side; the picture is what is judged, so it leads. */
.imggrid { display:grid; grid-template-columns:repeat(auto-fill, minmax(230px, 1fr)); gap:14px; }
.imgcard { border:1px solid var(--rule); border-radius:var(--radius); background:var(--paper);
  display:flex; flex-direction:column; min-width:0; overflow:hidden; }
.imgcard.primary { border-color:var(--verdigris); }
.imgcard.decided { opacity:.85; }
.imgwrap { position:relative; aspect-ratio:4/3; background:var(--panel); max-width:100%; }
.imgwrap img { width:100%; height:100%; object-fit:cover; display:block; }
.imgwrap input[type=checkbox] { position:absolute; top:8px; left:8px; width:18px; height:18px; z-index:1; }
.imgwrap .mainpill { position:absolute; top:8px; right:8px; }
.imgbroken { display:none; position:absolute; inset:0; padding:14px; color:var(--alarm); }
.imgcard.broken .imgwrap img { visibility:hidden; }
.imgcard.broken .imgbroken { display:block; }
.imgbody { padding:9px 11px 11px; display:flex; flex-direction:column; gap:5px; min-width:0; }
.imgcap { display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.imgsrc { overflow-wrap:anywhere; }
.imgact { display:flex; flex-wrap:wrap; gap:6px; align-items:center; }
.imgact form { display:flex; gap:6px; margin:0; flex-wrap:wrap; }
.imgact button { padding:4px 10px; font-size:12px; }
.imgcard .editbox label { display:flex; flex-direction:column; gap:3px; margin-top:5px; }
.imgcard .editbox input, .imgcard .editbox select { min-width:0; width:100%; box-sizing:border-box; font-size:12px; }
.bulkbar select[form=ibulk] { width:auto; max-width:220px; min-width:0; }
table.names td { vertical-align:top; }
/* A name in its own script reads at a size its script needs (Telugu, Tamil). */
.localname { font-size:17px; font-weight:600; line-height:1.3; }
.nameadd, .namealias { display:flex; flex-wrap:wrap; gap:5px; margin:0; align-items:center; }
.nameadd input, .nameadd select, .namealias select { min-width:0; max-width:190px; font-size:12px; }
.harvestbox { margin:0 0 12px; font-size:13px; }
.harvestbox:empty { display:none; }
.harvestbox form { display:flex; gap:8px; align-items:center; margin:0; }
.harvestbox .applybar { display:inline; padding:0; border:0; background:none; }

/* Entity pages: the text and the picture side by side, stacking when narrow. */
.entityhead { display:grid; grid-template-columns:minmax(0, 1fr) minmax(0, 380px); gap:24px;
  align-items:start; margin-bottom:10px; }
.entityhead > * { min-width:0; }
@media (max-width: 860px) { .entityhead { grid-template-columns:minmax(0, 1fr); } }
.titlerow { display:flex; gap:12px; align-items:center; flex-wrap:wrap; }
.titlerow h1 { margin:0 0 4px; }
.gallery { display:flex; flex-direction:column; gap:8px; }
.gallery figure { margin:0; }
.gallead img { width:100%; max-width:100%; aspect-ratio:4/3; object-fit:cover; border-radius:var(--radius);
  border:1px solid var(--rule); display:block; }
.galstrip { display:grid; grid-template-columns:repeat(auto-fill, minmax(84px, 1fr)); gap:6px; }
.galstrip img { width:100%; aspect-ratio:1; object-fit:cover; border-radius:5px; border:1px solid var(--rule); display:block; }
.galstrip figcaption { display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.nopic { margin:6px 0; }
img.thumb, span.thumb { width:40px; height:40px; border-radius:5px; object-fit:cover; display:block;
  border:1px solid var(--rule); background:var(--panel); }
span.thumb.none { border-style:dashed; opacity:.5; }
table.withthumbs td:first-child { width:44px; padding-right:0; }
.brandchips { display:flex; flex-wrap:wrap; gap:4px; margin-top:4px; }
.chip { font-size:11.5px; padding:1px 7px; border:1px solid var(--rule); border-radius:10px; }
.factctx { font-weight:500; margin-right:4px; }

/* Readiness: one row per crop × problem, a mark per check. */
.readysum { display:flex; gap:10px; flex-wrap:wrap; }
.readysum .stat { min-width:120px; }
table.readiness th.chk, table.readiness td.chk { text-align:center; font-size:12px; }
table.readiness td.chk .tiny { text-align:left; max-width:160px; }
.mark { font-size:14px; font-weight:600; }
.mark.ok { color:var(--verdigris); }
.mark.rev { color:var(--focus); }
.mark.no { color:var(--alarm); opacity:.7; }

/* coverage and quality (Phase 7) ------------------------------------------ */
tr.grouprow th { background:var(--panel); font-family:var(--mono); font-size:10.5px; letter-spacing:.06em;
  text-transform:uppercase; color:var(--muted); font-weight:600; padding:5px 10px; }
table.coverage .expwhy { max-width:80ch; margin-top:1px; display:-webkit-box; -webkit-line-clamp:1; -webkit-box-orient:vertical; overflow:hidden; }
table.coverage tr:hover .expwhy { -webkit-line-clamp:unset; }
.covbar { display:flex; height:10px; border-radius:2px; overflow:hidden; background:var(--hair); min-width:90px; }
.covbar span { display:block; min-width:2px; }
.covbar .m { background:var(--verdigris); }
.covbar .p { background:color-mix(in srgb, var(--accent) 55%, var(--paper)); }
.covbar .x { background:color-mix(in srgb, var(--alarm) 22%, var(--paper)); }
.covfilter { display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin:6px 0 4px; }
.covfilter input[type=search] { flex:1 1 180px; max-width:320px; }
.segs { display:flex; gap:4px; flex-wrap:wrap; }
.segs a { padding:4px 10px; border:1px solid var(--rule); border-radius:20px; font-size:12.5px; color:var(--muted); }
.segs a.on { color:var(--ink); border-color:var(--accent); font-weight:600; }
.segs .c { font-family:var(--mono); font-size:11px; font-variant-numeric:tabular-nums; margin-left:3px; }
details.exempt summary { cursor:pointer; color:var(--muted); font-size:12px; }
details.exempt form { display:flex; gap:6px; flex-wrap:wrap; align-items:center; margin-top:4px; }
details.exempt input[type=text] { flex:1 1 220px; min-width:0; }
.qfactors { display:grid; grid-template-columns:repeat(auto-fit, minmax(170px, 1fr)); gap:10px; margin:0 0 14px; }
.qfactor { border:1px solid var(--rule); border-radius:var(--radius); padding:9px 12px; background:var(--panel); min-width:0; }
.qfactor h3 { margin:0 0 4px; font-family:var(--mono); font-size:10.5px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--muted); font-weight:600; }
.qfactor p { margin:0 0 2px; }
.qfactor .big { font-size:13px; color:var(--muted); }
.qfactor .big b { font-family:var(--serif); font-size:22px; color:var(--ink); font-weight:500; font-variant-numeric:tabular-nums; }
table.checklist tr.na td { color:var(--muted); }
table.checklist tr.na a { color:var(--muted); }
.tbars { display:flex; align-items:flex-end; gap:3px; height:30px; }
.tbars span { width:11px; background:var(--verdigris); border-radius:1px 1px 0 0; }
.tbars span.z { background:var(--rule); }
.tbars span:last-child { background:var(--accent); }
.tbars span.z:last-child { background:var(--rule); }

/* phenology authoring and review (057) ------------------------------------ */
.addfrom { margin:0 0 10px; color:var(--muted); }
.addfrom a { color:var(--accent); }
.formerr { border:1px solid var(--alarm); color:var(--alarm); border-radius:var(--radius); padding:8px 12px; margin:0 0 12px; max-width:90ch; }
.phchooser { display:flex; flex-wrap:wrap; gap:6px 12px; align-items:center; margin:0 0 14px; padding:10px 12px;
  background:var(--panel); border:1px solid var(--rule); border-radius:var(--radius); }
.phchooser label { font-size:12px; color:var(--muted); }
.phchooser select { max-width:100%; }
.phform fieldset { border:1px solid var(--rule); border-radius:var(--radius); margin:0 0 14px; padding:10px 14px 12px; min-width:0; }
.phform legend { font-family:var(--mono); font-size:10.5px; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); padding:0 6px; }
.phgrid { display:grid; grid-template-columns:repeat(auto-fill, minmax(200px, 1fr)); gap:10px 14px; }
.phgrid > div { display:flex; flex-direction:column; gap:3px; min-width:0; }
.phgrid .wide { grid-column:1 / -1; }
.phgrid label { font-size:12px; color:var(--muted); }
.phgrid input, .phgrid select, .phgrid textarea { width:100%; min-width:0; }
.phgrid p { margin:2px 0 0; }
table.phnums input, table.phnums select { width:100%; min-width:60px; }
.phpreview { margin-top:12px; }
.phpreview h3 { margin:0 0 6px; font-size:14px; }
.phactions { display:flex; gap:8px; flex-wrap:wrap; margin:0 0 24px; }
article.phrow { border:1px solid var(--rule); border-radius:var(--radius); margin:0 0 12px; background:var(--paper); }
article.phrow header { display:flex; justify-content:space-between; gap:10px; align-items:flex-start; padding:9px 14px;
  border-bottom:1px solid var(--hair); background:var(--panel); }
article.phrow h3 { margin:0; font-size:15px; }
article.phrow header p { margin:1px 0 0; }
.phbody { display:grid; grid-template-columns:minmax(0, 1fr) minmax(0, 1.4fr) minmax(0, .8fr); gap:14px; padding:10px 14px; }
@media (max-width:1100px) { .phbody { grid-template-columns:1fr; } }
.phbody h4 { margin:0 0 4px; font-family:var(--mono); font-size:10.5px; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
.phbody p { margin:0 0 4px; }
.phsource blockquote { margin:6px 0 0; padding:6px 10px; border-left:3px solid var(--rule); font-size:12.5px; color:var(--ink); background:var(--panel); }
table.phmini { width:100%; font-size:12.5px; margin:0 0 6px; }
table.phmini td, table.phmini th { padding:3px 6px; }
.phbtns { display:flex; flex-direction:column; gap:5px; align-items:flex-start; }
.phbtns button[disabled] { opacity:.5; cursor:not-allowed; }
.phgrid input[type=text], .phgrid input:not([type]), .phgrid textarea, table.phnums input { padding:7px 9px; font-size:13px; }
.phsource blockquote { white-space:pre-line; max-height:22em; overflow:auto; }
.stagechip { white-space:nowrap; }
/* dealer changes (060) */
.dealerchange table.dcdiff { margin:6px 0 8px; max-width:720px; }
.dealerchange .dcactions { display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
.newprod.decided { opacity:.8; }

/* /api-docs dealer flow map */
.flowmap { margin:14px 0 22px; display:flex; flex-direction:column; gap:4px; }
.flowmap .lane { border:1px solid var(--rule); border-radius:var(--radius); padding:10px 12px 12px; background:var(--panel); }
.flowmap h3 { margin:0 0 8px; font-size:14px; display:flex; gap:8px; align-items:center; }
.flowmap h3 .n { display:inline-grid; place-items:center; width:22px; height:22px; border-radius:50%; background:var(--accent); color:var(--paper); font-size:12px; }
.flowmap .steps { display:flex; flex-wrap:wrap; gap:8px; align-items:flex-start; }
.flowmap .step { background:var(--paper); border:1px solid var(--rule); border-radius:var(--radius); padding:6px 9px; display:flex; flex-direction:column; gap:3px; min-width:0; max-width:15rem; font-size:12.5px; }
.flowmap .step code { font-family:var(--mono); font-size:11px; color:var(--accent); overflow-wrap:anywhere; }
.flowmap .step small { color:var(--muted); font-size:11.5px; line-height:1.35; }
.flowmap .step.ok { border-left:3px solid var(--verdigris); }
.flowmap .step.warn { border-left:3px solid var(--accent); }
.flowmap .step.new { border-left:3px solid var(--muted); }
.flowmap .split { display:flex; flex-direction:column; gap:6px; }
.flowmap .arrow { align-self:center; color:var(--muted); font-size:18px; }
.flowmap .down { text-align:center; color:var(--muted); font-size:12px; }
/* page access (061) */
table.access td, table.access th { vertical-align:top; }
.linkbtn.open { color:var(--verdigris); font-weight:600; }
.linkbtn.closed { color:var(--muted); }

/* reported wrong (064) --------------------------------------------------- */
/* An open report is the loudest thing on a record: somebody says it is wrong
   and a farmer may act on it. Settled reports fold away. */
.flagblock { display:flex; flex-direction:column; gap:6px; margin:0 0 12px; }
.flagblock.reported { border-left:3px solid var(--alarm); padding:8px 0 8px 10px;
  background:color-mix(in srgb, var(--alarm) 6%, transparent); border-radius:0 var(--radius) var(--radius) 0; }
.flagline { display:flex; flex-wrap:wrap; gap:4px 10px; align-items:baseline; }
.says { font-style:italic; }
.says.big { margin:0 0 3px; font-size:15px; }
.flagpast summary { cursor:pointer; }
.flagform summary { cursor:pointer; font-size:12px; color:var(--muted); }
.flagform[open] form { display:flex; gap:6px; align-items:center; flex-wrap:wrap; margin-top:6px; }
.flagform input[name=remarks] { min-width:min(100%, 26rem); flex:1 1 20rem; font-size:13px; }
.flagcard .dcactions form { display:flex; gap:6px; align-items:center; flex-wrap:wrap; }
.flagcard .dcactions input[name=note] { flex:1 1 20rem; min-width:min(100%, 18rem); font-size:13px; }
.flagcard.settled { opacity:.75; }
.flagcard:not(.settled) { border-left:3px solid var(--alarm); }

/* one brand, two ways of measuring a pack (065) ---------------------------- */
/* Its own colour, not warn and not bad: this is a question for a person, and
   it must not read as the same thing as a missing field or a locked record.
   Never colour alone — every mark here carries a word and a title too. */
.pill.unitmix { color:#7A5AA6; }
:root[data-theme="dark"] .pill.unitmix { color:#B49BDC; }
.unitmixnote { margin:0 0 12px; padding:8px 10px; font-size:13px;
  border-left:3px solid #7A5AA6; border-radius:0 var(--radius) var(--radius) 0;
  background:color-mix(in srgb, #7A5AA6 7%, transparent);
  display:flex; gap:8px; align-items:baseline; flex-wrap:wrap; }
:root[data-theme="dark"] .unitmixnote { border-left-color:#B49BDC;
  background:color-mix(in srgb, #B49BDC 10%, transparent); }
.unitmixnote .info { margin:0; }
.umchip { font-family:var(--mono); font-size:9.5px; letter-spacing:.06em;
  text-transform:uppercase; padding:1px 5px; border-radius:3px; margin-left:5px;
  border:1px solid color-mix(in srgb, currentColor 35%, transparent);
  background:color-mix(in srgb, currentColor 10%, transparent); white-space:nowrap; }
.umchip.mass { color:#7A5AA6; }
.umchip.vol { color:#1F6F8B; }
:root[data-theme="dark"] .umchip.mass { color:#B49BDC; }
:root[data-theme="dark"] .umchip.vol { color:#7FC4DE; }

/* uploads waiting for a person (067) -------------------------------------- */
.upcard { display:flex; gap:12px; align-items:flex-start; border:1px solid var(--rule);
  border-radius:8px; padding:10px 12px; margin:0 0 10px; background:var(--panel); }
.upcard:not(.settled) { border-left:3px solid var(--accent); }
.upcard.settled { opacity:.75; }
.upshot { flex:0 0 160px; min-height:90px; display:grid; place-items:center;
  background:var(--panel2); border-radius:var(--radius); overflow:hidden; }
.upshot img { max-width:160px; max-height:160px; display:block; }
.upmeta { flex:1 1 20rem; min-width:0; display:flex; flex-direction:column; gap:4px; }
.upmeta .dcactions { display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-top:4px; }
.upmeta .dcactions form { display:flex; gap:6px; align-items:center; }
.upmeta input[name=reason] { flex:1 1 16rem; min-width:min(100%, 14rem); font-size:13px; }
.docrow.waitingfile { border-left:2px solid var(--accent); padding-left:6px; }
/* a rail section whose choices are links rather than a select */
.railsec.raillinks a { display:block; padding:3px 0; color:var(--muted); font-size:13px; }
.railsec.raillinks a.on { color:var(--ink); font-weight:600; }
.morefields summary { cursor:pointer; font-size:13px; color:var(--muted); margin:6px 0 2px; }
.morefields[open] summary { margin-bottom:8px; }
.flagdecide { display:flex; gap:6px; align-items:center; flex-wrap:wrap; margin:4px 0 2px; }
.flagdecide input[name=note] { flex:1 1 22rem; min-width:min(100%, 16rem); font-size:13px; }
.flagcard .dcactions { display:flex; gap:10px; align-items:baseline; flex-wrap:wrap; }

/* separating packs into another product (split) --------------------------- */
.splitbar { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin:8px 0 0; }
.splitbar input[name=reason] { flex:1 1 26rem; min-width:min(100%, 18rem); font-size:13px; }
.splitnote { border-left:3px solid var(--accent); padding:6px 10px; margin:0 0 8px;
  background:color-mix(in srgb, var(--accent) 7%, transparent);
  border-radius:0 var(--radius) var(--radius) 0; }
tr.splitrow { opacity:.6; text-decoration:line-through; }
tr.splitrow a, tr.splitrow button { text-decoration:none; }

/* suggestions from the standard data (068) -------------------------------- */
.sugcard { border:1px solid var(--rule); border-left:3px solid var(--verdigris);
  border-radius:8px; padding:10px 12px; margin:0 0 10px; background:var(--panel); }
.sugcard.contested { border-left-color:var(--accent); }
.sugcard.settled { opacity:.7; border-left-color:var(--rule); }
.sugmain { display:flex; gap:18px; flex-wrap:wrap; align-items:flex-start; }
.sugwhat { flex:1 1 22rem; min-width:0; }
.sugvals { display:flex; gap:8px; align-items:baseline; font-size:15px; margin:2px 0 2px; }
.sugvals .was { color:var(--muted); text-decoration:line-through; }
.sugvals .arrow { color:var(--muted); }
.sugwho { flex:1 1 24rem; min-width:0; list-style:none; margin:0; padding:0;
  display:flex; flex-direction:column; gap:4px; }
.sugwho li { font-size:12.5px; border-left:2px solid var(--rule); padding-left:8px; }
.sugwho li.tier1 { border-left-color:var(--verdigris); }
.sugwho li.tier2 { border-left-color:var(--accent); }
.sugwho li.tier3, .sugwho li.tier4 { border-left-color:var(--muted); }
.sugcard .dcactions { margin-top:6px; }
.sugcard .dcactions form { display:flex; gap:6px; align-items:center; flex-wrap:wrap; }
.sugcard input[name=note] { flex:1 1 18rem; min-width:min(100%, 14rem); font-size:13px; }
.bulkaccept { margin-left:auto; }
