/* ═══════════════════════════════════════════════════════════════
   WORK TASKS — job tickets on a steel shop board.
   Three colours only: safety orange (act), chalk yellow (weekend),
   alarm red (urgent). Everything else is steel.

   Everything is scoped to .wtb so the board's own palette and type
   never leak into the rest of the app.
   ═══════════════════════════════════════════════════════════════ */

.wtb {
  /* Light — the app's default theme */
  --wtb-board: #EEEFF1;
  --wtb-plate: #FFFFFF;
  --wtb-raise: #F6F7F8;
  --wtb-sink:  #E9EAEC;
  --wtb-line:  #DCDEE1;
  --wtb-line-hi: #BFC3C8;
  --wtb-ink:   #0F1114;
  --wtb-ink-2: #5A626B;
  --wtb-ink-3: #878F98;
  --wtb-act:   #E6480D;
  --wtb-act-hi:#C93C08;
  --wtb-act-ink: #FFFFFF;
  --wtb-wknd:  #E9C34A;
  --wtb-wknd-ink: #12140F;
  --wtb-wknd-txt: #94700A;
  --wtb-alarm: #D93025;
  --wtb-live:  #0F8A5F;
  --wtb-photo-bg: #DEE1E4;
  --wtb-pop-shadow: 0 18px 44px rgba(15, 17, 20, 0.16);
  /* The band down the left edge: what kind of work this is. Same hues the
     rest of the app gives these categories, pulled toward the board's steel. */
  --wtb-pay-paid: #0E9F6E;
  --wtb-pay-commission: #7C5CF0;
  --wtb-pay-future: #98A1AC;
  --wtb-band: 4px;

  --wtb-f-c: 'IBM Plex Sans Condensed', 'Outfit', sans-serif;
  --wtb-f-b: var(--font-body);
  --wtb-f-m: var(--font-mono);
  --wtb-r: 4px;

  display: block;
  min-width: 0;
  max-width: 100%;
  color: var(--wtb-ink);
  font-size: 13px;
  line-height: 1.5;
}

[data-theme="dark"] .wtb {
  --wtb-board: #0B0C0E;
  --wtb-plate: #15171A;
  --wtb-raise: #1C1F23;
  --wtb-sink:  #101215;
  --wtb-line:  #262A2F;
  --wtb-line-hi: #3A4047;
  --wtb-ink:   #F2F4F6;
  --wtb-ink-2: #9AA1AA;
  --wtb-ink-3: #646C76;
  --wtb-act:   #FF5C1A;
  --wtb-act-hi:#FF7A45;
  --wtb-act-ink: #0B0C0E;
  --wtb-wknd:  #EBCB5B;
  --wtb-wknd-ink: #0B0C0E;
  --wtb-wknd-txt: #EBCB5B;
  --wtb-alarm: #FF453A;
  --wtb-live:  #35D6A0;
  --wtb-photo-bg: #0E1013;
  --wtb-pop-shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
  --wtb-pay-paid: #2BD49B;
  --wtb-pay-commission: #A78BFA;
  --wtb-pay-future: #59626D;
}

.wtb *, .wtb *::before, .wtb *::after { box-sizing: border-box; }
.wtb button { font: inherit; color: inherit; }
.wtb :focus-visible { outline: 2px solid var(--wtb-act); outline-offset: 2px; }
.wtb-signedout { padding: 60px 20px; text-align: center; color: var(--text-muted); }

/* The board wants breathing room under the pinned running bar. */
.wtb .pg-content { padding-bottom: 140px; }

.wtb-lbl {
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 11px;
  letter-spacing: .09em; text-transform: uppercase; color: var(--wtb-ink-3);
}
.wtb-num { font-family: var(--wtb-f-m); font-weight: 500; font-variant-numeric: tabular-nums; }

/* ═══════════ MASTHEAD ═══════════ */
.wtb-mast {
  display: flex; align-items: flex-end; gap: 14px 18px; flex-wrap: wrap;
  padding-bottom: 14px; border-bottom: 1px solid var(--wtb-line);
}
.wtb-mast__lead { min-width: 0; }
.wtb-mast__sp { flex: 1; min-width: 20px; }
.wtb-tally { display: flex; flex-wrap: wrap; }
.wtb-tally__i { padding-right: 14px; margin-right: 14px; border-right: 1px solid var(--wtb-line); }
.wtb-tally__i:last-child { border-right: 0; margin-right: 0; padding-right: 0; }
.wtb-tally__n {
  display: block; font-family: var(--wtb-f-m); font-weight: 500; font-size: 17px;
  line-height: 1.1; color: var(--wtb-ink); font-variant-numeric: tabular-nums;
}
.wtb-tally__n em { font-style: normal; font-size: 11px; color: var(--wtb-ink-3); margin-left: 3px; }
.wtb-tally__l { display: block; margin-top: 2px; font-size: 10px; }
/* Overdue only shouts when there is something to shout about. */
.wtb-tally__i--overdue.is-hot .wtb-tally__n,
.wtb-tally__i--overdue.is-hot .wtb-tally__l { color: var(--wtb-alarm); }

/* ═══════════ TICKER (phone totals) ═══════════ */
.wtb-ticker { display: none; }
@media (max-width: 920px) {
  .wtb-ticker {
    display: flex; align-items: baseline; gap: 14px; overflow-x: auto; white-space: nowrap;
    scrollbar-width: none; padding: 2px 0 8px; border-bottom: 1px solid var(--wtb-line);
    font-family: var(--wtb-f-c); font-weight: 600; font-size: 11px; letter-spacing: .08em;
    text-transform: uppercase; color: var(--wtb-ink-3);
  }
  .wtb-ticker::-webkit-scrollbar { display: none; }
  .wtb-ticker__i { flex-shrink: 0; }
  .wtb-ticker__i b { font-family: var(--wtb-f-m); font-weight: 500; font-size: 14px; color: var(--wtb-ink); letter-spacing: 0; }
  .wtb-ticker__i b em { font-style: normal; font-size: 10px; color: var(--wtb-ink-3); margin-left: 1px; }
  .wtb-ticker__i--overdue.is-hot, .wtb-ticker__i--overdue.is-hot b { color: var(--wtb-alarm); }
}
@media (max-width: 360px) {
  .wtb-ticker__i--wknd { display: none; }
  /* The blinking square is enough on the narrowest phones; the words cost the title its room. */
  .wtb-run__lbl { display: none; }
  /* ~150px of meta line: tighter type, and the pay token goes first. */
  .wtb-ln__m { font-size: 10px; letter-spacing: .04em; }
  .wtb-ln__dot { margin: 0 2px; }
  .wtb-ln__pay { display: none; }
}

/* ═══════════ BUTTONS ═══════════ */
.wtb-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 0 15px; height: 34px; border: 1px solid var(--wtb-line-hi); background: transparent;
  color: var(--wtb-ink); font-family: var(--wtb-f-c); font-weight: 600; font-size: 13px;
  letter-spacing: .06em; text-transform: uppercase; cursor: pointer; white-space: nowrap;
  border-radius: 0; transition: background .14s, border-color .14s, color .14s;
}
.wtb-btn:hover { background: var(--wtb-raise); border-color: var(--wtb-ink-3); }
.wtb-btn svg { width: 15px; height: 15px; }
.wtb-btn--act { background: var(--wtb-act); border-color: var(--wtb-act); color: var(--wtb-act-ink); }
.wtb-btn--act:hover { background: var(--wtb-act-hi); border-color: var(--wtb-act-hi); color: var(--wtb-act-ink); }
.wtb-btn--stop { background: var(--wtb-alarm); border-color: var(--wtb-alarm); color: #fff; }
.wtb-btn--stop:hover { filter: brightness(1.1); }
.wtb-btn--sm { height: 32px; padding: 0 12px; font-size: 12px; }

/* ═══════════ VIEW SWITCHES ═══════════ */
.wtb-tset { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.wtb-ftog {
  display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 12px;
  border: 1px solid var(--wtb-line-hi); background: transparent; color: var(--wtb-ink-2);
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 12.5px; letter-spacing: .07em;
  text-transform: uppercase; cursor: pointer; border-radius: 0; white-space: nowrap;
  transition: background .14s, border-color .14s, color .14s;
}
.wtb-ftog:hover { background: var(--wtb-raise); color: var(--wtb-ink); }
.wtb-ftog[aria-pressed="true"] { background: var(--wtb-ink); border-color: var(--wtb-ink); color: var(--wtb-board); }
.wtb-ftog svg { width: 15px; height: 15px; }
/* The badge only appears when filters are hidden but still narrowing the board. */
.wtb-ftog__n { font-size: 11px; padding: 0 5px; background: var(--wtb-act); color: var(--wtb-act-ink); }
/* Hidden filter bar — the toggle is the only way back. */
.wtb-filters[hidden] { display: none; }
.wtb-seg, .wtb-lay { display: flex; flex-shrink: 0; }
.wtb-seg__b {
  height: 34px; padding: 0 14px; border: 1px solid var(--wtb-line-hi); background: transparent;
  color: var(--wtb-ink-2); font-family: var(--wtb-f-c); font-weight: 600; font-size: 12.5px;
  letter-spacing: .07em; text-transform: uppercase; cursor: pointer; margin-left: -1px; border-radius: 0;
}
.wtb-seg__b:first-child { margin-left: 0; }
.wtb-seg__b:hover { color: var(--wtb-ink); background: var(--wtb-raise); }
.wtb-seg__b[aria-pressed="true"] { background: var(--wtb-ink); border-color: var(--wtb-ink); color: var(--wtb-board); }
.wtb-lay__b {
  width: 34px; height: 34px; display: grid; place-items: center; border: 1px solid var(--wtb-line-hi);
  background: transparent; color: var(--wtb-ink-2); cursor: pointer; margin-left: -1px; border-radius: 0;
}
.wtb-lay__b:first-child { margin-left: 0; }
.wtb-lay__b:hover { background: var(--wtb-raise); color: var(--wtb-ink); }
.wtb-lay__b[aria-pressed="true"] { background: var(--wtb-ink); border-color: var(--wtb-ink); color: var(--wtb-board); }
.wtb-lay__b svg { width: 17px; height: 17px; }

/* ═══════════ FILTER BAR ═══════════ */
.wtb-filters {
  display: flex; align-items: stretch; flex-wrap: wrap;
  border: 1px solid var(--wtb-line); background: var(--wtb-plate);
}
.wtb-fx { display: flex; align-items: center; gap: 6px; padding: 7px 10px; border-right: 1px solid var(--wtb-line); min-width: 0; }
.wtb-fx:last-child { border-right: 0; }
.wtb-fx__lbl { padding-right: 2px; flex-shrink: 0; }
.wtb-fx__scroll { display: flex; align-items: center; gap: 6px; min-width: 0; overflow-x: auto; }
.wtb-fx--find { flex: 1 1 200px; min-width: 0; gap: 10px; padding-left: 14px; }
.wtb-fx--crew { min-width: 0; }

.wtb-find__i { width: 16px; height: 16px; color: var(--wtb-ink-3); flex-shrink: 0; }
.wtb-find__i svg { width: 100%; height: 100%; display: block; }
.wtb-find__in {
  flex: 1; min-width: 0; background: transparent; border: 0; outline: none; color: var(--wtb-ink);
  font-family: var(--wtb-f-b); font-size: 13.5px; padding: 6px 0;
}
.wtb-find__in::placeholder { color: var(--wtb-ink-3); }
.wtb-find__in::-webkit-search-cancel-button,
.wtb-find__in::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }
.wtb-find__x { width: 24px; height: 24px; display: none; place-items: center; border: 0; background: transparent; color: var(--wtb-ink-3); cursor: pointer; }
.wtb-find__x svg { width: 13px; height: 13px; }
.wtb-find__x:hover { color: var(--wtb-ink); }
.wtb-filters.is-q .wtb-find__x { display: grid; }

.wtb-fb {
  display: inline-flex; align-items: center; gap: 7px; height: 32px; padding: 0 10px; white-space: nowrap;
  border: 1px solid transparent; background: transparent; color: var(--wtb-ink-2); cursor: pointer;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 12px; letter-spacing: .07em;
  text-transform: uppercase; border-radius: 0; flex-shrink: 0;
}
.wtb-fb:hover { background: var(--wtb-raise); color: var(--wtb-ink); }
.wtb-fb[aria-pressed="true"] { background: var(--wtb-ink); color: var(--wtb-board); }
.wtb-fb svg { width: 15px; height: 15px; }
.wtb-fb--av { padding: 0 11px 0 3px; }
.wtb-fb .wtb-av { width: 26px; height: 26px; }
.wtb-fb[aria-pressed="true"] .wtb-av { background: var(--wtb-board); border-color: var(--wtb-board); color: var(--wtb-ink); }
.wtb-fb .wtb-num { font-size: 11px; opacity: .6; }
.wtb-fb--flag[aria-pressed="true"] { background: var(--wtb-alarm); color: #fff; }
.wtb-fb--done[aria-pressed="true"] { background: var(--wtb-ink-2); color: var(--wtb-board); }
.wtb-fclear { display: none; margin-left: 6px; border-color: var(--wtb-line); border-style: solid; color: var(--wtb-ink-3); }
.wtb-fclear:hover { color: var(--wtb-ink); border-color: var(--wtb-line-hi); }
.wtb-filters.is-on .wtb-fclear { display: inline-flex; }

.wtb-av {
  width: 32px; height: 32px; flex-shrink: 0; background: var(--wtb-raise); border: 1px solid var(--wtb-line);
  display: grid; place-items: center; overflow: hidden; border-radius: 0;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 11px; letter-spacing: .05em; color: var(--wtb-ink-2);
}
.wtb-av svg { width: 15px; height: 15px; }

/* ═══════════ SECTIONS ═══════════ */
.wtb-sections { display: block; }
.wtb-sec { margin-bottom: 44px; }
.wtb-sec:last-child { margin-bottom: 0; }
.wtb-sec__head { display: flex; align-items: center; gap: 16px; margin-bottom: 18px; }
.wtb-sec__ix { font-family: var(--wtb-f-m); font-weight: 500; font-size: 12px; color: var(--wtb-ink-3); padding-top: 3px; flex-shrink: 0; }
.wtb-sec__t {
  font-family: var(--wtb-f-c); font-weight: 700; font-size: 25px; line-height: 1;
  letter-spacing: .05em; text-transform: uppercase; margin: 0; flex-shrink: 0; color: var(--wtb-ink);
}
.wtb-sec__rule { flex: 1; height: 1px; background: var(--wtb-line); min-width: 20px; }
.wtb-sec__stat { font-family: var(--wtb-f-m); font-weight: 500; font-size: 12px; color: var(--wtb-ink-2); white-space: nowrap; flex-shrink: 0; }
.wtb-sec__stat b { color: var(--wtb-ink); font-weight: 500; }
.wtb-sec__note { margin: -10px 0 18px; color: var(--wtb-ink-3); font-size: 12.5px; max-width: 62ch; }
.wtb-sec--this-saturday .wtb-sec__t, .wtb-sec--this-saturday .wtb-sec__ix,
.wtb-sec--this-sunday .wtb-sec__t, .wtb-sec--this-sunday .wtb-sec__ix,
.wtb-sec--next-saturday .wtb-sec__t, .wtb-sec--next-saturday .wtb-sec__ix,
.wtb-sec--next-sunday .wtb-sec__t, .wtb-sec--next-sunday .wtb-sec__ix { color: var(--wtb-wknd-txt); }
.wtb-sec--overdue .wtb-sec__t, .wtb-sec--overdue .wtb-sec__ix { color: var(--wtb-alarm); }
.wtb-sec--done .wtb-sec__t, .wtb-sec--done .wtb-sec__ix { color: var(--wtb-ink-3); }
.wtb-sec--done .wtb-row__t, .wtb-sec--done .wtb-tk__t { color: var(--wtb-ink-2); }

.wtb-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); }

/* ═══════════ JOB TICKET (card layout) ═══════════ */
.wtb-tk {
  display: flex; flex-direction: column; position: relative;
  background: var(--wtb-plate); border: 1px solid var(--wtb-line); border-radius: var(--wtb-r);
  transition: border-color .15s;
}
.wtb-tk:hover { border-color: var(--wtb-line-hi); }
.wtb-tk.is-drop { border-color: var(--wtb-act); box-shadow: inset 0 0 0 1px var(--wtb-act); }
.wtb-tk--urgent { border-top: 2px solid var(--wtb-alarm); }
.wtb-tk--run { border-color: var(--wtb-act); box-shadow: inset 0 0 0 1px var(--wtb-act); }

.wtb-tk__shot {
  display: block; width: 100%; aspect-ratio: 3 / 2; background: var(--wtb-photo-bg);
  overflow: hidden; border: 0; padding: 0; cursor: zoom-in; position: relative;
  border-radius: calc(var(--wtb-r) - 1px) calc(var(--wtb-r) - 1px) 0 0;
}
.wtb-tk__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wtb-tk__shot--empty {
  cursor: pointer; display: grid; place-items: center; gap: 9px; color: var(--wtb-ink-3);
  background: repeating-linear-gradient(-45deg, var(--wtb-sink) 0 9px, transparent 9px 18px);
}
.wtb-tk__shot--empty:hover { color: var(--wtb-ink-2); }
.wtb-tk__shot--empty svg { width: 26px; height: 26px; }
.wtb-tk__shot--empty span { display: block; }

.wtb-tk__tags { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 12px 16px 0; }
.wtb-tag {
  display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 8px; white-space: nowrap;
  font-family: var(--wtb-f-c); font-weight: 700; font-size: 11px; letter-spacing: .09em;
  text-transform: uppercase; border: 1px solid transparent; cursor: pointer; border-radius: 0;
  background: transparent; color: var(--wtb-ink-2);
}
.wtb-tag svg { width: 12px; height: 12px; }
.wtb-tag--wknd { background: var(--wtb-wknd); color: var(--wtb-wknd-ink); border-color: var(--wtb-wknd); }
.wtb-tag--week { background: transparent; color: var(--wtb-ink-2); border-color: var(--wtb-line-hi); }
.wtb-tag--none { background: transparent; color: var(--wtb-ink-3); border: 1px dashed var(--wtb-line-hi); }
.wtb-tag--none:hover { color: var(--wtb-act); border-color: var(--wtb-act); }
.wtb-tag--urgent { background: var(--wtb-alarm); color: #fff; border-color: var(--wtb-alarm); cursor: default; }
.wtb-tag--late { background: transparent; color: var(--wtb-alarm); border-color: var(--wtb-alarm); }
.wtb-tag--late:hover { background: var(--wtb-alarm); color: #fff; }
.wtb-tag__sp { flex: 1; }
.wtb-tag--pay { border: 0; padding: 0; height: auto; cursor: default; color: var(--wtb-ink-3); font-weight: 600; letter-spacing: .08em; }

.wtb-tk__body { padding: 11px 16px 16px; display: flex; flex-direction: column; gap: 9px; flex: 1; }
.wtb-tk__t {
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 19px; line-height: 1.22;
  letter-spacing: .005em; margin: 0; color: var(--wtb-ink);
}
.wtb-tk--done .wtb-tk__t { color: var(--wtb-ink-2); }
.wtb-tk__note {
  margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--wtb-ink-2);
  border-left: 2px solid var(--wtb-line); padding-left: 10px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.wtb-tk__where { margin: 0; font-size: 12px; color: var(--wtb-ink-3); }
.wtb-tk__pc { background: none; border: 0; padding: 0; cursor: pointer; letter-spacing: .07em; }
.wtb-tk__pc:hover { color: var(--wtb-ink-2); }
.wtb-tk__sp { flex: 1; min-height: 2px; }

.wtb-tk__who { display: flex; align-items: center; gap: 11px; padding: 12px 16px; border-top: 1px solid var(--wtb-line); }
.wtb-owner { display: flex; align-items: center; gap: 10px; min-width: 0; flex: 1; background: transparent; border: 0; padding: 0; cursor: pointer; text-align: left; }
.wtb-owner__n { display: block; font-family: var(--wtb-f-c); font-weight: 600; font-size: 13.5px; color: var(--wtb-ink); line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wtb-owner__l { display: block; margin-top: 1px; }
.wtb-owner:hover .wtb-owner__n { color: var(--wtb-act); }
.wtb-owner--none .wtb-owner__n { color: var(--wtb-ink-3); font-weight: 500; }
.wtb-owner--none .wtb-av { border-style: dashed; }
.wtb-hrs { text-align: right; flex-shrink: 0; }
.wtb-hrs__n { display: block; font-family: var(--wtb-f-m); font-weight: 500; font-size: 15px; color: var(--wtb-ink); line-height: 1.1; font-variant-numeric: tabular-nums; }
.wtb-hrs__n em { font-style: normal; font-size: 11px; color: var(--wtb-ink-3); margin-left: 2px; }
.wtb-tk--run .wtb-hrs__n { color: var(--wtb-act); }

.wtb-tk__foot { display: flex; align-items: stretch; border-top: 1px solid var(--wtb-line); }
.wtb-tk__go {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 9px; height: 46px;
  border: 0; background: transparent; color: var(--wtb-ink); cursor: pointer; border-radius: 0;
  font-family: var(--wtb-f-c); font-weight: 700; font-size: 13.5px; letter-spacing: .09em; text-transform: uppercase;
}
.wtb-tk__go svg { width: 15px; height: 15px; }
.wtb-tk__go--act { background: var(--wtb-act); color: var(--wtb-act-ink); }
.wtb-tk__go--act:hover { background: var(--wtb-act-hi); }
.wtb-tk__go--stop { background: var(--wtb-alarm); color: #fff; }
.wtb-tk__go--ghost:hover { background: var(--wtb-raise); }
.wtb-tk__act {
  width: 46px; height: 46px; display: grid; place-items: center; border: 0; border-left: 1px solid var(--wtb-line);
  background: transparent; color: var(--wtb-ink-3); cursor: pointer; border-radius: 0;
}
.wtb-tk__act:hover { background: var(--wtb-raise); color: var(--wtb-ink); }
.wtb-tk__act svg { width: 16px; height: 16px; }
.wtb-tk__act[aria-pressed="true"] { color: var(--wtb-alarm); }

/* finish prompt */

.wtb-ghost {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  min-height: 200px; border: 1px dashed var(--wtb-line-hi); background: transparent; color: var(--wtb-ink-3);
  cursor: pointer; border-radius: var(--wtb-r);
}
.wtb-ghost:hover { border-color: var(--wtb-act); color: var(--wtb-act); }
.wtb-ghost svg { width: 22px; height: 22px; }
.wtb-void { grid-column: 1 / -1; border: 1px dashed var(--wtb-line-hi); padding: 34px 22px; text-align: center; color: var(--wtb-ink-3); font-size: 12.5px; }
.wtb-void strong { display: block; font-family: var(--wtb-f-c); font-weight: 600; font-size: 15px; color: var(--wtb-ink-2); letter-spacing: .03em; text-transform: uppercase; margin-bottom: 5px; }

.wtb-nomatch { border: 1px dashed var(--wtb-line-hi); padding: 56px 24px; text-align: center; color: var(--wtb-ink-3); }
.wtb-nomatch strong { display: block; font-family: var(--wtb-f-c); font-weight: 700; font-size: 22px; letter-spacing: .05em; text-transform: uppercase; color: var(--wtb-ink-2); margin-bottom: 8px; }
.wtb-nomatch .wtb-btn { margin-top: 18px; }

/* ═══════════ ROW LAYOUT ═══════════ */
.wtb { --wtb-cols: var(--wtb-band) 78px minmax(0, 1fr) 160px 140px 82px auto; }
.wtb-rows { border: 1px solid var(--wtb-line); background: var(--wtb-plate); }
.wtb-row { position: relative; display: grid; grid-template-columns: var(--wtb-cols); align-items: center; border-bottom: 1px solid var(--wtb-line); }
.wtb-row:last-of-type { border-bottom: 0; }
.wtb-row:hover { background: var(--wtb-raise); }
.wtb-row.is-drop { box-shadow: inset 0 0 0 1px var(--wtb-act); }
.wtb-row__edge { align-self: stretch; background: transparent; min-height: 58px; }
.wtb-row--urgent .wtb-row__edge { background: var(--wtb-alarm); }
.wtb-row--run .wtb-row__edge { background: var(--wtb-act); }
.wtb-row--done .wtb-row__t { color: var(--wtb-ink-2); }

.wtb-row__shot { width: 78px; height: 58px; padding: 0; border: 0; display: block; overflow: hidden; background: var(--wtb-photo-bg); cursor: zoom-in; border-radius: 0; }
.wtb-row__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wtb-row__shot--empty { display: grid; place-items: center; color: var(--wtb-ink-3); cursor: pointer; background: repeating-linear-gradient(-45deg, var(--wtb-sink) 0 8px, transparent 8px 16px); }
.wtb-row__shot--empty svg { width: 17px; height: 17px; }

.wtb-row__main { padding: 10px 16px; min-width: 0; }
.wtb-row__t { font-family: var(--wtb-f-c); font-weight: 600; font-size: 15.5px; line-height: 1.25; margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--wtb-ink); }
.wtb-row__sub { margin: 3px 0 0; font-size: 12px; color: var(--wtb-ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wtb-row__sub b { color: var(--wtb-ink-2); font-weight: 500; }
.wtb-row__sub button { background: none; border: 0; padding: 0; color: inherit; cursor: pointer; font: inherit; }
.wtb-row__sub button:hover { color: var(--wtb-ink); }

.wtb-row__cell { padding: 8px 10px; min-width: 0; display: flex; align-items: center; }
.wtb-row__cell .wtb-tag { max-width: 100%; }
.wtb-row__who { display: flex; align-items: center; gap: 9px; min-width: 0; width: 100%; background: transparent; border: 0; padding: 4px 6px; cursor: pointer; text-align: left; color: inherit; border-radius: 0; }
.wtb-row__who:hover { background: var(--wtb-line); }
.wtb-row__who .wtb-av { width: 26px; height: 26px; }
.wtb-row__who span { font-family: var(--wtb-f-c); font-weight: 600; font-size: 13px; color: var(--wtb-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wtb-row__who--none span { color: var(--wtb-ink-3); font-weight: 500; }
.wtb-row__hrs { padding: 8px 12px 8px 6px; text-align: right; }
.wtb-row__hrs .wtb-hrs__n { font-size: 14px; }
.wtb-row--run .wtb-row__hrs .wtb-hrs__n { color: var(--wtb-act); }

.wtb-row__acts { display: flex; align-items: center; gap: 2px; padding: 0 8px 0 4px; }
.wtb-rgo {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px; height: 34px; padding: 0 13px;
  border: 1px solid var(--wtb-act); background: var(--wtb-act); color: var(--wtb-act-ink); cursor: pointer;
  font-family: var(--wtb-f-c); font-weight: 700; font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  white-space: nowrap; border-radius: 0;
}
.wtb-rgo:hover { background: var(--wtb-act-hi); border-color: var(--wtb-act-hi); }
.wtb-rgo svg { width: 13px; height: 13px; }
.wtb-rgo--stop { background: var(--wtb-alarm); border-color: var(--wtb-alarm); color: #fff; }
.wtb-rgo--ghost { background: transparent; border-color: var(--wtb-line-hi); color: var(--wtb-ink-2); }
.wtb-rgo--ghost:hover { background: var(--wtb-line); border-color: var(--wtb-ink-3); color: var(--wtb-ink); }
.wtb-ract { width: 34px; height: 34px; display: grid; place-items: center; border: 0; background: transparent; color: var(--wtb-ink-3); cursor: pointer; border-radius: 0; }
.wtb-ract:hover { color: var(--wtb-ink); background: var(--wtb-line); }
.wtb-ract svg { width: 16px; height: 16px; }
.wtb-ract[aria-pressed="true"] { color: var(--wtb-alarm); }
/* An arrow at the end of its run stays in place so the pair never shifts
   under the thumb — it just stops offering the move. */
.wtb-ract:disabled, .wtb-tk__act:disabled { opacity: .28; cursor: default; }
.wtb-ract:disabled:hover, .wtb-tk__act:disabled:hover { background: transparent; color: var(--wtb-ink-3); }

.wtb-rowadd {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 12px 16px;
  border: 0; border-top: 1px dashed var(--wtb-line-hi); background: transparent; color: var(--wtb-ink-3); cursor: pointer;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
}
.wtb-rowadd:hover { color: var(--wtb-act); background: var(--wtb-raise); }
.wtb-rowadd svg { width: 15px; height: 15px; }


/* ═══════════ DRAG AND DROP ═══════════ */
/* The handle is absolutely positioned in both layouts, which keeps it out of
   the row's grid flow — an in-flow grip would shift every column along. */
.wtb-grip {
  position: absolute; top: 0; left: 3px; z-index: 2;
  display: grid; place-items: center; width: 26px; height: 26px; padding: 0;
  border: 0; border-right: 1px solid var(--wtb-line); border-bottom: 1px solid var(--wtb-line);
  background: var(--wtb-plate); color: var(--wtb-ink-3); cursor: grab; border-radius: 0;
  touch-action: none;  /* the pointer stream is ours, not the scroller's */
  opacity: .55; transition: opacity .12s, color .12s;
}
.wtb-grip svg { width: 15px; height: 15px; }
.wtb-grip:active { cursor: grabbing; }
.wtb-row:hover .wtb-grip, .wtb-tk:hover .wtb-grip { opacity: 1; }
.wtb-grip:hover { color: var(--wtb-ink); }
.wtb-tk .wtb-grip { left: 0; width: 30px; height: 30px; }

/* The whole job is draggable, so the grip is a hint rather than the only way
   in — but it still has to be visible to be a hint. */
.wtb-row, .wtb-tk, .wtb-ln { touch-action: pan-y; }
body.wtb-dragging { user-select: none; }

body.wtb-dragging { user-select: none; -webkit-user-select: none; cursor: grabbing; }
.wtb-row.is-dragging, .wtb-tk.is-dragging { opacity: .3; }

/* The thing under your finger. */
.wtb-ghost-card {
  position: fixed; top: 0; left: 0; z-index: var(--z-modal);
  pointer-events: none; opacity: .95; box-shadow: var(--wtb-pop-shadow);
  border: 1px solid var(--wtb-act) !important; background: var(--wtb-plate);
  transform-origin: top left; overflow: hidden;
}
.wtb-ghost-card .wtb-grip { opacity: 1; }

/* Where it would land. */
.wtb-sec.is-drop-target > .wtb-rows,
.wtb-sec.is-drop-target > .wtb-grid {
  outline: 1px solid var(--wtb-act); outline-offset: 3px;
}
.wtb-sec.is-drop-target .wtb-sec__t { color: var(--wtb-act); }
.wtb-drop-marker { background: var(--wtb-act); pointer-events: none; }
.wtb-rows .wtb-drop-marker { height: 2px; margin: -1px 0; }
.wtb-grid .wtb-drop-marker { width: 3px; min-height: 100%; border-radius: var(--wtb-r); }

/* ═══════════ RUNNING BAR — pinned, always in reach ═══════════ */
.wtb-run {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-overlay);
  background: var(--wtb-plate); border-top: 2px solid var(--wtb-act);
  display: flex; align-items: center; gap: 16px; padding: 12px 24px;
  transform: translateY(120%); transition: transform .22s cubic-bezier(.2, .8, .3, 1), visibility .22s;
  visibility: hidden;
}
.wtb-run.is-on { transform: none; visibility: visible; }
.wtb-run__shot { width: 76px; height: 57px; flex-shrink: 0; background: var(--wtb-photo-bg); overflow: hidden; }
.wtb-run__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wtb-run__txt { min-width: 0; flex: 1; }
.wtb-run__st { display: flex; align-items: center; gap: 8px; margin-bottom: 3px; }
.wtb-run__sq { width: 8px; height: 8px; background: var(--wtb-act); animation: wtb-blink 1.5s ease-in-out infinite; }
@keyframes wtb-blink { 0%, 100% { opacity: 1; } 50% { opacity: .2; } }
.wtb-run__lbl { font-family: var(--wtb-f-c); font-weight: 600; font-size: 11px; letter-spacing: .11em; text-transform: uppercase; color: var(--wtb-act); }
.wtb-run__t { font-family: var(--wtb-f-c); font-weight: 600; font-size: 17px; line-height: 1.2; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--wtb-ink); }
.wtb-run__clock { font-family: var(--wtb-f-m); font-weight: 500; font-size: 30px; letter-spacing: -.02em; font-variant-numeric: tabular-nums; flex-shrink: 0; color: var(--wtb-ink); }
.wtb-run__btns { display: flex; gap: 8px; flex-shrink: 0; }

@media (min-width: 921px) {
  /* Clear the app sidebar so the bar tracks the content column. */
  .wtb-run { left: 16rem; }
}
@media (max-width: 920px) {
  /* One 64px row above the app's action bar: blink + title | clock | two
     square buttons. Tapping the text scrolls the running job into view, so
     the bar does not need to repeat what the list already shows. */
  .wtb-run {
    bottom: calc(62px + env(safe-area-inset-bottom, 0px));
    height: 64px; padding: 0 10px 0 14px; gap: 10px;
  }
  .wtb-run__shot { display: none; }
  .wtb-run__txt { cursor: pointer; }
  .wtb-run__st { margin-bottom: 1px; }
  .wtb-run__st .wtb-lbl { display: none; }
  .wtb-run__lbl { font-size: 10px; white-space: nowrap; }
  .wtb-run__t { font-size: 14px; }
  .wtb-run__clock { font-size: 20px; }
  .wtb-run__btns { gap: 6px; }
  .wtb-run__btns .wtb-btn { width: 48px; height: 48px; padding: 0; gap: 0; }
  .wtb-run__btns .wtb-btn svg { width: 18px; height: 18px; }
  .wtb-run__cap { display: none; }
}


/* ═══════════ POPOVER ═══════════ */
.wtb-pop {
  position: fixed; z-index: var(--z-dropdown); min-width: 222px; padding: 5px;
  background: var(--wtb-plate); border: 1px solid var(--wtb-line-hi); box-shadow: var(--wtb-pop-shadow);
}
.wtb-pop__h { padding: 9px 11px 7px; }
/* One line under a menu's title, for a menu that does something on the way
   out — the finish photo closing the job. */
.wtb-pop__say { margin: 0 0 4px; padding: 0 11px 8px; max-width: 260px; font-size: 12.5px;
  line-height: 1.45; color: var(--wtb-ink-3); border-bottom: 1px solid var(--wtb-line); }
/* The move the menu exists for, so a thumb finds it without reading. */
.wtb-pop__i--go { color: var(--wtb-act); font-weight: 600; }
.wtb-pop__i--go svg { color: var(--wtb-act); }
.wtb-pop__i {
  display: flex; align-items: center; gap: 11px; width: 100%; padding: 9px 11px; border: 0;
  background: transparent; color: var(--wtb-ink); font-family: var(--wtb-f-b); font-size: 13px;
  text-align: left; cursor: pointer; border-radius: 0;
}
.wtb-pop__i:hover { background: var(--wtb-raise); }
.wtb-pop__i[aria-checked="true"] { color: var(--wtb-act); font-weight: 600; }
.wtb-pop__i svg { width: 16px; height: 16px; flex-shrink: 0; opacity: .85; }
.wtb-pop__i .wtb-av { width: 26px; height: 26px; }
.wtb-pop__sep { height: 1px; background: var(--wtb-line); margin: 4px 0; }
.wtb-pop__d { margin-left: auto; font-family: var(--wtb-f-m); font-size: 11px; color: var(--wtb-ink-3); }
.wtb-pop__i[aria-checked="true"] .wtb-pop__d { color: inherit; }

/* Phone: the same menu, delivered as a bottom sheet. One button on the card
   still opens it — the sheet is only how the choice is presented down here. */
.wtb-scrim {
  position: fixed; inset: 0; z-index: var(--z-overlay);
  background: rgba(6, 7, 8, .48); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  animation: wtb-fade .16s ease-out;
}
.wtb-pop--sheet {
  left: 0; right: 0; bottom: 0; top: auto; width: 100%; min-width: 0; max-height: 78vh;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 6px 0 calc(8px + env(safe-area-inset-bottom, 0px));
  border: 0; border-top: 2px solid var(--wtb-act); z-index: var(--z-overlay);
  animation: wtb-rise .2s cubic-bezier(.2, .8, .3, 1);
}
/* A grab bar, so it reads as something you can dismiss. */
.wtb-pop--sheet::before {
  content: ''; display: block; width: 38px; height: 4px; margin: 6px auto 2px;
  background: var(--wtb-line-hi);
}
.wtb-pop--sheet .wtb-pop__h { padding: 10px 20px 8px; font-size: 12px; }
.wtb-pop--sheet .wtb-pop__say { padding: 0 20px 12px; max-width: none; font-size: 13.5px; }
.wtb-pop--sheet .wtb-pop__i { padding: 15px 20px; font-size: 15px; gap: 15px; min-height: 54px; }
.wtb-pop--sheet .wtb-pop__i svg { width: 20px; height: 20px; }
.wtb-pop--sheet .wtb-pop__i .wtb-av { width: 34px; height: 34px; }
.wtb-pop--sheet .wtb-pop__d { font-size: 13px; }
.wtb-pop__i--quiet { color: var(--wtb-ink-3); justify-content: center; }
@keyframes wtb-rise { from { transform: translateY(100%); } to { transform: none; } }
@keyframes wtb-fade { from { opacity: 0; } to { opacity: 1; } }

/* ═══════════ PHOTO VIEWER ═══════════ */
.wtb-vw { position: fixed; inset: 0; z-index: var(--z-modal); background: rgba(6, 7, 8, .94); display: none; padding: 28px; }
.wtb-vw[open] { display: grid; place-items: center; }
.wtb-vw__fig { margin: 0; display: flex; flex-direction: column; gap: 14px; align-items: center; max-width: min(94vw, 1020px); }
.wtb-vw__fig img { max-width: 100%; max-height: 70vh; object-fit: contain; background: #000; }
.wtb-vw__cap { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; justify-content: center; color: #C9CFD6; font-size: 12.5px; }
.wtb-vw__cap .wtb-lbl { color: #6E767F; }
.wtb-vw__strip { display: flex; gap: 7px; flex-wrap: wrap; justify-content: center; }
.wtb-vw__th { width: 64px; height: 46px; padding: 0; border: 1px solid #33393F; background: #000; cursor: pointer; overflow: hidden; border-radius: 0; }
.wtb-vw__th[aria-current="true"] { border-color: var(--wtb-act); box-shadow: 0 0 0 1px var(--wtb-act); }
.wtb-vw__th img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wtb-vw__nav { position: absolute; top: 50%; transform: translateY(-50%); width: 46px; height: 70px; border: 1px solid #33393F; background: rgba(0, 0, 0, .6); color: #fff; display: grid; place-items: center; cursor: pointer; border-radius: 0; }
.wtb-vw__nav:hover { background: #000; border-color: #5A626B; }
.wtb-vw__nav svg { width: 22px; height: 22px; }
.wtb-vw__prev { left: max(20px, calc(50% - 560px)); }
.wtb-vw__next { right: max(20px, calc(50% - 560px)); }
.wtb-vw__x { position: absolute; top: 20px; right: 22px; width: 40px; height: 40px; border: 1px solid #33393F; background: rgba(0, 0, 0, .6); color: #fff; display: grid; place-items: center; cursor: pointer; z-index: 1; border-radius: 0; }
.wtb-vw__x svg { width: 18px; height: 18px; }
.wtb-vw__acts { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }

/* The note on a shot — what the picture is of, which the picture cannot say.
   Inline, because the viewer is at --z-modal and anything the board pops sits
   below it. */
.wtb-vw__note {
  margin: 0;
  max-width: 640px;
  color: #E4E8EC;
  font-size: 13.5px;
  line-height: 1.5;
  text-align: center;
  white-space: pre-wrap;
}

.wtb-vw__note--edit { width: min(94vw, 520px); display: flex; flex-direction: column; gap: 8px; }

.wtb-vw__notei {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid #33393F;
  background: #101315;
  color: #E4E8EC;
  font: inherit;
  font-size: 13.5px;
  line-height: 1.45;
  resize: vertical;
}

.wtb-vw__notei:focus { outline: none; border-color: var(--wtb-act); }
.wtb-vw__notea { display: flex; gap: 8px; justify-content: flex-end; }

/* While a note is being written, the arrows and the action row are dead —
   stepViewer() and the thumb handler both refuse to move a photo out from
   under an unsaved note, and Edit note is the thing already open. A dead
   control is worse than one that is not there. */
.wtb-vw.is-noting .wtb-vw__nav,
.wtb-vw.is-noting .wtb-vw__acts { display: none; }
.wtb-vw .wtb-btn { border-color: #33393F; color: #fff; }
.wtb-vw .wtb-btn:hover { background: #1A1D20; }

/* ═══════════ TOAST ═══════════ */
.wtb-toast {
  position: fixed; left: 50%; bottom: 30px; transform: translate(-50%, 14px); z-index: var(--z-modal);
  background: var(--wtb-ink); color: var(--wtb-board); padding: 11px 16px;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 13px; letter-spacing: .04em; text-transform: uppercase;
  opacity: 0; pointer-events: none; transition: opacity .18s, transform .18s;
}
.wtb-toast.is-on { opacity: 1; transform: translate(-50%, 0); }
.wtb-toast.has-act { display: flex; align-items: center; gap: 14px; padding-right: 6px; }
/* A toast that carries a button (Undo after a push back) has to be reachable. */
.wtb-toast.has-act.is-on { pointer-events: auto; }
.wtb-toast__act {
  height: 30px; padding: 0 12px; border: 1px solid currentColor; border-radius: 0; background: transparent;
  color: inherit; cursor: pointer; font: inherit; letter-spacing: .06em; text-transform: uppercase;
}
.wtb-toast__act:hover { background: var(--wtb-act); border-color: var(--wtb-act); color: var(--wtb-act-ink); }
.wtb-run.is-on ~ .wtb-toast { bottom: 104px; }
@media (max-width: 920px) {
  .wtb-toast { bottom: calc(74px + env(safe-area-inset-bottom, 0px)); }
  .wtb-run.is-on ~ .wtb-toast { bottom: calc(166px + env(safe-area-inset-bottom, 0px)); }
}

/* ═══════════ FINISH DIALOG ═══════════
   Finishing is the move that cannot be undone by the person making it, and
   the one that wants a photo. Three real buttons, each saying what it does,
   rather than a menu hanging off a 26px tick. */
.wtb-fin { max-width: 460px; }
.wtb-fin__body { display: flex; flex-direction: column; gap: 4px; }
.wtb-fin__job {
  margin: 0; font-family: var(--wtb-f-c); font-weight: 600; font-size: 19px;
  line-height: 1.25; color: var(--wtb-ink);
}
.wtb-fin__meta {
  margin: 0 0 14px; font-family: var(--wtb-f-c); font-weight: 600; font-size: 11px;
  letter-spacing: .07em; text-transform: uppercase; color: var(--wtb-ink-3);
}
.wtb-fin__opts { display: flex; flex-direction: column; gap: 8px; }
.wtb-fin__opt {
  display: flex; align-items: center; gap: 13px; width: 100%; min-height: 62px; padding: 10px 14px;
  border: 1px solid var(--wtb-line-hi); background: transparent; color: var(--wtb-ink);
  text-align: left; cursor: pointer; border-radius: var(--wtb-r);
  transition: border-color .14s, background .14s;
}
.wtb-fin__opt:hover { background: var(--wtb-raise); border-color: var(--wtb-ink-3); }
.wtb-fin__opt:active { background: var(--wtb-sink); }
.wtb-fin__opt > svg { width: 21px; height: 21px; flex-shrink: 0; color: var(--wtb-ink-3); }
.wtb-fin__opt span { display: block; min-width: 0; }
.wtb-fin__opt b {
  display: block; font-family: var(--wtb-f-c); font-weight: 600; font-size: 15px;
  letter-spacing: .02em; line-height: 1.2;
}
.wtb-fin__opt i { display: block; margin-top: 2px; font-style: normal; font-size: 12.5px; color: var(--wtb-ink-3); }
.wtb-fin__opt--go { border-color: var(--wtb-act); box-shadow: inset 0 0 0 1px var(--wtb-act); }
.wtb-fin__opt--go > svg { color: var(--wtb-act); }
.wtb-fin__opt--go:hover { border-color: var(--wtb-act); background: var(--wtb-raise); }
.wtb-fin__note { margin: 14px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--wtb-ink-3); }
@media (max-width: 640px) {
  /* On a phone the dialog is the screen: full-width buttons a thumb cannot miss. */
  .wtb-fin__job { font-size: 18px; }
  .wtb-fin__opt { min-height: 66px; }
  .wtb-fin__note { display: none; }
}


/* ═══════════ TASK FORM — the `wtb-tf` block ═══════════
   Add and Edit. The board's own palette and square edges, an orange rule
   across the top like the Next job card, two columns from 900px (what and
   when | who and the detail) and the whole screen on a phone. Every selector
   is `.wtb .wtb-tf…` because `.wtb button { font: inherit }` outbids a bare
   class. The steps inside are the board's `wst-` checklist and the calendar
   is the `wcal` block — this block only lays them out. */
.wtb .wtb-tfo { padding: 24px; background: rgba(6, 7, 8, .55); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }
.wtb .wtb-tf {
  width: 100%; max-width: 980px; max-height: calc(100dvh - 48px); display: flex; flex-direction: column;
  background: var(--wtb-plate); color: var(--wtb-ink); border: 1px solid var(--wtb-line-hi);
  border-top: 3px solid var(--wtb-act); box-shadow: var(--wtb-pop-shadow); overflow: hidden;
}
.wtb .wtb-tf__head {
  display: flex; align-items: flex-start; gap: 14px; padding: 16px 20px 14px; border-bottom: 1px solid var(--wtb-line); flex: none;
}
.wtb .wtb-tf__titles { flex: 1 1 auto; min-width: 0; }
.wtb .wtb-tf__eyebrow { color: var(--wtb-act); }
.wtb .wtb-tf__title {
  margin: 3px 0 0; font-family: var(--wtb-f-c); font-weight: 600; font-size: 21px; line-height: 1.2;
  color: var(--wtb-ink); overflow-wrap: anywhere;
}
.wtb .wtb-tf__x {
  flex: none; width: 38px; height: 38px; padding: 0; border: 1px solid var(--wtb-line-hi); border-radius: 0;
  background: transparent; color: var(--wtb-ink-2); cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.wtb .wtb-tf__x:hover { background: var(--wtb-raise); color: var(--wtb-ink); }
.wtb .wtb-tf__x svg { width: 17px; height: 17px; }

.wtb .wtb-tf__form { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.wtb .wtb-tf__body { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: grid; grid-template-columns: minmax(0, 1fr); }
.wtb .wtb-tf__col { display: flex; flex-direction: column; gap: 22px; min-width: 0; padding: 18px 20px 24px; }
.wtb .wtb-tf__col + .wtb-tf__col { border-top: 1px solid var(--wtb-line); }
@media (min-width: 900px) {
  .wtb .wtb-tf__body { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .wtb .wtb-tf__col + .wtb-tf__col { border-top: 0; border-left: 1px solid var(--wtb-line); }
}
.wtb .wtb-tf__f { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.wtb .wtb-tf__l {
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 11.5px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--wtb-ink-2);
}
.wtb .wtb-tf__l i { margin-left: 6px; font-style: normal; font-weight: 500; letter-spacing: .02em; text-transform: none; color: var(--wtb-ink-3); }
.wtb .wtb-tf__hint { margin: 0; font-size: 12.5px; line-height: 1.45; color: var(--wtb-ink-3); }
.wtb .wtb-tf__hint:empty { display: none; }

.wtb .wtb-tf__name, .wtb .wtb-tf__in {
  width: 100%; border: 1px solid var(--wtb-line-hi); border-radius: 0; background: var(--wtb-raise);
  color: var(--wtb-ink); font-family: var(--wtb-f-b);
}
.wtb .wtb-tf__name { padding: 11px 12px; font-family: var(--wtb-f-c); font-weight: 600; font-size: 21px; line-height: 1.2; }
.wtb .wtb-tf__in { height: 42px; padding: 0 12px; font-size: 14px; }
.wtb .wtb-tf__notes { height: auto; min-height: 88px; padding: 10px 12px; line-height: 1.45; resize: vertical; }
.wtb .wtb-tf__name::placeholder, .wtb .wtb-tf__in::placeholder { color: var(--wtb-ink-3); font-weight: 400; }
.wtb .wtb-tf__name:focus, .wtb .wtb-tf__in:focus {
  outline: none; border-color: var(--wtb-act); background: var(--wtb-plate); box-shadow: inset 0 0 0 1px var(--wtb-act);
}

/* A row of square segments — pay type and priority. Picked is ink-filled;
   the pay type also carries its own band colour along the foot, the same
   colour as the job's left edge on the board. */
.wtb .wtb-seg { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); border: 1px solid var(--wtb-line-hi); }
.wtb .wtb-seg__o { position: relative; cursor: pointer; min-width: 0; }
.wtb .wtb-seg__o + .wtb-seg__o { border-left: 1px solid var(--wtb-line-hi); }
.wtb .wtb-seg__o input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; clip-path: inset(50%); }
.wtb .wtb-seg__o > span {
  display: flex; align-items: center; justify-content: center; height: 42px; padding: 0 8px;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 12.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--wtb-ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.wtb .wtb-seg__o:hover > span { background: var(--wtb-raise); color: var(--wtb-ink); }
.wtb .wtb-seg__o input:checked + span { background: var(--wtb-ink); color: var(--wtb-plate); }
.wtb .wtb-seg__o input:focus-visible + span { outline: 2px solid var(--wtb-act); outline-offset: -4px; }
.wtb .wtb-seg__o--paid input:checked + span { box-shadow: inset 0 -4px 0 var(--wtb-pay-paid); }
.wtb .wtb-seg__o--commission input:checked + span { box-shadow: inset 0 -4px 0 var(--wtb-pay-commission); }
.wtb .wtb-seg__o--future input:checked + span { box-shadow: inset 0 -4px 0 var(--wtb-pay-future); }
.wtb .wtb-seg__o--p1 input:checked + span { box-shadow: inset 0 -4px 0 var(--wtb-act); }
.wtb .wtb-seg__o--p2 input:checked + span { background: var(--wtb-alarm); color: #fff; }

/* Who is on it — one press per person rather than a dropdown to open. */
.wtb .wtb-crewpick { display: flex; flex-wrap: wrap; gap: 6px; }
.wtb .wtb-crewpick__o { position: relative; cursor: pointer; }
.wtb .wtb-crewpick__o input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; clip-path: inset(50%); }
.wtb .wtb-crewpick__o > span {
  display: inline-flex; align-items: center; gap: 8px; height: 40px; padding: 0 13px 0 5px;
  border: 1px solid var(--wtb-line-hi); font-size: 13.5px; color: var(--wtb-ink); white-space: nowrap;
}
.wtb .wtb-crewpick__o .wtb-av { width: 28px; height: 28px; font-size: 11px; }
.wtb .wtb-crewpick__o .wtb-av--none { background: transparent; border: 1px dashed var(--wtb-line-hi); color: var(--wtb-ink-3); }
.wtb .wtb-crewpick__o:hover > span { background: var(--wtb-raise); }
.wtb .wtb-crewpick__o input:checked + span { border-color: var(--wtb-act); box-shadow: inset 0 0 0 1px var(--wtb-act); background: var(--wtb-raise); font-weight: 600; }
.wtb .wtb-crewpick__o input:focus-visible + span { outline: 2px solid var(--wtb-act); outline-offset: 2px; }

/* Photos — square tiles, and a tile that is the picker. */
.wtb .wtb-tf__photos { display: grid; grid-template-columns: repeat(auto-fill, minmax(86px, 1fr)); gap: 8px; }
.wtb .wtb-tf__ph { position: relative; aspect-ratio: 1; overflow: hidden; background: var(--wtb-photo-bg); }
.wtb .wtb-tf__ph img { display: block; width: 100%; height: 100%; object-fit: cover; }
.wtb .wtb-tf__phx {
  position: absolute; top: 4px; right: 4px; width: 30px; height: 30px; padding: 0; border: 0; border-radius: 0;
  background: rgba(6, 7, 8, .7); color: #fff; cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.wtb .wtb-tf__phx svg { width: 14px; height: 14px; }
.wtb .wtb-tf__add {
  position: relative; aspect-ratio: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  border: 1px dashed var(--wtb-line-hi); color: var(--wtb-ink-2); cursor: pointer; text-align: center; padding: 6px;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase;
}
.wtb .wtb-tf__add:hover, .wtb .wtb-tf__add:focus-within { border-color: var(--wtb-act); color: var(--wtb-ink); background: var(--wtb-raise); }
.wtb .wtb-tf__add input { position: absolute; width: 1px; height: 1px; opacity: 0; clip-path: inset(50%); }
.wtb .wtb-tf__add svg { width: 24px; height: 24px; }

.wtb .wtb-tf__foot {
  flex: none; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px;
  padding: 12px 20px; border-top: 1px solid var(--wtb-line); background: var(--wtb-plate);
}
.wtb .wtb-tf__err { flex: 1 1 100%; margin: 0; }
.wtb .wtb-tf__btn {
  height: 44px; padding: 0 18px; border: 1px solid var(--wtb-line-hi); border-radius: 0; background: transparent;
  color: var(--wtb-ink); cursor: pointer;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 13px; letter-spacing: .07em; text-transform: uppercase;
}
.wtb .wtb-tf__btn:hover { background: var(--wtb-raise); }
.wtb .wtb-tf__btn--go { min-width: 160px; background: var(--wtb-act); border-color: var(--wtb-act); color: var(--wtb-act-ink); }
.wtb .wtb-tf__btn--go:hover { background: var(--wtb-act-hi); border-color: var(--wtb-act-hi); }
.wtb .wtb-tf__btn:disabled { opacity: .6; cursor: default; }

/* The form already labels the list, so the checklist's own word goes and
   its count and bar stay. */
.wtb .wtb-tf__steps .wst-h__t { display: none; }

/* A phone: the form is the screen, the buttons share the foot, and every box
   is 16px so iOS does not zoom the page into it. */
@media (max-width: 640px) {
  .wtb .wtb-tfo { padding: 0; align-items: stretch; }
  .wtb .wtb-tf { max-width: none; max-height: none; height: 100dvh; border: 0; border-top: 3px solid var(--wtb-act); }
  .wtb .wtb-tf__head { padding: 12px 16px; padding-top: calc(12px + env(safe-area-inset-top, 0px)); }
  .wtb .wtb-tf__col { padding: 16px 16px 22px; gap: 20px; }
  .wtb .wtb-tf__name { font-size: 20px; }
  .wtb .wtb-tf__in, .wtb .wtb-tf__notes { font-size: 16px; }
  .wtb .wtb-tf__in { height: 46px; }
  .wtb .wtb-seg__o > span { height: 46px; }
  .wtb .wtb-crewpick__o > span { height: 44px; }
  .wtb .wtb-tf__foot { padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px)); }
  .wtb .wtb-tf__btn { flex: 1 1 0; height: 50px; min-width: 0; }
}

.wtb-quick { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.wtb-quick__b {
  height: 30px; padding: 0 10px; border: 1px solid var(--wtb-line-hi); background: transparent;
  color: var(--wtb-ink-2); cursor: pointer; white-space: nowrap; border-radius: 0;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 11.5px; letter-spacing: .07em; text-transform: uppercase;
}
.wtb-quick__b:hover { background: var(--wtb-raise); color: var(--wtb-ink); }
.wtb-quick__b[aria-pressed="true"] { background: var(--wtb-act); border-color: var(--wtb-act); color: var(--wtb-act-ink); }
.wtb-quick__b--clear { border-style: dashed; }

/* ═══════════ DATE PICKER — the `wcal` block ═══════════
   Two weeks, Monday first, drawn by calHTML() in view.js for the task form,
   the schedule menu and the Days menu. Square everywhere. The pick is the
   board's orange: a filled first and last day, the days between tinted, so a
   run reads as one bar across the grid. Selectors are `.wtb .wcal-…` because
   `.wtb button { font: inherit }` outbids a bare class. */
.wtb .wcal { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.wtb .wcal-mode { display: grid; grid-template-columns: 1fr 1fr; border: 1px solid var(--wtb-line-hi); }
.wtb .wcal-mode button {
  height: 34px; border: 0; background: transparent; color: var(--wtb-ink-2); cursor: pointer; border-radius: 0;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
}
.wtb .wcal-mode button + button { border-left: 1px solid var(--wtb-line-hi); }
.wtb .wcal-mode button:hover { background: var(--wtb-raise); color: var(--wtb-ink); }
.wtb .wcal-mode button[aria-pressed="true"] { background: var(--wtb-ink); color: var(--wtb-plate); }
.wtb .wcal-h { display: flex; align-items: center; gap: 6px; }
.wtb .wcal-t { flex: 1 1 auto; font-size: 13px; font-weight: 600; color: var(--wtb-ink); }
.wtb .wcal-nav, .wtb .wcal-today {
  flex: none; height: 32px; border: 1px solid var(--wtb-line-hi); background: transparent; color: var(--wtb-ink);
  cursor: pointer; border-radius: 0; display: inline-flex; align-items: center; justify-content: center;
}
.wtb .wcal-nav { width: 32px; padding: 0; }
.wtb .wcal-nav svg { width: 15px; height: 15px; }
.wtb .wcal-today {
  padding: 0 10px; font-family: var(--wtb-f-c); font-weight: 600; font-size: 11.5px;
  letter-spacing: .06em; text-transform: uppercase; color: var(--wtb-ink-2);
}
.wtb .wcal-nav:hover, .wtb .wcal-today:hover { background: var(--wtb-raise); }
.wtb .wcal-g { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); row-gap: 3px; }
.wtb .wcal-w {
  padding-bottom: 2px; text-align: center; font-family: var(--wtb-f-c); font-weight: 600; font-size: 11px;
  letter-spacing: .06em; color: var(--wtb-ink-3);
}
.wtb .wcal-d {
  position: relative; height: 40px; padding: 0; border: 0; border-radius: 0; background: transparent;
  color: var(--wtb-ink); cursor: pointer; display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.wtb .wcal-d:hover:not(:disabled) { background: var(--wtb-raise); }
.wtb .wcal-n { font-size: 14px; line-height: 1; }
.wtb .wcal-m {
  position: absolute; top: 3px; left: 0; right: 0; text-align: center; line-height: 1;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 9px; letter-spacing: .06em; text-transform: uppercase; color: var(--wtb-ink-3);
}
.wtb .wcal-d .wcal-m + .wcal-n { margin-top: 8px; }
.wtb .wcal-d.is-wknd .wcal-n { color: var(--wtb-wknd-txt); }
.wtb .wcal-d.is-past .wcal-n { color: var(--wtb-ink-3); }
/* Today is ringed, never filled — filled means picked. */
.wtb .wcal-d.is-today { box-shadow: inset 0 0 0 1px var(--wtb-ink); }
.wtb .wcal-d.is-today .wcal-n { font-weight: 700; }
.wtb .wcal-d.is-in { background: color-mix(in srgb, var(--wtb-act) 16%, transparent); }
.wtb .wcal-d.is-start, .wtb .wcal-d.is-end { background: var(--wtb-act); }
.wtb .wcal-d.is-start .wcal-n, .wtb .wcal-d.is-end .wcal-n,
.wtb .wcal-d.is-start .wcal-m, .wtb .wcal-d.is-end .wcal-m { color: var(--wtb-act-ink); }
.wtb .wcal-d:disabled { cursor: default; opacity: .32; }
.wtb .wcal-say { min-height: 18px; font-size: 12.5px; color: var(--wtb-ink-2); }
.wtb .wcal.is-many .wcal-say { color: var(--wtb-ink); }

/* In a menu: the calendar is the menu, the quick days sit under it. */
.wtb-pop--cal { width: min(330px, calc(100vw - 24px)); }
.wtb-pop__cal { display: flex; flex-direction: column; gap: 6px; padding: 4px 11px 10px; }
.wtb-pop__quick { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 11px 11px; border-top: 1px solid var(--wtb-line); }
.wtb-pop--sheet.wtb-pop--cal { width: auto; }
.wtb-pop--sheet .wtb-pop__cal, .wtb-pop--sheet .wtb-pop__quick { padding-left: 20px; padding-right: 20px; }
.wtb .wtb-calslot { max-width: 420px; }
@media (pointer: coarse) {
  .wtb .wcal-d { height: 46px; }
  .wtb .wcal-n { font-size: 16px; }
  .wtb .wcal-mode button, .wtb .wcal-nav, .wtb .wcal-today { height: 42px; }
  .wtb .wcal-nav { width: 42px; }
}

/* ═══════════ FAB ═══════════ */
.wtb-fab {
  width: 52px; height: 52px; border-radius: 16px; display: none; align-items: center; justify-content: center;
  border: none; background: var(--wtb-act); color: var(--wtb-act-ink); cursor: pointer; box-shadow: var(--shadow-md);
}
.wtb-fab__icon { width: 22px; height: 22px; }
@media (max-width: 1024px) { .wtb-fab { display: flex; } }

/* ═══════════ RESPONSIVE ═══════════ */
@media (max-width: 1180px) { .wtb { --wtb-cols: var(--wtb-band) 70px minmax(0, 1fr) 152px 122px 76px auto; } }
@media (max-width: 1024px) {
  .wtb-mast__add { display: none; }  /* FAB takes over */
  .wtb-grid { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
}
@media (max-width: 760px) {
  .wtb-fx { flex-wrap: wrap; }
  .wtb-mast__sp { display: none; }
  .wtb-mast { gap: 12px 16px; }
}

/* ═══════════ TABLET (641–1024px) ═══════════
   The board on the shop's tablet, which is where most of it actually gets
   used: propped on a fender, read from arm's length, tapped with a thumb
   that has been holding something greasy.

   The desktop's seven columns do not fit and the phone's line is too small
   for the screen, so a row becomes three bands — the job, then its day and
   crew, then one strip of buttons. Every target is 46px, nothing is behind a
   hover, and the type goes up a size across the board. The card view turns
   into two real columns rather than three cramped ones. */
@media (min-width: 641px) and (max-width: 1024px) {
  .wtb { font-size: 14px; --wtb-tap: 46px; --wtb-band: 6px; }

  .wtb-sec__t { font-size: 26px; }
  .wtb-sec__stat { font-size: 12.5px; }
  .wtb-sec__note { font-size: 13px; }
  .wtb-sec__ix { font-size: 13px; }

  /* ── The row, in three bands ── */
  .wtb-row { grid-template-columns: var(--wtb-band) 104px minmax(0, 1fr) auto; align-items: center; }
  .wtb-row__edge { grid-row: 1 / 4; min-height: 100%; }
  .wtb-row__shot { grid-column: 2; grid-row: 1; width: 104px; height: 78px; margin: 12px 0 12px 12px; }
  .wtb-row__shot--empty svg { width: 22px; height: 22px; }
  .wtb-row__main { grid-column: 3; grid-row: 1; padding: 12px 16px; }
  /* Two lines of title beats one line with the end cut off — a job is named
     for what it is, and the difference is usually at the end. Clamped on a
     span rather than the line itself, because the line leads with the place
     input and -webkit-box would swallow it. */
  .wtb-row__t { font-size: 18px; white-space: normal; }
  /* Inline-box, not box: the place number leads the line and the title has
     to sit beside it, not under it. */
  .wtb-row__t .wtb-tt { display: -webkit-inline-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden; vertical-align: top; max-width: 100%; }
  /* Who is on it and what is wrong with it are the two things the sub line
     carries that appear nowhere else on the row — never cut those off. */
  .wtb-row__sub { font-size: 13px; margin-top: 4px; white-space: normal;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  .wtb-row__hrs { grid-column: 4; grid-row: 1; padding: 12px 16px; }
  .wtb-row__hrs .wtb-hrs__n { font-size: 18px; }
  .wtb-row__cell { grid-column: 2 / 4; grid-row: 2; padding: 0 16px 10px 12px; }
  .wtb-row__who { grid-column: 4; grid-row: 2; width: auto; padding: 0 16px 10px; justify-content: flex-end; }
  .wtb-row__who span { display: block; font-size: 14px; }
  .wtb-row__who .wtb-av { width: 30px; height: 30px; }
  .wtb-row__acts { grid-column: 2 / 5; grid-row: 3; padding: 0 12px 12px; gap: 6px; flex-wrap: wrap; }
  /* The clock is the row's main action and gets the width to prove it,
     but not the whole strip — the icons beside it are targets too. */
  .wtb-row__acts .wtb-rgo { flex: 1 1 auto; min-width: 150px; max-width: 360px; }

  /* ── Targets ── */
  .wtb-rgo { height: var(--wtb-tap); padding: 0 20px; font-size: 13.5px; }
  .wtb-rgo svg { width: 16px; height: 16px; }
  .wtb-ract { width: var(--wtb-tap); height: var(--wtb-tap); border: 1px solid var(--wtb-line); }
  .wtb-ract svg { width: 19px; height: 19px; }
  .wtb-tag { height: 30px; padding: 0 11px; font-size: 12px; }
  .wtb-tag svg { width: 14px; height: 14px; }
  .wtb-btn { height: 42px; }
  .wtb-rowadd, .wtb-more { padding: 15px 16px; font-size: 13px; }
  .wtb-pop__i { min-height: var(--wtb-tap); font-size: 14px; }
  .wtb-grip { opacity: 1; width: 30px; }

  /* ── Cards: two real columns ── */
  .wtb-grid { grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 16px; }
  .wtb-tk__t { font-size: 20px; }
  .wtb-tk__note, .wtb-tk__where { font-size: 13px; }
  /* Six 46px targets and a clock will not share one line on a card this
     wide, and "Clock in" broken across two lines is not a button. Give the
     clock the full width and let the icons have the strip under it. */
  .wtb-tk__foot { flex-wrap: wrap; }
  .wtb-tk__go { flex: 1 1 100%; height: var(--wtb-tap); font-size: 14px; white-space: nowrap; border-bottom: 1px solid var(--wtb-line); }
  .wtb-tk__act { flex: 1 0 auto; width: auto; min-width: var(--wtb-tap); height: var(--wtb-tap); }
  .wtb-tk__act svg { width: 19px; height: 19px; }
  .wtb-ghost { min-height: 230px; }
}

/* A tablet below the app's own mobile breakpoint keeps the phone shell — the
   ticker and the action bar — but it has room to wear it at full size. */
@media (min-width: 641px) and (max-width: 920px) {
  .wtb-ticker { gap: 20px; font-size: 12px; padding: 4px 0 10px; }
  .wtb-ticker__i b { font-size: 17px; }
  .wtb .pg-content { padding-bottom: calc(180px + env(safe-area-inset-bottom, 0px)); }

  .wtb-run { height: 78px; padding: 0 14px; gap: 14px; }
  .wtb-run__shot { display: block; width: 74px; height: 56px; }
  .wtb-run__st .wtb-lbl { display: block; }
  .wtb-run__t { font-size: 17px; }
  .wtb-run__clock { font-size: 28px; }
  .wtb-run__btns .wtb-btn { width: 56px; height: 56px; }
  .wtb-run__btns .wtb-btn svg { width: 22px; height: 22px; }
  .wtb-run.is-on ~ .wtb-toast { bottom: calc(186px + env(safe-area-inset-bottom, 0px)); }
}
@media (max-width: 640px) {
  .wtb .pg-content { padding-bottom: calc(230px + env(safe-area-inset-bottom, 0px)); }
  .wtb-tk__shot { aspect-ratio: 16 / 9; }
  .wtb-ghost { min-height: 118px; }
  .wtb-mast { gap: 12px 14px; padding-bottom: 12px; }
  .wtb-tally__i { padding-right: 12px; margin-right: 12px; }
  .wtb-tally__n { font-size: 16px; }
  .wtb-ftog__t { display: none; }
  .wtb-ftog { padding: 0 10px; }
  .wtb-sec__t { font-size: 21px; }
  /* Narrow screens can't fit title + rule + stat on one line — let it wrap. */
  .wtb-sec__head { flex-wrap: wrap; gap: 8px 12px; }
  .wtb-sec__rule { display: none; }
  .wtb-sec__stat { flex: 1 1 100%; }
  .wtb-grid { grid-template-columns: 1fr; }
  .wtb-fx--find { flex: 1 1 100%; border-right: 0; border-bottom: 1px solid var(--wtb-line); }
  .wtb-fx { border-bottom: 1px solid var(--wtb-line); border-right: 0; }
  .wtb-fx--end { border-bottom: 0; }
  .wtb-fb { font-size: 11.5px; padding: 0 9px; }
  /* The running bar's phone layout lives in the ≤920px block above. */
  .wtb-vw { padding: 14px; }
  .wtb-vw__nav { width: 36px; height: 56px; }
  .wtb-vw__prev { left: 6px; }
  .wtb-vw__next { right: 6px; }
  .wtb-vw__th { width: 48px; height: 35px; }
}

/* ═══════════ PHONE SHELL (≤920px) ═══════════ */
/* Below the app's mobile breakpoint the masthead (tally, switches, New task)
   and the filter bar leave the page. Totals go to the ticker; filters, group
   and layout sit behind the action bar's Filter and View; Task is the bar's
   add button. The first job is on screen without scrolling. */
@media (max-width: 920px) {
  .wtb-mast { display: none; }
  /* Parent-scoped on purpose: once the bar moves into the sheet this stops
     matching, and the sheet's own rule paints it. */
  .pg-content > .wtb-filters { display: none; }
  .wtb .pg-content { padding-bottom: calc(150px + env(safe-area-inset-bottom, 0px)); }

  /* The bar's Filter button carries the board's colour when filters narrow it. */
  .wtb .mob-action-btn.has-active { color: var(--wtb-act); }
  .wtb-mob-btn { position: relative; }
  .wtb-mob-badge {
    position: absolute; top: 6px; left: calc(50% + 6px); min-width: 16px; height: 16px; padding: 0 4px;
    display: grid; place-items: center; background: var(--wtb-act); color: var(--wtb-act-ink);
    font-size: 10px; line-height: 1;
  }

  /* The filter bar inside its sheet: stacked groups, chips that wrap, 44px targets. */
  .wtb-pop--filters { max-height: 84vh; }
  .wtb-pop__slot .wtb-filters { display: flex; flex-direction: column; border: 0; background: transparent; }
  .wtb-pop__slot .wtb-fx { border-right: 0; border-bottom: 1px solid var(--wtb-line); padding: 10px 16px 12px; flex-wrap: wrap; gap: 8px; }
  .wtb-pop__slot .wtb-fx--find { padding: 6px 16px 10px; flex-wrap: nowrap; }
  .wtb-pop__slot .wtb-fx__lbl { flex: 1 1 100%; padding: 0 0 2px; }
  .wtb-pop__slot .wtb-fx__scroll { flex-wrap: wrap; overflow: visible; gap: 8px; }
  .wtb-pop__slot .wtb-fb { height: 44px; border: 1px solid var(--wtb-line); }
  .wtb-pop__slot .wtb-fb[aria-pressed="true"] { border-color: var(--wtb-ink); }
  .wtb-pop__slot .wtb-fb--flag[aria-pressed="true"] { border-color: var(--wtb-alarm); }
  .wtb-pop__slot .wtb-find__in { font-size: 16px; padding: 10px 0; }
  .wtb-pop__slot .wtb-fclear { margin-left: 0; }
  .wtb-pop__i--done { justify-content: center; color: var(--wtb-act); font-family: var(--wtb-f-c); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
  .wtb-pop__h--title { font-family: var(--wtb-f-c); font-size: 15px; letter-spacing: .01em; text-transform: none; color: var(--wtb-ink); }
}

/* ═══════════ THE LINE (phone list, ≤640px) ═══════════ */
.wtb-rows--lines { border: 0; background: transparent; }
.wtb-ln {
  position: relative; display: grid;
  grid-template-columns: var(--wtb-band) 62px minmax(0, 1fr) 62px;
  grid-template-rows: auto auto;
  align-items: stretch; min-height: 72px; background: var(--wtb-plate);
  border: 1px solid var(--wtb-line); border-top: 0;
}
/* The photo and the go square own the full height; the name and everything
   under it share the middle. */
.wtb-ln__edge { grid-row: 1 / 3; }
.wtb-ln__shot { grid-row: 1 / 3; }
.wtb-ln__go   { grid-row: 1 / 3; }
.wtb-ln__body { grid-column: 3; grid-row: 1; }
.wtb-ln__foot { grid-column: 3; grid-row: 2; }
.wtb-rows--lines .wtb-ln:first-child { border-top: 1px solid var(--wtb-line); }
.wtb-ln__edge { background: transparent; }
.wtb-ln--urgent .wtb-ln__edge { background: var(--wtb-alarm); }
.wtb-ln--run .wtb-ln__edge { background: var(--wtb-act); }
.wtb-ln--run { box-shadow: inset 0 0 0 1px var(--wtb-act); }
.wtb-ln__shot {
  position: relative; display: block; width: 62px; padding: 0; border: 0; border-right: 1px solid var(--wtb-line);
  background: var(--wtb-photo-bg); overflow: hidden; cursor: zoom-in; border-radius: 0;
}
.wtb-ln__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wtb-ln__shot--empty { display: grid; place-items: center; color: var(--wtb-ink-3); cursor: pointer; background: repeating-linear-gradient(-45deg, var(--wtb-sink) 0 7px, transparent 7px 14px); }
.wtb-ln__shot--empty > svg { width: 18px; height: 18px; }
.wtb-ln__badge {
  position: absolute; right: 2px; bottom: 2px; min-width: 20px; height: 20px; padding: 0 3px;
  display: grid; place-items: center; background: var(--wtb-ink); color: var(--wtb-board);
  font-family: var(--wtb-f-c); font-weight: 700; font-size: 9.5px; letter-spacing: .05em;
}
.wtb-ln__badge--none { background: var(--wtb-plate); color: var(--wtb-ink-3); border: 1px dashed var(--wtb-line-hi); }
.wtb-ln__body {
  min-width: 0; display: flex; flex-direction: column; gap: 2px;
  padding: 9px 10px 3px; border: 0; background: transparent; text-align: left; cursor: pointer; border-radius: 0; color: inherit;
}
.wtb-ln__head { display: flex; align-items: baseline; gap: 7px; min-width: 0; }
/* One line, and the only line on a phone that carries free text. */
.wtb-ln__note {
  display: block; min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 11.5px; letter-spacing: .04em;
}
.wtb-ln__body:active { background: var(--wtb-raise); }
.wtb-ln__t {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 15px; line-height: 1.2; color: var(--wtb-ink);
}
.wtb-ln--done .wtb-ln__t { color: var(--wtb-ink-2); }
/* The second tier. The tokens wrap to a second line rather than being eaten
   by one ellipsis at the end — what is wrong with a job and who is on it were
   the first things to go, and they are the two worth reading. Two lines is
   the cap: past that a row stops being a row. */
.wtb-ln__foot {
  display: flex; align-items: center; gap: 4px 8px;
  min-width: 0; padding: 0 4px 7px 10px;
}
/* Three tokens on one line. The last one is the only free text, so it is the
   only thing that ever gives way — and the ⚠ or the dot before it still says
   what kind of thing was cut. */
.wtb-ln__mi {
  flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--wtb-ink-3);
}
.wtb-ln__acts { flex-shrink: 0; display: flex; align-items: center; gap: 2px; margin-left: auto; }
/* Narrow on purpose: the 62px go square beside them takes the traffic, and
   every pixel here comes straight out of the line that says why a job is
   stuck. They are still 34 tall, which is what a thumb needs. */
.wtb-lact {
  width: 34px; height: 34px; display: grid; place-items: center; flex-shrink: 0;
  border: 0; background: transparent; color: var(--wtb-ink-3); cursor: pointer; border-radius: 0;
}
.wtb-lact svg { width: 17px; height: 17px; }
.wtb-lact:active { background: var(--wtb-sink); color: var(--wtb-ink); }
.wtb-lact--ok { color: var(--wtb-ink-2); }
.wtb-ln .wtb-ix { flex-shrink: 0; }
.wtb-ln__mi > span { display: inline-flex; align-items: center; vertical-align: middle; }
.wtb-ln__dot { color: var(--wtb-line-hi); margin: 0 4px; }
.wtb-ln__date { padding: 1px 5px; border: 1px solid var(--wtb-line-hi); color: var(--wtb-ink-2); }
.wtb-ln__hrs { text-transform: lowercase; }
.wtb-ln__date--late { color: var(--wtb-alarm); border-color: var(--wtb-alarm); }
.wtb-ln__date--wknd { background: var(--wtb-wknd); color: var(--wtb-wknd-ink); border-color: var(--wtb-wknd); }
.wtb-ln__date--none { border-style: dashed; color: var(--wtb-ink-3); }
.wtb-ln__flag { display: inline-flex; align-items: center; gap: 3px; color: var(--wtb-alarm); }
.wtb-ln__flag svg { width: 11px; height: 11px; }
.wtb-ln__hrs b { font-family: var(--wtb-f-m); font-weight: 500; font-size: 12px; color: var(--wtb-ink); letter-spacing: 0; }
.wtb-ln--run .wtb-ln__hrs b { color: var(--wtb-act); }
.wtb-ln__pc { display: inline-flex; align-items: center; gap: 3px; }
.wtb-ln__pc svg { width: 12px; height: 12px; }
.wtb-ln__busy { color: var(--wtb-act); }
.wtb-ln__done { color: var(--wtb-ink-3); }
.wtb-ln__go {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  width: 56px; padding: 0; border: 0; border-left: 1px solid var(--wtb-line); background: transparent;
  color: var(--wtb-ink-2); cursor: pointer; border-radius: 0;
  font-family: var(--wtb-f-c); font-weight: 700; font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
}
.wtb-ln__go svg { width: 18px; height: 18px; }
.wtb-ln__go--act { background: var(--wtb-act); border-color: var(--wtb-act); color: var(--wtb-act-ink); }
.wtb-ln__go--stop { background: var(--wtb-alarm); border-color: var(--wtb-alarm); color: #fff; }
.wtb-ln__go--ghost:active, .wtb-ln__go--more:active { background: var(--wtb-raise); }
.wtb-ln__go--more { color: var(--wtb-ink-3); }

@media (max-width: 640px) {
  /* Section heads shrink to a title and a count; the index, rule and
     explanatory note are desktop furniture. */
  .wtb-sec { margin-bottom: 20px; }
  .wtb-sec__head { margin-bottom: 8px; gap: 10px; flex-wrap: nowrap; }
  .wtb-sec__ix, .wtb-sec__rule, .wtb-sec__note { display: none; }
  .wtb-sec__t { font-size: 15px; letter-spacing: .07em; }
  .wtb-sec__stat { flex: 0 0 auto; margin-left: auto; font-size: 11px; }
  .wtb-sec__head .wtb-btn { display: none; }               /* Completed's "Hide" */
  .wtb-sections > .wtb-btn[data-toggledone] { width: 100%; height: 44px; }
  /* A quiet text row, not a second box: the bar's Task button is the main add. */
  .wtb-rowadd { padding: 8px 12px; font-size: 11px; min-height: 40px; }
  .wtb-rows--lines .wtb-rowadd { border: 0; background: transparent; }
  .wtb-rowadd svg { width: 13px; height: 13px; }
  .wtb-nomatch { padding: 32px 16px; }
}

/* ═══════════ TOUCH ═══════════ */
/* Nothing you need to hit should be under ~44px on a screen you poke with a
   finger. These are the controls that were sized for a mouse. */
@media (pointer: coarse) {
  /* The photo viewer is a full-screen modal worked entirely with a thumb —
     its controls were sized for a mouse sitting over a desktop lightbox. */
  .wtb-vw__x { width: 46px; height: 46px; }
  .wtb-vw__x svg { width: 20px; height: 20px; }
  .wtb-vw__nav { width: 52px; height: 84px; }
  .wtb-vw__th { width: 68px; height: 50px; }
  .wtb-vw__acts .wtb-btn { height: 46px; padding: 0 16px; font-size: 12.5px; }
  .wtb-vw__notea .wtb-btn { height: 46px; }
  /* 16px or Safari zooms the whole page the moment the note is tapped, and
     leaves it zoomed after the modal has gone. */
  .wtb-vw__notei { font-size: 16px; padding: 12px; }
  .wtb-vw__note { font-size: 15px; }

  .wtb-ract { width: 44px; height: 44px; }
  .wtb-rgo { height: 42px; padding: 0 15px; }
  .wtb-fb { height: 44px; padding: 0 12px; }
  .wtb-pop__i { min-height: 44px; }
  .wtb-fb--av { padding: 0 12px 0 4px; }
  .wtb-tag { height: 28px; padding: 0 10px; }
  .wtb-tk__tags { gap: 8px 9px; }
  .wtb-row__who { padding: 8px 6px; min-height: 44px; }
  .wtb-quick__b { height: 38px; padding: 0 14px; }
  .wtb-ftog { height: 38px; }
  .wtb-seg__b { height: 38px; }
  .wtb-lay__b { width: 38px; height: 38px; }
  /* iOS zooms the page when a focused input is under 16px. */
  .wtb-find__in { font-size: 16px; }
}

/* ═══════════ PHONE POLISH ═══════════ */
@media (max-width: 640px) {
  /* ── The viewer on a phone ──
     It was a desktop lightbox shrunk down: the figure centred in the screen,
     which on a 844px phone left ~460px of nothing above a photo 272px tall —
     the one thing anyone opened it for, given a third of the display. Now it
     is what a photo viewer on a phone is: the picture takes every pixel the
     controls do not need, and the controls sit where a thumb already is. */
  .wtb-vw { padding: 0; }
  .wtb-vw[open] { display: flex; place-items: initial; }
  .wtb-vw__fig {
    flex: 1;
    width: 100%;
    max-width: none;
    min-height: 0;
    gap: 0;
    align-items: stretch;
    /* --wtb-vw-keys is what the on-screen keyboard is covering, measured off
       visualViewport in view.js. The photo is the flexible one, so it is what
       gives the room up — and takes it straight back when the keys go away. */
    padding-bottom: calc(env(safe-area-inset-bottom) + var(--wtb-vw-keys, 0px));
  }
  /* The photo takes what is left. min-height:0 is what lets it give room
     back to the strip and the buttons rather than pushing them off. */
  .wtb-vw__fig img {
    flex: 1;
    min-height: 0;
    max-height: none;
    width: 100%;
    background: transparent;
  }

  /* Over the photo, clear of the notch, and a real target. */
  .wtb-vw__x { top: calc(10px + env(safe-area-inset-top)); right: 10px; }

  /* Still a thumb's worth, but out of the middle of the picture — and
     swiping is the main way through a set here anyway. */
  .wtb-vw__nav { width: 44px; height: 64px; background: rgba(0, 0, 0, .55); border-color: transparent; }
  .wtb-vw__prev { left: 0; }
  .wtb-vw__next { right: 0; }

  /* One line. "Bay 3" and the job title wrapped onto two rows at 360px, and
     the job title is the one thing anyone opening this already knows — so it
     is what gets cut, never the 5 / 12 in front of it. */
  .wtb-vw__cap {
    gap: 8px;
    padding: 9px 14px 0;
    font-size: 13px;
    flex-wrap: nowrap;
    justify-content: flex-start;
  }
  .wtb-vw__cap > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .wtb-vw__cap > span:first-child { flex: none; }

  /* One row that scrolls, not a block that wraps: six thumbnails wrapped
     onto two lines and took the height out of the photo above them. */
  .wtb-vw__strip {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    gap: 8px;
    padding: 10px 14px 2px;
    -webkit-overflow-scrolling: touch;
  }
  .wtb-vw__th { flex: none; width: 64px; height: 48px; scroll-snap-align: center; }

  /* The bottom bar. Two to a row rather than three ellipsised stubs. */
  .wtb-vw__acts { gap: 8px; padding: 10px 14px calc(10px + env(safe-area-inset-bottom)); }
  .wtb-vw__acts .wtb-btn { flex: 1 1 auto; min-width: 44%; }

  /* A long note must not squeeze the photo out — it scrolls on its own. */
  .wtb-vw__note { padding: 10px 14px 0; max-height: 22vh; overflow-y: auto; }
  .wtb-vw__note--edit { width: auto; padding: 10px 14px 0; }
  .wtb-vw__notea .wtb-btn { flex: 1 1 auto; }
  .wtb-vw__notei { min-height: 96px; }

  /* Writing one: the strip and the caption go too. Everything left is the
     photo and the box, and the keyboard inset above decides how they split. */
  .wtb-vw.is-noting .wtb-vw__cap,
  .wtb-vw.is-noting .wtb-vw__strip { display: none; }
  .wtb-vw.is-noting .wtb-vw__fig img { min-height: 15vh; }
  .wtb-vw.is-noting .wtb-vw__note--edit { padding-bottom: 14px; }

  /* Three priority boxes side by side is one word per line on a phone. */

  /* The finish prompt's two buttons, full width and stacked side by side. */

  /* Section headings carried desktop-sized air between them. */
  .wtb-sec { margin-bottom: 30px; }
  .wtb-sec__head { margin-bottom: 14px; }
  .wtb-sec__note { margin: -6px 0 14px; }
  .wtb-grid { gap: 12px; }

  .wtb-nomatch { padding: 40px 18px; }
  .wtb-void { padding: 26px 18px; }

}

@media (prefers-reduced-motion: reduce) {
  .wtb *, .wtb-run, .wtb-toast { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ═══════════ BULK SELECT ═══════════
   Off until asked for: the Select toggle turns the board into a picker, and
   the bar only appears once something is actually ticked. */
.wtb-ftog--select[aria-pressed="true"] {
  background: var(--wtb-act); border-color: var(--wtb-act); color: var(--wtb-act-ink);
}
/* The box sits over the job's photo rather than taking a column of its own,
   so every layout — row, phone line and card — picks it up unchanged. */
.wtb-pick-box {
  position: absolute; top: 8px; left: 9px; z-index: 3;
  width: 24px; height: 24px; display: grid; place-items: center;
  padding: 0; cursor: pointer; border-radius: 0;
  border: 1.5px solid var(--wtb-line-hi); background: var(--wtb-plate); color: transparent;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .35);
}
.wtb-pick-box:hover { border-color: var(--wtb-act); }
.wtb-pick-box.is-on { background: var(--wtb-act); border-color: var(--wtb-act); color: var(--wtb-act-ink); }
.wtb-pick-box svg { width: 14px; height: 14px; }
/* Nothing should start a clock or open a photo while you are ticking boxes. */
.is-wtb-selecting .wtb-row__shot,
.is-wtb-selecting .wtb-ln__shot,
.is-wtb-selecting .wtb-tk__shot { pointer-events: none; }

.wtb-bulk {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-overlay);
  display: flex; align-items: center; gap: 12px; padding: 12px 24px;
  background: var(--wtb-plate); border-top: 2px solid var(--wtb-alarm);
  transform: translateY(120%); visibility: hidden;
  transition: transform .22s cubic-bezier(.2, .8, .3, 1), visibility .22s;
}
.wtb-bulk.is-on { transform: none; visibility: visible; }
.wtb-bulk__n { font-family: var(--wtb-f-c); font-size: 13px; color: var(--wtb-ink-2); }
.wtb-bulk__n b { font-family: var(--wtb-f-m); font-size: 15px; color: var(--wtb-ink); }
.wtb-bulk__sp { flex: 1; }
.wtb-btn--danger { border-color: var(--wtb-alarm); color: var(--wtb-alarm); }
.wtb-btn--danger:hover { background: var(--wtb-alarm); border-color: var(--wtb-alarm); color: #fff; }
@media (max-width: 640px) {
  .wtb-bulk { padding: 10px 14px; gap: 8px; }
  .wtb-bulk__n { font-size: 12px; }
}

/* ═══════════ PLACE IN THE DAY ═══════════
   The number says where a job sits in its section; the fade says the same
   thing without being read. Hover brings a row back in full, and nothing
   fades far enough to stop being legible. */
.wtb-ix {
  font-family: var(--wtb-f-m); font-weight: 500; font-size: .78em;
  color: var(--wtb-ink-3); margin-right: 9px; font-variant-numeric: tabular-nums;
}
/* The rest of a long day sits behind one quiet line rather than a slow fade —
   it reads as a short list, and the count says what is under it. */
.wtb-more {
  display: flex; align-items: center; gap: 9px; width: 100%; padding: 10px 16px;
  border: 0; border-top: 1px dashed var(--wtb-line); background: transparent;
  color: var(--wtb-ink-3); cursor: pointer;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 12px;
  letter-spacing: .08em; text-transform: uppercase;
}
.wtb-more:hover { color: var(--wtb-ink); background: var(--wtb-raise); }
.wtb-more svg { width: 14px; height: 14px; }
.wtb-grid .wtb-more { margin-top: 12px; border-top: 0; justify-content: center; }

/* ═══════════ PAY BAND ═══════════ */
/* The resting colour of a job's left edge is what it pays: green for paid
   work, violet for commission, steel for the backlog. Urgent, running and
   flagged all paint over it below — a job being late or under someone's
   hands outranks how it is billed. */
.wtb-row--pay-paid .wtb-row__edge,       .wtb-ln--pay-paid .wtb-ln__edge       { background: var(--wtb-pay-paid); }
.wtb-row--pay-commission .wtb-row__edge, .wtb-ln--pay-commission .wtb-ln__edge { background: var(--wtb-pay-commission); }
.wtb-row--pay-future .wtb-row__edge,     .wtb-ln--pay-future .wtb-ln__edge     { background: var(--wtb-pay-future); }
.wtb-tk--pay-paid       { border-left: var(--wtb-band) solid var(--wtb-pay-paid); }
.wtb-tk--pay-commission { border-left: var(--wtb-band) solid var(--wtb-pay-commission); }
.wtb-tk--pay-future     { border-left: var(--wtb-band) solid var(--wtb-pay-future); }
/* A finished job keeps its band, quietly — it is history, not work. */
.wtb-row--done .wtb-row__edge, .wtb-ln--done .wtb-ln__edge { opacity: .4; }
.wtb-tk--done { border-left-color: var(--wtb-line-hi); }


/* ═══════════ ISSUE ═══════════
   What is wrong with a job, said on the job itself. Notes say how the work is
   done; an issue says why it is not being done. */
.wtb-issue {
  display: inline-flex; align-items: center; gap: 5px; vertical-align: -2px;
  color: var(--wtb-alarm); font-weight: 500;
}
.wtb-issue svg { width: 12px; height: 12px; flex-shrink: 0; }
.wtb-ract.is-issue, .wtb-tk__act.is-issue { color: var(--wtb-alarm); }
/* A blocked job marks its edge, but never over the top of a running clock or
   an urgent flag — those are the louder facts. */
.wtb-row--issue .wtb-row__edge,
.wtb-ln--issue .wtb-ln__edge {
  background: repeating-linear-gradient(-45deg, var(--wtb-alarm) 0 4px, transparent 4px 8px);
}
.wtb-row--urgent .wtb-row__edge, .wtb-row--run .wtb-row__edge,
.wtb-ln--urgent .wtb-ln__edge, .wtb-ln--run .wtb-ln__edge { background: var(--wtb-alarm); }
.wtb-row--run .wtb-row__edge, .wtb-ln--run .wtb-ln__edge { background: var(--wtb-act); }
.wtb-tk--issue { border-color: var(--wtb-alarm); }

.wtb-pop__note { display: block; padding: 10px 12px; }
.wtb-pop__note textarea {
  width: 100%; min-width: 240px; resize: vertical; padding: 9px 10px;
  border: 1px solid var(--wtb-line-hi); background: var(--wtb-sink); color: var(--wtb-ink);
  font: inherit; font-size: 13px; line-height: 1.5; border-radius: 0;
}
.wtb-pop__note textarea:focus { outline: none; border-color: var(--wtb-act); }
.wtb-pop__row { display: flex; gap: 8px; padding: 0 12px 12px; }

/* The place a job holds is also the control that changes it. */
.wtb-ix--set {
  width: 2.4em; padding: 1px 3px; text-align: center; border-radius: 0;
  border: 1px solid transparent; background: transparent; color: var(--wtb-ink-3);
  font-family: var(--wtb-f-m); font-weight: 500; font-size: .78em;
  font-variant-numeric: tabular-nums; cursor: text;
}
.wtb-ix--set:hover { border-color: var(--wtb-line-hi); color: var(--wtb-ink-2); }
.wtb-ix--set:focus {
  outline: none; border-color: var(--wtb-act); background: var(--wtb-sink); color: var(--wtb-ink);
}

/* ═══════════ ON THE CLOCK ═══════════
   Who is on a job right now, in the column that already answers "whose job is
   this" — a live clock outranks an assignment while it is running. */
.wtb-live {
  display: inline-flex; align-items: center; gap: 6px; vertical-align: -1px;
  font-weight: 600; color: var(--wtb-live);
}
.wtb-live__dot {
  width: 7px; height: 7px; flex-shrink: 0; border-radius: 50%;
  background: var(--wtb-live);
}
@media (prefers-reduced-motion: no-preference) {
  .wtb-live__dot { animation: wtb-pulse 1.6s ease-out infinite; }
  @keyframes wtb-pulse {
    0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--wtb-live) 70%, transparent); }
    70%  { box-shadow: 0 0 0 6px color-mix(in srgb, var(--wtb-live) 0%, transparent); }
    100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--wtb-live) 0%, transparent); }
  }
}
/* The sub line clips at the row's width, so a running job gets the room:
   the name is the part you need, the notes are not. */
.wtb-row--run .wtb-row__sub, .wtb-ln--run .wtb-ln__m { color: var(--wtb-ink-2); }

/* ═══════════ THE JOB, FULL SCREEN ═══════════
   A phone line has about 136px for a job carrying a car, a day, a crew
   member, hours, notes, an issue and a strip of photos. Tapping one opens
   this instead of a sheet of verbs — the job itself, with the actions under
   the thumb where they were.

   It sits at --z-overlay and before the two modals in the markup, so the add
   form, the finish dialog, the viewer and the board's own sheets all open
   over it. Behaviour: assets/js/views/work-tasks/view.js (openJob). */
.wtb-job {
  position: fixed; inset: 0; z-index: var(--z-overlay);
  display: flex; flex-direction: column;
  background: var(--wtb-board);
  animation: wtb-rise .18s cubic-bezier(.2, .8, .3, 1);
}
.wtb-job[hidden] { display: none; }
body.wtb-job-on { overflow: hidden; }

/* ── The bar. The pay band off the row, laid flat across the top: what kind
      of work this is, before a word is read. Urgent and running paint over
      it, the same order of importance the rows keep. ── */
.wtb-job__bar {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 10px;
  padding: calc(8px + env(safe-area-inset-top, 0px)) 12px 8px;
  background: var(--wtb-plate);
  border-bottom: 1px solid var(--wtb-line);
  border-top: var(--wtb-band) solid var(--wtb-pay-future);
}
.wtb-job--pay-paid .wtb-job__bar { border-top-color: var(--wtb-pay-paid); }
.wtb-job--pay-commission .wtb-job__bar { border-top-color: var(--wtb-pay-commission); }
.wtb-job--run .wtb-job__bar { border-top-color: var(--wtb-live); }
.wtb-job--urgent .wtb-job__bar { border-top-color: var(--wtb-alarm); }
.wtb-job--done .wtb-job__bar { border-top-color: var(--wtb-line-hi); }

.wtb-job__back {
  display: inline-flex; align-items: center; gap: 4px;
  min-height: 44px; padding: 0 10px 0 4px; border: 0; background: none;
  color: var(--wtb-ink); font-family: var(--wtb-f-b); font-size: 14px; font-weight: 600;
  cursor: pointer; border-radius: var(--wtb-r);
}
.wtb-job__back svg { width: 20px; height: 20px; }
.wtb-job__back:active { background: var(--wtb-raise); }
.wtb-job__sec {
  margin-left: auto; min-width: 0;
  font-family: var(--wtb-f-c); font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--wtb-ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.wtb-job__scroll {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 14px 14px 20px;
  display: flex; flex-direction: column; gap: 14px;
}
/* Each block is its own height, never a share of what is left. Left to shrink,
   the photo strip lost a third of itself and the thumbnails came out cropped. */
.wtb-job__scroll > * { flex: 0 0 auto; }

/* ── Head ── */
.wtb-jhead__tags { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.wtb-jhead__t {
  margin: 9px 0 0;
  font-family: var(--wtb-f-c); font-size: 22px; font-weight: 700; line-height: 1.2;
  letter-spacing: -.01em; color: var(--wtb-ink);
}
.wtb-job--done .wtb-jhead__t { color: var(--wtb-ink-2); }
.wtb-jhead__live, .wtb-jhead__done { margin: 8px 0 0; font-size: 13px; }
.wtb-jhead__done { color: var(--wtb-ink-2); }

/* ── The photos, big enough to tell one shot from another ── */
.wtb-jshots {
  display: flex; gap: 8px; overflow-x: auto; -webkit-overflow-scrolling: touch;
  padding-bottom: 2px; scrollbar-width: none;
}
.wtb-jshots::-webkit-scrollbar { display: none; }
.wtb-jshot {
  flex: 0 0 auto; width: 96px; height: 96px; padding: 0;
  border: 1px solid var(--wtb-line); border-radius: var(--wtb-r);
  background: var(--wtb-photo-bg); overflow: hidden; cursor: pointer;
}
.wtb-jshot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wtb-jshot--add {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  border-style: dashed; background: var(--wtb-plate); color: var(--wtb-ink-2);
  font-family: var(--wtb-f-b); font-size: 12px; font-weight: 600;
}
.wtb-jshot--add svg { width: 22px; height: 22px; }
.wtb-jshot--add:active { border-color: var(--wtb-act); color: var(--wtb-act); }

/* ── The facts. A row with an action is the way to change that fact, so
      Scheduled and Assigned are buttons and the rest are not. ── */
.wtb-jfacts {
  display: flex; flex-direction: column;
  background: var(--wtb-plate); border: 1px solid var(--wtb-line); border-radius: var(--wtb-r);
}
.wtb-jf {
  display: flex; align-items: center; gap: 12px;
  width: 100%; min-height: 48px; padding: 10px 12px;
  border: 0; border-top: 1px solid var(--wtb-line);
  background: none; color: var(--wtb-ink);
  font-family: var(--wtb-f-b); font-size: 14px; text-align: left;
}
.wtb-jf:first-child { border-top: 0; }
.wtb-jf--go { cursor: pointer; }
.wtb-jf--go:active { background: var(--wtb-raise); }
.wtb-jf--go svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--wtb-ink-3); }
.wtb-jf__k {
  flex: 0 0 96px;
  font-family: var(--wtb-f-c); font-size: 11px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--wtb-ink-3);
}
.wtb-jf__v {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; gap: 7px;
  font-weight: 500; overflow: hidden; text-overflow: ellipsis;
}
.wtb-jf__v b { font-family: var(--wtb-f-m); font-variant-numeric: tabular-nums; }
.wtb-jf__none { color: var(--wtb-ink-3); }

/* ── Notes, and what is stopping it ── */
.wtb-jnote {
  padding: 11px 12px;
  background: var(--wtb-plate); border: 1px solid var(--wtb-line); border-radius: var(--wtb-r);
}
.wtb-jnote__k {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--wtb-f-c); font-size: 11px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--wtb-ink-3);
}
.wtb-jnote__k svg { width: 13px; height: 13px; }
.wtb-jnote__v { margin: 6px 0 0; font-size: 14px; line-height: 1.5; white-space: pre-wrap; }
.wtb-jnote--issue { border-color: color-mix(in srgb, var(--wtb-alarm) 45%, var(--wtb-line)); }
.wtb-jnote--issue .wtb-jnote__k { color: var(--wtb-alarm); }
.wtb-jnote__go {
  margin-top: 8px; padding: 0; border: 0; background: none;
  color: var(--wtb-act); font-family: var(--wtb-f-b); font-size: 13px; font-weight: 600;
  text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}

/* ── The foot. The two things a job ends with on top, everything else in one
      wrapping row under them — all of it in the thumb zone. ── */
.wtb-job__foot {
  flex: 0 0 auto;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom, 0px));
  background: var(--wtb-plate); border-top: 1px solid var(--wtb-line);
  display: flex; flex-direction: column; gap: 8px;
}
.wtb-jfoot__go { display: flex; gap: 8px; }
.wtb-jgo {
  flex: 1 1 0; min-width: 0;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 52px; padding: 0 12px;
  border: 1px solid var(--wtb-act); border-radius: var(--wtb-r);
  background: var(--wtb-act); color: var(--wtb-act-ink);
  font-family: var(--wtb-f-b); font-size: 15px; font-weight: 700; cursor: pointer;
}
.wtb-jgo svg { width: 17px; height: 17px; flex-shrink: 0; }
.wtb-jgo:active { filter: brightness(.92); }
.wtb-jgo--stop { background: var(--wtb-live); border-color: var(--wtb-live); color: #fff; }
.wtb-jgo--ok { background: var(--wtb-plate); border-color: var(--wtb-line-hi); color: var(--wtb-ink); }
.wtb-jgo--ghost { background: var(--wtb-plate); border-color: var(--wtb-line-hi); color: var(--wtb-ink); }

.wtb-jfoot__acts { display: flex; flex-wrap: wrap; gap: 8px; }
.wtb-jact {
  flex: 1 1 auto; min-width: 92px;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 44px; padding: 0 10px;
  border: 1px solid var(--wtb-line); border-radius: var(--wtb-r);
  background: var(--wtb-raise); color: var(--wtb-ink-2);
  font-family: var(--wtb-f-b); font-size: 13px; font-weight: 600; cursor: pointer;
}
.wtb-jact svg { width: 15px; height: 15px; flex-shrink: 0; }
.wtb-jact:active { background: var(--wtb-sink); }
.wtb-jact.is-issue { color: var(--wtb-alarm); border-color: color-mix(in srgb, var(--wtb-alarm) 45%, var(--wtb-line)); }
.wtb-jact--bad { color: var(--wtb-alarm); }

@media (prefers-reduced-motion: reduce) {
  .wtb-job { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════
   WEEK BOARD — the `wtw-` block. The board's third reading: the next
   job beside how the week stands, a red overdue bar hung off the foot
   of both, then the days still to come beside the jobs with no day.

   It reads the board's own tokens, so it follows the theme with the
   rest of the board. Orange is the next thing to do, red is late,
   green is finished or ahead — nothing else is coloured. Square
   corners throughout: this is a plan on a wall, not a set of pills.
   ═══════════════════════════════════════════════════════════════ */

/* What the week replaces in the chrome. Its own head carries the title and
   the overdue count, so the tally would say the same things twice; rows vs
   cards and bulk select mean nothing to a list of days. */
.wtb--week .wtb-mast__lead,
.wtb--week .wtb-ticker,
.wtb--week .wtb-lay,
.wtb--week #wtbSelectTog { display: none; }
.wtb--week .wtb-mast { padding-bottom: 0; border-bottom: 0; }

.wtb .wtw { display: flex; flex-direction: column; gap: 20px; font-size: 14px; line-height: 1.45; }
.wtb .wtw-sp { flex: 1 1 0; }

/* Tones — the only colours the block uses for words. */
.wtb .wtw-tone--alarm { color: var(--wtb-alarm); }
.wtb .wtw-tone--act { color: var(--wtb-act); }
.wtb .wtw-tone--live { color: var(--wtb-live); }
.wtb .wtw-tone--mute { color: var(--wtb-ink-2); }
.wtb .wtw-tone--dim { color: var(--wtb-ink-3); }
.wtb .wtw-tone--ink { color: var(--wtb-ink); }
.wtb .wtw-strong { font-weight: 600; }

/* ── Buttons ── */
.wtb .wtw-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: 44px; padding: 0 12px; flex: none;
  border: 1px solid var(--wtb-line-hi); border-radius: 0; background: transparent;
  color: var(--wtb-ink); cursor: pointer; white-space: nowrap;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 12px;
  letter-spacing: .06em; text-transform: uppercase;
}
.wtb .wtw-btn svg { width: 13px; height: 13px; }
.wtb .wtw-btn:hover { background: var(--wtb-raise); }
.wtb .wtw-btn--big { height: 48px; padding: 0 16px; font-size: 13px; }
.wtb .wtw-btn--act { background: var(--wtb-act); border-color: var(--wtb-act); color: var(--wtb-act-ink); font-weight: 700; padding: 0 20px; }
.wtb .wtw-btn--act:hover { background: var(--wtb-act-hi); border-color: var(--wtb-act-hi); }
.wtb .wtw-btn--stop { border-color: var(--wtb-alarm); color: var(--wtb-alarm); }
.wtb .wtw-btn--line { border-color: var(--wtb-act); color: var(--wtb-act-hi); }
.wtb .wtw-btn--quiet { border-color: transparent; color: var(--wtb-ink-2); }
.wtb .wtw-btn--quiet:hover { color: var(--wtb-ink); background: transparent; }
.wtb .wtw-btn--dash { border-style: dashed; color: var(--wtb-ink-2); }
.wtb .wtw-btn--more { width: 100%; background: var(--wtb-raise); border-color: var(--wtb-line); color: var(--wtb-ink-2); }

/* ── Head: which week, and how much is overdue ── */
.wtb .wtw-head { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px 18px; }
.wtb .wtw-head__t { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.wtb .wtw-title {
  margin: 0; font-family: var(--wtb-f-c); font-weight: 700; font-size: 34px;
  line-height: 1.05; letter-spacing: .01em; color: var(--wtb-ink);
}
.wtb .wtw-range { font-size: 13px; color: var(--wtb-ink-2); }
.wtb .wtw-seg { display: flex; border: 1px solid var(--wtb-line-hi); }
.wtb .wtw-seg button {
  height: 44px; padding: 0 16px; border: 0; background: transparent; color: var(--wtb-ink-2);
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 13px; letter-spacing: .06em;
  text-transform: uppercase; cursor: pointer;
}
.wtb .wtw-seg button + button { border-left: 1px solid var(--wtb-line-hi); }
.wtb .wtw-seg button[aria-pressed="true"] { background: var(--wtb-ink); color: var(--wtb-board); }
.wtb .wtw-seg--below { display: none; }
.wtb .wtw-seg button:disabled { opacity: .35; cursor: default; }
.wtb .wtw-seg button:not([aria-pressed="true"]):not(:disabled):hover { background: var(--wtb-raise); color: var(--wtb-ink); }
/* The arrows step a week either way; the Weeks button names the week when it
   is neither this one nor the next, so the switch always says where you are. */
.wtb .wtw-seg__step { width: 44px; padding: 0 !important; display: inline-flex; align-items: center; justify-content: center; }
.wtb .wtw-seg__step svg { width: 16px; height: 16px; }
.wtb .wtw-seg__pick { display: inline-flex; align-items: center; justify-content: center; gap: 6px; white-space: nowrap; min-width: 0; }
.wtb .wtw-seg__pick svg { width: 12px; height: 12px; flex: none; }
/* The Weeks menu: one row a week, its number, its name and dates, and what is booked. */
.wtw-wkpop { width: min(340px, calc(100vw - 24px)); }
.wtb-pop--sheet.wtw-wkpop { width: auto; }
.wtw-wklist { max-height: min(420px, 60vh); overflow-y: auto; }
.wtb .wtw-wkrow { gap: 12px; }
.wtb .wtw-wkrow__n { flex: none; width: 34px; font-size: 12px; color: var(--wtb-ink-3); }
.wtb .wtw-wkrow__t { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.wtb .wtw-wkrow__t b { font-weight: 600; }
.wtb .wtw-wkrow__t i { font-style: normal; font-size: 12px; color: var(--wtb-ink-3); }
.wtb .wtw-wkrow.is-past b { color: var(--wtb-ink-2); font-weight: 500; }
.wtb .wtw-wkrow[aria-checked="true"] { box-shadow: inset 3px 0 0 var(--wtb-act); }
/* Two spellings for one button: the long one where there is room. */
.wtb .wtw-sm { display: none; }

/* ── Top: the next job beside how the week is going ── */
.wtb .wtw-topw { display: flex; flex-direction: column; }
/* The two cards meet edge to edge, so the red bar under them reads as the
   foot of one block rather than a third thing on the page. */
.wtb .wtw-top { display: flex; flex-wrap: wrap; align-items: stretch; }
.wtb .wtw-next, .wtb .wtw-sum {
  min-width: 0; display: flex; flex-direction: column;
  background: var(--wtb-plate); padding: 22px 24px;
}
.wtb .wtw-next { flex: 2 1 460px; gap: 12px; border: 2px solid var(--wtb-act); }
.wtb .wtw-sum { flex: 1 1 300px; gap: 10px; border: 1px solid var(--wtb-line); }
.wtb .wtw-kicker {
  font-family: var(--wtb-f-c); font-weight: 700; font-size: 13px; letter-spacing: .09em;
  text-transform: uppercase; color: var(--wtb-act);
}
.wtb .wtw-next__main { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 16px; }
.wtb .wtw-next__txt { flex: 1 1 240px; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.wtb .wtw-next__t {
  margin: 0; padding: 0; border: 0; background: none; text-align: left; color: var(--wtb-ink);
  font-family: var(--wtb-f-c); font-weight: 700; font-size: 28px; line-height: 1.15;
}
.wtb button.wtw-next__t { cursor: pointer; }
.wtb button.wtw-next__t:hover { color: var(--wtb-act-hi); }
.wtb .wtw-why { font-size: 14px; font-weight: 600; }
.wtb .wtw-notes { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; background: var(--wtb-raise); border: 1px solid var(--wtb-line); }
.wtb .wtw-notes span { font-family: var(--wtb-f-c); font-weight: 600; font-size: 13px; color: var(--wtb-ink-2); }
.wtb .wtw-notes p { margin: 0; font-size: 15px; white-space: pre-line; }
.wtb .wtw-next__acts { display: flex; flex-wrap: wrap; gap: 8px; }
.wtb .wtw-after { display: flex; flex-direction: column; gap: 6px; padding-top: 12px; border-top: 1px solid var(--wtb-line); }
.wtb .wtw-after__h { font-family: var(--wtb-f-c); font-weight: 600; font-size: 13px; color: var(--wtb-ink-2); }
.wtb .wtw-after__r { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; }
.wtb .wtw-after__t {
  flex: 1 1 200px; min-width: 0; padding: 0; border: 0; background: none; text-align: left;
  color: var(--wtb-ink); font-size: 14px;
}
.wtb .wtw-after__w { font-size: 13px; }
.wtb button.wtw-after__t { cursor: pointer; }
.wtb button.wtw-after__t:hover { color: var(--wtb-act-hi); }

/* ── The overdue bar: red, hung off the foot of the top cards, folded to one
      line until somebody opens it ── */
.wtb .wtw-od {
  display: flex; flex-direction: column; scroll-margin-top: 80px;
  background: var(--wtb-sink); border: 1px solid var(--wtb-alarm); border-top: 0;
}
.wtb .wtw-od__bar {
  display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 24px;
  border: 0; background: var(--wtb-alarm); color: var(--wtb-board); text-align: left; cursor: pointer;
}
.wtb .wtw-od__bar b { font-size: 16px; font-weight: 500; }
.wtb .wtw-od__t, .wtb .wtw-od__v {
  font-family: var(--wtb-f-c); font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
}
.wtb .wtw-od__t { font-size: 15px; }
.wtb .wtw-od__v { font-size: 12px; }
.wtb .wtw-od__line { flex: 1 1 0; min-width: 0; font-size: 13px; font-weight: 600; }
.wtb .wtw-od__list { display: flex; flex-direction: column; padding: 2px 24px 10px; }
.wtb .wtw-od__r {
  display: flex; flex-wrap: wrap; align-items: center; gap: 2px 12px;
  padding: 4px 0; border-bottom: 1px solid var(--wtb-line);
}
.wtb .wtw-od__name {
  flex: 1 1 220px; min-width: 0; padding: 0; border: 0; background: none; text-align: left;
  color: var(--wtb-ink); font-size: 14px;
}
.wtb button.wtw-od__name { cursor: pointer; }
.wtb button.wtw-od__name:hover { color: var(--wtb-act-hi); }
.wtb .wtw-od__late { font-size: 13px; font-weight: 600; color: var(--wtb-alarm); }
.wtb .wtw-od__more { align-self: flex-start; padding: 0; }

.wtb .wtw-sum__h { font-family: var(--wtb-f-c); font-weight: 600; font-size: 13px; color: var(--wtb-ink-2); }
.wtb .wtw-sum__v { font-family: var(--wtb-f-c); font-weight: 700; font-size: 40px; line-height: 1; }
.wtb .wtw-sum__sub { margin: 0; font-size: 14px; color: var(--wtb-ink-2); }
.wtb .wtw-sum__pace { font-size: 14px; font-weight: 500; }
.wtb .wtw-stats {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px;
  margin-top: auto; padding-top: 12px; border-top: 1px solid var(--wtb-line);
}
.wtb .wtw-stats div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.wtb .wtw-stats b { font-size: 20px; font-weight: 500; color: var(--wtb-ink); }
.wtb .wtw-stats b.wtw-tone--alarm { color: var(--wtb-alarm); }
.wtb .wtw-stats b.wtw-tone--live { color: var(--wtb-live); }
.wtb .wtw-stats span { font-size: 13px; color: var(--wtb-ink-2); }

/* ── Shared bits of a job ── */
.wtb .wtw-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; font-size: 13px; color: var(--wtb-ink-2); }
.wtb .wtw-pay { display: inline-flex; align-items: center; gap: 6px; }
.wtb .wtw-pay i { width: 8px; height: 8px; background: var(--wtb-pay-future); }
.wtb .wtw-pay--paid i { background: var(--wtb-pay-paid); }
.wtb .wtw-pay--commission i { background: var(--wtb-pay-commission); }
.wtb .wtw-who {
  min-height: 24px; padding: 0; border: 0; background: none; cursor: pointer;
  color: var(--wtb-ink-2); font-size: 13px; text-align: left;
}
.wtb .wtw-who:hover { color: var(--wtb-ink); text-decoration: underline; }
.wtb .wtw-hrs { color: var(--wtb-live); }
.wtb .wtw-hot { color: var(--wtb-alarm); }
.wtb .wtw-issue { font-size: 13px; font-weight: 600; color: var(--wtb-wknd-txt); }
.wtb .wtw-issue--lg { font-size: 14px; }
.wtb .wtw-note { font-size: 13px; color: var(--wtb-ink-2); }
.wtb .wtw-shot {
  position: relative; flex: none; padding: 0; overflow: hidden; cursor: zoom-in;
  border: 1px solid var(--wtb-line-hi); background: var(--wtb-photo-bg);
}
.wtb .wtw-shot img { display: block; width: 100%; height: 100%; object-fit: cover; }
.wtb .wtw-shot__n {
  position: absolute; right: 0; bottom: 0; padding: 1px 5px;
  background: var(--wtb-board); color: var(--wtb-ink); font-size: 11px;
}
.wtb .wtw-shot--next { width: 148px; height: 148px; }
.wtb .wtw-shot--row { width: 56px; height: 56px; }
.wtb .wtw-shot--rail { width: 96px; height: 96px; }
.wtb .wtw-marks { display: flex; flex-wrap: wrap; gap: 4px; }
.wtb .wtw-mark { width: 11px; height: 11px; border: 2px solid var(--wtb-ink-3); }
.wtb .wtw-mark--done { background: var(--wtb-live); border-color: var(--wtb-live); }
.wtb .wtw-mark--late { background: var(--wtb-alarm); border-color: var(--wtb-alarm); }
.wtb .wtw-mark--early { border-color: var(--wtb-live); }

/* ── The phone's day strip — hidden until the screen is a phone ── */
.wtb .wtw-strip { display: none; }

/* ── The days beside the No date panel ── */
.wtb .wtw-body { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 20px; }
.wtb .wtw-days { flex: 999 1 620px; min-width: 0; border-bottom: 1px solid var(--wtb-line); }
/* The days already gone, folded to one line that still says what they left. */
.wtb .wtw-past {
  width: 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 2px 14px;
  min-height: 44px; padding: 0 16px; border: 0; border-top: 1px solid var(--wtb-line);
  background: transparent; color: var(--wtb-ink-2); text-align: left; cursor: pointer;
}
.wtb .wtw-past:hover { background: var(--wtb-raise); }
.wtb .wtw-past__t { font-family: var(--wtb-f-c); font-weight: 600; font-size: 15px; }
.wtb .wtw-past__l { flex: 1 1 0; min-width: 0; font-size: 13px; }
.wtb .wtw-past__v { font-family: var(--wtb-f-c); font-weight: 600; font-size: 12px; letter-spacing: .06em; text-transform: uppercase; }
.wtb .wtw-day {
  display: grid; grid-template-columns: 170px minmax(0, 1fr); gap: 20px;
  padding: 14px 16px; border-top: 1px solid var(--wtb-line);
  scroll-margin-top: 80px;
}
.wtb .wtw-day.is-today { background: var(--wtb-plate); }
.wtb .wtw-day__head { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.wtb .wtw-today {
  font-family: var(--wtb-f-c); font-weight: 700; font-size: 12px; letter-spacing: .09em;
  text-transform: uppercase; color: var(--wtb-act);
}
.wtb .wtw-day__name {
  margin: 0; font-family: var(--wtb-f-c); font-weight: 600; font-size: 19px; line-height: 1.1;
  color: var(--wtb-ink);
}
.wtb .wtw-day.is-past .wtw-day__name { color: var(--wtb-ink-2); }
.wtb .wtw-day__st { font-size: 13px; font-weight: 600; }
.wtb .wtw-day__head .wtw-marks { margin-top: 2px; }
.wtb .wtw-day__jobs { min-width: 0; display: flex; flex-direction: column; }
.wtb .wtw-empty { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; min-height: 44px; }

.wtb .wtw-task {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  padding: 8px 0; border-bottom: 1px solid var(--wtb-raise);
}
.wtb .wtw-task:last-child { border-bottom: 0; }
.wtb .wtw-task__body { flex: 1 1 260px; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.wtb .wtw-task__t, .wtb .wtw-ri__t {
  padding: 0; border: 0; background: none; text-align: left; color: var(--wtb-ink);
  font-size: 15px; font-weight: 500;
}
.wtb .wtw-ri__t { font-size: 14px; }
.wtb button.wtw-task__t, .wtb button.wtw-ri__t { cursor: pointer; }
.wtb button.wtw-task__t:hover, .wtb button.wtw-ri__t:hover { color: var(--wtb-act-hi); }
.wtb .wtw-task.is-done .wtw-task__t { color: var(--wtb-ink-3); text-decoration: line-through; }
.wtb .wtw-task.is-running .wtw-task__t { color: var(--wtb-live); }

/* The finished box: a 24px square on a 44px target. */
.wtb .wtw-box {
  flex: none; width: 44px; height: 44px; padding: 0; border: 0; background: transparent;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
}
.wtb span.wtw-box { cursor: default; }
.wtb .wtw-box > span {
  width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--wtb-ink-3); color: transparent;
}
.wtb .wtw-box svg { width: 14px; height: 14px; }
.wtb .wtw-box:hover > span { border-color: var(--wtb-live); }
.wtb .wtw-box.is-done > span { background: var(--wtb-live); border-color: var(--wtb-live); color: var(--wtb-board); }

/* ── How many days a job runs: a control in the job's meta line ── */
.wtb .wtw-span {
  display: inline-flex; align-items: center; gap: 4px; min-height: 28px; padding: 0 8px;
  border: 1px solid var(--wtb-line-hi); background: transparent; color: var(--wtb-ink-2); cursor: pointer;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 12px; letter-spacing: .04em; text-transform: uppercase;
}
.wtb .wtw-span svg { width: 12px; height: 12px; }
.wtb .wtw-span:hover { color: var(--wtb-ink); border-color: var(--wtb-ink-3); }
/* A run wears the action colour on its days so it reads as one job. */
.wtb .wtw-span.is-multi { border-color: var(--wtb-act); color: var(--wtb-act); }
.wtb .wtw-span.is-static { cursor: default; }
.wtb .wtw-push svg { width: 13px; height: 13px; }

/* ── Dragging on the week ── */
.wtb [data-wk-drag] { cursor: grab; -webkit-touch-callout: none; }
.wtb .wtw-task.is-dragging, .wtb .wtw-od__r.is-dragging, .wtb .wtw-ri.is-dragging { opacity: .3; }
.wtb .wtw-day.is-drop { outline: 2px solid var(--wtb-act); outline-offset: -2px; }
.wtb .wtw-nd.is-drop { outline: 2px solid var(--wtb-act); outline-offset: -2px; }
.wtb .wtw-drop-marker { height: 2px; margin: -1px 0; background: var(--wtb-act); pointer-events: none; }
.wtb-ghost-card.wtw-ghost { padding: 8px 12px; height: auto !important; }
/* Under a drag the phone's action bar is see-through to the pointer, so a
   finger over it still finds the day beneath. */
body.wtb-dragging [data-mob-bar] { pointer-events: none; }

/* ── No date: a panel beside the days ── */
.wtb .wtw-nd {
  flex: 1 1 300px; min-width: 0; max-width: 400px;
  display: flex; flex-direction: column; gap: 6px;
  background: var(--wtb-plate); border: 1px solid var(--wtb-line); padding: 18px;
}
.wtb .wtw-nd__h { display: flex; align-items: baseline; gap: 10px; }
.wtb .wtw-nd__h .wtb-num { font-size: 15px; color: var(--wtb-ink-2); }
.wtb .wtw-nd__t { margin: 0; font-family: var(--wtb-f-c); font-weight: 700; font-size: 20px; color: var(--wtb-ink); }
.wtb .wtw-nd__p { margin: 0 0 4px; font-size: 13px; color: var(--wtb-ink-2); }
.wtb .wtw-ri {
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  padding: 12px 0; border-top: 1px solid var(--wtb-line);
}

/* ── Tablet: the board's own working size ── */
@media (max-width: 1024px) {
  .wtb .wtw-day { grid-template-columns: 130px minmax(0, 1fr); gap: 14px; padding: 12px; }
  .wtb .wtw-nd { max-width: none; flex-basis: 100%; }
}

/* ── Phone ── */
@media (max-width: 640px) {
  .wtb .wtw { gap: 16px; }
  .wtb .wtw-range { font-size: 12px; }
  /* The head is one line; the week switch drops below the summary. */
  .wtb .wtw-head__t { flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; }
  .wtb .wtw-title { font-size: 20px; line-height: 1.1; }
  .wtb .wtw-seg--head { display: none; }
  .wtb .wtw-seg--below { display: grid; grid-template-columns: 44px repeat(3, minmax(0, 1fr)) 44px; }
  .wtb .wtw-seg--below button { padding: 0 6px; font-size: 12px; letter-spacing: .04em; }
  .wtb .wtw-lg { display: none; }
  .wtb .wtw-sm { display: inline; }

  /* The overdue bar hangs off the job card, and the summary comes after. */
  .wtb .wtw-top { display: contents; }
  .wtb .wtw-next { order: 1; flex: none; padding: 14px; gap: 10px; }
  .wtb .wtw-od { order: 2; flex: none; }
  .wtb .wtw-sum { order: 3; flex: none; margin-top: 16px; padding: 14px; gap: 8px; }
  .wtb .wtw-od__bar { padding: 0 16px; }
  .wtb .wtw-od__list { padding: 2px 16px 10px; }
  /* The photo leads the card, full width; the clock gets a row to itself. */
  .wtb .wtw-next__main { flex-direction: column; gap: 10px; }
  .wtb .wtw-next__txt { flex-basis: auto; }
  .wtb .wtw-shot--next { order: -1; width: 100%; height: 150px; }
  .wtb .wtw-next__acts > .wtw-btn { flex: 1 1 0; min-width: 0; height: 44px; padding: 0 4px; font-size: 12px; }
  .wtb .wtw-next__acts > [data-in], .wtb .wtw-next__acts > [data-out] { flex: 1 1 100%; height: 52px; font-size: 15px; }
  .wtb .wtw-btn--skip { border-color: var(--wtb-line); }
  .wtb .wtw-after__r { flex-wrap: nowrap; }
  .wtb .wtw-after__t { flex: 1 1 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .wtb .wtw-after__w { flex: none; }
  /* The summary shrinks to its verdict and its four numbers. */
  .wtb .wtw-sum__h, .wtb .wtw-sum__sub { display: none; }
  .wtb .wtw-sum__v { display: inline; font-size: 28px; margin-right: 12px; }
  .wtb .wtw-sum__pace { display: inline; }
  .wtb .wtw-stats { gap: 8px; padding-top: 8px; }
  .wtb .wtw-stats b { font-size: 18px; }
  .wtb .wtw-next__t { font-size: 22px; }
  .wtb .wtw-sum__v { font-size: 34px; }

  .wtb .wtw-strip { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
  .wtb .wtw-cell {
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 8px 0 9px; min-height: 76px; text-decoration: none; color: var(--wtb-ink);
    border: 1px solid var(--wtb-line);
  }
  .wtb .wtw-cell.is-today { background: var(--wtb-raise); border-color: var(--wtb-act); }
  .wtb .wtw-cell__d { font-family: var(--wtb-f-c); font-weight: 600; font-size: 12px; }
  .wtb .wtw-cell.is-past .wtw-cell__d { color: var(--wtb-ink-2); }
  .wtb .wtw-cell__n { font-size: 15px; }
  .wtb .wtw-cell .wtw-marks { justify-content: center; gap: 3px; padding: 0 4px; }
  .wtb .wtw-cell .wtw-mark { width: 9px; height: 9px; }

  /* A day is a heading over cards. A past day with nothing open is left to
     the strip, which already shows it went green. */
  .wtb .wtw-days { border-bottom: 0; display: flex; flex-direction: column; gap: 16px; }
  .wtb .wtw-day { display: flex; flex-direction: column; gap: 8px; padding: 10px 0 0; scroll-margin-top: 70px; }
  .wtb .wtw-day.is-today { background: transparent; }
  .wtb .wtw-day__head { flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
  .wtb .wtw-day__head .wtw-marks { display: none; }
  .wtb .wtw-day__st { margin-left: auto; }
  .wtb .wtw-day__jobs { gap: 8px; }
  .wtb .wtw-task {
    align-items: flex-start; gap: 6px; padding: 8px 12px 10px 4px;
    background: var(--wtb-plate); border: 1px solid var(--wtb-line);
  }
  .wtb .wtw-task:last-child { border-bottom: 1px solid var(--wtb-line); }
  .wtb .wtw-task__body { flex: 1 1 calc(100% - 60px); padding-top: 10px; gap: 6px; }
  .wtb .wtw-task > .wtw-shot, .wtb .wtw-task > .wtw-btn { margin-left: 50px; }
  .wtb .wtw-task > .wtw-shot + .wtw-btn { margin-left: 0; }

  /* No date becomes a section of cards under the days. */
  .wtb .wtw-body { flex-direction: column; align-items: stretch; gap: 16px; }
  .wtb .wtw-days, .wtb .wtw-nd { flex: none; }
  .wtb .wtw-nd { background: transparent; border: 0; border-top: 1px solid var(--wtb-line); padding: 10px 0 0; gap: 8px; }
  .wtb .wtw-nd__t { font-weight: 600; font-size: 19px; }
  .wtb .wtw-nd__p { display: none; }
  .wtb .wtw-nd .wtw-ri { align-items: stretch; padding: 12px; background: var(--wtb-plate); border: 1px solid var(--wtb-line); }
  .wtb .wtw-nd .wtw-ri > .wtw-btn { align-self: flex-start; }
}

/* ═══════════════════════════════════════════════════════════════
   STEPS — the `wst-` block. The checklist inside a job, drawn by one
   renderer (stepsHTML) wherever it appears: under the Next job, in a
   week row, on the phone's full-screen job and in the older views' pop.
   It reads the board's tokens; green is ticked, nothing else is coloured.
   ═══════════════════════════════════════════════════════════════ */
.wtb #wtbStepsField[hidden] { display: none; }

.wtb .wst { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.wtb .wst-h { display: flex; align-items: center; gap: 10px; }
.wtb .wst-h__t {
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 13px; color: var(--wtb-ink-2);
}
.wtb .wst-h__n { font-size: 13px; color: var(--wtb-ink); }
/* How far through, as a bar — read without counting. */
.wtb .wst-bar { flex: 1 1 auto; height: 4px; background: var(--wtb-line); }
.wtb .wst-bar i { display: block; height: 100%; background: var(--wtb-live); transition: width .2s; }

.wtb .wst-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--wtb-line); }
.wtb .wst-r {
  display: flex; align-items: center; gap: 4px; min-height: 40px;
  border-bottom: 1px solid var(--wtb-line);
}
/* The number is the step's place and its handle — drag it, tap it to type a
   place. touch-action: none is what lets a finger on it drag at once while a
   swipe anywhere else on the list still scrolls. */
.wtb .wst-n {
  flex: none; width: 28px; height: 40px; padding: 0; border: 0; border-radius: 0; background: transparent;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--wtb-ink-3); font-family: var(--wtb-f-m); font-size: 13px; font-weight: 600;
  cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none;
}
.wtb .wst-n:hover:not(:disabled), .wtb .wst-n:focus-visible { color: var(--wtb-ink); background: var(--wtb-raise); }
.wtb .wst-n:disabled { cursor: default; }
.wtb .wst-n--in {
  height: 32px; border: 1px solid var(--wtb-act); background: var(--wtb-raise); color: var(--wtb-ink);
  text-align: center; cursor: text; touch-action: auto; user-select: text; -webkit-user-select: text; outline: none;
}
.wtb .wst-r.is-done .wst-n { color: var(--wtb-ink-3); }
.wtb .wst-r { position: relative; }
.wtb .wst-r.is-lift { background: var(--wtb-raise); opacity: .6; }
.wtb .wst-r.is-lift .wst-n { cursor: grabbing; color: var(--wtb-act-hi); }
.wtb .wst-r.is-mark-above::before, .wtb .wst-r.is-mark-below::after {
  content: ''; position: absolute; left: 0; right: 0; height: 2px; background: var(--wtb-act);
}
.wtb .wst-r.is-mark-above::before { top: -1px; }
.wtb .wst-r.is-mark-below::after { bottom: -1px; }
body.wtb-dragging .wst-n { cursor: grabbing; }

.wtb .wst-box {
  flex: none; width: 40px; height: 40px; padding: 0; border: 0; background: transparent; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.wtb .wst-box > span {
  width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--wtb-ink-3); color: transparent;
}
.wtb .wst-box svg { width: 12px; height: 12px; }
.wtb .wst-box:hover > span { border-color: var(--wtb-live); }
.wtb .wst-r.is-done .wst-box > span { background: var(--wtb-live); border-color: var(--wtb-live); color: var(--wtb-board); }
.wtb .wst-t {
  flex: 1 1 auto; min-width: 0; padding: 8px 0; border: 0; background: none; text-align: left; cursor: text;
  color: var(--wtb-ink); font-size: 14px; line-height: 1.35; overflow-wrap: anywhere;
}
.wtb .wst-r.is-done .wst-t { color: var(--wtb-ink-3); text-decoration: line-through; }
.wtb .wst-edit {
  flex: 1 1 auto; min-width: 0; height: 34px; padding: 0 8px; border: 1px solid var(--wtb-act);
  background: var(--wtb-raise); color: var(--wtb-ink); font: inherit; font-size: 14px; border-radius: 0;
}
.wtb .wst-by { flex: none; font-size: 12px; color: var(--wtb-ink-3); }
.wtb .wst-del {
  flex: none; width: 36px; height: 36px; padding: 0; border: 0; background: transparent; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; color: var(--wtb-ink-3);
  opacity: .5; transition: opacity .12s, color .12s;
}
.wtb .wst-del svg { width: 14px; height: 14px; }
.wtb .wst-r:hover .wst-del, .wtb .wst-del:focus-visible { opacity: 1; }
.wtb .wst-del:hover { color: var(--wtb-alarm); }

.wtb .wst-all {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 8px 0 2px;
  font-size: 13px; font-weight: 600; color: var(--wtb-live);
}
.wtb .wst-add { display: flex; gap: 6px; }
.wtb .wst-add__in {
  flex: 1 1 auto; min-width: 0; height: 40px; padding: 0 10px; border-radius: 0;
  border: 1px dashed var(--wtb-line-hi); background: transparent; color: var(--wtb-ink);
  font: inherit; font-size: 14px;
}
.wtb .wst-add__in:focus { border-style: solid; border-color: var(--wtb-act); background: var(--wtb-raise); outline: none; }
.wtb .wst-add__in::placeholder { color: var(--wtb-ink-3); }
.wtb .wst-add__go {
  flex: none; display: inline-flex; align-items: center; gap: 6px; height: 40px; padding: 0 12px;
  border: 1px solid var(--wtb-line-hi); background: transparent; color: var(--wtb-ink); cursor: pointer; border-radius: 0;
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
}
.wtb .wst-add__go svg { width: 13px; height: 13px; }
.wtb .wst-add__go:hover { border-color: var(--wtb-act); color: var(--wtb-act-hi); }

/* In the Next job card the list has room to breathe. */
.wtb .wtw-next .wst { padding-top: 6px; }

/* ── The steps toggle in a week row, and the count chip in the older views ── */
.wtb .wtw-steps, .wtb .wst-chip {
  display: inline-flex; align-items: center; gap: 5px; min-height: 28px; padding: 0 8px; cursor: pointer;
  border: 1px solid var(--wtb-line-hi); background: transparent; color: var(--wtb-ink-2);
  font-family: var(--wtb-f-c); font-weight: 600; font-size: 12px; letter-spacing: .04em; text-transform: uppercase;
}
.wtb .wtw-steps svg, .wtb .wst-chip svg { width: 11px; height: 11px; }
.wtb .wtw-steps:hover, .wtb .wst-chip:hover { color: var(--wtb-ink); border-color: var(--wtb-ink-3); }
.wtb .wtw-steps.is-none { border-style: dashed; color: var(--wtb-ink-3); }
.wtb .wtw-steps.is-open { border-color: var(--wtb-ink); color: var(--wtb-ink); }
.wtb .wtw-steps.is-done, .wtb .wst-chip.is-done { border-color: var(--wtb-live); color: var(--wtb-live); }
.wtb .wst-chip { min-height: 24px; vertical-align: middle; }
.wtb .wtw-task__body > .wst { margin-top: 6px; }
/* An unfolded list makes the row tall; its box and its clock stay at the top
   with the job's name rather than drifting to the middle of the steps. */
.wtb .wtw-task.is-steps { align-items: flex-start; }
.wtb-ln__steps { display: inline-flex; align-items: center; gap: 3px; }
.wtb-ln__steps svg { width: 10px; height: 10px; }
.wtb-ln__steps.is-done { color: var(--wtb-live); }

/* ── On the full-screen job and in the pop ── */
.wtb .wtb-jsteps { padding: 14px 16px; border-bottom: 1px solid var(--wtb-line); }
.wtb-pop--steps { width: min(420px, calc(100vw - 24px)); }
.wtb-pop__steps { padding: 4px 11px 11px; }

/* ── Touch: every control in the list is a thumb's width ── */
@media (pointer: coarse) {
  .wtb .wst-r { min-height: 48px; }
  .wtb .wst-box { width: 48px; height: 48px; }
  .wtb .wst-n { width: 40px; height: 48px; font-size: 15px; }
  .wtb .wst-n--in { height: 40px; }
  .wtb .wst-box > span { width: 24px; height: 24px; }
  .wtb .wst-box svg { width: 14px; height: 14px; }
  .wtb .wst-del { width: 44px; height: 44px; opacity: .8; }
  .wtb .wst-t { font-size: 15px; padding: 10px 0; }
  .wtb .wst-add__in, .wtb .wst-add__go { height: 48px; }
  .wtb .wtw-steps { min-height: 36px; padding: 0 10px; }
}
/* 16px in the boxes on a phone: iOS zooms the whole page into any field set
   smaller, and a checklist that lurches every time a step is typed is one
   nobody keeps using. */
@media (max-width: 640px), (pointer: coarse) {
  .wtb .wst-add__in, .wtb .wst-edit, .wtb .wst-n--in { font-size: 16px; }
}
