/* ============================================================================
   Creative Arts — Production Tracker
   Steel and paper. The materials of the shop: cool-cast sheet steel, the white
   of a printed Production Report, and one signal green — the colour a nesting
   program draws its cut paths in. Green appears only where the laser is running,
   so the single green button in this app is the one that starts the machine.
   ========================================================================== */

:root{
  color-scheme:light;

  /* steel ------------------------------------------------------------- */
  --paper:#FBFCFD;
  --surface:#FFFFFF;
  --steel-50:#F2F5F7;
  --steel-75:#EAEEF1;
  --steel-100:#E0E6EA;
  --steel-200:#CAD4DA;
  --steel-300:#AFBCC5;
  --steel-400:#8B9AA5;
  --steel-500:#6C7C88;
  --steel-600:#53626D;
  --steel-700:#3C4A54;
  --steel-800:#2A353D;
  --steel-900:#1A2229;
  --steel-950:#121920;

  --ink:var(--steel-900);
  --ink-2:var(--steel-600);
  /* NOT steel-400 (#8B9AA5, 2.89:1 on white). This is not a decorative grey:
     it carries every column header, tile label, panel note, page subtitle and
     phone-card label in the product. On a tablet beside a laser that has to be
     readable. #66757F is 4.76:1. steel-400 stays what it is, for hover borders
     and the Viewer avatar. */
  --ink-3:#66757F;
  --rule:var(--steel-100);
  --rule-firm:var(--steel-200);

  /* the one signal colour --------------------------------------------- */
  --laser:#00A05A;
  --laser-deep:#00814A;
  --laser-wash:#E4F4EC;

  /* the states, used on data only -------------------------------------- */
  --s-cut:#00A05A;
  --s-handling:#6C7C88;
  --s-bench:#B6C2CA;
  --s-setup:#6B4FA8;
  --s-idle:#C9761B;
  /* The state colours are chosen to read as bands and chips, where they sit on
     large blocks. As 15px TEXT on paper they are 3.4:1, under the 4.5:1 body
     text needs -- so text takes these two instead. Same hues, darker. */
  --s-idle-ink:#A45C08;
  --s-cut-ink:#00814A;
  --s-break:#3D7EA6;
  --alert:#C0392B;
  --alert-wash:#FBEDEB;
  --warn-wash:#FBF2E6;

  --sans:"IBM Plex Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,Menlo,monospace;

  --r-control:4px;
  --r-panel:6px;
  /* phone cards. Every other surface here is rounded; this token was being
     used before it existed, so border-radius resolved to 0 and the cards
     looked like spreadsheet rows. */
  --r-md:8px;
  --r-pill:999px;
  --lift:0 1px 2px rgba(26,34,41,.06), 0 8px 24px -6px rgba(26,34,41,.14);
  --lift-high:0 2px 6px rgba(26,34,41,.10), 0 24px 60px -12px rgba(26,34,41,.28);
  --t:140ms cubic-bezier(.22,.61,.36,1);
  /* the phone's bottom bar: 58px of bar, plus whatever the home indicator
     wants underneath it */
  --bar-h:58px;
  /* three dots in a row — the one glyph in the bar that is not a screen */
  --more-glyph:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="5" cy="12" r="1.9"/><circle cx="12" cy="12" r="1.9"/><circle cx="19" cy="12" r="1.9"/></svg>');
}

*{box-sizing:border-box}
[hidden]{display:none!important}
html,body{height:100%}
body{margin:0;background:var(--paper);color:var(--ink);
  font-family:var(--sans);font-size:15px;line-height:1.5;
  font-feature-settings:"cv05" 1;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
h1,h2,h3,h4{margin:0;font-weight:600;line-height:1.16;letter-spacing:-0.017em}
p{margin:0 0 1em}
a{color:var(--steel-800);text-underline-offset:2px;text-decoration-color:var(--steel-300)}
a:hover{text-decoration-color:var(--steel-600)}
button{font:inherit;color:inherit}
::selection{background:var(--laser-wash);color:var(--steel-900)}

/* durations, ids, programme names: tabular, so columns of time line up */
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums;letter-spacing:-0.01em}
.muted{color:var(--ink-3)}
.small{font-size:13px}
.tiny{font-size:12px}
.strong{font-weight:600}
.right{text-align:right}

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

/* ---------------------------------------------------------- avatars ----- */
.av{width:32px;height:32px;border-radius:var(--r-pill);display:grid;place-items:center;
  color:#fff;font-size:12px;font-weight:600;flex:none;letter-spacing:.01em;
  font-family:var(--mono)}
.av.r-Admin{background:var(--steel-800)}
.av.r-Supervisor{background:var(--s-break)}
.av.r-Designer{background:var(--s-setup)}
.av.r-Sales{background:var(--s-idle)}
.av.r-Operator{background:var(--laser-deep)}
.av.r-Viewer{background:var(--steel-400)}

/* ============================ sign in ==================================== */
#login{min-height:100vh;display:grid;grid-template-columns:minmax(320px,40%) 1fr}

.si-brand{background:var(--steel-50);color:var(--ink);padding:52px 48px 44px;
  border-right:1px solid var(--rule);
  display:grid;grid-template-rows:auto 1fr auto;gap:24px;position:relative;overflow:hidden}
/* A nest: parts laid out on a sheet, the defining picture of this trade, drawn the
   way a CAM screen draws one. It is the hero of this panel, not decoration behind it. */
.si-brand .nestwrap{display:grid;place-items:center;min-height:0}
.si-brand .nestwrap svg{width:100%;max-width:340px;height:auto;display:block}
.si-brand .nestwrap rect,.si-brand .nestwrap path,.si-brand .nestwrap circle{fill:none;
  stroke:var(--laser);stroke-width:1.4;opacity:.9;vector-effect:non-scaling-stroke}
.si-brand .nestwrap .sheet{stroke:var(--steel-300);stroke-width:1.8;opacity:1;fill:var(--surface)}
.si-brand>div{position:relative;z-index:1}
.si-brand .co{font-size:13px;font-weight:500;color:var(--ink-3);letter-spacing:.01em}
.si-brand h1{font-size:clamp(30px,3.4vw,42px);margin:10px 0 16px;max-width:12ch;color:var(--ink);
  letter-spacing:-0.028em;line-height:1.04}
.si-brand p{color:var(--ink-2);font-size:17px;max-width:36ch;margin:0;line-height:1.55}
.si-facts{display:flex;gap:30px;flex-wrap:wrap;margin-top:40px}
.si-facts b{display:block;font-family:var(--mono);font-size:20px;font-weight:500;color:var(--ink);
  letter-spacing:-0.02em;line-height:1.1}
.si-facts span{font-size:13px;color:var(--ink-3)}

.si-main{display:flex;align-items:center;justify-content:center;padding:48px 36px;background:var(--surface)}
.si-inner{width:100%;max-width:430px}
.si-inner h2{font-size:20px;margin-bottom:8px}
.si-inner .hint{color:var(--ink-3);font-size:14px;margin-bottom:24px}

.people{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.person{display:flex;align-items:center;gap:11px;padding:11px 12px;cursor:pointer;
  background:var(--surface);border:1px solid var(--rule);border-radius:var(--r-panel);
  text-align:left;transition:border-color var(--t),background var(--t)}
.person:hover{border-color:var(--steel-400);background:var(--steel-50)}
.person .nm{font-weight:500;font-size:14px;line-height:1.2}
.person .rl{font-size:12px;color:var(--ink-3);margin-top:1px}


/* Five tiles in a two-column grid left the fifth — "Sheet handling", the one
   the design deliberately colour-codes as an answer — half-width with an empty
   cell beside it, and a hairline stopping dead in the middle of the row. */
@media (max-width:620px){
  .tiles .tile:last-child:nth-child(odd){grid-column:1/-1;border-right:0}
}

/* Every input reaches 16px on a touch screen. Below that iOS zooms the page
   the moment a field takes focus, and the operator is left panning a magnified
   form one-handed at the machine. Desktop keeps the denser 14px. */
@media (max-width:700px){
  input,select,textarea{font-size:16px;padding:9px 11px}
}

/* A duration and a phone number are single things: "61h 18m · 11 runs" split
   over two lines, and a number broke mid-dial-code. */
td.n, td .mono{white-space:nowrap}
tr.dim td{opacity:.52}
tr.dim.clickable:hover td{opacity:.72}
/* Sized to match the Username field directly above it. 57px under 33px was the
   single most unfinished-looking thing on the screen the shop floor meets most. */
.pinbox{width:100%;text-align:center;font-family:var(--mono);font-size:17px;
  letter-spacing:.34em;text-indent:.34em;padding:7px 12px}
.pinbox.wrong{border-color:var(--alert);animation:nudge .28s}
.dots{display:flex;gap:13px;justify-content:center;margin:8px 0 6px}
.dots i{width:11px;height:11px;border-radius:var(--r-pill);background:transparent;
  border:1.5px solid var(--steel-300);display:block;transition:all var(--t)}
.dots i.on{background:var(--steel-800);border-color:var(--steel-800)}
.dots.wrong i{border-color:var(--alert);background:transparent;animation:nudge .28s}
@keyframes nudge{0%,100%{transform:translateX(0)}30%{transform:translateX(-4px)}70%{transform:translateX(4px)}}

/* The keypad is for the tablet by the laser: an operator taps four digits with
   one hand, often wearing a glove. On anything with a mouse it is in the way,
   and worse, it made the screen look as though typing was not an option — so
   it only appears where a finger is the pointing device. The PIN field itself
   is a real input on every device: type it and press Enter. */
/* Settings: seven lists as hairline sections of one panel rather than seven
   panels of the same shape stacked down 2569px. */
.lists>.lsec + .lsec{border-top:1px solid var(--rule)}
.lsec{display:grid;grid-template-columns:200px 1fr;gap:22px;padding:16px 0}
.lsec:first-child{padding-top:2px}
.lsec:last-child{padding-bottom:2px}
.lsec-h h4{font-size:14px;font-weight:600;margin-bottom:4px}
.chips{display:flex;gap:7px;flex-wrap:wrap}
@media (max-width:700px){
  .lsec{grid-template-columns:1fr;gap:9px}
}

/* a master-list entry: tap to retire, tap again to bring back */
.chipbtn{font:inherit;font-size:13px;padding:5px 11px;border-radius:var(--r-pill);
  border:1px solid var(--rule-firm);background:var(--surface);color:var(--ink-2);cursor:pointer}
.chipbtn:hover{border-color:var(--steel-400);background:var(--steel-50)}
.chipbtn.off{background:transparent;color:var(--ink-3);border-style:dashed;
  text-decoration:line-through}
.chipbtn.off:hover{text-decoration:none;color:var(--ink-2)}

/* the "a new version is ready" bar, styled here rather than inline in the page
   so it follows the palette like everything else */
.swbar{position:fixed;left:0;right:0;bottom:0;z-index:998;background:var(--steel-900);
  color:#fff;padding:12px 16px;display:flex;gap:12px;align-items:center;
  justify-content:center;flex-wrap:wrap;font-size:14px}
.swbar .btn.ghost{background:transparent;color:var(--steel-300);border-color:var(--steel-600)}

/* the search that appears once the operator has more than six jobs to pick from */
/* 16px exactly, off the scale on purpose: iOS zooms the whole page when a
   focused input is smaller than this, and an operator does not want the screen
   jumping as he searches for his nest. */
.opfind{width:100%;margin-bottom:8px;font-size:16px;padding:11px 12px}
/* Full width. It was 288px under 350px fields — the control an operator taps
   with a glove on was narrower than the inputs above it. */
.pinpad{display:none;grid-template-columns:repeat(3,1fr);gap:8px;margin:0 auto}
@media (pointer:coarse){ .pinpad{display:grid} .si-go{display:none} }
.si-go{margin-top:18px}
.key{height:56px;font-family:var(--mono);font-size:20px;font-weight:500;background:var(--surface);
  color:var(--ink);border:1px solid var(--rule-firm);border-radius:var(--r-control);cursor:pointer;
  font-variant-numeric:tabular-nums;transition:background var(--t),border-color var(--t)}
.key:hover{background:var(--steel-50);border-color:var(--steel-400)}
.key:active{background:var(--steel-100)}
.key.soft{font-family:var(--sans);font-size:14px;color:var(--ink-2)}
.key.go{background:var(--steel-900);border-color:var(--steel-900);color:#fff;
  font-family:var(--sans);font-size:14px;font-weight:500}
.key.go:hover{background:var(--steel-800)}
.key.go:disabled{opacity:.3;cursor:not-allowed}
.si-note{font-size:13px;color:var(--ink-3);text-align:center;margin-top:22px;line-height:1.5}
.si-err{color:var(--alert);font-size:13px;text-align:center;min-height:20px;margin-bottom:8px}

/* ============================ app shell ================================== */
/* The notch and the home bar. With viewport-fit=cover the page runs under
   both, so an installed app on an iPhone put its sign-out button behind the
   home indicator. env() is nought on every device without them. */
#shell{display:grid;grid-template-columns:232px 1fr;min-height:100vh;
  padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);
  padding-bottom:env(safe-area-inset-bottom)}

#side{background:var(--surface);border-right:1px solid var(--rule);display:flex;
  flex-direction:column;position:sticky;top:0;height:100vh;overflow-y:auto}
.brand{padding:20px 20px 16px;border-bottom:1px solid var(--rule);display:flex;gap:10px;align-items:center}
.brand .glyph{width:26px;height:26px;flex:none}
.brand b{display:block;font-size:14px;font-weight:600;letter-spacing:-0.01em;line-height:1.2}
.brand span{font-size:12px;color:var(--ink-3)}

.nav{padding:10px 10px 16px;flex:1}
.navmore{display:none}
.nav a{display:flex;align-items:center;gap:10px;padding:7px 10px;border-radius:var(--r-control);
  font-size:14px;text-decoration:none;color:var(--ink-2);font-weight:450;margin-bottom:1px;
  transition:background var(--t),color var(--t)}
.nav a svg{width:16px;height:16px;flex:none;stroke:currentColor;fill:none;
  stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;opacity:.72}
.nav a:hover{background:var(--steel-50);color:var(--ink)}
.nav a.on{background:var(--steel-900);color:#fff}
.nav a.on svg{opacity:1}
.nav .grp{font-size:12px;font-weight:500;color:var(--ink-3);padding:16px 10px 6px}
.nav .count{margin-left:auto;font-family:var(--mono);font-size:11px;font-weight:500;
  background:var(--alert);color:#fff;padding:1px 6px;border-radius:var(--r-pill)}
.nav a.on .count{background:rgba(255,255,255,.22)}

.whoami{border-top:1px solid var(--rule);padding:12px 14px;display:flex;gap:10px;align-items:center}
/* The version this device is running, at the foot of the sidebar. Quiet enough
   to ignore, there when somebody has to ask which copy a tablet is on. */
.ver { margin-top: 10px; font-family: var(--mono); font-size: 11px;
       color: var(--ink-3); letter-spacing: .02em; }
.ver:empty { display: none; }
.whoami .nm{font-size:13px;font-weight:500;line-height:1.25}
.whoami .rl{font-size:12px;color:var(--ink-3)}
.linkbtn{background:none;border:0;padding:0;font-size:13px;color:var(--ink-3);cursor:pointer;
  text-decoration:underline;text-underline-offset:2px}
.linkbtn:hover{color:var(--ink)}

#main{min-width:0;padding:26px 32px 72px}
.pagehead{display:flex;justify-content:space-between;align-items:flex-end;gap:20px;flex-wrap:wrap;
  margin:-26px -32px 26px;padding:26px 32px 22px;
  border-bottom:1px solid var(--rule);background:var(--surface)}
.pagehead h2{font-size:24px;letter-spacing:-0.022em}
.pagehead .sub{font-size:14px;color:var(--ink-3);margin-top:5px}

/* ============================ controls =================================== */
.btn{display:inline-flex;align-items:center;gap:7px;background:var(--steel-900);color:#fff;
  border:1px solid var(--steel-900);padding:7px 14px;font-size:14px;font-weight:500;
  border-radius:var(--r-control);cursor:pointer;transition:background var(--t),border-color var(--t)}
.btn:hover{background:var(--steel-800);border-color:var(--steel-800)}
.btn.ghost{background:transparent;color:var(--ink-2);border-color:var(--rule-firm)}
.btn.ghost:hover{background:var(--steel-50);color:var(--ink);border-color:var(--steel-400)}
/* the only green button in the office app: it starts the machine */
.btn.go{background:var(--laser);border-color:var(--laser)}
.btn.go:hover{background:var(--laser-deep);border-color:var(--laser-deep)}
.btn.stop{background:var(--alert);border-color:var(--alert)}
.btn:disabled{opacity:.4;cursor:not-allowed}
.btn.sm{padding:5px 11px;font-size:13px}

.toolbar{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:16px}
.toolbar .check{display:flex;align-items:center;gap:7px;font-size:13px;color:var(--ink-2);
  white-space:nowrap;cursor:pointer}
input,select,textarea{font:inherit;font-size:14px;padding:7px 10px;border:1px solid var(--rule-firm);
  background:var(--surface);border-radius:var(--r-control);color:var(--ink);max-width:100%;
  transition:border-color var(--t)}
input:hover,select:hover,textarea:hover{border-color:var(--steel-400)}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--steel-800);
  box-shadow:0 0 0 3px var(--steel-100)}
label{display:block;font-size:13px;font-weight:500;color:var(--ink-2);margin-bottom:4px}
.field{margin-bottom:16px}
.fieldrow{display:grid;grid-template-columns:repeat(auto-fit,minmax(168px,1fr));gap:14px}

.seg{display:inline-flex;border:1px solid var(--rule-firm);border-radius:var(--r-control);
  overflow:hidden;background:var(--surface)}
.seg button{background:transparent;border:0;padding:6px 13px;font-size:13px;cursor:pointer;
  min-height:32px;
  color:var(--ink-2);border-right:1px solid var(--rule);transition:background var(--t),color var(--t)}
.seg button:last-child{border-right:0}
.seg button:hover{background:var(--steel-50);color:var(--ink)}
.seg button.on{background:var(--steel-900);color:#fff}

/* ============================ surfaces =================================== */
/* The page ground and the panel ground are 1.03:1 apart, so the border IS the
   separation — and --rule is only 1.19:1 on white, which is why surfaces read
   flat. Firm on the perimeter, hairline inside: the system already had both
   tokens and was using one of them. */
.panel{background:var(--surface);border:1px solid var(--rule-firm);border-radius:var(--r-panel);
  margin-bottom:24px;overflow:hidden}
.panel>.ph{padding:14px 18px;border-bottom:1px solid var(--rule);display:flex;
  justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap}
.panel>.ph h3{font-size:15px;font-weight:600}
.panel>.ph .note{font-size:13px;color:var(--ink-3);margin-top:3px;max-width:72ch}
.panel>.pb{padding:18px}
.panel>.pb.flush{padding:0}

/* figures. No uppercase label: the number is the headline, the words support it. */
.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));border-color:var(--rule-firm);
  border:1px solid var(--rule);border-radius:var(--r-panel);background:var(--surface);
  margin-bottom:24px;overflow:hidden}
.tile{padding:16px 18px;border-right:1px solid var(--rule)}
.tile:last-child{border-right:0}
.tile .lab{font-size:13px;color:var(--ink-3);margin-bottom:8px;font-weight:450}
.tile .val.plain{font-family:var(--sans);letter-spacing:-0.02em;
  font-variant-numeric:tabular-nums}
.tile .val{font-family:var(--mono);font-size:24px;font-weight:500;letter-spacing:-0.035em;
  line-height:1.05;font-variant-numeric:tabular-nums}
.tile .sub{font-size:13px;color:var(--ink-3);margin-top:6px}
/* the mono face is for durations and counts; a tile whose value is words uses the text face */
.tile.text .val{font-family:var(--sans);font-size:20px;font-weight:500;letter-spacing:-0.022em}
.tile.hero .val{color:var(--laser-deep)}
.tile.warnv .val{color:var(--s-idle)}

.tablewrap{overflow-x:auto}
table{width:100%;border-collapse:collapse;font-size:14px}
/* No position:sticky here. .tablewrap is a scroll container with no height, so
   there is no scrollport for a header to stick against — it never once fired,
   and on a 3000px table the header was 874px above the viewport after two
   rows. Dead weight pretending to be a feature. */
th{text-align:left;font-weight:500;color:var(--ink-3);font-size:13px;padding:10px 12px;
  border-bottom:1px solid var(--rule-firm);white-space:nowrap;background:var(--surface)}
/* 12px, not 14px. Across ten columns that was 40px of padding, and the Gap
   column — the one the table exists for — was falling 159px off the right of a
   1200px laptop screen, inside a scroller with no scrollbar and no shadow. */
td{padding:10px 12px;border-bottom:1px solid var(--rule);vertical-align:middle}
/* A machine id is 31 characters of mono and was taking a quarter of the table
   to show something nobody reads in full. It truncates; the run detail has it. */
td.prog{max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* the trailing status cell was 119px wide to hold a pill or nothing at all */
td.tail,th.tail{width:1%;white-space:nowrap}
tbody tr:last-child td{border-bottom:0}
tbody tr.clickable{cursor:pointer;transition:background var(--t)}
/* the row is the control, so the focus ring goes round the row */
tbody tr.clickable:focus-visible{outline:2px solid var(--steel-800);outline-offset:-2px}
tbody tr.clickable:hover{background:var(--steel-50)}
td.n,th.n{text-align:right;font-variant-numeric:tabular-nums}
.empty{padding:40px 20px;text-align:center;color:var(--ink-3);font-size:14px}

/* ---- a table becomes a stack of cards on a phone -------------------------
   Every report here is a table, and on a phone every one of them put the
   number the owner came for off the right-hand edge: All runs showed Date,
   Operator and Operation, with Planned and Gap 586px away inside a scroller
   with no scrollbar and no shadow. Not hidden — invisible.

   So below 700px each row becomes a card, each cell prints the column name it
   came from, and the one figure the screen exists to show is the big number.
   The markup is identical either way: the header row is simply not displayed
   and the cells carry their own labels. */
@media (max-width:760px){
  .tablewrap{overflow-x:visible}
  table,tbody,tr,td{display:block;width:auto}
  thead{display:none}
  tbody tr{border:1px solid var(--rule-firm);border-radius:var(--r-md);
    padding:4px 0;margin-bottom:8px;background:var(--surface)}
  /* Inside a panel the card border sat 1px inside the panel's own, giving a
     visible doubled rule down both edges. Inside a panel the cards ARE the
     panel's contents, so they drop their own frame and use a rule between. */
  .panel>.pb.flush tbody tr{border-width:0 0 1px 0;border-radius:0;margin-bottom:0;
    padding:6px 0}
  .panel>.pb.flush tbody tr:last-child{border-bottom:0}
  tbody tr:last-child{margin-bottom:0}
  tbody tr.clickable:active{background:var(--steel-50)}
  td{display:flex;gap:14px;align-items:baseline;justify-content:space-between;
    padding:7px 14px;border-bottom:0;text-align:left}
  td[data-label]::before{content:attr(data-label);flex:0 0 auto;font-size:13px;
    color:var(--ink-3);white-space:nowrap}
  /* a cell with no column name is a chevron or a status pill: let it sit alone */
  td:not([data-label]){justify-content:flex-end;padding-top:0}
  td:empty{display:none}
  td.n{text-align:right}
  /* A machine id is the widest, busiest thing in the card and the least useful
     to read in full — it competed with the figure the card exists for. */
  td.prog{max-width:none}
  td.prog .mono{font-size:13px;color:var(--ink-3)}

  /* the figure this screen is for */
  td.hero{padding-top:11px;padding-bottom:11px;border-top:1px solid var(--rule);
    margin-top:4px;align-items:center}
  td.hero::before{font-size:13px;color:var(--ink-2);font-weight:500}
  td.hero>*,td.hero{font-size:20px;font-variant-numeric:tabular-nums}
  /* a status pill belongs to the figure above it, not floating on its own */
  td.tail{padding-top:0;padding-bottom:10px;justify-content:flex-end}
}

.pill{display:inline-block;padding:2px 9px;border-radius:var(--r-pill);font-size:13px;
  font-weight:500;border:1px solid transparent;white-space:nowrap}
.pill.open{background:var(--steel-50);color:var(--steel-600);border-color:var(--steel-200)}
.pill.prod{background:var(--warn-wash);color:#8A5406;border-color:#EBD9BE}
.pill.done{background:var(--laser-wash);color:var(--laser-deep);border-color:#BFE3D0}
.pill.cancel{background:var(--alert-wash);color:var(--alert);border-color:#EDCDC8}
.pill.grey{background:var(--steel-50);color:var(--ink-3);border-color:var(--rule-firm)}
.pill.alert{background:var(--alert-wash);color:var(--alert);border-color:#EDCDC8}

/* ============================ data ======================================= */
.sw{display:inline-block;width:9px;height:9px;border-radius:2px;margin-right:7px;vertical-align:baseline}
.sw.running{background:var(--s-cut)}
.sw.setup{background:var(--s-setup)}
.sw.idle{background:var(--s-idle)}
.sw.break{background:var(--s-break)}

.stack{display:flex;height:30px;border-radius:var(--r-control);overflow:hidden;background:var(--steel-75)}
.stack i{display:grid;place-items:center;font-size:12px;font-weight:500;color:#fff;
  font-style:normal;overflow:hidden;white-space:nowrap;min-width:0;
  box-shadow:inset -1px 0 0 rgba(255,255,255,.28)}
.stack i:last-child{box-shadow:none}
.legend{display:flex;gap:18px;flex-wrap:wrap;margin-top:13px;font-size:13px;color:var(--ink-2)}
.legend b{font-weight:500;color:var(--ink)}

.cols{display:flex;align-items:flex-end;gap:4px;height:168px;padding-top:6px}
.cols .c{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:flex-end;height:100%;
  border-radius:2px;overflow:hidden}
.cols .c i{display:block;font-style:normal;width:100%}
.cols .c .cap{font-family:var(--mono);font-size:11px;color:var(--ink-3);text-align:center;
  margin-top:7px;white-space:nowrap;overflow:hidden}

.hbar{display:flex;align-items:center;gap:14px;margin-bottom:8px}
.hbar .nm{width:150px;flex:none;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hbar .tr{flex:1;height:20px;background:var(--steel-75);border-radius:2px;overflow:hidden;display:flex}
.hbar .tr i{display:block;font-style:normal;height:100%}
.hbar .vl{width:94px;flex:none;text-align:right;font-family:var(--mono);font-size:13px;
  font-weight:500;font-variant-numeric:tabular-nums}

/* the shift timeline: the signature graphic of this product */
.tl{display:flex;height:34px;border-radius:var(--r-control);overflow:hidden;
  border:1px solid var(--rule-firm)}
.tl i{display:block;font-style:normal;height:100%;min-width:1px;
  box-shadow:inset -1px 0 0 rgba(255,255,255,.3)}
.tlmarks{display:flex;justify-content:space-between;font-family:var(--mono);font-size:12px;
  color:var(--ink-3);margin-top:6px}

/* ============================ the operator's screen ==================== */
.phonewrap{display:flex;justify-content:center;padding:8px 0 48px;min-width:0}
/* On a desktop the phone frame is a deliberate preview and it works. On an
   actual phone it is a picture of a phone drawn inside a phone: 358px wide with
   18px of inner padding, a 24px radius and a shadow, inside a 390px viewport
   that already has its own gutter — 68px, 17% of the screen, spent on frame
   that a gloved thumb would rather have as screen. */
@media (max-width:760px){
  .phonewrap{padding:0 0 32px}
  .phone{max-width:none;border:0;border-radius:0;box-shadow:none;padding:2px 0 8px}
  .phone .ptop{padding-bottom:10px}
}
.opgrid{display:grid;grid-template-columns:396px minmax(0,1fr);gap:30px;align-items:start;
  padding-bottom:48px}
.opgrid .phonewrap{padding:0;justify-content:flex-start}
.opside .panel{margin-bottom:16px}
/* minmax(0,1fr), not 1fr: a bare 1fr has an automatic minimum of the item's
   min-content, so the 396px panel held the column open at 416px and the whole
   page scrolled sideways on a phone. */
@media (max-width:920px){
  .opgrid{grid-template-columns:minmax(0,1fr)}
  .opgrid .phonewrap{justify-content:center;min-width:0}
}
.phone{width:100%;max-width:396px;background:var(--surface);color:var(--ink);
  border-radius:24px;border:1px solid var(--rule-firm);padding:20px 18px 24px;box-shadow:var(--lift)}
.phone .ptop{display:flex;justify-content:space-between;font-size:13px;color:var(--ink-3);
  padding-bottom:12px;border-bottom:1px solid var(--rule);margin-bottom:16px}
.phone .ptop .mono{font-size:13px}
.phone h3{font-size:20px;margin-bottom:4px;letter-spacing:-0.02em}
.phone .plead{font-size:13px;color:var(--ink-3);margin-bottom:16px;line-height:1.45}
.phone input,.phone select,.phone textarea{width:100%}
.phone input:focus,.phone textarea:focus{border-color:var(--laser);
  box-shadow:0 0 0 3px var(--laser-wash)}

.opt{display:block;width:100%;text-align:left;border:1px solid var(--rule-firm);background:var(--surface);
  color:var(--ink);border-radius:9px;padding:12px 13px;margin-bottom:8px;cursor:pointer;
  transition:border-color var(--t),background var(--t)}
.opt:hover{border-color:var(--steel-400);background:var(--steel-50)}
.opt.on{border-color:var(--laser);background:var(--laser-wash)}
.opt .t{font-weight:500;font-size:14px}
.opt .s{display:block;font-size:12px;color:var(--ink-3);margin-top:4px}

.bigclock{font-family:var(--mono);font-size:46px;font-weight:500;letter-spacing:-0.045em;
  line-height:1;margin:10px 0 3px;font-variant-numeric:tabular-nums}
.chip{display:inline-flex;align-items:center;gap:8px;font-size:13px;font-weight:500;
  padding:5px 12px 5px 10px;border-radius:var(--r-pill)}
.chip .dot{width:8px;height:8px;border-radius:50%;background:currentColor;flex:none}
.c-running{color:var(--laser-deep);background:var(--laser-wash)}
.c-idle{color:#8A5406;background:var(--warn-wash)}
.c-setup{color:#4E3A7D;background:#EFEBF8}
.c-break{color:#2A5B7A;background:#E8F1F7}

.opbtns{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:18px}
.opbtn{border:0;border-radius:11px;padding:15px 8px;font-size:15px;font-weight:500;cursor:pointer;
  color:#fff;transition:filter var(--t)}
.opbtn:hover{filter:brightness(1.09)}
/* `grid-column` only spans anything inside .opbtns. START is appended
   straight to the card, where a bare button shrinks to its own text — so the
   one control the screen exists for was a two-word tab floating left. */
.opbtn.wide{grid-column:1/-1;width:100%;display:block}
.opbtn.run{background:var(--laser)}
.opbtn.idle{background:var(--s-idle)}
.opbtn.setup{background:var(--s-setup)}
.opbtn.brk{background:var(--s-break)}
.opbtn.stop{background:var(--alert)}
/* --ink-3 on steel-100 is 2.30:1. "Pick something first" is the very first
   thing an operator reads at the machine; it has to be legible. */
.opbtn:disabled{background:var(--steel-100);color:var(--ink-2);cursor:not-allowed;filter:none}
.opbtn:disabled:hover{filter:none}

.statelist{margin-top:17px;padding-top:14px;border-top:1px solid var(--rule)}
.staterow{display:flex;justify-content:space-between;font-size:13px;padding:4px 0;
  color:var(--ink-2)}
.staterow .vl{font-family:var(--mono);font-weight:500;color:var(--ink);
  font-variant-numeric:tabular-nums}

/* the segmented control on the phone: the live operation is the laser's colour */
.phone .seg button.on,.modal.narrow .seg button.on{background:var(--laser);border-color:var(--laser);color:#fff}

/* ============================ overlays =================================== */
.mask{position:fixed;inset:0;background:rgba(18,25,32,.42);backdrop-filter:blur(2px);
  display:grid;place-items:center;padding:22px;z-index:100;overflow-y:auto;
  animation:fade var(--t)}
@keyframes fade{from{opacity:0}to{opacity:1}}
.modal{background:var(--surface);border:1px solid var(--rule-firm);border-radius:10px;width:100%;
  max-width:620px;box-shadow:var(--lift-high);max-height:92vh;display:flex;flex-direction:column}
.modal.narrow{max-width:396px;border-radius:18px}
.modal .mh{padding:16px 20px;border-bottom:1px solid var(--rule);display:flex;
  justify-content:space-between;align-items:center;gap:12px}

.modal .mh h3{font-size:17px}
.modal .mb{padding:20px;overflow-y:auto}
.modal .mf{padding:15px 20px;border-top:1px solid var(--rule);display:flex;gap:9px;
  justify-content:flex-end;flex-wrap:wrap}

.x{background:none;border:0;font-size:20px;line-height:1;cursor:pointer;color:var(--ink-3);padding:0 4px}
.x:hover{color:var(--ink)}

.toast{position:fixed;left:50%;bottom:28px;transform:translateX(-50%);background:var(--steel-900);
  color:#fff;padding:11px 18px;border-radius:var(--r-control);font-size:14px;z-index:200;
  box-shadow:var(--lift-high);max-width:90vw;animation:rise 180ms cubic-bezier(.22,.61,.36,1)}
@keyframes rise{from{opacity:0;transform:translate(-50%,8px)}to{opacity:1;transform:translate(-50%,0)}}

/* a note carries its meaning in a left rule, not a coloured wash */
.banner{border:1px solid var(--rule);border-left:3px solid var(--s-idle);background:var(--surface);
  padding:14px 18px;margin-bottom:24px;font-size:14px;border-radius:var(--r-panel);line-height:1.55}
.banner.bad{border-left-color:var(--alert)}
.banner.good{border-left-color:var(--laser)}
.banner b{font-weight:600}

.kv{display:grid;grid-template-columns:auto 1fr;gap:8px 18px;font-size:14px}
.kv dt{color:var(--ink-3)}
.kv dd{margin:0;font-weight:450}

.readonly{border:1px solid var(--rule);background:var(--steel-50);padding:10px 15px;font-size:13px;
  color:var(--ink-2);margin-bottom:20px;border-radius:var(--r-panel)}

/* ============================ responsive ================================= */
@media (max-width:1000px){
  #shell{grid-template-columns:1fr}
  /* Two rows on a narrow screen: who you are on top, where you can go beneath.
     Cramming brand, nav and account into one 412px row truncated all three. */
  #side{position:sticky;top:0;z-index:20;height:auto;display:grid;
    grid-template-columns:1fr auto;grid-template-areas:"brand who" "nav nav";
    border-right:0;border-bottom:1px solid var(--rule)}
  /* The sticky header was 131px of an 844px screen — 15.5% of the operator's
     view given over to chrome, and the brand row inside it tells a man standing
     at his own shop's laser which shop he is in. The mark stays as the anchor
     for the nav; the wordmark goes. */
  .brand{grid-area:brand;border-bottom:0;padding:8px 14px}
  .brand>div{display:none}
  .whoami{grid-area:who;border-top:0;padding:10px 14px;gap:8px}
  .whoami .rl{display:none}
  .nav{grid-area:nav;display:flex;gap:4px;overflow-x:auto;padding:0 10px 10px;
    border-top:1px solid var(--rule);padding-top:8px;-webkit-overflow-scrolling:touch}
  /* 44px, because this strip is the only way around the app and it sits in the
     top-left corner — the hardest place to reach with one thumb. */
  .nav a{white-space:nowrap;margin:0;padding:12px 13px}
  /* Wrapped, not scrolled. Fifteen links in a sideways strip is 1552px of
     hidden travel with no scrollbar and no shadow: "Needs attention" and the
     badge counting runs that need the supervisor sat 186px off the right edge.
     One row by default, all of them behind More. */
  /* Two rows closed, which is exactly enough for the five screens the owner
     opens — Dashboard, Hours & machine, By customer, Floor now, Needs attention
     — plus the More that reveals the office ones. One row only fitted two. */
  .nav{flex-wrap:wrap;overflow:hidden;align-content:flex-start;
       padding-bottom:8px;row-gap:6px}
  /* Two rows only for the roles that have more links than fit in one. A short
     list simply takes the height it needs. */
  .nav.long{max-height:112px}
  .nav.open{max-height:none}
  .navmore{display:flex;align-items:center;gap:7px;order:-1;flex:0 0 auto;font:inherit;font-size:13px;font-weight:500;
    padding:12px 13px;border:1px solid var(--rule-firm);border-radius:var(--r-control);
    background:var(--surface);color:var(--ink-2);cursor:pointer;white-space:nowrap}
  .nav.open .navmore{order:0}
  .nav .grp{display:none}
  .nav.open .grp{display:block;flex:0 0 100%;padding:10px 4px 2px;margin:0}
  #main{padding:20px 20px 60px}
  .pagehead{margin:-20px -20px 22px;padding:20px 20px 18px}
}
@media (max-width:860px){
  #login{grid-template-columns:1fr}
  .si-brand{padding:28px 24px 24px}
  .si-brand h1{font-size:24px;margin:8px 0 10px}
  .si-brand .nestwrap svg{max-width:260px}
  .si-facts{margin-top:22px;gap:20px}
  .si-main{padding:28px 20px 48px}
}
/* A phone is the shop-floor case: the operator wants the keypad, not the
   cover page. Everything above the form collapses to a single line so the
   PIN is reachable without scrolling. */
@media (max-width:860px) and (max-height:900px){
  #login{min-height:100dvh;grid-template-rows:auto 1fr}
  .si-brand{padding:16px 20px;display:flex;flex-direction:row;align-items:baseline;gap:9px}
  .si-brand .co{font-size:12px}
  .si-brand h1{font-size:17px;margin:0;max-width:none}
  .si-brand p,.si-brand .nestwrap,.si-brand .si-facts{display:none}
  .si-main{padding:22px 20px 32px;align-items:flex-start}
}
@media (max-width:620px){
  .tiles{grid-template-columns:1fr 1fr}
  .tile{border-bottom:1px solid var(--rule)}
  /* Forty-four pixels, because this is used standing at a machine, sometimes
     with a glove half off. The small buttons computed to 31.5px and the dialog
     close to 20x28 -- fine with a mouse, a coin toss with a thumb. The segment
     buttons were given this treatment already; the rest were missed. */
  .btn,.btn.sm,.btn.ghost.sm,.chipbtn{min-height:44px;padding-top:11px;padding-bottom:11px}
  .x{min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center}
  .linkbtn{min-height:44px;display:inline-flex;align-items:center}
  /* "Primetech Industries" was clipped to fit a fixed 104px while the bar it
     labels had only 112px. The name takes what it needs, the bar gets the rest. */
  .hbar .nm{width:auto;max-width:40%}
  /* 13 columns 18px wide, with segments down to half a pixel and day numbers at
     10.5px: it carries no readable value on a phone, and the legend beside it
     already says the same thing in words. */
  .daypanel{display:none}
  .seg button{padding:11px 14px}
  .hbar .vl{width:76px}
  #main{padding:16px 16px 52px}
  .pagehead{margin:-16px -16px 20px;padding:18px 16px 16px}
}
/* One tile per row was costing 113px of height apiece to hold a figure 63px
   wide, which pushed "Actually cutting" and "Sheet handling" — the two the
   dashboard exists for, and the two deliberately colour-coded as the answer —
   clean off the first screen. Two up at every phone width. */
@media (max-width:430px){ .people{grid-template-columns:1fr} }
/* ================== phone: a bottom bar, not a folded sidebar ============= */
/* A sidebar folded into a strip across the top is a desktop app wearing a
   phone's clothes. The strip lived in the top-left corner: the furthest point
   on the screen from the hand holding it, and the one place a man standing at
   a laser cannot reach without putting something down first.

   Below 760px the shell becomes what a phone app is. Content scrolls under a
   bar fixed to the bottom edge, where the thumb already rests. The bar carries
   the three screens the role actually opens, plus the account, plus More --
   and More opens the whole navigation as a sheet, with the shop's name, who
   you are signed in as and Sign out at the foot of it. */
@media (max-width:760px){
  /* 16px, not 15. Below 16px iOS Safari zooms the page when a field takes
     focus, and leaves the operator scrolled sideways inside a form whose right
     edge he cannot see. It is also simply easier to read at arm's length. */
  body{font-size:16px}
  input,select,textarea,.phone input,.phone select,.phone textarea{font-size:16px}

  #shell{grid-template-columns:1fr;padding-bottom:0}
  /* Clear the bar, the home indicator, and a thumb's worth of air. Without
     this the last row of every list sits underneath the bar for ever. */
  #main{padding-bottom:calc(var(--bar-h) + env(safe-area-inset-bottom) + 20px)}

  #side{position:fixed;left:0;right:0;bottom:0;top:auto;z-index:60;
    height:auto;display:block;overflow:visible;
    background:var(--surface);
    border-right:0;border-bottom:0;border-top:1px solid var(--rule-firm);
    box-shadow:0 -10px 30px -22px rgba(26,34,41,.55);
    padding-bottom:env(safe-area-inset-bottom)}
  @supports (backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px)){
    #side{background:rgba(255,255,255,.88);
      -webkit-backdrop-filter:saturate(180%) blur(14px);
      backdrop-filter:saturate(180%) blur(14px)}
  }

  /* Closed, the bar is only the bar. The shop's name, the account and the
     version belong to the sheet — a phone has no room to spend on chrome that
     tells a man which shop he is standing in. */
  .brand,.whoami,.ver{display:none}

  .nav{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:0;
    padding:0;margin:0;overflow:visible;max-height:none;border-top:0;flex:none}
  .nav.long{max-height:none}
  .nav .grp{display:none}
  .nav a{display:none}

  .nav a.bar,.navmore{position:relative;display:grid;grid-template-rows:auto auto;
    justify-items:center;align-content:center;gap:3px;
    min-height:var(--bar-h);padding:7px 3px;margin:0;
    border:0;border-radius:0;background:none;
    font-size:11px;font-weight:500;line-height:1.2;letter-spacing:0;
    text-align:center;white-space:normal;color:var(--ink-3);
    text-decoration:none;cursor:pointer;order:0}
  .nav a.bar svg,.navmore svg{width:23px;height:23px;opacity:1}
  /* Two lines, never three. "Needs attention" takes two at 390px and three on
     a narrow phone with large text set — which turned a 60px bar into a third
     of the screen, permanently, on every page. */
  .nav a.bar span{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
    overflow:hidden;max-width:100%}
  .nav a.bar:hover{background:none;color:var(--ink-2)}
  /* The one green thing on the screen is the laser running. The tab you are on
     is not the laser, so it states itself in ink, not in signal colour. */
  .nav a.bar.on{background:none;color:var(--ink);font-weight:600}
  .nav a.bar.on svg{stroke-width:2.1}
  /* A rule the width of the label, so the active tab is readable in a glance
     from the length of an arm, not only from the weight of its type. */
  .nav a.bar.on::after{content:"";position:absolute;top:0;left:22%;right:22%;
    height:2px;background:var(--ink);border-radius:0 0 2px 2px}

  /* The badge counts runs waiting on the supervisor. In a row it sat at the
     end of the label; in a column there is no end of the label, so it becomes
     what a badge on a tab bar is. */
  .nav .count{position:absolute;top:4px;left:50%;margin:0;transform:translateX(3px);
    min-width:17px;padding:1px 5px;font-size:10px;line-height:15px;text-align:center}
  .nav a.bar.on .count{background:var(--alert);color:#fff}

  .navmore{-webkit-appearance:none;appearance:none}
  .navmore::before{content:"";width:23px;height:23px;
    background:currentColor;opacity:.9;
    -webkit-mask:var(--more-glyph) center/23px 23px no-repeat;
    mask:var(--more-glyph) center/23px 23px no-repeat}

  /* ---- More, opened: the whole navigation as a sheet ---- */
  #side.open{top:0;display:flex;flex-direction:column;overflow-y:auto;
    background:var(--surface);-webkit-backdrop-filter:none;backdrop-filter:none;
    padding-top:env(safe-area-inset-top)}
  #side.open .brand{display:flex;padding:16px 18px 14px;border-bottom:1px solid var(--rule)}
  #side.open .brand>div{display:block}
  #side.open .nav{display:block;padding:10px 10px 18px;flex:1 0 auto;
    grid-auto-flow:row}
  #side.open .nav .grp{display:block}
  #side.open .nav a{display:flex;flex-direction:row;align-items:center;gap:12px;
    justify-items:stretch;text-align:left;white-space:nowrap;
    min-height:48px;padding:10px 12px;border-radius:var(--r-control);
    font-size:15px;font-weight:500;color:var(--ink-2)}
  #side.open .nav a::after{display:none}
  #side.open .nav a svg{width:18px;height:18px}
  #side.open .nav a.on{background:var(--steel-900);color:#fff}
  #side.open .nav .count{position:static;transform:none;margin-left:auto;
    font-size:11px;line-height:1.5;padding:1px 7px}
  /* Closing the sheet is the same tap that opened it, so it sits where the
     thumb left it: the last cell of the bar, still at the bottom. */
  #side.open .navmore{position:sticky;bottom:0;order:99;width:100%;
    grid-template-rows:auto;grid-auto-flow:column;justify-content:center;gap:9px;
    padding:14px;background:var(--surface);border-top:1px solid var(--rule);
    font-size:15px;color:var(--ink)}
  #side.open .navmore::before{display:none}
  #side.open .whoami{display:flex;order:98;padding:14px 18px;
    border-top:1px solid var(--rule)}
  #side.open .whoami .rl{display:block}
  #side.open .ver{display:block;order:98;padding:0 18px 10px;margin:0}

  /* ---- STOP is reachable from wherever he has scrolled to ---- */
  /* While a run is live these four buttons are the screen. They sat in the
     card, near the top, and the card is followed by the shift figures and the
     history — so an operator who had scrolled down to read either could not
     stop his own run without scrolling back up, one-handed, at a machine.
     They dock above the tab bar instead, and the card leaves room for them.

     `sticky` cannot do this: it keeps an element inside its own container,
     and the container here is the card, which scrolls away. */
  .phone .opbtns{position:fixed;left:0;right:0;z-index:50;margin:0;
    bottom:calc(var(--bar-h) + env(safe-area-inset-bottom));
    padding:10px 14px;background:var(--surface);
    border-top:1px solid var(--rule);
    box-shadow:0 -10px 26px -20px rgba(26,34,41,.55)}
  .opbtn{min-height:56px;font-size:17px;border-radius:13px}
  /* The dock is fixed, so it hides whatever the page ends with. The page has
     to be able to scroll past it — otherwise the last run in the operator's
     history is permanently underneath the Stop button. */
  #main:has(.opbtns){padding-bottom:calc(var(--bar-h) + env(safe-area-inset-bottom) + 158px)}

  /* START is not docked: it is the last step of a short form that fits the
     screen, and a green bar pinned to the bottom of a page where nothing is
     running yet reads as a machine that is about to start on its own. */
  .phone .opbtn.wide.run{min-height:56px;font-size:17px}
}

/* Two things are fixed to the bottom edge of a phone, and the tab bar was
   there first: it is the only way off whatever screen the other one is
   covering. The reload prompt and every toast now stand on it, not over it. */
@media (max-width:760px){
  .swbar{bottom:calc(var(--bar-h) + env(safe-area-inset-bottom));
    border-top:1px solid var(--steel-700)}
  .toast{bottom:calc(var(--bar-h) + env(safe-area-inset-bottom) + 14px);
    left:14px;right:14px;transform:none;max-width:none;text-align:center}

  /* A select computed to 38px. It is the control that picks the material, the
     thickness, the sheet size and the customer — four of the six things a new
     order is — and it is used with a thumb, standing up. The buttons were
     given 44px already; the fields they sit between were missed. */
  input,select,textarea{min-height:44px}

  /* 11px mono under a bar chart is a footnote on a desk and nothing at all in
     a workshop. The columns are 26px wide at this size; a two-digit day at
     12px fits inside one with room to spare. */
  .cols .c .cap{font-size:12px}
}

/* ---------------- a card is not a table with the columns stacked --------- */
/* Eight label/value rows is a spreadsheet transcribed: one run filled a whole
   phone screen, so thirty-two runs were thirty-two screens of scrolling with
   nothing to catch the eye on the way past. A card ranks the same data —
   what the row IS on top, what it is worth at the bottom, the columns that
   only make sense next to other columns left on the desktop where they work. */
@media (max-width:760px){
  tbody tr{display:flex;flex-wrap:wrap;align-items:baseline}
  td{flex:1 0 100%}

  /* the line that names the row */
  td.ttl{order:-3;padding-bottom:2px;font-size:16px;font-weight:600;
    color:var(--ink);justify-content:flex-start}
  td.ttl::before{content:none!important}
  td.ttl .mono,td.ttl .muted{font-size:15px!important;color:var(--ink)!important;
    font-weight:600}

  /* the line under it: who, and when. They sit together on one line. */
  td.sub{order:-2;flex:0 0 auto;padding:0 0 8px 14px;font-size:13px;
    color:var(--ink-3);justify-content:flex-start;gap:0}
  td.sub::before{content:none!important}
  td.sub~td.sub{padding-left:0}
  td.sub~td.sub::before{content:"\00b7"!important;color:var(--steel-300);
    padding:0 6px;font-size:13px}

  /* a column that is only meaningful beside other columns */
  td.hideph,th.hideph{display:none}

  /* the rest keeps its label, tighter: this is a card, not a form */
  td{padding:5px 14px}
  td[data-label]::before{font-size:12px}
  td.hero{padding-top:9px;padding-bottom:9px}
}

@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
