/* inventoryAi — the whole stylesheet.
 *
 * Hand-written rather than a framework: the app is a dozen screens made of the
 * same six components, and a CDN build with no configuration is what made the
 * old screens look like defaults arranged in a column.
 *
 * Everything below is built from the tokens. If a colour appears as a literal
 * anywhere past :root, that is a bug — it will not follow the dark palette.
 */

:root {
  --bg: #F4F4F3;
  --surface: #FFFFFF;
  --sidebar: #1C1F22;
  --sidebar-text: #A8AEB4;
  --sidebar-active: #2C3136;
  --ink: #16191C;
  --muted: #646B72;
  --faint: #949BA1;
  --hair: #E3E4E4;
  --brand: #A4551A;
  --brand-soft: #FAF0E5;
  --amber: #8A6D1F;
  --amber-soft: #F7F2DE;
  --danger: #B23B36;
  --danger-soft: #FBECEB;

  --radius: 6px;
  --shadow-sm: 0 1px 2px rgba(20, 33, 28, .07);
  --shadow: 0 2px 4px rgba(20, 33, 28, .06), 0 8px 20px rgba(20, 33, 28, .06);

  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --mono: ui-monospace, "Cascadia Mono", "SF Mono", Consolas, monospace;

  /* Nothing interactive smaller than a thumb. One interface serves a phone
     behind a counter and a laptop in the office. */
  --tap: 2.75rem;

  /* Chart series. Validated with the six-check palette validator in both
     modes — lightness band, chroma floor, CVD separation, normal-vision floor
     and contrast against the surface. Do not substitute by eye. */
  --chart-sales: #A4551A;
  --chart-margin: #1B6FA8;
  --chart-cash: #1B6FA8;
  --chart-grid: var(--hair);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #131517;
    --surface: #1A1D20;
    --sidebar: #0F1113;
    --sidebar-text: #9BA2A8;
    --sidebar-active: #262A2E;
    --ink: #E8EAEC;
    --muted: #99A1A8;
    --faint: #6E767D;
    --hair: #2A2E32;
    --brand: #E08B45;
    --brand-soft: #2A1E12;
    --amber: #D0B45C;
    --amber-soft: #262010;
    --danger: #D97B75;
    --danger-soft: #2B1917;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow: 0 2px 4px rgba(0, 0, 0, .35), 0 8px 20px rgba(0, 0, 0, .3);

    /* Dark is its own set of steps, not the light pair brightened: the dark
       lightness band is L 0.48-0.67, and --brand at #E08B45 sits outside it. */
    --chart-sales: #C2703A;
    --chart-margin: #3D7FC4;
    --chart-cash: #3D7FC4;
  }
}

:root[data-theme="dark"] {
  --bg: #131517;
  --surface: #1A1D20;
  --sidebar: #0F1113;
  --sidebar-text: #9BA2A8;
  --sidebar-active: #262A2E;
  --ink: #E8EAEC;
  --muted: #99A1A8;
  --faint: #6E767D;
  --hair: #2A2E32;
  --brand: #E08B45;
  --brand-soft: #2A1E12;
  --amber: #D0B45C;
  --amber-soft: #262010;
  --danger: #D97B75;
  --danger-soft: #2B1917;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow: 0 2px 4px rgba(0, 0, 0, .35), 0 8px 20px rgba(0, 0, 0, .3);

  /* Dark is its own set of steps, not the light pair brightened: the dark
     lightness band is L 0.48-0.67, and --brand at #E08B45 sits outside it. */
  --chart-sales: #C2703A;
  --chart-margin: #3D7FC4;
  --chart-cash: #3D7FC4;
}

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

/* Any author `display` beats the UA stylesheet's [hidden], so a component
   given `display: grid` stays on screen while claiming to be hidden. This is
   what put an empty selected-item panel under the search box. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--brand); }

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 3px;
}

/* Figures. Money and quantities line up in columns everywhere, which is the
   difference between software that looks considered and software that does not. */
.num, td.num, .price, .amt {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- shell -- */

.app { display: grid; grid-template-columns: 216px 1fr; min-height: 100vh; }

.side {
  background: var(--sidebar);
  padding: 1rem .75rem;
  display: flex;
  flex-direction: column;
}

.brandmark {
  display: flex; align-items: center; gap: .55rem;
  padding: .35rem .5rem 1.25rem;
  color: #fff; font-weight: 600; letter-spacing: -.01em;
  text-decoration: none;
}
.brandmark .dot {
  width: 22px; height: 22px; border-radius: 5px;
  background: var(--brand); flex: none;
}
.brandmark .logo {
  width: 22px; height: 22px; border-radius: 5px;
  object-fit: contain; flex: none;
}

.side nav { display: flex; flex-direction: column; gap: 1px; }
.side nav a {
  display: flex; align-items: center; gap: .6rem;
  min-height: var(--tap);
  padding: .5rem .6rem;
  border-radius: var(--radius);
  color: var(--sidebar-text);
  text-decoration: none;
  font-size: .875rem;
}
.side nav a:hover { background: var(--sidebar-active); color: #fff; }
.side nav a[aria-current="page"] {
  background: var(--sidebar-active); color: #fff; font-weight: 500;
}
.side nav a svg { width: 16px; height: 16px; flex: none; opacity: .85; }

.side .whoami {
  margin-top: auto;
  padding: .75rem .6rem 0;
  border-top: 1px solid rgba(255, 255, 255, .07);
  color: var(--sidebar-text);
  font-size: .8rem;
}
.side .whoami .role { opacity: .6; }
.side .whoami form { margin: .4rem 0 0; }
.side .whoami button {
  background: none; border: 0; padding: 0;
  color: var(--sidebar-text); font: inherit; font-size: .8rem;
  cursor: pointer; text-decoration: underline;
}
.side .whoami button:hover { color: #fff; }

.top {
  background: var(--surface);
  border-bottom: 1px solid var(--hair);
  padding: .7rem 1.5rem;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  position: sticky; top: 0; z-index: 5;
}
.crumbs { color: var(--muted); font-size: .82rem; }
.crumbs b { color: var(--ink); font-weight: 600; }
.store {
  display: inline-flex; align-items: center; gap: .4rem;
  background: var(--brand-soft); color: var(--brand);
  padding: .2rem .55rem; border-radius: 100px;
  font-size: .78rem; font-weight: 500; white-space: nowrap;
}

main { padding: 1.5rem; max-width: 1180px; }

/* The sidebar becomes a horizontal strip on a phone. The nav is five links,
   so it fits; a drawer would be more machinery for no gain. */
@media (max-width: 860px) {
  .app { grid-template-columns: 1fr; }
  .side { flex-direction: row; align-items: center; gap: .5rem; padding: .5rem .75rem; }
  .side .brandmark { padding: 0; }
  .side .brandmark span:not(.dot) { display: none; }
  .side nav { flex-direction: row; overflow-x: auto; flex: 1; }
  .side nav a { white-space: nowrap; }
  .side .whoami {
    margin: 0; padding: 0; border: 0; border-left: 1px solid rgba(255,255,255,.07);
    padding-left: .75rem;
  }
  .side .whoami .role, .side .whoami .name { display: none; }
  .top { padding: .6rem 1rem; }
  main { padding: 1rem; }
}

/* ----------------------------------------------------------- typography -- */

h1 { font-size: 1.35rem; font-weight: 600; letter-spacing: -.02em; margin: 0 0 .2rem; }
h2 { font-size: .9rem; font-weight: 600; margin: 0; }
.sub { color: var(--muted); margin: 0 0 1.25rem; font-size: .875rem; }
.spacer { height: 1.5rem; }

/* ---------------------------------------------------------------- panel -- */

.panel {
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: 10px;
  box-shadow: var(--shadow-sm);
}
.panel > header {
  padding: .8rem 1rem;
  border-bottom: 1px solid var(--hair);
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.panel > .body { padding: 1rem; }

.panel .foot {
  display: flex; justify-content: space-between; align-items: center;
  padding: .7rem 1rem; color: var(--muted); font-size: .8rem;
  border-top: 1px solid var(--hair);
}
.panel .foot .tot {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  color: var(--ink); font-weight: 600; font-size: .95rem;
}

/* ---------------------------------------------------------------- table -- */

.scroller { overflow-x: auto; }

table { width: 100%; min-width: 560px; border-collapse: collapse; }
/* Narrow tables — three columns in a half-width panel — do not need the wide
   minimum, and inheriting it made them scroll and hide their own figures. */
table.compact { min-width: 0; }
th {
  text-align: left;
  font-size: .7rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
  padding: .55rem 1rem;
  border-bottom: 1px solid var(--hair);
  background: var(--bg);
  white-space: nowrap;
}
th.r, td.r { text-align: right; }
td { padding: .6rem 1rem; border-bottom: 1px solid var(--hair); }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--brand-soft); }
td.who { color: var(--muted); font-size: .8rem; }
td.empty { color: var(--muted); text-align: center; padding: 1.5rem 1rem; }

/* ----------------------------------------------------------------- pill -- */

.pill {
  display: inline-block;
  font-size: .72rem; padding: .12rem .45rem; border-radius: 100px;
  /* Neutral on purpose. A pill reading "50 in stock" is information, not
     something to act on, and tinting it with the accent is what made the old
     palette read as one colour on top of itself. */
  background: var(--bg); color: var(--muted); border: 1px solid var(--hair);
  font-weight: 500; white-space: nowrap;
}
.pill.low { background: var(--amber-soft); color: var(--amber); border-color: transparent; }
.pill.none { background: var(--danger-soft); color: var(--danger); border-color: transparent; }

/* -------------------------------------------------------------- control -- */

.field { display: block; margin-bottom: .9rem; }
.field label,
label {
  display: block;
  font-size: .75rem; color: var(--muted);
  margin-bottom: .3rem; font-weight: 500;
}

.control {
  width: 100%;
  min-height: var(--tap);
  border: 1px solid var(--hair);
  background: var(--surface);
  color: var(--ink);
  border-radius: var(--radius);
  padding: .5rem .6rem;
  font: inherit; font-size: 1rem;
}
.control:focus { outline: 0; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.control[readonly] { background: var(--bg); color: var(--muted); }
input.num, .control.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }

select.control { appearance: none; padding-right: 2rem; }

.stepper { display: flex; }
.stepper button {
  width: 42px; min-height: var(--tap);
  border: 1px solid var(--hair); background: var(--surface); color: var(--ink);
  font-size: 1.1rem; cursor: pointer;
}
.stepper button:first-child { border-radius: var(--radius) 0 0 var(--radius); }
.stepper button:last-child { border-radius: 0 var(--radius) var(--radius) 0; }
.stepper .control { border-radius: 0; text-align: center; border-left: 0; border-right: 0; }

.err { color: var(--danger); font-size: .8rem; margin: .25rem 0 0; }
.err ul { margin: 0; padding-left: 1.1rem; }

/* ------------------------------------------------------------------ btn -- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  min-height: var(--tap);
  border: 1px solid transparent; border-radius: var(--radius);
  background: var(--brand); color: #fff;
  font: inherit; font-weight: 600;
  padding: .5rem 1rem; cursor: pointer; text-decoration: none;
}
.btn:hover { filter: brightness(1.08); }
.btn:disabled { opacity: .45; cursor: not-allowed; filter: none; }
.btn.wide { width: 100%; }
.btn.ghost {
  background: var(--surface); color: var(--ink);
  border-color: var(--hair); font-weight: 500;
}
.btn.ghost:hover { background: var(--brand-soft); filter: none; }
.btn.quiet {
  background: none; border: 0; color: var(--muted);
  font-weight: 500; padding: .35rem .5rem; min-height: 0;
}
.btn.quiet:hover { color: var(--danger); filter: none; }

.toolbar { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }

/* -------------------------------------------------------------- message -- */

.msg {
  border: 1px solid var(--hair); background: var(--surface);
  border-left: 3px solid var(--muted);
  border-radius: var(--radius);
  padding: .7rem 1rem; margin-bottom: 1rem; font-size: .875rem;
}
.msg.error { border-left-color: var(--danger); background: var(--danger-soft); }
.msg.success { border-left-color: var(--brand); background: var(--brand-soft); }

.banner {
  background: var(--amber-soft); color: var(--ink);
  border-bottom: 1px solid var(--hair);
  padding: .6rem 1.5rem; font-size: .85rem;
}
.banner b { color: var(--amber); }

/* --------------------------------------------------------------- signin -- */

.signin {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 1.5rem;
}
.signin .panel { width: 100%; max-width: 22rem; }
.signin .brandmark { color: var(--ink); justify-content: center; padding-bottom: 1rem; }

@media (prefers-reduced-motion: no-preference) {
  .btn, .side nav a, tbody tr { transition: background-color .12s ease, filter .12s ease; }
}

/* --------------------------------------------------------- record a sale -- */

.searchbox {
  display: flex; align-items: center; gap: .6rem;
  background: var(--surface);
  border: 1.5px solid var(--brand);
  border-radius: 10px;
  padding: .7rem 1rem;
  box-shadow: 0 0 0 3px var(--brand-soft);
}
.searchbox svg { width: 18px; height: 18px; color: var(--brand); flex: none; }
.searchbox input {
  border: 0; outline: 0; background: transparent; color: var(--ink);
  font: inherit; font-size: 1.05rem; width: 100%; min-height: 1.6rem;
}

.results:not(:empty) {
  margin-top: .4rem;
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: 10px;
  box-shadow: var(--shadow);
  overflow: hidden;
}
.result {
  display: grid; grid-template-columns: 1fr auto auto;
  align-items: center; gap: 1rem;
  width: 100%; min-height: var(--tap);
  padding: .6rem 1rem;
  border: 0; border-bottom: 1px solid var(--hair);
  background: var(--surface); color: var(--ink);
  font: inherit; text-align: left; cursor: pointer;
}
.result:last-child { border-bottom: 0; }
.result:hover:not(:disabled) { background: var(--brand-soft); }
.result:disabled { opacity: .5; cursor: not-allowed; }
.result .nm { font-weight: 500; }
.result .price { font-size: 1rem; }
.noresults { padding: .8rem 1rem; margin: .4rem 0 0; color: var(--muted);
  background: var(--surface); border: 1px solid var(--hair); border-radius: 10px; }

.chosen { margin-top: 1rem; display: grid; grid-template-columns: 1fr 280px; gap: 1rem; }
.chosen .fields { display: grid; grid-template-columns: 1fr 1fr; gap: .9rem; }
@media (max-width: 780px) {
  .chosen { grid-template-columns: 1fr; }
}

.totalcard { display: flex; flex-direction: column; justify-content: space-between; }
.totalcard .lbl { color: var(--muted); font-size: .78rem; display: block; }
.totalcard .amt {
  display: block; font-size: 2rem; font-weight: 600;
  letter-spacing: -.02em; margin-top: .1rem;
}

/* -------------------------------------------------- screens: shared bits -- */

.pagehead {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 1.25rem;
}
.pagehead .sub { margin: 0; }
.sectionhead {
  font-size: .8rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); margin: 0 0 .6rem;
}

.twocol { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; align-items: start; }
/* Grid children default to min-width:auto, so a table with a min-width pushes
   its column wide and squeezes the one beside it. This lets them shrink and
   the table scroll inside its own .scroller instead. */
.twocol > *, .cardgrid > * { min-width: 0; }
.cardgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; }
@media (max-width: 780px) {
  .twocol { grid-template-columns: 1fr; }
}
.panel.narrow { max-width: 26rem; }

/* Figure lists — the money day and the month summary. */
.figures { margin: 0; }
.figures > div {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; padding: .3rem 0;
}
.figures > div.rule {
  border-top: 1px solid var(--hair); margin-top: .35rem; padding-top: .6rem;
}
.figures > div.rule dt, .figures > div.rule dd { font-weight: 600; }
.figures dt { color: var(--muted); margin: 0; }
.figures dd { margin: 0; }
.figures .derived { color: var(--faint); font-size: .75rem; }

.foot.bottomline { background: var(--bg); }
.foot.bottomline span:first-child { color: var(--ink); font-weight: 600; font-size: .95rem; }
.foot .tot.big { font-size: 1.5rem; }

.amt {
  display: block; font-size: 1.75rem; font-weight: 600; letter-spacing: -.02em;
}
.who { color: var(--muted); font-size: .8rem; }

/* Inline undo forms inside table cells. */
.inline { display: flex; align-items: center; gap: .35rem; }
.control.tiny { width: 7rem; min-height: 2rem; padding: .25rem .4rem; font-size: .8rem; }

/* Search that lives in a panel header rather than on its own. */
.inline-search { max-width: 16rem; min-height: 2.25rem; font-size: .875rem; }

/* Delivery and count rows. lines.js keys off data-* attributes, not these
   classes — renaming a data attribute silently breaks it and no test notices. */
.linerows { display: flex; flex-direction: column; gap: .6rem; }
.linerow { display: grid; grid-template-columns: 1fr 8rem 8rem auto; gap: .5rem; align-items: center; }
.linerow.two { grid-template-columns: 1fr 12rem auto; }
@media (max-width: 700px) {
  .linerow, .linerow.two { grid-template-columns: 1fr 1fr; }
  .linerow select { grid-column: 1 / -1; }
}

.checkline {
  display: flex; align-items: center; gap: .6rem;
  margin: .9rem 0 0; font-size: .875rem; color: var(--ink); font-weight: 400;
}
.checkline input { width: 1.1rem; height: 1.1rem; }

/* What needs attention. */
.attention { display: flex; flex-direction: column; gap: .9rem; }
.flag .what { margin: 0; font-weight: 500; display: flex; align-items: center; gap: .45rem; }
.flag .detail { margin: .2rem 0 0; color: var(--muted); font-size: .8rem; }

/* ------------------------------------------------------------ dashboard -- */

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1rem;
}
.tile {
  background: var(--surface);
  border: 1px solid var(--hair);
  border-radius: 10px;
  box-shadow: var(--shadow-sm);
  padding: 1rem;
  display: flex; flex-direction: column; gap: .15rem;
  min-width: 0;
}
.tile .label {
  font-size: .72rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
}
.tile .value {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 1.6rem; font-weight: 600; letter-spacing: -.02em;
  line-height: 1.15; overflow-wrap: anywhere;
}
.tile .note { font-size: .75rem; color: var(--muted); }
/* The headline tile. One number an owner opens the page for should not look
   like the five beside it. */
.tile.lead { background: var(--sidebar); border-color: var(--sidebar); }
.tile.lead .label { color: var(--sidebar-text); }
.tile.lead .value { color: #fff; font-size: 1.9rem; }
.tile.lead .note { color: var(--sidebar-text); }
.tile .value.down { color: var(--danger); }
.tile.lead .value.down { color: #FF9E97; }
.tile .delta { font-size: .8125rem; color: var(--muted); }
/* Direction is carried by the arrow glyph as well as the colour: a delta that
   only means something in colour means nothing to a colourblind reader, and
   nothing at all in print. */
.tile .delta.up { color: var(--brand); }
.tile .delta.down { color: var(--danger); }

/* The line chart: an inline SVG rather than a library, drawn from geometry
   computed server-side in reports/queries.py. preserveAspectRatio="none" on
   the <svg> lets it stretch to its panel width while the viewBox keeps the
   computed y values meaningful.

   The viewBox is fixed at 720x200 user units and the SVG scales to its
   container, so stroke-width and font-size below are NOT screen pixels —
   they shrink with the container. `vector-effect="non-scaling-stroke"` on
   the polylines, axis/zero lines and marker rings (set in
   _line_chart.html) keeps their stroke-width in true screen pixels at any
   width; text has no such escape hatch, so its font-size is picked for the
   narrow case rather than the wide one. */
.chart { width: 100%; height: auto; display: block; }
.chart .grid { stroke: var(--chart-grid); stroke-width: 1; }
.chart .axis { stroke: var(--hair); stroke-width: 1; }
.chart .series { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart .series.chart-sales { stroke: var(--chart-sales); }
.chart .series.chart-margin { stroke: var(--chart-margin); }
.chart .series.chart-cash { stroke: var(--chart-cash); }
.chart .zero { stroke: var(--hair); stroke-width: 1; stroke-dasharray: 3 3; }
.chart .marker { r: 4; stroke: var(--surface); stroke-width: 2; }
.chart .marker.chart-sales { fill: var(--chart-sales); }
.chart .marker.chart-margin { fill: var(--chart-margin); }
.chart .marker.chart-cash { fill: var(--chart-cash); }
.chart text { fill: var(--faint); font-size: 18px; font-family: var(--mono); }

.chart-legend { display: flex; gap: 1rem; align-items: center; font-size: .8125rem; color: var(--muted); }
.chart-legend .key { display: inline-flex; align-items: center; gap: .375rem; }
.chart-legend .swatch { width: 10px; height: 10px; border-radius: 2px; flex: none; }
.chart-legend .swatch.chart-sales { background: var(--chart-sales); }
.chart-legend .swatch.chart-margin { background: var(--chart-margin); }

.bars { display: flex; flex-direction: column; gap: .55rem; }
.bars .row { display: grid; grid-template-columns: 8.5rem 1fr auto; gap: .6rem; align-items: center; }
/* display:block matters — these are spans, and an inline element ignores
   height, which drew the tracks empty. */
.bars .track {
  display: block; background: var(--bg); border-radius: 100px;
  height: .55rem; overflow: hidden;
}
.bars .fill { display: block; background: var(--brand); height: 100%; border-radius: 100px; }
.bars .cat { color: var(--muted); font-size: .8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bars .amt2 {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: .8rem; text-align: right;
}
@media (max-width: 560px) {
  .bars .row { grid-template-columns: 6rem 1fr auto; }
}

/* The generic bar partial (_bar_chart.html): cash's sibling charts, drawn as
   plain HTML rather than SVG so ranked, long product names stay selectable
   and un-clipped. Its own container class — `.barchart`, not `.bars` — so it
   cannot collide with the expenses panel's own `.bars .row/.cat/.track/.fill/
   .amt2` markup above. It once reused `.bars` and silently changed that
   panel's row gap, a panel the dashboard spec placed out of scope. */
.barchart { display: flex; flex-direction: column; gap: .5rem; }
.bar-row { display: grid; grid-template-columns: minmax(6rem, 12rem) 1fr auto; gap: .75rem; align-items: center; }
.bar-label { color: var(--ink); font-size: .875rem; display: flex; flex-direction: column; gap: .1rem; }
/* The units figure a manager needs to reorder — kept visible on every bar
   rather than dropped along with the table's owner-only "Made" column. */
.bar-note { color: var(--muted); font-size: .75rem; }
.bar-track { background: var(--bg); border-radius: 3px; height: 14px; }
/* 4px rounded ends, anchored at the baseline — the fill starts flush left and
   only its far end is rounded, so the bar cannot appear to float. */
.bar-fill { display: block; height: 100%; background: var(--chart-sales); border-radius: 0 4px 4px 0; }
.bar-value {
  color: var(--muted); font-size: .8125rem;
  display: flex; flex-direction: column; align-items: flex-end; gap: .1rem;
}
/* Per-product profit — an owner-only figure the old table gated behind
   may_see_owner_figures. Its presence in the row (not a role check here)
   is the gate: a manager's row never carries `profit` to begin with. */
.bar-made { color: var(--faint); font-size: .75rem; }
@media (max-width: 860px) { .bar-row { grid-template-columns: 1fr auto; } .bar-track { grid-column: 1 / -1; } }
