/* ==========================================================================
   Site Stock -- app.css
   W3.CSS 3.00 provides the reset, the grid, the button and input primitives.
   Everything below re-skins them into one system: painted steel, off-white
   paper, one hazard-orange accent, 3px radius, hairline rules, no shadows
   except on the two pieces of chrome that genuinely float over the content.

   Contents
     1  Tokens
     2  W3.CSS overrides
     3  App shell (app bar, sidebar, tab bar, sheet, FAB)
     4  Type
     5  The tally ledger
     6  Forms
     7  Desktop tables
     8  Buttons and chips
     9  Toasts, empty states, misc
    10  Responsive
    11  Motion
   ========================================================================== */

/* 1  Tokens ---------------------------------------------------------------- */
:root {
  --graphite:  #1C2024;   /* painted steel: app bar, sidebar, primary ink  */
  --ink:       #23282D;   /* body text                                     */
  --ink-2:     #3C454E;   /* secondary headings                            */
  --steel:     #5A6672;   /* units, counts, quiet labels                   */
  --steel-2:   #8A939C;   /* placeholders, disabled                       */
  --bone:      #F4F4F1;   /* page, cool off-white                          */
  --paper:     #FFFFFF;   /* raised blocks: the only pure white            */
  --rule:      #E3E1DB;   /* hairline                                      */
  --rule-2:    #CFCCC3;   /* stronger hairline, table header line           */
  --hazard:    #C9541A;   /* the single accent                             */
  --hazard-lo: #FBEDE4;   /* hazard at 12% for chip fills                  */
  --in:        #2E7D5B;   /* ledger in  /  positive figures                */
  --out:       #B3261E;   /* ledger out /  negative figures                */
  --info:      #2C5D7C;

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

  --r:      3px;         /* sheet metal, not a rounded card */
  --r-sm:   2px;
  --tap:    48px;        /* smallest comfortable touch target */

  --appbar-h: 52px;
  --tabbar-h: 58px;
  --rail-w:   68px;
  --side-w:   236px;
  --gutter:   14px;

  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);

  --shadow-chrome: 0 1px 0 var(--rule), 0 -1px 0 var(--rule);
  --speed: 120ms;
}

@media (min-width: 1024px) {
  :root { --appbar-h: 60px; --gutter: 24px; }
}

/* 2  W3.CSS overrides ------------------------------------------------------ */
html {
  -webkit-text-size-adjust: 100%;
  height: 100%;
}

body.app {
  margin: 0;
  min-height: 100%;
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.47;
  color: var(--ink);
  background: var(--bone);
  letter-spacing: -0.003em;
  /* No rubber-band of the whole document: the tab bar and app bar are fixed. */
  overscroll-behavior-y: none;
  -webkit-tap-highlight-color: transparent;
}

/* Chrome never selects, content always can. */
body.app .appbar,
body.app .sidebar,
body.app .tabbar,
body.app .sheet,
body.app .fab,
body.app .toasts { -webkit-user-select: none; user-select: none; }

a { color: var(--hazard); text-decoration: none; }
a:hover { text-decoration: underline; }
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--hazard);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* W3 classes we reuse, restyled so nothing looks like stock W3.CSS. */
.w3-button {
  border-radius: var(--r);
  touch-action: manipulation;
  transition: background-color var(--speed) linear, color var(--speed) linear,
              border-color var(--speed) linear;
}
.w3-input, .w3-select {
  border-radius: var(--r);
  border-color: var(--rule-2);
}
.w3-table th { border-bottom-color: var(--rule-2); }

/* 3  App shell ------------------------------------------------------------- */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.ic {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  display: block;
  fill: none;
}

.skiplink {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 90;
  padding: 10px 14px;
  background: var(--graphite);
  color: #fff;
  border-radius: var(--r);
  transform: translateY(-200%);
  transition: transform var(--speed) linear;
}
.skiplink:focus { transform: none; text-decoration: none; }

/* --- top bar ------------------------------------------------------------- */
.appbar {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  height: calc(var(--appbar-h) + var(--safe-t));
  padding: var(--safe-t) calc(10px + var(--safe-r)) 0 calc(10px + var(--safe-l));
  background: var(--graphite);
  color: #F2F3F2;
  box-shadow: 0 1px 0 rgba(0, 0, 0, .18);
}

.appbar__lead {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.appbar__mark {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex: 0 0 auto;
  background: var(--hazard);
  color: #fff;
  border-radius: var(--r-sm);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0;
}

/* The WeMep wordmark. It is blue, so it sits on a light chip to stay legible
   against the dark shell. */
.brandmark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  background: #fff;
  border-radius: var(--r-sm);
  padding: 3px 6px;
  box-sizing: border-box;
}
.brandmark img {
  display: block;
  height: 16px;
  width: auto;
  max-width: 48px;
  object-fit: contain;
}
.brandmark--lg {
  padding: 6px 10px;
  border-radius: var(--r);
}
.brandmark--lg img {
  height: 28px;
  width: auto;
  max-width: 100px;
  object-fit: contain;
}
.sidebar__brand .brandmark {
  padding: 3px 5px;
  max-height: 24px;
}
.sidebar__brand .brandmark img {
  height: 13px;
  width: auto;
  max-width: 36px;
  object-fit: contain;
}

.appbar__title {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.014em;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.appbar__tail {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
}

.appbar__meta {
  font-size: 12.5px;
  color: #9BA4AC;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Actions inside the bar: a bordered ghost button that fits the dark bar. */
.appbar .btn {
  height: 34px;
  padding: 0 11px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13.5px;
  font-weight: 600;
  border-radius: var(--r);
  border: 1px solid #3B434A;
  background: transparent;
  color: #EDEFF0;
  white-space: nowrap;
  touch-action: manipulation;
  transition: background-color var(--speed) linear, border-color var(--speed) linear;
}
.appbar .btn .ic { width: 17px; height: 17px; }
.appbar .btn:hover { background: #2A3036; border-color: #4A535B; text-decoration: none; }
.appbar .btn--go { background: var(--hazard); border-color: var(--hazard); color: #fff; }
.appbar .btn--go:hover { background: #B44A16; border-color: #B44A16; }
.appbar .btn--quiet { border-color: transparent; color: #B9C1C8; padding: 0 7px; }

.iconbtn {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  border: 0;
  border-radius: var(--r);
  background: transparent;
  color: inherit;
  cursor: pointer;
  touch-action: manipulation;
  padding: 0;
  transition: background-color var(--speed) linear;
}
.iconbtn:hover { background: rgba(255, 255, 255, .09); text-decoration: none; }
.appbar .iconbtn--inapp { margin-left: -6px; color: #F2F3F2; }
.appbar .iconbtn--inapp:hover { background: #2A3036; }

/* --- shell and sidebar --------------------------------------------------- */
.shell { min-height: 100%; }

.sidebar { display: none; }

.main {
  padding: calc(var(--appbar-h) + var(--safe-t) + 12px) var(--gutter) 0;
  padding-left: calc(var(--gutter) + var(--safe-l));
  padding-right: calc(var(--gutter) + var(--safe-r));
  /* Room for the tab bar and the floating button. */
  padding-bottom: calc(var(--tabbar-h) + var(--safe-b) + 84px);
  max-width: 1180px;
}

/* --- bottom tab bar ------------------------------------------------------ */
.tabbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 45;
  display: flex;
  height: calc(var(--tabbar-h) + var(--safe-b));
  padding-bottom: var(--safe-b);
  background: var(--paper);
  border-top: 1px solid var(--rule);
  box-shadow: 0 -1px 0 rgba(0, 0, 0, .03);
}

.tabbar__item {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: var(--tap);
  border: 0;
  background: transparent;
  color: var(--steel);
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0;
  text-decoration: none;
  cursor: pointer;
  padding: 0;
  touch-action: manipulation;
  transition: color var(--speed) linear;
}
.tabbar__item .ic { width: 21px; height: 21px; }
.tabbar__item:active { color: var(--hazard); }
.tabbar__item:hover { text-decoration: none; }
.tabbar__item.is-current { color: var(--hazard); }

/* --- floating add button ------------------------------------------------- */
.fab {
  position: fixed;
  right: calc(16px + var(--safe-r));
  bottom: calc(var(--tabbar-h) + var(--safe-b) + 16px);
  z-index: 44;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 50px;
  padding: 0 18px 0 15px;
  background: var(--hazard);
  color: #fff;
  border-radius: var(--r);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.006em;
  box-shadow: 0 2px 6px rgba(28, 32, 36, .22);
  touch-action: manipulation;
  transition: background-color var(--speed) linear, transform 90ms linear;
}
.fab:hover { background: #B44A16; text-decoration: none; color: #fff; }
.fab:active { transform: translateY(1px); }
.fab .ic { width: 19px; height: 19px; }

/* --- more sheet ---------------------------------------------------------- */
.sheet { position: fixed; inset: 0; z-index: 60; }
.sheet[hidden] { display: none; }
.sheet__scrim {
  position: absolute;
  inset: 0;
  background: rgba(20, 23, 26, .5);
  animation: fade 140ms linear;
}
.sheet__panel {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--paper);
  border-top: 1px solid var(--rule);
  border-radius: 8px 8px 0 0;
  padding: 6px 0 calc(10px + var(--safe-b));
  max-height: 86vh;
  overflow-y: auto;
  animation: sheet-up 200ms cubic-bezier(.22, .7, .3, 1);
}
.sheet__grip {
  width: 36px;
  height: 4px;
  border-radius: 2px;
  background: var(--rule-2);
  margin: 4px auto 10px;
}
.sheet__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 12px 12px;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 4px;
}
.sheet__who { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.sheet__who strong { font-size: 15px; font-weight: 600; }
.sheet__who span { font-size: 12.5px; color: var(--steel); }

.sheet__links { list-style: none; margin: 0; padding: 0; }
.sheet__links a {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: var(--tap);
  padding: 0 16px;
  color: var(--ink);
  font-size: 15px;
  font-weight: 500;
  border-bottom: 1px solid var(--rule);
}
.sheet__links a:active { background: var(--bone); text-decoration: none; }
.sheet__links .ic { color: var(--steel); }
.sheet__foot {
  margin: 0;
  padding: 14px 16px 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--steel-2);
}

.avatar {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  background: var(--graphite);
  color: #fff;
  border-radius: var(--r-sm);
  font-size: 14px;
  font-weight: 600;
}

/* 4  Type ------------------------------------------------------------------ */
h1, h2, h3, h4 {
  font-family: var(--font);
  color: var(--graphite);
  font-weight: 600;
  letter-spacing: -0.016em;
  line-height: 1.24;
  margin: 0;
}
h2 { font-size: 16px; }
h3 { font-size: 14.5px; }

p { margin: 0 0 10px; max-width: 68ch; }
p:last-child { margin-bottom: 0; }

a { overflow-wrap: anywhere; }

.num, .tally, td.num, th.num, .money {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
.mono { font-family: var(--mono); font-size: .92em; letter-spacing: .01em; }

.muted  { color: var(--steel); }
.quiet  { color: var(--steel-2); }
.tiny   { font-size: 12.5px; }
.strong { font-weight: 600; }
.pos    { color: var(--in); }
.neg    { color: var(--out); }
.accent { color: var(--hazard); }

.section {
  margin: 0 0 18px;
}
.section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 0 2px 8px;
  border-bottom: 1px solid var(--rule-2);
  margin-bottom: 2px;
}
.section__head h2 { margin: 0; }
.section__note { font-size: 12.5px; color: var(--steel); }
/* A section head can hold a real link, so it has to be a real target. */
.section__head a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 2px;
  color: var(--steel);
  font-size: 12.5px;
  font-weight: 600;
}
.section__head a:hover { color: var(--hazard); text-decoration: none; }

.prose { max-width: 68ch; }
.prose p { max-width: 68ch; }

/* 5  The tally ledger ------------------------------------------------------ */
.block {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  overflow: hidden;
}
.block--flush { border-left: 0; border-right: 0; border-radius: 0; }
.block__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--rule);
  background: #FAFAF8;
  font-size: 13px;
  color: var(--steel);
}
.block__head strong { color: var(--graphite); font-weight: 600; }

.rows { list-style: none; margin: 0; padding: 0; min-width: 0; }

/* One row of the ledger. Tap-friendly on a phone, a hairline on a desktop. */
.trow {
  position: relative;
  display: grid;
  /* minmax(0, 1fr) for the same reason as .grid-2: a bare 1fr will not shrink
     below the min-content of the name, and a long item name in a narrow
     column pushes the whole row past the edge of the page. */
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "name tally" "bar bar" "sub sub";
  align-items: baseline;
  column-gap: 12px;
  padding: 11px 12px 12px;
  border-bottom: 1px solid var(--rule);
  color: inherit;
  background: var(--paper);
  min-width: 0;
}
.rows > li:last-child .trow { border-bottom: 0; }
.trow:hover { text-decoration: none; background: #FCFCFB; }
.trow:active { background: var(--bone); }

.trow__name {
  grid-area: name;
  min-width: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--graphite);
  letter-spacing: -0.008em;
  overflow-wrap: anywhere;
}
.trow__sub {
  grid-area: sub;
  justify-self: stretch;
  margin-top: 3px;
  min-width: 0;
  font-size: 12.5px;
  color: var(--steel);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.trow__sub .sep { color: var(--rule-2); padding: 0 5px; }

/* The signature: the balance, big, tabular, right-aligned, with a unit. */
.trow__tally {
  grid-area: tally;
  display: flex;
  align-items: baseline;
  gap: 3px;
  font-size: 25px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--graphite);
}
.trow__tally b { font: inherit; letter-spacing: inherit; }
.trow__tally .u {
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--steel-2);
}
.trow--low .trow__tally { color: var(--hazard); }
.trow--out .trow__tally { color: var(--out); }

/* 3px reorder bar. Steel while healthy, hazard once it needs reordering.
   justify-self: stretch is load-bearing. The bar and the sub-line are declared to
   span both grid columns, but an auto-sized track will not stretch a grid item
   across it, so both collapsed to the width of their own content while the text
   inside overflowed invisibly. */
.trow__bar {
  grid-area: bar;
  justify-self: stretch;
  align-self: stretch;
  height: 3px;
  margin-top: 9px;
  border-radius: 2px;
  background: #EDEBE5;
  overflow: hidden;
}
.trow__bar i {
  display: block;
  height: 100%;
  width: var(--fill, 0%);
  background: var(--steel-2);
  border-radius: 2px;
  transition: width 520ms cubic-bezier(.2, .8, .25, 1);
}
.trow--low .trow__bar i { background: var(--hazard); }
.trow--out .trow__bar i { background: var(--out); }

/* The row stays stacked until there is genuinely room for four columns.
   Anything earlier overflows on a tablet, which is worse than a tall list.

   The minimums are deliberately smaller than they look like they should be.
   A 1000px viewport does not mean a 1000px row: on the dashboard the rows sit
   in a two-column grid, so at 1024px each one is only about 360px wide. Sized
   for a full-width row, the four columns needed about 400px and squeezed the
   sub-line to zero, so its text overflowed invisibly and the page gained a
   horizontal scrollbar. These minimums add up to roughly 320px, which fits a
   half-width column and still lets the 2.2fr/1fr tracks grow into whatever
   space there is. */
@media (min-width: 1000px) {
  .trow {
    grid-template-columns: minmax(120px, 2.2fr) minmax(36px, 1fr) auto minmax(80px, auto);
    grid-template-areas: "name bar sub tally";
    align-items: center;
    column-gap: 12px;
    padding: 9px 14px;
  }
  .trow__bar { margin-top: 0; }
  .trow__sub { margin-top: 0; text-align: right; }
  .trow__tally { justify-content: flex-end; font-size: 21px; }
}

/* Status chips: state, not decoration. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 20px;
  padding: 0 7px;
  border-radius: var(--r-sm);
  border: 1px solid var(--rule-2);
  background: #F7F6F3;
  color: var(--ink-2);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .005em;
  white-space: nowrap;
  vertical-align: 1px;
}
.chip .ic { width: 12px; height: 12px; }
.chip--low    { border-color: #E9C6B1; background: var(--hazard-lo); color: #9C3F13; }
.chip--out    { border-color: #E7BBB8; background: #FBEBEA; color: #8E1E18; }
.chip--in     { border-color: #BEDCCB; background: #E9F3ED; color: #1F5C41; }
.chip--warn   { border-color: #E9C6B1; background: var(--hazard-lo); color: #9C3F13; }
.chip--quiet  { border-color: var(--rule); background: #F7F6F3; color: var(--steel); }

/* A line that was voided stays visible but is struck through. */
.voided { color: var(--steel-2); }
.voided .strike { text-decoration: line-through; text-decoration-color: var(--out); }
.voidnote { display: block; font-size: 12px; color: var(--out); margin-top: 2px; }

/* 6  Forms ----------------------------------------------------------------- */
.form { margin: 0; }

.field { margin: 0 0 14px; }
.field:last-child { margin-bottom: 0; }

.field > label, .lbl {
  display: block;
  margin-bottom: 5px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-2);
  letter-spacing: -0.004em;
}
.field .hint {
  display: block;
  margin-top: 5px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--steel);
}
.field .hint--warn { color: #9C3F13; }

.inp, .w3-input, .w3-select, .sel {
  width: 100%;
  min-height: var(--tap);
  padding: 11px 12px;
  font-family: inherit;
  font-size: 16px; /* 16px stops iOS and Android WebView zooming on focus */
  line-height: 1.4;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--rule-2);
  border-radius: var(--r);
  -webkit-appearance: none;
  appearance: none;
  transition: border-color var(--speed) linear, background-color var(--speed) linear;
}
textarea.inp { min-height: 84px; resize: vertical; }
.inp:hover, .w3-input:hover, .w3-select:hover { border-color: #A9A69E; }
.inp:focus, .w3-input:focus, .w3-select:focus {
  border-color: var(--hazard);
  background: #FFFDFC;
}
.inp::placeholder { color: var(--steel-2); }
.inp[aria-invalid="true"] { border-color: var(--out); background: #FFFBFA; }

.sel, .w3-select {
  padding-right: 38px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%235A6672' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9.5 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
}

/* minmax(0, 1fr) rather than 1fr. A bare 1fr track will not shrink below the
   min-content width of what is in it, so two of them side by side can push
   past the viewport. That happened between 1024 and 1099px, where the sidebar
   is already 236px wide but the content area is not yet wide enough for two
   columns. Letting the track go to zero and clipping the text inside it is the
   lesser fault, and the inner layout below handles that. */
.grid-2 { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 18px; }
@media (min-width: 1024px) { .grid-2 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.grid-3 { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 14px; }
@media (min-width: 900px) { .grid-3 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); } }

/* Calculated read-only figures. They are never editable, so they look it. */
.calc {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  min-height: var(--tap);
  padding: 11px 12px;
  background: #F7F6F3;
  border: 1px dashed var(--rule-2);
  border-radius: var(--r);
  font-variant-numeric: tabular-nums;
}
.calc__label { font-size: 13px; color: var(--steel); }
.calc__value { font-size: 19px; font-weight: 600; color: var(--graphite); letter-spacing: -0.02em; }

.calc--total {
  background: var(--graphite);
  border: 1px solid var(--graphite);
  border-radius: var(--r);
  padding: 13px 14px;
}
.calc--total .calc__label { color: #A8B0B7; }
.calc--total .calc__value { color: #fff; font-size: 22px; }

.choices { display: flex; flex-wrap: wrap; gap: 7px; }
.choice {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 42px;
  padding: 0 13px;
  border: 1px solid var(--rule-2);
  border-radius: var(--r);
  background: var(--paper);
  color: var(--ink-2);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  touch-action: manipulation;
  transition: border-color var(--speed) linear, background-color var(--speed) linear,
              color var(--speed) linear;
}
.choice input { position: absolute; opacity: 0; width: 0; height: 0; }
.choice:hover { border-color: #A9A69E; }
/* A choice rendered as a link has no checkbox inside it, so it is marked with
   .is-on instead of :has(input:checked). */
.choice.is-on,
.choice[aria-current] {
  border-color: var(--hazard);
  background: var(--hazard-lo);
  color: #8F3A11;
}
.choice.is-on .ic,
.choice[aria-current] .ic { color: var(--hazard); }
.choice:has(input:checked) {
  border-color: var(--hazard);
  background: var(--hazard-lo);
  color: #8F3A11;
}
.choice:has(input:checked) .ic { color: var(--hazard); }
.choice .ic { width: 17px; height: 17px; color: var(--steel); }
.choice:has(input:focus-visible) { outline: 2px solid var(--hazard); outline-offset: 2px; }

/* Sticky action bar at the foot of a form, clear of the tab bar. */
.formbar {
  position: sticky;
  bottom: calc(var(--tabbar-h) + var(--safe-b));
  z-index: 20;
  display: flex;
  gap: 8px;
  margin: 18px calc(var(--gutter) * -1) 0;
  padding: 10px var(--gutter) calc(10px + var(--safe-b));
  background: rgba(244, 244, 241, .96);
  border-top: 1px solid var(--rule);
  -webkit-backdrop-filter: saturate(140%) blur(6px);
  backdrop-filter: saturate(140%) blur(6px);
}
.formbar .btn { flex: 1 1 auto; justify-content: center; min-height: var(--tap); }
.formbar .btn--side { flex: 0 0 auto; padding: 0 16px; }

@media (min-width: 1024px) {
  .formbar {
    bottom: 0;
    margin: 20px 0 0;
    padding: 12px 0;
    background: none;
    border-top: 0;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .formbar .btn { flex: 0 0 auto; min-width: 150px; }
}

/* Inline error, plain language, says what to do. */
.alert {
  display: flex;
  gap: 9px;
  padding: 11px 12px;
  border: 1px solid #E7BBB8;
  border-left: 3px solid var(--out);
  border-radius: var(--r);
  background: #FDF4F3;
  color: #7E1A15;
  font-size: 13.5px;
  line-height: 1.45;
  margin: 0 0 14px;
}
.alert .ic { width: 17px; height: 17px; margin-top: 1px; flex: 0 0 auto; }
.alert--notice { border-color: #E9C6B1; border-left-color: var(--hazard); background: #FDF6F1; color: #8F3A11; }
.alert--warn   { border-color: #E0A79C; border-left-color: var(--danger); background: #FCF1EF; color: #8E2A1C; }
.alert--info   { border-color: #C3D8E4; border-left-color: var(--info); background: #F2F7FA; color: #23485F; }
/* The outcome of something that worked. Green is used nowhere else in the app
   body -- the ledger's positive figures carry it instead -- so a confirmation
   never competes with a figure the reader is meant to add up. */
.alert--success {
  border-color: #BEDCCB;
  border-left-color: var(--in);
  background: #E9F3ED;
  color: #1F5C41;
}
.alert p { margin: 0; max-width: none; }
.alert ul { margin: 6px 0 0; padding-left: 18px; }

/* 7  Desktop tables -------------------------------------------------------- */
.tablewrap {
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--paper);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th, .table td { padding: 9px 12px; text-align: left; white-space: nowrap; }
/* .tablewrap scrolls sideways, so it is the nearest scrollport. A sticky
   offset measured from its top edge pushed these cells down onto the first
   rows instead of holding them above the data, so the header stays in flow. */
.table thead th {
  background: #FAFAF8;
  border-bottom: 1px solid var(--rule-2);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--steel);
  letter-spacing: .02em;
}
.table tbody tr { border-bottom: 1px solid var(--rule); }
.table tbody tr:last-child { border-bottom: 0; }
.table tbody tr:hover { background: #FCFCFB; }
.table td.num, .table th.num { text-align: right; }
.table .wrap { white-space: normal; min-width: 180px; }
.table tfoot td {
  border-top: 2px solid var(--rule-2);
  font-weight: 600;
  color: var(--graphite);
  background: #FAFAF8;
}
.table--dense th, .table--dense td { padding: 7px 10px; font-size: 13.5px; }

/* 7b  Column tables --------------------------------------------------------
   The catalogue, the machines, the sites and the two cost ledgers are all read
   by comparing columns against each other -- is this balance lower than the
   one above it, which sites are past their reorder point -- so they are laid
   out as columns rather than as a stack of cards.

   Two things the plain .table rules cannot do on their own:

   1. A row that leads somewhere has to stay one tap target. An <a> cannot wrap
      a <tr>, so the link lives in the first cell and throws an ::after over the
      rest of the row. Without this only the name is clickable, which on a
      phone is a much smaller target than the row a store keeper aims at.
   2. Seven columns do not fit a 360px phone. .table--fold turns the table into
      one card per row below 760px, each cell carrying its own label from
      data-label, so the figures stay readable instead of becoming a sideways
      scroll. The <thead> stays in the document for screen readers. */

/* The stretched link. Only applied to rows that are purely a link: a row that
   carries buttons or a <form> would have its clicks swallowed by the overlay.
   position: relative sits on the cell rather than the <tr> because a
   positioned table row is not a dependable containing block across engines. */
.rt-link { position: relative; text-align: left; font-weight: 600; }
.stock-table__link { color: inherit; text-decoration: none; }
.rt-link .stock-table__link::after { content: ''; position: absolute; inset: 0; }
.stock-table tbody tr:hover .stock-table__link,
.table tbody tr:hover .rt-link .stock-table__link { text-decoration: underline; }
.stock-table__link:focus-visible { outline: 2px solid var(--hazard); outline-offset: 2px; }

/* The actions cell has to sit above that overlay, or the stretched link would
   take the tap meant for Edit or Void. It carries the column's label on a
   phone and its buttons on a desktop, so it is the one cell that earns both. */
.rt-actions { position: relative; z-index: 2; }
.rt-actions .btnrow { gap: 4px; }

.stock-table__item { min-width: 190px; }
.stock-table__item .chip,
.rt-cell .chip { margin-left: 6px; }

/* The balance stays the signature figure: big, tabular, right-aligned, and
   carrying its unit. */
.stock-table__left b,
.rt-total b {
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.02em;
}
.stock-table__left .u {
  margin-left: 4px;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--steel-2);
}
.stock-row--low  .stock-table__left b { color: var(--hazard); }
.stock-row--out  .stock-table__left b { color: var(--out); }

/* The reorder bar, same 3px rule as .trow__bar but sized to its cell. */
.cellbar {
  display: block;
  height: 3px;
  min-width: 64px;
  border-radius: 2px;
  background: #EDEBE5;
  overflow: hidden;
}
.cellbar i {
  display: block;
  height: 100%;
  width: var(--fill, 0%);
  background: var(--steel-2);
  border-radius: 2px;
  transition: width 520ms cubic-bezier(.2, .8, .25, 1);
}
.stock-row--low .cellbar i { background: var(--hazard); }
.stock-row--out .cellbar i { background: var(--out); }

/* A site's share of the spend: the bar with the percentage written on it, so
   the figure is readable without measuring the bar against its neighbours. */
.rt-share { white-space: nowrap; }
.rt-share__pct {
  display: inline-block;
  margin-left: 7px;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--steel);
}

/* The empty-state cell spans the table, so it must not inherit the padding
   that the other cells carry or the message floats away from the edges. */
.rt-void, .stock-table__void { padding: 0 !important; white-space: normal; }

@media (max-width: 759px) {
  /* Fold to one card per row. The <thead> is kept for screen readers and
     hidden visually; each cell shows its own data-label instead. */
  .table--fold thead {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .table--fold tbody tr { display: block; padding: 12px 14px; }
  .table--fold tbody th,
  .table--fold tbody td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 2px 0;
    text-align: left;
    white-space: normal;
  }
  .table--fold tbody td[data-label]::before {
    content: attr(data-label);
    flex: 0 0 auto;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--steel-2);
  }
  /* The first cell is the row's title, not a labelled figure, so it keeps its
     own weight and takes no label. */
  .table--fold tbody th::before,
  .table--fold tbody td.rt-cell::before { content: none; }
  .table--fold tbody td.num { text-align: right; }

  /* The bar wants the full width of the card, and its label sits on the same
     line as the figure rather than above it. */
  .rt-share { padding-top: 8px !important; }
  .rt-share::before { align-self: center; }
  .rt-share .cellbar { flex: 1 1 auto; min-width: 0; }

  .rt-total { padding-top: 8px !important; }
  .rt-total b { font-size: 21px; }

  /* Correct and Void have to stay reachable and stay side by side. */
  .rt-actions { padding-top: 8px !important; }
  .rt-actions .btnrow { justify-content: flex-start !important; flex-wrap: wrap; }
  .rt-actions::before { align-self: center; }

  .stock-table__item, .rt-cell { min-width: 0; }
  .stock-table__level { padding-top: 8px !important; }
  .stock-table__level::before { align-self: center; }
  .stock-table__left { padding-top: 8px !important; }
  .stock-table__left b { font-size: 21px; }
}

/* 8  Buttons and chips ----------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 42px;
  padding: 0 15px;
  font-family: inherit;
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: -0.006em;
  line-height: 1;
  color: var(--ink-2);
  background: var(--paper);
  border: 1px solid var(--rule-2);
  border-radius: var(--r);
  cursor: pointer;
  text-decoration: none;
  touch-action: manipulation;
  transition: background-color var(--speed) linear, border-color var(--speed) linear,
              color var(--speed) linear;
}
.btn:hover { background: #F7F6F3; border-color: #A9A69E; text-decoration: none; }
.btn:active { background: #F0EEE9; }
.btn .ic { width: 17px; height: 17px; }
.btn--primary { background: var(--hazard); border-color: var(--hazard); color: #fff; }
.btn--primary:hover { background: #B44A16; border-color: #B44A16; color: #fff; }
.btn--primary:active { background: #A34414; }
.btn--dark { background: var(--graphite); border-color: var(--graphite); color: #fff; }
.btn--dark:hover { background: #2C3238; border-color: #2C3238; color: #fff; }
.btn--danger { color: #8E1E18; border-color: #E7BBB8; background: #FDF4F3; }
.btn--danger:hover { background: #FBE7E5; border-color: #DDA19D; }
.btn--ghost { background: transparent; border-color: transparent; color: var(--steel); }
.btn--ghost:hover { background: rgba(28, 32, 36, .06); color: var(--ink); }
.btn--sm { min-height: 34px; padding: 0 11px; font-size: 13.5px; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .45; pointer-events: none; }

/* The small button is a deliberate desktop density, and it is the right size for
   a mouse. A thumb is not a mouse: 34px is under the 44px that is reliably
   hittable on a phone, and these sit in the middle of a table of things a store
   keeper taps while holding stock. The whole button is the target, so there is
   no argument for keeping it short there. */
@media (pointer: coarse) {
  .btn--sm { min-height: 44px; padding: 0 15px; }
  /* The appbar holds one or two of these, and the bar has a fixed height. */
  .appbar .btn--sm { height: 44px; }
}

/* Same reasoning for the small text link that reads as a ledger row rather than
   a button. It is the cheapest thing on the page to hit and the easiest to
   miss. */
@media (pointer: coarse) {
  .linkrow .btn--quiet,
  .linkrow .btn--sm { min-height: 44px; }
  .tfoot a,
  .trow--link a { min-height: 44px; display: inline-flex; align-items: center; }
}

/* A bare text link inside a heading or a hint line is 19px tall and about 4mm
   from anything else. Growing the line box around it gives the whole strip a
   target without changing how it reads. */
@media (pointer: coarse) {
  .block__more,
  .hint__link,
  .section__note a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .hint__link { padding: 0 2px; }
}

.btnrow {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.btnrow--end { justify-content: flex-end; }
.btnrow--between { justify-content: space-between; }

.linkrow {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  min-height: 40px;
}

/* A tap target that is a link but looks like a row of the ledger. */
.tap {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: var(--tap);
  padding: 10px 12px;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--paper);
  color: var(--ink-2);
  font-size: 14px;
  font-weight: 600;
  text-align: center;
  touch-action: manipulation;
  transition: border-color var(--speed) linear, background-color var(--speed) linear;
}
.tap:hover { background: #F7F6F3; border-color: #A9A69E; text-decoration: none; }
.tap .ic { width: 17px; height: 17px; color: var(--steel); }

/* 9  Toasts, empty states, misc -------------------------------------------- */
.toasts {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(var(--tabbar-h) + var(--safe-b) + 12px);
  z-index: 70;
  width: min(520px, calc(100vw - 24px));
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}
.toasts--inline {
  position: static;
  transform: none;
  width: auto;
  margin: 0 0 16px;
  flex-direction: column;
}
.toasts--inline .toast { animation: none; pointer-events: auto; }

.toast {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 11px 13px;
  border-radius: var(--r);
  background: var(--graphite);
  color: #F2F3F2;
  font-size: 13.5px;
  line-height: 1.45;
  box-shadow: 0 3px 10px rgba(28, 32, 36, .28);
  animation: toast-in 220ms cubic-bezier(.2, .8, .3, 1);
  pointer-events: auto;
}
.toast p { margin: 0; max-width: none; }
.toast--error p { color: #FFFFFF; overflow-wrap: anywhere; }
.toast .ic { width: 17px; height: 17px; margin-top: 1px; }
.toast--success .ic { color: #6FCF97; }
.toast--error   { background: #7E1A15; }
.toast--error .ic { color: #FFC9C5; }
.toast--notice  { background: #3A4450; }
.toast.is-leaving { animation: toast-out 180ms linear forwards; }

.empty {
  padding: 30px 18px 34px;
  text-align: center;
}
.empty__mark {
  width: 40px;
  height: 40px;
  margin: 0 auto 12px;
  display: grid;
  place-items: center;
  border: 1px solid var(--rule-2);
  border-radius: var(--r);
  color: var(--steel-2);
}
.empty__mark .ic { width: 20px; height: 20px; }
.empty p { margin: 0 auto; max-width: 34ch; color: var(--steel); font-size: 14px; }
.empty .btn { margin-top: 14px; }
.empty--tight { padding: 22px 16px 26px; }

.note {
  display: flex;
  gap: 9px;
  padding: 11px 12px;
  border-left: 3px solid var(--rule-2);
  background: #FAFAF8;
  color: var(--ink-2);
  font-size: 13.5px;
  line-height: 1.5;
  border-radius: 0 var(--r) var(--r) 0;
}
.note .ic { width: 17px; height: 17px; color: var(--steel); flex: 0 0 auto; margin-top: 1px; }
.note p { margin: 0; }

.definition {
  display: grid;
  grid-template-columns: minmax(120px, 34%) 1fr;
  gap: 0;
  font-size: 14px;
}
.definition dt {
  padding: 9px 0;
  border-bottom: 1px solid var(--rule);
  color: var(--steel);
  font-size: 13px;
}
.definition dd {
  margin: 0;
  padding: 9px 0;
  border-bottom: 1px solid var(--rule);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.definition dd:last-child, .definition dt:last-child { border-bottom: 0; }

.stack   { display: flex; flex-direction: column; gap: 18px; }
.stack-s { display: flex; flex-direction: column; gap: 9px; }
.inline  { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.inline-end { display: flex; align-items: center; gap: 9px; justify-content: space-between; flex-wrap: wrap; }
.grow    { flex: 1 1 auto; min-width: 0; }
.right   { text-align: right; }
.nowrap  { white-space: nowrap; }
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.hide    { display: none !important; }

.searchbar {
  display: flex;
  gap: 8px;
  margin: 0 0 12px;
}
.searchbar .inp { flex: 1 1 auto; }
.searchbar .btn { flex: 0 0 auto; }

.filters {
  padding: 2px 0 0;
  margin-bottom: 14px;
}
.filters .field { margin-bottom: 10px; }

.skeleton {
  background: linear-gradient(90deg, #EDEBE5 25%, #F5F4F1 50%, #EDEBE5 75%);
  background-size: 300% 100%;
  animation: shimmer 1.15s linear infinite;
  border-radius: var(--r-sm);
  height: 12px;
}
.skeleton-row {
  padding: 13px 12px;
  border-bottom: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.spinner {
  width: 18px;
  height: 18px;
  border: 2px solid var(--rule-2);
  border-top-color: var(--hazard);
  border-radius: 50%;
  animation: spin 700ms linear infinite;
  display: inline-block;
}
.is-busy { position: relative; pointer-events: none; }
.is-busy .btn__text { opacity: .5; }

/* The site cost ledger: one row per site, the hazard bar is each site's
   share of company spend. Replaces the usual row of stat cards. */
.costbar {
  position: relative;
  height: 3px;
  background: #EDEBE5;
  border-radius: 2px;
  overflow: hidden;
}
.costbar i { display: block; height: 100%; background: var(--hazard); border-radius: 2px; }

.share {
  display: block;
  font-size: 12px;
  color: var(--steel);
  font-variant-numeric: tabular-nums;
}

.print-head { display: none; }
.print-only { display: none; }

/* Pull-to-refresh tell. Sits under the app bar, only visible while dragging. */
.ptr {
  position: fixed;
  top: calc(var(--appbar-h) + var(--safe-t));
  left: 50%;
  z-index: 39;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  margin-left: -17px;
  border-radius: 50%;
  background: var(--paper);
  border: 1px solid var(--rule);
  opacity: 0;
  pointer-events: none;
  transform: translateY(-44px);
  transition: transform 160ms cubic-bezier(.2, .8, .3, 1), opacity 160ms linear;
}
.ptr__dot {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--steel-2);
  transition: background-color 120ms linear, transform 120ms linear;
}
.ptr.is-armed .ptr__dot { background: var(--hazard); transform: scale(1.25); }
.ptr.is-spinning .ptr__dot {
  background: transparent;
  border: 2px solid var(--rule-2);
  border-top-color: var(--hazard);
  width: 17px;
  height: 17px;
  animation: spin 700ms linear infinite;
}

/* A live "stock remaining" readout that sits inside a form. It stacks into
   labelled rows so the two figures -- now, and after this entry -- never blur
   into one another on a narrow phone. */
.readout {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  padding: 10px 12px;
  background: #F7F6F3;
  border: 1px solid var(--rule-2);
  border-radius: var(--r);
  font-size: 13.5px;
}
.readout__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex: 1 1 130px;
}
.readout__row + .readout__row { border-top: 1px solid var(--rule); padding-top: 7px; }
.readout__label { color: var(--steel); }
.readout .trow__bar { flex: 1 1 100%; max-width: 100%; margin: 0; }
.readout__value {
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.readout__value.neg { color: var(--out); }
.readout__value.pos { color: var(--in); }
.readout__warn {
  flex: 1 1 100%;
  margin: 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--out);
}
.readout.is-low { border-color: #E9C6B1; background: #FDF6F1; }
.readout.is-low .readout__value { color: var(--hazard); }
.readout.is-low .trow__bar i { background: var(--hazard); }
.readout.is-over { border-color: #E0A79C; background: #FCF1EF; }
.readout.is-over .trow__bar i { background: var(--out); }

/* --- cost ledgers -------------------------------------------------------- */
/* A material line and a labour line share one shape: the words on the left, the
   multiplication in the middle, the money hard right. Same grid on both, so
   the eye learns it once. */
.filters__row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px;
}
.filters__row .field { flex: 1 1 150px; margin-bottom: 0; }
.filters__row .field .sel, .filters__row .field .inp { min-width: 0; }
.filters__row > .btn { flex: 0 0 auto; }

.costs {
  display: flex;
  flex-wrap: wrap;
  border-top: 2px solid var(--ink);
  border-bottom: 1px solid var(--rule);
  margin-bottom: 14px;
}
.costs__cell {
  flex: 1 1 130px;
  padding: 10px 12px 11px;
  border-left: 1px solid var(--rule);
  min-width: 0;
}
.costs__cell:first-child { border-left: 0; }
.costs__label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--steel);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.costs__value {
  display: block;
  margin-top: 3px;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.costs__cell--strong .costs__value { color: var(--hazard); }

.cline {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: 'name total' 'math total' 'sub sub';
  gap: 2px 12px;
  padding: 12px;
  border-bottom: 1px solid var(--rule);
}
.cline:last-child { border-bottom: 0; }
.cline__name {
  grid-area: name;
  font-weight: 600;
  font-size: 15px;
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  min-width: 0;
}
.cline__math {
  grid-area: math;
  font-family: var(--mono);
  font-size: 12.5px;
  color: var(--steel);
  font-variant-numeric: tabular-nums;
}
.cline__total {
  grid-area: total;
  align-self: center;
  font-size: 21px;
  font-weight: 600;
  letter-spacing: -0.02em;
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.cline__total::after,
.costs__value::after {
  content: ' ' attr(data-currency);
  font-size: 11px;
  font-weight: 600;
  color: var(--steel-2);
}
/* A count of lines, days or sites is not money, so it carries no currency. */
.costs__value[data-plain]::after {
  content: none;
}
.cline__sub {
  grid-area: sub;
  font-size: 12px;
  color: var(--steel);
  margin-top: 3px;
}
.cline.voided .cline__name,
.cline.voided .cline__total { color: var(--steel-2); }
.cline.voided .cline__total { text-decoration: line-through; }

/* --- sign in ------------------------------------------------------------- */
/* Not a card on grey. A painted steel panel with the company on it, and the
   form in the working half. On a phone the panel is just the header. */
.signin { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }

.signin__panel {
  background: var(--graphite);
  color: #B9C1C8;
  padding: calc(20px + var(--safe-t)) 20px 22px;
  padding-left: calc(20px + var(--safe-l));
  padding-right: calc(20px + var(--safe-r));
}

.signin__id .brandmark { margin-bottom: 12px; }
.signin__id h1 {
  color: #F5F6F6;
  font-size: 22px;
  letter-spacing: -0.022em;
  margin: 0;
}
.signin__co {
  margin: 3px 0 0;
  font-size: 13.5px;
  color: #9BA4AC;
}
.signin__what {
  margin: 12px 0 0;
  max-width: 34ch;
  font-size: 13px;
  line-height: 1.5;
  color: #79838B;
}

.signin__facts { display: flex; gap: 20px; margin: 18px 0 0; }
.signin__facts div { margin: 0; }
.signin__facts dt { font-size: 10.5px; color: #6E7880; }
.signin__facts dd {
  margin: 1px 0 0;
  font-size: 13px;
  color: #D3D8DC;
  font-variant-numeric: tabular-nums;
}

.signin__form {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 26px 20px calc(26px + var(--safe-b));
  padding-left: calc(20px + var(--safe-l));
  padding-right: calc(20px + var(--safe-r));
}
.signin__box { width: 100%; max-width: 380px; margin: 0 auto; }
.signin__box h2 { font-size: 19px; margin-bottom: 16px; }

/* The password row. The input keeps the full width of the column and the Show
   button sits inside its right edge, so revealing the password does not shift
   the layout the reader is already looking at. */
.passfield { position: relative; }
.passfield .inp { padding-right: 68px; }
.passfield__toggle {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  min-height: 36px;
  padding: 0 10px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--steel);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  cursor: pointer;
  touch-action: manipulation;
  transition: color var(--speed) linear, background-color var(--speed) linear;
}
.passfield__toggle:hover { color: var(--graphite); background: #F0EEE9; }
.passfield__toggle[aria-pressed="true"] { color: var(--hazard); }
.passfield__toggle:focus-visible { outline: 2px solid var(--hazard); outline-offset: 1px; }
.signin__foot {
  max-width: 380px;
  margin: 26px auto 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--steel-2);
  text-align: center;
}

@media (min-width: 860px) {
  .signin { flex-direction: row; }
  .signin__panel {
    width: 42%;
    max-width: 480px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 40px;
  }
  .signin__id h1 { font-size: 30px; }
  .signin__what { font-size: 14px; max-width: 30ch; }
  .signin__form { padding: 40px; }
  .signin__box { max-width: 400px; }
  .signin__box h2 { font-size: 22px; }
}

/* 10  Responsive ----------------------------------------------------------- */@media (min-width: 760px) {
  .hide-desk { display: none !important; }
  .only-desk { display: revert !important; }
}
@media (max-width: 759px) {
  .hide-phone { display: none !important; }
  .tablewrap { border-radius: 0; border-left: 0; border-right: 0; }
}

@media (min-width: 760px) {
  .only-phone { display: none !important; }

  :root { --tabbar-h: 0px; }

  .main {
    padding-top: calc(var(--appbar-h) + var(--safe-t) + 20px);
    padding-bottom: 56px;
    margin-left: var(--rail-w);
  }

  .tabbar { display: none; }
  .fab { display: none; }
  .toasts { bottom: 20px; left: auto; right: 20px; transform: none; }

  .formbar { bottom: 0; }

  /* Sidebar appears. Icon-only rail first, full sidebar from 1024. */
  .sidebar {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: var(--rail-w);
    z-index: 30;
    background: var(--graphite);
    color: #B9C1C8;
    padding-top: var(--safe-t);
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .sidebar__brand {
    display: grid;
    place-items: center;
    height: var(--appbar-h);
    flex: 0 0 auto;
    border-bottom: 1px solid #2C3238;
  }
  .sidebar__mark {
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    background: var(--hazard);
    color: #fff;
    border-radius: var(--r-sm);
    font-size: 15px;
    font-weight: 700;
  }
  .sidebar__brandtext { display: none; }

  .sidebar__list { list-style: none; margin: 0; padding: 8px 0; }
  .sidebar__group { display: none; }

  .sidebar__link {
    display: flex;
    align-items: center;
    gap: 11px;
    height: 42px;
    margin: 1px 8px;
    padding: 0 9px;
    border-radius: var(--r);
    color: #B9C1C8;
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
    transition: background-color var(--speed) linear, color var(--speed) linear;
  }
  .sidebar__link span { display: none; }
  .sidebar__link .ic { width: 21px; height: 21px; }
  .sidebar__link:hover { background: #262C32; color: #fff; text-decoration: none; }
  .sidebar__link.is-current {
    background: #2E353C;
    color: #fff;
    box-shadow: inset 2px 0 0 var(--hazard);
  }
  .sidebar__link.is-current .ic { color: var(--hazard); }

  .sidebar__foot { margin-top: auto; padding: 8px; border-top: 1px solid #2C3238; }
  .sidebar__user {
    display: grid;
    place-items: center;
    min-height: 44px;
  }
  .sidebar__usernav { display: none; }
  .sidebar__avatar {
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    background: #333B43;
    color: #E4E8EA;
    border-radius: var(--r-sm);
    font-size: 13px;
    font-weight: 600;
  }
  .sidebar__logout {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 40px;
    margin-top: 4px;
    border-radius: var(--r);
    color: #98A1A9;
    transition: background-color var(--speed) linear, color var(--speed) linear;
  }
  .sidebar__logout span { display: none; }
  .sidebar__logout:hover { background: #262C32; color: #fff; text-decoration: none; }

  .appbar { left: var(--rail-w); }
}

@media (min-width: 1024px) {
  .main { margin-left: var(--side-w); }
  .appbar { left: var(--side-w); }

  .sidebar { width: var(--side-w); }
  .sidebar__brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 16px;
    justify-content: flex-start;
  }
  .sidebar__brandtext { display: flex; flex-direction: column; min-width: 0; }
  .sidebar__brandtext strong { color: #F2F3F2; font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
  .sidebar__brandtext span {
    color: #79838B;
    font-size: 10.5px;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .sidebar__group {
    display: block;
    padding: 14px 16px 5px;
    font-size: 10.5px;
    font-weight: 600;
    color: #6E7880;
    letter-spacing: .04em;
  }
  .sidebar__link { margin: 1px 8px; padding: 0 9px; }
  .sidebar__link span { display: block; overflow: hidden; text-overflow: ellipsis; }

  .sidebar__user {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 8px;
    border-radius: var(--r);
  }
  .sidebar__user:hover { background: #262C32; text-decoration: none; }
  .sidebar__usernav { display: flex; flex-direction: column; min-width: 0; }
  .sidebar__usernav strong {
    color: #E4E8EA;
    font-size: 13.5px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .sidebar__usernav span { color: #79838B; font-size: 11.5px; }
  .sidebar__logout { justify-content: flex-start; gap: 11px; padding: 0 9px; }
  .sidebar__logout span { display: block; }
}

@media (min-width: 1024px) {
  .appbar { padding-left: 20px; padding-right: 20px; }
  .appbar__title { font-size: 19px; }
}

/* 11  Motion --------------------------------------------------------------- */
@keyframes fade { from { opacity: 0 } to { opacity: 1 } }
@keyframes sheet-up { from { transform: translateY(18px); opacity: .4 } to { transform: none; opacity: 1 } }
@keyframes toast-in { from { transform: translateY(10px); opacity: 0 } to { transform: none; opacity: 1 } }
@keyframes toast-out { to { transform: translateY(6px); opacity: 0 } }
@keyframes shimmer { from { background-position: 150% 0 } to { background-position: -150% 0 } }
@keyframes spin { to { transform: rotate(360deg) } }

/* The one orchestrated page-load moment: the balance figures count up from
   zero, once, so the eye lands on the number that matters. */
@keyframes tally-up { from { opacity: .25 } to { opacity: 1 } }
.counting { animation: tally-up 560ms cubic-bezier(.2, .8, .25, 1) both; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* Print is handled in print.css, which the app only loads on a report page. */

/* ---------------------------------------------------------- deep links ----
   reports.php sets jump--<section> on <body> when another screen links into a
   particular block of it. The offset clears the sticky header so the heading
   underneath is not hidden on arrival.

   The anchors are set in the markup, so this only has to avoid landing on a
   heading that is already at the very top. A phone, where there is less to
   scroll, is left alone rather than nudged for no reason. */
@media (prefers-reduced-motion: no-preference) {
  .jump--stock    { scroll-behavior: smooth; }
  .jump--stock #stock,
  .jump--movements #movements,
  .jump--sites #sites,
  .jump--machines #machines {
    scroll-margin-top: calc(var(--topbar-h, 56px) + 8px);
  }
}
@media (min-width: 900px) {
  .jump--stock #stock,
  .jump--movements #movements,
  .jump--sites #sites,
  .jump--machines #machines {
    scroll-margin-top: 12px;
  }
}
