:root {
  /* Organic Guardians: deep pine green from the wordmark, warm paper, white cards.
     Red is kept for two jobs — withdrawal warnings, and a form refusing to save. */
  --pine: #175243;           /* brand green */
  --pine-deep: #0F3D31;      /* sidebar/hero depths */
  --pine-soft: #1C5F4E;      /* hovers on green */
  --pine-tint: #E3EDE4;      /* green-tinted wells */
  --page: #F8F4EB;           /* warm paper */
  --panel: #175243;          /* sidebar */
  --inset: #F2EDE1;          /* table headers, wells */
  --card: #FFFFFF;
  --offset: #F2EDE1;
  --offset-deep: #E9E2D2;
  --line: #E4DCCB;
  --line-soft: #EDE7D9;
  --ink: #1E2B26;            /* green-black */
  --ink-2: #64726B;
  --ink-3: #98A49D;
  --cream: #FAF6ED;          /* text on green */
  --red: #C43717;            /* the withdrawal stamp — alerts only */
  --red-soft: #D33030;
  --red-tint: #F6E3DB;
  --sage: #DCE8DC;
  --sage-ink: #2F5D46;
  --terra: #E2976E;
  --terra-tint: #F4E4D3;
  --terra-ink: #8F5B33;
  --ochre: #C77E2F;          /* the statement-band block colour */
  --ochre-ink: #123528;      /* deep green text on ochre */
  --btn: #175243;
  --btn-hi: #0F3D31;
  --r-card: 16px;
  --r-ctl: 10px;
  --r-pill: 999px;
  --font-display: "Fraunces", Georgia, serif;
  --font-ui: "Inter", -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", Courier, monospace;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font: 400 14.5px/1.62 var(--font-ui);
  background: var(--page);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}
::selection { background: #D8E6D9; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: #C9C0AC; border-radius: 99px; }
::-webkit-scrollbar-track { background: transparent; }

/* ---------- back lights: a slow warm wash, barely there ---------- */
.lights { position: fixed; inset: 0; z-index: -2; background: var(--page); overflow: hidden; }
.lights > div { position: absolute; border-radius: 50%; will-change: transform, opacity; }
.beam {
  width: 1200px; height: 800px; top: -420px; left: 50%; margin-left: -600px;
  background: radial-gradient(closest-side, rgba(255, 255, 255, 0.9), transparent 70%);
  filter: blur(60px);
  animation: pulse 18s ease-in-out infinite alternate;
}
.orb-a {
  width: 760px; height: 760px; top: -140px; left: -260px;
  background: radial-gradient(closest-side, rgba(23, 82, 67, 0.10), transparent 70%);
  filter: blur(80px);
  animation: drift-a 55s ease-in-out infinite alternate;
}
.orb-b {
  width: 680px; height: 680px; top: 34%; right: -280px;
  background: radial-gradient(closest-side, rgba(220, 232, 220, 0.5), transparent 70%);
  filter: blur(85px);
  animation: drift-b 70s ease-in-out infinite alternate;
}
.orb-c {
  width: 560px; height: 560px; bottom: -260px; left: 22%;
  background: radial-gradient(closest-side, rgba(226, 151, 110, 0.12), transparent 70%);
  filter: blur(85px);
  animation: drift-c 84s ease-in-out infinite alternate;
}
@keyframes pulse   { from { opacity: 0.7; transform: scale(1); } to { opacity: 1; transform: scale(1.05); } }
@keyframes drift-a { from { transform: translate3d(0,0,0) scale(1); } to { transform: translate3d(150px, 110px, 0) scale(1.12); } }
@keyframes drift-b { from { transform: translate3d(0,0,0) scale(1); } to { transform: translate3d(-160px, -120px, 0) scale(1.08); } }
@keyframes drift-c { from { transform: translate3d(0,0,0) scale(1.04); } to { transform: translate3d(130px, -100px, 0) scale(0.96); } }

/* paper grain */
.grain {
  position: fixed; inset: 0; z-index: -1; pointer-events: none; opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='280' height='280'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.6'/%3E%3C/svg%3E");
  background-size: 280px;
  mix-blend-mode: multiply;
}

/* ---------- the wordmark: arched SVG (text fallback for white-label) ---------- */
.archmark { display: block; height: auto; }
.archmark text { font-family: var(--font-display); font-weight: 500; fill: currentColor; }
.brandtext .archmark { width: 182px; }
.authbrand .archmark { width: 300px; filter: drop-shadow(0 14px 36px rgba(0, 20, 12, 0.3)); }
.wordstack { display: inline-flex; flex-direction: column; align-items: flex-start; line-height: 0.94; }
.wordstack .wb { margin-left: 0.55em; margin-top: -0.03em; }

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

.side {
  width: 264px;
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
  padding: 1.9rem 1.1rem 1.4rem;
  background: linear-gradient(180deg, var(--panel), var(--pine-deep));
  border-right: 0;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  color: var(--cream);
}
.brand { display: flex; align-items: center; gap: 0.8rem; text-decoration: none; color: var(--cream); padding: 0 0.4rem; }
.brand:hover { color: var(--cream); }
.brandtext { display: flex; flex-direction: column; line-height: 1.02; }
.wordmark {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.42rem;
  letter-spacing: 0.005em;
  text-transform: none;
}
.tagline {
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: rgba(250, 246, 237, 0.6);
  margin-top: 6px;
}

.side nav { display: flex; flex-direction: column; gap: 2px; }
.side nav a {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 0.54rem 0.85rem;
  border-radius: var(--r-ctl);
  text-decoration: none;
  color: rgba(250, 246, 237, 0.72);
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  transition: background 0.15s, color 0.15s;
}
.side nav a:hover { background: rgba(255, 255, 255, 0.08); color: var(--cream); }
.side nav a.active { background: var(--page); color: var(--pine); font-weight: 600; box-shadow: 0 2px 8px rgba(0, 20, 12, 0.25); }
/* Style A (look options, 2026-10-07): no dot before each link — the paper
   pill on the active one says where you are, and a sub page's indent says
   whose it is. */
.tick { display: none; }
.side nav a.sub { padding: 0.38rem 0.85rem 0.38rem 1.7rem; font-size: 0.8rem; }
.side nav a.sub.active { box-shadow: none; }

.sidefoot { margin-top: auto; padding: 1rem 0.85rem 0; border-top: 1px solid rgba(250, 246, 237, 0.16); }
.sidefoot .who { font-size: 0.84rem; font-weight: 600; display: flex; align-items: center; gap: 0.55rem; color: var(--cream); }
.sidefoot .role {
  font-size: 0.72rem; font-weight: 500;
  color: rgba(250, 246, 237, 0.8); background: rgba(255, 255, 255, 0.12); border-radius: 6px; padding: 0.08rem 0.5rem;
}
.sidefoot form { margin-top: 0.45rem; }
.sidefoot .linkish { color: rgba(250, 246, 237, 0.6); }
.sidefoot .linkish:hover { color: var(--cream); }

main { flex: 1; min-width: 0; padding: 2.8rem 3.2rem 2rem; max-width: 1160px; margin-inline: auto; }
footer { color: var(--ink-3); font-size: 0.76rem; padding: 3rem 0 1rem; text-align: center; font-weight: 400; }

/* The phone's chrome: a bar, and the sidebar as a drawer behind it. Drawn
   only below 880px; above it these elements are not on the page at all. */
.phonebar, .scrim { display: none; }

@media (max-width: 880px) {
  .shell { flex-direction: column; }
  /* One 56px bar instead of a 200px band: the menu, the name, the search. */
  .phonebar {
    display: flex; align-items: center; gap: 0.6rem;
    position: sticky; top: 0; z-index: 40;
    padding: 0.5rem 0.75rem;
    background: linear-gradient(180deg, var(--panel), var(--pine-deep));
    color: var(--cream);
  }
  .menubtn {
    display: inline-flex; align-items: center; gap: 0.45rem; flex: none; margin: 0;
    padding: 0.42rem 0.7rem; font-size: 0.78rem; font-weight: 600;
    background: rgba(255, 255, 255, 0.12); color: var(--cream); border: 0; border-radius: var(--r-ctl);
  }
  .menubtn .bars { width: 14px; height: 10px; flex: none; border-top: 2px solid currentColor; border-bottom: 2px solid currentColor; position: relative; }
  .menubtn .bars::after { content: ""; position: absolute; left: 0; right: 0; top: 4px; border-top: 2px solid currentColor; }
  .phonebrand {
    font-family: var(--font-display); font-size: 0.95rem; font-weight: 500;
    color: var(--cream); text-decoration: none; white-space: nowrap; flex: none;
  }
  .phonebar .find { flex: 1 1 auto; min-width: 0; margin: 0; }
  .phonebar .find input { width: 100%; }
  @media (max-width: 370px) { .phonebrand { display: none; } }

  .scrim { display: block; position: fixed; inset: 0; z-index: 44; background: rgba(6, 26, 19, 0.45); }
  body.drawer-open { overflow: hidden; }

  /* The drawer is the desktop sidebar, off the left edge until asked for —
     same links, same account, same Log out, nothing rebuilt for the phone. */
  .side {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 45;
    width: min(82vw, 300px); height: 100vh; max-width: 82vw;
    padding: 1.4rem 1.1rem; gap: 1.3rem;
    transform: translateX(-100%); transition: transform 0.18s ease-out;
    box-shadow: 0 0 40px rgba(0, 20, 12, 0.35);
  }
  .side.open { transform: none; }
  /* The bar already carries a search, so the drawer's copy stands down. */
  .side .find { display: none; }
  main { padding: 1.6rem 1.2rem 2rem; }
  h1 { font-size: 1.75rem; }
  /* A column flex container is as wide as its widest child, so one wide table
     used to stretch the whole page and take the chrome sideways with it.
     Pinned to the viewport, the table scrolls inside its own .tablewrap. */
  .shell, main { width: 100%; max-width: 100%; box-sizing: border-box; }
}

/* ---------- type: Fraunces display over Inter text ---------- */
h1 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 2.125rem;
  text-transform: none;
  letter-spacing: 0.005em;
  line-height: 1.18;
  margin: 0 0 1.2rem;
  text-wrap: balance;
  color: var(--ink);
}
h2 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.18rem;
  text-transform: none;
  letter-spacing: 0.01em;
  margin: 2.2rem 0 0.7rem;
  color: var(--ink);
}
a { color: var(--pine); font-weight: 600; text-decoration-color: #B9CDBB; text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
a:hover { color: var(--pine-deep); }
.muted { color: var(--ink-2); }

/* ---------- cards ---------- */
.card {
  background: var(--card);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
  padding: 1.5rem 1.7rem;
  margin-bottom: 1.3rem;
  box-shadow: 0 1px 2px rgba(30, 43, 38, 0.04), 0 16px 40px -24px rgba(30, 43, 38, 0.22);
}
.card.narrow { max-width: 440px; margin: 1.4rem auto; }
/* The one card that must be seen first — the withdrawal list, a compliance
   gap — carries a red edge; red is the compliance colour (Style A). */
.card.alert { border-left: 4px solid var(--red); }

/* ---------- Rule 21: documents on the record ---------- */
.documents { margin: 0 0 1.3rem; }
.documents h2 { margin-bottom: 0.4rem; }
.doclist { list-style: none; padding: 0; margin: 0; }
.doclist li { padding: 0.45rem 0; border-top: 1px solid var(--line-soft); font-size: 0.92rem; }
.doclist li:first-child { border-top: 0; }
.grid { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); margin-bottom: 0.4rem; }
/* Number strip (page review 01, Style A): the key numbers in one line — a big
   number, a plain label beneath — not a row of full-height cards. On a phone
   it wraps two-up, not one card per screen. */
.grid:has(> .stat) { display: flex; flex-wrap: wrap; gap: 0.9rem 2.8rem; margin: 0.4rem 0 1.6rem; }
.card.stat { background: none; border: 0; border-radius: 0; box-shadow: none; padding: 0; margin: 0; }
@media (max-width: 560px) {
  .grid:has(> .stat) { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem 1.2rem; }
}
.stat .big {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 2.1rem;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--pine);
}
.stat .sub {
  margin-top: 0.2rem;
  font-size: 0.84rem;
  color: var(--ink-2);
}

/* ---------- forms ---------- */
label { display: block; margin: 0.7rem 0; font-size: 0.84rem; font-weight: 600; color: var(--ink-2); }
input, select, textarea {
  display: block;
  width: 100%;
  padding: 0.6rem 0.75rem;
  margin-top: 0.35rem;
  border: 1px solid var(--line);
  border-radius: var(--r-ctl);
  font: 400 0.95rem/1.4 var(--font-ui);
  text-transform: none;
  letter-spacing: normal;
  background: #FFFEFB;
  color: var(--ink);
  transition: border-color 0.15s, box-shadow 0.15s;
}
input::placeholder { color: var(--ink-3); }
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: none;
  border-color: var(--pine);
  box-shadow: 0 0 0 3px rgba(23, 82, 67, 0.16);
}
a:focus-visible, button:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(23, 82, 67, 0.3); border-radius: 8px; }
input[type="checkbox"] { display: inline-block; width: auto; margin-right: 0.45rem; accent-color: var(--pine); }
label.inline { font-weight: 400; font-size: 0.85rem; text-transform: none; letter-spacing: normal; color: var(--ink); }
/* Two boxes side by side, each a whole answer (Add component on a set: fixed
   or variable); stacked on a phone. */
.twobox { display: grid; grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr)); gap: 1rem; align-items: start; }
/* A checkbox list standing in for a multi-select (a variable component's options):
   group headings, a row per product with room to read and tick, scrolling
   only past a generous height, columns when the page is wide enough. */
.picklist-label { font-weight: 600; font-size: 0.84rem; color: var(--ink-2); margin: 0.9rem 0 0.4rem; }
.picklist { border: 1.5px solid var(--line); border-radius: 12px; padding: 0.6rem 0.9rem; max-height: 26rem; overflow: auto; background: #fff; margin-bottom: 0.8rem; }
.picklist-group + .picklist-group { margin-top: 0.7rem; }
.picklist-head { font-weight: 600; font-size: 0.8rem; color: var(--ink-3); padding: 0.35rem 0 0.2rem; border-bottom: 1px solid var(--line); margin-bottom: 0.25rem; }
.picklist-rows { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: 0 1rem; }
.picklist-rows label.inline { display: flex; align-items: center; padding: 0.45rem 0.3rem; margin: 0; font-size: 0.9rem; border-radius: 8px; cursor: pointer; }
.picklist-rows label.inline:hover { background: #F6F4EC; }
.picklist-rows input[type="checkbox"] { width: 1.05rem; height: 1.05rem; margin-right: 0.6rem; flex: none; }
textarea { min-height: 4rem; }
.formrow { display: flex; gap: 1.1rem; flex-wrap: wrap; }
.formrow > label { flex: 1; min-width: 150px; }

button {
  font: 600 0.84rem/1.3 var(--font-ui);
  text-transform: none;
  letter-spacing: 0.02em;
  background: var(--btn);
  color: var(--cream);
  border: 0;
  border-radius: var(--r-pill);
  padding: 0.62rem 1.45rem;
  cursor: pointer;
  margin-top: 0.7rem;
  transition: background 0.15s, transform 0.1s;
}
button:hover { background: var(--btn-hi); }
button:active { transform: translateY(1px); }
button.small { padding: 0.3rem 0.85rem; font-size: 0.72rem; margin: 0; }
button.danger { background: var(--red); }
button.danger:hover { background: #A22C10; }
button.linkish {
  background: none; color: var(--ink-2); text-decoration: underline;
  text-transform: none; letter-spacing: normal;
  text-underline-offset: 2px; padding: 0; margin: 0; font-weight: 400; font-size: inherit;
  border-radius: 0;
}
button.linkish:hover { background: none; color: var(--ink); }

/* ---------- tables ---------- */
.tablewrap {
  overflow-x: auto;
  background: var(--card);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
  margin-bottom: 1.3rem;
  box-shadow: 0 1px 2px rgba(30, 43, 38, 0.04), 0 16px 40px -24px rgba(30, 43, 38, 0.22);
}
table { border-collapse: collapse; width: 100%; }
th, td { text-align: left; padding: 0.62rem 0.95rem; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
th {
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--ink-2);
  background: var(--inset);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
td { font-size: 0.86rem; font-family: var(--font-ui); font-variant-numeric: tabular-nums; }
tbody tr { transition: background 0.1s; }
tbody tr:hover { background: var(--inset); }
tr:last-child td { border-bottom: 0; }
td.empty { color: var(--ink-3); text-align: center; padding: 2rem; font-family: var(--font-ui); }

/* ---------- pills ---------- */
/* Quiet normal, loud exception (page review 02, Style A): a normal or
   finished state — organic, clear, on holding, paid, sold — is plain grey
   text; only a state that needs attention wears a soft tint, red for a
   compliance problem, amber for attention. No spaced capitals. */
.pill {
  display: inline-block;
  padding: 0;
  border-radius: var(--r-pill);
  font-family: var(--font-ui);
  font-size: 0.86rem;
  font-weight: 400;
  border: 0;
  background: none;
  color: var(--ink-2);
  white-space: nowrap;
  vertical-align: baseline;
}
.pill.organic, .pill.ok { background: none; color: var(--ink-2); }
.pill.warn, .pill.bad, .pill.tag { padding: 0.1rem 0.6rem; font-size: 0.78rem; font-weight: 600; vertical-align: middle; }
.pill.warn { background: var(--terra-tint); color: var(--terra-ink); }
.pill.bad { background: var(--red-tint); color: var(--red); }
.pill.tag { background: var(--ochre); color: var(--cream); }
/* The number strip (page review pattern; 09 F8): key numbers in one line,
   a big figure over a small plain label; two-up on a phone. Red only for a
   figure that is a compliance problem (flagged kills). */
.numstrip { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.5rem 2.2rem; margin: 0.1rem 0 1.2rem; }
.numstrip .ns-caption { flex: 0 0 100%; margin: 0 0 -0.2rem; font-size: 0.78rem; color: var(--ink-2); }
.numstrip .ns-item { display: flex; flex-direction: column; color: inherit; text-decoration: none; }
.numstrip a.ns-item:hover .ns-label { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.numstrip .ns-value { font-family: var(--font-display); font-size: 1.55rem; line-height: 1.15; font-variant-numeric: tabular-nums; }
.numstrip .ns-value.bad { color: var(--red); }
.numstrip .ns-value.warn { color: var(--terra-ink); }
.numstrip .ns-label { font-size: 0.78rem; color: var(--ink-2); }
@media (max-width: 560px) {
  .numstrip { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem 1rem; }
  .numstrip .ns-value { font-size: 1.3rem; }
  .numstrip .ns-caption { grid-column: 1 / -1; }
}
/* A short line under a cell's value for something missing — the abattoir
   with no certificate on file (page review 09 F6). Amber for attention, red
   for a compliance problem; nothing at all when all is well. */
.cellnote { display: block; margin-top: 0.1rem; font-size: 0.76rem; font-weight: 500; }
.cellnote.warn { color: var(--terra-ink); }
.cellnote.bad { color: var(--red); }
/* Rule 29: a sale's two state pills (money, goods) stay on one line together.
   Two quiet ones side by side read "paid · dispatched", not "paid dispatched". */
.pills { display: inline-flex; gap: 0.3rem; white-space: nowrap; vertical-align: middle; }
.pills > .pill + .pill:not(.warn):not(.bad):not(.tag)::before { content: "·"; margin-right: 0.3rem; color: var(--ink-3); }

.flash {
  padding: 0.8rem 1.15rem;
  border-radius: var(--r-ctl);
  margin-bottom: 1.2rem;
  font-weight: 500;
  font-size: 0.87rem;
}
.flash.ok { background: var(--sage); color: var(--sage-ink); }
.flash.error { background: var(--red-tint); color: var(--red); }

/* ---------- toolbar ---------- */
.toolbar { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-bottom: 1.2rem; flex-wrap: wrap; }
.toolbar h1 { margin: 0; }
.toolbar .actions { display: flex; gap: 0.55rem; align-items: center; }
.toolbar .actions form { margin: 0; }
.toolbar .actions a { text-decoration: none; }
/* A quiet switch beside the primary action (Bulk edit) keeps its (i) with it. */
.toolbar .actions .bulkswitch { display: inline-flex; align-items: center; gap: 0.35rem; }

.lot-line { display: grid; grid-template-columns: 1fr 150px; gap: 0.9rem; align-items: end; }
@media (max-width: 560px) { .lot-line { grid-template-columns: 1fr; gap: 0.2rem; } }

/* ---------- auth: full green, one white card ---------- */
body.auth { min-height: 100vh; background: linear-gradient(165deg, var(--panel), var(--pine-deep)); color: var(--cream); }
body.auth .lights, body.auth .grain { display: none; }
.authmain { max-width: 430px; margin: 0 auto; padding: 9vh 1.2rem 3rem; }
.authbrand { display: flex; flex-direction: column; align-items: center; margin-bottom: 1.9rem; }
.authbrand .authhome { text-decoration: none; color: inherit; }
.authbrand .authhome:hover { color: inherit; opacity: 0.92; }
.authbrand .wordmark.big {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 2.9rem;
  color: var(--cream);
  text-transform: none;
  letter-spacing: 0.005em;
  text-shadow: 0 12px 40px rgba(0, 20, 12, 0.35);
}
.authbrand .tagline { margin-top: 0.8rem; font-size: 0.82rem; color: rgba(250, 246, 237, 0.6); }
.authmain .card { padding: 1.9rem 2rem; border: 0; box-shadow: 0 24px 70px -30px rgba(0, 20, 12, 0.55); }
.authmain h1 { font-size: 1.45rem; }
.authmain button { width: 100%; margin-top: 1.1rem; }
/* helper lines inside labels read as prose, not shouting */
.authmain label .muted { display: block; margin-top: 0.45rem; text-transform: none; letter-spacing: normal; font-weight: 400; font-size: 0.8rem; line-height: 1.55; }

/* ---------- signup wizard ---------- */
.step { display: none; }
.step.active { display: block; }
.stepmeta { display: flex; justify-content: space-between; align-items: center; font-size: 0.8rem; font-weight: 600; color: var(--ink-3); margin-bottom: 1rem; }
.stepmeta > span { white-space: nowrap; }
.backlink { background: none; border: 0; color: var(--ink-2); cursor: pointer; font: inherit; font-size: 0.78rem; text-decoration: underline; text-underline-offset: 2px; padding: 0; margin: 0; text-transform: none; letter-spacing: normal; }
.backlink:hover { background: none; color: var(--ink); transform: none; }
.bookpick { display: flex; flex-direction: column; gap: 0.75rem; margin-top: 1.1rem; }
.bookpick .book {
  display: flex; gap: 1rem; align-items: center; cursor: pointer; margin: 0;
  border: 1.5px solid var(--line); border-radius: 14px; padding: 1rem 1.1rem;
  text-transform: none; letter-spacing: normal; font-weight: 400; font-size: 0.86rem; color: var(--ink);
  transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
.bookpick .book:hover { border-color: var(--pine); }
.bookpick input:checked + .book { border-color: var(--pine); background: #FBFDF9; box-shadow: 0 0 0 3px rgba(23, 82, 67, 0.14); }
.bookpick input:focus-visible + .book { box-shadow: 0 0 0 3px rgba(23, 82, 67, 0.3); }
.book svg { width: 46px; height: 46px; flex: none; color: var(--pine); background: var(--pine-tint); border-radius: 999px; padding: 9px; }
.book .bt { font-weight: 600; font-size: 0.95rem; }
.book .bd { color: var(--ink-2); font-size: 0.78rem; line-height: 1.5; }
.authmain .flash.error { background: var(--red-tint); }

@media (prefers-reduced-motion: reduce) {
  .lights > div { animation: none; }
  .brand .mark, .authbrand .bigmark, tbody tr, button { transition: none; }
}

/* ---------- Rule 31: print like the template they know ---------- */
/* .printonly is the certifier's table, .printhide the screen version. */
.printonly { display: none; }
@media print {
  @page { size: A4 landscape; margin: 12mm; }
  .printhide { display: none !important; }
  .printonly { display: block; }
  .printbook h2 { font-size: 1rem; margin: 0.2rem 0 0.3rem; }
  .printbook .printmeta, .printbook .printfoot { font-size: 9.5px; color: #000; margin: 0.2rem 0 0.5rem; }
  .printbook table { width: 100%; border-collapse: collapse; font-size: 9.5px; }
  .printbook thead { display: table-header-group; }
  .printbook tr { break-inside: avoid; page-break-inside: avoid; }
  .printbook th, .printbook td { border: 1px solid #000; padding: 3px 5px; vertical-align: top; text-align: left; white-space: normal; color: #000; background: #fff; }
  .printbook th { font-weight: 700; background: #eee; }
  .printbook th.group { text-align: center; }
  .printbook td.blank { min-width: 5em; }
  .printbook td.empty { text-align: center; color: #333; padding: 1em; }
}

/* ---------- print: clean documents ---------- */
@media print {
  .lights, .grain, .side, footer, .toolbar .actions, .noprint, .flash { display: none !important; }
  body { background: #fff !important; color: #000; font-size: 11px; }
  .shell { display: block; }
  main { max-width: none; margin: 0; padding: 0; }
  main::before {
    content: "ORGANIC CERTIFICATION RECORD";
    display: block;
    font-weight: 700;
    font-size: 0.9rem;
    letter-spacing: 0.16em;
    border-bottom: 2px solid #000;
    padding-bottom: 0.35rem;
    margin-bottom: 1rem;
  }
  .card, .tablewrap { background: #fff; border: 1px solid #bbb; box-shadow: none; border-radius: 4px; break-inside: avoid; }
  h1, h2, td, .muted, label { color: #000; }
  th { color: #333; background: #f2f2f2; }
  .pill { background: none; border: 1px solid #999; color: #000; padding: 0 0.35rem; }
  tbody tr:hover { background: none; }
  a { color: inherit; text-decoration: none; }
}

/* in-table row actions: one tidy row instead of a wrapping stack */
.rowactions { display: flex; gap: 0.35rem; align-items: center; white-space: nowrap; }
.rowactions form { margin: 0; display: inline; }
button.dangerish { color: var(--red); }
button.dangerish:hover { background: none; color: #A22C10; }

/* ---------- Rule 25: destructive actions are quiet ---------- */
/* A delete or remove is a text link in the page's quiet grey, red only under
   the pointer, behind a confirm that names the thing. Never a red button:
   red is the compliance colour and keeps its meaning. */
button.quietdel { color: var(--ink-3); }
button.quietdel:hover { background: none; color: var(--red); }
form.quietdel { display: inline; margin: 0; }

/* compact selects living inside table cells (bulk edit) */
.cellselect { width: auto; margin: 0; padding: 0.3rem 1.6rem 0.3rem 0.55rem; font-size: 0.82rem; }
.cellselect.changed { border-color: var(--pine); box-shadow: 0 0 0 2px rgba(23, 82, 67, 0.18); }
input.cellnum { width: 6.2rem; padding-right: 0.55rem; }

/* the Help & ideas widget: a floating button opening a compact panel */
#hlp { position: fixed; right: 1.1rem; bottom: 1.1rem; z-index: 60; display: flex; flex-direction: column; align-items: flex-end; gap: 0.6rem; }
#hlp-fab { border: 0; border-radius: 99px; padding: 0.55rem 1.1rem; background: var(--pine); color: #FAF6ED; font-weight: 600; cursor: pointer; box-shadow: 0 6px 18px rgba(23, 82, 67, 0.35); }
#hlp-panel { display: none; flex-direction: column; width: min(24rem, calc(100vw - 2.2rem)); height: min(34rem, 80vh); background: var(--card); border: 1px solid var(--line-soft); border-radius: var(--r-card); box-shadow: 0 12px 34px rgba(30, 43, 38, 0.25); overflow: hidden; }
.hlp-head { display: flex; justify-content: space-between; align-items: center; padding: 0.6rem 0.9rem; background: var(--pine); color: #FAF6ED; font-weight: 600; flex: none; }
.hlp-head button { border: 0; background: none; color: inherit; font-size: 1.2rem; cursor: pointer; }
.hlp-tabs { display: flex; border-bottom: 1px solid var(--line-soft); flex: none; }
.hlp-tab { flex: 1; border: 0; background: none; padding: 0.55rem 0; font-size: 0.85rem; font-weight: 600; cursor: pointer; color: inherit; opacity: 0.55; border-bottom: 2px solid transparent; border-radius: 0; }
.hlp-tab.active { opacity: 1; border-bottom-color: var(--pine); }
.hlp-pane { flex: 1; display: flex; flex-direction: column; min-height: 0; overflow-y: auto; }
#hlp-log { flex: 1; overflow-y: auto; padding: 0.7rem; display: flex; flex-direction: column; gap: 0.45rem; }
.hlp-msg { padding: 0.45rem 0.7rem; border-radius: 0.7rem; font-size: 0.86rem; max-width: 90%; white-space: pre-wrap; }
.hlp-bot { background: rgba(23, 82, 67, 0.08); align-self: flex-start; }
.hlp-user { background: var(--pine); color: #FAF6ED; align-self: flex-end; }
#hlp-chat { display: flex; gap: 0.4rem; padding: 0 0.7rem 0.6rem; }
#hlp-chat input { flex: 1; margin: 0; }
#hlp-chat button { margin: 0; }
.hlp-idea { padding: 0.7rem 0.8rem 0.9rem; font-size: 0.72rem; }
.hlp-idea textarea { width: 100%; margin: 0.35rem 0; }
.hlp-shot { display: block; font-size: 0.8rem; margin-bottom: 0.4rem; }

/* On a phone the floating button is a 44px circle — the tap-target minimum —
   rather than a 160px bar parked on whatever is beneath it (at 320 it was
   sitting on the dashboard's own "+ Slaughter" and "+ Sale"). The words move
   into the button's accessible name, and the page reserves room at its end so
   the last thing on it is never trapped underneath. */
@media (max-width: 560px) {
  #hlp { right: 0.7rem; bottom: 0.7rem; }
  #hlp-fab { width: 2.75rem; height: 2.75rem; padding: 0; border-radius: 50%; font-size: 1.15rem; line-height: 1; }
  #hlp-fab .hlp-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  main { padding-bottom: 4.6rem; }
}

/* in-flight feedback for slow submits (AI invoice reading etc.) */
.busyline { display: none; align-items: center; gap: 0.6rem; margin-top: 0.9rem; color: var(--ink-soft, inherit); }
.spinner { width: 1.1rem; height: 1.1rem; flex: none; border: 2.5px solid var(--line-soft); border-top-color: var(--pine); border-radius: 50%; animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* .tight tables: one line per row, no wrapping, closer packing — the wrapper
   already scrolls horizontally if a screen is too narrow */
.tight th, .tight td { white-space: nowrap; padding: 0.42rem 0.8rem; vertical-align: middle; }

/* .tight tables freeze their first column (the name) while the rest scrolls —
   solid backgrounds so scrolling content slides underneath, not through */
.tight th:first-child, .tight td:first-child { position: sticky; left: 0; z-index: 2; }
.tight td:first-child { background: #fff; }
.tight th:first-child { background: var(--inset); }
.tight tbody tr:hover td:first-child { background: var(--inset); }

/* Certification chips on signup: status first (certified / in conversion /
   not yet), then tick every body that certifies you; multi-scheme bodies
   unfold smaller scheme chips beneath their body chip. Same checked/focus
   language as the book cards, worn as compact pills. */
.certstatus, .certpick { display: flex; flex-wrap: wrap; gap: 0.55rem; margin-top: 0.7rem; }
/* The hidden attribute means hidden, even on the inputs and buttons this
   stylesheet gives a display of their own. Without this a form control marked
   hidden keeps its box and the row it sits in grows sideways. */
[hidden] { display: none !important; }
/* Radios and checkboxes worn as chips: the control is taken out of sight but
   stays focusable and keeps its label. It has to be given a box of its own.
   A radio inherits the 100%-wide form control at the top of this file, and an
   absolutely positioned 100%-wide box starting halfway across the card runs
   off the side of the page — which is why the signup form scrolled sideways
   at every width, desktop included, on three invisible radios (2001px of
   document on a 1440px screen). Checkboxes escaped it only because they are
   width:auto. One rule for every chip, so neither can drift again. */
.bookpick input, .certstatus input, .certpick input, .segrow input {
  position: absolute; width: 1px; height: 1px; margin: 0; padding: 0;
  opacity: 0; pointer-events: none; clip-path: inset(50%);
}
.certstatus .cert, .certpick .cert {
  cursor: pointer; margin: 0; border: 1.5px solid var(--line); border-radius: 12px;
  padding: 0.5rem 0.9rem; font-weight: 500; font-size: 0.84rem; color: var(--ink); line-height: 1.3;
  text-transform: none; letter-spacing: normal;
  transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
.certstatus .cert .cc, .certpick .cert .cc { display: block; font-weight: 400; font-size: 0.72rem; opacity: 0.55; letter-spacing: 0.03em; }
.certstatus .cert:hover, .certpick .cert:hover { border-color: var(--pine); }
.certstatus input:checked + .cert, .certpick input:checked + .cert { border-color: var(--pine); background: #FBFDF9; box-shadow: 0 0 0 3px rgba(23, 82, 67, 0.14); }
.certstatus input:focus-visible + .cert, .certpick input:focus-visible + .cert { box-shadow: 0 0 0 3px rgba(23, 82, 67, 0.3); }
.certgroup { display: flex; flex-direction: column; gap: 0.35rem; }
.certschemes { display: flex; flex-wrap: wrap; gap: 0.35rem; padding-left: 0.5rem; }
.certpick .cert.schemechip { padding: 0.28rem 0.65rem; font-size: 0.76rem; border-radius: 9px; }

/* Three-dot row menu: a native details popover, no JS. */
.rowmenu { position: relative; display: inline-block; }
.rowmenu summary { list-style: none; cursor: pointer; padding: 0.05rem 0.55rem; border-radius: 8px; font-weight: 700; user-select: none; }
.rowmenu summary::-webkit-details-marker { display: none; }
.rowmenu summary:hover { background: var(--inset); }

/* ---------- Rule 32: a settings page with a spine ---------- */
.spined { display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: 0 2rem; align-items: start; }
.spine { position: sticky; top: 1.2rem; display: flex; flex-direction: column; gap: 2px; }
.spine a {
  display: block; padding: 0.42rem 0.75rem; border-radius: var(--r-pill);
  font-family: var(--font-ui); font-size: 0.86rem; font-weight: 500; color: var(--ink-2); text-decoration: none;
}
.spine a:hover { background: var(--inset); color: var(--ink); }
.spine a.current { background: var(--card); color: var(--ink); box-shadow: 0 1px 2px rgba(30, 43, 38, 0.06); }
.spined-main > form > section, .spined-main > section { scroll-margin-top: 1rem; }
.spined-main section > h2:first-child { margin-top: 0; }
@media (max-width: 880px) {
  .spined { display: block; }
  .spine { position: static; flex-direction: row; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 1rem; }
  .spine a { padding: 0.3rem 0.7rem; font-size: 0.78rem; border: 1px solid var(--line-soft); background: var(--card); }
  .spine a.current { background: var(--ink); color: var(--cream); border-color: var(--ink); }
}
.rowmenu[open] > div { position: absolute; right: 0; top: 1.6rem; z-index: 20; background: #fff;
  border: 1px solid var(--line); border-radius: 10px; padding: 0.35rem 0.6rem; box-shadow: 0 6px 18px rgba(0, 20, 12, 0.1); white-space: nowrap; }

/* One form, three quiet cards on the same ground: who they are, what they
   supply, where they stand. Hierarchy comes from spacing and three tiny
   section marks, not colour; every explanation lives behind the small "i",
   so the form itself is only questions. */
.formstack { display: flex; flex-direction: column; gap: 0.9rem; margin-bottom: 1.3rem; }
.formsec {
  background: var(--card); border: 1px solid var(--line-soft); border-radius: var(--r-card);
  padding: 1.35rem 1.6rem 1.45rem;
  box-shadow: 0 1px 2px rgba(30, 43, 38, 0.04), 0 16px 40px -24px rgba(30, 43, 38, 0.22);
}
.formsec > h2 {
  font-family: var(--font-display); font-size: 1.05rem; font-weight: 500;
  letter-spacing: 0.01em; color: var(--ink);
  margin: 0 0 0.9rem;
}
.formsec > label:first-of-type, .formsec > .formrow:first-of-type { margin-top: 0; }

/* ---------- Rule 14: a record's own history, last on the page ---------- */
.history { margin-top: 2.2rem; }
.history h2 { margin-bottom: 0.5rem; }
.history-table td { vertical-align: top; font-size: 0.86rem; }
.history-table td.nowrap { white-space: nowrap; }
.history-verb { font-family: var(--font-ui); font-size: 0.84rem; font-weight: 600; color: var(--ink-2); margin-right: 0.25rem; }
.history-foot { font-size: 0.82rem; margin-top: 0.5rem; }

/* The "i": hover or focus for the sentence that used to crowd the form. */
.tip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 0.85rem; height: 0.85rem; border-radius: 50%; flex: none;
  border: 1px solid var(--ink-3); color: var(--ink-3);
  font-size: 0.6rem; font-weight: 600; font-style: normal; line-height: 1;
  text-transform: none; letter-spacing: 0; vertical-align: -1px;
  margin-left: 0.35rem; cursor: help; position: relative;
}
.tip::after {
  content: attr(data-tip); position: absolute; bottom: calc(100% + 7px); left: 50%;
  transform: translateX(-50%); width: max-content; max-width: 250px;
  background: var(--ink); color: var(--page); padding: 0.5rem 0.7rem; border-radius: 8px;
  font-size: 0.74rem; font-weight: 400; line-height: 1.45; letter-spacing: 0.01em;
  text-transform: none; white-space: normal; text-align: left;
  opacity: 0; pointer-events: none; transition: opacity 0.12s; z-index: 30;
}
.tip:hover::after, .tip:focus-visible::after { opacity: 1; }
.pill .tip { width: 0.72rem; height: 0.72rem; font-size: 0.5rem; margin-left: 0.2rem; vertical-align: -1px; }
/* Inside a scrolling table wrapper an upward bubble is clipped by the
   wrapper's edge — open downward there instead, and keep the last column's
   bubble inside the right edge. */
.tablewrap .tip::after { bottom: auto; top: calc(100% + 7px); }
.invtable th:last-child .tip::after, .invtable td:last-child .tip::after { left: auto; right: -0.3rem; transform: none; }
/* A toolbar (i) sits at the page's right edge at every width, so its bubble
   opens leftwards always — a centred one hangs off the edge, and an invisible
   box out there is still a page you can drag sideways. */
.toolbar .actions .tip::after { left: auto; right: -0.3rem; transform: none; }
.tip:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(23, 82, 67, 0.3); }
/* On a phone a centred bubble hangs off the right edge, and an invisible box
   out there is still a page you can drag sideways (audit F-08 / proc P2-02).
   Narrow screens open every bubble leftwards from its (i) — the same trick
   the last table column already uses — and cap it to the viewport. */
@media (max-width: 560px) {
  .tip::after { left: auto; right: -0.3rem; transform: none; max-width: calc(100vw - 2.5rem); }
}

/* Plain radios, sentence case, one line each — an answer, not a poster. */
.pickrow { display: flex; flex-direction: column; gap: 0.55rem; margin: 0.1rem 0 0; }
.pickrow .opt { display: flex; align-items: center; }
.pickrow label {
  display: flex; align-items: center; gap: 0.55rem; margin: 0;
  font-size: 0.86rem; font-weight: 400; text-transform: none; letter-spacing: normal;
  color: var(--ink); cursor: pointer;
}
.pickrow input { width: auto; margin: 0; flex: none; accent-color: var(--pine); }

/* "Kind first" (shared/segments.js): the answer the rest of the form depends
   on, as one row of joined choices; nothing chosen until the farmer says. */
.segs { border: 0; padding: 0; margin: 0.7rem 0; min-width: 0; }
.segs legend { padding: 0; margin-bottom: 0.35rem; font-size: 0.8rem; font-weight: 600; color: var(--ink-2); }
.segrow { position: relative; display: inline-flex; flex-wrap: wrap; border: 1px solid var(--line); border-radius: var(--r-ctl); background: #FFFEFB; overflow: hidden; }
.segrow label { margin: 0; padding: 0.55rem 1rem; font-size: 0.9rem; font-weight: 500; text-transform: none; letter-spacing: normal; color: var(--ink); cursor: pointer; transition: background 0.15s, color 0.15s; }
.segrow label + input + label { border-left: 1px solid var(--line); }
.segrow label:hover { background: rgba(23, 82, 67, 0.06); }
.segrow input:checked + label { background: var(--pine); color: #fff; }
.segrow input:focus-visible + label { box-shadow: inset 0 0 0 3px rgba(23, 82, 67, 0.35); }

/* Paperwork appears only once the chosen answer says there is paperwork. */
.cbdocs { margin-top: 1.15rem; padding-top: 1.05rem; border-top: 1px solid var(--line-soft); }
.cbdocs > .formrow:first-child, .cbdocs > label:first-child { margin-top: 0; }

/* The import review's line table: reads like the invoice itself — one row
   per line, inputs sized to their content, the mismatch warning as its own
   full-width row beneath the line it belongs to. */
.invtable td { vertical-align: middle; }
.invtable th, .invtable td { padding: 0.5rem 0.5rem; }
.invtable input, .invtable select { margin: 0; font-size: 0.82rem; padding: 0.4rem 0.5rem; }
.invtable .c-inc, .invtable .c-cert { text-align: center; }
.invtable .c-inc input, .invtable .c-cert input { width: auto; margin: 0; }
.invtable .c-num input { width: 4.8rem; font-variant-numeric: tabular-nums; }
.invtable .c-lot input { width: 6.5rem; }
.invtable .c-desc { font-size: 0.8rem; color: var(--ink-2); max-width: 13rem; line-height: 1.45; }
.invtable .c-desc > div { margin-top: 0.25rem; }
.invtable .c-ing { min-width: 13rem; }
.invtable .c-ing select { max-width: 15rem; }
.invtable .c-ing .ing-pills { display: block; margin-top: 0.3rem; }
.invtable tr.mismatchrow td { padding-top: 0.2rem; border-top: 0; }

/* A sale's lines, written the way an invoice writes them: the thing being
   sold takes the width it needs, the figures stay narrow and tabular, and the
   whole line sits on one row. Rows past the first are hidden until asked for. */
.tablewrap.lines { max-width: 52rem; }
.linetable { table-layout: fixed; min-width: 20rem; }
.linetable .c-num { width: 7.5rem; }
/* A fixed list — the kill sheet's animals — carries a tick and two short
   facts beside the name, so those columns are sized to what they hold and
   the name takes what is left. */
.linetable .c-inc { width: 4.2rem; }
.linetable .c-tight { width: 8rem; }
.linetable .c-pill { width: 12rem; }
/* A label inside a row names the row; it is not a caption standing over a
   box, so it reads as ordinary text — and the whole name is a tap target
   for the row's tick. */
.linetable td label {
  display: inline; margin: 0; font: inherit; text-transform: none;
  letter-spacing: normal; color: inherit; cursor: pointer;
}
.linetable .c-act { width: 2.2rem; text-align: center; }
/* A delivery's line: the figures, the lot and the tick are sized to what they
   hold, so the ingredient — the only column whose content varies — takes the
   width that is left. */
.linetable .c-lot { width: 8.5rem; }
.linetable .c-cert { width: 4.2rem; }
.linetable .rowclear { padding: 0.1rem 0.45rem; }
/* On a phone the line still stays a line: the figures keep their narrow
   columns and the picker takes what is left — a select shows its full list
   when tapped, so a truncated label costs nothing and a sideways nudge would. */
@media (max-width: 560px) {
  .linetable { min-width: 0; }
  /* On a phone the row keeps what the decision needs — tick, name, compliance,
     head — and drops the species, which the name and the register already
     say. Hiding the class hides its heading with it. */
  .linetable .c-num { width: 5.4rem; }
  .linetable .c-lot { width: 5rem; }
  .linetable .c-cert { width: 3rem; }
  .linetable .c-inc { width: 2.2rem; }
  .linetable .c-tight { display: none; }
  .linetable .c-pill { width: 5.6rem; }
  .linetable th, .linetable td { padding: 0.5rem 0.3rem; }
}
.linetable .c-item { overflow-wrap: anywhere; }
.linetable .c-item select, .linetable .c-item input,
.linetable .c-ing select, .linetable .c-ing input,
.linetable .c-lot input, .linetable .c-num input { width: 100%; max-width: none; }
#cutting .linetable .c-num select { width: 100%; max-width: none; }
/* The cutting sheet's one use-by for every line: a date box, date-sized. */
label.usebyall { flex: 0 1 22rem; }
/* On a phone its line cards name the use-by and lot number boxes too. */
@media (max-width: 600px) {
  #cutting .linetable.lt-stack td.c-lot { flex: 1 1 0; min-width: 0; }
  #cutting .linetable.lt-stack td.c-lot::before {
    content: attr(data-label); display: block; font-size: 0.72rem;
    color: var(--ink-2); margin-bottom: 0.15rem;
  }
}
#addline { margin-top: 0.7rem; }
/* Chosen on top (page review 10 F1): what is ticked sits in a block at the
   head of the register with its count; the rest of the holding beneath. A
   ticked animal still in withdrawal on the kill date is red there — its row
   tinted, a red edge, its "can go from" pill and a "remove". */
.chosen tbody.going { border-bottom: 2px solid var(--line); }
.chosen tr.goinghead td { background: var(--pine-tint); color: var(--pine-deep); font-size: 0.86rem; padding: 0.5rem 0.6rem; }
.chosen tr.goingempty td { font-size: 0.84rem; padding: 0.6rem; }
.chosen .goingrefused:not(:empty) { margin-left: 0.6rem; color: var(--red); font-weight: 600; }
.chosen tr.resthead td { background: var(--inset); color: var(--ink-2); font-size: 0.74rem; padding: 0.35rem 0.6rem; }
.chosen tbody.going tr.pick-a td { background: #FCFAF4; }
.chosen tbody tr.pick-a.refused td { background: var(--red-tint); }
.chosen tbody tr.pick-a.refused td:first-child { box-shadow: inset 4px 0 0 var(--red); }
.chosen button.pickremove { margin-left: 0.3rem; padding: 0; color: var(--red); font-size: 0.78rem; text-decoration: underline; text-underline-offset: 2px; }
/* Type to pick (page review 10 F3): a finder box and species chips above the
   register; the chip that is on is filled in the brand's tint. */
.pickfind { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.8rem; margin: 0 0 0.8rem; }
.pickfind .pickfilter { flex: 1 1 13rem; max-width: 20rem; margin: 0; }
.pickchips { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.chosen button.pickchip { margin: 0; padding: 0.28rem 0.75rem; font-size: 0.8rem; font-weight: 500; background: none; color: var(--ink-2); border: 1px solid var(--line); }
.chosen button.pickchip:hover { background: var(--inset); color: var(--ink); }
.chosen button.pickchip[aria-pressed="true"] { background: var(--pine-tint); color: var(--pine-deep); border-color: var(--pine-tint); }
.pickchip .count { margin-left: 0.15rem; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.pickchip .count.bad { color: var(--red); font-weight: 600; }
.pickfind .pickcount { font-size: 0.8rem; }
/* The pill wraps inside its column rather than running under the head box,
   so the "can go from" date can always be read. */
.chosen .c-pill .pill { white-space: normal; line-height: 1.35; }
/* Phone rows as stacks, for the animal picker (page review 06 F3): beside
   four fixed columns a name like "Ewes — Long Acre" broke three letters to a
   line. At phone width each animal is a two-line card — the tick, the name
   (with its head) and any head box on top, its status beneath. A head that
   is only a number is already beside the name, so its column steps aside. */
@media (max-width: 560px) {
  .chosen .linetable { table-layout: auto; }
  .chosen .linetable thead {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
  }
  .chosen tbody tr.pick-a:not([hidden]) {
    display: grid; grid-template-columns: 2rem minmax(0, 1fr) auto; column-gap: 0.4rem; row-gap: 0.15rem;
    align-items: center; padding: 0.5rem 0.45rem; border-bottom: 1px solid var(--line-soft);
  }
  .chosen tbody tr.pick-a td { display: block; width: auto; padding: 0; border: 0; background: none; }
  .chosen tbody tr.pick-a td.c-tight { display: none; }
  .chosen tbody tr.pick-a td.c-inc { grid-row: 1 / span 2; }
  .chosen tbody tr.pick-a td.c-item { grid-column: 2; overflow-wrap: normal; }
  .chosen tbody tr.pick-a td.c-num { grid-column: 3; grid-row: 1; }
  .chosen tbody tr.pick-a td.c-num input { width: 4.6rem; }
  .chosen tbody tr.pick-a td.c-num:not(:has(input)) { display: none; }
  .chosen tbody tr.pick-a td.c-pill { grid-column: 2 / span 2; }
  .chosen tbody tr.pick-a td.c-pill:empty { display: none; }
  .chosen tbody.going tr.pick-a { background: #FCFAF4; }
  .chosen tbody tr.pick-a.refused { background: var(--red-tint); box-shadow: inset 4px 0 0 var(--red); }
  .chosen tbody tr.pick-a.refused td:first-child { box-shadow: none; }
}
/* Phone rows as stacks, for a pad of invoice lines (page review 15 F1): at
   phone width a sale line is a card — the thing being sold on its own full
   row, the figures beneath it side by side, each named by its column (the
   cell's data-label), the × at the end. Before this the picker was squeezed
   to 18px under the quantity box and could not be tapped. The heading row
   stays for screen readers; every control already has its own name. */
@media (max-width: 600px) {
  .linetable.lt-stack { table-layout: auto; min-width: 0; }
  .linetable.lt-stack thead {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
  }
  .linetable.lt-stack tbody tr:not([hidden]) {
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.35rem 0.5rem;
    padding: 0.6rem 0.5rem; border-bottom: 1px solid var(--line);
  }
  .linetable.lt-stack td { display: block; width: auto; padding: 0; border: 0; }
  .linetable.lt-stack td.c-item { flex: 0 0 100%; }
  .linetable.lt-stack td.c-num { flex: 1 1 0; min-width: 0; }
  /* A delivery line (page review 17 F7): the input, then its figures on one
     row, then its batch and date on the next, each named like the figures. */
  .linetable.lt-stack td.c-fig { flex: 1 1 26%; order: 1; }
  .linetable.lt-stack td.c-lot { flex: 1 1 40%; min-width: 0; order: 2; }
  .linetable.lt-stack td.c-act { flex: 0 0 auto; order: 3; }
  .linetable.lt-stack td.c-num::before, .linetable.lt-stack td.c-lot::before {
    content: attr(data-label); display: block; font-size: 0.72rem;
    color: var(--ink-2); margin-bottom: 0.15rem;
  }
}

/* A sale form's head (page review livestock-15-4, growing-G15-4): one
   customer box, wide, with its quiet line beneath; the date and their order
   number sized to their answers (rule 5). */
.salehead .custbox { flex: 3 1 18rem; min-width: 0; }
.salehead > label.c-date { flex: 0 1 11rem; }
.salehead > label.c-ref { flex: 1 1 11rem; }
.custbox .custline { margin: -0.35rem 0 0.6rem; font-size: 0.8rem; }
.custbox .custemail { max-width: 26rem; }
/* The pricing folded to one line after the lines (growing-G15-4): the words
   say what applies; "change" opens the same three settings. */
.pricefold { margin: 0.4rem 0 0.6rem; }
.pricefold summary { list-style: none; cursor: pointer; font-size: 0.86rem; color: var(--ink-2); padding: 0.2rem 0; }
.pricefold summary::-webkit-details-marker { display: none; }
.pricefold .pricefold-change { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; margin-left: 0.3rem; }
.pricefold[open] .pricefold-change { display: none; }

/* Type to pick (rule 7; page review livestock-15-5, src/routes/shared/
   typepick.js): a text box in front of a long line picker, its matches in a
   list beneath; the select behind it stays the form's answer. */
.typepick-hidden { display: none !important; }
.typepick-box { width: 100%; }
.typepick-list {
  position: absolute; left: 0; right: 0; z-index: 30; margin: 0.15rem 0 0; padding: 0.25rem 0;
  list-style: none; max-height: 16rem; overflow-y: auto; background: #fff;
  border: 1px solid var(--line); border-radius: var(--r-ctl); box-shadow: 0 10px 28px -12px rgba(30, 43, 38, 0.35);
  font: 400 0.88rem/1.35 var(--font-ui); text-transform: none; letter-spacing: normal; color: var(--ink);
}
.typepick-list li { padding: 0.45rem 0.75rem; cursor: pointer; }
.typepick-list li.on, .typepick-list li:hover { background: var(--inset); }
.typepick-list li.none { color: var(--ink-3); cursor: default; }

/* The trial-over banner: on every page of a read-only farm, so the pause is
   visible before anyone fills in a form that cannot save. */
.banner-readonly { border-left: 4px solid var(--ochre); }
.banner-readonly a { font-weight: 600; }

/* The validation summary that stays put (audit P2-12). The native bubble
   vanishes and leaves a form looking fine while refusing to save; this sits at
   the top of the form until every field named in it is right.
   Red, and the field itself boxed in red (Fraser, 2026-09-18: "need red
   highlighting and box highlighting for errors") — a form that refuses to
   save has to be impossible to misread. */
.errsum {
  background: var(--red-tint);
  color: var(--red);
  border: 1.5px solid var(--red-soft);
  border-left: 5px solid var(--red);
  border-radius: var(--r-ctl);
  padding: 0.8rem 1rem;
  margin: 0 0 1.1rem;
}
.errsum p { margin: 0 0 0.35rem; font-weight: 600; }
.errsum ul { margin: 0; padding-left: 1.1rem; }
.errsum li { margin: 0.15rem 0; }
.errsum a { color: inherit; font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
.errsum:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
/* The field that failed: a red box, a red label above it, and a red focus
   ring while it is being put right. */
[aria-invalid="true"] { border-color: var(--red-soft) !important; border-width: 2px; background: #FFF5F2; box-shadow: 0 0 0 3px rgba(196, 55, 23, 0.12); }
[aria-invalid="true"]:focus-visible { border-color: var(--red) !important; box-shadow: 0 0 0 3px rgba(196, 55, 23, 0.28); }
label.haserr, label:has(> [aria-invalid="true"]), label:has([aria-invalid="true"]) { color: var(--red); }

/* Opening stock: one tight table — pick the item by typing, quantity, its
   batch number, another line for the next batch. Saved lines sit above the
   blank ones in the same table and stay editable. */
.ostable .c-item { min-width: 14rem; }
.ostable .c-item input { width: 100%; max-width: 20rem; }
.ostable .c-lot input { width: 9rem; }
.ostable .c-x { text-align: center; width: 2.2rem; white-space: nowrap; }
.ostable .c-date { white-space: nowrap; }
.ostable .os-del { font-size: 1.1rem; line-height: 1; padding: 0.1rem 0.4rem; color: var(--ink-2); }
.ostable .os-del:hover { color: var(--bad, #a33); }
.ostable tbody + tbody tr:first-child td { border-top: 2px solid var(--line, #e3ded3); }
.os-foot { display: flex; align-items: center; gap: 1rem; margin-top: 0.8rem; flex-wrap: wrap; }
.os-foot .os-spacer { flex: 1; }
.os-foot .os-date { margin: 0; display: flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; color: var(--ink-2); }
.os-foot .os-date input { width: auto; margin: 0; }
.os-foot > button:last-child { margin: 0; }

/* Opening stock's unit column: the unit a picked item brings, or the picker
   for a name being coined on the line. One column, one answer. */
.ostable .c-unit { white-space: nowrap; }
.ostable .c-unit select { width: auto; margin: 0; }

/* Certifications: one list, one row per certification. The main one is a row
   like any other — the pill says which it is, and it opens in place to its
   own fields rather than living in a different form somewhere else. */
.certrow { display: flex; align-items: center; gap: 0.45rem 0.9rem; flex-wrap: wrap; padding: 0.55rem 0; border-bottom: 1px solid var(--line-soft); }
.certrow:last-child, .certmain:last-child .certrow { border-bottom: 0; }
.certrow-do { margin-left: auto; display: flex; align-items: center; gap: 0.9rem; }
.certrow-do form { margin: 0; }
.certmain summary { list-style: none; cursor: pointer; }
.certmain summary .linkish { color: var(--ink-2); text-decoration: underline; text-underline-offset: 2px; font-size: 0.72rem; }
.certmain summary:hover .linkish { color: var(--ink); }
.certmain summary::-webkit-details-marker { display: none; }
.certmain summary .certrow { margin: 0; }
.certmain[open] summary .certrow { border-bottom: 0; }
.certmain[open] .certedit { border-bottom: 1px solid var(--line-soft); padding-bottom: 1rem; margin-bottom: 0.2rem; }
.certedit { padding-left: 0.1rem; }
@media (max-width: 560px) {
  .certrow-do { margin-left: 0; width: 100%; }
}

/* ---------- the list engine (rule 13: every list scales the same way) ----------
   One search box above the table, sortable headings, a pager underneath. */
.listhead { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; margin: 0.2rem 0 0.9rem; }
.listhead .listsearch { flex: 1 1 14rem; max-width: 24rem; margin: 0; }
.listhead .listcount, .listtitle .listcount { font-size: 0.8rem; white-space: nowrap; }
.listtitle .listcount { font-family: var(--font-ui); font-weight: 400; margin-left: 0.4rem; }
.listhead .listclear { font-size: 0.8rem; }
.listsection { margin-bottom: 0.4rem; }
th.sortable a { color: inherit; text-decoration: none; display: inline-block; }
th.sortable a::after { content: "↕"; opacity: 0.35; margin-left: 0.3em; font-size: 0.7rem; }
th.sortable:hover a::after { opacity: 0.7; }
th.sorted-asc a::after { content: "▲"; opacity: 1; }
th.sorted-desc a::after { content: "▼"; opacity: 1; }
th.sorted-asc, th.sorted-desc { color: var(--ink); }
.pager { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem; margin: -0.5rem 0 1.3rem; font-family: var(--font-ui); font-size: 0.82rem; }
.pager a, .pager span { padding: 0.25rem 0.55rem; border-radius: 8px; }
.pager a { text-decoration: none; }
.pager a:hover { background: var(--inset); }
.pager .here { background: var(--pine-tint); color: var(--pine-deep); font-weight: 600; }
.pager .off { color: var(--ink-3); }
.pager .gap { padding: 0.25rem 0.1rem; color: var(--ink-3); }
.pager .muted { margin-left: auto; }
@media (max-width: 560px) {
  .listhead .listsearch { max-width: none; }
  .pager .muted { margin-left: 0; flex-basis: 100%; }
}
/* Phone rows as stacks (page review 09 F1): a list that opts in (listPage's
   `stack: true`) is a column of short cards at phone width. The row's name
   and its one attention state share the top line — a withdrawal override can
   never sit off the right edge again — and the other facts wrap beneath it,
   each with its column's small name. The headings stay above the cards as a
   row of sort links. Wider screens keep the table exactly as it was. */
@media (max-width: 560px) {
  .tablewrap.stacks { overflow-x: visible; }
  .stacks table, .stacks tbody { display: block; width: 100%; }
  .stacks thead { display: block; }
  .stacks thead tr { display: flex; flex-wrap: wrap; gap: 0 0.15rem; padding: 0.3rem 0.6rem; background: var(--inset); border-bottom: 1px solid var(--line); }
  .stacks th { padding: 0.25rem 0.35rem; border: 0; background: none; }
  .stacks tbody tr { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.2rem 0.85rem; padding: 0.7rem 0.95rem; border-bottom: 1px solid var(--line-soft); }
  .stacks tbody tr:last-child { border-bottom: 0; }
  /* The line break between the top line and the facts: a full-width,
     zero-height flex item slotted between them by order. */
  .stacks tbody tr::before { content: ""; order: 2; flex: 0 0 100%; height: 0; }
  .stacks td { display: block; order: 3; padding: 0; border: 0; white-space: normal; position: static; background: none; }
  .stacks td.st-lead { order: 0; flex: 1 1 auto; min-width: 0; font-weight: 600; }
  .stacks td.st-top { order: 1; flex: 0 1 auto; margin-left: auto; text-align: right; }
  .stacks td.st-hide { display: none; }
  .stacks td[data-label]:not(.st-lead):not(.st-top):not(.st-plain)::before {
    content: attr(data-label); margin-right: 0.3rem; color: var(--ink-3); font-size: 0.72rem;
  }
  .stacks td.empty { order: 0; flex: 1 1 100%; }
}

/* ---------- find anything (design-system rule 12) ---------- */
/* One box under the brand on every page. It sits on the green, so it is the
   green's own input: cream outline, cream placeholder, paper when it has the
   cursor. Tighter than a form field — it is chrome, not a question. */
.find { margin: -0.7rem 0 -0.6rem; padding: 0 0.4rem; }
.find input {
  margin: 0;
  padding: 0.42rem 0.7rem;
  font-size: 0.82rem;
  line-height: 1.3;
  background: rgba(250, 246, 237, 0.09);
  border-color: rgba(250, 246, 237, 0.26);
  color: var(--cream);
}
.find input::placeholder { color: rgba(250, 246, 237, 0.55); }
.find input:focus-visible { background: var(--page); color: var(--ink); border-color: var(--page); box-shadow: 0 0 0 3px rgba(250, 246, 237, 0.28); }
.find input::-webkit-search-cancel-button { filter: invert(1); }
.findlist { list-style: none; padding: 0; margin: 0 0 0.6rem; }
.findlist li { padding: 0.42rem 0; border-bottom: 1px solid var(--line-soft); font-size: 0.92rem; }
.findlist li:last-child { border-bottom: 0; }
kbd { font: 500 0.78rem/1 var(--font-ui); padding: 0.15rem 0.4rem; border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 5px; background: var(--card); }
@media (max-width: 880px) {
  /* In the phone's bar the box takes what the menu and the name leave; in
     the drawer it is hidden. Full width, never wider — the page must not go
     sideways for it. */
  .find { margin: 0; padding: 0; min-width: 0; }
  .find input { width: 100%; box-sizing: border-box; }
}

/* ---------- rule 15: an empty list says what to do first ---------- */
td.emptystate { padding: 2.6rem 1.5rem; text-align: center; white-space: normal; }
.tight td.emptystate { position: static; }
.emptystate .emptybody { max-width: 30rem; margin: 0 auto; }
.emptystate h3 { font-family: var(--font-display); font-weight: 500; font-size: 1.18rem; margin: 0 0 0.45rem; color: var(--ink); text-transform: none; letter-spacing: 0.01em; }
.emptystate p { font-family: var(--font-ui); font-size: 0.88rem; color: var(--ink-2); margin: 0 0 1rem; line-height: 1.5; }
.emptystate a { text-decoration: none; }
@media (max-width: 560px) {
  /* A wide table scrolls inside its frame; the empty state must not scroll
     off with it — pin it to the visible left edge, sized to the screen. */
  td.emptystate { padding: 2rem 1rem; }
  .emptystate .emptybody { margin: 0; max-width: calc(100vw - 4.6rem); position: sticky; left: 1rem; }
}

/* ---------- rule 19: used-up lots step aside ---------- */
.listextra { font-size: 0.8rem; white-space: nowrap; }
.usedup-link, .usedup-toggle { font-size: 0.8rem; font-weight: 500; text-transform: none; letter-spacing: normal; }

/* ---------- rule 30: a list of things with a state has tabs for the states ---------- */
/* The money owed above a sales list (sales-tabs.js owedLine). */
.owed { margin: 0 0 0.7rem; font-size: 0.92rem; color: var(--ink-2); }
.owed a { color: inherit; }
.listtabs { display: flex; flex-wrap: wrap; gap: 0.1rem; margin: 0 0 0.9rem; border-bottom: 1px solid var(--line); }
.listtabs a { padding: 0.5rem 0.85rem; text-decoration: none; color: var(--ink-2); font-family: var(--font-ui); font-weight: 500; font-size: 0.86rem; border-bottom: 2px solid transparent; margin-bottom: -1px; white-space: nowrap; }
.listtabs a:hover { color: var(--ink); }
.listtabs a.active { color: var(--ink); border-bottom-color: var(--pine); }
.listtabs .count { color: var(--ink-3); font-size: 0.76rem; margin-left: 0.25rem; font-variant-numeric: tabular-nums; }
/* State segments: an attention state's count wears the attention colour. */
.listtabs .count.warn { color: var(--terra-ink); font-weight: 600; }
.listtabs .count.bad { color: var(--red); font-weight: 600; }
@media (max-width: 560px) {
  .listtabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .listtabs a { padding: 0.45rem 0.65rem; font-size: 0.82rem; }
}

/* Phone rows as stacks, for the sales lists (page review livestock-14-3;
   src/routes/shared/sales-rows.js): at phone width each sale is a two-line
   card — the customer and the total on top, invoice · date · what beneath,
   the money and goods state under the total. Nothing scrolls sideways and
   nothing is cut off. The cells are found by what they hold (:has), so a
   browser without :has keeps the table as it was. */
.salestack .sl-facts { display: none; }
.salestack .nowrap, .salestack td > .sl-what { white-space: nowrap; }
@media (max-width: 600px) {
  @supports selector(:has(*)) {
    .salestack { overflow-x: visible; }
    .salestack table { min-width: 0; }
    .salestack thead {
      position: absolute; width: 1px; height: 1px; overflow: hidden;
      clip: rect(0 0 0 0); white-space: nowrap;
    }
    .salestack tbody tr {
      display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 0.8rem; row-gap: 0.2rem;
      padding: 0.7rem 0.95rem; border-bottom: 1px solid var(--line-soft);
    }
    .salestack tbody tr:last-child { border-bottom: 0; }
    .salestack tbody td { display: none; padding: 0; border: 0; white-space: normal; position: static; background: none; }
    .salestack tbody td:has(> .sl-facts) { display: block; grid-column: 1; grid-row: 1 / span 2; min-width: 0; overflow-wrap: anywhere; }
    .salestack tbody td:has(> .sl-total) { display: block; grid-column: 2; grid-row: 1; text-align: right; font-weight: 600; white-space: nowrap; }
    .salestack tbody td:has(> .sl-state) { display: block; grid-column: 2; grid-row: 2; text-align: right; }
    .salestack tbody td.empty { display: block; grid-column: 1 / -1; }
    .salestack .sl-facts { display: block; margin-top: 0.2rem; font-size: 0.8rem; color: var(--ink-2); }
    .salestack .sl-state .pills { flex-direction: column; align-items: flex-end; gap: 0.2rem; }
  }
}

/* Rule 18: Save first, the quiet "Save & add another" beside it, the way
   back after that. One primary button per form — the second submit is
   outlined, never a second blue one. */
.formfoot { display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap; margin-top: 0.7rem; }
.formfoot button { margin-top: 0; }
button.again { background: none; color: var(--ink-2); border: 1.5px solid var(--ink-2); padding: calc(0.62rem - 1.5px) 1.2rem; }
button.again:hover { background: none; color: var(--ink); border-color: var(--ink); }
.formfoot a { font-size: 0.85rem; }
.carry-note { margin: 0 0 0.8rem; padding: 0.55rem 0.9rem; border-left: 3px solid var(--btn); background: rgba(30, 43, 38, 0.04); font-size: 0.9rem; }
/* An edit form's state line (page review 05 F1): where a status set by
   records comes from, and the one way to change it — in place of a dropdown. */
.stateline { margin: 0 0 1rem; padding: 0.6rem 0.9rem; border-left: 3px solid var(--pine); background: rgba(30, 43, 38, 0.04); font-size: 0.9rem; line-height: 1.5; }
.stateline label.inline { margin: 0.5rem 0 0; }
/* Rule 23 on an organic-status change (shared/change-reason.js): the "why"
   appears beneath the status the moment it changes. */
.change-reason { margin: 0.1rem 0 0.4rem; padding: 0 0.9rem; border-left: 3px solid var(--ochre); }
.change-reason > .formrow > label { margin: 0.5rem 0; }

/* Rule 22: "+ new" beside a picker opens a small dialog that posts to the
   same create route and comes back with the new one selected. */
.picker-new { margin-left: 0.5rem; font-size: 0.72rem; text-transform: none; letter-spacing: normal; font-weight: 500; }
.picker-new .linkish { font-size: 0.78rem; }
dialog.picker-dialog { border: 0; border-radius: 12px; padding: 1.2rem 1.4rem 1.1rem; width: min(26rem, calc(100vw - 2rem)); background: var(--cream, #FAF6ED); color: var(--ink); box-shadow: 0 18px 50px rgba(30, 43, 38, 0.25); }
dialog.picker-dialog::backdrop { background: rgba(30, 43, 38, 0.45); }
dialog.picker-dialog h2 { margin: 0 0 0.4rem; font-size: 1.15rem; }
dialog.picker-dialog form { margin: 0; }
dialog.picker-dialog .picker-foot { display: flex; align-items: center; gap: 0.9rem; margin-top: 0.8rem; }
dialog.picker-dialog .picker-foot button { margin-top: 0; }
dialog.picker-dialog .picker-error { margin: 0.6rem 0 0; }

/* Rule 23: the reason list; the words box only shows for "Other". */
.reason-words[hidden] { display: none; }

/* The Outcome line (page review 07 F3): what saving will leave, under the
   quantity box, in the page's quiet text — one line, never a paragraph. */
.outcome { margin: 0.1rem 0 0; font-size: 0.88rem; color: var(--ink-2); }
.outcome:empty { display: none; }

/* A rich setting's little editor (the invoice footer): Bold / Italic /
   Underline over an editable box that looks like every other input. */
.rich { margin-top: 0.3rem; }
.rich-toolbar { display: flex; gap: 0.3rem; margin-bottom: 0.3rem; }
.rich-toolbar button { margin: 0; padding: 0.15rem 0.7rem; font-size: 0.85rem; background: var(--cream, #FAF6ED); color: var(--ink); border: 1px solid var(--line, #E4E0D2); }
.rich-toolbar button:hover { background: #EFEAD9; }
.rich-toolbar .rich-bold { font-weight: 700; }
.rich-toolbar .rich-italic { font-style: italic; }
.rich-toolbar .rich-underline { text-decoration: underline; }
.rich-area { min-height: 6rem; padding: 0.6rem 0.8rem; border: 1px solid var(--line, #E4E0D2); border-radius: 10px; background: #fff; font: inherit; font-size: 1rem; font-weight: 400; color: var(--ink); text-transform: none; letter-spacing: normal; line-height: 1.5; white-space: pre-wrap; }
.rich-area:focus-visible { outline: 2px solid var(--green, #1E4D3B); outline-offset: 1px; }

/* A list that must fit its frame rather than scroll sideways (the Sales list,
   2026-09-24): cells wrap, pills stack, nothing is frozen. */
.fits th, .fits td { padding: 0.5rem 0.55rem; vertical-align: middle; }
.fits td .pill, .fits .nowrap { white-space: nowrap; }
.fits td:first-child { min-width: 8.5rem; }
.fits .pills { display: inline-flex; flex-wrap: wrap; gap: 0.25rem; white-space: normal; }
.bulkbar label { display: inline-flex; align-items: center; gap: 0.4rem; white-space: nowrap; text-transform: none; letter-spacing: normal; font-size: 0.9rem; font-weight: 500; color: var(--ink); }
.bulkbar label input[type=date] { margin: 0; }

.fits td a button { white-space: nowrap; }
/* Bulk actions ride along the bottom of the screen while bulk edit is on, so
   ticking a row far down a long list still has its button in view. */
.bulkbar { position: sticky; bottom: 0.8rem; z-index: 5; align-items: center; gap: 0.9rem; flex-wrap: wrap;
  box-shadow: 0 -2px 18px -6px rgba(30, 43, 38, 0.28); border: 1px solid var(--line); }

/* Quick-record chips (page review 01-3): the dashboard's ways into the day's
   records — quiet outline chips under the title, never filled buttons. */
.quickrec { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin: -0.6rem 0 1.2rem; }
.quickrec-label { color: var(--ink-2); font-size: 0.84rem; margin-right: 0.15rem; }
.quickrec a.chip { border: 1.5px solid var(--line); border-radius: var(--r-pill); background: var(--card); padding: 0.25rem 0.8rem; font-size: 0.8rem; line-height: 1.35; color: var(--ink); text-decoration: none; white-space: nowrap; }
.quickrec a.chip:hover { border-color: var(--pine); color: var(--pine); }

/* Setup card steps aside (page review 01-4): once the farm is running, the
   getting-started card is one slim line at the dashboard's foot that opens
   in place, with "Not now" beside it. */
.card.setupslim { display: flex; align-items: flex-start; gap: 0.8rem; padding: 0.8rem 1.2rem; margin-top: 1.4rem; }
.setupslim details { flex: 1; min-width: 0; }
.setupslim summary { list-style: none; cursor: pointer; }
.setupslim summary::-webkit-details-marker { display: none; }
.setupslim-open { color: var(--pine); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; margin-left: 0.3rem; }
.setupslim details[open] .setupslim-open { display: none; }
.setupslim-body { margin-top: 0.6rem; }
.setupslim-hide { margin: 0; flex: none; }
.setupslim-hide button { background: none; color: var(--ink-2); border: 1.5px solid var(--line); }
.setupslim-hide button:hover { background: none; color: var(--ink); border-color: var(--ink-2); }

/* Soonest-first attention list (page review G01-2). On a phone each row
   stacks — what, then when, then the days to go — instead of three
   squeezed columns. */
@media (max-width: 560px) {
  .attention thead { display: none; }
  .attention table, .attention tbody, .attention tr, .attention td { display: block; width: auto; }
  .attention tr { padding: 0.6rem 0.85rem; border-bottom: 1px solid var(--line-soft); }
  .attention tr:last-child { border-bottom: 0; }
  .attention .fits td { padding: 0; border: 0; min-width: 0; }
  .attention td + td { color: var(--ink-2); font-size: 0.86rem; margin-top: 0.15rem; }
  .attention .daysto::after { content: " days to go"; }
}

/* Facts grid (page-review pattern, G03): a record's facts as label over
   value — not one long sentence of dots and pills — wrapping two-up on a
   phone. A wide fact (a verdict with its evidence) takes the whole row. */
.facts { display: grid; grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr)); gap: 0.7rem 1.4rem; margin: 0; }
.facts > div { min-width: 0; }
.facts > div.wide { grid-column: 1 / -1; }
.facts dt { font-size: 0.74rem; color: var(--ink-2); margin: 0; }
.facts dd { margin: 0.15rem 0 0; overflow-wrap: anywhere; }
