/* EC ERP - the one stylesheet. No framework, no build step.
 *
 * Tokens first, then layout, then components, with the narrow-screen rules
 * last so they override what they need to.
 *
 * Saved UTF-8. The Taka sign and Bangla text render as mojibake otherwise.
 */

/* ---------------------------------------------------------------- tokens */

:root {
  --ink:          #1c2024;
  --ink-muted:    #5b6570;
  --ink-faint:    #808b96;
  --paper:        #ffffff;
  --page:         #f5f6f7;
  --line:         #d9dee3;
  --line-strong:  #bcc4cc;

  --accent:       #1f6f4a;
  --accent-dark:  #185639;
  --accent-faint: #eaf3ee;

  --danger:       #a32222;
  --danger-faint: #fbeceb;

  /* The product list's Add Product button, darker than the accent so it
     stands out. White on it is about 9:1. */
  --go:           #14532d;
  --go-dark:      #0d3b1f;

  --radius: 6px;
  --gap:    1rem;
  --page-width: 1050px;

  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial,
          "Noto Sans", "Noto Sans Bengali", sans-serif;
  --mono: ui-monospace, "Cascadia Mono", Consolas, "Liberation Mono", monospace;
}

/* ---------------------------------------------------------------- base */

*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
}

h1, h2, h3 { line-height: 1.25; margin: 0 0 0.5rem; font-weight: 600; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.2rem; }
h3 { font-size: 1.05rem; }

p { margin: 0 0 var(--gap); }

a { color: var(--accent-dark); }
a:hover { text-decoration: none; }

code {
  font-family: var(--mono);
  font-size: 0.9em;
  background: var(--page);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 0.05em 0.3em;
}

.lead { color: var(--ink-muted); max-width: 62ch; }

/* Visible focus everywhere. Never remove the outline without replacing it. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------- layout */

.topbar {
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

.topbar-inner {
  max-width: var(--page-width);
  margin: 0 auto;
  padding: 0.65rem var(--gap);
  display: flex;
  align-items: center;
  gap: var(--gap);
  flex-wrap: wrap;
}

.brand {
  font-weight: 800;
  font-size: 1.55rem;
  line-height: 1.1;
  color: var(--go);
  text-decoration: none;
  letter-spacing: 0.02em;
}

/* The seven modules as buttons, so they read as navigation rather than text.
   The page you are on is filled dark green; the others are outlined in a
   light green. Filled against outlined is also a difference of shape and
   weight, so the current page shows in greyscale too - not by colour alone. */
.nav {
  display: flex;
  gap: 0.4rem;
  flex: 1 1 auto;
  flex-wrap: wrap;
}

.nav a {
  padding: 0.45rem 0.9rem;
  font-size: 1.02rem;
  font-weight: 700;
  color: var(--accent-dark);
  text-decoration: none;
  background: var(--accent-faint);
  border: 1px solid #b9d5c4;
  border-radius: var(--radius);
}

.nav a:hover {
  color: var(--go-dark);
  background: #d4e8db;
  border-color: var(--accent);
}

.nav a[aria-current="page"] {
  color: #fff;
  background: var(--go);
  border-color: var(--go);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}

.nav a[aria-current="page"]:hover { background: var(--go-dark); border-color: var(--go-dark); }

.topbar-user {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-left: auto;
}

/* Who is signed in: a plain label that can be found at a glance - the name in
   bold, with its first letter in a small dark-green circle. */
.username {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.3rem 0.8rem 0.3rem 0.3rem;
  font-size: 1rem;
  font-weight: 700;
  color: var(--ink);
  background: var(--page);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
}

.username-initial {
  display: inline-grid;
  place-items: center;
  width: 1.7rem;
  height: 1.7rem;
  font-size: 0.9rem;
  color: #fff;
  background: var(--go);
  border-radius: 50%;
}

/* Sign out: a real button, outlined in the brand green, filled on hover.
   Scoped to the top bar so it outranks the general .btn rules further down. */
.topbar-user .btn-signout {
  padding: 0.42rem 0.95rem;
  font-size: 0.98rem;
  font-weight: 700;
  color: var(--go);
  background: var(--paper);
  border: 2px solid var(--go);
}

.topbar-user .btn-signout:hover { color: #fff; background: var(--go); }

.page {
  max-width: var(--page-width);
  margin: 0 auto;
  padding: 1.5rem var(--gap) 3rem;
}

.centred {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--gap);
}

/* ---------------------------------------------------------------- flashes */

.flashes { margin-bottom: var(--gap); }

.flash {
  margin: 0 0 0.5rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--line);
  border-left-width: 4px;
  border-radius: var(--radius);
  background: var(--paper);
}

.flash-success { border-left-color: var(--accent); background: var(--accent-faint); }
.flash-error   { border-left-color: var(--danger); background: var(--danger-faint); }
.flash-warning { border-left-color: #b8860b; background: #fdf6e3; }
.flash-message { border-left-color: var(--line-strong); }

/* ---------------------------------------------------------------- forms */

.field { margin-bottom: var(--gap); }

label {
  display: block;
  margin-bottom: 0.25rem;
  font-weight: 600;
  font-size: 0.92rem;
}

input[type="text"],
input[type="password"],
input[type="email"],
input[type="tel"],
input[type="number"],
input[type="date"],
input[type="search"],
select,
textarea {
  width: 100%;
  padding: 0.5rem 0.6rem;
  font: inherit;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
}

textarea { min-height: 5rem; resize: vertical; }

.field-hint { display: block; margin-top: 0.25rem; color: var(--ink-muted); font-size: 0.85rem; }

.field-error {
  display: block;
  margin-top: 0.25rem;
  color: var(--danger);
  font-size: 0.87rem;
}

.form-error {
  padding: 0.7rem 0.9rem;
  margin-bottom: var(--gap);
  color: var(--danger);
  background: var(--danger-faint);
  border: 1px solid var(--danger);
  border-radius: var(--radius);
}

.inline-form { display: inline; margin: 0; }

/* ---------------------------------------------------------------- buttons */

.btn {
  display: inline-block;
  padding: 0.5rem 0.9rem;
  font: inherit;
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  cursor: pointer;
}

.btn:hover { background: var(--page); }

.btn-primary {
  color: #fff;
  background: var(--accent);
  border-color: var(--accent);
}

.btn-primary:hover { background: var(--accent-dark); border-color: var(--accent-dark); }

.btn-add {
  padding: 0.65rem 1.3rem;
  font-size: 1.1rem;
  font-weight: 700;
  color: #fff;
  background: var(--go);
  border-color: var(--go);
}

.btn-add:hover { background: var(--go-dark); border-color: var(--go-dark); }

.btn-danger { color: var(--danger); border-color: var(--danger); }
.btn-danger:hover { background: var(--danger-faint); }

.btn-quiet {
  padding: 0.3rem 0.6rem;
  font-weight: 500;
  font-size: 0.9rem;
  color: var(--ink-muted);
  border-color: var(--line);
}

/* A row's action buttons (Return, Edit, Delete): one size and weight, so a
   link and a form button in the same cell read as the same kind of thing.
   Written as .actions .btn-row so it outranks the ".actions > a" link rules. */
.actions .btn-row {
  padding: 0.45rem 0.95rem;
  font-size: 1rem;
  font-weight: 700;
}

.actions > .btn-row,
.actions > .inline-form { margin-right: 0.4rem; }

/* A toolbar's search: filled and bold, so it reads as the next thing to press
   after typing, not as part of the field. */
.btn-search {
  padding: 0.55rem 1.2rem;
  font-size: 1.05rem;
  font-weight: 700;
}

.btn-block { display: block; width: 100%; }

.btn:disabled { opacity: 0.55; cursor: not-allowed; }

/* ---------------------------------------------------------------- tables */

.table {
  width: 100%;
  border-collapse: collapse;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.table caption,
.table-caption {
  caption-side: top;
  text-align: left;
  padding-bottom: 0.5rem;
  color: var(--ink-muted);
  font-size: 0.9rem;
}

.table th,
.table td {
  padding: 0.55rem 0.75rem;
  text-align: left;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.table thead th {
  background: var(--page);
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--ink-muted);
  white-space: nowrap;
}

.table tbody tr:last-child td,
.table tbody tr:last-child th { border-bottom: 0; }

/* Money and quantities are right-aligned so columns line up digit for digit.
   .table .num, because the .table th/td rule above outranks a bare .num. */
.num,
.table .num { text-align: right; font-variant-numeric: tabular-nums; }

.muted { color: var(--ink-muted); }
.faint { color: var(--ink-faint); }

/* ---------------------------------------------------------------- login */

.login-card {
  width: 100%;
  max-width: 22rem;
  padding: 1.75rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 8px;
}

.login-title {
  margin-bottom: 1.25rem;
  text-align: center;
  font-size: 1.9rem;
  font-weight: 800;
  color: var(--go);
  letter-spacing: 0.02em;
}

.error-code {
  margin: 0;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
}

.error-title { margin: 0.15rem 0 0.6rem; font-size: 1.25rem; }
.error-message { color: var(--ink-muted); }
.error-actions { margin: 0; }


/* ---------------------------------------------------------------- headings */

.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--gap);
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
}

.page-head h1 { margin-bottom: 0.15rem; }

.head-actions { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }

.subnav { display: flex; gap: 0.25rem; flex-wrap: wrap; }

.subnav a {
  padding: 0.3rem 0.6rem;
  border-radius: var(--radius);
  color: var(--ink-muted);
  text-decoration: none;
  font-size: 0.92rem;
}

.subnav a:hover { background: var(--paper); color: var(--ink); }

.subnav a[aria-current="page"] {
  background: var(--accent-faint);
  color: var(--accent-dark);
  font-weight: 600;
}

/* The settings page's tabs: larger than the report tabs, because they are
   the page's only way around. Outlined, and the current one filled - a
   difference of weight and border as well as colour. */
.settings-tabs { gap: 0.4rem; margin: 0 0 1.1rem; }

.settings-tabs a {
  padding: 0.5rem 0.95rem;
  font-size: 0.98rem;
  font-weight: 600;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line-strong);
}

.settings-tabs a:hover { border-color: var(--accent); background: var(--accent-faint); }

.settings-tabs a[aria-current="page"] {
  color: var(--accent-dark);
  background: var(--accent-faint);
  border: 2px solid var(--accent);
  padding: calc(0.5rem - 1px) calc(0.95rem - 1px);
}

.tab-count { color: var(--ink-muted); font-weight: 500; }

.small { font-size: 0.88rem; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------------------------------------------------------------- cards */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}

.cards-tight { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

/* A row of actions under the cards, pushed to the right. */
.list-actions {
  display: flex;
  justify-content: flex-end;
  margin: -0.35rem 0 1rem;
}

.card {
  padding: 0.85rem 1rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.card-label {
  margin: 0 0 0.3rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.card-value {
  margin: 0;
  font-size: 1.35rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.card-note { margin: 0.3rem 0 0; font-size: 0.82rem; color: var(--ink-muted); }

.card-low { background: #fdf7f6; border-color: #e6c9c6; }

/* The home page's two cards: roomier and larger, as the first thing the owner
   reads after signing in. The report pages keep the compact cards above. */
.cards-large .card { padding: 1.25rem 1.5rem; }
.cards-large .card-label { font-size: 0.95rem; font-weight: 700; color: var(--ink); }
.cards-large .card-value { font-size: 1.9rem; font-weight: 700; }
.cards-large .card-note { font-size: 0.92rem; }

.page-title-large { font-size: 1.85rem; font-weight: 700; }

/* ---------------------------------------------------------------- toolbar */

.toolbar {
  display: flex;
  align-items: flex-end;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.85rem 1rem;
  margin-bottom: 1.25rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.toolbar-field { min-width: 11rem; }
.toolbar-field label { font-size: 0.82rem; }
.toolbar-check { display: flex; align-items: flex-end; min-width: auto; }

/* The home page's category filter: a label that reads at a glance, a border
   that shows where the box is, and bold choices in the open list. */
.toolbar-large .toolbar-field label { font-size: 1rem; font-weight: 700; }
.toolbar-large select {
  font-size: 1.05rem;
  font-weight: 700;
  border: 2px solid var(--ink-muted);
}
.toolbar-large option { font-weight: 700; }

.clear-link { align-self: center; font-size: 0.9rem; }

/* ---------------------------------------------------------------- panels */

.panel {
  padding: 1.1rem 1.15rem;
  margin-bottom: 1.25rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.panel > .table,
.panel .table-scroll > .table { border: 0; }

.panel > h2 { margin-bottom: 0.75rem; }

/* An add form folded behind a button (Add purchase, Add communication, Add
   order). A <details> element, so it opens with JavaScript off. Closed until
   pressed; while open, the button reads "× Close" and the form sits in a box
   below it. */
.adder { margin-bottom: 1rem; }

.adder > summary {
  display: inline-block;
  list-style: none;
  padding: 0.5rem 1rem;
  font-weight: 700;
  color: var(--accent-dark);
  background: var(--paper);
  border: 2px solid var(--accent);
  border-radius: var(--radius);
  cursor: pointer;
  user-select: none;
}

.adder > summary::-webkit-details-marker { display: none; }
.adder > summary:hover { color: #fff; background: var(--accent); }

.adder .adder-close,
.adder[open] .adder-open { display: none; }
.adder[open] .adder-close { display: inline; }

.adder[open] > summary { color: var(--ink-muted); border-color: var(--line-strong); }
.adder[open] > summary:hover { color: var(--ink); background: var(--page); }

.adder > form {
  margin-top: 0.75rem;
  padding: 1rem;
  background: var(--page);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.callout {
  padding: 0.7rem 0.9rem;
  margin-bottom: var(--gap);
  background: var(--page);
  border-left: 4px solid var(--line-strong);
  border-radius: var(--radius);
  color: var(--ink-muted);
  font-size: 0.92rem;
}

.callout-warn { background: #fdf6e3; border-left-color: #b8860b; color: var(--ink); }
.callout-strong {
  background: var(--accent-faint);
  border-left-color: var(--accent);
  color: var(--ink);
  font-size: 1rem;
  font-weight: 600;
}

.empty-state {
  padding: 2rem 1rem;
  text-align: center;
  color: var(--ink-muted);
  background: var(--paper);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
}

/* ---------------------------------------------------------------- forms */

.form-narrow { max-width: 30rem; }

.form-grid { max-width: 34rem; }

.form-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 1.1rem;
}

.row-form {
  display: flex;
  align-items: flex-end;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
  max-width: 34rem;
}

.row-form .field { flex: 1 1 16rem; margin-bottom: 0; }

.inline-rename { display: flex; gap: 0.4rem; align-items: center; }
.inline-rename input { min-width: 8rem; }

.field-check label { font-weight: 500; }

.label-inline {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-weight: 500;
}

.label-inline input { width: auto; }

/* An amount paired with its per-unit / whole-lot basis. */
.cost-line {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
}

.cost-line > .field:first-child { flex: 2 1 12rem; }
.cost-line > .field:last-child  { flex: 1 1 9rem; }

.preview {
  margin: 0.25rem 0 0;
  min-height: 1.4em;
  font-weight: 600;
  color: var(--accent-dark);
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- tables */

.table-narrow { max-width: 34rem; }

.actions { white-space: nowrap; }
.actions > a { margin-right: 0.5rem; font-size: 0.9rem; }

.empty { color: var(--ink-muted); text-align: center; padding: 1.5rem 0.75rem; }

.truncate {
  max-width: 18rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A flagged row: a subtle tint PLUS the word "low" in the Margin cell. Colour
   alone carries no meaning for a colour-blind reader, in greyscale, or on a
   printed price list. */
.row-low > td { background: #fdf7f6; }

.marker {
  margin-left: 0.3rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--ink-muted);
  text-transform: lowercase;
}

.value-warn { color: var(--danger); }

.row-total > th,
.row-total > td {
  background: var(--page);
  font-weight: 700;
  border-top: 2px solid var(--line-strong);
}

.row-quiet > td { color: var(--ink-faint); }

.row-cancelled > td { color: var(--ink-faint); }

/* A date or an order reference reads as one thing, so it never breaks. */
.nowrap { white-space: nowrap; }

/* One returned product inside an order that kept the rest: struck through, so
   the strike - not the grey - says it is not counted. */
.line-returned { color: var(--ink-faint); text-decoration: line-through; }

.row-highlight > td { background: var(--accent-faint); }

/* The product list: rows the eye can follow across nine columns. A darker,
   bolder header; roomier rows with firmer lines; every other row shaded; the
   row under the pointer tinted; the product's name in bold. The shading is on
   the row, so a low-margin row's own tint on its cells still shows through. */
.table-strong thead th {
  font-size: 0.88rem;
  font-weight: 700;
  color: var(--ink);
  background: #e9edf0;
  border-bottom: 2px solid var(--line-strong);
  white-space: normal;
  vertical-align: bottom;
}

.table-strong th,
.table-strong td { padding: 0.75rem; vertical-align: middle; }

/* A figure and its marker ("11.43% low") stay together on one line. */
.table-strong td.num { white-space: nowrap; }

.table-strong td { border-bottom: 1px solid var(--line-strong); }

/* Nine columns do not fit the page on one line of actions, so they may wrap
   - between links, never inside "Add Purchase". */
.table-strong td.actions { white-space: normal; min-width: 10.5rem; }
.table-strong td.actions > * { white-space: nowrap; }

.table-strong tbody tr:nth-child(even) { background: #edf0f3; }
.table-strong tbody tr:hover { background: var(--accent-faint); }
.table-strong tr.row-low > td { background: var(--danger-faint); }

.table-strong .cell-name { font-size: 1.02rem; font-weight: 700; }
.table-strong .marker { font-size: 0.82rem; font-weight: 700; color: var(--ink); }

.table tfoot th,
.table tfoot td { border-bottom: 0; }

/* ---------------------------------------------------------------- downloads */

.downloads {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
}

.downloads-label {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

/* Disabled until a report has been run: a button that silently downloads a
   different range than the one on screen is worse than no button. */
.is-disabled { opacity: 0.5; cursor: not-allowed; }

/* Under a paged table: how much is shown, and the way to the rest. */
.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-top: 0.75rem;
}

.pager-count { color: var(--ink-muted); font-size: 0.92rem; }
.pager-links { display: flex; align-items: center; gap: 0.5rem; }
.pager-where { font-weight: 600; font-size: 0.92rem; }

/* ---------------------------------------------------------------- records */

.record {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.35rem 1rem;
  margin: 0;
}

.record-wide { grid-template-columns: 11rem 1fr; }

.record dt { font-weight: 600; font-size: 0.9rem; color: var(--ink-muted); }
.record dd { margin: 0; }

/* Multi-line text keeps its line breaks. */
.multiline { white-space: pre-line; }

.badge {
  display: inline-block;
  padding: 0.1rem 0.45rem;
  background: var(--page);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.82rem;
  color: var(--ink-muted);
}

.star { color: #b8860b; }

.log { list-style: none; margin: 0; padding: 0; }

.log > li {
  padding: 0.65rem 0;
  border-bottom: 1px solid var(--line);
}

.log > li:last-child { border-bottom: 0; }

.log-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-bottom: 0.25rem;
}

.log-date { font-weight: 600; font-size: 0.9rem; }
.log-head .inline-form { margin-left: auto; }
/* ---------------------------------------------------------------- narrow */

/* Wide tables scroll inside their own box rather than dropping columns.
   position: relative keeps the visually hidden labels in the pricing grid
   inside that box as well; without it they escape, and the whole page
   scrolls sideways on a phone. */
.table-scroll { overflow-x: auto; position: relative; }

@media (max-width: 720px) {
  /* The brand and Sign out share the first line; the seven links wrap
     underneath, every one of them visible - there is no menu to open. */
  .topbar-inner { padding: 0.5rem 0.75rem; gap: 0.35rem 0.75rem; }
  .topbar-user { order: 1; }
  .nav { order: 2; flex-basis: 100%; gap: 0.35rem; }
  /* Still buttons, a little tighter, so seven fit in two rows. */
  .nav a { padding: 0.4rem 0.7rem; font-size: 0.97rem; }

  .page { padding: 1rem 0.75rem 2.5rem; }

  .page-head { flex-direction: column; align-items: stretch; }

  /* Stacked, the side-by-side flex bases would become heights - a tall gap
     under every amount - so they go, and each field takes the full width. */
  .cost-line { flex-direction: column; gap: 0; align-items: stretch; }
  .cost-line > .field:first-child,
  .cost-line > .field:last-child { flex: none; }
  .record, .record-wide { grid-template-columns: 1fr; gap: 0.1rem; }
  .record dd { margin-bottom: 0.5rem; }

  .truncate { max-width: none; white-space: normal; }

  /* Lists become stacked cards, one per row. Each cell carries its own label
     from the data-label attribute, so no header is lost. A .table-columns
     table is left alone - see below. */
  .table:not(.table-columns) thead { display: none; }

  .table:not(.table-columns),
  .table:not(.table-columns) tbody,
  .table:not(.table-columns) tfoot,
  .table:not(.table-columns) tr,
  .table:not(.table-columns) th,
  .table:not(.table-columns) td,
  .table:not(.table-columns) caption { display: block; width: 100%; }

  .table:not(.table-columns) tr {
    padding: 0.6rem 0.75rem;
    border-bottom: 1px solid var(--line);
  }

  .table:not(.table-columns) tr:last-child { border-bottom: 0; }

  .table:not(.table-columns) th,
  .table:not(.table-columns) td {
    padding: 0.2rem 0;
    border-bottom: 0;
    text-align: left;
  }

  .table:not(.table-columns) td[data-label]::before {
    content: attr(data-label) ": ";
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--ink-muted);
  }

  .table:not(.table-columns) td:empty { display: none; }

  /* A tint or a total belongs to the whole card, not to each line in it. */
  .table:not(.table-columns) tr.row-low { background: #fdf7f6; }
  .table:not(.table-columns) tr.row-highlight { background: var(--accent-faint); }
  .table:not(.table-columns) tr.row-total {
    background: var(--page);
    border-top: 2px solid var(--line-strong);
  }
  .table:not(.table-columns) tr.row-total > * { border-top: 0; }

  /* The buttons say what they are, so the "Actions:" label goes, and every
     link becomes a target a thumb can hit without catching its neighbour. */
  .table:not(.table-columns) td.actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    padding-top: 0.5rem;
    white-space: normal;
  }

  .table:not(.table-columns) td.actions::before { content: none; }

  .table:not(.table-columns) td.actions > a {
    display: inline-flex;
    align-items: center;
    min-height: 2.5rem;
    margin: 0;
    padding: 0 0.85rem;
    font-weight: 600;
    text-decoration: none;
    background: var(--paper);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
  }

  .table:not(.table-columns) td.actions .btn { min-height: 2.5rem; }
  .table:not(.table-columns) td.actions > .btn-row { margin: 0; font-weight: 700; }
  .table:not(.table-columns) td.actions > .inline-form { margin: 0; }

  /* As cards, a firmer line between products, and the low tint on the card. */
  .table.table-strong tbody tr { border-bottom: 2px solid var(--line-strong); }
  .table.table-strong tbody tr:last-child { border-bottom: 0; }
  .table.table-strong tr.row-low { background: var(--danger-faint); }

  /* A .table-columns table keeps its columns and scrolls sideways inside its
     .table-scroll box: the reports and the pricing grid, where the row IS the
     comparison and a card per row would put each figure on its own line, and
     small tables that fit a phone as they are. The first column stays put
     while the rest scroll, so no figure is read without its date or name. */
  .table-scroll > .table-columns tr > :first-child {
    position: sticky;
    left: 0;
    min-width: 8rem;
    background: var(--paper);
  }

  .table-scroll > .table-columns thead th:first-child,
  .table-scroll > .table-columns .row-total > :first-child { background: var(--page); }

  /* Wrapped to the visible width of the box, not the full width of the table. */
  .table-scroll > .table-columns > caption {
    position: sticky;
    left: 0;
    max-width: calc(100vw - 4rem);
  }

  .pricing-table .cell-name { white-space: normal; }

  /* A comma-separated list reads as a few lines, not one word per line. */
  .table-scroll > .table-columns .cell-list { min-width: 14rem; }
}

/* ---------------------------------------------------------------- pricing */

/* The grid keeps its columns at phone width (.table-columns). A stacked card
   per product would put each competitor on its own line and destroy the
   comparison the page is for. */
.cell-name { font-weight: 500; white-space: nowrap; }

.cell-price { min-width: 8rem; }

.cell-price input {
  text-align: right;
  font-variant-numeric: tabular-nums;
  padding: 0.35rem 0.45rem;
}

/* The add product form shows what belongs to the chosen Product Type - the
   Combo items section only for a Combo Pack. CSS alone: the selected option is
   state the browser already holds, so this needs no JavaScript and still works
   with it off. The edit form has no type select and renders only its own. */
form:has(#product_type option[value="regular"]:checked) .only-combo,
form:has(#product_type option[value="combo"]:checked) .only-regular { display: none; }

.combo-items {
  margin: 0 0 1rem;
  padding: 0.75rem 1rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
}

.combo-items > legend { padding: 0 0.35rem; font-weight: 600; }

.combo-add { margin-top: 0.6rem; }

/* The supplier form's products: ticked, not typed. As many columns as fit,
   scrolling inside the box once the list is long. */
.check-list {
  margin: 0 0 var(--gap);
  padding: 0.75rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
}

.check-list > legend { padding: 0 0.35rem; font-weight: 600; font-size: 0.92rem; }

.check-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.4rem 1rem;
  max-height: 18rem;
  overflow-y: auto;
}

.check-grid label { margin: 0; font-weight: 500; align-items: flex-start; }
.check-grid input { flex: none; margin-top: 0.2rem; }

/* ---------------------------------------------------------------- compare */

.compare-picker { margin-bottom: var(--gap); }

/* The lowest asking price in a row: a green tint PLUS bold PLUS the word
   "lowest", so it reads the same in greyscale and to a colour-blind reader. */
.compare-table td.cell-lowest {
  background: var(--accent-faint);
  font-weight: 700;
}

.compare-table td.cell-lowest .marker { color: var(--accent-dark); }

/* An asking-price box with its unit beside it: "25.50 / kg". */
.price-box { display: inline-flex; align-items: center; gap: 0.4rem; }
.price-box input { width: 8rem; }

/* At phone width the rows stack as cards like any list, one item per card. */
.combo-grid td { vertical-align: top; }
.combo-grid td.num { width: 7.5rem; }
.combo-grid td.num input {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* How stale a hand-typed figure is, so an old one looks old. */
.cell-stamp {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.72rem;
  color: var(--ink-faint);
  white-space: nowrap;
}

.form-actions-sticky {
  position: sticky;
  bottom: 0;
  padding: 0.75rem 0;
  background: var(--paper);
  border-top: 1px solid var(--line);
  align-items: baseline;
}

.form-actions-sticky .field-hint { flex: 1 1 18rem; margin-top: 0; }

/* ---------------------------------------------------------------- users */

.user-form { margin-bottom: 1.25rem; }

/* A new password is set from a fold on each row, so the table stays one line
   a user. A <details> element, so it opens with JavaScript off. */
.password-fold {
  display: inline-block;
  margin-right: 0.5rem;
  vertical-align: top;
  white-space: normal;
}

.password-fold > summary {
  cursor: pointer;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--accent-dark);
}

.password-fold form {
  display: grid;
  gap: 0.35rem;
  min-width: 14rem;
  margin: 0.5rem 0;
}

.password-fold label { font-size: 0.85rem; font-weight: 600; }
