/* Sales portal UI — "Soil & Sage".
 *
 * R01: the palette is no longer declared here. It comes from
 * /shared/tokens.css, linked ahead of this file in index.html, so this portal,
 * the HR and grower portals and the public website share one definition.
 * Redeclaring any of those tokens below will fail
 * scripts/ops/check-design-tokens.js in CI — that is the point of the check.
 *
 * Two values changed on adoption, both deliberate:
 *   --warn  #9a7a16 → #715b16   the old value measured 3.11–3.80:1 on our
 *                               surfaces, under WCAG AA for the tag text it is
 *                               used for. The new one measures 5.00–6.13.
 *   --radius  12px → 14px       matching the app and the website.
 */
* { box-sizing: border-box; }
body { margin: 0; background: var(--beige); color: var(--ink); font-family: var(--font); font-weight: var(--weight-body); line-height: 1.6; }
h1,h2,h3 { font-weight: var(--weight-heading); letter-spacing: .01em; margin: 0 0 .5rem; }
h1 { font-size: 1.55rem; } h2 { font-size: 1.15rem; } h3 { font-size: 1rem; }
a { color: var(--link); }
.wrap { max-width: 1180px; margin: 0 auto; padding: 1.5rem 1rem 4rem; }

header { border-bottom: 1px solid var(--hairline); background: var(--beige-alt); }
header .wrap { padding-block: 1rem; display: flex; flex-wrap: wrap; gap: .75rem 1rem; align-items: center; }
.brand { font-size: 1.05rem; margin-right: auto; }
.brand small { display: block; font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-muted); }
.who { font-size: .85rem; color: var(--ink-muted); }

nav.tabs { display: flex; flex-wrap: wrap; gap: .25rem; border-bottom: 1px solid var(--hairline); margin-bottom: 1.5rem; }
nav.tabs button { background: none; border: 0; border-bottom: 2px solid transparent; font: inherit; font-size: .9rem;
  color: var(--ink-muted); padding: .6rem .9rem; min-height: 44px; cursor: pointer; }
nav.tabs button[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--sage); }
nav.tabs button:hover { color: var(--link); }

.card { background: var(--cream); border: 1px solid var(--hairline); border-radius: var(--radius); padding: 1.25rem; margin-bottom: 1rem; }
.card > :last-child { margin-bottom: 0; }
.grid { display: grid; gap: 1rem; }
@media (min-width: 44rem) { .grid.two { grid-template-columns: 1fr 1fr; } .grid.three { grid-template-columns: repeat(3,1fr); } }

label { display: block; font-size: .8rem; color: var(--ink-muted); margin-bottom: .75rem; }
input, select, textarea { display: block; width: 100%; margin-top: .25rem; font: inherit; color: var(--ink);
  background: var(--cream-muted); border: 1px solid var(--hairline); border-radius: 8px; padding: .55rem .7rem; min-height: 44px; }
input:focus, select:focus { outline: 2px solid var(--sage-dark); outline-offset: 1px; }

button.btn { font: inherit; font-size: .85rem; letter-spacing: .04em; min-height: 44px; padding: .55rem 1.2rem;
  border-radius: 999px; border: 1px solid var(--sage-dark); background: var(--sage-dark); color: var(--cream); cursor: pointer; }
button.btn.ghost { background: transparent; color: var(--ink); border-color: var(--hairline); }
button.btn.small { min-height: 34px; padding: .25rem .8rem; font-size: .78rem; }
button.btn:hover { background: var(--link); border-color: var(--link); color: var(--cream); }
button.btn.ghost:hover { background: transparent; color: var(--link); border-color: var(--sage); }
button.btn[disabled] { opacity: .5; cursor: not-allowed; }

.scroll { overflow-x: auto; }
table { border-collapse: collapse; width: 100%; font-size: .86rem; }
th, td { text-align: left; padding: .5rem .6rem; border-bottom: 1px solid var(--hairline); vertical-align: top; }
th { font-weight: var(--weight-ui); font-size: .7rem; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-muted); }
tbody tr:hover { background: var(--cream-muted); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }

.muted { color: var(--ink-muted); } .small { font-size: .82rem; } .mono { font-family: var(--mono); font-size: .8rem; }
.row { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.spread { display: flex; flex-wrap: wrap; gap: .75rem; justify-content: space-between; align-items: baseline; }
.hidden { display: none !important; }
.login { max-width: 25rem; margin: 3rem auto; }

.kpi { font-size: 1.5rem; font-weight: var(--weight-display); letter-spacing: .01em; }
.kpi small { display: block; font-size: .7rem; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-muted); font-weight: var(--weight-ui); }
/* R06 — the invoice line editor.
   Five columns is right on a laptop and unusable on a phone: at 375px each
   field gets about 60px, which is not enough to read a product name or type a
   price. Below the same 44rem breakpoint the rest of this file already uses,
   the line stacks and each field gets the full width.
   The remove button stays on its own row rather than squeezing a sixth column
   in beside the fields. */
.linewrap { display: grid; gap: .4rem; align-items: end; margin-bottom: .5rem;
  padding-bottom: .6rem; border-bottom: 1px solid var(--hairline); }
@media (min-width: 44rem) {
  .linewrap { grid-template-columns: 2fr .6fr .8fr 1.2fr auto; padding-bottom: 0; border-bottom: 0; }
}

/* --- authenticator enrolment (B02) ---------------------------------------
   The QR sits on white, never on the beige page background: quiet-zone
   contrast is what scanners key on, and a tinted background is the usual
   reason a technically-correct symbol will not read. */
.enrol-steps { margin: .5rem 0 .9rem; padding-left: 1.1rem; color: var(--ink-muted); font-size: .85rem; }
.enrol-steps li { margin-bottom: .25rem; }
.qr { width: fit-content; margin: 0 auto .9rem; padding: .6rem; background: #fff;
      border: 1px solid var(--hairline); border-radius: var(--radius); line-height: 0; }
.qr svg { display: block; width: 200px; height: 200px; }
details > summary { cursor: pointer; color: var(--link); padding: .35rem 0; font-size: .85rem; }
details code { display: block; margin-top: .4rem; padding: .5rem .6rem; background: var(--cream-muted);
               border: 1px solid var(--hairline); border-radius: 8px;
               font-family: var(--mono); letter-spacing: .08em; word-break: break-all; }

/* --- serial timeline (I27) ------------------------------------------------
   A vertical line with a dot per step: the unit's own state machine, read top
   to bottom. Vertical rather than horizontal because four steps with dates,
   an actor and two document links each will not sit side by side on a phone —
   R06 exists because that kind of overflow was already measured here. */
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline-step { position: relative; padding: 0 0 1.1rem 1.6rem; }
.timeline-step::before {
  content: "";
  position: absolute;
  left: 0.32rem;
  top: 1rem;
  bottom: -0.2rem;
  width: 1px;
  background: var(--hairline);
}
.timeline-step:last-child::before { display: none; }
.timeline-dot {
  position: absolute;
  left: 0;
  top: 0.3rem;
  width: 0.75rem;
  height: 0.75rem;
  border-radius: 50%;
  border: 1px solid var(--hairline);
  background: var(--cream);
}
.timeline-step.done .timeline-dot { background: var(--status-good-ink); border-color: var(--status-good-ink); }
.timeline-step.now .timeline-dot { background: var(--sage); border-color: var(--sage-dark); box-shadow: 0 0 0 3px var(--tint-sage); }
.timeline-label { font-weight: var(--weight-ui); }
/* A step not yet reached is context, not content: it must read as lighter
   without dropping under AA, so the muted ink carries it rather than opacity. */
.timeline-step.future .timeline-label { color: var(--ink-muted); }
.timeline-body > .row { margin-top: 0.35rem; }

@media print {
  /* The line and dots are colour on paper; keep the structure, lose the ink. */
  .timeline-step.now .timeline-dot { box-shadow: none; }
  .timeline-step { break-inside: avoid; }
}

/* --- bulk action bar (I29) ------------------------------------------------
   Sits above the table and appears only with a selection, so the list reads as
   a list until it is being used as a worklist. */
.bulkbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  margin-bottom: 0.75rem;
  padding: 0.6rem 0.8rem;
  background: var(--cream-muted);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
}
.bulkbar > .small:first-child { margin-right: auto; font-weight: var(--weight-ui); }
@media print { .bulkbar { display: none; } }

/* --- K01 brand lockup ------------------------------------------------------
   The logo is a PNG with its own black panel baked in, so it is NOT tinted or
   given a background here — doing either would put a box inside a box. It is
   sized in rem so it tracks the header's type rather than pinning to a pixel
   height that stops matching when the density control changes the scale. */
.brand { display: flex; align-items: center; gap: 0.6rem; }
.brand__logo { height: 2rem; width: 2rem; display: block; border-radius: 7px; }
.brand__text { display: block; }
@media (max-width: 34rem) {
  /* On a phone the lockup and the words say the same thing twice, and the
     header has no room for both. The logo carries it. */
  .brand__text { display: none; }
}
