:root {
  --paper: #f6f5f1;
  --surface: #ffffff;
  --ink: #1b1c1a;
  --muted: #6c6e69;
  --faint: #9a9c96;
  --line: #e3e1d9;
  --line-strong: #cfcdc3;
  --accent: #0f6e56;
  --accent-soft: #e3f1ec;
  --danger: #c2261d;
  --danger-soft: #fdeceb;
  --danger-line: #f3b9b4;
  --warn: #b26a00;
  --warn-soft: #fff4e0;
  --warn-line: #f0cf95;
  --ok: #17794a;
  --ok-soft: #e6f5ec;
  --ok-line: #a9dcc0;
  --info: #1c5fa8;
  --info-soft: #e9f1fb;
  --info-line: #b3cdea;
  --shadow-sm: 0 1px 2px rgba(20,22,18,.05);
  --shadow-md: 0 2px 8px rgba(20,22,18,.07);
  --sidebar-bg: #1b1c1a;
  --subtle: #faf9f5;
  --radius: 8px;
  --mono: "SFMono-Regular", "JetBrains Mono", "DejaVu Sans Mono", ui-monospace,
          Menlo, Consolas, monospace;
  --sans: -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

[data-theme="dark"] {
  --paper: #15161b;
  --surface: #1e2027;
  --ink: #e8e8e4;
  --muted: #a9aba5;
  --faint: #7e807a;
  --line: #2c2e36;
  --line-strong: #3b3e48;
  --accent: #3aa688;
  --accent-soft: #173a30;
  --danger: #ff8a80;
  --danger-soft: #3d2020;
  --danger-line: #5d2f2c;
  --warn: #e8b055;
  --warn-soft: #3a2f18;
  --warn-line: #57431f;
  --ok: #6fd39b;
  --ok-soft: #16301f;
  --ok-line: #24503a;
  --info: #7fb2ee;
  --info-soft: #17273a;
  --info-line: #274460;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.3);
  --shadow-md: 0 2px 8px rgba(0,0,0,.35);
  --sidebar-bg: #0f1013;
  --subtle: #24262e;
}

* { box-sizing: border-box; }

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

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

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
.sidebar :focus-visible { outline-color: var(--accent-soft); }

.mono, .num { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* ---- layout ---- */
.shell { display: flex; min-height: 100vh; }

.sidebar {
  width: 232px;
  background: var(--sidebar-bg);
  color: #e9e8e2;
  padding: 22px 0 0;
  position: sticky;
  top: 0;
  height: 100vh;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
}
.brand {
  padding: 0 18px 18px;
  border-bottom: 1px solid rgba(255,255,255,.1);
  margin-bottom: 14px;
  flex-shrink: 0;
}
.brand-row { display: flex; align-items: center; gap: 11px; }
.brand-mark { display: block; flex-shrink: 0; }
.brand .logo {
  font-size: 16px;
  font-weight: 600;
  color: #fff;
  line-height: 1.1;
}
.brand .name {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--faint);
  margin-top: 3px;
}
.nav {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}
.nav { scrollbar-width: auto; scrollbar-color: rgba(255,255,255,.3) transparent; }
.nav::-webkit-scrollbar { width: 14px; }
.nav::-webkit-scrollbar-track { background: rgba(0,0,0,.2); }
.nav::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,.3);
  border-radius: 7px;
  border: 3px solid transparent;
  background-clip: padding-box;
}
.nav::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.5); background-clip: padding-box; }
.nav a {
  display: block;
  padding: 9px 22px;
  color: #c8c8c2;
  font-size: 14px;
  border-left: 3px solid transparent;
}
.nav a:hover { background: rgba(255,255,255,.05); text-decoration: none; color: #fff; }
.nav a.active {
  color: #fff;
  border-left-color: var(--accent);
  background: rgba(127,211,184,.08);
}
.nav .group-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: none;
  border: 0;
  margin-top: 6px;
  padding: 14px 22px 6px;
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-align: left;
  color: var(--faint);
  cursor: pointer;
}
.nav .group-label:hover { color: #c8c8c2; }
.nav .chev {
  width: 0; height: 0;
  margin-left: 8px;
  border-left: 4px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform .15s ease;
}
.nav-group:not(.collapsed) .chev { transform: rotate(90deg); }
.nav-group.collapsed .group-items { display: none; }
.sidebar .foot {
  flex-shrink: 0;
  padding: 18px 22px;
  border-top: 1px solid rgba(255,255,255,.08);
  font-size: 12px;
  color: var(--faint);
}
.sidebar .foot a { color: #c8c8c2; }

.main { flex: 1; min-width: 0; }
.topbar {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  padding: 14px 30px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.topbar h1 { font-size: 19px; font-weight: 600; margin: 0 auto 0 0; }
.topbar-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.theme-toggle {
  background: none;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  cursor: pointer;
  width: 36px; height: 36px;
  font-size: 16px; line-height: 1;
  color: var(--ink);
  flex-shrink: 0;
}
.theme-toggle:hover { background: var(--subtle); }
.lang-select { width: auto; max-width: 130px; padding: 7px 9px; font-size: 13px; flex-shrink: 0; }
.content { padding: 26px 30px 60px; max-width: 1180px; }

/* hamburger (mobile only) */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 38px; height: 38px;
  padding: 8px;
  margin-right: 6px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
  cursor: pointer;
  flex-shrink: 0;
}
.nav-toggle span { display: block; height: 2px; background: var(--ink); border-radius: 2px; }
.scrim { display: none; }

/* keyboard skip link */
.skip-link {
  position: absolute; left: 8px; top: -60px;
  background: var(--accent); color: #fff;
  padding: 8px 14px; border-radius: var(--radius);
  z-index: 100; transition: top .15s;
}
.skip-link:focus { top: 8px; text-decoration: none; }

/* ---- buttons ---- */
.btn {
  display: inline-block;
  font-family: var(--sans);
  font-size: 14px;
  padding: 8px 15px;
  border-radius: var(--radius);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  transition: background .12s;
}
.btn:hover { background: var(--subtle); text-decoration: none; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.primary:hover { background: #0c5a47; }
.btn.danger { color: var(--danger); border-color: #e4c3c3; }
.btn.danger:hover { background: var(--danger-soft); }
.btn.sm { padding: 5px 10px; font-size: 13px; }

/* ---- cards / metrics ---- */
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 14px; margin-bottom: 26px; }
.metric {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 18px;
  box-shadow: var(--shadow-sm);
  position: relative;
  overflow: hidden;
}
/* a 3px bar across the top says at a glance whether this number is fine */
.metric.is-ok::before, .metric.is-late::before,
.metric.is-soon::before, .metric.is-todo::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
}
.metric.is-ok::before   { background: var(--ok); }
.metric.is-late::before { background: var(--danger); }
.metric.is-soon::before { background: var(--warn); }
.metric.is-todo::before { background: var(--info); }
.metric.is-ok .value    { color: var(--ok); }
.metric.is-late .value  { color: var(--danger); }
.metric.is-soon .value  { color: var(--warn); }
.metric .label { font-size: 12px; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.metric .value { font-family: var(--mono); font-size: 25px; margin-top: 6px; font-variant-numeric: tabular-nums; }
.metric.alert .value { color: var(--danger); }
.metric.warn .value { color: var(--warn); }

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin-bottom: 22px;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.panel > h2 {
  font-size: 14px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
  padding: 13px 18px;
  border-bottom: 1px solid var(--line);
}

/* ---- tables ---- */
table.grid { width: 100%; border-collapse: collapse; font-size: 14px; }
table.grid th {
  text-align: left;
  font-size: 11px;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--subtle);
}
table.grid td { padding: 10px 14px; border-bottom: 1px solid var(--line); }
table.grid tr:last-child td { border-bottom: none; }
table.grid tr:hover td { background: var(--subtle); }
td.num, th.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
.partno { font-family: var(--mono); font-weight: 500; }

/* ---- pills ---- */
.pill {
  display: inline-block;
  font-size: 12px;
  padding: 2px 9px;
  border-radius: 20px;
  background: var(--subtle);
  color: var(--muted);
  font-family: var(--sans);
}
.pill.in { background: var(--ok-soft); color: var(--ok); border:1px solid var(--ok-line); }
.pill.low { background: var(--danger-soft); color: var(--danger); border:1px solid var(--danger-line); }
.pill.soon { background: var(--warn-soft); color: var(--warn); border:1px solid var(--warn-line); }
.pill.raw { background: #eef0f4; color: #3a4256; }
.pill.manufactured { background: var(--accent-soft); color: var(--accent); }
.pill.in-mv { background: var(--ok-soft); color: var(--ok); }
.pill.out-mv { background: var(--danger-soft); color: var(--danger); }

/* ---- status badges -----------------------------------------------------
   One vocabulary for "where does this stand", used on every list so the
   colour means the same thing wherever you see it:
     ok      done, in stock, on time
     todo    waiting on you - planned, confirmed, to make
     late    overdue, short, expired, cancelled
     soon    expiring, nearly out, due shortly
     idle    nothing happening - draft, inactive
   The dot carries the meaning as well as the colour, so it still reads
   when printed in black and white or by someone colour-blind. */
.status {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600; line-height: 1.6;
  padding: 2px 10px 2px 8px; border-radius: 20px;
  border: 1px solid var(--line); background: var(--subtle); color: var(--muted);
  white-space: nowrap;
}
.status::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: currentColor; flex: none;
}
.status.ok   { background: var(--ok-soft);     color: var(--ok);     border-color: var(--ok-line); }
.status.todo { background: var(--info-soft);   color: var(--info);   border-color: var(--info-line); }
.status.late { background: var(--danger-soft); color: var(--danger); border-color: var(--danger-line); }
.status.soon { background: var(--warn-soft);   color: var(--warn);   border-color: var(--warn-line); }
.status.idle { background: var(--subtle);      color: var(--faint);  border-color: var(--line); }

/* a whole row can carry the state, with a colour bar down its left edge */
table.grid tr.row-late  td:first-child { box-shadow: inset 3px 0 0 var(--danger); }
table.grid tr.row-soon  td:first-child { box-shadow: inset 3px 0 0 var(--warn); }
table.grid tr.row-ok    td:first-child { box-shadow: inset 3px 0 0 var(--ok); }
table.grid tr.row-todo  td:first-child { box-shadow: inset 3px 0 0 var(--info); }

/* numbers that are themselves the warning */
.num.is-late, .v-late { color: var(--danger); font-weight: 600; }
.num.is-soon, .v-soon { color: var(--warn);   font-weight: 600; }
.num.is-ok,   .v-ok   { color: var(--ok);     font-weight: 600; }

/* ---- forms ---- */
form.stack { max-width: 640px; }
.field { margin-bottom: 16px; }
.field label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 5px; }
.field .hint { font-size: 12px; color: var(--muted); margin-top: 4px; }
/* search, email and tel were missing here for a long time, so those fields fell
   back to the browser's own styling — a white box on every dark-mode page. The
   filter bar is a type=search, which put one on all forty list screens. */
input[type=text], input[type=password], input[type=number], input[type=date],
input[type=search], input[type=email], input[type=tel],
select, textarea {
  width: 100%;
  font-family: var(--sans);
  font-size: 15px;
  padding: 9px 11px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.form-actions { display: flex; gap: 10px; margin-top: 22px; }

/* ---- toolbar / search ---- */
.toolbar { display: flex; gap: 10px; align-items: center; margin-bottom: 18px; flex-wrap: wrap; }
.toolbar .spacer { flex: 1; }
/* Controls in a filter bar size to their content. Without the date here, a bar
   with a From/To range broke into four stacked rows on any narrow window. */
.toolbar input[type=text], .toolbar input[type=search],
.toolbar input[type=date], .toolbar input[type=number],
.toolbar select { width: auto; }

/* ---- flash ---- */
.flash { padding: 11px 16px; border-radius: var(--radius); margin-bottom: 16px; font-size: 14px; }
.flash.success { background: var(--ok-soft); color: var(--ok); }
.flash.error { background: var(--danger-soft); color: var(--danger); }
.flash.info, .flash.warning { background: var(--accent-soft); color: var(--accent-strong, var(--accent)); }

.empty { color: var(--muted); padding: 24px 18px; text-align: center; font-size: 14px; }

/* ---- login ---- */
.login-wrap { display: flex; min-height: 100vh; align-items: center; justify-content: center; }
.login-card { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 34px 32px; width: 360px; }
.login-card .logo { font-family: var(--mono); font-size: 13px; letter-spacing: .12em; text-transform: uppercase; color: var(--accent); }
.login-brand { display: flex; align-items: center; gap: 11px; }
.login-card .brand-mark { display: block; }
.login-card h1 { font-size: 21px; margin: 8px 0 22px; }

/* ---- responsive: tablet & mobile ---- */
@media (max-width: 1100px) {
  .sidebar { width: 204px; }
}
@media (max-width: 840px) {
  .nav-toggle { display: flex; }
  .sidebar {
    position: fixed; top: 0; left: 0;
    width: 264px; height: 100vh;
    transform: translateX(-100%);
    transition: transform .22s ease;
    z-index: 60;
    box-shadow: 2px 0 16px rgba(0,0,0,.25);
  }
  .shell.nav-open .sidebar { transform: translateX(0); }
  .scrim {
    display: block; position: fixed; inset: 0;
    background: rgba(0,0,0,.45); z-index: 50;
  }
  .scrim[hidden] { display: none; }
  .main { width: 100%; min-width: 0; }
  .topbar { padding: 12px 16px; }
  .topbar h1 { font-size: 17px; }
  .content { padding: 18px 16px 50px; max-width: none; }
  .row2 { grid-template-columns: 1fr; }
  /* let wide data tables scroll horizontally inside their panel instead of breaking the layout */
  .panel { overflow-x: auto; }
  table.grid th, table.grid td { white-space: nowrap; }
  /* bigger touch targets */
  .nav a { padding: 12px 22px; }
  .btn { padding: 10px 15px; }
  .btn.sm { padding: 7px 11px; }
}

/* ---- Leads: pipeline board + timeline ------------------------------------ */
.muted { color: var(--muted); }
.kanban {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(215px, 1fr);
  gap: 12px; overflow-x: auto; padding-bottom: 8px; align-items: start;
}
.kanban-col {
  background: var(--subtle); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px;
}
.kanban-head {
  font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); font-weight: 600; margin: 2px 4px 10px;
  display: flex; align-items: center; gap: 8px;
}
.kanban-card {
  display: block; background: var(--surface); border: 1px solid var(--line);
  border-radius: 8px; padding: 10px 12px; margin-bottom: 8px;
  color: inherit; text-decoration: none;
}
.kanban-card:hover { border-color: var(--accent); text-decoration: none; }
.kc-name { font-weight: 600; font-size: 14px; }
.kc-product { font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.kc-foot { display: flex; align-items: center; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.kc-action { font-size: 12px; color: var(--muted); }
.kanban-empty { color: var(--muted); text-align: center; padding: 14px 0; font-size: 13px; }
.tl-item { border-top: 1px solid var(--line); padding: 10px 0; }
.tl-item:first-of-type { border-top: 0; }
.tl-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tl-detail summary { cursor: pointer; font-size: 12.5px; color: var(--muted); margin-top: 6px; }

/* ---- dashboard: what needs attention -----------------------------------
   Big, clickable, colour-coded counts that open the list behind them. A
   zero is kept deliberately quiet so the eye lands only on what is wrong. */
.attention-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: 12px;
}
.att {
  display: block;
  padding: 16px 18px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  text-decoration: none;
  color: var(--ink);
  box-shadow: var(--shadow-sm);
  border-left-width: 4px;
  transition: transform .08s ease, box-shadow .12s ease;
}
.att:hover { transform: translateY(-1px); box-shadow: var(--shadow-md); }
.att-n { display: block; font-family: var(--mono); font-size: 32px; line-height: 1.05;
         font-variant-numeric: tabular-nums; }
.att-l { display: block; margin-top: 6px; font-size: 14px; font-weight: 600; }
.att-h { display: block; margin-top: 2px; font-size: 12px; color: var(--muted); }

.att-late { border-left-color: var(--danger); background: var(--danger-soft); }
.att-late .att-n, .att-late .att-l { color: var(--danger); }
.att-soon { border-left-color: var(--warn); background: var(--warn-soft); }
.att-soon .att-n, .att-soon .att-l { color: var(--warn); }
.att-todo { border-left-color: var(--info); background: var(--info-soft); }
.att-todo .att-n, .att-todo .att-l { color: var(--info); }
/* nothing to do here: stay out of the way */
.att-zero { border-left-color: var(--line); }
.att-zero .att-n { color: var(--faint); }
.att-zero .att-l { color: var(--muted); font-weight: 500; }

.worklist { display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); gap: 16px; }
.worklist .panel { margin-bottom: 0; }
.worklist table.grid { font-size: 13px; }
.worklist table.grid td { padding: 8px 12px; }

/* ---- phones: below the tablet breakpoint -------------------------------
   840px already gives the drawer and scrolling tables. This is the narrow
   end, where the factory floor actually is. */
@media (max-width: 560px) {
  /* dvh, not vh: mobile browsers count the address bar in vh and the drawer
     ends up taller than the screen, so its bottom items can't be reached */
  .sidebar { height: 100dvh; }

  .content { padding: 14px 14px 48px; }

  /* The heading shared one row with the language picker, the theme button and
     the page actions, so a title of more than one word was squeezed into three
     wrapped lines. Giving it the rest of row one pushes the controls to row
     two, where there is room for them. 46px is the menu button plus its gap. */
  .topbar { flex-wrap: wrap; row-gap: 10px; }
  .topbar h1 { font-size: 16px; flex: 1 1 calc(100% - 46px); min-width: 0; margin: 0; }
  .topbar-actions { flex: 1 1 auto; }

  /* two across reads better than four squeezed or one wasteful column */
  .metrics { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .metric { padding: 12px 13px; }
  .metric .value { font-size: 20px; }
  .metric .label { font-size: 10px; }
  .attention-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .att { padding: 13px 14px 11px; }
  .att-n { font-size: 25px; }
  .att-l { font-size: 13px; }
  .worklist { grid-template-columns: 1fr; }

  /* a filter bar of inline controls becomes an unusable row on a phone */
  .toolbar { flex-direction: column; align-items: stretch; }
  .toolbar > * { width: 100%; }
  .toolbar .spacer { display: none; }
  .toolbar input, .toolbar select, .toolbar .btn { min-height: 42px; }

  /* thumb-sized controls and full-width actions */
  .field input, .field select, .field textarea { min-height: 42px; font-size: 16px; }
  .form-actions { flex-direction: column; align-items: stretch; gap: 8px; }
  .form-actions .btn { width: 100%; text-align: center; padding: 12px 16px; }
  .form-actions > div[style*="flex:1"] { display: none; }

  h1 { font-size: 21px; }
  .panel > h2 { padding: 11px 14px; }
  table.grid th, table.grid td { padding: 9px 11px; }
}

/* 16px on inputs stops iOS zooming the whole page when one is focused */
@media (max-width: 840px) {
  input, select, textarea { font-size: 16px; }
}

/* ---- print -------------------------------------------------------------
   Any list or detail page should print as a clean A4 document: no
   navigation, no controls, nothing the reader cannot act on from paper.
   Status is carried by text and a border as well as colour, because most
   office printers are black and white. */
@media print {
  @page { size: A4; margin: 14mm 12mm; }

  html, body { background: #fff !important; color: #000 !important; }
  body { font-size: 10.5pt; }

  /* the whole application chrome goes */
  .sidebar, .scrim, .nav-toggle, .topbar, .toolbar, .form-actions,
  .btn, .export-wrap, .pagination, .flash, .hint.no-print,
  form.toolbar, .att, .attention-grid { display: none !important; }

  /* the page itself fills the sheet */
  .shell, .main, .content {
    display: block !important; width: auto !important; max-width: none !important;
    margin: 0 !important; padding: 0 !important; overflow: visible !important;
  }

  /* a printed title, since the topbar is gone */
  .content::before {
    content: attr(data-print-title);
    display: block; font-size: 15pt; font-weight: 700; margin-bottom: 4mm;
    padding-bottom: 2mm; border-bottom: 1pt solid #000;
  }

  .panel {
    border: 1pt solid #999 !important; box-shadow: none !important;
    break-inside: auto; margin-bottom: 5mm; overflow: visible !important;
  }
  .panel > h2 { background: #eee !important; color: #000 !important; border-bottom: 1pt solid #999; }

  table.grid { width: 100% !important; font-size: 9.5pt; }
  table.grid th {
    background: #eee !important; color: #000 !important;
    border-bottom: 1pt solid #000 !important;
  }
  table.grid td { border-bottom: .5pt solid #bbb !important; }
  /* a row should not be split across two sheets, and headers repeat */
  table.grid tr { break-inside: avoid; }
  thead { display: table-header-group; }
  table.grid th, table.grid td { white-space: normal !important; }

  /* colour may not survive the printer, so keep the shape and the word */
  .status, .pill {
    border: .75pt solid #666 !important; background: #fff !important;
    color: #000 !important; padding: 0 4pt;
  }
  .status::before { background: #000 !important; }
  table.grid tr.row-late td:first-child,
  table.grid tr.row-soon td:first-child,
  table.grid tr.row-ok td:first-child,
  table.grid tr.row-todo td:first-child { box-shadow: none !important; }
  tr.row-late td { font-weight: 600; }

  .metrics { display: flex !important; gap: 6mm; margin-bottom: 5mm; }
  .metric { border: none !important; box-shadow: none !important; padding: 0 !important; }
  .metric::before { display: none !important; }

  /* the row-selection column means nothing on paper. Both the header and the
     body cell are identified by holding a checkbox, so the column drops out
     whole and the rest stays aligned. */
  table.grid th:first-child:has(input[type="checkbox"]),
  table.grid td:first-child:has(input[type="checkbox"]) { display: none !important; }

  a { color: #000 !important; text-decoration: none !important; }
  canvas { max-width: 100% !important; }
}
