/* ============================================================================
   finance.css — the petty cash book.

   Written phone-first, because that is where an entry is actually made: at
   the counter, one hand, straight after the money left the box. The desktop
   table is the same markup widened, not a second design.
   ========================================================================= */

/* --- shop and month bar --------------------------------------------------- */

.fin-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  margin-bottom: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.fin-bar-shop,
.fin-bar-month {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Once the two groups wrap onto separate lines, each takes the full width and
   spreads — otherwise the month arrows end up huddled under the shop label
   with the rest of the row empty beside them. */
@media (max-width: 560px) {
  .fin-bar-shop,
  .fin-bar-month {
    flex: 1 0 100%;
    justify-content: space-between;
  }

  .fin-shop-select { max-width: none; flex: 1 1 auto; margin-left: 10px; }
  .fin-bar > span:empty { display: none; }
  .fin-bar { padding: 8px 10px; }
  .fin-bar-month .btn { min-width: 44px; min-height: 44px; }
}

.fin-bar-label {
  font-size: 12px;
  color: var(--ink-faint);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.fin-shop-name {
  font-weight: 600;
  color: var(--ink);
}

.fin-shop-select {
  width: auto;
  min-width: 150px;
  max-width: 220px;
}

.fin-month-label {
  min-width: 96px;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--ink);
}

/* --- the four figures ----------------------------------------------------- */

/* Two across on a phone, four on a desktop. The closing balance is the one
   anybody opened this screen for, so it is the one that carries weight. */
.fin-summary {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 16px;
}

@media (min-width: 720px) {
  .fin-summary { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.fin-figure {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.fin-figure-label {
  font-size: 12px;
  color: var(--ink-soft);
}

.fin-figure-value {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 18px;
  font-weight: 600;
  color: var(--ink);
}

.fin-figure--in  .fin-figure-value { color: var(--success-ink); }
.fin-figure--out .fin-figure-value { color: var(--danger); }

.fin-figure--total {
  background: var(--accent-soft);
  border-color: var(--accent);
}
.fin-figure--total .fin-figure-value { color: var(--accent-deep); font-size: 20px; }

/* --- the form ------------------------------------------------------------- */

.fin-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
  margin-bottom: 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}

.fin-form-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 17px;
  color: var(--ink);
}

.fin-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
}

@media (min-width: 560px) {
  .fin-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.fin-form-actions {
  display: flex;
  gap: 10px;
}

.fin-form-actions .btn { flex: 1 1 auto; }

/* Money is read as a column of digits, so it is set in the mono face and
   large enough to check without leaning in. */
.fin-amount-input {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 18px;
  font-weight: 600;
}

/* A tick in a table, big enough to hit with a thumb. The delivery picker is
   a column of these and the whole shipment is decided by them, so they are
   not the browser's 13px default. */
.fin-tick {
  width: 20px;
  height: 20px;
  accent-color: var(--success);
  cursor: pointer;
}

/* What the ticked lines come to, under the table they came from. Green
   because it is a figure somebody is about to commit to, and it sits where
   the desktop tool puts it. */
.fin-form-total {
  margin: 6px 0 10px;
  text-align: right;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--success-ink);
  min-height: 1.2em;
}

/* --- direction ------------------------------------------------------------ */

/* The single most important control on the page. Two whole months of the
   old book's expenses had been typed into the Cash In column; here the
   choice is a pair of buttons whose selected state is visible from arm's
   length, in a colour that says which way the money went. */
.fin-dir-group {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.fin-dir {
  padding: 12px 8px;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-soft);
  background: var(--surface-alt);
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.fin-dir[aria-pressed='true'] {
  color: var(--action-ink);
}

.fin-dir--out[aria-pressed='true'] {
  background: var(--danger);
  border-color: var(--danger);
}

.fin-dir--in[aria-pressed='true'] {
  background: var(--success);
  border-color: var(--success);
}

.fin-dir:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* --- category ------------------------------------------------------------- */

.fin-cat-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
}

.fin-cat-row .field-input { flex: 1 1 auto; }
.fin-cat-row .btn { flex: 0 0 auto; }

.fin-cat-form {
  display: flex;
  gap: 8px;
  margin: 12px 0;
}

.fin-cat-form .field-input { flex: 1 1 auto; }

.fin-cat-manage {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.fin-cat-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.fin-cat-item-name { font-weight: 500; color: var(--ink); }

/* --- voucher photo -------------------------------------------------------- */

.fin-photo-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.fin-photo-state {
  font-size: 13px;
  color: var(--ink-soft);
}

/* Small enough to prove the right picture was attached, not so large that
   the Save button falls off the bottom of a phone screen. */
.fin-photo-preview {
  display: block;
  max-width: 180px;
  max-height: 180px;
  margin-top: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  object-fit: cover;
}

.field-label--soft {
  display: block;
  margin-top: 10px;
  color: var(--ink-faint);
  font-weight: 500;
}

/* --- the ledger ----------------------------------------------------------- */

.fin-book-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

.fin-book-head .btn { margin-left: auto; }
.fin-book-head .btn ~ .btn { margin-left: 0; }

.fin-badge {
  padding: 4px 10px;
  font-size: 12px;
  font-weight: 600;
  border-radius: 999px;
}

.fin-badge--closed {
  color: var(--warning);
  background: var(--warning-soft);
}

/* A long table scrolls inside its own box, both ways.
 *
 * It used to be the page that scrolled: a hundred orders made the page two
 * thousand pixels tall, and the only sideways scrollbar was at the very
 * bottom of it -- so reading the last column of the first row meant dragging
 * the whole page down, scrolling across, and coming back up. Now the box is
 * at most a screenful tall, its scrollbar is always where the table is, and
 * the column headings stay put while the rows move under them.
 */
/* Since 2026-10-25 (the user's word) the box no longer scrolls up and down:
   one scroll, the page's, and a long table comes a page at a time
   (auto-pager.js). It still scrolls sideways where the table is wider. */
.fin-table-wrap {
  overflow: auto;
  overscroll-behavior-x: contain;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.fin-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  /* Opaque, or the rows show through as they pass underneath. */
  background: var(--surface-alt);
  box-shadow: inset 0 -1px 0 var(--border);
}

.fin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.fin-table th,
.fin-table td {
  padding: 10px 12px;
  text-align: left;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

.fin-table th {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  background: var(--surface-alt);
  white-space: nowrap;
}

.fin-table tbody tr:last-child td { border-bottom: none; }

/* Scoped to the table on purpose: `.fin-table th` and `.fin-table td` set
   text-align above and outrank a bare class, so a money column laid out with
   .fin-num alone stayed left-aligned and the digits never lined up. */
.fin-table .fin-num {
  text-align: right;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.fin-in  { color: var(--success-ink); }
.fin-out { color: var(--danger); }
.fin-balance { font-weight: 600; color: var(--ink); }

.fin-th-no, .fin-td-no { width: 40px; color: var(--ink-faint); }
.fin-td-desc { min-width: 180px; }
.fin-td-actions { white-space: nowrap; }
.fin-td-actions .btn + .btn { margin-left: 6px; }
.fin-slip-none { color: var(--ink-faint); }

/* The narrowest column in the table, and a label that wrapped inside its own
   button turned a two-word control into a two-line one. */
.fin-td-slip, .fin-slip-btn { white-space: nowrap; }

/* On a phone the table stops being a table: every row becomes a card and
   each cell prints the heading it lost. A nine-column grid on a 360px
   screen is unreadable either way, and one markup is one thing to fix.
   A tablet is no better: at 768px eighteen lists scrolled sideways, so the
   cards run up to the width the module's side list appears at. */
@media (max-width: 860px) {
  /* A button in a card's cell has a third of the card: its words may wrap there. */
  .fin-table td .btn { white-space: normal; }
  .fin-table, .fin-table tbody, .fin-table tr, .fin-table td { display: block; }
  .fin-table thead { display: none; }

  .fin-table tr {
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
  }

  .fin-table td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 3px 0;
    border: none;
    text-align: right;
  }

  .fin-table td::before {
    content: attr(data-label);
    font-size: 12px;
    font-weight: 600;
    color: var(--ink-faint);
    text-align: left;
  }

  /* An empty Cash In on an expense line is noise on a card — the Cash Out
     row beside it already says which way the money went. */
  .fin-table td:empty { display: none; }

  .fin-td-desc { font-weight: 500; }

  /* The narrow column that keeps the row number tidy in a table would pin it
     next to its own label on a card, out of line with every other value. */
  .fin-td-no { width: auto; }

  .fin-td-actions {
    justify-content: flex-end;
    padding-top: 8px;
  }
  .fin-td-actions::before { content: none; }
}

/* A card per row, but short: two values to a line, each under its label,
   rather than one long label-and-value list. Words and buttons still get
   the whole width. */
@media (max-width: 860px) {
  .fin-table tr {
    display: grid;
    /* Three across: a month of lines is a long scroll at two. */
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px 12px;
    margin-bottom: 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
  }
  .fin-table tbody tr:last-child { border-bottom: 1px solid var(--border); }
  .fin-table-wrap { border: 0; background: none; overflow: visible; max-height: none; }
  .fin-table td {
    display: grid;
    align-content: start;
    justify-content: stretch;
    gap: 1px;
    padding: 0;
    text-align: left;
    min-width: 0;
    overflow-wrap: anywhere;
  }
  .fin-table td::before { font-family: var(--font-body); font-size: 12px; font-weight: 700; letter-spacing: 0; line-height: 1.35; }
  .fin-table .fin-num { text-align: left; font-size: 15px; }
  .fin-table .fin-td-desc,
  .fin-table .fin-td-actions,
  .fin-table td:has(> button),
  .fin-table td:has(> .row-actions),
  .fin-table td:has(> a.btn) { grid-column: 1 / -1; }
  .fin-table .fin-td-actions { display: flex; justify-content: flex-end; padding-top: 4px; border-top: 1px solid var(--border); }
  .fin-table tfoot tr { background: var(--surface-alt); }
  /* The running number is the table's, not the entry's; the date and the
     voucher already say which line this is. */
  .fin-table tbody .fin-td-no { display: none; }
  /* Target Calculate keeps the layout it has always had on a phone: the
     office reads it as its sheet, and asked for it left as it was. */
  .fin-table-wrap:has(> .tgt-report), .tgt-summary .fin-table-wrap {
    overflow: auto; max-height: min(72vh, 780px);
    border: 1px solid var(--border); background: var(--surface);
  }
  .fin-table.tgt-report tr, .tgt-summary .fin-table tr {
    display: block; gap: 0; margin: 0; padding: 12px 14px;
    border: 0; border-bottom: 1px solid var(--border); border-radius: 0; background: none;
  }
  .fin-table.tgt-report td, .tgt-summary .fin-table td {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
    padding: 3px 0; text-align: right; overflow-wrap: normal;
  }
  .fin-table.tgt-report .fin-num, .tgt-summary .fin-table .fin-num { text-align: right; font-size: inherit; }
  .fin-table .fin-td-slip { grid-column: auto; }
  .fin-table .fin-td-slip .btn, .fin-table .fin-td-slip button { min-height: 36px; padding: 4px 10px; font-size: 13px; width: auto; justify-self: start; }
}

/* --- where the money went ------------------------------------------------- */

.fin-cats {
  margin: 18px 0;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.fin-cats-title {
  margin: 0 0 10px;
  font-family: var(--font-display);
  font-size: 15px;
  color: var(--ink);
}

.fin-cats-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.fin-cat {
  display: grid;
  grid-template-columns: minmax(96px, 1fr) 2fr auto;
  align-items: center;
  gap: 10px;
  font-size: 13px;
}

.fin-cat-name { color: var(--ink); }

.fin-cat-bar {
  height: 8px;
  background: var(--surface-alt);
  border-radius: 999px;
  overflow: hidden;
}

.fin-cat-fill {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: 999px;
}

.fin-cat-amount {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}

/* --- opening balance ------------------------------------------------------ */

.fin-opening {
  display: grid;
  grid-template-columns: auto minmax(120px, 200px) auto;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.fin-opening .form-note {
  grid-column: 1 / -1;
  margin: 0;
}

/* A grid cell stretches its child; a Save button as wide as the field beside
   it reads like a second field. */
.fin-opening .btn { justify-self: start; }

@media (max-width: 560px) {
  .fin-opening { grid-template-columns: 1fr auto; }
  .fin-opening .field-label { grid-column: 1 / -1; }
}

/* --- the photo viewer ----------------------------------------------------- */

.fin-slip-dialog {
  width: min(92vw, 640px);
  max-height: 88vh;
  padding: 0;
  border: none;
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

.fin-slip-dialog::backdrop {
  background: rgba(16, 32, 58, 0.6);
}

.fin-slip-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}

.fin-slip-title {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--ink-soft);
}

.fin-slip-body {
  padding: 12px;
  max-height: calc(88vh - 60px);
  overflow: auto;
  text-align: center;
}

/* A receipt is read by zooming in, so it fills the width and scrolls
   rather than being shrunk to fit the box. */
.fin-slip-img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
}

.form-note--ok {
  color: var(--success-ink);
  font-weight: 600;
}

/* ============================================================================
   Daily Sale — the second book behind the Finance Data card.
   ========================================================================= */

/* --- choosing a book ------------------------------------------------------ */

.fin-modules {
  max-width: 720px;
  margin: 0 auto;
}

.fin-modules-title {
  margin: 0 0 14px;
  font-family: var(--font-display);
  font-size: 18px;
  color: var(--ink);
  text-align: center;
}

/* The way back to the choice sits at the head of the tab strip rather than
   above it, so it does not push the tabs down a line on a phone. */
.tab-btn--back {
  color: var(--ink-soft);
  font-weight: 500;
}

/* --- one day's takings ---------------------------------------------------- */

/* A field per channel. Two across on a phone, four on a desktop: the sheet
   this replaces had fourteen of them on one row, which is a horizontal
   scroll nobody finishes. */
.sale-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

@media (min-width: 620px) {
  .sale-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 900px) {
  .sale-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.sale-grid .field-label {
  font-size: 12px;
  color: var(--ink-soft);
}

.sale-grid .fin-amount-input {
  font-size: 16px;
}

/* The total as it is typed — the only check anyone actually performs against
   the cash drawer, so it stays in front of them while they type. */
.sale-running {
  flex-direction: row;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

/* --- channels ------------------------------------------------------------- */

.sale-ch-group + .sale-ch-group {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}

/* Bank and Pay takings, shown beside the cash they are not part of. Muted so
   the eye follows the column that actually moves the balance. */
.fin-table .fin-muted { color: var(--ink-faint); }

/* A heading over one kind of channel in the entry form. */
.sale-ch-block + .fin-figure { margin-top: -4px; }

/* --- what stands where the form was, once a record is in ------------------ */

/* Deliberately the same card as the form it replaces, so nothing jumps: the
   panel keeps its position on the page and only its contents change. */
.sale-saved-figures {
  margin-bottom: 0;
}

.sale-saved .fin-figure-value {
  font-size: 17px;
}

/* --- a summed column, marked off from the ones it sums ------------------- */

/* With one channel of each kind the totals repeat the figures beside them,
   and a column that looks like its neighbours but is not one of them reads
   as a duplicate entry. The rule and the tint say "this side is a sum". */
.fin-table .fin-sum {
  background: var(--surface-alt);
}

.fin-table th.fin-sum,
.fin-table td.fin-sum {
  border-left: 2px solid var(--border);
}

/* The pair is one block, so only the first of them carries the divider. */
.fin-table .fin-sum + .fin-sum {
  border-left: none;
}

/* On a phone the table is a stack of cards and there are no columns to sit
   between, so the mark becomes a bar down the side of the two lines. */
@media (max-width: 720px) {
  .fin-table td.fin-sum {
    padding-inline: 8px 0;
    background: none;
    border-left: 3px solid var(--accent-soft);
  }

  .fin-table td.fin-sum + .fin-sum {
    border-left: 3px solid var(--accent-soft);
  }
}

/* The codes a price list does not carry, on the PO convert screen. Collapsed
   by default and tinted, because it is the part that needs acting on and the
   priced table below it is long enough to bury anything. */
.pur-unmatched {
  margin: 12px 0;
  padding: 10px 12px;
  border: 1px solid var(--warning);
  border-radius: var(--radius-sm);
  background: var(--warning-soft);
}

.pur-unmatched > summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  color: var(--warning);
}

/* The supplier picker and its "add a code" button, side by side. */
.pur-supplier {
  display: flex;
  gap: 8px;
  align-items: center;
}

.pur-supplier > select { flex: 1 1 auto; min-width: 0; }
.pur-supplier > .btn { flex: 0 0 auto; }

/* A figure that is absent rather than zero. */
.fin-muted { color: var(--ink-faint); }

/* The same shrink problem as .panel, one level down. A grid or flex child
   keeps its content's natural width unless told otherwise, so one long
   figure — a total in the millions, a shop name that does not break —
   widened its tile, then the row, then the page. */
.fin-summary > *,
.fin-figure,
.fin-figure > * { min-width: 0; }

.fin-figure-label,
.fin-figure-value { overflow-wrap: anywhere; }

/* The four stages an order passes through, as a strip of counts. Scrolls
   sideways on a phone rather than wrapping into a block of buttons. */
.pur-stages {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding-bottom: 4px;
}

.pur-stage {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-faint);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.pur-stage.is-active {
  border-color: var(--brand-line, var(--ink));
  background: var(--ink);
  color: #fff;
}

.pur-stage-count {
  padding: 0 6px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.08);
  font-variant-numeric: tabular-nums;
}

.pur-stage.is-active .pur-stage-count { background: rgba(255, 255, 255, 0.22); }

/* The row above a list: what narrows it, what acts on it, and how many
   rows survived. Wraps rather than scrolling, because the count is the part
   that must stay visible and it sits at the end. */
.pur-filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 10px 0 12px;
  min-width: 0;
}

.pur-filter-bar > * { min-width: 0; }

.pur-search { max-width: 240px; min-width: 0; }

.pur-count {
  margin-left: auto;
  color: var(--success-ink);
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* "Custom Date [from] ~ [to]" — the boxes go flat until the tick turns
   them on, so an untouched filter does not look like an active one.

   Wraps on a phone: two date boxes and a label do not fit across 375px, and
   a filter bar that pushes the page sideways makes the list under it
   unreadable. */
.pur-daterange {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0;
  min-width: 0;
}

.pur-date { width: auto; min-width: 0; flex: 1 1 130px; }
.pur-date:disabled { opacity: 0.5; }
.pur-tilde { color: var(--ink-faint); }

/* The consignment summary under a route's list. Short, because it is read
   at a glance and the list above it is the long one. */
.pur-rcly-totals { max-height: 220px; overflow-y: auto; }
.pur-rcly-totals tr.is-active { background: var(--success-soft); }

/* A table cell that is the figure somebody came to the page for. */
.fin-table .is-total { color: var(--success-ink); font-weight: 700; }

/* A button that reads as part of the text it sits in — for a code or a
   number that happens to be clickable. */
.btn-link {
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.btn-link:hover { color: var(--success-ink); }

/* A whole list row that is a button: the voucher is the thing being picked
   and a small button beside the text makes the text look like a label. */
.row-pick {
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: 100%;
  padding: 4px 0;
  border: 0;
  background: none;
  text-align: left;
  font: inherit;
  cursor: pointer;
}

.row-pick .row-title { font-weight: 700; }
.row-item.is-active { border-color: var(--success); background: var(--success-soft); }

/* An RCLY typed into a table cell. Narrow enough not to push the row wide,
   wide enough for "RCLY260926520". */
.pur-rcly-input {
  min-width: 140px;
  font-family: var(--font-mono);
}

/* The delivery picker, the shape the desktop tool uses: the supplier's
   vouchers down the left, the chosen one's lines across the rest. The two
   answer each other, so they have to be on screen together.

   Below a phone's width they stack, and the voucher list comes first — it
   is the question the rest of the screen depends on. */
.pur-pick {
  display: grid;
  grid-template-columns: minmax(190px, 230px) minmax(0, 1fr);
  gap: 16px;
  align-items: start;
  margin: 12px 0;
}

.pur-pick-left,
.pur-pick-right { min-width: 0; }

/* Long enough to show a few without the page growing a scrollbar of its
   own; a supplier with thirty open vouchers scrolls inside the box. */
.pur-vouchers { max-height: 360px; overflow-y: auto; }

/* DL, China Packing List and Total Box across the top, wrapping as they
   must rather than squeezing the date box to nothing. */
.pur-pick-head {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 4px;
}

.pur-pick-head .field { flex: 1 1 200px; min-width: 0; margin: 0; }

@media (max-width: 760px) {
  .pur-pick { grid-template-columns: minmax(0, 1fr); }
  .pur-vouchers { max-height: 220px; }
}

/* --- where is this product? ----------------------------------------------

   One card per product, shut until asked. A code that is on nine orders is
   nine journeys, and all nine at once buries the one being asked about. */
.pur-found {
  margin: 10px 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  overflow: hidden;
}

.pur-found-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  width: 100%;
  padding: 12px 14px;
  border: 0;
  background: none;
  text-align: left;
  font: inherit;
  cursor: pointer;
}

.pur-found-head:hover { background: var(--surface-2, rgba(0, 0, 0, 0.02)); }
.pur-found-code { font-family: var(--font-mono); font-weight: 700; color: var(--ink); }
.pur-found-name { flex: 1 1 220px; min-width: 0; color: var(--ink-soft); }
.pur-found-qty {
  color: var(--success-ink);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.pur-found-order {
  padding: 12px 14px;
  border-top: 1px solid var(--border);
}

.pur-found-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.pur-found-voucher { font-family: var(--font-mono); font-weight: 700; }

/* How far this order has got, in one word and one colour. */
.pur-stage-tag {
  padding: 2px 9px;
  border-radius: 999px;
  background: var(--border);
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

.pur-stage-tag.is-arrived { background: var(--success-soft); color: #0C7150; }
.pur-stage-tag.is-routed,
.pur-stage-tag.is-sent { background: var(--brand-color); color: var(--ink); }

/* The journey, as a list of steps. What has happened is solid; what has not
   is grey — which is the whole answer to "where is it". */
.pur-track { margin: 0; padding: 0; list-style: none; }

.pur-step {
  display: grid;
  grid-template-columns: 140px 110px minmax(0, 1fr);
  gap: 4px 12px;
  padding: 5px 0 5px 16px;
  border-left: 2px solid var(--border);
  color: var(--ink-faint);
  font-size: 13px;
}

.pur-step.is-done { border-left-color: var(--success); color: var(--ink); }
.pur-step-label { font-weight: 600; }
.pur-step-when { font-variant-numeric: tabular-nums; }
.pur-step-detail { color: var(--ink-soft); overflow-wrap: anywhere; }

@media (max-width: 560px) {
  .pur-step { grid-template-columns: minmax(0, 1fr) auto; }
  .pur-step-detail { grid-column: 1 / -1; }
}

/* A section of the PO detail: a heading, the buttons that act on it, and
   the figures they change. The eight-button row this replaced said nothing
   about which button did what. */
.pur-block {
  margin: 16px 0;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
}

.pur-block > .panel-head { margin: 0 0 10px; }
.pur-block > .panel-head .panel-title { font-size: 14px; }
.pur-block .fin-summary { margin: 0; }
.pur-block > .form-note { margin: 0; }

/* The detail's header, the shape the desktop dialog uses: what the order is
   on the left, everything that can be done to it on the right of the same
   line. Wraps to two lines on a narrow screen rather than squeezing. */
.pur-detail-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px 20px;
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}

.pur-detail-id { display: flex; flex-wrap: wrap; gap: 6px 28px; min-width: 0; }
.pur-detail-field { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.pur-detail-value {
  font-family: var(--font-mono);
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.pur-detail-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-end;
}

/* A field and the button that saves it, on one line. */
.pur-detail-row {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  margin: 12px 0;
}

.pur-detail-row .field { flex: 1 1 auto; min-width: 0; margin: 0; }

/* --- the Purchase section's own navigation --------------------------------

   Eleven pages down the left, the way the desktop tool lists them. Across
   the top they did not fit: the last tab ran off the edge of the screen and
   there was nothing to say it was there.

   The sidebar sticks, so moving between pages does not mean scrolling back
   up a long list of orders to find the next one. */
.pur-shell {
  display: grid;
  grid-template-columns: minmax(170px, 200px) minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}

.pur-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  position: sticky;
  top: 12px;
  /* Its own scroll, so a long list of pages never depends on where the
     work beside it has got to. */
  max-height: calc(100vh - 24px);
  overflow-y: auto;
  scrollbar-width: thin;
  padding-right: 14px;
  border-right: 1px solid var(--border);
}

.pur-nav-btn {
  padding: 9px 12px;
  border: 0;
  border-left: 3px solid transparent;
  border-radius: 0 8px 8px 0;
  background: none;
  color: var(--ink-soft);
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  text-decoration: none;
  transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}

.pur-nav-btn:hover { color: var(--ink); background: rgba(0, 0, 0, 0.03); }
/* A run of pages that belong together, headed once (Assets & Inventory). */
.pur-nav-group {
  margin: 12px 0 2px; padding: 0 12px;
  font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint);
}
/* In a module whose pages are grouped, a group's heading reads as a heading:
   dark and heavy, a rule above it, and its pages set in under it — lighter,
   so "Admin Purchase" the group is not taken for "Admin Purchase" the page. */
.pur-nav--desk .pur-nav-group {
  margin: 14px 0 4px; padding: 12px 12px 0; border-top: 1px solid var(--border);
  font-family: var(--font-display); font-size: 13px; font-weight: 800; letter-spacing: 0.04em; color: var(--ink);
}
.pur-nav--desk .pur-nav-btn { font-weight: 700; color: var(--ink); }
.pur-nav--desk .pur-nav-group ~ .pur-nav-btn { padding-left: 24px; font-size: 13.5px; font-weight: 500; color: var(--ink-soft); }
.pur-nav--desk .pur-nav-group ~ .pur-nav-btn.is-active { font-weight: 700; color: var(--accent-deep); }
/* A strip that scrolls sideways has no room for headings above its items. */
@media (max-width: 860px) { .pur-nav-group { display: none; } }
/* The way back to the module list, set apart from the pages. */
.pur-nav-back { margin-bottom: 6px; color: var(--ink-faint); font-weight: 500; }

.pur-nav-btn.is-active {
  border-left-color: var(--accent);
  background: var(--accent-soft, rgba(0, 0, 0, 0.04));
  color: var(--accent-deep);
}

/* Work waiting on a page, said on the link to it. */
.nav-badge {
  display: inline-block; min-width: 18px; margin-left: 6px; padding: 0 5px;
  border-radius: 9px; background: var(--danger); color: #fff;
  font-size: 12px; font-weight: 700; line-height: 18px; text-align: center; vertical-align: 1px;
}

/* A module with many pages, on a phone: its groups in a grid, all in sight,
   and under them the pages of the open group. Nothing runs off the edge. */
.grp-nav { display: none; }
@media (max-width: 860px) {
  .pur-nav.pur-nav--desk { display: none; }
  .grp-nav { display: grid; gap: 8px; }
  .grp-nav-groups { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
  .grp-nav-group {
    display: flex; align-items: center; justify-content: center; min-height: 44px; padding: 6px 4px;
    border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
    color: var(--ink-soft); font-size: 13px; font-weight: 600; line-height: 1.3; text-align: center; text-decoration: none;
  }
  .grp-nav-group.is-active { border-color: var(--accent); background: var(--accent-soft, rgba(0, 0, 0, 0.04)); color: var(--accent-deep); }
  .grp-nav-tabs { display: flex; flex-wrap: wrap; gap: 6px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
  .grp-nav-tab {
    display: inline-flex; align-items: center; min-height: 40px; padding: 6px 12px;
    border-radius: 20px; background: var(--surface-alt, rgba(0, 0, 0, 0.04));
    color: var(--ink-soft); font-size: 13px; font-weight: 600; text-decoration: none; white-space: nowrap;
  }
  .grp-nav-tab.is-active { background: var(--ink); color: #fff; }
}

/* On a phone it goes back to being a strip that scrolls sideways: a sidebar
   would take half the screen and leave the work in a column too narrow to
   read a table in. */
@media (max-width: 860px) {
  .pur-shell { grid-template-columns: minmax(0, 1fr); gap: 16px; }

  /* Its pages wrap onto as many lines as they need: a strip that scrolled
     sideways hid most of thirteen pages past the edge of the screen. */
  .pur-nav {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px;
    max-height: none;
    padding: 0 0 10px;
    border-right: 0;
    border-bottom: 1px solid var(--border);
    overflow: visible;
    -webkit-mask-image: none !important;
    mask-image: none !important;
  }

  .pur-nav-btn {
    flex: none;
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    padding: 6px 12px;
    border: 0;
    border-radius: 20px;
    background: var(--surface-alt);
    font-size: 13px;
    white-space: nowrap;
  }

  .pur-nav-btn.is-active {
    background: var(--ink);
    color: #fff;
  }
}

/* The code box beside the description box. Narrower, because a product
   code is eight digits and a description is a sentence. */
.pur-find-code { max-width: 180px; }

/* --- checking the forwarder's bill ---------------------------------------

   Which of weight and volume they charged on. Worth a badge rather than a
   word in a column: it is the whole reason a bill can look wrong and be
   right, and the eye should find it without reading. */
.pur-basis {
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  font-family: var(--font-mono);
}

.pur-basis.is-kg { background: var(--border); color: var(--ink-soft); }
.pur-basis.is-cbm { background: var(--brand-color); color: var(--ink); }
.pur-basis.is-volumetric { background: var(--brand-color); color: var(--ink); }

/* The working and the charges, one step to a line: a formula that wraps
   mid-way reads as two formulas. */
.pur-working-line { display: block; white-space: nowrap; }
.pur-charges .pur-working-line { font-size: 12px; }

/* Which way the consignment travelled. The bill does not say — it carries
   two city names and nothing else — so this is a picker in every row rather
   than a word: what this app recorded is a starting point and the office is
   the authority. One that nobody has answered is outlined, because an
   unanswered row is not priced and the eye should find it. */
.pur-route-cell { display: inline-flex; align-items: center; gap: 6px; }

.pur-route-pick {
  width: auto;
  min-width: 92px;
  padding: 3px 6px;
  font-size: 12px;
}

.pur-route-pick.is-empty {
  border-color: var(--danger);
  color: var(--danger);
}

/* A line that does not add up. Not shouting — most bills are right, and a
   row picked out in red on a page of forty is doing its whole job. */
.fin-table tr.is-wrong td { background: var(--danger-soft, #fef2f2); }
.is-wrong-num { color: var(--danger); font-weight: 700; }

/* The totals under a list: bold, ruled off from the rows above, and the
   ticked lot tinted so it is not read as the whole. */
.fin-table tfoot td {
  font-weight: 700;
  border-top: 2px solid var(--border);
  background: var(--surface-2, #f8fafc);
}
.fin-table tr.pur-total-row.is-picked td { background: var(--success-soft, #ecfdf5); }
.pur-total-box { font-size: 1.1em; }

/* Whether the supplier's own packing list has arrived. Nothing leaves the
   supplier without one, so an order that has not got one is stuck whatever
   else is true of it — worth seeing down a column rather than after opening
   a hundred orders in turn. */
.pur-china-yes { color: var(--success-ink); font-weight: 700; }
.pur-china-no { color: var(--danger); font-weight: 700; }

/* A button that is a switch rather than an action: it shows which way it
   is set, and the label says what pressing it would do next. */
.btn.is-on {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-deep);
}

/* How long an order has waited unasked. A week without anybody chasing is
   the thing worth seeing from across the room. */
.pur-asked { font-variant-numeric: tabular-nums; }
.pur-asked--never,
.pur-asked--stale { color: var(--danger); font-weight: 700; }

/* Each list on the "today" screen: what is stuck, and the way to it. */
.pur-today-block { margin-top: 18px; }
.pur-today-block > .panel-head { margin-bottom: 8px; }

/* What has happened to an order, folded away until asked for. */
.pur-history { margin: 12px 0; }
.pur-history > summary { cursor: pointer; font-size: 13px; font-weight: 700; }

/* --- Ma A Lin's book ------------------------------------------------------- */

.pur-agent-month { display: flex; align-items: center; gap: 6px; }
.pur-agent-month-label { min-width: 84px; text-align: center; font-weight: 600; }

/* Payment and top-up side by side where there is room for both — measured
   against the panel itself rather than the window, because the Purchase
   sidebar takes a fifth of a tablet and the window width says nothing about
   what is left for the forms. */
.pur-agent-forms {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  gap: 14px;
  margin-bottom: 18px;
}
.pur-agent-forms .fin-form { margin-bottom: 0; min-width: 0; }

/* The same for the fields inside a form. */
.fin-grid.pur-agent-grid {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr));
}
.pur-agent-grid > *,
.pur-agent-grid .field-input { min-width: 0; }

.pur-agent-status { display: flex; gap: 8px; flex-wrap: wrap; }
.pur-agent-accounts { margin: 0 0 10px; }
.pur-agent-status .btn.is-active { background: var(--success); border-color: var(--success); color: #fff; }
.pur-agent-status .btn.is-active.is-pending { background: var(--danger); border-color: var(--danger); }

.pur-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.pur-chip {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  max-width: 100%;
  padding: 6px 10px;
  font: inherit;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  cursor: pointer;
}
.pur-chip:hover { border-color: var(--accent); }
.pur-chip-main { font-family: var(--font-mono); font-size: 13px; font-weight: 600; overflow-wrap: anywhere; }
.pur-chip-sub { font-size: 12px; color: var(--ink-soft); }

.pur-ref {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 4px 3px 10px;
  font-size: 13px;
  background: var(--accent-soft);
  border-radius: 999px;
  overflow-wrap: anywhere;
}
.pur-ref button {
  padding: 0 6px;
  font-size: 16px;
  line-height: 1;
  color: var(--ink-soft);
  background: transparent;
  border: 0;
  cursor: pointer;
}
.pur-ref-add { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.pur-ref-add .field-input { flex: 1 1 140px; min-width: 0; }
.pur-ref-add .pur-kind { flex: 0 0 90px; }

.fin-table tr.is-pending td { background: rgba(220, 38, 38, 0.06); }
.pur-vr-lines { white-space: pre-line; }
.confirm-message { white-space: pre-line; }

.pur-tag {
  display: inline-block;
  margin: 1px 4px 1px 0;
  padding: 1px 8px;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  border-radius: 999px;
}
.pur-tag--ok   { color: var(--success-ink); background: rgba(22, 163, 74, 0.12); }
.pur-tag--warn { color: #b45309;        background: rgba(217, 119, 6, 0.14); }
.pur-tag--bad  { color: var(--danger);  background: rgba(220, 38, 38, 0.12); }
.pur-tag--soft { color: var(--ink-soft); background: rgba(0, 0, 0, 0.06); }

.pur-recon-open { cursor: pointer; }

/* --- Shipment / POS receive check -------------------------------------------
   The figures along the top are also the way in: each is a button that
   narrows the list to what it counts. */
.pm-source { margin: 2px 0 10px; }
.pm-caveat { margin-top: 4px; color: #b45309; }
.pm-link {
  padding: 0;
  font: inherit;
  color: var(--accent-deep);
  background: none;
  border: 0;
  text-decoration: underline;
  cursor: pointer;
}

.pm-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin: 0 0 12px;
}
@media (min-width: 620px) { .pm-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .pm-cards { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

.pm-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  padding: 10px 12px;
  font: inherit;
  text-align: left;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  cursor: pointer;
}
.pm-card:hover { border-color: var(--accent); }
.pm-card.is-active { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.pm-card-label { font-size: 12px; color: var(--ink-soft); overflow-wrap: anywhere; }
.pm-card-value {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 20px;
  font-weight: 600;
}
.pm-card--attention.has-some { border-color: var(--danger); }
.pm-card--attention.has-some .pm-card-value { color: var(--danger); }
.pm-card--attention.has-some.is-active { box-shadow: inset 0 0 0 1px var(--danger); }

.pm-supplier { width: auto; max-width: 200px; }
.pm-filter .pur-search { flex: 1 1 240px; max-width: 360px; }

.pm-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 12px; }
.pm-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 4px 12px;
  font: inherit;
  font-size: 13px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
}
.pm-chip:hover { border-color: var(--accent); }
.pm-chip.is-active { color: #fff; background: var(--accent); border-color: var(--accent); }
.pm-chip-n { font-variant-numeric: tabular-nums; font-weight: 600; opacity: 0.8; }

.pm-row { cursor: pointer; }
.pm-row:hover td { background: rgba(0, 0, 0, 0.03); }
.pm-open {
  padding: 0;
  font: inherit;
  font-family: var(--font-mono);
  font-weight: 600;
  color: var(--accent-deep);
  background: none;
  border: 0;
  text-align: left;
  overflow-wrap: anywhere;
  cursor: pointer;
}
.pm-open:hover { text-decoration: underline; }
.pm-table .pm-diff { color: var(--danger); font-weight: 600; }
.pm-status { min-width: 170px; }
.pm-why { display: block; margin-top: 2px; font-size: 12px; color: var(--ink-soft); white-space: normal; }
.pm-code { font-family: var(--font-mono); white-space: nowrap; }
.pm-desc { min-width: 200px; white-space: normal; }
.pm-foot { margin: 8px 0; }

.pm-reasons { margin: 0 0 12px; padding: 8px 12px 8px 28px; font-size: 13px; background: rgba(217, 119, 6, 0.1); border-radius: var(--radius-md); }
.pm-totals { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin: 0 0 10px; }
@media (min-width: 620px) { .pm-totals { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.pm-total { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--radius-md); }
.pm-total-label { font-size: 12px; color: var(--ink-soft); }
.pm-total-value { font-family: var(--font-display); font-variant-numeric: tabular-nums; font-size: 16px; font-weight: 600; }
.pm-total--diff .pm-total-value { color: var(--danger); }
.pm-only { margin: 0 0 8px; }

/* The web's shipments for the order in hand: folded away unless something
   on it wants looking at, since that is when it is read. */
.pm-ships { margin: 0 0 12px; padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--radius-md); }
.pm-ships > summary { font-size: 13px; font-weight: 600; cursor: pointer; }
.pm-ships[open] > summary { margin-bottom: 6px; }
.pm-ship-codes { display: flex; flex-wrap: wrap; gap: 4px 6px; }
.pm-ship-code {
  padding: 1px 7px;
  font-family: var(--font-mono);
  font-size: 12px;
  white-space: nowrap;
  background: rgba(0, 0, 0, 0.05);
  border-radius: var(--radius-sm);
}
/* A code one of the lines below is flagged for. */
.pm-ship-code.is-marked { font-weight: 700; background: rgba(217, 119, 6, 0.18); }

@media (max-width: 860px) {
  /* On a card three to a row is for numbers. The state, with its reasons,
     and a product's name each take the card's full width. */
  .pm-table td.pm-status, .pm-table td.pm-desc { grid-column: 1 / -1; }
  .pm-status, .pm-desc { min-width: 0; }
  .pm-table td.pm-status .pur-tag { justify-self: start; }
  .pm-supplier { max-width: none; flex: 1 1 140px; }
  .pm-filter .pur-search { flex: 1 1 100%; max-width: none; }
}
.pur-recon-open:hover td { background: rgba(0, 0, 0, 0.03); }
.pur-recon-detail > td { padding: 6px 0 14px 18px; background: var(--surface); }

/* Daily Sale: from / to under the month, and the day table under the list. */
.sale-range { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 0 12px; }
.sale-range .btn.is-on { background: var(--ink); color: #fff; border-color: var(--ink); }
.sale-range-now { margin: 0 0 8px; font-weight: 700; }
.sale-daily { margin-top: 18px; }
.fin-total-row td { font-weight: 700; border-top: 2px solid var(--line, #dfe3ea); }
.sale-range .field-input { width: auto; flex: 0 1 170px; min-width: 140px; }
/* A phone: the two dates side by side, the two quick picks under them. */
@media (max-width: 640px) {
  .sale-range { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .sale-range > .fin-bar-label, .sale-range > .form-note, .sale-range > p { grid-column: 1 / -1; }
  .sale-range > span:not(.fin-bar-label) { display: none; }
  .sale-range .field-input { width: 100%; min-width: 0; }
  .sale-range .btn { min-height: 44px; justify-content: center; }
}

/* Wholesale Target Calculate (2026-10-31): returns taken off, and what is still short. */
.tgt-report td.tgt-return { color: #b91c1c; }
.tgt-report td.tgt-need { color: #b45309; font-weight: 700; }

/* Petty Cash by month or by From–To (2026-10-31). */
.fin-range { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 12px; margin: -4px 0 12px; }
.fin-range-modes { display: inline-flex; border: 1px solid var(--color-border, #d1d5db); border-radius: 999px; overflow: hidden; }
.fin-range-mode { border: 0; background: transparent; padding: 6px 14px; font: inherit; font-size: 13px; cursor: pointer; color: inherit; min-height: 36px; }
.fin-range-mode.is-on { background: var(--color-primary, #15803d); color: #fff; font-weight: 600; }
.fin-range-dates { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px; }
.fin-range-dates label { display: flex; flex-direction: column; gap: 2px; }
.fin-range-note { flex-basis: 100%; margin: 0; }
.fin-range-title { font-weight: 600; margin-right: auto; }
@media (max-width: 640px) {
  .fin-range-dates { width: 100%; }
  .fin-range-dates label { flex: 1 1 40%; }
  .fin-range-dates .btn { flex: 1 1 100%; min-height: 44px; }
}
.fin-range-dates input { min-width: 0; width: 100%; box-sizing: border-box; }
