/* Korbis Dispatch V3 — app.css
 *
 * One palette, in daylight. The surfaces are cool paper, the type is ink,
 * and color is spent on meaning: five statuses that every screen shares --
 * go, stop, wait, done, plan -- and six categorical colors for telling
 * things apart. A status is a fill or a chip; a category is a stripe, a dot
 * or a soft header. They never trade shapes, which is what keeps a screen
 * with both on it readable at a glance.
 *
 * Every color is a token here, and the suite holds every ink to 4.5:1 on
 * the surface it sits on. A pair that fails does not ship; nothing else in
 * the file writes a number.
 */

:root {
  /* Type scale.
   *
   * In rem, not px, so that somebody who has turned their browser text up --
   * which on a jobsite is most people over forty -- actually gets bigger text
   * instead of being ignored. 1rem is the browser's own base, normally 16px,
   * which is the accepted floor for body copy.
   *
   * The floor here is 0.75rem (12px). Below that, uppercase labels stop being
   * glanceable in daylight, and there is nothing on this screen important
   * enough to justify making somebody squint. */
  --t-xs:   0.75rem;    /* 12px — eyebrows, chips, meta */
  --t-sm:   0.8125rem;  /* 13px — secondary controls */
  --t-md:   0.875rem;   /* 14px — dense rows */
  --t-base: 1rem;       /* 16px — body */
  --t-lg:   1.125rem;   /* 18px — a panel's title */
  --t-title: 1.75rem;   /* 28px — one per screen: the page or the record */
  --t-figure: 1.375rem; /* 22px mono — a number in a tile or a fact */
  --t-hero: 2.25rem;    /* 36px — the crew's code on the board and the sign-in card, read across a cab; nowhere in the office */

  /* Tap targets. 44px is Apple's long-standing floor and the WCAG 2.5.5
   * figure; Material asks 48. Anything a finger has to find is held to 44. */
  --tap: 44px;

  /* ---- surfaces and ink ----
   *
   * Cool paper: the canvas is a pale gray, the card is white, the line is a
   * shade between. The three inks were measured on both surfaces; --ink-3
   * carries every 12px eyebrow and clears 4.5:1 on the canvas. Hierarchy
   * between them comes from size and weight, never from fading one out. */
  --slab:      #EEF0F3;   /* the canvas */
  --slab-deep: #E1E4E9;   /* a well in the canvas */
  --card:      #FFFFFF;
  --paper:     var(--card);
  --ink:       #15171C;
  --ink-2:     #484E5B;
  --ink-3:     #5C6371;
  --line:      #D5D9E0;
  --chalk:     #FFFFFF;   /* text on something dark; a surface never reads it */
  --night:     var(--ink);

  /* ---- the five statuses ----
   *
   * Each has a fill, the ink that sits on the fill, the deep value used as
   * text on a light surface, and a tint with its own ink for a quiet chip.
   *
   * go   — the lime. Loaded, live, approved, the commit button. It is the
   *        loudest thing on a screen read outdoors and crews know it.
   * stop — red. Work is stopped, a truck is held, a crew needs the office.
   *        The office is also told off-screen (see notify); the color is
   *        for the person already looking.
   * wait — amber. A question, a photo, something the office owes an answer.
   *        Nobody is standing around yet.
   * done — green. Finished, signed off.
   * plan — blue. Booked, scheduled, ahead. */
  --hivis:     #D9FF3D;
  --hivis-ink: #2B3300;
  --tint-go:   #F4FFCF;
  --go-ink:    #3E4D00;

  --stake:     #D92D20;   /* the stop fill; the old name, kept, because 60 rules read it */
  --stake-on:  #FFFFFF;   /* text on the stop fill */
  --stake-ink: #B42318;   /* stop as text, on a light surface */
  --stake-lit: #FF7A6E;   /* stop as text, on a dark surface */
  --tint-stop: #FEE4E2;
  --stop-ink:  #912018;

  --wait:      #F5B417;
  --wait-on:   #231A00;
  --wait-ink:  #8A5A00;
  --tint-wait: #FEF0C7;
  --tint-warn: var(--tint-wait);
  --warn-edge: #DC9A00;

  --cure:      #15803D;
  --cure-on:   #FFFFFF;
  --cure-ink:  #166534;
  --tint-good: #DCFCE7;

  --plan:      #2563EB;
  --plan-on:   #FFFFFF;
  --plan-ink:  #1D4ED8;
  --tint-plan: #DBEAFE;

  --tint-err:  var(--tint-stop);
  --err-ink:   var(--stop-ink);

  /* ---- six for telling things apart ----
   *
   * A truck, a company, a kind of place: each gets one of these by its id,
   * so it is the same color on every screen and never the same as its
   * neighbor. Fills carry white; tints carry their own ink. Never a status. */
  --cat-1: #6D5BD0; --cat-1-tint: #ECE9FB; --cat-1-ink: #4B3AA6;
  --cat-2: #0E7C86; --cat-2-tint: #DDF4F6; --cat-2-ink: #0B6069;
  --cat-3: #C2410C; --cat-3-tint: #FFEBDD; --cat-3-ink: #9A3412;
  --cat-4: #BE1D6E; --cat-4-tint: #FCE4EF; --cat-4-ink: #9D1859;
  --cat-5: #3B6FE0; --cat-5-tint: #E2EAFD; --cat-5-ink: #2B57BF;
  --cat-6: #5B7C0F; --cat-6-tint: #EDF5D6; --cat-6-ink: #48630C;

  /* ---- shades, veils and the dark surfaces ----
   *
   * The strip and the tablet board are dark by design -- what is on air,
   * read across a cab. The crew's phone is daylight. */
  --shade-a:     rgba(21,23,28,.06);
  --shade-b:     rgba(21,23,28,.11);
  --shade-c:     rgba(21,23,28,.3);
  --ink-veil:    rgba(21,23,28,.55);   /* behind a dialog */
  --ink-haze:    rgba(21,23,28,.16);
  --stake-glow:  rgba(217,45,32,.25);
  --card-clear:  rgba(255,255,255,0);  /* the card, faded to nothing */
  --bar-line:    rgba(255,255,255,.14);
  --bar-fill:    rgba(255,255,255,.06);
  --bar-fill-2:  rgba(255,255,255,.12);
  --dark-1:      #1B1E25;
  --dark-2:      #2C3039;
  --dark-3:      #3E434E;   /* a line on a dark surface */
  --dark-ink:    #E3E6EC;
  --dark-ink-2:  #9AA1AE;   /* muted on dark */
  --dark-ink-3:  #8A909C;
  --dim-on-dark: #B4BAC6;   /* the address under a job name on the crew's header */
  --photo-bg:    #000000;

  /* ---- the account's own colors ----
   *
   * --brand paints the strip and the column's lit row; --brand-ink is the
   * text on it, chosen by the app from the color's luminance. --btn is the
   * commit (Save, I'm here), the lime unless the account chose otherwise;
   * --btn-solid is the start (+ Work order), the ink. Everything the app
   * highlights follows --accent. Unset, all of it is the product's own look.
   * The five statuses are never touched by any of these: their meaning
   * belongs to the product, not to whoever is paying for it. */
  --brand: var(--ink);
  --brand-accent: var(--hivis);
  --brand-ink: #FFFFFF;
  --brand-dim: rgba(255,255,255,.62);
  --btn: var(--hivis);
  --btn-ink: var(--hivis-ink);
  --btn-solid: var(--ink);
  --btn-solid-ink: var(--chalk);
  --tab-on: var(--hivis);
  --tab-on-ink: var(--hivis-ink);
  --accent: var(--hivis);
  --accent-ink: var(--hivis-ink);
  --label: var(--ink);
  --label-ink: var(--chalk);

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

  /* ---- corners, in four steps ----
   *
   * Softer than they were: a card is 16, a panel 20, a control 10. The
   * square setting sets all five and nothing else. */
  --r-xs: 6px;     /* chips, tags, inputs' inner corners */
  --r-sm: 10px;    /* buttons, fields, small rows */
  --r-md: 16px;    /* cards, rows, dialogs' inner boxes */
  --r-lg: 20px;    /* panels, the work order, the phone frame */
  --r-pill: 999px;
  --r: var(--r-xs);

  /* A swatch's color, set on the element by the page (style="--sw:#2F5D50"),
   * so a disc can show any color while the stylesheet writes none. */
  --sw: transparent;

  --s1: 4px;  --s2: 8px;  --s3: 12px;  --s4: 16px;  --s5: 24px;  --s6: 32px;
  --bar-h: 60px;
  --wrap: 1400px;

  /* Layered, not lined: a card sits on the canvas by its shadow, and a
   * lifted thing (a dialog, a dragged row) by a deeper one. */
  --shadow: 0 1px 2px var(--shade-a), 0 4px 16px var(--shade-a);
  --shadow-lift: 0 4px 10px var(--shade-a), 0 16px 40px var(--shade-b);
}

* { box-sizing: border-box; }

html, body {
  margin:0;
  background: var(--slab);
  color: var(--ink);
  font-family: var(--display);
  font-size: 1rem;
  line-height: 1.45;
  -webkit-text-size-adjust: 100%;
  /* Every number on this screen is compared with the number beside it --
   * 07:00 against 08:00, 3 on crew against 2. Tabular figures line those up
   * in every font the stack can resolve to, so a column of times is a column. */
  font-variant-numeric: tabular-nums;
}

/* ---------- type ---------- */
/* The line above a title, a card's kind, a field's label: a small label in
 * sentence case, quiet by weight and color rather than by shouting. The
 * tracked-out capitals it replaced were the loudest habit on the page and
 * said nothing the words did not. A code -- a tablet's label, a job number
 * -- is still set in mono capitals, because it is painted on a case. */
.eyebrow {
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-3);
}
h3.eyebrow { color: var(--ink-2); margin:var(--s5) 0 var(--s3); }
/* ---------- a thing's own color ----------
 *
 * A truck (a tablet), a company, a kind of place: each carries one of the
 * six categorical colors by its id, so it is the same color on the shelf,
 * on Home, in the month and on a tool. The class sets three hooks; a
 * component reads --cat for a stripe or a dot, --cat-tint and --cat-ink for
 * a quiet chip. Nothing without a class shows a color, which is why the
 * defaults are the neutral gray. */
.cat-1 { --cat: var(--cat-1); --cat-tint: var(--cat-1-tint); --cat-ink: var(--cat-1-ink); }
.cat-2 { --cat: var(--cat-2); --cat-tint: var(--cat-2-tint); --cat-ink: var(--cat-2-ink); }
.cat-3 { --cat: var(--cat-3); --cat-tint: var(--cat-3-tint); --cat-ink: var(--cat-3-ink); }
.cat-4 { --cat: var(--cat-4); --cat-tint: var(--cat-4-tint); --cat-ink: var(--cat-4-ink); }
.cat-5 { --cat: var(--cat-5); --cat-tint: var(--cat-5-tint); --cat-ink: var(--cat-5-ink); }
.cat-6 { --cat: var(--cat-6); --cat-tint: var(--cat-6-tint); --cat-ink: var(--cat-6-ink); }
.catchip { display:inline-flex; align-items:center; gap:var(--s1); padding:2px var(--s2); border-radius:var(--r-pill);
  font-size:var(--t-xs); font-weight:600; background:var(--cat-tint, var(--slab-deep)); color:var(--cat-ink, var(--ink-2)); white-space:nowrap; }
.catchip::before { content:""; width:8px; height:8px; border-radius:var(--r-pill); background:var(--cat, var(--ink-3)); flex:0 0 auto; }
/* A mark: an icon in a tinted rounded square, the way a start or a section
 * announces what it is. Takes the thing's color when it has one. */
.mark { display:inline-grid; place-items:center; width:36px; height:36px; border-radius:var(--r-sm); flex:0 0 auto;
  background:var(--cat-tint, var(--slab)); color:var(--cat-ink, var(--ink-2)); }
.mark .ico { width:20px; height:20px; }
/* An icon: a 24-grid mark at the size of the text beside it, in its color. */
.ico { width: 1.25em; height: 1.25em; flex: 0 0 auto; display: inline-block; vertical-align: -.3em; }
.ui-btn .ico { width: 1.15em; height: 1.15em; }
h1, h2, h3 { margin:0; font-weight: 800; letter-spacing: -.02em; text-wrap: balance; }
/* One title per screen, in sentence case. The eyebrow above it carries the
 * uppercase; the title carries the words. */
h1 { font-size: var(--t-title); text-transform: none; letter-spacing: -.01em; line-height: 1.1; }
h2 { font-size: var(--t-lg); }
h3 { font-size: var(--t-base); }
p { text-wrap: pretty; }
.muted { color: var(--ink-2); }
.tiny { font-size: var(--t-sm); }

.code {
  font-family: var(--mono);
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
}

/* ---------- shell ----------
 *
 * Three zones: who this is, where you can go, what you can do. The bar used
 * to be one flex row that simply ran out of room -- at 1440 wide the tabs
 * were drawn over the account's name, "Sign out" broke onto two lines and
 * the search box shrank to "Find anyth". On a phone the search box left the
 * bar altogether. The brand now truncates, the tabs scroll, and the tools
 * never wrap. Under 900 wide the bar becomes two rows: the account and its
 * tools, then the tabs with the search box, and both stay on screen. */
.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap:var(--s3);
  padding:0 var(--s4); height: var(--bar-h);
  background: var(--brand, var(--ink)); color: var(--brand-ink, var(--chalk));
  border-bottom: 3px solid var(--brand-accent);
}
.brand {
  font-weight: 800; letter-spacing: .22em; text-transform: uppercase;
  font-size: var(--t-md); color: var(--brand-ink, var(--chalk));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.brand span { color: var(--brand-accent); }

/* Scrolls sideways when it must, without showing a scrollbar in the chrome.
 * The selected tab is scrolled into view by the page. */
.tabs { display: flex; gap: var(--s1); flex: 0 1 auto; min-width: 0;
  overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none; }
.tabs::-webkit-scrollbar { display: none; }
.tab {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  color: var(--brand-dim); font: inherit; font-weight: 700; font-size: var(--t-md);
  text-transform: uppercase; letter-spacing: .08em;
  padding:var(--s2) var(--s3); border-radius: var(--r-sm);
  flex: 0 0 auto; white-space: nowrap; min-height: 40px;
}
.tab:hover { color: var(--chalk); background: var(--bar-fill); }
.tab[aria-selected="true"],
.tab.on { background: var(--tab-on); color: var(--tab-on-ink); }

.spacer { flex: 1; }

/* The bell is the one orange thing in the bar, and it reads like the sign it
 * is: ink on orange, with the count reversed out so it is the loudest number
 * on the screen. */
.bell {
  display: inline-flex; align-items: center; gap:var(--s2);
  border: 0; cursor: pointer; font: inherit; font-weight: 800;
  text-transform: uppercase; letter-spacing: .06em; font-size: var(--t-sm);
  padding:var(--s2) var(--s4); border-radius: var(--r-sm); min-height: 40px;
  background: var(--stake); color: var(--stake-on); flex: 0 0 auto; white-space: nowrap;
}
.bell[hidden] { display: none; }
.bell .n {
  background: var(--stake-on); color: var(--stake);
  min-width: 22px; height: 22px; border-radius: var(--r-pill);
  display: grid; place-items: center; font-size: var(--t-sm); padding:0 var(--s2);
}

.wrap { max-width: var(--wrap); margin:0 auto; padding:var(--s5) var(--s5) 90px; }

/* ---------- the shell: a strip across the top, a rail down the side ----------
 *
 * The strip is what is happening now; the rail is where to go. Neither
 * scrolls away. The screens themselves are unchanged underneath: the same
 * sections, the same ids, the same keys (1-8 still walk the rail). */
.topbar.live { height: auto; min-height: 64px; padding:0 var(--s4); gap:var(--s3); flex-wrap: wrap; }
.topbar.live .findwrap { flex: 0 1 170px; }
/* The strip may be two rows: the figures, then the tray under them. */
.livetray { flex: 1 1 100%; order: 9; margin:0 calc(-1 * var(--s4)); padding:var(--s2) var(--s4) var(--s3); background: var(--bar-fill);
  border-top: 1px solid var(--bar-fill-2); display: flex; flex-direction: column; gap:var(--s2); }
.livetray[hidden] { display: none; }
.trayrow { display: flex; align-items: center; gap:var(--s4); padding:var(--s2) var(--s3); border-radius: var(--r-sm); background: var(--card); color: var(--ink); }
.traypic img { width: 56px; height: 56px; object-fit: cover; border-radius: var(--r-xs); display: block; }
.traymain { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap:1px; }
.traymain b { font-size: var(--t-base); }
.traymain .kind { font-size: var(--t-xs); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--stake-ink); }
.traydetail { font-size: var(--t-sm); color: var(--ink-2); margin-top:var(--s1); }
.trayrow .ui-btns { flex: 0 0 auto; }
.traypic { appearance: none; border: 0; background: transparent; padding:0; cursor: zoom-in; flex: 0 0 auto; }
.revpic { appearance: none; border: 0; background: transparent; padding:0; cursor: zoom-in; display: block; }
.picdlg { max-width: min(1100px, calc(100vw - 32px)); }
.picbody { display: grid; place-items: center; background: var(--slab); padding:0; }
.picbody img { max-width: 100%; max-height: calc(100vh - 230px); display: block; object-fit: contain; }
.picdlg a.ui-btn.lg { display: inline-flex; align-items: center; background: transparent; color: var(--ink-2); font-size: var(--t-sm); text-transform: none; letter-spacing: 0; text-decoration: underline; }
.live-clock { display: flex; flex-direction: column; line-height: 1.15; flex: 0 0 auto;
  padding:0 var(--s4); border-left: 1px solid var(--bar-line); }
.live-clock b { font-size: var(--t-sm); letter-spacing: 0; text-transform: none; font-weight: 700; }
.live-clock span { font: 700 var(--t-md)/1.1 ui-monospace, monospace; color: var(--brand-dim); font-variant-numeric: tabular-nums; }
.live-now { display: flex; align-items: stretch; gap:var(--s2); flex: 0 1 auto; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.live-now::-webkit-scrollbar { display: none; }
.livetile { appearance: none; border: 1px solid var(--bar-line); background: var(--bar-fill);
  color: var(--brand-ink); font: inherit; cursor: pointer; border-radius: var(--r-sm);
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap:2px;
  padding:var(--s1) var(--s4); white-space: nowrap; min-height: 48px; flex: 0 0 auto; }
.livetile b { font: 800 var(--t-figure)/1 ui-monospace, monospace; font-variant-numeric: tabular-nums; }
.livetile[aria-expanded="true"] { outline: 2px solid var(--brand-ink); outline-offset: -2px; }
.livetile span { font-size: var(--t-xs); font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--brand-dim); }
.livetile.zero { opacity: .55; }
/* Live: crews moving, the number in the lime. Wait: the office owes an
 * answer, the tile in amber. Stop: something is held, the tile in red. The
 * three read at a glance from across a desk, which is the strip's whole job. */
.livetile.live b { color: var(--brand-accent); }
.livetile.wait { background: var(--wait); border-color: var(--wait); color: var(--wait-on); opacity: 1; }
.livetile.wait span { color: var(--wait-on); }
.livetile.stop { background: var(--stake); border-color: var(--stake); color: var(--stake-on); opacity: 1; }
.livetile.stop span { color: var(--stake-on); }
.livetile:hover { background: var(--bar-fill-2); }
.livetile.wait:hover { background: var(--wait); color: var(--wait-on); filter: brightness(1.04); }
.livetile.stop:hover { background: var(--stake); color: var(--stake-on); filter: brightness(1.06); }
/* ---------- dispatching the pile ----------
 *
 * The three controls a dispatcher actually uses: the corridors, a tick per
 * place, and a bar that says what is picked and where it is going. The bar is
 * only there once something is ticked — a form nobody is using is a form in
 * the way.
 */
.corridors { display:flex; flex-wrap:wrap; align-items:center; gap:var(--s2);
  padding:var(--s3) 0; }
.corridors[hidden] { display:none; }
.corridors .ui-btn { gap:var(--s2); }

.sendbar { position:sticky; top:var(--bar-h); z-index:30;
  display:flex; flex-wrap:wrap; align-items:center; gap:var(--s3);
  padding:var(--s3) var(--s4); margin-bottom:var(--s3);
  border:1px solid var(--brand-accent); border-radius:var(--r-md);
  background:var(--card); box-shadow:var(--shadow); }
.sendbar[hidden] { display:none; }
.sb-n { font:800 var(--t-lg)/1 ui-monospace, monospace; color:var(--brand-accent); }
.sb-what { font-weight:700; }
.sb-f { display:flex; align-items:center; gap:var(--s2); font-size:var(--t-sm); }
.sb-f span { color:var(--ink-2); font-weight:600; }
.sb-f select, .sb-f input { min-height:var(--tap); border:1px solid var(--line);
  border-radius:var(--r-xs); background:var(--paper); color:var(--ink);
  font:inherit; padding:0 var(--s2); }

.wkpick { display:flex; align-items:center; padding-right:var(--s3); flex:0 0 auto; }
.wkpick input { width:22px; height:22px; accent-color:var(--brand-accent); }
.wkcard.picked { border-color:var(--brand-accent); box-shadow:0 0 0 1px var(--brand-accent) inset; }
.ui-chip.owner { background:var(--slab-deep); color:var(--ink-2); font-weight:700; }

/* Where the work is. A plot, not a map service — nothing on this box is
   fetched, and "are these together or scattered" is the only question a
   dispatcher is asking of it. */
.pilemap { border:1px solid var(--line); border-radius:var(--r-md); background:var(--card);
  margin-bottom:var(--s3); }
.pilemap[hidden] { display:none; }
.pilemap > summary { cursor:pointer; padding:var(--s3) var(--s4); font-weight:700;
  min-height:var(--tap); display:flex; align-items:center; }
.pm-body { padding:0 var(--s4) var(--s3); }
.pm-svg { width:100%; height:220px; background:var(--slab); border-radius:var(--r-sm);
  border:1px solid var(--line); }
.pm-dot { fill:var(--brand-accent); opacity:.75; }
.pm-dot.out { fill:var(--ink-2); opacity:1; }

/* Whose account is on screen, when it is not your own.
   Deliberately loud: everything a host does while lensed lands on a client's
   records, and a screen that looks exactly like your own is how somebody
   edits the wrong company's day. */
.lenswho { display:inline-flex; align-items:center; gap:var(--s1); flex:0 0 auto;
  padding:var(--s1) var(--s3); border-radius:var(--r-pill);
  background:var(--wait); color:var(--wait-on);
  font-size:var(--t-xs); font-weight:800; letter-spacing:.02em; white-space:nowrap; }
.lenswho[hidden] { display:none; }
.lenswho::before { content:'Acting for'; font-weight:600; opacity:.75; }

/* ---------- Ask Korbis ----------
 *
 * On the top bar, next to the counts, on every screen. It is deliberately NOT
 * a .livetile: those are figures you read, this is a thing you press, and a
 * button that looks like a readout is a button people do not press.
 *
 * The lit edge and the slow sweep across it are the one piece of ornament in
 * the product, and they earn their place: this is the control that is supposed
 * to invite you, and every assistant people already use signals itself the
 * same way. It stops entirely for prefers-reduced-motion, and it stops when
 * the model is not answering, because a control that shimmers and then refuses
 * is a lie.
 */
.askbtn { position: relative; appearance: none; cursor: pointer; font: inherit;
  display: inline-flex; align-items: center; gap:var(--s2); flex: 0 0 auto;
  min-height: 48px; padding:var(--s1) var(--s4); margin-right:var(--s2);
  border: 1px solid var(--brand-accent); border-radius: var(--r-pill);
  background: var(--bar-fill); color: var(--brand-ink);
  overflow: hidden; isolation: isolate; }
.askbtn:hover { background: var(--bar-fill-2); }
.askbtn:focus-visible { outline: 2px solid var(--brand-accent); outline-offset: 2px; }
.askbtn[aria-expanded="true"] { background: var(--brand-accent); color: var(--ink); }
.askmark { width: 20px; height: 20px; color: var(--brand-accent); flex: 0 0 auto; }
.askbtn[aria-expanded="true"] .askmark { color: currentColor; }
.asktext { font-size: var(--t-sm); font-weight: 700; white-space: nowrap; }
.askkey { font: 600 var(--t-xs)/1 ui-monospace, monospace; color: var(--brand-dim);
  border: 1px solid var(--bar-line); border-radius: var(--r-xs); padding:var(--s1); }
/* The sweep. One element, behind the label, clipped by the button. */
.askglow { position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(100deg, transparent 20%, var(--brand-accent) 50%, transparent 80%);
  opacity: .16; transform: translateX(-60%); animation: asksweep 7s ease-in-out infinite; }
@keyframes asksweep {
  0%, 62% { transform: translateX(-60%); }
  92%, 100% { transform: translateX(60%); }
}
.askbtn.isoff { border-color: var(--bar-line); }
.askbtn.isoff .askmark { color: var(--brand-dim); }
.askbtn.isoff .askglow { animation: none; opacity: 0; }
@media (prefers-reduced-motion: reduce) { .askglow { animation: none; opacity: .1; } }

/* The sheet it opens.
 *
 * `askover`, not `askwrap`. There was already an .askwrap on this page -- it
 * is what "Waiting on you" and "Photos to check" sit in on the day view -- and
 * giving that name a `position: fixed; inset: 0` rule turned the dispatcher's
 * own panels into full-screen covers the moment a crew was waiting on an
 * answer. A new overlay needs a name nothing else already answers to. */
.askover { position: fixed; inset: 0; z-index: 120; display: grid;
  grid-template-rows: auto 1fr; justify-items: center; }
.askover[hidden] { display: none; }
.askscrim { position: absolute; inset: 0; background: var(--ink-veil);
  backdrop-filter: blur(3px); }
.asksheet { position: relative; z-index: 1; width: min(760px, calc(100vw - var(--s4) * 2));
  margin-top: min(9vh, 84px); background: var(--card); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-lift);
  max-height: min(78vh, 760px); display: flex; flex-direction: column; overflow: hidden; }
.askhead { display: grid; grid-template-columns: auto minmax(0,1fr) auto; align-items: center;
  gap:var(--s3); padding:var(--s4) var(--s4) var(--s3); border-bottom: 1px solid var(--line); }
.askhead-mark { display: grid; place-items: center; width: 38px; height: 38px;
  border-radius: var(--r-md); background: var(--slab-deep); color: var(--brand-accent); }
.askhead-mark .ico { width: 22px; height: 22px; }
.askhead h2 { margin: 0; font-size: var(--t-lg); }
.askhead p { margin: 2px 0 0; }
.askclose { appearance: none; border: 1px solid var(--line); background: var(--paper);
  color: var(--ink-2); font: inherit; cursor: pointer; border-radius: var(--r-sm);
  width: 34px; height: 34px; line-height: 1; }
.askclose:hover { background: var(--slab-deep); }
.askbody { padding:var(--s4); overflow: auto; flex: 1 1 auto; }
.askfoot { padding:var(--s2) var(--s4) var(--s3); border-top: 1px solid var(--line);
  background: var(--paper); }
/* The panel, while it is a guest in here: no card of its own, no heading --
   the sheet already said what this is. */
.aipanel.inask { border: 0; box-shadow: none; padding: 0; background: transparent; margin: 0; }
.aipanel.inask .panelhead { display: none; }
body.askon { overflow: hidden; }

.livenext { appearance: none; border: 1px solid var(--bar-line); background: transparent; color: var(--brand-ink);
  font: inherit; cursor: pointer; border-radius: var(--r-sm); display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap:var(--s2);
  align-items: baseline; padding:var(--s1) var(--s4); text-align: left; white-space: nowrap; min-height: 48px; max-width: 30ch; flex: 0 1 auto; overflow: hidden; }
/* The strip never wraps the ? off the line: the next-out chip gives way first. */
.topbar.live .livenext { min-width: 0; flex: 0 1 30ch; }
.livenext .eyebrow { grid-column: 1 / -1; color: var(--brand-accent); margin:0; }
.livenext.soon { border-color: var(--brand-accent); }
.livenext.soon b { color: var(--brand-accent); }
.livenext b { font: 800 var(--t-md)/1.2 ui-monospace, monospace; }
.livenext .nx { overflow: hidden; text-overflow: ellipsis; font-size: var(--t-sm); color: var(--brand-dim); }

.shellbody { display: flex; align-items: flex-start; min-height: calc(100vh - var(--bar-h)); }
.sidebar { flex: 0 0 200px; position: sticky; top: var(--bar-h); height: calc(100vh - var(--bar-h));
  display: flex; flex-direction: column; background: var(--card); border-right: 1px solid var(--line); padding:var(--s4) var(--s3); }
.sidebar .tabs { flex-direction: column; overflow: visible; gap:2px; flex: 1 1 auto; }
.sidebar .tab { color: var(--ink-2); text-align: left; text-transform: none; letter-spacing: 0; font-size: var(--t-base);
  text-decoration: none; display: flex; align-items: center; gap:var(--s3);
  font-weight: 600; padding:var(--s2) var(--s3); min-height: 40px; width: 100%; border-radius: var(--r-sm); }
.sidebar .tab:not([aria-selected="true"]) .ico { color: var(--ink-3); }
.sidebar .tab:hover { color: var(--ink); background: var(--slab); }
.sidebar .tab:hover .ico { color: var(--ink); }
.sidebar .tab[aria-selected="true"] { background: var(--brand); color: var(--brand-ink); font-weight: 700; }
.sideh { font-size: var(--t-xs); font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--ink-3);
  padding:var(--s4) var(--s3) var(--s1); }
.sideh:first-child { padding-top:2px; }
.sidefoot { border-top: 1px solid var(--line); padding-top:var(--s2); display: flex; flex-direction: column; gap:2px; }
.sidefoot .tab { color: var(--ink-2); text-transform: none; letter-spacing: 0; text-align: left; font-size: var(--t-sm); min-height: 36px; padding:var(--s2) var(--s3); text-decoration: none; display: flex; align-items: center; gap:var(--s2); }
.sidefoot .tab:hover { color: var(--ink); background: var(--slab); }
.sidewho { font-size: var(--t-xs); color: var(--ink-3); padding:var(--s2) var(--s3) 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shellbody > .wrap { flex: 1 1 auto; min-width: 0; margin:0; max-width: var(--wrap); padding:var(--s5) var(--s6) 90px; }
@media (max-width: 899.5px) {
  .shellbody { display: block; }
  /* The column becomes the bar along the bottom of a phone: a mark over a
   * word, the lit one in the account's color, sliding sideways when there
   * are more than fit. Setup and Sign out sit at its end, not over it. */
  .sidebar { position: fixed; left: 0; right: 0; bottom: 0; top: auto; height: auto; z-index: 40;
    flex-direction: row; align-items: stretch; padding:var(--s1) var(--s2) var(--s2); border-right: 0; border-top: 1px solid var(--line);
    box-shadow: var(--shadow-lift); padding-bottom: max(var(--s2), env(safe-area-inset-bottom)); }
  .sidebar .tabs { flex-direction: row; overflow-x: auto; order: 1; flex: 1 1 0; min-width: 0; gap:0; }
  .sidebar .tab, .sidefoot .tab { width: auto; flex: 0 0 auto; flex-direction: column; justify-content: center; gap:var(--s1);
    font-size: var(--t-xs); font-weight: 600; padding:var(--s1) var(--s3); min-width: 64px; min-height: 52px; text-align: center; line-height: 1.2; }
  .sidebar .tab .ico, .sidefoot .tab .ico { width: 22px; height: 22px; }
  .sideh { display: none; }
  .sidefoot { border: 0; padding:0; flex-direction: row; order: 2; margin-left:auto; border-left: 1px solid var(--line); padding-left:var(--s1); }
  /* The figures wrap to a second line rather than clip mid-word. */
  .live-now { flex-wrap: wrap; overflow: visible; flex: 1 1 100%; }
  .sidewho { display: none; }
  .live-clock, .livenext { display: none; }
  /* A phone gets the figures that are not zero, and nothing that is. */
  .livetile.zero { display: none; }
  .topbar.live { padding:var(--s2) var(--s4); row-gap:var(--s2); }
  .topbar.live .findwrap { flex: 1 1 100%; order: 8; margin:0; }
  .topbar.live .findwrap:focus-within { flex-basis: 100%; }
  .topbar #helpBtn { display: none; }
  .shellbody > .wrap { padding:var(--s4) var(--s4) 110px; }
  .starts { grid-template-columns: 1fr 1fr; gap:var(--s2); }
  .start.prime { grid-column: 1 / -1; }
  .start:not(.prime) span { display: none; }
  .start:not(.prime) { min-height: var(--tap); padding:var(--s2) var(--s3); }
}

/* ---------- the head ----------
 * One block on every screen -- a list, a record, the loading screen, Setup,
 * a start, a question screen:
 *
 *   [< Back]   EYEBROW                              [ Primary ] [ Second ]
 *              Title
 *              one line of standing
 *
 * Back only where there is somewhere to go back to. At most two actions in
 * the head; the rest live in the panels. The stepper on Today and Month
 * (.nav) is one action: a group of three plain buttons. */
.head { display:flex; align-items:flex-start; gap:var(--s4); flex-wrap:wrap; margin-bottom:var(--s5); }
.head > .back { flex:0 0 auto; margin-top:var(--s1); }
.head-title { flex:1 1 320px; min-width:0; }
.head-title h1 { margin:var(--s1) 0 0; }
.standing { font-size:var(--t-sm); color:var(--ink-2); margin-top:var(--s1); }
.head-acts { flex:0 0 auto; display:flex; gap:var(--s2); flex-wrap:wrap; align-items:center; }
.nav { display:flex; gap:var(--s2); }

/* ---------- alerts ---------- */
.alerts { display: grid; gap:var(--s2); margin-bottom:var(--s5); }
.alert {
  display: flex; gap:var(--s4); align-items: flex-start;
  padding:var(--s3) var(--s4); border-radius: var(--r);
  background: var(--card); border: 1px solid var(--line);
  border-left: 5px solid var(--ink-3);
}
.alert.stop { border-left-color: var(--stake); background: var(--tint-stop); color: var(--stop-ink); }
.alert.warn { border-left-color: var(--warn-edge); background: var(--tint-warn); }
.alert .t { font-weight: 800; }
.alert .b { color: var(--ink-2); font-size: var(--t-md); }
.alert button {
  margin-left:auto; flex: none; border: 1px solid var(--ink); background: var(--btn-solid); color: var(--btn-solid-ink);
  font: inherit; font-weight: 700; font-size: var(--t-sm); text-transform: uppercase; letter-spacing: .05em;
  padding:var(--s2) var(--s3); border-radius: var(--r); cursor: pointer;
}

/* ---------- asks (approvals) ---------- */
.askwrap { margin-bottom:var(--s5); }
.ask {
  background: var(--card); border: 2px solid var(--stake); border-radius: var(--r);
  padding:var(--s4); margin-bottom:var(--s3);
  transition: transform .18s ease, opacity .18s ease;
}
.ask.settled { transform: translateX(14px); opacity: 0; }
.ask .kind {
  display: inline-block; background: var(--stake); color:var(--stake-on);
  font-size: var(--t-xs); font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  padding:var(--s1) var(--s2); border-radius: var(--r-xs); margin-bottom:var(--s2);
}
.ask .q { font-size: var(--t-figure); font-weight: 800; line-height: 1.25; }
.ask .who { color: var(--ink-2); font-size: var(--t-md); margin-top:var(--s1); }
.ask .detail {
  margin-top:var(--s3); padding:var(--s3) var(--s3); background: var(--slab);
  border-radius: var(--r); font-size: var(--t-base); white-space: pre-wrap;
}
.ask .acts { display: flex; gap:var(--s3); margin-top:var(--s4); flex-wrap: wrap; }

/* The large button is the one family at its largest size: see .ui-btn.lg. */
/* ---------- the tablet rail (signature element) ---------- */
.rail {
  display: grid; gap:var(--s4);
  grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
}

.slate {
  position: relative; background: var(--card);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow); overflow: hidden;
  display: flex; flex-direction: column; min-height: 216px;
  text-align: left; font: inherit; color: inherit; cursor: pointer; padding:0;
}
.slate:hover { border-color: var(--ink-3); }
.slate .band { height: 7px; background: var(--line); }
.slate.planned    .band { background: var(--accent); color:var(--accent-ink); }
.slate.dispatched .band { background: var(--accent); color:var(--accent-ink); }
.slate.onsite     .band { background: var(--accent); color:var(--accent-ink); }
.slate.done       .band { background: var(--cure); color: var(--cure-on); }
.slate.blocked    .band { background: var(--stake); color:var(--stake-on); }

.slate .top {
  display: flex; align-items: center; justify-content: space-between;
  padding:var(--s3) var(--s4) 0;
}
/* The tablet's label is the slate's eyebrow -- the card's kind line -- in
 * mono because it is a code painted on a case. */
.slate .label {
  font-family: var(--mono); font-weight: 800; font-size: var(--t-xs);
  letter-spacing: .1em; text-transform: uppercase; color: var(--cat-ink, var(--ink-2));
  display:inline-flex; align-items:center; gap:var(--s2);
}
.slate .label::before { content:""; width:10px; height:10px; border-radius:var(--r-pill); background:var(--cat, var(--ink-3)); }


.slate .body { padding:var(--s2) var(--s4) var(--s4); flex: 1; display: flex; flex-direction: column; }
.slate .jobname { font-size: var(--t-lg); font-weight: 800; line-height: 1.2; letter-spacing: -.01em; }
.slate .scope { color: var(--ink-2); font-size: var(--t-md); margin-top:var(--s1); }
.slate .meta {
  margin-top:auto; padding-top:var(--s3); display: flex; gap:var(--s2); flex-wrap: wrap;
  font-size: var(--t-sm); color: var(--ink-2);
}
.slate .meta b { color: var(--ink); font-weight: 700; }
.slate .shortcode {
  font-family: var(--mono); font-weight: 700; letter-spacing: .2em;
  font-size: var(--t-base); color: var(--ink);
}

.slate.empty {
  background: transparent; border: 2px dashed var(--line); box-shadow: none;
  align-items: center; justify-content: center; text-align: center;
}
.slate.empty:hover { border-color: var(--stake); background: var(--tint-stop); color: var(--stop-ink); }
.slate.empty .band { display: none; }
.slate.empty .msg { padding:var(--s5) var(--s4); }
.slate.empty .msg .big-x { font-size: var(--t-title); font-weight: 800; color: var(--ink-3); }
.slate.empty .msg .sub { color: var(--ink-2); font-size: var(--t-md); margin-top:var(--s2); }
.slate.empty .msg .add {
  margin-top:var(--s3); display: inline-block; background: var(--btn-solid); color: var(--btn-solid-ink);
  font-weight: 800; font-size: var(--t-sm); text-transform: uppercase; letter-spacing: .06em;
  padding:var(--s3) var(--s4); border-radius: var(--r);
}
.slate .flag {
  position: absolute; top: 0; right: 0;
  background: var(--stake); color:var(--stake-on); font-size: var(--t-xs); font-weight: 800;
  letter-spacing: .1em; text-transform: uppercase; padding:var(--s1) var(--s3);
  border-bottom-left-radius: 6px;
}

/* ---------- month ---------- */
.monthgrid { display: grid; grid-template-columns: repeat(7, 1fr); gap:var(--s1); }
.dow {
  text-align: center; font-size: var(--t-xs); font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-3); padding-bottom:var(--s1);
}
/* Every day is the same box. The month grid pins its rows to one height
 * (grid-auto-rows) and each cell fills it, so the calendar reads as a real
 * calendar instead of rows that grow and shrink with how much is on the day.
 * What does not fit is clipped inside the cell, and the chip list already
 * caps itself with a "+N more". */
.calfoot { display:flex; align-items:center; justify-content:space-between; gap:var(--s4); flex-wrap:wrap; margin-top:var(--s4); }
.calsub { display:flex; gap:var(--s2); flex-wrap:wrap; }
.calsub .ui-btn .ico { width:16px; height:16px; }
#monthGrid { grid-auto-rows: 124px; }
.cell {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md);
  height: 124px; padding:var(--s3); cursor: pointer; text-align: left; overflow: hidden;
  font: inherit; color: inherit; display: flex; flex-direction: column; gap:var(--s1);
}
.cell:hover { border-color: var(--ink); }
.cell.other { background: transparent; border-style: dashed; opacity: .5; }
.cell.now { border: 2px solid var(--ink); }
.cell .dnum { font-weight: 800; font-size: var(--t-md); flex:0 0 auto; }
.cell .dnum .free { float: right; font-size: var(--t-xs); color:var(--ink-2); font-weight: 800; letter-spacing: .08em; }
/* The day's work, stacked and clipped to what the cell can hold. */
.mchips { flex:1 1 auto; min-height:0; overflow:hidden; display:flex; flex-direction:column; gap:var(--s1); align-content:flex-start; }
.mchips .chip { max-width:100%; }
/* ---------- the chip ----------
 *
 * One shape on the platform: a pill, 12px, medium weight, sentence case,
 * a tint with its ink. Planned is blue, loaded and live are the lime tint,
 * done is green, stopped is red, waiting is amber; anything else is the
 * quiet gray. A chip never shouts -- the fill's meaning is the loud part. */
.chip[class*="cat-"] { border-left:3px solid var(--cat); border-radius:var(--r-xs) var(--r-pill) var(--r-pill) var(--r-xs); }
.chip, .pill, .ui-chip, .rev, .needs {
  display: inline-flex; align-items: center; gap:var(--s1); max-width: 100%;
  font-size: var(--t-xs); font-weight: 600; line-height: 1.5; letter-spacing: 0; text-transform: none;
  padding:2px var(--s2); border-radius: var(--r-pill); background: var(--slab-deep); color: var(--ink-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle;
}
.chip.planned, .pill.planned { background: var(--tint-plan); color: var(--plan-ink); }
.chip.dispatched, .chip.onsite, .pill.dispatched, .pill.onsite, .pill.live, .ui-chip.live { background: var(--tint-go); color: var(--go-ink); }
.chip.done, .pill.done, .ui-chip.done { background: var(--tint-good); color: var(--cure-ink); }
.chip.blocked, .pill.blocked, .ui-chip.stop, .rev.redo { background: var(--tint-stop); color: var(--stop-ink); }
.pill.park, .pill.shut, .ui-chip.dark { background: var(--slab-deep); color: var(--ink-2); }
.rev.pending, .rev.need, .needs { background: var(--tint-wait); color: var(--wait-ink); }
.rev.ok { background: var(--tint-good); color: var(--cure-ink); }
/* A photograph taken and sitting in this tablet's outbox. Deliberately the
   calm slab and not the amber of .rev.need — the crew has done their part and
   nothing is being asked of them. */
.rev.hold { background: var(--slab-deep); color: var(--ink-2); }
.chip .tl { font-family: var(--mono); letter-spacing: .06em; opacity: .75; }

/* ---------- jobs list ---------- */
.jobrow .n { font-weight: 800; font-size: var(--t-lg); }
.jobrow .c { font-family: var(--mono); font-size: var(--t-sm); color: var(--ink-2); letter-spacing: .1em; }

/* ---------- forms ----------
 * The one field, `.f`: an eyebrow label (with a meta hint beside it when a
 * word helps), a 16px control 44px tall, and a meta note under it when the
 * control needs a sentence. A <label> or a <div>; a read-only one shows a
 * fact where the control would be. Every form on the platform -- records,
 * a start, the loading screen, Setup's windows, the strip's questions -- is
 * built from it, on the one grid, `.form`. */
.f { display: block; margin-bottom:var(--s3); }
.f > .lab {
  display: block; font-size: var(--t-md); font-weight: 600; letter-spacing: 0;
  text-transform: none; color: var(--ink); margin-bottom:var(--s2);
}
.f .hint { font-size: var(--t-sm); font-weight: 400; color: var(--ink-3); text-transform: none; letter-spacing: 0; }
.note { margin:var(--s1) 0 0; font-size: var(--t-sm); color: var(--ink-3); }
div.f > b { font-size: var(--t-lg); }
/* The entry line: a field whose control is a row -- the thing, a count, the
 * button that files it. A place's register, a company's tools, a job here. */
.f > .line { display:flex; gap:var(--s2); align-items:center; }
.f > .line > input, .f > .line > select { flex:1 1 auto; min-width:0; }
.f > .line > input[type=number], .f > .line > .short { flex:0 0 4.5rem; }
.f > .line > .ui-btn { flex:0 0 auto; }
/* The one grid: two columns, `.wide` across both, the buttons last with the
 * go first. On a phone, one column. */
.form { display:grid; grid-template-columns:1fr 1fr; gap:var(--s3) var(--s4); }
.form > .f, .form > .chk { margin:0; }
/* A pair of fields stays level at the control even when one label's hint
 * wraps: the field fills its row and the label takes the slack. */
.form > .f { display:flex; flex-direction:column; }
.form > .f > .lab { flex:1 0 auto; }
.form > .wide { grid-column:1 / -1; }
.form > .ui-btns { grid-column:1 / -1; margin-top:var(--s2); align-items:center; }
.form > .ui-btns .grow { flex:1; }
.form > .err, .form > .guide, .form > .note { grid-column:1 / -1; margin:0; }
/* The destructive one stands apart, at the far end of the form's last row. */
.form > .ui-btns .danger { margin-left:auto; }
/* ---------- the control ----------
 *
 * One drawing for every text field, select and textarea on the platform:
 * white, a hairline, the small corner, 44px tall, 16px text. It rests, it
 * is hovered, it is focused (the account's color, one ring), it is wrong
 * (the stop color, and the note under it says what). A select draws its
 * own chevron from two gradients in the caption ink, so the arrow is the
 * same on every browser and in every appearance. */
input, select, textarea {
  width: 100%; font: inherit; font-size: var(--t-base); color: var(--ink);
  padding:0 var(--s3); border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--paper); min-height: var(--tap);
  transition: border-color .12s, box-shadow .12s;
}
input::placeholder, textarea::placeholder { color: var(--ink-3); opacity: 1; }
input:hover:not(:disabled):not(:focus), select:hover:not(:disabled):not(:focus), textarea:hover:not(:disabled):not(:focus) { border-color: var(--ink-3); }
input:disabled, select:disabled, textarea:disabled { background: var(--slab); color: var(--ink-3); cursor: not-allowed; }
select {
  appearance: none; -webkit-appearance: none; padding-right: var(--s6); cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-3) 50%), linear-gradient(135deg, var(--ink-3) 50%, transparent 50%);
  background-position: calc(100% - 19px) 50%, calc(100% - 13px) 50%;
  background-size: 6px 6px, 6px 6px; background-repeat: no-repeat;
}
select:focus { background-image: linear-gradient(45deg, transparent 50%, var(--ink) 50%), linear-gradient(135deg, var(--ink) 50%, transparent 50%); }
input[type=checkbox], input[type=radio] { width: 20px; height: 20px; min-height: 0; padding:0; accent-color: var(--brand); flex: 0 0 auto; }
input[type=color] { padding:var(--s1); width: 52px; }
input[type=file] { padding:var(--s2) var(--s3); min-height: 0; }
input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] { border-color: var(--stake-ink); }
/* One ring for keyboard focus, in ink. It used to be orange on inputs and
 * ink everywhere else, and orange has one meaning on this screen. On the
 * dark bar it reverses so it can be seen. */
input:focus, select:focus, textarea:focus, button:focus-visible, .slate:focus-visible, .cell:focus-visible, .boothv2.open:focus-visible {
  outline: 2px solid var(--ink); outline-offset: 2px;
}
/* A field's ring hugs the field and takes the account's color; it is the
 * only place the brand touches a form. */
input:focus, select:focus, textarea:focus { outline: 2px solid var(--brand); outline-offset: 0; border-color: var(--brand); }
.topbar :focus-visible { outline-color: var(--brand-ink); }
textarea { min-height: 96px; padding:var(--s3); line-height: 1.45; resize: vertical; }
/* One height for every one-line control. A date or time field draws its
 * picker in a taller line box than a text field, so a pair of them sat four
 * pixels off level in the photographs; the box is held to the tap height. */
input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=range]), select { height: var(--tap); }

/* ---------- dialog ---------- */
dialog {
  border: 0; border-radius: var(--r-lg); padding:0; max-width: 560px; width: calc(100% - 32px);
  background: var(--card); color: var(--ink); box-shadow: 0 20px 60px var(--shade-c);
}
dialog::backdrop { background: var(--ink-veil); }
dialog .dh { padding:var(--s4) var(--s5) 0; }
/* As tall as the screen allows, less the title and the buttons. 62vh left a
 * laptop at a conference table scrolling a short box inside a tall dialog. */
dialog .db { padding:var(--s4) var(--s5); max-height: calc(100vh - 210px); overflow: auto; }
dialog .df { padding:var(--s4) var(--s5) var(--s5); display: flex; gap:var(--s3); flex-wrap: wrap; }
dialog .df .grow { flex: 1; }

/* ---------- toast / undo ---------- */
#toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%) translateY(140%);
  background: var(--night); color: var(--chalk); border-radius: var(--r-sm);
  padding:var(--s3) var(--s4); display: flex; align-items: center; gap:var(--s4);
  box-shadow: 0 10px 30px var(--shade-c); z-index: 90; max-width: min(560px, 92vw);
  transition: transform .22s cubic-bezier(.2,.8,.3,1);
}
#toast.up { transform: translateX(-50%) translateY(0); }
/* The question card.
 *
 * The console has one look -- a light panel card -- and this is the surface
 * that has to hold a question, a sentence being typed for a crew, or a couple
 * of fields. It used to be a strip pinned to the bottom of the window that
 * stretched to 92vw the moment it wanted text, which read as a different
 * product. It is a panel now, centred over a dimmed page, with the title, the
 * field and the two answers stacked the way every other panel stacks. */
#decide {
  position: fixed; inset: 0; z-index: 95; display: flex; align-items: center; justify-content: center;
  padding:var(--s5); background: var(--shade-c);
}
#decide[hidden] { display: none; }
#decide .dcard {
  background: var(--card); color: var(--ink); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-lift); padding:var(--s5);
  width: min(520px, 100%); max-height: 86vh; overflow: auto;
  display: flex; flex-direction: column; gap:var(--s4);
}
/* Asking for something typed needs the room a sentence deserves. */
#decide.asks .dcard { width: min(660px, 100%); }
/* The answers, where a panel keeps its actions: the end of the line, the one
 * that happens on the right. */
#decide .dacts { display: flex; justify-content: flex-end; align-items: center; gap:var(--s2); flex-wrap: wrap; }
/* The Korbis AI panel on Home: the same light card as every other panel, with
 * one text field in the product's own field style. */
/* ---------- the composer ----------
 *
 * The shape every assistant uses, because that is the one people already know:
 * the whole box is the field, it grows with what you type, the + and the mic
 * live inside it on the left, and the round send button sits on the right.
 * Enter sends. Files land as chips above the text. Nothing here is novel on
 * purpose -- the muscle memory is the feature. */
.aiblurb { color: var(--ink-2); font-size: var(--t-sm); margin:0 0 var(--s3); }
/* Switched off at the workstation. The box is blocked and says why, rather
 * than disappearing and leaving a client wondering where the tool went. */
/* What it offered back: choices to press, or a link to copy. */
.voiceextra { display: flex; align-items: center; gap:var(--s2); flex-wrap: wrap; margin-top:var(--s2); }
.voiceextra[hidden] { display: none; }
.voiceextra .grow { flex: 1 1 240px; min-width: 0; }
.aioff { margin:var(--s3) 0 0; padding:var(--s2) var(--s3); border-radius: var(--r-sm);
  background: var(--tint-wait); color: var(--wait-ink); font-size: var(--t-sm); font-weight: 600; }
.aioff[hidden] { display: none; }
.aipanel.isoff .composer { background: var(--slab); border-style: dashed; }
.aipanel.isoff .composer .cinput { color: var(--ink-3); }
.aipanel.isoff .aitry { opacity: .5; }
.trychip:disabled, .cbtn:disabled { opacity: .5; cursor: not-allowed; }
.composer { border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--paper);
  padding:var(--s2) var(--s3); transition: border-color .12s, box-shadow .12s; }
.composer:focus-within { border-color: var(--brand); box-shadow: 0 0 0 2px var(--tint-plan); }
.composer.over { border-color: var(--cure); border-style: dashed; }
.composer .cinput { width: 100%; border: 0; background: transparent; resize: none; overflow-y: auto;
  min-height: 0; max-height: 240px; padding:var(--s2) 0; font: inherit; font-size: var(--t-base); color: var(--ink); }
.composer .cinput:focus { outline: none; border: 0; box-shadow: none; }
.cbar { display: flex; align-items: center; gap:var(--s2); flex-wrap: wrap; }
.cbar .grow { flex: 1 1 auto; min-width: 0; }
.cbtn, .csend { width: 36px; height: 36px; min-height: 0; padding:0; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; cursor: pointer; flex: 0 0 auto; }
.cbtn { border: 1px solid var(--line); background: var(--card); color: var(--ink-2); }
.cbtn:hover { border-color: var(--ink-3); color: var(--ink); }
.cbtn.talking { background: var(--cure); border-color: var(--cure); color: var(--cure-on); }
.csend { border: 0; background: var(--brand); color: var(--brand-ink); }
.csend:disabled { background: var(--slab); color: var(--ink-3); cursor: default; }
.cfiles { list-style: none; margin:0 0 var(--s2); padding:0; display: flex; flex-wrap: wrap; gap:var(--s2); }
.cfiles li { display: flex; align-items: center; gap:var(--s2); background: var(--slab); color: var(--ink-2);
  border-radius: var(--r-pill); padding:var(--s1) var(--s3); font-size: var(--t-sm); max-width: 100%; }
.cfiles li span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cfiles li button { border: 0; background: none; color: var(--ink-3); cursor: pointer; padding:0;
  min-height: 0; font: inherit; line-height: 1; }
.cfiles li button:hover { color: var(--stake-ink); }
/* What it can do, in its own words: press one and it fills the box. */
.aitry { display: flex; align-items: center; gap:var(--s2); flex-wrap: wrap; margin-top:var(--s3); }
.trychip { border: 1px solid var(--line); background: var(--card); color: var(--ink-2); cursor: pointer;
  border-radius: var(--r-pill); padding:var(--s1) var(--s3); font: inherit; font-size: var(--t-sm); min-height: 0; }
.trychip:hover { border-color: var(--ink-3); color: var(--ink); }
/* Ask without writing. A tick you set for one question, not a mode to remember. */
.askonly { display: flex; align-items: center; gap:var(--s2); font-size: var(--t-sm); color: var(--ink-2); cursor: pointer; }
.askonly input { width: 18px; height: 18px; min-height: 0; flex: 0 0 auto; }
.sr-only { position: absolute; width: 1px; height: 1px; padding:0; margin:-1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* Decline sits beside Confirm on the pending bar: one button each way. */
.pendacts { margin-left: auto; display: flex; align-items: center; gap:var(--s2); flex-wrap: wrap; }
.pendbar .pendacts .ui-btn { margin-left: 0; }
#voiceMic.talking { background: var(--cure); color: var(--cure-on); }
/* One line per file the assistant read, under the composer. */
.dropresults { list-style: none; margin:var(--s2) 0 0; padding:0; display: flex; flex-direction: column; gap:var(--s1);
  font-size: var(--t-sm); max-height: 160px; overflow: auto; }
.dropresults li.ok::before { content: '✓ '; color: var(--cure); }
.dropresults li.bad::before { content: '✗ '; }
/* Declined, or gone for some other reason: struck through, with nothing left
 * to click. A line that opens onto a record that no longer exists is worse
 * than no line at all. */
.dropresults li.gone { color: var(--ink-3); text-decoration: line-through; text-decoration-color: var(--line); }
.dropresults .ui-btn { margin-left:var(--s2); }
/* What the assistant answered or proposes, set apart from the hint. */
.voicesay { margin-top:var(--s2); padding:var(--s2) var(--s3); border-left: 3px solid var(--cure); background: var(--slab); color: var(--ink); }
.voicesay[hidden] { display: none; }
#decide .dq { display: flex; flex-direction: column; gap:var(--s2); min-width: 0; }
#decide #decideTitle { font-size: var(--t-lg); font-weight: 800; line-height: 1.25; }
#decide #decideText { margin-top:var(--s1); width: 100%; min-height: 96px; font: inherit; font-size: var(--t-base); padding:var(--s3);
  border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--paper); color: var(--ink); resize: vertical; }
#decide #decideText[hidden] { display: none; }
#decide #decideText::placeholder { color: var(--ink-3); }
/* The question's fields are the one field on the one grid, in the strip's
 * own colors: the label in the strip's dim ink, the control on its fill. */
#decide .form { margin-top:var(--s1); width: 100%; }
#decide .form[hidden] { display: none; }
#decide .f > .lab { color: var(--ink-3); }
#decide .note { color: var(--brand-dim); }
#decide .f select, #decide .f input, #decide .f textarea { border-color: var(--line); background: var(--card); color: var(--ink); }
#decide .f select option { color: var(--ink); background: var(--paper); }
#decide .f textarea { min-height: 96px; }
#decide .dq .tiny { color: var(--ink-2); }
/* Left over from when this was a dark bar: white ink on a near-transparent
 * white fill, which on the light card is a white button on a white card. It
 * takes the platform's own quiet button now, like every other Cancel. */
/* The yes is the thing that happens: orange when it is destructive, the go color when it is not. */
#decide #decideYes { background: var(--btn); color: var(--btn-ink); border-color: var(--btn); }
#decide #decideYes.danger { background: var(--stake); color: var(--stake-on); border-color: var(--stake); }
#toast button {
  background: var(--btn); color: var(--btn-ink); border: 0; border-radius: var(--r-xs);
  font: inherit; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
  font-size: var(--t-sm); padding:var(--s2) var(--s3); cursor: pointer;
}

/* ---------- empty states ---------- */
/* An empty screen is an invitation: a mark, what this is, what to add first.
 * No dashed box -- the absence is the point, and a box around nothing reads
 * as something broken. */
.blank {
  text-align: center; padding:var(--s6) var(--s5); color: var(--ink-2);
  display: flex; flex-direction: column; align-items: center; gap:var(--s2); max-width: 440px; margin:0 auto;
}
.blank .mark { width: 56px; height: 56px; border-radius: var(--r-pill); margin-bottom:var(--s2); }
.blank .mark .ico { width: 26px; height: 26px; }
.blank .h { font-size: var(--t-lg); font-weight: 800; color: var(--ink); }
.blank .ui-btn, .blank a.ui-btn { margin-top:var(--s2); }

/* ---------- error banner ---------- */
.err {
  background: var(--tint-err); border: 2px solid var(--stake); color: var(--err-ink);
  border-radius: var(--r); padding:var(--s3) var(--s4); font-weight: 600; margin-bottom:var(--s4);
}
.err[hidden] { display: none; }

@media (max-width: 620px) {
  .wrap { padding:var(--s4) var(--s3) 80px; }
  .form { grid-template-columns: 1fr; }
  h1 { font-size: var(--t-figure); }
  /* A long note under a short title on a phone: the note takes the next line
   * rather than a narrow column beside the title. */
  .panelhead { flex-wrap: wrap; }
  .panelhead .tiny { flex: 1 1 100%; text-align: left; }
  .topbar { gap:var(--s3); padding:0 var(--s3); }
  .brand { font-size: var(--t-xs); letter-spacing: .14em; }
  .tab { padding:var(--s2) var(--s3); font-size: var(--t-sm); }
  .monthgrid { gap:var(--s1); }
  #monthGrid { grid-auto-rows: 84px; }
  .cell { height: 84px; padding:var(--s1); }
}


/* ---------- photos ---------- */
/* Thumbnails are deliberately large. A crew member checking that the photo
   they just took actually landed should not have to squint at a 40px chip. */
.shots { display:flex; gap:var(--s2); flex-wrap:wrap; margin:var(--s3) 0 var(--s1); }
.shot { display:block; width:92px; height:92px; border-radius:var(--r-md); overflow:hidden;
        border:2px solid var(--line); background:var(--slab); flex:0 0 auto; }
.shot img { width:100%; height:100%; object-fit:cover; display:block; }
.shot:hover { border-color:var(--ink); }

.stepwrap { margin-bottom:var(--s3); }
.stepwrap.redo .steprow2 { box-shadow:var(--shadow), 0 0 0 2px var(--stake); }
.addshot { display:block; width:100%; margin-top:var(--s2); padding:var(--s3); border-radius:var(--r-md);
           border:2px dashed var(--line); background:transparent; color:var(--ink-2);
           font:inherit; font-weight:700; font-size:var(--t-base); cursor:pointer; }
.addshot:hover { border-color:var(--ink); color:var(--ink); }
.addshot:disabled { opacity:.55; cursor:default; }


.redonote { margin:var(--s2) 0 0; padding:var(--s3) var(--s3); border-left:4px solid var(--stake);
            background:var(--paper); border-radius:0 var(--r-sm) var(--r-sm) 0; font-size:var(--t-md); }

/* PM review cards */
/* The photo on the left, the words and the two answers on the right, so four
 * of these fit on a screen instead of one. It was a phone-tall picture with
 * a full-width button under it and a page of white beside it. */
.review { border:2px solid var(--ink); border-radius:var(--r-lg); background:var(--paper);
          padding:var(--s4) var(--s4); margin-bottom:var(--s3);
          display:grid; grid-template-columns:200px minmax(0,1fr); grid-template-rows:auto auto 1fr;
          grid-template-areas:"pic head" "pic when" "pic acts"; gap:2px var(--s4); align-items:start; }
.review .rhead { grid-area:head; display:flex; justify-content:space-between; gap:var(--s3); align-items:baseline;
                 flex-wrap:wrap; margin-bottom:2px; }
.review .rhead + .tiny { grid-area:when; }
.review .rtitle { font-weight:800; font-size:var(--t-lg); }
.review .rbig { grid-area:pic; display:flex; gap:var(--s2); flex-wrap:wrap; margin:0; }
.review .rbig img { width:100%; max-width:200px; max-height:240px; object-fit:cover; border-radius:var(--r-md); border:2px solid var(--line); display:block; }
.review .rbig a + a img { max-width:96px; }
.review .acts { grid-area:acts; align-self:end; display:flex; gap:var(--s3); margin-top:var(--s3); flex-wrap:wrap; }
.review .acts button { flex:0 1 240px; padding:var(--s4) var(--s4); border-radius:var(--r-md); border:0;
                       font:inherit; font-weight:800; font-size:var(--t-base); cursor:pointer; }
.review .acts .no { flex:0 1 180px; background:var(--paper); color:var(--ink); border:2px solid var(--ink); }
@media (max-width:700px) { .review { grid-template-columns:1fr; grid-template-areas:"head" "when" "pic" "acts"; } }
/* One answer is the usual one. "Looks good" is the action button; "Send it
 * back" is a plain one beside it. Orange is for work that is blocked, and a
 * photo you would rather see again is not that -- painted orange at full
 * width it out-shouted the approval and read as the thing to press. */
.review .yes { background: var(--btn); color:var(--btn-ink); }


.bar { height:10px; border-radius:var(--r-pill); background:var(--line); overflow:hidden; margin:var(--s2) 0; }
.bar > i { display:block; height:100%; background:var(--cure); color: var(--cure-on); }

.chk { display:flex; gap:var(--s3); align-items:flex-start; margin:0 0 var(--s3); padding:var(--s2) var(--s3);
       border:1px solid var(--line); border-radius:var(--r-md); background:var(--slab);
       font-size:var(--t-md); cursor:pointer; }
.chk input { width:19px; height:19px; margin:1px 0 0; flex:0 0 auto; cursor:pointer; }

/* Unscheduled tray */
.tray { margin:var(--s5) 0 var(--s2); }
.tray .card2 { border:2px dashed var(--line); border-radius:var(--r-md); background:var(--paper);
               padding:var(--s4); margin-bottom:var(--s3); display:flex; gap:var(--s3);
               align-items:center; flex-wrap:wrap; }
.tray .card2 .grow { flex:1 1 240px; }
.tray .card2 .nm { font-weight:800; font-size:var(--t-base); }
.tray .card2 button { padding:var(--s3) var(--s4); border-radius:var(--r-sm); border:0; background: var(--btn-solid);
                      color:var(--btn-solid-ink); font:inherit; font-weight:700; cursor:pointer; }

/* ---------- archived / finished job view ---------- */
.hd.archived { background:var(--ink-2); }
.banner.done { background:var(--cure); color:var(--cure-on); }

.bighours { font:800 var(--t-title)/1 ui-monospace,monospace; margin:var(--s2) 0 2px; letter-spacing:-.02em; }
.bighours span { font-size:var(--t-base); font-weight:700; margin-left:var(--s2); letter-spacing:0; }

.hrow { display:flex; justify-content:space-between; align-items:baseline;
        padding:var(--s2) 0; border-bottom:1px solid var(--line); font-size:var(--t-base); }
.hrow:last-child { border-bottom:0; }
.hrow.total { border-top:2px solid var(--ink); margin-top:var(--s1); font-weight:800; }

ul.arch { list-style:none; margin:0; padding:0; }
ul.arch li { display:flex; gap:var(--s3); padding:var(--s2) 0; border-bottom:1px solid var(--line);
             font-size:var(--t-base); align-items:flex-start; }
ul.arch li:last-child { border-bottom:0; }
ul.arch li .tick { width:22px; flex:0 0 auto; font-weight:800; }
ul.arch li.yes .tick { color:var(--cure); }
ul.arch li.no { color:var(--ink-2); }
ul.arch li.no .tick { color:var(--line); }

.lrow { padding:var(--s2) 0; border-bottom:1px solid var(--line); font-size:var(--t-md); }
.lrow:last-child { border-bottom:0; }

/* ---------- finished strip on the console ---------- */
.fin:hover { border-color:var(--ink); }
.fin .lab { font:700 var(--t-xs)/1 ui-monospace,monospace; letter-spacing:.1em;
            text-transform:uppercase; color:var(--ink-2); }
.fin .nm { font-weight:800; font-size:var(--t-base); margin:var(--s1) 0 var(--s1); }
.fin .mt { font-size:var(--t-sm); color:var(--ink-2); }

/* ---------- crew: name gate, on-the-clock strip, submit ---------- */
.gate { margin-top:var(--s4); }
.gate .ui-btn.lg.go { width:100%; margin-top:var(--s2); }
.gate input { font-size:var(--t-lg); padding:var(--s4); }

.onclock { display:flex; justify-content:space-between; align-items:baseline;
           gap:var(--s3); padding:var(--s3) var(--s4); border-radius:var(--r-md); background: var(--label);
           color:var(--label-ink); margin:0 0 var(--s4); font-size:var(--t-base); }
.onclock .elapsed { font:800 var(--t-lg)/1 ui-monospace,monospace; color:var(--hivis); }

.submitwrap { margin-top:var(--s5); padding-top:var(--s5); border-top:2px solid var(--line); }
.submitwrap .ui-btn.lg { width:100%; }
.ui-btn.lg.submit { font-size:var(--t-lg); padding:var(--s5); }
.ui-btn.lg.submit.off { background:var(--line); color:var(--ink-2); cursor:not-allowed; }
.blockers { margin:0 0 var(--s3); padding:var(--s3) var(--s4); border-left:4px solid var(--stake);
            background:var(--paper); border-radius:0 var(--r-sm) var(--r-sm) 0; font-size:var(--t-md); font-weight:700; }

/* ---------- step editor ---------- */
.steplist { display:flex; flex-direction:column; gap:var(--s2); margin-bottom:var(--s2); }
.steprow { display:flex; gap:var(--s2); align-items:center; }
.steprow .stitle { flex:1; min-width:0; padding:var(--s3) var(--s3); border:1px solid var(--line);
                   border-radius:var(--r-sm); font:inherit; font-size:var(--t-base); background:var(--paper); }
.steprow .stitle:focus { outline:2px solid var(--ink); outline-offset:-1px; }
.steprow .scam { display:inline-flex; align-items:center; gap:var(--s2); padding:var(--s3) var(--s3);
                 border:1px solid var(--line); border-radius:var(--r-sm); background:var(--paper);
                 color:var(--ink-2); font:inherit; font-size:var(--t-xs); font-weight:700;
                 cursor:pointer; flex:0 0 auto; }
.steprow .scam:hover { border-color:var(--ink); color:var(--ink); }
.steprow .sdel { flex:0 0 auto; width:38px; height:41px; border:1px solid var(--line);
                 border-radius:var(--r-sm); background:var(--paper); color:var(--ink-2); font-size:var(--t-lg);
                 line-height:1; cursor:pointer; }
.steprow .sdel:hover { border-color:var(--stake); color:var(--stake-ink); }
.addstep { width:100%; padding:var(--s3); border:2px dashed var(--line); border-radius:var(--r-md);
           background:transparent; color:var(--ink-2); font:inherit; font-weight:700;
           cursor:pointer; }
.addstep:hover { border-color:var(--ink); color:var(--ink); }

@media (max-width:560px) {
  .steprow .scam .lbl { display:none; }
}

/* ---------- jobs screen ---------- */
.jsearch { width:100%; padding:var(--s4) var(--s4); border:1px solid var(--line); border-radius:var(--r-md);
           font:inherit; font-size:var(--t-base); background:var(--paper); margin-bottom:var(--s4); }
.jsearch:focus { outline:2px solid var(--ink); outline-offset:-1px; }

.jobrow { display:flex; gap:var(--s4); align-items:flex-start; flex-wrap:wrap;
          padding:var(--s4); border:1px solid var(--line); border-radius:var(--r-md);
          background:var(--paper); margin-bottom:var(--s3); }
.jobrow.closed { background:transparent; border-style:dashed; }
.jobrow .jmain { flex:1 1 260px; min-width:0; }
.jobrow .n { font-weight:800; font-size:var(--t-lg); }
.jobrow .jside { flex:0 0 auto; text-align:right; }
.jobrow .c { font:700 var(--t-sm)/1 ui-monospace,monospace; letter-spacing:.08em; color:var(--ink-2); }
.jobrow .jacts { display:flex; gap:var(--s2); flex:0 0 auto; align-items:center; flex-wrap:wrap; }
.jbtn { padding:var(--s3) var(--s4); border:1px solid var(--line); border-radius:var(--r-sm); background:var(--paper);
        font:inherit; font-size:var(--t-sm); font-weight:700; cursor:pointer; }
.jbtn:hover { border-color:var(--ink); }
.jbtn.dark { background: var(--btn-solid); color:var(--btn-solid-ink); border-color:var(--ink); }

.pills { display:flex; gap:var(--s2); flex-wrap:wrap; margin-top:var(--s2); }


.donefold { margin-top:var(--s4); border-top:2px solid var(--line); padding-top:var(--s4); }
.donefold summary { cursor:pointer; font-weight:800; font-size:var(--t-base); padding:var(--s2) 0;
                    color:var(--ink-2); }
.donefold summary:hover { color:var(--ink); }
.donefold[open] summary { margin-bottom:var(--s3); color:var(--ink); }

.histrow { display:block; width:100%; text-align:left; padding:var(--s4); margin-bottom:var(--s2);
           border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper);
           font:inherit; cursor:pointer; }
.histrow:hover { border-color:var(--ink); }
.histrow .hd2 { display:flex; gap:var(--s2); align-items:baseline; margin-bottom:var(--s1); }

/* ============================================================================
   DESIGN SYSTEM — added in the polish pass.
   Everything below is a reusable component. Screens should compose these
   rather than styling one-off elements, so a control looks and behaves the
   same wherever it appears. This is what makes the app feel like one product
   instead of a set of pages, and it is what a future Asset Manager screen
   should build from without writing new CSS.
   ========================================================================= */

/* ---- toast: was visible as a black sliver when idle ---- */
#toast { opacity: 0; pointer-events: none; transition: transform .22s cubic-bezier(.2,.8,.3,1), opacity .18s; }
#toast.up { opacity: 1; pointer-events: auto; }

/* ---- buttons: one scale, three intents ---- */
.ui-btn { display:inline-flex; align-items:center; justify-content:center; gap:var(--s2);
  padding:var(--s3) var(--s4); min-height:var(--tap); border:1px solid var(--line); border-radius:var(--r-sm);
  background:var(--paper); color:var(--ink); font:inherit; font-size:var(--t-md); font-weight:700;
  cursor:pointer; white-space:nowrap; transition:border-color .12s, background .12s, color .12s; }
.ui-btn:hover { border-color:var(--ink-3); background:var(--slab); }
a.ui-btn { text-decoration:none; }
.ui-btn:focus-visible { outline:2px solid var(--ink); outline-offset:2px; }
.ui-btn:disabled { opacity:.45; cursor:not-allowed; }
.ui-btn.go { background: var(--btn); border-color:var(--ink); color:var(--btn-ink); }
.ui-btn.danger { color:var(--stake-ink); }
.ui-btn.danger:hover { border-color:var(--stake); background:var(--tint-stop); color: var(--stop-ink); }
.ui-btn.sm { padding:var(--s2) var(--s3); min-height:36px; font-size:var(--t-sm); }
/* The page's largest action: a start, a save, the one thing on a screen. */
.ui-btn.lg { padding:var(--s3) var(--s5); min-height:48px; font-size:var(--t-base); font-weight:700; letter-spacing:0; }
.ui-btn.quiet { background:var(--paper); color:var(--ink); border-color:var(--line); }
.ui-btn.quiet:hover { background:var(--slab); border-color:var(--ink-3); }
/* A small button is still a target. On a touch screen it gets the full 44,
   because a tablet in gloves is exactly where mis-taps cost a morning. */
@media (pointer: coarse) {
  .ui-btn.sm, .tab, .seg, button { min-height: var(--tap); }
}
.ui-btn.icon { padding:0; width:38px; min-height:38px; }

.ui-btns { display:flex; gap:var(--s2); flex-wrap:wrap; align-items:center; }

/* ---- switch: the single toggle used everywhere ---- */
.ui-switch { display:inline-flex; align-items:center; gap:var(--s3); cursor:pointer;
  font-size:var(--t-sm); font-weight:700; color:var(--ink-2); user-select:none; }
.ui-switch input { position:absolute; opacity:0; width:0; height:0; }
.ui-switch .track { position:relative; width:44px; height:26px; border-radius:var(--r-pill);
  background:var(--line); border:1px solid var(--line); flex:0 0 auto; transition:background .16s; }
.ui-switch .track::after { content:''; position:absolute; top:2px; left:2px; width:20px; height:20px;
  border-radius:50%; background:var(--paper); box-shadow:0 1px 3px var(--shade-c); transition:transform .16s; }
.ui-switch input:checked + .track { background: var(--accent); border-color:var(--ink); color:var(--accent-ink); }
.ui-switch input:checked + .track::after { transform:translateX(18px); }
.ui-switch input:focus-visible + .track { outline:2px solid var(--ink); outline-offset:2px; }
.ui-switch input:checked ~ .swlabel { color:var(--ink); }

/* ---- chips / status ---- */


/* ---- the card ----
 * One card for a job, a place, a person, a company, a tool:
 *
 *   .ch   the head -- .cm (the name as the way in, the meta lines under it)
 *         on the left, .cs (its standing: a date, a number, a state) right
 *   .chips  what it carries, as chips
 *   .ui-btns  what you can do, small, the destructive one at the far end
 *
 * The lists are one grid (.cards): one column, two on a wide monitor. */
.ui-card { border:0; border-radius:var(--r-md); background:var(--paper); padding:var(--s4); min-width:0; box-shadow:var(--shadow); }
/* Inside a panel a card is a well: the canvas color, no edge, no shadow. */
.panel .ui-card, .look .ui-card, .sec .ui-card { background:var(--slab); box-shadow:none; }
.panel .ui-card:hover { background:var(--slab-deep); }
.ui-card + .ui-card { margin-top:var(--s3); }
/* The booth's camera: the picture, then the booth's own words under it. */
/* The one opened large, in the same frame the tiles use: the shape and the
   empty color belong to the frame, the picture sits in it. */
.cam .fr { position:relative; display:block; width:100%; max-width:800px; aspect-ratio:16 / 9;
  background:var(--ink-haze); border-radius:var(--r-md); margin-top:var(--s3); overflow:hidden; }
.cam .fr img { display:block; width:100%; height:100%; object-fit:contain; }
.cam .fr img:not([src]) { visibility:hidden; }
#boothWatch { margin-bottom:var(--s4); }
/* An exact live picture of the booth's own screen -- the booth's board in a
 * frame, refreshing itself. Not scaled cleverly; a plain 16:10 window. */
.boothscreen { margin:var(--s3) 0; border-radius:var(--r-md); overflow:hidden; background:var(--ink-haze); border:1px solid var(--line); }
.boothframe { display:block; width:100%; aspect-ratio:16 / 9; border:0; background:var(--ink); }
/* A pane of the booth's dashboard. It carried a rule and a gap along its top
 * from when all five were stacked down the card; under the tool strip that
 * rule was a line drawn across the middle of nothing. */
.boothsec { display:flex; flex-direction:column; gap:var(--s3); }
.boothsec h3 { font-size:var(--t-xs); text-transform:uppercase; letter-spacing:.08em; color:var(--ink-3); font-weight:800; margin:0; }
.boothsec .line { display:flex; gap:var(--s2); align-items:center; }
.boothsec .line > .grow, .boothsec .ui-field.grow { flex:1 1 auto; min-width:0; }
.boothsec .ui-btns { flex-wrap:wrap; }
/* Hold-to-talk reads as a press-and-hold: a filled key (its color comes from
 * the .primary family) big enough for a thumb; .ui-btn.talking turns it to the
 * stop pairing while the mic is live. */
.holdtalk { font-weight:800; padding:var(--s2) var(--s4); border-radius:var(--r-pill);
  min-height:var(--tap); touch-action:none; user-select:none; }
/*
 * The booth's cameras, on the card, before any tab is pressed.
 *
 * One grid, uniform tiles: a booth on a recorder has as many cameras as the
 * recorder has ports, and a ragged strip of different-sized pictures is
 * harder to read than a wall of the same rectangle. The tiles fill the row
 * they are given, so two cameras are two wide pictures and eight are eight
 * small ones without any of them being a special case.
 */
.boothcams { display:grid; gap:var(--s3); margin:var(--s3) 0 var(--s4);
  /* Bounded at both ends. Left to stretch, one camera became a billboard
     across the whole card and two filled the screen before the controls; the
     upper bound keeps a wall of cameras a wall, whether there are two or
     eight, and one tile is opened large by pressing it. */
  grid-template-columns:repeat(auto-fit, minmax(230px, 340px)); justify-content:start; }
.boothcams:empty { display:none; margin:0; }
.camtile { margin:0; min-width:0; }
/* The frame holds the shape and the empty color; the picture sits in it. A
   tile with nothing in it yet is then a calm rectangle instead of a broken
   picture, and it does not change size when the stream arrives. */
.camtile .fr { position:relative; display:block; width:100%; aspect-ratio:16 / 9;
  background:var(--ink-haze); border-radius:var(--r-md); overflow:hidden; }
.camtile img { display:block; width:100%; height:100%; object-fit:contain; cursor:zoom-in; }
.camtile img:not([src]) { visibility:hidden; }
/* Stacked, not a row. Side by side, the name and the state competed for a
   narrow tile and the name lost -- eight cameras all reading "Bay 3 · c…".
   The name is the thing being looked for, so it gets the line. */
.camtile figcaption { margin-top:var(--s1); font-size:var(--t-sm); min-width:0; }
.camtile figcaption .nm { display:block; font-weight:800; color:var(--ink);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.camtile figcaption .st { display:block; color:var(--ink-3); font-size:var(--t-xs);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Past the sixth, a camera waits to be asked rather than opening another
   encoder on a machine nobody is standing next to. */
.camtile-go { position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); }
.boothcam { margin-top:var(--s2); }
.boothaudio { margin-top:var(--s2); }
.boothaudio audio { width:100%; height:36px; }
.ui-btn.talking { background:var(--tint-stop); color:var(--stop-ink); }
.ui-btn.xs { font-size:var(--t-xs); padding:var(--s1) var(--s2); }
[data-boothsharelink] code { font-family:var(--mono); font-size:var(--t-xs); word-break:break-all; }
.jobsrow { display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap; }
/* ---- the booth tab, v2: executive-ready ---- */
.boothv2 { padding:var(--s4) var(--s5) var(--s5); }
/* The Home booth card is a doorway into the Booth tab: it reads as clickable
 * and lifts on hover, the same language as a .slate. The full controls live
 * only in the Booth tab, so this card stays a summary. */
.boothv2.open { cursor:pointer; transition:border-color .12s, box-shadow .12s, transform .12s; }
.boothv2.open:hover { border-color:var(--ink-3); box-shadow:var(--shadow-lift); transform:translateY(-1px); }
.boothopen-cue { margin:var(--s3) 0 0; color:var(--ink-3); font-size:var(--t-sm); }
.boothhead { display:flex; align-items:center; gap:var(--s3); }
.boothglyph { flex:0 0 auto; width:44px; height:44px; border-radius:var(--r-md); background:var(--brand); color:var(--brand-ink);
  display:flex; align-items:center; justify-content:center; }
.boothglyph .ico { width:24px; height:24px; }
.boothhead .boothid { flex:1 1 auto; min-width:0; }
.boothhead .nm { font-weight:800; font-size:var(--t-lg, 1.05rem); }
.boothhead .cs { color:var(--ink-3); font-size:var(--t-sm); }
.lamp { flex:0 0 auto; font-size:var(--t-xs); font-weight:800; text-transform:uppercase; letter-spacing:.06em;
  padding:var(--s1) var(--s3); border-radius:var(--r-pill); background:var(--slab); color:var(--ink-3); }
.lamp.on { background:var(--cure); color:var(--cure-on); }
/* the assigned job and how far along it is today */
.boothjob { margin-top:var(--s3); display:flex; flex-direction:column; gap:var(--s1); }
.boothjob:empty { display:none; }
.jobrow { display:flex; align-items:center; gap:var(--s2); }
.jobname { font-weight:700; }
.progress { height:8px; border-radius:var(--r-pill); background:var(--slab-deep); overflow:hidden; }
.progress > span { display:block; height:100%; background:var(--cure); color:var(--cure-on); border-radius:var(--r-pill); transition:width .4s ease; }
/* The booth's tool strip: one row of real buttons, one pane at a time. The
 * card used to stack all five and run off the bottom of the screen. */
.boothtabs { display:flex; gap:var(--s2); flex-wrap:wrap; margin:var(--s3) 0 var(--s4); }
.boothtab { display:flex; align-items:center; gap:var(--s2); cursor:pointer; font:inherit;
  font-size:var(--t-sm); font-weight:700; color:var(--ink-2); background:var(--card);
  border:1px solid var(--line); border-radius:var(--r-pill); padding:var(--s2) var(--s3); min-height:0; }
.boothtab .ico { width:16px; height:16px; }
.boothtab:hover { border-color:var(--ink-3); color:var(--ink); }
.boothtab.on { background:var(--brand); border-color:var(--brand); color:var(--brand-ink); }
.boothsec[hidden] { display:none; }
/* A pane keeps its own room so switching tools does not make the card jump. */
.boothv2 .boothsec { min-height:180px; }
/* section heads carry an icon; the screen head carries the mode switch */
.boothsec-h { display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap; }
.boothsec-h .ico { width:18px; height:18px; color:var(--ink-3); flex:0 0 auto; }
.boothsec-h > h3 { margin:0; }
.boothsec-h .boothseg { margin-left:auto; }
/* the segmented control -- Communication vs Job tasks */
.boothseg { display:inline-flex; background:var(--slab); border:1px solid var(--line); border-radius:var(--r-pill); padding:var(--s1); }
.boothseg-b { border:0; background:transparent; color:var(--ink-2); font:inherit; font-size:var(--t-sm); font-weight:700;
  padding:var(--s1) var(--s3); border-radius:var(--r-pill); cursor:pointer; min-height:32px; }
.boothseg-b.on { background:var(--tab-on); color:var(--tab-on-ink); }
/* ---- putting something on the screen ----
 *
 * Two named groups -- something new, or something you kept -- and then, set
 * apart from both, what happens to whatever is already up. Unlabelled rows of
 * small gray buttons is what this was, and it read as unfinished because
 * nothing said which button belonged with which. */
.commonly { display:flex; flex-direction:column; gap:var(--s4); }
.boothgroups { display:grid; gap:var(--s4); grid-template-columns:repeat(auto-fit, minmax(260px, 1fr)); align-items:start; }
.boothgroup { display:flex; flex-direction:column; gap:var(--s2); min-width:0; }
.boothgroup .glab { font-size:var(--t-xs); text-transform:uppercase; letter-spacing:.08em;
  color:var(--ink-3); font-weight:800; }
.boothgroup .ui-btn .ico { width:15px; height:15px; }
/* What happens to what is up already, on its own line under a rule. */
.boothfoot { display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap;
  padding-top:var(--s3); border-top:1px solid var(--line); }
.boothfoot .grow { flex:1 1 auto; }

/* what each mode shows */
.mode-comm .tasksonly { display:none; }
.mode-tasks .commonly { display:none; }
.tasksonly { margin:0; }
.ui-card .ch { display:flex; justify-content:space-between; align-items:flex-start;
  gap:var(--s4); flex-wrap:wrap; margin-bottom:var(--s3); }
.ui-card .cm { min-width:0; flex:1 1 200px; }
.ui-card .cs { flex:0 0 auto; text-align:right; font-size:var(--t-sm); color:var(--ink-2); display:flex; flex-direction:column; align-items:flex-end; gap:var(--s1); }
.ui-card .ct { font-weight:800; font-size:var(--t-base); }
.ui-card .chips { display:flex; gap:var(--s2); flex-wrap:wrap; margin-bottom:var(--s3); }
.ui-card > .ui-btns .grow { flex:1; }
.ui-card.is-closed { background:transparent; border-style:dashed; }
.ui-card.is-late { border-color:var(--stake); }
.cards { display:grid; gap:var(--s3); }
.cards > .ui-card + .ui-card { margin-top:0; }
@media (min-width: 1700px) { .cards { grid-template-columns: 1fr 1fr; align-items:start; } }

/* ---- the toolbar: the search box, then the filters, the same widths on every list ---- */
.ui-toolbar { display:flex; gap:var(--s3); flex-wrap:wrap; align-items:center; margin-bottom:var(--s4); }
.ui-toolbar .grow { flex:1 1 240px; }
.ui-toolbar > select.ui-field, .ui-toolbar > input[type=date] { flex:0 0 200px; width:auto; }
/* The toolbar's field is the one control; a select in a toolbar draws its own arrow. */
select.ui-field { cursor:pointer; padding-right: var(--s6); appearance:none;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235E5A53' stroke-width='2.5'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat:no-repeat; background-position:right 11px center; background-size:15px; }

/* ---- file list ---- */
.ui-files { display:flex; flex-direction:column; gap:var(--s2); }
.ui-file { display:flex; align-items:center; gap:var(--s3); padding:var(--s3) var(--s3);
  border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper); }
.ui-file .fi { flex:0 0 auto; width:34px; height:34px; border-radius:var(--r-sm); background:var(--slab);
  display:flex; align-items:center; justify-content:center; font:800 var(--t-xs)/1 ui-monospace,monospace;
  color:var(--ink-2); text-transform:uppercase; }
.ui-file .fn { flex:1; min-width:0; }
.ui-file .fn b { display:block; font-size:var(--t-md); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ui-file .fn span { font-size:var(--t-xs); color:var(--ink-2); }
.ui-drop { border:2px dashed var(--line); border-radius:var(--r-md); padding:var(--s4); text-align:center;
  color:var(--ink-2); cursor:pointer; font-size:var(--t-md); font-weight:700; background:transparent; width:100%; }
.ui-drop:hover, .ui-drop.over { border-color:var(--ink); color:var(--ink); background:var(--slab); }

/* ---- section heading ---- */
.ui-sec { margin:var(--s5) 0 var(--s3); }
.ui-sec h2 { margin:0; font-size:var(--t-base); letter-spacing:.06em; text-transform:uppercase; }
.ui-sec p { margin:var(--s1) 0 0; font-size:var(--t-sm); color:var(--ink-2); }

/* ---- responsive ---- */
@media (max-width:760px) {
  .ui-toolbar { flex-direction:column; align-items:stretch; }
  /* In a column the filters' 200px is a height, not a width. */
  .ui-toolbar .grow, .ui-toolbar > select.ui-field, .ui-toolbar > input[type=date] { flex:0 0 auto; width:100%; }
  .ui-btns { width:100%; }
  .ui-btns .ui-btn { flex:1; }
}

/* ---- finished cards ---- */
.finished { display:grid; gap:var(--s3); grid-template-columns:repeat(auto-fill,minmax(260px,1fr)); }
.fincard { display:block; text-align:left; font:inherit; cursor:pointer; padding:var(--s4);
  border:1px solid var(--line); border-left:5px solid var(--cure); border-radius:var(--r-md);
  background:var(--paper); transition:border-color .12s, box-shadow .12s; }
.fincard:hover { border-color:var(--ink); border-left-color:var(--cure);
  box-shadow:0 3px 12px var(--shade-a); }
.fincard .fh { display:flex; justify-content:space-between; align-items:center; margin-bottom:var(--s2); }
.fincard .fn2 { font-weight:800; font-size:var(--t-base); line-height:1.25; }
.fincard .fs { font-size:var(--t-sm); color:var(--ink-2); margin:var(--s1) 0 var(--s3);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.fincard .fmeta { display:flex; gap:var(--s2); flex-wrap:wrap; font-size:var(--t-xs); color:var(--ink-2); }
.fincard .fmeta span { padding:var(--s1) var(--s2); background:var(--slab); border-radius:var(--r-pill); font-weight:700; }


/* ---- step editor rows ---- */
.steprow { display:flex; flex-direction:column; gap:var(--s2); padding:var(--s3);
  border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper); }
.steprow .sline { display:flex; gap:var(--s2); align-items:center; }
.steprow .stitle { flex:1; min-width:0; }


/* ---- shelf card wrapper ----
   The card is a <button>, and a form cannot legally nest inside one. So the
   wrapper carries the card's frame and the button sits flush inside it, which
   puts the quick-add row visually inside the tablet where it belongs. */
.slatewrap { display:flex; flex-direction:column; border:1px solid var(--line);
  border-radius:var(--r-md); background:var(--paper); overflow:hidden;
  transition:border-color .12s, box-shadow .12s; }
.slatewrap:hover { border-color:var(--ink); box-shadow:0 3px 14px var(--shade-a); }
.slatewrap.empty { background:transparent; border:2px dashed var(--line); }
.slatewrap.blocked { border-color:var(--stake); }
.slatewrap > .slate { border:0 !important; border-radius:0 !important; background:transparent !important;
  box-shadow:none !important; width:100%; }
.slatewrap > .slate:hover { box-shadow:none !important; }


/* ---- work order: unlocked editing ---- */
.wo-scope { margin-bottom:var(--s3); font-weight:700; }
.wo-steps { display:flex; flex-direction:column; gap:var(--s2); margin-bottom:var(--s2); }
.wo-step { display:flex; align-items:center; gap:var(--s2); padding:var(--s2) var(--s2); border-radius:var(--r-sm);
  background:var(--slab); }
.wo-step.done { opacity:.7; }
.wo-step .tick { width:16px; flex:0 0 auto; font-weight:800; color:var(--cure); font-size:var(--t-md); }
.wo-step .wtitle { flex:1; min-width:0; padding:var(--s2) var(--s3); border:1px solid transparent;
  border-radius:var(--r-sm); background:var(--paper); font:inherit; font-size:var(--t-md); }
.wo-step .wtitle:focus { outline:none; border-color:var(--ink); }
/* Wide enough for its own word. At 36px "Photo" was clipped to "Pho". */
.cambtn { flex:0 0 auto; min-width:36px; height:36px; padding:0 var(--s3); border:1px solid var(--line); border-radius:var(--r-sm);
  background:var(--paper); font:inherit; font-size:var(--t-xs); font-weight:800; letter-spacing:.04em; line-height:1; cursor:pointer; opacity:.4;
  filter:grayscale(1); transition:opacity .12s, filter .12s, background .12s; }
.cambtn:hover { opacity:.8; }
.cambtn.on { opacity:1; filter:none; background: var(--btn); border-color:var(--ink); color:var(--btn-ink); }
.delbtn { flex:0 0 auto; width:36px; height:36px; border:0; background:transparent;
  color:var(--ink-2); font-size:var(--t-lg); line-height:1; cursor:pointer; border-radius:var(--r-sm); }
.delbtn:hover { color:var(--stake-ink); background:var(--paper); }
.wo-new { border-style:dashed; }
.arch .cam { font-size:var(--t-xs); opacity:.75; }

/* ---- work order history fold ---- */
.wo-hist { margin:var(--s4) 0 var(--s1); border-top:1px solid var(--line); padding-top:var(--s3); }
.wo-hist summary { cursor:pointer; font-weight:800; font-size:var(--t-sm); letter-spacing:.05em;
  text-transform:uppercase; color:var(--ink-2); padding:var(--s1) 0; }
.wo-hist summary:hover { color:var(--ink); }
.wo-hist[open] summary { margin-bottom:var(--s3); color:var(--ink); }
.wo-hist .histrow { padding:var(--s3) var(--s3); margin-bottom:var(--s2); }

/* ---- tighter dialogs: less air, same clarity ---- */
dialog .db { padding-top:var(--s4); }
dialog .f { margin-bottom:var(--s3); }

/* ============================================================================
   WORK ORDER SCREEN
   Three columns on a laptop: what they are doing, who and how long, and how
   they get in. The PM should be able to answer any question about a crew
   without scrolling. Collapses to one column on a tablet or phone.
   ========================================================================= */

@media (max-width:1180px) { .wo-grid { grid-template-columns:minmax(0,1.3fr) minmax(0,1fr); }
  .wo-col.codes { grid-column:1 / -1; display:flex; gap:var(--s4); flex-wrap:wrap; align-items:flex-start; }
  .wo-col.codes > * { flex:1 1 220px; } }
@media (max-width:780px) { .wo-grid { grid-template-columns:1fr; }
  .wo-col.codes { flex-direction:column; } }

.wo-col { min-width:0; }
.wo-col.main { border-right:1px solid var(--line); padding-right:var(--s5); }
@media (max-width:780px) { .wo-col.main { border-right:0; padding-right:0; } }

.wo-scopeline { margin:0 0 var(--s4); font-size:var(--t-lg); font-weight:800; line-height:1.3; }
.wo-progress { margin:var(--s4) 0 var(--s1); }

.wo-facts { display:grid; grid-template-columns:1fr 1fr; gap:var(--s3); padding:var(--s4);
  background:var(--slab); border-radius:var(--r-md); }
.wo-facts div { display:flex; flex-direction:column; gap:2px; min-width:0; }
.wo-facts span { font-size:var(--t-xs); font-weight:800; letter-spacing:.07em; text-transform:uppercase;
  color:var(--ink-2); }
.wo-facts b { font-size:var(--t-base); overflow:hidden; text-overflow:ellipsis; }

.wo-log { font-size:var(--t-sm); color:var(--ink-2); max-height:230px; overflow:auto; }
.wo-log > div { padding:var(--s2) 0; border-bottom:1px solid var(--line); }

.wo-job { padding:var(--s4); border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper);
  margin-bottom:var(--s4); }
.wo-job b { display:block; font-size:var(--t-base); margin:var(--s1) 0 2px; }

.wo-qr { text-align:center; padding:var(--s4); border:1px solid var(--line); border-radius:var(--r-md);
  background:var(--paper); margin-bottom:var(--s4); }
.wo-qr img { width:100%; max-width:190px; display:block; margin:var(--s2) auto var(--s2); }
.wo-qr .code { font:800 var(--t-figure)/1 ui-monospace,monospace; letter-spacing:.14em; margin:var(--s2) 0 var(--s1); }

/* ============================================================================
   WORK ORDER PANEL — opens under the shelf, never replaces it
   ========================================================================= */
#woPanel { margin:var(--s2) 0 var(--s5); padding:var(--s5); border:1px solid var(--ink);
  border-radius:var(--r-lg); background:var(--paper); box-shadow:0 6px 26px var(--shade-a); }
/* The work order is a record opened in place: the record's head, ruled off. */
#woPanel .head { margin-bottom:var(--s4); padding-bottom:var(--s4); border-bottom:1px solid var(--line); }

/* the card you are looking at is obvious in the row */
.slatewrap.picked { border-color:var(--ink); box-shadow:0 0 0 3px var(--ink); }

/* two columns: what they are doing, and who/how long */
.wo-grid { display:grid; gap:var(--s5); align-items:start;
  grid-template-columns:minmax(0,1.5fr) minmax(0,1fr); }
@media (max-width:860px) { .wo-grid { grid-template-columns:1fr; }
  .wo-col.main { border-right:0; padding-right:0; } }

/* access strip: job identity + both codes, side by side */
.wo-access .acc-job { flex:1 1 260px; min-width:0; }
.wo-access .acc-job b { display:block; font-size:var(--t-base); margin:var(--s1) 0 2px; }
.wo-access .acc-qr { flex:0 0 auto; width:174px; text-align:center; padding:var(--s3);
  border:1px solid var(--line); border-radius:var(--r-md); background:var(--slab); }
.wo-access .acc-qr img { width:140px; height:140px; display:block; margin:var(--s2) auto var(--s2);
  background:var(--paper); border-radius:var(--r-sm); }
.wo-access .acc-qr .code { font:800 var(--t-lg)/1 ui-monospace,monospace; letter-spacing:.12em; margin:var(--s1) 0 var(--s1); }
@media (max-width:520px) { .wo-access .acc-qr { width:100%; } }

/* ---- shelf stays put while the work order is read ---- */
@media (min-width:900px) {
  .rail { position:sticky; top:var(--bar-h); z-index:20; background:var(--slab);
    padding:var(--s3) 0 var(--s3); box-shadow:0 10px 18px -14px var(--shade-c); }
}

/* ---- paperwork strip: the first thing in a work order ---- */
.wo-paper { padding:var(--s4) var(--s4); margin-bottom:var(--s4); border:1px solid var(--line);
  border-radius:var(--r-md); background:var(--slab); }
.paper-head { display:flex; align-items:center; gap:var(--s3); flex-wrap:wrap; }
.paper-list { display:flex; gap:var(--s2); flex-wrap:wrap; margin-top:var(--s3); }
.paper-chip { display:inline-flex; align-items:center; gap:var(--s2); max-width:250px;
  min-height:36px; padding:var(--s2) var(--s3); border:1px solid var(--line); border-radius:var(--r-pill); background:var(--paper);
  text-decoration:none; color:var(--ink); font-size:var(--t-sm); font-weight:700; }
.paper-chip:hover { border-color:var(--ink); }
.paper-chip .ext { font:800 var(--t-xs)/1 ui-monospace,monospace; text-transform:uppercase;
  padding:var(--s1) var(--s1); border-radius:var(--r-xs); background: var(--label); color:var(--label-ink); }
.paper-chip .nm { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* The note to the crew is the one entry line. */
.paper-note { margin:var(--s3) 0 0; }

/* What the crew is reading right now, and the button that takes it down. It is
   only ever in the markup when something is pinned, so there is no empty state
   to look at on the hundreds of days nobody sent a message. */
.paper-pinned { margin:var(--s4) 0 0; padding-top:var(--s4); border-top:1px solid var(--line); }
.pin-list { display:flex; flex-direction:column; gap:var(--s2); margin-top:var(--s3); }
.pin-msg { padding:var(--s2) var(--s3); border:1px solid var(--line); border-left:3px solid var(--accent);
  border-radius:var(--r-sm); background:var(--paper); }
.pin-msg p { margin:0; font-size:var(--t-sm); }

/* ---- access strip: identity + code buttons, one line ---- */
.wo-access { display:flex; gap:var(--s4); flex-wrap:wrap; align-items:center;
  margin-top:var(--s5); padding-top:var(--s4); border-top:1px solid var(--line); }
.wo-access .acc-job { flex:1 1 240px; min-width:0; display:flex; flex-direction:column; gap:2px; }
.wo-access .acc-job b { font-size:var(--t-base); }

.jsplit { margin-top:var(--s4); padding-top:var(--s4); border-top:2px solid var(--line); }
.addkinds { margin-top:var(--s3); }
.addtablet { margin-top:var(--s3); }

/* ============================================================================
   CREW SCREEN — read top down: what the office said, what to do, then buttons.
   Built for a phone in sunlight, held by someone in gloves who has been on
   site for six hours. Big targets, high contrast, nothing decorative.
   ========================================================================= */

/* messages from the office — the most important thing on the page */
.msgs { border:2px solid var(--ink); border-radius:var(--r-md); background:var(--paper);
  padding:var(--s4) var(--s4); margin:0 0 var(--s4); }
.msgs h3 { margin:0 0 var(--s2); font-size:var(--t-xs); letter-spacing:.09em; text-transform:uppercase;
  color:var(--ink-2); }
.msgs .msg { padding:var(--s2) 0; border-bottom:1px solid var(--line); }
.msgs .msg:last-child { border-bottom:0; padding-bottom:0; }
.msgs .msg p { margin:0 0 var(--s1); font-size:var(--t-base); line-height:1.4; font-weight:600; }
.msgs .msg span { font-size:var(--t-xs); color:var(--ink-2); }

.manuals { margin:0 0 var(--s4); border:1px solid var(--line); border-radius:var(--r-md);
  background:var(--paper); padding:var(--s3) var(--s4); }
.manuals summary { cursor:pointer; font-weight:800; font-size:var(--t-base); }
.manuals[open] summary { margin-bottom:var(--s3); }

.steps-h { margin:var(--s5) 0 var(--s3); }

/* one row per step: a big tick target, and a camera only where one is required */
/* A step and its camera are one box: the words, the chip that says what the
 * step is waiting on under them, and the camera on the right edge behind a
 * hairline. Two boxes side by side read as two things to do. */
.steprow2 { display:flex; gap:0; align-items:stretch; background:var(--card); border-radius:var(--r-md); box-shadow:var(--shadow); overflow:hidden; }
.steprow2 .step { flex:1; min-width:0; border:0; border-radius:0; margin:0; background:transparent; box-shadow:none; }
.steprow2 .step .txt { display:flex; flex-direction:column; align-items:flex-start; gap:var(--s1); min-width:0; }
.steprow2 .step .txt .rev { margin:0; }
.shotbtn { flex:0 0 auto; width:64px; border:0; border-left:1px solid var(--line); border-radius:0;
  background:var(--paper); color:var(--ink-2); font-size:var(--t-figure); line-height:1; cursor:pointer; }
.shotbtn:hover { background:var(--slab); color:var(--ink); }
.shotbtn svg { display:block; margin:0 auto; }
.shotbtn.has { background: var(--btn); color:var(--btn-ink); }
.shotbtn:disabled { opacity:.5; }

.actions { display:flex; flex-direction:column; gap:var(--s3); margin:var(--s5) 0 var(--s2);
  padding-top:var(--s5); border-top:2px solid var(--line); }
.actions .ui-btn.lg { width:100%; }
.actions .ui-btn.lg.go { font-size:var(--t-lg); padding:var(--s5); }

.whoami { margin:var(--s4) 0 var(--s6); text-align:center; font-size:var(--t-sm); color:var(--ink-2); }
.linky { border:0; background:none; padding:0; font:inherit; font-size:var(--t-sm);
  color:var(--ink-2); text-decoration:underline; cursor:pointer; }

/* ---- office controls the tablet screen ---- */
.tabctl { display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap; margin-top:var(--s3);
  padding-top:var(--s3); border-top:1px dashed var(--line); }
.castbtn { border:0; background: var(--btn-solid); color:var(--btn-solid-ink); min-width:32px; height:32px;
  padding:0 var(--s2); border-radius:var(--r-xs); font-size:var(--t-xs); line-height:1; cursor:pointer; flex:0 0 auto; }
.castbtn:hover { background:var(--cure); color: var(--cure-on); }
.paper-chip .nm { text-decoration:none; color:var(--ink); overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }

/* ---- tablet board: notes and the full-screen viewer ---- */
.boardnotes { border:3px solid var(--hivis); border-radius:var(--r-lg); background:var(--dark-1);
  padding:var(--s4) var(--s5); margin:0 0 var(--s5); }
.boardnotes h3 { margin:0 0 var(--s3); font-size:var(--t-md); letter-spacing:.12em; text-transform:uppercase;
  color:var(--hivis); }
.bnote { padding:var(--s3) 0; border-bottom:1px solid var(--dark-2); }
.bnote:last-child { border-bottom:0; padding-bottom:0; }
.bnote p { margin:0 0 var(--s1); font-size:var(--t-title); line-height:1.35; font-weight:700; color:var(--chalk);
  word-break:break-word; }
.bnote span { font-size:var(--t-md); color:var(--ink-3); }

.showwrap { position:fixed; inset:0; background:var(--photo-bg); display:flex; flex-direction:column; z-index:50; }
.showbar { display:flex; align-items:center; gap:var(--s4); padding:var(--s3) var(--s4); background:var(--night);
  color:var(--chalk); flex:0 0 auto; }
.showbar .nm { font-weight:800; font-size:var(--t-lg); }
.showbar .pg { font:800 var(--t-md)/1 ui-monospace,monospace; color:var(--hivis); }
.showbar .hint { margin-left:auto; font-size:var(--t-sm); color:var(--ink-3); }
.showframe { flex:1; width:100%; border:0; background:var(--paper); }
.showimg { flex:1; width:100%; height:100%; object-fit:contain; background:var(--photo-bg); }
.radiotap { position:fixed; bottom:20px; left:50%; transform:translateX(-50%); z-index:60;
  padding:var(--s4) var(--s5); border:0; border-radius:var(--r-pill); background: var(--btn); color:var(--btn-ink);
  font:inherit; font-weight:800; font-size:var(--t-lg); cursor:pointer; }

/* ---- crew: pinned messages vs the quiet log ---- */
.msgs.pinned { border-color: var(--stake); }
.msgs.pinned h3 { color:var(--stake-ink); }

.eventlog { margin:var(--s5) 0 0; border-top:1px solid var(--line); padding-top:var(--s3); }
.eventlog summary { cursor:pointer; font-size:var(--t-sm); font-weight:700; color:var(--ink-2); }
.eventlog > div { padding:var(--s2) 0; border-bottom:1px solid var(--line);
  font-size:var(--t-sm); color:var(--ink-2); }
.eventlog > div:last-child { border-bottom:0; }

/* image previews instead of downloads */
.filecard { display:block; border:1px solid var(--line); border-radius:var(--r-md); overflow:hidden;
  background:var(--paper); text-decoration:none; color:var(--ink); }
.filecard img { display:block; width:100%; max-height:230px; object-fit:cover; }
.filecard span { display:block; padding:var(--s2) var(--s3); font-size:var(--t-sm); font-weight:700; }

.sumbox { display:block; margin:var(--s5) 0 0; }
.sumbox textarea { width:100%; padding:var(--s3); border:1px solid var(--line); border-radius:var(--r-md);
  font:inherit; font-size:var(--t-base); background:var(--paper); resize:vertical; }
.ui-btn.lg.submit.off { background:var(--line); color:var(--ink-2); cursor:not-allowed; }

.reconnect { position:fixed; right:14px; bottom:14px; z-index:70; padding:var(--s2) var(--s4);
  border-radius:var(--r-pill); background:var(--dark-2); color:var(--dark-ink); font-size:var(--t-sm); font-weight:700; }

/* ---- on hold ---- */
.holdbar { display:flex; align-items:center; gap:var(--s4); flex-wrap:wrap; margin-bottom:var(--s4);
  padding:var(--s4) var(--s4); border-radius:var(--r-md); background:var(--stake); color:var(--stake-on); }
.pendbar { display:flex; align-items:center; gap:var(--s4); flex-wrap:wrap; margin-bottom:var(--s4);
  padding:var(--s4); border-radius:var(--r-md); background:var(--wait); color:var(--wait-on); }
.pendbar b { display:block; font-size:var(--t-base); letter-spacing:.04em; }
.pendbar span { font-size:var(--t-md); opacity:.92; }
.pendbar .ui-btn { margin-left:auto; }
.holdbar b { display:block; font-size:var(--t-base); letter-spacing:.04em; }
.holdbar span { font-size:var(--t-md); opacity:.92; }
.holdbar .ui-btn { margin-left:auto; }
.holdflag { display:inline-block; margin-top:var(--s2); padding:var(--s1) var(--s3); border-radius:var(--r-pill);
  background:var(--stake); color:var(--stake-on); font-size:var(--t-xs); font-weight:800; letter-spacing:.06em; }
.slatewrap.held { border-color:var(--stake); box-shadow:0 0 0 3px var(--stake-glow); }

/* ---- what the tablet is showing, mirrored for the office ---- */
.hud { margin-top:var(--s3); padding-top:var(--s3); border-top:1px dashed var(--line); }
.hudbar { display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap; margin-bottom:var(--s2); }
.hudframe { width:100%; height:340px; border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper); }
.hudimg { width:100%; max-height:340px; object-fit:contain; border:1px solid var(--line);
  border-radius:var(--r-md); background:var(--photo-bg); }

.pdffall { display:flex; flex-direction:column; align-items:center; justify-content:center;
  height:100%; gap:var(--s4); background:var(--slab); color:var(--ink); text-align:center; padding:var(--s6); }
.pdffall p { margin:0; font-size:var(--t-lg); font-weight:700; max-width:520px; }
.fallbtn { padding:var(--s4) var(--s6); border-radius:var(--r-md); background: var(--btn); color:var(--btn-ink);
  text-decoration:none; font-weight:800; font-size:var(--t-lg); }
.othderdays { margin-top:var(--s5); font-size:var(--t-lg); color:var(--dark-ink); }
.othderdays .lbl { font-size:var(--t-md); letter-spacing:.08em; text-transform:uppercase; color:var(--ink-3);
  margin-bottom:var(--s2); }
.othderdays .lbl2 { font-size:var(--t-md); color:var(--ink-3); margin-top:var(--s3); }

.sumrow { display:flex; align-items:center; gap:var(--s3); margin-top:var(--s2); }
.sumrow .tiny { flex:1; }
.woextra { margin-top:var(--s5); padding-top:var(--s4); border-top:1px solid var(--line); }
.woextra summary { cursor:pointer; font-weight:800; font-size:var(--t-sm); letter-spacing:.05em;
  text-transform:uppercase; color:var(--ink-2); padding:var(--s1) 0; }
.woextra summary:hover { color:var(--ink); }
.woextra[open] summary { margin-bottom:var(--s3); color:var(--ink); }

.pdffall .ui-btn.lg { font-size:var(--t-title); font-weight:800; margin:0; }
.pdffall .small { font-size:var(--t-base); color:var(--ink-2); max-width:520px; margin:0; }

/* ---- crew: steps the office has to sign off ---- */
.step.proofstep { cursor:default; opacity:1; }
.step.proofstep .tick { font-size:var(--t-lg); }
.waitline { margin:var(--s4) 0 0; padding:var(--s3) var(--s4); border-left:4px solid var(--ink);
  background:var(--paper); border-radius:0 var(--r-sm) var(--r-sm) 0; font-size:var(--t-md); font-weight:700; }

/* ---- tablet board: no dead white band under the content ---- */
html, body { min-height:100%; }
body.boardpage { min-height:100vh; display:flex; flex-direction:column;
  background:var(--night); color:var(--chalk); }
body.boardpage #board { flex:1 1 auto; display:flex; flex-direction:column; }
body.boardpage .split { flex:1 1 auto; }

/* ---------- projects, the register, and gear ----------
 * Orange stays reserved for work being stopped. A tool that is signed out is
 * ordinary — it gets weight and a rule, never the stake color.
 */

/* ---------- projects & the asset register ----------
 *
 * The register is a working surface, not a report. It is laid out so that the
 * two things anybody actually does -- add a thing, correct a count -- are the
 * two easiest targets on the screen, and everything else gets out of the way.
 *
 * Orange stays reserved. An item signed out is not blocking anybody, so it
 * reads as a muted row, never as an alarm.
 */
/* The place is a record now, the same bones as a job: no box of its own. */
.projfold { margin-top:var(--s4); }

/* The site card: the facts that travel onto every job at this address. */
.sitecard { border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper);
  padding:var(--s4) var(--s4); margin-bottom:var(--s5); display:flex; flex-direction:column; gap:var(--s2); font-size:var(--t-md); }
.sitecard div { display:flex; gap:var(--s3); align-items:baseline; flex-wrap:wrap; }
.sitecard .lbl { flex:0 0 132px; font-size:var(--t-xs); font-weight:800; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-3); }
.sitecard a { color:var(--ink); }

.reg-h { margin:var(--s5) 0 var(--s3); color:var(--ink-2); }

.register { display:flex; flex-direction:column; gap:var(--s1); }
.regsplit { margin:var(--s4) 0 var(--s1); font-size:var(--t-xs); font-weight:800; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-3); border-top:1px solid var(--line); padding-top:var(--s3); }

.asset { display:flex; align-items:center; gap:var(--s3); padding:var(--s1) var(--s2); border-radius:var(--r-md);
  border:1px solid transparent; }
.asset:hover { background:var(--paper); border-color:var(--line); }
.asset.is-out { opacity:.62; }

/* Quantity is a live field, not something behind an edit button: fixing a
 * count is the commonest action here and it should cost one gesture. */
.asset .aqty { width:66px; flex:0 0 auto; text-align:right; font-variant-numeric:tabular-nums;
  font-weight:800; padding:var(--s2) var(--s2); border:1px solid var(--line); border-radius:var(--r-sm);
  background:var(--paper); font-size:var(--t-base); }
.asset .aqty:focus { outline:2px solid var(--ink); outline-offset:-1px; }
.asset .aunit { flex:0 0 34px; font-size:var(--t-xs); color:var(--ink-3); font-weight:700; }
.asset .aname { flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.asset .aedit { width:100%; border:1px solid transparent; background:transparent; padding:var(--s2) var(--s2);
  border-radius:var(--r-sm); font-size:var(--t-base); font-weight:600; color:var(--ink); font-family:inherit; }
.asset .aedit:hover { border-color:var(--line); background:var(--paper); }
.asset .aedit:focus { outline:none; border-color:var(--ink); background:var(--paper); }
.asset .asub { font-size:var(--t-xs); color:var(--ink-3); padding:0 var(--s2); }
.asset .asub.out { color:var(--ink-2); font-weight:700; }
.asset .ui-btn.icon { flex:0 0 auto; opacity:0; }
.asset:hover .ui-btn.icon, .asset .ui-btn.icon:focus-visible { opacity:1; }

/* ---------- adding an item ----------
 *
 * Plain fields rather than a syntax to remember. The common case is one line:
 * what it is, how many, what unit. Anything rarer -- a serial number, a
 * barcode, where in the shop it sits -- is one toggle away, present when it is
 * needed and out of sight when it is not.
 *
 * Sticky at the bottom so it stays under the thumb after forty rows.
 */
.entry { position:sticky; bottom:0; margin-top:var(--s4); padding:var(--s4) 0 var(--s1);
  background:linear-gradient(to bottom, var(--card-clear), var(--card) 18%); }
.entryrow { display:flex; gap:var(--s2); align-items:stretch; }
.entryrow .ename { flex:1 1 auto; min-width:0; font-size:var(--t-base); }
.entryrow .eqty { flex:0 0 82px; text-align:right; font-variant-numeric:tabular-nums;
  font-weight:800; font-size:var(--t-base); }
.entryrow .eunit { flex:0 0 128px; }
.entryrow .ui-btn { flex:0 0 auto; white-space:nowrap; }

.entrymore { display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); gap:var(--s3);
  margin-top:var(--s3); padding:var(--s4); border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper); }
.entrymore[hidden] { display:none; }
.entrymore label.f { margin:0; }
.entrymore .entryfixed { grid-column:1/-1; margin:0; }

.entryfoot { display:flex; align-items:center; gap:var(--s3); margin-top:var(--s2); }
.entryfoot .grow { flex:1; }

@media (max-width: 720px) {
  .entryrow { flex-wrap:wrap; }
  .entryrow .ename { flex:1 1 100%; }
  .entryrow .eqty { flex:1 1 80px; }
  .entryrow .eunit { flex:1 1 120px; }
}

.projjobs { display:flex; flex-direction:column; gap:var(--s2); }
.projjob { display:flex; justify-content:space-between; align-items:baseline; gap:var(--s3);
  padding:var(--s2) var(--s3); border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper); flex-wrap:wrap; }

@media (max-width: 720px) {
  .sitecard .lbl { flex:0 0 100%; }
  .asset .ui-btn.icon { opacity:1; }
  .asset .aqty { width:58px; }
}

/* ---------- the crew's gear checklist ----------
 * Deliberately not a gate. A lead who checks finds out in the yard; a lead in
 * a hurry is not blocked. Making it mandatory would only teach people to tick
 * everything without looking, which is worse than not asking.
 */
.gearfold .gearcheck { display:flex; align-items:center; gap:var(--s3); width:100%;
  padding:var(--s4) var(--s4); margin-bottom:var(--s2); border:2px solid var(--line); border-radius:var(--r-md);
  background:var(--paper); font-size:var(--t-lg); font-weight:700; text-align:left; color:var(--ink);
  font-family:inherit; cursor:pointer; }
.gearfold .gearcheck .tick { flex:0 0 26px; height:26px; border:2px solid var(--line);
  border-radius:var(--r-sm); display:flex; align-items:center; justify-content:center;
  font-weight:900; color:var(--cure); }
.gearfold .gearcheck.on { border-color:var(--cure); background:var(--tint-good); color: var(--cure-ink); }
.gearfold .gearcheck.on .tick { border-color:var(--cure); }
.gearfold .gearcheck .txt { flex:1; min-width:0; }
.gearfold .gearcheck .gm { font-size:var(--t-xs); color:var(--ink-3); font-weight:600; }

/* ---------- one search box ----------
 * Wide enough to read what you typed, never so wide it pushes the tabs over
 * the name. It grows when it has your attention. */
.findwrap { position:relative; flex:0 1 200px; min-width:120px; margin-left:auto;
  transition:flex-basis .15s ease; }
.findwrap:focus-within { flex-basis:320px; }
/* The account's name is not the thing that gives way. */
.brandwrap { flex:0 0 auto; max-width:30%; }
.findwrap input { width:100%; padding:var(--s2) var(--s4); border:1px solid var(--line); border-radius:var(--r-pill);
  background:var(--paper); font-size:var(--t-md); font-family:inherit; min-height:40px; }
.findwrap input:focus { outline:2px solid var(--ink); outline-offset:-1px; }
/* Nothing in the bar may break onto a second line. */
.topbar > button, .topbar > select { flex:0 0 auto; white-space:nowrap; }
.topbar .lenspick { max-width:9rem; }
.findres { position:absolute; top:calc(100% + 6px); right:0; width:min(430px,80vw); z-index:60;
  background:var(--paper); border:1px solid var(--ink); border-radius:var(--r-md); box-shadow:0 8px 30px var(--ink-haze);
  max-height:60vh; overflow:auto; padding:var(--s1); }
.findrow { display:flex; align-items:center; gap:var(--s3); width:100%; padding:var(--s2) var(--s3); border:0;
  background:transparent; border-radius:var(--r-sm); cursor:pointer; text-align:left; font-family:inherit; }
.findrow:hover { background:var(--slab); }
.findkind { flex:0 0 74px; font-size:var(--t-xs); font-weight:800; letter-spacing:.07em; text-transform:uppercase;
  color:var(--ink-3); }
.findmain { flex:1; min-width:0; display:flex; flex-direction:column; font-size:var(--t-md); color:var(--ink); }
.findmain span { font-size:var(--t-xs); color:var(--ink-3); }
.findnone { padding:var(--s4); font-size:var(--t-sm); color:var(--ink-3); }

/* ---------- click to call ---------- */
.telly { display:inline-flex; align-items:center; min-height:32px; padding:var(--s1) var(--s3); border:1px solid var(--line); border-radius:var(--r-pill);
  font-size:var(--t-xs); font-weight:700; color:var(--ink); text-decoration:none; background:var(--paper);
  font-variant-numeric:tabular-nums; }
.telly:hover { border-color:var(--ink); background: var(--brand); color:var(--brand-ink); }


.cardcalls { display:flex; flex-direction:column; gap:var(--s2); margin-bottom:var(--s3); }
.callbtn { display:flex; align-items:baseline; gap:var(--s3); padding:var(--s3) var(--s4); border:2px solid var(--line);
  border-radius:var(--r-md); text-decoration:none; color:var(--ink); background:var(--paper); }
.callbtn:hover { border-color:var(--ink); background: var(--brand); color:var(--brand-ink); }
.callbtn .cl { flex:0 0 62px; font-size:var(--t-xs); font-weight:800; letter-spacing:.07em;
  text-transform:uppercase; color:var(--ink-3); }
.callbtn b { font-size:var(--t-lg); font-variant-numeric:tabular-nums; }

.warn { background:var(--tint-warn); border:1px solid var(--warn-edge); border-radius:var(--r-sm); padding:var(--s3) var(--s3);
  font-size:var(--t-sm); margin-bottom:var(--s3); }
.warn[hidden] { display:none; }

/* ---------- inventory ---------- */
.invheld { font-size:var(--t-xs); color:var(--ink-2); font-weight:700; }
.invheld.late { color:var(--stake-ink); }
.invhome { font-size:var(--t-xs); color:var(--ink-3); }
.alert.info { border-left-color: var(--ink-3); }

/* ---------- crew: who to call, and the gate code ---------- */
.whocall { display:flex; flex-direction:column; gap:var(--s2); margin-bottom:var(--s4); }
.callrow { display:flex; align-items:center; justify-content:space-between; gap:var(--s3);
  padding:var(--s4) var(--s4); border:2px solid var(--line); border-radius:var(--r-md); background:var(--paper);
  text-decoration:none; color:var(--ink); }
.callrow .cn { display:flex; flex-direction:column; }
.callrow .cn b { font-size:var(--t-lg); }
.callrow .cn span { font-size:var(--t-xs); color:var(--ink-3); }
.callrow .cnum { font-size:var(--t-base); font-weight:800; font-variant-numeric:tabular-nums; }
.gate { font-size:var(--t-base); margin-top:var(--s1); }
.gate b { font-family:var(--mono); font-size:var(--t-lg); letter-spacing:.08em; }

/* Two rows on a tablet or a phone. Row one is the account and its tools; row
 * two is the tabs, which scroll, with the search box at their end. The old
 * rule gave the search box a full-width second line inside a bar that was
 * fixed at one line high, so on a phone it simply was not there. */
@media (max-width: 900px) {
  .topbar { height:auto; min-height:var(--bar-h); flex-wrap:wrap; padding:var(--s2) var(--s3); row-gap:var(--s2);
    column-gap:var(--s2); }
  /* Row one: the name gives way (it truncates) so Setup and Sign out never
   * drop down among the tabs. The tool buttons tighten up. */
  .brandwrap { flex:1 1 0; min-width:6rem; max-width:none; }
  .topbar .spacer { display:none; }
  .topbar > .tab { padding:var(--s2) var(--s2); font-size:var(--t-xs); letter-spacing:.06em; }
  .topbar .lenspick { max-width:6.5rem; font-size:var(--t-xs); padding:0 var(--s2); }
  /* Ask Korbis keeps its mark and loses its words before the counts lose
   * theirs: the mark alone is still unmistakably the thing you press. */
  .asktext, .askkey { display:none; }
  .askbtn { padding:var(--s1) var(--s2); margin-right:var(--s1); }
  /* The client's name still fits; the words in front of it do not. */
  .lenswho::before { content:''; }
  /* Was its own @media block for this same width, further down the file. Two
   * blocks for one breakpoint means every check of that width reads whichever
   * comes first, and the other goes unchecked. */
  .buildwrap { grid-template-columns:1fr; }
  /* Row two: the tabs take what is left and scroll; the search box is always
   * on screen at their end. */
  /* A basis just short of the row forces the tabs onto their own line and
   * leaves exactly the search box's width beside them. */
  .tabs { order:10; flex:1 1 calc(100% - 150px); min-width:0; margin:0; }
  .findwrap { order:11; flex:0 0 138px; min-width:0; margin-left:0; }
  .findwrap:focus-within { flex-basis:200px; }
  .findres { right:0; left:auto; width:min(430px, calc(100vw - 24px)); }
}

/* Hiding means hidden.
 *
 * The hidden attribute only sets display:none through the user-agent
 * stylesheet, so any class here that declares its own display -- .joblist is
 * a grid, .ui-toolbar is a flex row -- silently beat it, and panes that were
 * supposed to swap stacked on top of each other instead. One rule, applied
 * once, rather than remembering to add [hidden]{display:none} per component. */
[hidden] { display: none !important; }

/* ---------- locations / people toggle ---------- */
.segbar { display:flex; gap:var(--s1); margin-bottom:var(--s4); padding:var(--s1); background:var(--paper);
  border:1px solid var(--line); border-radius:var(--r-pill); width:fit-content; }
.seg { border:0; background:transparent; font:inherit; font-weight:800; font-size:var(--t-sm);
  padding:var(--s2) var(--s4); border-radius:var(--r-pill); cursor:pointer; color:var(--ink-3); }
.seg:hover { color:var(--ink); }

/* ---------- the dashboard ----------
 *
 * Full width, and nothing on it that is only a number. Every tile, row and
 * bar is a link to the place where the thing can be dealt with — a morning
 * screen that shows a problem but not a way to act on it is a screen you
 * scroll past. Reading order is deliberate: what is happening, what is
 * wrong, what is running, what is coming.
 */
#view-home { max-width:none; }
.dash { display:flex; flex-direction:column; gap:var(--s4); }
.dash .head { margin-bottom:0; }
/* ---------- the record ----------
 * One shape for one thing: the head, the facts, then the modules. A job
 * reads this way; a location or a truck would read the same. The facts are
 * the same box Home's figures are: a figure in mono over its word, orange
 * when it needs the office. On Home each is a button to its screen. */
.facts { display:grid; grid-template-columns:repeat(auto-fit, minmax(140px, 1fr)); gap:0; margin-bottom:var(--s4);
  background:var(--card); border-radius:var(--r-lg); box-shadow:var(--shadow); padding:var(--s2) 0; overflow:hidden; }
.facts > .fact { border:0; border-radius:0; box-shadow:none; background:transparent; border-left:1px solid var(--line); }
.facts > .fact:first-child { border-left:0; }
.facts > .fact.hot { background:var(--tint-wait); color:var(--wait-ink); }
.dash .facts { margin-bottom:0; }
.fact { background:var(--card); border:1px solid var(--line); border-radius:var(--r-md); padding:var(--s3) var(--s4); display:flex; flex-direction:column; gap:2px; align-items:flex-start; }
.fact b { font:800 var(--t-figure)/1 ui-monospace, monospace; font-variant-numeric:tabular-nums; letter-spacing:-.02em; }
.fact span { font-size:var(--t-sm); font-weight:600; letter-spacing:0; text-transform:none; color:var(--ink-3); text-align:left; }
/* A fact that needs the office is amber -- it is waiting, not stopped. */
.fact.hot { background:var(--tint-wait); border-color:var(--warn-edge); color:var(--wait-ink); }
.fact.hot b { color:var(--wait-ink); }
.fact.hot span { color:var(--wait-ink); }
button.fact { font-family:inherit; color:var(--ink); cursor:pointer; text-align:left; }
button.fact:hover { border-color:var(--ink); }
button.fact.hot { color:var(--stake-on); }
.rec-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(440px, 1fr)); gap:var(--s4); align-items:start; }
.rec-grid > .wide { grid-column:1 / -1; }
.panel .sitecard { margin:0; }
.recrow { appearance:none; width:100%; text-align:left; font:inherit; color:var(--ink); background:var(--paper); border:1px solid var(--line);
  border-radius:var(--r-sm); padding:var(--s3) var(--s3); display:flex; gap:var(--s3); align-items:center; cursor:pointer; margin-bottom:var(--s2); }
.recrow:hover { border-color:var(--ink); }
.recwhen { font-weight:800; font-size:var(--t-xs); letter-spacing:.06em; text-transform:uppercase; color:var(--ink-2); }
.recmain { display:flex; flex-direction:column; gap:1px; min-width:0; flex:1 1 auto; }
.recmain b { font-size:var(--t-base); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.recrow .pill { flex:0 0 auto; }
.recshots { display:grid; grid-template-columns:repeat(auto-fill, minmax(96px, 1fr)); gap:var(--s2); }
.recshots img { width:100%; aspect-ratio:1; object-fit:cover; border-radius:var(--r-sm); border:1px solid var(--line); display:block; }
.recfile { display:flex; align-items:center; gap:var(--s3); padding:var(--s2) 0; border-bottom:1px solid var(--line); }
.recfile b { flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.recdetail { display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); gap:var(--s3) var(--s4); }
/* A record's own form is the one grid (.form) on the record, not in a window. */
.panel > .form { margin-bottom:var(--s3); }
.panel > .form:last-child { margin-bottom:0; }
.linkish { appearance:none; border:0; background:transparent; padding:0; font:inherit; color:var(--ink-2); text-decoration:underline; cursor:pointer; }
.stakeword { color:var(--stake-ink); font-weight:700; }
.recdetail > div { display:flex; flex-direction:column; gap:2px; }
.recname { appearance:none; border:0; background:transparent; padding:0; font:inherit; font-weight:800; color:var(--ink); cursor:pointer; text-align:left; }
.recname:hover { text-decoration:underline; }
.ui-card[data-jobopen], .ui-card[data-placeopen], .ui-card[data-coopen], .ui-card[data-toolopen], .ui-card[data-personrow] { cursor:pointer; }

/* The loading bay: the work order as a screen. The head, then the form,
 * then the buttons; a question screen that is not a form closes with the
 * same row of buttons. */
.loadbay { max-width: 760px; }
.loadbay > .ui-btns, .loadbay > form > .ui-btns, .loadbay > .body + .ui-btns { margin-top:var(--s4); }
.loadbay .body { margin-bottom:var(--s4); }
.loadbay .ui-btns .grow { flex:1; }
.loadbay .body > .note:first-child { margin:0 0 var(--s3); }
/* The tablet's code, to be read across a room. */
.qrbody { text-align:center; }
.qrbody img { width:100%; max-width:320px; border-radius:var(--r-md); }
.qrbody .code { font-size:var(--t-title); letter-spacing:.16em; margin:var(--s3) 0 var(--s1); }
/* A Setup window as a panel in place of the sections: the same bones, the
 * same box, with the head inside it. */
.setscreen { margin-bottom:var(--s4); }
.setscreen[hidden] { display: none; }
.setscreen .head { margin-bottom:var(--s4); padding-bottom:var(--s3); border-bottom:1px solid var(--line); }

/* The starts: a row of cards, the work order first and lit. */
.starts { display:grid; grid-template-columns:repeat(auto-fit, minmax(160px, 1fr)); gap:var(--s3); }
.start { appearance:none; text-align:left; cursor:pointer; font:inherit; color:var(--ink);
  background:var(--card); border:1px solid var(--line); border-radius:var(--r-md); padding:var(--s3) var(--s4);
  display:flex; flex-direction:column; gap:var(--s1); min-height:64px; }
.start:hover { border-color:var(--ink); }
.start { display:flex; align-items:center; gap:var(--s3); }
.start .mark { width:40px; height:40px; }
.start > div { display:flex; flex-direction:column; gap:2px; min-width:0; }
.start b { font-size:var(--t-base); font-weight:700; }
.start span { font-size:var(--t-sm); color:var(--ink-3); }
.start.prime .mark { background:var(--btn); color:var(--btn-ink); }
.start.prime { background:var(--btn-solid); color:var(--btn-solid-ink); border-color:var(--btn-solid); }
.start.prime span { color:var(--btn-solid-ink); opacity:.75; }
.start.prime:hover { filter:brightness(1.1); }
.dashgrid { display:grid; grid-template-columns:minmax(0,1.55fr) minmax(0,1fr); gap:var(--s4); align-items:start; }
.dashcol { display:flex; flex-direction:column; gap:var(--s4); min-width:0; }
/* ---------- the panel ----------
 * One box for one idea: a titled section with a note or one small action on
 * the right and a rule under it. Home's panels, a record's modules, Setup's
 * sections and the shelves are all this. A panel head on its own (Today's
 * sections, over the rail) is the same head without the box. */
.panel { border:0; border-radius:var(--r-lg); background:var(--card); padding:var(--s4) var(--s5); min-width:0; box-shadow:var(--shadow); }
.panel.mine { box-shadow:var(--shadow), 0 0 0 2px var(--brand); }
.panelhead { display:flex; align-items:center; justify-content:space-between; gap:var(--s3);
  margin-bottom:var(--s4); padding-bottom:var(--s3); border-bottom:1px solid var(--line); }
.panelhead h2 { font-size:var(--t-lg); font-weight:800; letter-spacing:0; margin:0; min-height:36px; display:flex; align-items:center; gap:var(--s3); }
.panelhead h2 { flex:0 0 auto; }
.panelhead .tiny, .panelhead .note { text-align:right; flex:0 1 auto; min-width:0; }

.dashrun, .dashask { display:flex; align-items:center; gap:var(--s3); width:100%; padding:var(--s3) var(--s2);
  border:0; border-bottom:1px solid var(--line); border-radius:0; background:transparent; margin:0;
  cursor:pointer; font-family:inherit; text-align:left; color:var(--ink); }
.dashrun:last-child, .dashask:last-child { border-bottom:0; }
.dashrun:hover, .dashask:hover { background:var(--slab); }
.dashrun.noshelf .dr-state { background:var(--tint-stop); color:var(--stop-ink); }
.dr-state { display:inline-flex; align-items:center; gap:var(--s1); padding:2px var(--s2); border-radius:var(--r-pill);
  font-size:var(--t-xs); font-weight:600; background:var(--cat-tint, var(--slab-deep)); color:var(--cat-ink, var(--ink-2)); white-space:nowrap; }
.dashrun.cat-1 .dr-state::before, .dashrun.cat-2 .dr-state::before, .dashrun.cat-3 .dr-state::before, .dashrun.cat-4 .dr-state::before, .dashrun.cat-5 .dr-state::before, .dashrun.cat-6 .dr-state::before {
  content:""; width:8px; height:8px; border-radius:var(--r-pill); background:var(--cat); }
.dr-when { flex:0 0 54px; font-weight:800; font-variant-numeric:tabular-nums; font-size:var(--t-md); }
.dr-main, .da-main { flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.dr-main b, .da-main b { font-size:var(--t-base); }
.dr-main span, .da-main span { font-size:var(--t-xs); color:var(--ink-3); }
.dr-state { flex:0 0 auto; font-size:var(--t-xs); font-weight:700; color:var(--ink-3); }
.da-go { flex:0 0 auto; font-size:var(--t-xs); font-weight:800; color:var(--stake-ink); }

.aheadrow { display:flex; align-items:center; gap:var(--s3); width:100%; padding:var(--s2) var(--s2); border:0;
  background:transparent; border-radius:var(--r-sm); cursor:pointer; font-family:inherit; color:var(--ink); }
.aheadrow:hover { background:var(--paper); }
.aheadrow.is-today { background: var(--accent); font-weight:800; color:var(--accent-ink); }
/* Everything on the lit row reads in the row's own ink, whatever the appearance. */
.aheadrow.is-today .ah-n, .aheadrow.is-today .ah-dots { color: inherit; }
.ah-day { flex:0 0 76px; font-size:var(--t-xs); }
/* A dot per crew, then the number in words. The bar it replaced was the one
 * thing on the home page that needed explaining: a bar of what, out of what. */
.ah-dots { flex:1; text-align:left; font-size:var(--t-xs); letter-spacing:3px; color:var(--ink-2); }
.ah-n { flex:0 0 auto; font-size:var(--t-xs); color:var(--ink-3); font-variant-numeric:tabular-nums; }

.adriftrow { display:flex; align-items:center; justify-content:space-between; gap:var(--s3);
  padding:var(--s2) var(--s3); border-bottom:1px solid var(--line); flex-wrap:wrap; }
.adriftrow:last-child { border-bottom:0; }
.ad-main { display:flex; flex-direction:column; }
.ad-main b { font-size:var(--t-md); }
.ad-main span { font-size:var(--t-xs); color:var(--ink-3); }

/* A delete is a quiet control until you go looking for it. */

@media (max-width: 980px) { .dashgrid { grid-template-columns:1fr; } }

/* Whose tool is it. Once more than one company's kit is on the system, this
   is the first thing the eye needs, so it sits directly under the name. */

/* ---------- Setup: branding ----------
 *
 * The preview is the point. Choosing a color from a list of swatches tells
 * you nothing about what your people will actually see at six in the morning,
 * so the sign-in page is rebuilt beside the choices and changes as you click.
 */
.brandrow { display:grid; grid-template-columns:minmax(0,300px) minmax(0,1fr); gap:var(--s5);
  align-items:start; }

.swatches { display:grid; grid-template-columns:repeat(auto-fit,minmax(128px,1fr)); gap:var(--s2); }
.sw { display:flex; align-items:center; gap:var(--s2); padding:var(--s2) var(--s3); min-height:40px; border:1px solid var(--line);
  border-radius:var(--r-md); background:var(--paper); cursor:pointer; font-family:inherit; font-size:var(--t-sm);
  font-weight:700; color:var(--ink); text-align:left; }
.sw:hover { border-color:var(--ink); }
.sw.on { border-color:var(--ink); box-shadow:inset 0 0 0 1px var(--ink); }
.sw .dot { width:18px; height:18px; border-radius:var(--r-xs); flex:0 0 auto;
  border:1px solid var(--shade-b); }
.sw .nmx { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* A destructive control should be findable and never the thing your eye lands
   on first. Quiet until hovered, then unmistakable. */
button.danger { color:var(--ink-3); }
button.danger:hover { color:var(--stake-ink); border-color:var(--stake); }

@media (max-width: 760px) { .brandrow { grid-template-columns:1fr; } }

.ownhue { margin-top:var(--s3); }
.ownhue summary { cursor:pointer; font-size:var(--t-xs); font-weight:700; color:var(--ink-3); }
.ownhue summary:hover { color:var(--ink); }
.ownhue-b { display:flex; gap:var(--s2); margin-top:var(--s3); }
.ownhue-b input { flex:0 0 130px; font-family:var(--mono); text-transform:uppercase; }

/* ---------- the last mile ----------
 *
 * Small things, but their absence is what makes software feel unfinished:
 * a visible focus ring for anyone on a keyboard, controls that look disabled
 * when they are, text that cannot be selected by accident on a tap target,
 * and motion that respects the person who asked for less of it.
 */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}
button:disabled, .ui-btn:disabled, .ui-btn.lg:disabled {
  opacity: .5; cursor: not-allowed;
}
button, .ui-btn, .tab, .seg, .fact { -webkit-tap-highlight-color: transparent; }
.tab, .seg, .sw, .fact span { user-select: none; }

/* Long names should truncate rather than break a row's layout. */
.ct, .nm, .dr-main b, .findmain b { overflow-wrap: anywhere; }

/* Printing a schedule should not print the furniture. */
@media print {
  .tabs, .findwrap, .ui-btns, #toast, .segbar, footer { display: none !important; }
  body { background: var(--paper); }
  .ui-card, .panel { break-inside: avoid; box-shadow: none; }
}

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

/* Compact spacing, for somebody running a lot of work on one screen. Type
   never shrinks below the readable floor -- only the air between things
   goes: the same scale at three-quarters, everywhere at once. */
body.compact { --s1: 3px; --s2: 6px; --s3: 9px; --s4: 12px; --s5: 18px; --s6: 24px; }

.prefrows { display:flex; flex-wrap:wrap; gap:var(--s2); }
.prefrow .chk { margin:0; }

/* An account nobody can sign in to is the one failure the host cannot see
   and the client cannot fix. It gets the only warm edge on the page. */
.row.is-broken { border-left:4px solid var(--stake); }
.sm.broken { color:var(--stake-ink); }

/* ---------- the shelf in Setup ----------
 * The label and the QR belong side by side: the office reads one and the crew
 * scans the other, and they have to be the same tablet.
 */
.tabletrow { align-items:flex-start; gap:var(--s4); flex-wrap:wrap; }
.tabletrow .nm { display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap; }
.tabletrow .tname { font: inherit; font-weight:800; font-size:var(--t-lg); letter-spacing:.02em;
  border:1px solid transparent; background:transparent; border-radius:var(--r-sm); padding:var(--s1) var(--s2);
  min-width:9ch; max-width:22ch; color:var(--ink); }
.tabletrow .tname:hover { border-color:var(--line); background:var(--paper); }
.tabletrow .tname:focus { outline:none; border-color:var(--ink); background:var(--paper); }
.tabletqr { flex:0 0 auto; display:flex; flex-direction:column; align-items:center; gap:var(--s1); }
.tabletqr img { width:96px; height:96px; display:block; background:var(--paper);
  border:1px solid var(--line); border-radius:var(--r-sm); padding:var(--s1); }
.tabletacts { display:flex; flex-direction:column; gap:var(--s2); flex:0 0 auto; }
@media (max-width: 720px) {
  .tabletacts { flex-direction:row; flex-wrap:wrap; }
  .tabletqr img { width:76px; height:76px; }
}

/* A real color well, not a box you type hex into. The verdict updates as the
   picker moves, so nobody saves something unreadable and finds out later. */
.ownhue-b { align-items:center; }
.ownhue-b input[type="color"] { width:52px; height:44px; padding:var(--s1); border:1px solid var(--line);
  border-radius:var(--r-md); background:var(--paper); cursor:pointer; flex:0 0 auto; }
.hexread { font-family:var(--mono); font-size:var(--t-sm); color:var(--ink-2);
  letter-spacing:.04em; min-width:8ch; }
.warnline { color:var(--stake-ink); font-weight:700; }

/* A first-run note is guidance, not a fault. Orange means work is stopped and
   nothing is stopped here — there is simply nothing entered yet. */
.guide { margin:0 0 var(--s4); padding:var(--s3) var(--s4); border:1px solid var(--line);
  border-left:4px solid var(--ink-3); border-radius:var(--r-md); background:var(--paper);
  font-size:var(--t-md); color:var(--ink-2); }
.guide[hidden] { display:none; }

/* The client's mark, in the bar they look at all day. */
.brandlogo { height:26px; max-width:130px; display:block; object-fit:contain; }
.brandwrap { display:flex; align-items:center; gap:var(--s3); min-width:0; }
.brandwrap .brand { white-space:nowrap; }


/* A row inside a row looked like a box hugging its own label. The choice is
   the whole row; the border belongs to the row, not to the checkbox. */
/* A panel on the front page: its name, on or off, and the two arrows that
 * order it -- a chip's worth, so six of them are two lines, not a screen. */
.prefrow .chk { border:0; background:transparent; padding:0; margin:0; flex:1; min-height:0; }
.prefrow { display:inline-flex; align-items:center; gap:var(--s2); padding:var(--s1) var(--s2) var(--s1) var(--s3);
  border:1px solid var(--line); border-radius:var(--r-pill); background:var(--paper); }
.prefrow .ui-btn { min-height:32px; padding:0 var(--s2); }

/* One shelf per account, so your own hardware is not buried among clients'.
 * Each is a panel; the host's own is marked. */
.shelf { margin-bottom:var(--s4); }
.shelf:last-child { margin-bottom:0; }

/* ---------- the account's color, where it belongs ----------
 *
 * Applied to the chrome and to primary actions -- surfaces that already carry
 * white text, so every preset stays legible without the theme having to think
 * about contrast. Deliberately NOT applied to:
 *
 *   - orange (--stake), which means work is stopped and belongs to the product
 *   - the lime "go" on Save and Sign in, which is high-visibility by design
 *     and is read at arm's length on a jobsite
 *
 * A client may color their environment. They may not redefine what a color
 * means to a crew.
 */

/* Buttons follow the Buttons setting, never the navigation color. The two
 * used to be the same variable, so "+ Work order" ignored the button choice
 * and quietly tracked the bar instead — the setting said "every action
 * button" and reached exactly one of them. */
.ui-btn.primary { background: var(--btn-solid); border-color: var(--btn-solid);
  color: var(--btn-solid-ink); }
.ui-btn.primary:hover { filter: brightness(1.12); }
.seg.on { background: var(--label); color: var(--label-ink); }
.chip.on { border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); }
.dashrun:focus-visible, .dashask:focus-visible { outline-color: var(--brand); }



/* The company's mark on a crew screen. Small, out of the way, and never in
   front of the work — a tablet at arm's length has one job. */
.crewmark { position:fixed; top:10px; right:12px; max-height:30px; max-width:120px;
  object-fit:contain; z-index:5; opacity:.9; pointer-events:none; }
@media (max-width: 520px) { .crewmark { max-height:22px; max-width:88px; } }

/* Text on the bar follows the bar, whatever color it is. The tab that is on
   inverts, so it stays the loudest thing up there at any brightness. */
.topbar .tab { color: var(--brand-dim, var(--bar-line)); }
.topbar .tab:hover { color: var(--brand-ink); background: var(--bar-fill-2); }
.topbar .spacer { flex: 1; }
.findwrap input { color: var(--ink); }

/* ---------- clients' shelves ----------
 * Present, separate, and foldable. Yours is the rail above; these are other
 * people's hardware and never mix into what you dispatch from.
 */
.cshelf { margin-top:var(--s4); border:1px solid var(--line); border-radius:var(--r-lg);
  background:var(--card); padding:var(--s3) var(--s4); }
.cshelf.is-folded { padding:var(--s2) var(--s4); background:transparent; }
.cshelf-head { display:flex; align-items:center; gap:var(--s3); }
.cshelf-head b { font-size:var(--t-md); }
.cshelf-fold { border:0; background:transparent; font:inherit; cursor:pointer;
  color:var(--ink-3); padding:var(--s1) var(--s2); min-width:32px; min-height:32px; }
.cshelf-rail { display:flex; gap:var(--s2); flex-wrap:wrap; margin-top:var(--s3); }
.cslate { flex:1 1 170px; border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper);
  padding:var(--s2) var(--s3); min-width:0; }
.cslate.has { border-color:var(--ink-3); }
.cs-label { font-weight:800; font-size:var(--t-sm); letter-spacing:.04em; }
.cs-what { font-size:var(--t-xs); color:var(--ink-3); overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; }

/* ---------- button style, chosen per account ----------
 *
 * The default keeps the lime: it is deliberately the loudest thing on a
 * screen read outdoors, and a crew learns it means go. An account that would
 * rather have its own color can have it — every color the system accepts
 * already carries white text at 4.5:1, so the swap is always legible.
 */
body.square { --r-xs: 2px; --r-sm: 3px; --r-md: 3px; --r-lg: 4px; --r-pill: 4px; }

/* A destructive control should read as available, not as switched off. It was
   faint enough to look disabled beside live buttons. */
button.danger {
  color: var(--ink-2); border-color: var(--line);
}
button.danger:hover {
  color:var(--stake-ink); border-color: var(--stake); background: var(--paper);
}

/* ---------- appearance, rebuilt ----------
 *
 * One wide sample across the top and one row per decision underneath. The
 * previous version put a small sample beside four stacked groups and asked
 * people to imagine the result; every control here changes the sample and the
 * page as it is clicked.
 */
.look { display: flex; flex-direction: column; gap:var(--s4); }

/* The sample carries its own copy of every hook, so it can show a color that
   has not been saved yet without repainting the whole page. */
.lookprev { border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden;
  background: var(--card); box-shadow: var(--shadow); --brand: var(--night);
  --brand-ink: var(--chalk); --brand-dim: rgba(255,255,255,.62);
  --btn: var(--hivis); --btn-ink: var(--hivis-ink);
  --btn-solid: var(--night); --btn-solid-ink: var(--chalk);
  --tab-on: var(--hivis); --tab-on-ink: var(--hivis-ink); }
.lookprev.square { --r-xs: 2px; --r-sm: 3px; --r-md: 3px; --r-lg: 4px; --r-pill: 4px; border-radius: var(--r-xs); }
.lookprev .pv-bar { display: flex; align-items: center; gap:var(--s3); padding:var(--s3) var(--s4);
  background: var(--brand); border-bottom: 3px solid var(--brand-accent, var(--brand)); color:var(--brand-ink); }
.lookprev .pv-mark { font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  font-size: var(--t-xs); color: var(--brand-ink); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 16ch; }
.lookprev img { height: 22px; max-width: 90px; object-fit: contain; }
.lookprev .pv-live { display: inline-flex; align-items: baseline; gap:var(--s1); font-size: var(--t-xs); font-weight: 600;
  text-transform: none; letter-spacing: 0; color: var(--brand-dim); border: 1px solid var(--bar-line);
  border-radius: var(--r-sm); padding:var(--s1) var(--s2); }
.lookprev .pv-live b { font: 800 var(--t-base)/1 ui-monospace, monospace; color: var(--brand-accent); }
/* The sample's waiting figure is amber, the way the real strip's is. */
.lookprev .pv-live.hot { background: var(--wait); border-color: var(--wait); color: var(--wait-on); }
.lookprev .pv-live.hot b { color: var(--wait-on); }
.lookprev .pv-shell { display: flex; align-items: stretch; }
.lookprev .pv-side { flex: 0 0 96px; display: flex; flex-direction: column; gap:2px; padding:var(--s3) var(--s2);
  background: var(--card); border-right: 1px solid var(--line); }
.lookprev .pv-tab { font-size: var(--t-xs); font-weight: 700; color: var(--ink-2);
  padding:var(--s2) var(--s3); border-radius: var(--r-sm); }
.lookprev .pv-tab[aria-selected="true"] { background: var(--brand); color: var(--brand-ink); }
.lookprev .pv-body { flex: 1 1 auto; display: flex; align-items: center; gap:var(--s3); padding:var(--s4); }
.lookprev .pv-tile { flex: 0 1 130px; border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--paper); padding:var(--s3) var(--s3); display: flex; flex-direction: column; }
.lookprev .pv-tile b { font-size: var(--t-figure); }
.lookprev .pv-tile span { font-size: var(--t-xs); color: var(--ink-3); }
.lookprev .pv-acts { margin-left:auto; display: flex; gap:var(--s2); }
.lookprev .pv-go { background: var(--btn); color: var(--btn-ink); border-radius: var(--r-sm);
  padding:var(--s3) var(--s4); font-size: var(--t-xs); font-weight: 800; text-transform: uppercase;
  letter-spacing: .05em; }
.lookprev .pv-btn { background: var(--btn-solid); color: var(--btn-solid-ink); border-radius: var(--r-sm);
  padding:var(--s3) var(--s4); font-size: var(--t-xs); font-weight: 800; }

/* The one setting row: a bold label with one line under it on the left,
 * the controls on the right, a rule under. Every setting in Setup -- the
 * look, the tablets, the daily check, the advanced ones -- is this. */
.setrows { display: flex; flex-direction: column; }
.setrow { display: flex; align-items: center; gap:var(--s4); padding:var(--s2) 0;
  border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.setrow:last-child { border-bottom: 0; }
.setrow-l { flex: 0 0 260px; display: flex; flex-direction: column; gap:1px; min-width:0; }
.setrow-l b { font-size: var(--t-base); }
.setrow-r { display: flex; align-items: center; gap:var(--s3); flex: 1; flex-wrap: wrap; min-width:0; }
.setrow-r > select { flex:0 1 320px; width:auto; }
.setrow-r .urlbox { flex:1 1 240px; margin:0; }
.setrow-r .bar { flex:1 1 200px; }
.setrows + .grid { margin-top:var(--s4); }

.chips { display: flex; gap:var(--s2); flex-wrap: wrap; flex: 1; }
/* Twelve swatches: a disc of the color over its name, the chosen one ringed
 * in its own color. The disc reads the color from a custom property set on
 * the element, so the stylesheet still writes no color of its own. */
.colorset { display:flex; flex-wrap:wrap; gap:var(--s3) var(--s2); }
.colorset .themechip { flex-direction:column; gap:var(--s1); padding:var(--s1); border:0; background:transparent; min-width:56px; border-radius:var(--r-sm); }
.colorset .themechip .dot { width:36px; height:36px; border-radius:var(--r-pill); background:var(--sw); box-shadow:0 0 0 2px var(--card), 0 0 0 3px var(--line); transition:transform .12s, box-shadow .12s; }
.colorset .themechip:hover .dot { transform:scale(1.06); }
.colorset .themechip.on { box-shadow:none; }
.colorset .themechip.on .dot { box-shadow:0 0 0 2px var(--card), 0 0 0 4px var(--sw); }
.colorset .themechip .nmx { font-size:var(--t-xs); font-weight:600; color:var(--ink-2); }
.colorset .themechip.on .nmx { color:var(--ink); font-weight:700; }
.ownrow { width:100%; max-width:440px; margin-top:var(--s3); }
/* The phone: the code on the left, the link and its buttons beside it. */
.notifyscan { display:flex; gap:var(--s4); align-items:flex-start; flex-wrap:wrap; }
.notifyscan img { width:148px; height:148px; border-radius:var(--r-md); background:var(--paper); box-shadow:var(--shadow); flex:0 0 auto; }
.notifylink { display:flex; flex-direction:column; gap:var(--s2); min-width:0; max-width:420px; }
.notifylink a.code { font-size:var(--t-sm); letter-spacing:0; text-transform:none; word-break:break-all; color:var(--ink); }
.chk-col { display:flex; flex-direction:column; gap:var(--s2); }
.ownf { margin:0; }
.ownswatch { width:var(--tap); height:var(--tap); flex:0 0 auto; border-radius:var(--r-sm); border:1px solid var(--line); background:var(--sw, transparent); }
.ownf input { font-family:var(--mono); text-transform:uppercase; }
.themechip { display: inline-flex; align-items: center; gap:var(--s2); padding:var(--s2) var(--s3);
  border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--paper); cursor: pointer;
  font: inherit; font-size: var(--t-sm); font-weight: 700; color: var(--ink);
  min-height: var(--tap); }
.themechip:hover { border-color: var(--ink); }
.themechip.on { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.themechip .dot { width: 15px; height: 15px; border-radius: 50%; flex: 0 0 auto;
  border: 1px solid var(--shade-b); }

.btncustom { display: inline-flex; align-items: center; gap:var(--s3); }
.btncustom[hidden] { display: none; }
input[type="color"] { width: 46px; height: var(--tap); padding:var(--s1); border: 1px solid var(--line);
  border-radius: var(--r-md); background: var(--paper); cursor: pointer; flex: 0 0 auto; }
.verdict { font-size: var(--t-xs); color: var(--ink-3); }

@media (max-width: 760px) {
  .setrow-l { flex: 1 1 100%; }
}

/* ---------- backup and restore ----------
 * A restore replaces everything and cannot be undone from inside the app, so
 * the confirmation is deliberately a wall rather than a button.
 */
.restorebox { margin-top:var(--s4); border:1px solid var(--line); border-left:4px solid var(--ink);
  border-radius:var(--r-md); background:var(--paper); padding:var(--s4) var(--s4); }
.restorebox[hidden] { display:none; }
.rb-head { font-size:var(--t-xs); font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  color:var(--ink-3); margin-bottom:var(--s2); }
.rb-body { font-size:var(--t-md); margin-bottom:var(--s3); }
.rb-counts { display:flex; gap:var(--s4); flex-wrap:wrap; margin-top:var(--s2); color:var(--ink-2);
  font-size:var(--t-sm); }
.rb-counts b { color:var(--ink); font-size:var(--t-base); }
.rb-warn { font-size:var(--t-sm); color:var(--ink-2); margin-bottom:var(--s3);
  padding:var(--s3) var(--s3); border-radius:var(--r-sm); background:var(--slab); }
.rb-warn.hot { color:var(--stake-ink); font-weight:700; border:1px solid var(--stake);
  background:var(--paper); }

/* ---------- the truck: crew, poles, and the form at each ----------
 *
 * Everything here is read at arm's length, outdoors, often in gloves and
 * sometimes in traffic control. Targets are large, one pole is open at a
 * time, and a field that does not apply yet is not on the screen at all.
 */
.crewbox { margin:var(--s4) 0; padding:var(--s4) var(--s4); border:1px solid var(--line);
  border-radius:var(--r-lg); background:var(--card); }
.crewrow { display:flex; gap:var(--s2); flex-wrap:wrap; margin-bottom:var(--s3); }
.crewchip { padding:var(--s2) var(--s3); border-radius:var(--r-pill); background:var(--slab-deep);
  font-size:var(--t-sm); font-weight:700; }
.crewchip.lead { background:var(--tint-go); color:var(--go-ink); }
.crewadd { display:flex; gap:var(--s3); flex-wrap:wrap; align-items:center; }
.crewadd input { flex:1 1 180px; min-height:var(--tap); font-size:var(--t-lg); }
.crewlead { display:flex; align-items:center; gap:var(--s2); font-size:var(--t-sm);
  color:var(--ink-2); flex:1 1 100%; }
/* The box sits beside its words. The row's name field rule stretched the
 * checkbox to 180px and pushed "I'm running the crew" to the far edge. */
.crewlead input { width:22px; height:22px; flex:0 0 auto; min-height:0; }

.stop { border:1px solid var(--line); border-radius:var(--r-lg); background:var(--card);
  margin-bottom:var(--s3); overflow:hidden; }
.stop.open { border-color:var(--ink); }
.stop.done { opacity:.72; }
.stop.flagged { border-left:5px solid var(--stake); }
.stophead { display:flex; align-items:center; gap:var(--s3); width:100%; padding:var(--s4);
  background:transparent; border:0; font:inherit; text-align:left; cursor:pointer;
  min-height:var(--tap); }
.stoptick { width:28px; height:28px; flex:0 0 28px; border-radius:50%;
  border:2px solid var(--line); display:flex; align-items:center; justify-content:center;
  font-weight:800; }
.stop.done .stoptick { background:var(--cure); border-color:var(--cure); color:var(--cure-on); }
.stopmain { flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.stopmain b { font-size:var(--t-lg); letter-spacing:.02em; }
.stopwhere, .stopsum { font-size:var(--t-sm); color:var(--ink-3); overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.stopflag { flex:0 0 auto; font-size:var(--t-xs); font-weight:800; text-transform:uppercase;
  letter-spacing:.06em; color:var(--stake-ink); }
.stopleft { flex:0 0 auto; font-size:var(--t-xs); font-weight:700; color:var(--ink-3); }

.stopform { padding:0 var(--s4) var(--s4); border-top:1px solid var(--line); }
.fhead { margin:var(--s4) 0 var(--s2); font-size:var(--t-xs); font-weight:800; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-3); }
.frow { margin:var(--s4) 0; }
.flab { font-size:var(--t-base); font-weight:700; margin-bottom:var(--s2); }
.fq { font-size:var(--t-xs); font-weight:700; color:var(--stake-ink); margin-left:var(--s2); }
.fhelp { display:block; font-size:var(--t-sm); font-weight:400; color:var(--ink-3); margin-top:2px; }
.ftext { width:100%; min-height:var(--tap); font-size:var(--t-lg); }

.measure { display:flex; gap:var(--s3); align-items:stretch; }
.measure .fval { flex:1; min-height:52px; font-size:var(--t-title); font-weight:700;
  font-family:var(--mono); text-align:right; padding-right:var(--s3); }
.units { display:flex; gap:var(--s2); }
.unit { min-width:52px; min-height:52px; border:1px solid var(--line); border-radius:var(--r-md);
  background:var(--paper); font:inherit; font-weight:700; font-size:var(--t-base); cursor:pointer; }
.unit.on { background:var(--label); color:var(--label-ink); border-color:var(--label); }
.fboth { margin-top:var(--s2); font-size:var(--t-sm); color:var(--ink-3); font-family:var(--mono); }

.picks { display:flex; gap:var(--s2); flex-wrap:wrap; }
/* An explicit color, because a <button> with none inherits the platform's --
 * on iOS that is link blue, and every answer on the crew's form rendered as
 * though it were a hyperlink. -webkit-appearance for the same reason: Safari
 * will otherwise impose its own control shape over ours. */
.pick { flex:1 1 auto; min-height:var(--tap); padding:var(--s3) var(--s4); border:1px solid var(--line);
  border-radius:var(--r-md); background:var(--paper); font:inherit; font-size:var(--t-base); font-weight:700;
  color:var(--ink); -webkit-appearance:none; appearance:none;
  cursor:pointer; text-align:left; }
.pick.on { background:var(--label); color:var(--label-ink); border-color:var(--label); }

.stopfoot { margin-top:var(--s5); }
.stopneed { padding:var(--s3) var(--s3); border-radius:var(--r-md); background:var(--slab);
  font-size:var(--t-sm); color:var(--ink-2); margin-bottom:var(--s2); }
.stopshort { padding:var(--s3) var(--s3); border-radius:var(--r-md); border:1px solid var(--stake);
  color:var(--stake-ink); font-size:var(--t-sm); margin-bottom:var(--s2); background:var(--paper); }
.stopfoot .ui-btn.lg { width:100%; }

/* The photo control on a form is a full-width button with a sentence on it.
 * It was inheriting .shotbtn, which is a 62px icon square from the step list,
 * so the words wrapped one letter per line. */
.frow .shotbtn { width:100%; flex:1 1 auto; min-height:56px; padding:var(--s4) var(--s4);
  font-size:var(--t-lg); font-weight:800; line-height:1.2; color:var(--ink);
  -webkit-appearance:none; appearance:none; border:2px solid var(--line); border-radius:var(--r-md); }
.frow .shotbtn.has { background:var(--accent); color:var(--accent-ink); border-color:var(--accent); }

/* No signal, and what is still waiting to send. Fixed to the bottom because a
   crew scrolling a form must not lose sight of whether the office has it. */
.outbox { position:fixed; left:0; right:0; bottom:0; z-index:60;
  padding:var(--s3) var(--s4) calc(var(--s3) + env(safe-area-inset-bottom, 0px));
  font-size:var(--t-sm); font-weight:700; text-align:center;
  background:var(--label); color:var(--label-ink); }
/* Three states, and only one of them is a decision.
   Losing signal is a state. Work on its way is also a state — it used to be
   orange, and a crew read the orange as "the office is reviewing this, stop",
   and lost an afternoon standing about. Both are muted now.
   Orange is kept for a capture that has genuinely failed several times, which
   is the only one of the three where somebody has to decide something. */
.outbox.off { background:var(--ink-2); color:var(--chalk); }
.outbox.on  { background:var(--ink-2); color:var(--chalk); }
.outbox.on, .outbox.stuck { cursor:pointer; }
.outbox.stuck { background:var(--stake); color:var(--stake-on); }
.outbox[hidden] { display:none; }

/* What the bar is holding, one row each. */
.oblist { display:flex; flex-direction:column; gap:var(--s2); }
.obrow { display:grid; grid-template-columns:1fr auto; gap:var(--s1) var(--s3); align-items:center;
  border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper);
  padding:var(--s3); }
.obrow.bad { border-color:var(--stake); }
.obwhat { font-weight:700; }
.obwhen { grid-column:1; font-size:var(--t-xs); color:var(--ink-2); }
.obrow .ui-btn { grid-row:1 / span 2; }
body { padding-bottom:0; }

/* ---------- the form builder ----------
 * One row per question. Type is fixed once placed — changing a measurement
 * into a photograph halfway through a job would orphan what was captured.
 */
.fields { display:flex; flex-direction:column; gap:var(--s2); }
.fieldrow { border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper); padding:var(--s3) var(--s3); }
.fr-top { display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap; }
.fr-type { font-size:var(--t-xs); font-weight:800; text-transform:uppercase; letter-spacing:.06em;
  color:var(--ink-3); flex:0 0 auto; min-width:9ch; }
.fr-label { flex:1 1 200px; min-height:var(--tap); }
.fr-req { display:flex; align-items:center; gap:var(--s2); font-size:var(--t-xs); color:var(--ink-3); }
.fr-req input { width:18px; height:18px; }
.fr-opts { margin-top:var(--s2); display:flex; flex-direction:column; gap:var(--s2); }
.fr-opts textarea { width:100%; font-family:var(--mono); font-size:var(--t-sm); }
.fr-opts label { display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap; }
.fr-opts label input, .fr-opts label select { min-height:36px; }

/* The job number is shown, not asked for. A field somebody has to fill in is a
   decision they have to make; a line of text is just information. */
.jobnum { margin:calc(-1 * var(--s1)) 0 var(--s4); }
.jobnum b { font-family:var(--mono); color:var(--ink); letter-spacing:.04em; }
.jobnum .linky { padding-left:var(--s2); font-size:var(--t-xs); }

/* What the office sent, above anything the crew is asked for. */
.officebox { margin:var(--s4) 0; padding:var(--s4) var(--s4); border:1px solid var(--line);
  border-left:4px solid var(--accent); border-radius:var(--r-lg); background:var(--card); }
.ob-line { font-size:var(--t-md); color:var(--ink-2); margin-top:var(--s1); }
.ob-line b { color:var(--ink); font-weight:700; }

/* One thing to fill in opens straight to it — a list of one is a tap nobody
   should have to make. */
.stop.solo { border:0; background:transparent; }
.stop.solo .stopform { border-top:0; padding-left:0; padding-right:0; }
.soloref { font-size:var(--t-xs); font-weight:800; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-3); margin-bottom:var(--s1); }

/* One line to the crew, readable at arm's length, gone in five seconds.
   Anything they have to dismiss is a tap they should not owe us. */
.crewsay { position:fixed; left:0; right:0; top:0; z-index:70;
  padding:calc(var(--s4) + env(safe-area-inset-top, 0px)) var(--s4) var(--s4);
  background:var(--label); color:var(--label-ink); font-size:var(--t-base); font-weight:700;
  text-align:center; }
.crewsay[hidden] { display:none; }

/* ---------- the form builder ----------
 * The questions on the left, what the crew will see on the right. Both are
 * drawn by the same renderer, so the preview cannot drift from the tablet.
 */
.buildwrap { display:grid; grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr); gap:var(--s5);
  align-items:start; }
.buildcol { min-width:0; }
.phone { border:1px solid var(--line); border-radius:var(--r-lg); background:var(--slab);
  padding:var(--s4); max-height:60vh; overflow:auto; }
.phonein { background:var(--card); border-radius:var(--r-md); padding:var(--s4) var(--s4); }
.pv-head { font-size:var(--t-xs); font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  color:var(--ink-3); margin-bottom:var(--s3); }
.pv-note { margin-top:var(--s4); font-size:var(--t-xs); color:var(--ink-3); }
.phonein button, .phonein input, .phonein textarea, .phonein select { pointer-events:none; }

/* Everything conditional lives behind a line that says what it does, so a form
   with no conditions reads as a plain list of questions. */
.fr-when { margin-top:var(--s2); }
.fr-when > summary { cursor:pointer; font-size:var(--t-xs); color:var(--ink-3);
  padding:var(--s1) 0; list-style:none; }
.fr-when > summary::-webkit-details-marker { display:none; }
.fr-when > summary::before { content:'▸ '; }
.fr-when[open] > summary::before { content:'▾ '; }
.fr-when > summary b { color:var(--ink); }
.fr-sub { margin-top:var(--s2); display:flex; flex-direction:column; gap:var(--s2); }
.fr-sub textarea { width:100%; font-size:var(--t-sm); }
.fr-sub label { display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap; }
.fr-sub select { min-height:36px; max-width:100%; }

/* ---------- the day at a glance ----------
 * A crew loading seven poles wants to know from the truck window: which pole,
 * what kind of work, where, and how many are left. The number is the biggest
 * thing on the row because it is what they are looking for.
 */
.dayglance { margin:var(--s4) 0 var(--s3); }
.daycount { font-size:var(--t-md); color:var(--ink-2); margin-top:var(--s1); }
.daycount b { color:var(--ink); font-size:var(--t-base); }
.dayflag { color:var(--stake-ink); font-weight:700; }
.daybar { height:7px; border-radius:var(--r-pill); background:var(--slab-deep); overflow:hidden;
  margin-top:var(--s2); }
.daybar span { display:block; height:100%; background:var(--cure); color: var(--cure-on); }

.stoptop { display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap; }
.poleno { font-family:var(--mono); font-size:var(--t-figure); letter-spacing:.04em; }
.stoptagged { font-size:var(--t-md); color:var(--ink); }
.stop .stoptick { font-family:var(--mono); font-size:var(--t-sm); color:var(--ink-3); }
.stop.done .stoptick { color:var(--chalk); }

/* Which kind of work, in a word and a color. Removal is the one that cannot be
   undone, so it carries the strongest mark. */
.kindtag { font-size:var(--t-xs); font-weight:800; letter-spacing:.06em; text-transform:uppercase;
  padding:var(--s1) var(--s2); border-radius:var(--r-xs); background:var(--slab-deep); color:var(--ink-2); }
.kindtag.big { font-size:var(--t-sm); padding:var(--s1) var(--s3); }
.k-violation .kindtag { background:var(--stake); color:var(--stake-on); }
.k-transfer  .kindtag { background:var(--label); color:var(--label-ink); }
.k-removal   .kindtag { background:var(--night); color:var(--chalk); }
.k-violation { border-left:5px solid var(--stake); }
.k-transfer  { border-left:5px solid var(--label); }
.k-removal   { border-left:5px solid var(--ink); }

/* The pole, restated at the top of its own form. A crew scrolled into a long
   form should never scroll back up to check which pole they are on. */
.polehead { margin-bottom:var(--s4); padding-bottom:var(--s3); border-bottom:1px solid var(--line); }
.polehead-no { font-family:var(--mono); font-size:var(--t-title); font-weight:800; letter-spacing:.04em; }
.polehead-tag { margin-top:var(--s2); font-size:var(--t-base); font-weight:700; }
.polehead-where { margin-top:var(--s1); font-size:var(--t-sm); color:var(--ink-3); }
.polechange { margin:0 0 var(--s4); }
.polechange > summary { cursor:pointer; font-size:var(--t-sm); color:var(--ink-2); padding:var(--s2) 0; }

/* What the office sent with the job — a photograph that helps find the pole,
   an as-built to plan from. High on the screen, because a crew looking for a
   pole is looking now. */
.sentbox { margin:var(--s4) 0; padding:var(--s4) var(--s4); border:1px solid var(--line);
  border-radius:var(--r-lg); background:var(--card); }
.sentrow { display:flex; gap:var(--s2); flex-wrap:wrap; }
.sentfile { display:flex; flex-direction:column; gap:2px; padding:var(--s3) var(--s4); min-height:var(--tap);
  border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper); text-decoration:none;
  color:var(--ink); }
.sf-name { font-size:var(--t-md); font-weight:700; }
.sf-label { font-size:var(--t-xs); color:var(--ink-3); }

/* What the office says is outstanding at this place. A crew with gloves on
   reads lines, not a run-on sentence — and it is why they are stopped here. */
.polehead-for { margin-top:var(--s3); }
.polehead-for .eyebrow { display:block; margin-bottom:var(--s2); }
.polework { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:var(--s2); }
.polework li { display:flex; gap:var(--s2); align-items:baseline; font-size:var(--t-lg); font-weight:600;
  padding:var(--s2) var(--s3); border-radius:var(--r-md); background:var(--slab); }
.polework li.cleared { opacity:.55; text-decoration:line-through; }
.pw-kind { flex:0 0 auto; font-size:var(--t-xs); font-weight:800; letter-spacing:.06em;
  color:var(--ink-3); }

/* ---------- findings on a place ----------
 * Opened under the row rather than in a dialog: a dialog on top of a list, to
 * type one line, is three clicks and a lost sense of where you were.
 */
.worksum { display:block; width:100%; text-align:left; margin:0 0 var(--s3); padding:var(--s2) var(--s3);
  border:1px solid var(--stake); border-radius:var(--r-md); background:var(--paper); color:var(--stake-ink);
  font:inherit; font-size:var(--t-sm); font-weight:600; cursor:pointer; }
.worksum b { font-size:var(--t-base); }
.workpanel { margin:0 0 var(--s3); padding:var(--s3); border:1px solid var(--line); border-radius:var(--r-md);
  background:var(--slab); }
.workpanel[hidden] { display:none; }
.worklist { list-style:none; margin:0 0 var(--s3); padding:0; display:flex; flex-direction:column; gap:var(--s2); }
.worklist li { display:flex; align-items:center; gap:var(--s2); padding:var(--s2) var(--s3); border-radius:var(--r-sm);
  background:var(--paper); font-size:var(--t-md); }
.worklist li.cleared { opacity:.55; text-decoration:line-through; }
.wl-kind { flex:0 0 auto; font-size:var(--t-xs); font-weight:800; text-transform:uppercase;
  letter-spacing:.05em; color:var(--ink-3); min-width:8ch; }
.wl-note { flex:1; min-width:0; }
.workadd { display:flex; gap:var(--s2); flex-wrap:wrap; }
.workadd select { flex:0 0 auto; min-height:var(--tap); }
.workadd input { flex:1 1 240px; min-height:var(--tap); }

/* ---------- picking places for a day ----------
 * Opens filtered to the ones with work outstanding, because those are the ones
 * the office is looking for. Everything a row needs is on the row.
 */
.pickbar { display:flex; gap:var(--s3); align-items:center; flex-wrap:wrap; margin-bottom:var(--s3); }
.pickbar input[type=text], #pickSearch { flex:1 1 240px; min-height:var(--tap); }
.pickonly { display:flex; align-items:center; gap:var(--s2); font-size:var(--t-sm); color:var(--ink-2); }
.pickonly input { width:20px; height:20px; }
.picklist { max-height:52vh; overflow:auto; display:flex; flex-direction:column; gap:var(--s2);
  border:1px solid var(--line); border-radius:var(--r-md); padding:var(--s2); background:var(--slab); }
.pickrow { display:flex; align-items:flex-start; gap:var(--s3); padding:var(--s3) var(--s3); border-radius:var(--r-md);
  background:var(--paper); cursor:pointer; }
.pickrow.on { outline:2px solid var(--accent); }
.pickrow input { width:22px; height:22px; flex:0 0 auto; margin-top:2px; }
.pk-main { display:flex; flex-direction:column; gap:2px; min-width:0; }
.pk-top { display:flex; align-items:center; gap:var(--s2); }
.pk-top b { font-family:var(--mono); font-size:var(--t-base); letter-spacing:.03em; }
.pk-count { font-size:var(--t-xs); font-weight:800; padding:2px var(--s2); border-radius:var(--r-pill);
  background:var(--stake); color:var(--stake-on); }
.pk-where, .pk-work { font-size:var(--t-sm); color:var(--ink-3); overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.pk-work { color:var(--ink-2); }

/* ---------- the places on a day, as the office sees them ----------
 * A bare step list said "0 of 1 done" and nothing else. Everything the office
 * would otherwise open three screens to check is on the row.
 */
.wo-places { margin:var(--s4) 0 0; }
.wop-head { display:flex; align-items:center; gap:var(--s3); flex-wrap:wrap; margin-bottom:var(--s3); }
.wop-head .hot { color:var(--stake-ink); font-weight:700; }
.wop { border:1px solid var(--line); border-left:4px solid var(--line); border-radius:var(--r-md);
  background:var(--paper); padding:var(--s3) var(--s4); margin-bottom:var(--s2); }
.wop.done { opacity:.7; }
.wop.k-violation { border-left-color:var(--stake); }
.wop.k-transfer  { border-left-color:var(--label); }
.wop.k-removal   { border-left-color:var(--ink); }
.wop-top { display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap; }
.wop-tick { width:22px; height:22px; flex:0 0 auto; border-radius:50%; border:2px solid var(--line);
  display:flex; align-items:center; justify-content:center; font-size:var(--t-sm); font-weight:800; }
.wop.done .wop-tick { background:var(--cure); border-color:var(--cure); color:var(--cure-on); }
.wop-where { font-size:var(--t-sm); color:var(--ink-3); margin-top:var(--s1); }
.wop-sum { font-size:var(--t-sm); color:var(--ink-2); margin-top:var(--s1); }
.wop-work { list-style:none; margin:var(--s2) 0 0; padding:0; display:flex; flex-direction:column; gap:var(--s1); }
.wop-work li { font-size:var(--t-sm); }
.wop-work li::before { content:'· '; color:var(--ink-3); }
.wop-work li.cleared { opacity:.5; text-decoration:line-through; }

/* The five photographs, at a glance. Filled means it has come in. */
.wop-shots { display:flex; gap:var(--s1); flex-wrap:wrap; margin-top:var(--s2); }
.wop-shots .shot { font-size:var(--t-xs); font-weight:700; letter-spacing:.03em;
  padding:var(--s1) var(--s2); border-radius:var(--r-xs); border:1px dashed var(--line); color:var(--ink-3); }
.wop-shots .shot.got { border-style:solid; border-color:var(--accent); background:var(--accent);
  color:var(--accent-ink); }
.wop-need { margin-top:var(--s2); font-size:var(--t-sm); color:var(--stake-ink); }

/* Each finding is a thing the crew answers, not a line they read past.
   Tapping it opens the box the office verifies against. */
.polework li { padding:0; background:transparent; display:block; }
.pw-tap { display:flex; align-items:flex-start; gap:var(--s3); width:100%; text-align:left;
  padding:var(--s3) var(--s3); border:1px solid var(--line); border-radius:var(--r-md); background:var(--slab);
  font:inherit; color:var(--ink); -webkit-appearance:none; appearance:none;
  cursor:pointer; min-height:var(--tap); }
.polework li.ok .pw-tap { border-color:var(--cure); background:var(--paper); }
.pw-tick { flex:0 0 auto; width:24px; height:24px; border-radius:50%; border:2px solid var(--line);
  display:flex; align-items:center; justify-content:center; font-weight:800; font-size:var(--t-md); }
.polework li.ok .pw-tick { background:var(--cure); border-color:var(--cure); color:var(--cure-on); }
.pw-body { display:flex; flex-direction:column; gap:var(--s1); min-width:0; }
.pw-note { font-size:var(--t-lg); font-weight:600; }
.pw-said { font-size:var(--t-sm); color:var(--ink-2); font-weight:400; }
.pw-open { margin-top:var(--s2); padding:0 2px; }
.pw-open textarea { width:100%; font-size:var(--t-lg); margin-bottom:var(--s2); }
.pw-open .ui-btn.lg { width:auto; flex:1; }

/* ---------- the violations board ---------- */
.wkcard { border-left:4px solid var(--line); }
.wkcard.k-violation { border-left-color:var(--stake); }
.wkcard.k-transfer  { border-left-color:var(--label); }
.wkcard.k-removal   { border-left-color:var(--ink); }
.wkcard.done { opacity:.65; }
.wk-said { margin:0 0 var(--s3); padding:var(--s3) var(--s3); border-radius:var(--r-md); background:var(--slab);
  font-size:var(--t-md); }
.wk-said .eyebrow { display:block; margin-bottom:var(--s1); }

/* Type what you would say; the code is what gets stored. */
.codepick { position:relative; flex:0 1 200px; }
.codepick input { width:100%; min-height:var(--tap); font-family:var(--mono);
  text-transform:uppercase; }
.codehits { position:absolute; z-index:40; left:0; right:0; top:calc(100% + 4px);
  border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper); overflow:hidden;
  box-shadow:0 8px 24px var(--shade-b); max-height:240px; overflow-y:auto; }
.codehits[hidden] { display:none; }
.codehit { display:block; width:100%; text-align:left; padding:var(--s2) var(--s3); border:0;
  background:var(--paper); font:inherit; font-size:var(--t-sm); color:var(--ink); cursor:pointer; }
.codehit:hover, .codehit:focus { background:var(--slab); }
.codehit b { font-family:var(--mono); margin-right:var(--s2); }
.wl-code { color:var(--ink-3); font-weight:400; }

/* ---------- a list of rows ----------
 * A pole carries however many attachments it carries. Numbered because
 * "which one is this" is what a crew asks themselves, and because the office
 * reading it later needs the order to mean something.
 */
.listrows { display:flex; flex-direction:column; gap:var(--s2); }
/* (The compact side-by-side row was replaced by the section layout below —
   three inputs in a line is what the crew kept getting wrong.) */
/* Five columns do not fit a phone in one line, so they wrap — and every box
   carries its own label, because a wrapped header stops lining up with what is
   under it and that is how a midspan reading ends up in the pole box. */
.lr-m { display:flex; flex-direction:column; gap:2px; flex:1 1 5.5rem; min-width:0; }
.lr-cap { font-size:var(--t-xs); color:var(--ink-3); font-weight:700; }
.lr-n { flex:0 0 100%; font-family:var(--mono); font-size:var(--t-xs); font-weight:800;
  letter-spacing:.06em; color:var(--ink-3); }
.lr-n::before { content:'#'; }
.lr-cell { flex:1 1 0; min-width:0; min-height:var(--tap); font-size:var(--t-base); }
.lr-measure { width:100%; font-family:var(--mono); text-align:right; }
.lr-code { flex:0 1 8ch; font-family:var(--mono); }
.lr-code { text-align:left; text-transform:uppercase; }
.lr-x { flex:0 0 36px; min-height:var(--tap); border:0; background:transparent;
  color:var(--ink-3); font-size:var(--t-figure); line-height:1; cursor:pointer; }
.lr-x.ghost { pointer-events:none; }

/* Things only somebody standing at the pole can do, and all of them lost the
   moment they drive away. */
.polebtns { display:flex; gap:var(--s2); flex-wrap:wrap; margin:var(--s4) 0; }
.polebtns .ui-btn { flex:1 1 auto; min-height:var(--tap); }
.foundbox { margin:0 0 var(--s4); padding:var(--s4); border:2px solid var(--stake); border-radius:var(--r-md);
  background:var(--paper); }
.foundbox .eyebrow { display:block; margin-bottom:var(--s2); }
.foundbox textarea { width:100%; font-size:var(--t-lg); margin:var(--s2) 0; }
.foundbox .chk { margin:var(--s1) 0 var(--s3); }

/* Raise it, or re-sag it. Worked out from what the crew measured, with the
   numbers shown so an experienced hand can disagree with the arithmetic
   rather than with a verdict. */
.advice { margin:0 0 var(--s3); padding:var(--s3) var(--s4); border-radius:var(--r-md); border-left:5px solid var(--line);
  background:var(--slab); }
.advice.a-resag { border-left-color:var(--cure); }
.advice.a-raise { border-left-color:var(--label); }
.advice.a-engineering { border-left-color:var(--stake); }
.ad-head { font-size:var(--t-lg); font-weight:800; margin-bottom:var(--s1); }
.ad-why { font-size:var(--t-md); color:var(--ink-2); }
.ad-note { margin-top:var(--s2); font-size:var(--t-sm); color:var(--stake-ink); font-weight:600; }

/* One row per pole on the violations board, with its findings under it. */
.wkfinds { list-style:none; margin:var(--s3) 0; padding:0; display:flex; flex-direction:column; gap:var(--s2); }
.wkfinds li { display:flex; align-items:center; gap:var(--s3); flex-wrap:wrap;
  padding:var(--s2) var(--s3); border-radius:var(--r-sm); background:var(--slab); font-size:var(--t-md); }
.wkfinds li.done { opacity:.55; text-decoration:line-through; }
.wkfinds li.waiting { background:var(--paper); outline:1px solid var(--line); }
.wk-crew { flex:1 1 100%; font-size:var(--t-sm); color:var(--ink-2); }
.wk-crew::before { content:''; }

/* The truck a tablet is bolted into. One record for the pair. */
.truckrow { display:flex; gap:var(--s2); flex-wrap:wrap; margin-top:var(--s2); }
.tveh { flex:1 1 8rem; min-width:0; min-height:36px; font-size:var(--t-sm); }
.tveh:first-child { flex:2 1 12rem; }

/* A form that has fallen behind the ready-made one it came from. */
.behind { margin-top:var(--s2); padding:var(--s3) var(--s3); border-radius:var(--r-md); border:1px solid var(--accent);
  background:var(--paper); font-size:var(--t-sm); color:var(--ink-2); }
.behind .ui-btn { margin-top:var(--s2); }

/* The truck a tablet lives in, on the shelf card. */
.truckline { font-size:var(--t-xs); color:var(--ink-3); font-family:var(--mono);
  letter-spacing:.03em; margin-top:2px; }
/* Inside the card's padding, like everything else on it. It sat flush with
 * the edge, and the rounded corner took the first letter. */
.slotgear { margin:var(--s2) 0 0; padding:0 var(--s4); font-size:var(--t-xs); font-weight:700; color:var(--ink-2); text-align:left; }
.slate > .roll { margin:var(--s2) var(--s4) var(--s3); align-self:flex-start; }

/* The same verdict the crew gets, on the office's row. */
.wop-advice { margin-top:var(--s2); padding:var(--s2) var(--s3); border-radius:var(--r-sm); background:var(--slab);
  font-size:var(--t-sm); border-left:4px solid var(--line); }
.wop-advice.a-resag { border-left-color:var(--cure); }
.wop-advice.a-raise { border-left-color:var(--label); }
.wop-advice.a-engineering { border-left-color:var(--stake); }

/* ---------- the directory, grouped ----------
 * A shop and a supply yard are places you keep things; the rest are places you
 * go and work. On four hundred poles, a yard between two of them is lost.
 */
.dirgroup { margin-bottom:var(--s5); }
.dirgroup.pending .dirhead { color:var(--stake-ink); }
.dirhead { display:flex; align-items:center; gap:var(--s3); flex-wrap:wrap; margin:0 0 var(--s3); }
.dirhead .eyebrow { margin:0; }
.proposed { margin:0 0 var(--s3); padding:var(--s3) var(--s3); border-radius:var(--r-md);
  border:2px solid var(--stake); background:var(--paper); font-size:var(--t-sm); }
.proposed .ui-btn { margin-top:var(--s2); }

/* A pole the office does not have. It goes on today's list right away and
   waits for the office to check the number. */
.addplace { margin:var(--s4) 0; }
.ui-btn.wide { width:100%; min-height:var(--tap); }
.ap-open { padding:var(--s4); border:2px dashed var(--line); border-radius:var(--r-md); background:var(--paper); }
.ap-open .eyebrow { display:block; margin-bottom:var(--s2); }
.ap-open input { width:100%; font-size:var(--t-lg); margin-bottom:var(--s2); min-height:var(--tap); }

/* What this pole read last time. Offered, not assumed. */
.carried { margin:0 0 var(--s4); padding:var(--s4); border:2px solid var(--label);
  border-radius:var(--r-md); background:var(--paper); }
.carried .eyebrow { display:block; margin-bottom:var(--s2); }
.carried p { margin:0 0 var(--s3); font-size:var(--t-md); color:var(--ink-2); }

/* Mark off what you cleared, beside the violation photo. */
.clearbox { margin:var(--s4) 0; padding:var(--s4); border-radius:var(--r-md); background:var(--slab); }
.clearbox.todo { outline:2px solid var(--stake); background:var(--paper); }
.clearbox .eyebrow { display:block; margin-bottom:var(--s2); }
.polework.read li { background:transparent; padding:var(--s2) 0; }
.polework.read .pw-tick { border-color:var(--line); }

/* Out of the way: a trained hand's job at the end of a pole. */
.polemore { margin:var(--s4) 0; }
.polemore > summary { cursor:pointer; font-size:var(--t-sm); color:var(--ink-3);
  padding:var(--s3) 0; min-height:var(--tap); display:flex; align-items:center; }
.ui-btn.quiet { color:var(--ink-3); }

/* How many lines this pole carries — one, or nine. */
.listtop { display:flex; align-items:center; gap:var(--s2); margin-bottom:var(--s2); }
.lt-count { font-size:var(--t-xs); font-weight:800; letter-spacing:.05em; color:var(--ink-3);
  text-transform:uppercase; }
.lt-quick { display:flex; gap:var(--s2); }
.lt-quick .ui-btn { min-width:44px; min-height:38px; padding:0 var(--s3); }

/* "Someone else…" — the box only appears when it is needed. */
.lr-other { margin-top:var(--s1); }
.lr-other[hidden] { display:none; }

/* One click from a violation onto a truck. A pole with a violation on it is
   already actionable; inventing a work order to say so was the ceremony. */
.sendto { display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap; }
.sendto .ui-btn { min-height:38px; }

/* ---------- every truck, everything on it ---------- */
.truckcard .ct { font-size:var(--t-lg); }
.tk-stops { list-style:none; margin:var(--s3) 0; padding:0; display:flex; flex-direction:column; gap:var(--s1); }
.tk-stops li { display:flex; align-items:center; gap:var(--s3); padding:var(--s2) var(--s3); border-radius:var(--r-sm);
  background:var(--slab); border-left:4px solid var(--line); }
.tk-stops li.done { opacity:.55; }
.tk-stops li.k-violation { border-left-color:var(--stake); }
.tk-stops li.k-transfer  { border-left-color:var(--label); }
.tk-stops li.k-removal   { border-left-color:var(--ink); }
.tk-tick { width:20px; height:20px; flex:0 0 auto; border-radius:50%; border:2px solid var(--line);
  display:flex; align-items:center; justify-content:center; font-size:var(--t-xs); font-weight:800; }
.tk-stops li.done .tk-tick { background:var(--cure); border-color:var(--cure); color:var(--cure-on); }
.tk-gear { margin:var(--s3) 0; padding:var(--s3) var(--s3); border-radius:var(--r-md); background:var(--slab); }
.tk-gear .eyebrow { display:block; margin-bottom:var(--s1); }
.tk-gear ul { list-style:none; margin:0; padding:0; display:flex; flex-wrap:wrap; gap:var(--s2) var(--s4); }
.tk-gear li { font-size:var(--t-sm); }

/* ---------- the dispatcher's whole day ----------
 * A pole has violations. A pole with violations IS the work order. Put it on a
 * truck. That is the job, so that is the screen.
 */
#poleDash { margin-bottom:var(--s6); }
#poleDash[hidden] { display:none; }
/* The one title that is a figure: five hundred poles is the morning. */
.head-title h1.pd-count { font-size:clamp(38px, 7vw, 64px); line-height:1; letter-spacing:-.02em; }
.pd-bar { display:flex; gap:var(--s3); align-items:center; flex-wrap:wrap; margin-bottom:var(--s4); }
.pd-bar input { flex:1 1 260px; min-height:var(--tap); }

.pilecard { border:1px solid var(--line); border-left:5px solid var(--stake);
  border-radius:var(--r-md); background:var(--paper); padding:var(--s3) var(--s4); margin-bottom:var(--s2); }
.pilecard.out { border-left-color:var(--line); opacity:.62; }
.pc-top { display:flex; align-items:center; gap:var(--s3); flex-wrap:wrap; }
.pc-top .poleno { font-size:var(--t-lg); }
.pc-where { font-size:var(--t-sm); color:var(--ink-3); overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; max-width:32ch; }
.pc-work { list-style:none; margin:var(--s2) 0 0; padding:0; display:flex; flex-direction:column; gap:var(--s1); }
.pc-work li { display:flex; gap:var(--s2); align-items:baseline; font-size:var(--t-md); }

/* One pole, everything wrong with it, in one dialog. */
.npw { display:flex; gap:var(--s2); align-items:center; margin-bottom:var(--s2); }
.npw .codepick { flex:0 1 190px; }
.npw .ui-field { flex:1 1 220px; min-height:var(--tap); }

/* A truck's paperwork, at a glance. The alternative is finding out roadside. */
.paper { display:flex; gap:var(--s2); flex-wrap:wrap; margin-top:var(--s2); }
.pp { font-size:var(--t-xs); font-weight:700; padding:var(--s1) var(--s2); border-radius:var(--r-sm);
  border:1px solid var(--line); color:var(--ink-3); }
.pp.ok { border-color:var(--cure); color:var(--cure); }
.pp.soon { border-color:var(--accent); background:var(--accent); color:var(--accent-ink); }
.pp.expired { border-color:var(--stake); background:var(--stake); color:var(--stake-on); }
.pp.unknown { border-style:dashed; }
.paperbad { margin-top:var(--s2); font-size:var(--t-xs); font-weight:800; color:var(--stake-ink); }
.tdate { display:flex; flex-direction:column; gap:2px; flex:1 1 8rem; }
.tdate span { font-size:var(--t-xs); color:var(--ink-3); font-weight:700; }
.tdate input { min-height:36px; font-size:var(--t-sm); }

/* Three people, three mornings. */
.hv-switch { display:flex; gap:var(--s2); flex-wrap:wrap; margin-bottom:var(--s4); }
.hv { border:1px solid var(--line); background:var(--paper); color:var(--ink-2); font:inherit;
  font-size:var(--t-sm); font-weight:600; padding:var(--s2) var(--s3); border-radius:var(--r-pill);
  min-height:40px; cursor:pointer; }
.hv.on { background:var(--label); border-color:var(--label); color:var(--label-ink); }

/* Send the pile out without picking poles one at a time. */
.pd-quick { display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap; margin-bottom:var(--s4);
  padding:var(--s3) var(--s3); border-radius:var(--r-md); background:var(--slab); }
.pd-quick[hidden] { display:none; }

/* What the backlog means in days. */

/* The kit on a truck, counted and edited where you are looking at it. */
.kithead { display:flex; align-items:baseline; gap:var(--s3); margin-bottom:var(--s2); }
.kithead .eyebrow { margin:0; }
.kitlist { list-style:none; margin:0 0 var(--s3); padding:0;
  display:grid; grid-template-columns:repeat(auto-fill, minmax(190px, 1fr)); gap:var(--s2); }
.kitlist li { display:flex; align-items:center; gap:var(--s2); padding:var(--s2) var(--s2); border-radius:var(--r-sm);
  background:var(--paper); }
.kitqty { width:4.5rem; min-height:36px; font-family:var(--mono); text-align:right;
  font-size:var(--t-sm); }
.kitname { flex:1; min-width:0; font-size:var(--t-sm); font-weight:600; }
/* The kit's entry line is the one entry line; the count reads in mono. */
.kitadd { margin-top:var(--s3); }
.kitadd input[type=number] { text-align:right; font-family:var(--mono); }

/* The truck, described where the refusal happens. */
.truckline-edit { display:flex; gap:var(--s2); flex-wrap:wrap; margin-top:var(--s2); }
.truckline-edit input { flex:1 1 7rem; min-width:0; min-height:36px; font-size:var(--t-sm); }
.truckline-edit input:first-child { flex:2 1 11rem; }

/* ---------- the day, drawn ----------
 * No tiles and no outside service — this works with the internet off. It draws
 * the poles against each other: the shape of the run, what is done, what is
 * next. Navigation is a link handed to the phone, which is better at driving
 * directions than anything here would be.
 */
.daymap { margin:0 0 var(--s4); }
.mapshow { display:flex; align-items:center; justify-content:space-between; width:100%;
  padding:var(--s3) var(--s4); border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper);
  font:inherit; font-size:var(--t-lg); color:var(--ink); min-height:var(--tap); cursor:pointer;
  -webkit-appearance:none; appearance:none; }
.mapsvg { width:100%; height:auto; margin-top:var(--s3); border:1px solid var(--line);
  border-radius:var(--r-md); background:var(--slab); display:block; }
.maprun { fill:none; stroke:var(--ink-3); stroke-width:2; stroke-dasharray:5 4;
  stroke-linejoin:round; }
.mapdot circle { fill:var(--chalk); stroke:var(--stake); stroke-width:2.5; }
/* The numerals scale with the drawing, so 12px in a 320-wide viewBox renders
   larger than 12px on the phone. Sized to the floor anyway, and the dots grown
   to hold them — a number nobody can read is not a label. */
.mapdot text { font-family:var(--mono); font-size:var(--t-xs); font-weight:800; text-anchor:middle;
  fill:var(--ink); }
.mapdot.done circle { fill:var(--cure); stroke:var(--cure); }
.mapdot.done text { fill:var(--chalk); }
.mapdot.next circle { stroke:var(--ink); stroke-width:4; }
.maplist { list-style:none; margin:var(--s3) 0 0; padding:0; display:flex; flex-direction:column; gap:var(--s2); }
.maplist li { display:flex; align-items:center; gap:var(--s3); padding:var(--s2) var(--s3); border-radius:var(--r-md);
  background:var(--slab); }
.maplist li.done { opacity:.55; }
.ml-n { flex:0 0 22px; text-align:center; font-family:var(--mono); font-weight:800;
  font-size:var(--t-sm); }
.ml-main { flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.ml-main b { font-family:var(--mono); font-size:var(--t-lg); }

/* ---------- a row is a small section ----------
 * Three cramped inputs side by side is what the crew kept getting wrong. The
 * company comes first; the height below it says whose height it is and uses
 * the same control as every other height on the form.
 */
.listrow { display:block; padding:var(--s3); border:1px solid var(--line); border-radius:var(--r-md);
  background:var(--paper); margin-bottom:var(--s2); }
.lr-head { display:flex; align-items:center; gap:var(--s3); margin-bottom:var(--s2); }
.lr-who { font-size:var(--t-lg); }
.lr-head .lr-n { flex:0 0 auto; }
.lr-head .lr-x { margin-left:auto; }
.lr-field { margin-bottom:var(--s3); }
.lr-field:last-child { margin-bottom:0; }
.lr-field .flab { font-size:var(--t-sm); font-weight:700; color:var(--ink-2); margin-bottom:var(--s1); }
.lr-field .lr-cell { width:100%; min-height:var(--tap); font-size:var(--t-lg); }
.lr-field .measure .fval { flex:1; }


/* Never trapped in one pole. Which of how many, a step either side, and a way
   back to the whole list. */
.solonav { display:flex; align-items:stretch; gap:var(--s2); margin-bottom:var(--s4); }
.solonav .ui-btn { flex:0 0 56px; font-size:var(--t-figure); line-height:1; min-height:var(--tap); }
.solocount { flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:2px; padding:var(--s2); border:1px solid var(--line); border-radius:var(--r-md); background:var(--paper);
  font:inherit; color:var(--ink); cursor:pointer; min-height:var(--tap);
  -webkit-appearance:none; appearance:none; }
.solocount b { font-size:var(--t-lg); }
.ui-btn.lg.next { margin-top:var(--s4); background:var(--label); color:var(--label-ink);
  border-color:var(--label); }

/* A number, asked for properly. */
.bignum { width:100%; font-size:var(--t-title); text-align:center; font-family:var(--mono);
  min-height:64px; }
.cshape { max-width:15rem; min-height:38px; font-size:var(--t-sm); }

/* Work already dispatched on an older form — the gap that made every other
   fix invisible to the crew. */
.stalework { margin-top:var(--s2); padding:var(--s3) var(--s3); border-radius:var(--r-md);
  border:1px solid var(--stake); background:var(--paper); font-size:var(--t-sm); }
.stalework[hidden] { display:none; }
.stalework .ui-btn { margin-top:var(--s2); }

/* Which copy of the product this is. Quiet, always there, readable down a
   phone line. */
.buildstamp { margin:var(--s6) 0 var(--s3); text-align:center; font-family:var(--mono);
  font-size:var(--t-xs); color:var(--ink-3); letter-spacing:.04em; }

/* Forms that keep themselves in step. */
.autoforms { border:1px solid var(--line); border-radius:var(--r-md); padding:var(--s4) var(--s4);
  margin-bottom:var(--s4); background:var(--slab); }
.switchrow { display:flex; gap:var(--s3); align-items:flex-start; cursor:pointer; margin-bottom:var(--s3); }
.switchrow input { width:22px; height:22px; flex:0 0 auto; margin-top:2px; }
.switchrow b { display:block; }

/* The lens — which accounts the provider is looking at.
   Marked when it is narrowed, because a filtered screen that looks unfiltered
   is how somebody concludes their data has vanished. */
.lenspick { min-height:34px; font-size:var(--t-sm); font-weight:600; max-width:13rem;
  border-radius:var(--r-pill); padding:0 var(--s3); border:1px solid var(--line); background:var(--paper); }
.lenspick[hidden] { display:none; }
.lenspick.narrowed { border-color:var(--stake); color:var(--stake-ink); font-weight:800; }

/* ---------- finding a setting ----------
 * Ten sections in one scroll and no way to search meant reading every heading
 * on the way to the one you wanted.
 */
/* Setup as two columns: the sections down the left, the page on the right.
 * The left column sticks; the current section is marked as you read. */
.wrap.setup { display:grid; grid-template-columns:230px minmax(0,1fr); gap:var(--s3) var(--s6); align-items:start; }
.wrap.setup > .head { grid-column:1 / -1; }
.setbar { position:sticky; top:calc(var(--bar-h) + 12px); display:flex; flex-direction:column; gap:var(--s3); }
.setbar input[type=search] { width:100%; min-height:var(--tap); font-size:var(--t-base); }
.setjump { display:flex; flex-direction:column; gap:1px; position:sticky; top:calc(var(--bar-h) + var(--s4)); }
@media (max-width: 899.5px) {
  /* On a phone the rail is a row of pills above the section, scrolling sideways. */
  .setjump { flex-direction:row; overflow-x:auto; gap:var(--s2); position:static; scrollbar-width:none; padding-bottom:var(--s1); }
  .setjump::-webkit-scrollbar { display:none; }
  .setjump .sideh { display:none; }
  .setjump a { white-space:nowrap; flex:0 0 auto; border-radius:var(--r-pill); background:var(--card); box-shadow:var(--shadow); }
}
.setjump a { font-size:var(--t-sm); font-weight:700; color:var(--ink-2); text-decoration:none;
  padding:var(--s2) var(--s3); border-radius:var(--r-sm); border:0; min-height:36px; display:flex; align-items:center; }
.setjump a:hover { color:var(--ink); background:var(--slab); }
.setjump a.on { background:var(--brand); color:var(--brand-ink); }
.setjump a[hidden], .setjump .sideh[hidden] { display:none; }
.setjump .sideh { padding:var(--s3) var(--s3) var(--s1); }
.setjump .sideh:first-child { padding-top:0; }
.setadv { display:flex; align-items:center; gap:var(--s2); font-size:var(--t-sm); color:var(--ink-2); padding:var(--s2) var(--s3); border-top:1px solid var(--line); margin-top:var(--s2); }
.setadv input { width:18px; height:18px; min-height:0; margin:0; }
.setbody { min-width:0; }
.setnone { margin:var(--s4) 0 0; color:var(--ink-3); font-size:var(--t-sm); }
@media (max-width: 899.5px) { .wrap.setup { display:block; } .setbar { position:static; } .setjump { flex-direction:row; flex-wrap:wrap; } }
main section[id^="sec-"] { scroll-margin-top:96px; }

/* Adding tools at the pace somebody empties a garage. */
.toolrow { display:flex; gap:var(--s2); align-items:center; }
.toolrow input[type=number] { width:5rem; min-height:var(--tap); text-align:right;
  font-family:var(--mono); font-size:var(--t-lg); }
.toolrow input:not([type=number]) { flex:1; min-height:var(--tap); font-size:var(--t-lg); }
.toolrecent { margin-top:var(--s4); }
.toolrecent ul { list-style:none; margin:var(--s2) 0 0; padding:0;
  display:flex; flex-direction:column; gap:var(--s1); }
.toolrecent li { display:flex; gap:var(--s2); align-items:baseline; padding:var(--s2) var(--s3);
  border-radius:var(--r-sm); background:var(--slab); font-size:var(--t-md); }
.toolrecent li b { font-family:var(--mono); }
.toolrecent li .muted { margin-left:auto; }

/* ---------- the pile, at a glance ----------
 * Every finding printed its full text, so eight poles filled three screens and
 * the office scrolled past the thing they came for.
 */
.pc-work { margin:var(--s2) 0 0; }
.pc-work > summary { list-style:none; cursor:pointer; display:flex; gap:var(--s1);
  align-items:center; flex-wrap:wrap; }
.pc-work > summary::-webkit-details-marker { display:none; }
.wcode { font-family:var(--mono); font-size:var(--t-xs); font-weight:800;
  letter-spacing:.04em; padding:var(--s1) var(--s2); border-radius:var(--r-xs);
  background:var(--slab); color:var(--ink-2); }
.pc-see { font-size:var(--t-xs); color:var(--ink-3); }
.pc-work[open] > summary .pc-see { visibility:hidden; }
.pc-work ul { list-style:none; margin:var(--s2) 0 0; padding:0;
  display:flex; flex-direction:column; gap:var(--s1); }
.pc-work li { display:flex; gap:var(--s2); align-items:baseline; font-size:var(--t-sm); }
.pd-listhead { margin:0 0 var(--s3); font-size:var(--t-xs); font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; color:var(--ink-3); }

/* The morning warnings: one line each until somebody wants the detail. */
.alert > summary { list-style:none; cursor:pointer; display:flex; align-items:center;
  gap:var(--s3); }
.alert > summary::-webkit-details-marker { display:none; }
.alert .a-more { margin-left:auto; font-size:var(--t-xs); color:var(--ink-3); }
.alert[open] .a-more { visibility:hidden; }
.alert > div { margin-top:var(--s2); }

/* ---------- the timeless pass ----------
 * The trucks on a pile row: the suggestion is solid, the alternatives quiet,
 * and a gloved thumb gets air between them. */
.pc-trucks { display:inline-flex; gap:var(--s2); flex-wrap:wrap; align-items:center; }

/* ---------------- before the keys ----------------
 *
 * The morning check on the crew screen, and its one line on the shelf. The
 * shelf badge follows the product's own colors: hi-vis for a truck that
 * rolled, orange for one that is held, and quiet ink for one nobody has
 * started -- so the dispatcher's eye finds the problem, not the good news.
 */
.startprog { display: flex; flex-direction: column; gap:var(--s2); margin:var(--s1) 0 var(--s4); font-size: var(--t-md); color: var(--ink-2); }
.startprog b { color: var(--ink); font-variant-numeric: tabular-nums; }
.startform .kitrow .flab .need { font-size: var(--t-xs); color: var(--ink-3); margin-left:var(--s2); }
.startform .kitrow .flab .gt { font-size: var(--t-xs); color: var(--ink-3); margin-left:var(--s2); }
.startform .kitnone { margin:0 0 var(--s3); }
.startform .startnote { width: 100%; }
.rolled { display: flex; align-items: center; gap:var(--s2); margin:0 0 var(--s3); padding:var(--s2) var(--s3); border-radius: var(--r-sm); background: var(--accent); color: var(--accent-ink); font-size: var(--t-md); font-weight: 600; }
.rolled::before { content: '✓'; font-weight: 800; }

.roll { display: inline-block; margin-top:var(--s2); padding:var(--s1) var(--s2); border-radius: var(--r-pill); font-size: var(--t-xs); font-weight: 600; letter-spacing: .01em; line-height: 1.3; max-width: 100%; white-space: normal; text-align: left; background: var(--slab-deep); color: var(--ink-2); }
.roll.ready { background: var(--accent); color: var(--accent-ink); }
.roll.held { background: var(--stake); color: var(--stake-on); }
.roll.open { background: var(--card); color: var(--ink); border: 1px solid var(--line); }
.roll[data-start] { cursor: pointer; }
.roll[data-start]:hover { filter: brightness(.95); }

.startmeta { display: flex; flex-wrap: wrap; gap:var(--s2) var(--s4); font-size: var(--t-sm); color: var(--ink-2); margin:0 0 var(--s3); }
.startsaid { padding:var(--s2) var(--s3); border-left: 3px solid var(--line); margin:0 0 var(--s3); font-size: var(--t-md); white-space: pre-wrap; }
.startans { display: flex; justify-content: space-between; gap:var(--s3); padding:var(--s2) 0; border-bottom: 1px solid var(--line); font-size: var(--t-md); }
.startans .sa-l { color: var(--ink-2); }
.startans .sa-v { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Ink on the orange, not orange ink: orange text on the card is 3:1 and
 * fails the floor; the chip reads at 5.7:1 and matches the roll badge. */
.startans.held .sa-v { background: var(--stake); color: var(--stake-on); padding:1px var(--s2); border-radius: var(--r-pill); }
.startans.blank .sa-v { color: var(--ink-3); font-weight: 400; }

/* ---------------- the daily check, on the Trucks screen ----------------
 * The panel reads like a truck card so it belongs on the screen; the editor
 * is a list of sections and questions, because that is what the form is. */
.dcpanel { margin-bottom: var(--s3); }
.dcpanel .ct { font-size: var(--t-lg); }
.dcfacts { display: flex; flex-wrap: wrap; align-items: center; gap:var(--s2); margin-top:var(--s3); }
.dcseg { gap:0; }
.dcseg .ui-btn { border-radius: 0; }
.dcseg .ui-btn:first-child { border-radius: var(--r-sm) 0 0 var(--r-sm); }
.dcseg .ui-btn:last-child { border-radius: 0 var(--r-sm) var(--r-sm) 0; }
.dcrow { display: flex; flex-wrap: wrap; align-items: center; gap:var(--s2) var(--s3); margin-top:var(--s3); }
.dcrow .eyebrow { margin:0; }
.dcsec { padding:var(--s3) 0 var(--s2); border-top: 1px solid var(--line); }
.dcsec:first-child { border-top: 0; padding-top:0; }
.dcsec.kit { background: var(--slab); border-radius: var(--r-sm); padding:var(--s3) var(--s3); border-top: 0; margin:var(--s2) 0; }
.dcsechead { display: flex; align-items: center; gap:var(--s3); margin-bottom:var(--s2); }
.dcsechead input { flex: 1 1 auto; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; font-size: var(--t-xs); border: 1px solid transparent; border-radius: var(--r-xs); padding:var(--s1) var(--s2); background: transparent; }
.dcsechead input:focus { border-color: var(--line); background: var(--card); }
.dcq { display: flex; align-items: center; gap:var(--s2); padding:var(--s1) 0; }
.dcq input { flex: 1 1 auto; min-width: 0; }
.dcq .ui-chip { white-space: nowrap; flex: 0 0 auto; }
#dcDlg { max-width: 780px; }
.dcmove { display: flex; flex-direction: column; gap:1px; }
.dcmove button { border: 0; background: transparent; font-size: var(--t-xs); line-height: 1; padding:2px var(--s2); cursor: pointer; color: var(--ink-2); }
.dcmove button:disabled { color: var(--line); cursor: default; }
.ui-chip.hold { cursor: pointer; }
.ui-chip.hold.on { background: var(--stake); color: var(--stake-on); }
.dcadd { display: flex; flex-wrap: wrap; align-items: center; gap:var(--s2); margin-top:var(--s2); }
.dcadd input[data-dcnew] { flex: 1 1 200px; min-width: 0; }
/* Adding a section is the one entry line, ruled off from the questions above. */
.dcaddsec { border-top: 1px solid var(--line); padding-top:var(--s3); margin-top:var(--s3); }
.dcadd select { flex: 0 0 auto; width: auto; }
.dcadd label { display: inline-flex; align-items: center; gap:var(--s2); white-space: nowrap; flex: 0 0 auto; }
.dcadd label input[type="checkbox"] { width: 20px; height: 20px; min-height: 0; margin:0; flex: 0 0 auto; }

/* ---- the check-ins screen ----
 *
 * The manager's morning: four figures, one switch, a card per truck. Every
 * color here is a status the product already has -- go, wait, stop -- read
 * through the same tokens the shelf uses, so a held truck is the same red on
 * both screens and a waiting one the same amber. */
.cifacts .fact { cursor: pointer; text-align: left; }
.cifacts .fact.on { outline: 2px solid var(--accent); outline-offset: -2px; }
.cifacts .fact.good b { color: var(--cure-ink); }
.cifacts .fact.bad { background: var(--tint-stop); color: var(--stop-ink); }
.cifacts .fact.bad b, .cifacts .fact.bad span { color: var(--stop-ink); }
.cifacts .fact.zero b { color: var(--ink-3); }
.cimode { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s3) var(--s4); margin-bottom: var(--s4); }
.cimode .ct { font-size: var(--t-lg); font-weight: 800; }
.cimode .cm { flex: 1 1 320px; }
.cimode p { margin: var(--s1) 0 0; max-width: 60ch; }
.ci-note { margin: 0 0 var(--s3); max-width: 70ch; }
.cigrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--s3); margin-bottom: var(--s5); align-items: start; }
.cicard { display: flex; flex-direction: column; gap: var(--s2); border-left: 5px solid var(--line); }
.cicard.ready { border-left-color: var(--cure); }
.cicard.sent { border-left-color: var(--wait); background: var(--tint-wait); color: var(--wait-ink); }
.cicard.held { border-left-color: var(--stake); }
.cicard.open { border-left-color: var(--plan); }
.cicard.off { opacity: .7; }
.ci-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s3); }
.ci-name b { font-size: var(--t-lg); display: block; }
.ci-name span { font-size: var(--t-sm); color: var(--ink-2); }
.cicard.sent .ci-name span { color: var(--wait-ink); }
.ci-pill { flex: 0 0 auto; padding: var(--s1) var(--s3); border-radius: var(--r-pill); font-size: var(--t-xs); font-weight: 800; letter-spacing: .04em; text-transform: uppercase; background: var(--slab-deep); color: var(--ink-2); }
.ci-pill.ready { background: var(--cure); color: var(--cure-on); }
.ci-pill.sent { background: var(--wait); color: var(--wait-on); }
.ci-pill.held { background: var(--stake); color: var(--stake-on); }
.ci-pill.open { background: var(--plan); color: var(--plan-on); }
.ci-meta { display: flex; flex-wrap: wrap; gap: var(--s1) var(--s3); font-size: var(--t-sm); color: var(--ink-2); }
.cicard.sent .ci-meta, .cicard.sent .tiny.muted { color: var(--wait-ink); }
.cibar { margin: var(--s1) 0; }
.ci-said { font-size: var(--t-md); color: var(--ink-2); font-style: italic; }
.ci-shots { margin: var(--s1) 0; }
.ci-shots .shot { width: 72px; height: 72px; }
.ci-acts { margin-top: auto; align-items: center; }
.ci-two { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: var(--s4); }
.cilist { display: flex; flex-direction: column; gap: 2px; width: 100%; text-align: left; padding: var(--s3) var(--s4); border: 1px solid var(--line); border-radius: var(--r-md); background: var(--card); color: var(--ink); cursor: pointer; margin-bottom: var(--s2); font: inherit; }
.cilist:hover { border-color: var(--ink); }
.cl-name { font-weight: 800; font-size: var(--t-base); display: flex; align-items: center; gap: var(--s2); }
.cl-facts { font-size: var(--t-sm); color: var(--ink-2); }
.cilib { align-items: center; gap: var(--s3); }
.cilib a { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); font-weight: 600; }
.ciq .panelhead { margin-bottom: var(--s2); }
.ciqrow { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s2) var(--s4); padding: var(--s3) 0; border-top: 1px solid var(--line); }
.ciq-l { font-size: var(--t-sm); color: var(--ink-2); flex: 1 1 280px; }
.ciq-l b { color: var(--ink); }
.ciq-t { font-size: var(--t-base); color: var(--ink); font-weight: 600; margin-top: 2px; }
.roll.sent { background: var(--wait); color: var(--wait-on); }
.dclisthead { display: grid; gap: var(--s3); margin-bottom: var(--s3); padding-bottom: var(--s3); border-bottom: 1px solid var(--line); }
.dctrucks { display: flex; flex-wrap: wrap; gap: var(--s2); }
.dctruck { display: inline-flex; align-items: center; gap: var(--s2); padding: var(--s2) var(--s3); border: 1px solid var(--line); border-radius: var(--r-pill); font-size: var(--t-sm); font-weight: 600; cursor: pointer; background: var(--card); color: var(--ink); }
.dctruck.on { background: var(--tint-go); border-color: var(--go-ink); color: var(--go-ink); }
.dctruck input { width: 18px; height: 18px; min-height: 0; margin: 0; }
.dcstdnote { flex: 1 1 100%; }
@media (prefers-reduced-motion: reduce) { .cicard, .cifacts .fact { transition: none; } }
.ci-dvir { display: inline-block; vertical-align: middle; margin-left: var(--s2); padding: 2px var(--s2); border-radius: var(--r-xs); background: var(--label); color: var(--label-ink); font-size: var(--t-xs); font-weight: 800; letter-spacing: .1em; }
.ci-shots .shot { width: 112px; height: 112px; }
/* ---- one truck, opened from its card ---- */
.truckgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: var(--s4); align-items: start; }
.tk-col { display: grid; gap: var(--s4); }
.tk-check { display: grid; gap: var(--s2); }
.tk-checkhead { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; }
.tk-answers { max-height: 260px; overflow: auto; }
.tk-days { display: grid; gap: var(--s2); }
.tk-day { display: flex; align-items: center; gap: var(--s3); width: 100%; text-align: left; padding: var(--s2) var(--s3); border: 1px solid var(--line); border-radius: var(--r-md); background: var(--card); color: var(--ink); font: inherit; cursor: pointer; }
.tk-day:hover { border-color: var(--ink); }
.tk-day b { flex: 1 1 auto; }
.tk-tag { text-align: center; }
.tk-qr { width: 200px; height: 200px; display: block; margin: 0 auto var(--s3); }
.tk-tag .ui-btns { justify-content: center; margin-top: var(--s3); }
.tk-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--s3); }
.tk-kit { margin-top: var(--s4); }
.cicard[role="button"] { cursor: pointer; }
.cicard[role="button"]:hover { border-color: var(--ink); }
.cicard[role="button"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* ---- the lasher, and a note on the truck ---- */
.lasher { display: inline-flex; align-items: center; gap: var(--s1); padding: 2px var(--s2) 2px var(--s2); border-radius: var(--r-pill); background: var(--cat-2-tint); color: var(--cat-2-ink); border: 1px solid var(--cat-2); font-size: var(--t-xs); font-weight: 800; letter-spacing: .04em; }
.lasher .ico { width: 16px; height: 16px; }
.lasher.t-b { background: var(--cat-1-tint); color: var(--cat-1-ink); border-color: var(--cat-1); }
.lasher.t-c { background: var(--cat-3-tint); color: var(--cat-3-ink); border-color: var(--cat-3); }
.lasher.t-d { background: var(--cat-4-tint); color: var(--cat-4-ink); border-color: var(--cat-4); }
.lasher.t-g, .lasher.t-j, .lasher.t-j2 { background: var(--cat-5-tint); color: var(--cat-5-ink); border-color: var(--cat-5); }
.lasher.t-m { background: var(--cat-6-tint); color: var(--cat-6-ink); border-color: var(--cat-6); }
.ci-lashers { display: flex; flex-wrap: wrap; gap: var(--s1); }
.ci-note { display: flex; gap: var(--s2); align-items: flex-start; padding: var(--s2) var(--s3); border-radius: var(--r-sm); background: var(--tint-plan); color: var(--plan-ink); font-size: var(--t-sm); font-weight: 600; }
.ci-note .ico { width: 16px; height: 16px; flex: 0 0 auto; margin-top: 2px; }
.tk-note { width: 100%; min-height: 64px; }
.tk-shared { display: grid; gap: var(--s2); margin-bottom: var(--s3); }
.tk-sharedrow { display: flex; align-items: center; gap: var(--s3); padding: var(--s2) 0; border-bottom: 1px solid var(--line); }
.fleetadd { justify-content: center; margin: var(--s4) 0 var(--s6); }
.invquick { margin-bottom: var(--s4); }
.invquick .line { display: flex; gap: var(--s2); flex-wrap: wrap; }
.invquick .line input { flex: 1 1 220px; min-width: 0; }
.invquick .line select { flex: 0 1 200px; }
.invwhere { min-width: 160px; }
.is-lasher { border-left: 5px solid var(--cat-2); }
.tk-lasher .tk-sharedrow select { flex: 0 1 220px; }
/* ---- a field that reads as solid text until it is pressed ---- */
.f.pen .lab { display: flex; align-items: center; gap: var(--s1); }
.f.pen .lab .pen { width: 14px; height: 14px; color: var(--ink-3); }
.f.pen input, .f.pen select, .f.pen textarea { border-color: transparent; background: transparent; padding-left: 0; font-weight: 700; color: var(--ink); }
.f.pen input::placeholder, .f.pen textarea::placeholder { font-weight: 400; color: var(--ink-3); }
.f.pen input:hover, .f.pen select:hover, .f.pen textarea:hover { border-color: var(--line); background: var(--card); padding-left: var(--s3); }
.f.pen input:focus, .f.pen select:focus, .f.pen textarea:focus { border-color: var(--ink); background: var(--card); padding-left: var(--s3); font-weight: 500; }
.f.pen textarea { padding-left: 0; }
.f.is-saved .lab::after { content: 'Saved'; margin-left: auto; font-size: var(--t-xs); font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--cure-ink); }
#view-fleet .head-acts { flex-wrap: nowrap; align-items: center; }
#view-fleet .head-acts #fleetDay { width: auto; }
.tk-card .tk-facts { margin: var(--s3) 0; }
