/* WE53 · Field Service — styles for the /service contour only.
   Kept in its own file on purpose: style.css is edited by several people at once and
   these blocks were wiped three times in one day. This file loads AFTER style.css,
   so anything here also wins over a stale duplicate left behind there. */
/* ── Field service ──────────────────────────────────────────────────────────
   Second contour of the portal: dispatch board (desktop) and the courier's day
   (phone). The courier screen is the one that has to survive a bar terrace in
   sunlight, so its controls are large and stacked; the board reuses the tables. */
.badge.s-new{background:var(--amber-bg);color:var(--amber-fg)}
.badge.s-assigned{background:var(--surface-1);color:var(--text-secondary)}
.badge.s-planned{background:var(--bg-accent);color:var(--text-accent)}
.badge.s-in_progress{background:var(--accent);color:#fff}
.badge.s-failed{background:var(--red-bg);color:var(--red-fg)}
.badge.s-cancelled{background:transparent;color:var(--text-muted);border:1px solid var(--border)}
.badge.role-courier{background:var(--bg-accent);color:var(--text-accent)}
.badge.role-service_lead{background:var(--accent);color:#fff}
.badge.role-support{background:var(--surface-1);color:var(--text-secondary)}

.sv-board .sv-desc{max-width:340px;overflow:hidden;display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical}
.sv-assign{display:flex;gap:5px;align-items:center}
.sv-assign select,.sv-assign input[type=date]{font-size:12px;padding:4px 7px;
  border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface-2)}
.sv-over{color:var(--red-fg);font-weight:600}
tr.sv-in_progress td{background:var(--bg-accent)}
tr.sv-self td{background:var(--surface-1)}

/* forms */
.sv-row{display:flex;gap:12px;flex-wrap:wrap;align-items:flex-end;margin-bottom:12px}
.sv-row label,.sv-full{display:flex;flex-direction:column;gap:4px;font-size:12px;
  color:var(--text-secondary);font-weight:500}
.sv-full{width:100%;margin-bottom:12px}
.sv-row input,.sv-row select,.sv-row textarea,.sv-full input,.sv-full select,
.sv-full textarea{font-size:14px;padding:8px 10px;border:1px solid var(--border);
  border-radius:var(--radius-sm);background:var(--surface-2);color:var(--text-primary);
  font-family:inherit;min-width:180px}
.sv-full input,.sv-full textarea{width:100%}
.sv-venue{position:relative}
.sv-vqlist{position:absolute;top:100%;left:0;right:0;z-index:9;background:var(--surface-2);
  border:1px solid var(--border-strong);border-radius:var(--radius-sm);box-shadow:var(--shadow);
  max-height:280px;overflow:auto}
.sv-vqitem{padding:7px 11px;cursor:pointer;font-size:13px;color:var(--text-primary)}
.sv-vqitem:hover{background:var(--bg-accent)}
.sv-vqname{font-weight:600}
.sv-vend{color:var(--text-muted);font-size:11px;margin-left:5px}
.sv-city{color:var(--text-secondary);font-size:11px}
.sv-vqempty{padding:9px 11px;font-size:12px;color:var(--text-muted)}
.sv-pick{background:var(--surface-1);border-radius:var(--radius-sm);padding:9px 12px;
  margin-bottom:12px;font-size:13px}
.sv-cancel{margin-top:6px;padding-top:10px;border-top:1px dashed var(--border)}

/* task page */
.sv-meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:8px 18px;
  font-size:13px}
.sv-k{display:block;font-size:10.5px;text-transform:uppercase;letter-spacing:.03em;
  color:var(--text-muted);font-weight:600}
.sv-desc-box{margin-top:12px;background:var(--surface-1);border-radius:var(--radius-sm);
  padding:10px 12px;font-size:13.5px;white-space:pre-wrap}
.sv-outcome{margin-top:12px;background:var(--green-bg);color:var(--green-fg);
  border-radius:var(--radius-sm);padding:10px 12px;font-size:13.5px}
.sv-photos{display:flex;flex-wrap:wrap;gap:10px}
.sv-photos a{display:flex;flex-direction:column;gap:3px;width:150px}
.sv-photos img{width:150px;height:150px;object-fit:cover;border-radius:var(--radius-sm);
  border:1px solid var(--border)}
.sv-timeline{list-style:none;margin:0 0 14px;padding:0;font-size:12.5px}
.sv-timeline li{display:flex;gap:10px;padding:5px 0;border-bottom:1px solid var(--border)}
.sv-timeline li:last-child{border-bottom:0}
.sv-when{color:var(--text-muted);white-space:nowrap;font-variant-numeric:tabular-nums}
.sv-who{color:var(--text-secondary);min-width:90px}
.sv-what{color:var(--text-primary)}
.sv-ev-closed .sv-what{color:var(--green-fg)}
.sv-pb summary{cursor:pointer;font-size:13px;font-weight:600;color:var(--text-secondary);
  padding:6px 0}
.sv-pbrow{align-items:center;gap:8px;margin-bottom:6px}
.sv-pblbl{font-size:12px;color:var(--text-secondary);min-width:150px}
.sv-qty{max-width:90px;min-width:70px}
.sv-sn{flex:1}

/* courier day */
.sv-dayhead{display:flex;justify-content:space-between;align-items:center;gap:12px}
.sv-daypick input{font-size:13px;padding:6px 10px;border:1px solid var(--border);
  border-radius:var(--radius-sm);background:var(--surface-2)}
.sv-stop{padding:14px 16px}
.sv-stophead{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;
  margin-bottom:8px;font-size:15px}
.sv-stopmeta{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-bottom:8px}
.sv-addr{font-size:13.5px;margin-bottom:8px}
.sv-actions{display:flex;gap:8px;margin:12px 0 8px}
.sv-actions .btn{flex:1}
.sv-reportfold>summary{list-style:none;display:inline-block;margin-top:4px}
.sv-reportfold>summary::-webkit-details-marker{display:none}
.sv-report{margin-top:12px;border-top:1px solid var(--border);padding-top:12px}
.sv-donelist{list-style:none;margin:0;padding:0;font-size:13px}
.sv-donelist li{padding:5px 0;border-bottom:1px solid var(--border)}
.sv-donelist li:last-child{border-bottom:0}

@media(max-width:640px){
  .sv-row{flex-direction:column;align-items:stretch;gap:10px}
  .sv-row label,.sv-row input,.sv-row select{width:100%;min-width:0}
  .sv-pbrow{flex-direction:row;flex-wrap:wrap}
  .sv-pblbl{min-width:100%}
  .sv-actions .btn{padding:12px 10px;font-size:14px}
  .sv-report .btn{width:100%;padding:13px}
  .sv-photos a,.sv-photos img{width:calc(50% - 5px)}
  .sv-photos img{height:120px}
}
.sv-cardblock{margin:0 0 14px;width:100%}
.sv-cardblock .flag-venues li{display:flex;gap:7px;align-items:center;flex-wrap:wrap}

.wc-ev{cursor:pointer}
.wc-sel .wc-num{background:var(--bg-accent);color:var(--text-accent);font-weight:600}
.task-sched{border:1px solid var(--border);background:var(--surface-0,#fff);color:var(--text-secondary);font-size:11px;padding:1px 7px;border-radius:6px;cursor:pointer}
.task-sched:hover{border-color:var(--border-accent);color:var(--text-accent)}
.tm-overlay{position:fixed;inset:0;background:rgba(20,28,40,.45);display:flex;align-items:center;justify-content:center;z-index:200;padding:16px}
.tm-card{background:var(--surface-0,#fff);border-radius:14px;max-width:460px;width:100%;max-height:88vh;overflow-y:auto;padding:18px 20px;position:relative;box-shadow:0 24px 60px rgba(0,0,0,.25)}
.tm-close{position:absolute;top:10px;right:12px;border:0;background:transparent;font-size:18px;color:var(--text-muted);cursor:pointer}
.tm-title{font-size:16px;font-weight:600;color:var(--text-primary);margin:0 24px 6px 0}
.tm-label{font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);margin:12px 0 4px}
.tm-cal{border:1px solid var(--border);border-radius:10px;padding:8px 10px}
.tm-cal .wc-title{font-size:15px}
.tm-cal .wc-day{min-height:34px}
.tm-cal .wc-num{width:28px;height:28px;font-size:13px}
.tm-status{font-size:13px;color:var(--text-secondary);margin-top:10px}
.tm-comments{display:flex;flex-direction:column;gap:6px}
.tm-c{background:var(--surface-1);border-radius:8px;padding:6px 8px}
.tm-ca{font-weight:600;font-size:12px;color:var(--text-primary)}
.tm-ct{font-size:11px;color:var(--text-muted);margin-left:6px}
.tm-cb{font-size:13px;color:var(--text-secondary);margin-top:2px;white-space:pre-wrap}
.tm-add{display:flex;gap:6px;margin-top:8px}
.tm-add .tm-author{width:90px}
.tm-add .tm-cbody{flex:1}
.tm-add input{border:1px solid var(--border);border-radius:6px;padding:5px 8px;font-size:13px}
.tm-overlay[hidden]{display:none}
.taskfold-sum .card-city{margin-left:8px;font-size:12px;padding:2px 6px;border:1px solid var(--border);border-radius:6px;background:var(--surface-0,#fff);color:var(--text-secondary);max-width:150px;cursor:pointer}
.taskfold-sum .card-city:hover{border-color:var(--border-accent)}
.wc-hide-city{display:none !important}
/* Compact calendar: inactive week rows shorter, active week full height. */
.weekcal .wc-day.wc-muted{min-height:30px;padding:2px}
.weekcal .wc-day.wc-muted .wc-num{width:26px;height:26px;font-size:12.5px}

/* Long task chips must not stretch their grid column (columns stay equal). */
.wc-day{min-width:0}
.weekcal .wc-evs{min-width:0}

.weekcal.cal-hidden{display:none}
.cal-toggle.on{border-color:var(--border-accent);color:var(--text-accent)}
.oc-actions{margin:6px 0 10px}

.selectors .oc-xls{align-self:center}

.stations-table tr.drop-hot{background:rgba(192,57,43,.06)}

main.wide{max-width:1500px}
.stations-table td:first-child{white-space:normal;min-width:220px}

.station-search{margin:2px 0 10px}
.station-q{width:440px;max-width:100%;padding:8px 14px;border:1px solid var(--border);border-radius:10px;font-size:14px;background:var(--surface-0,#fff);color:var(--text-primary)}
.stations-table tbody tr.q-hide{display:none !important}
.nav-nb{white-space:nowrap}

.filters .station-q{width:240px;font-size:13px;padding:7px 10px;border-radius:var(--radius-sm)}

.ttag-other{background:#eef1f4;color:#5a6675}

/* Neutral "Other" badge holding the card's misc action items (📞 calls +
   🔧 service visits). Grey fill (surface-1, like the Other task tag), kept in BOTH
   closed and open states so it never flashes white. Lives in the .att-flags row
   next to the problem-venue flags (e.g. "never started"). */
.flag-other,.flag-other[open]{background:var(--surface-1);border-color:var(--border)}
.flag-other .flag-count{color:var(--text-primary)}
.flag-other .flag-label{color:var(--text-secondary)}
.flag-other .fv-task{display:inline-flex;margin-left:6px}
/* 🔧 Service visits kept as its own subsection inside the Other badge — same look
   as the standalone block before, just nested and inset. */
.other-body .sv-cardblock{width:auto;margin:0 11px 10px}
.other-body>.flag-venues:first-child{padding-top:8px}

/* ── Field service · city picker, board search, photo drop ─────────────────── */
.citypick{display:inline-block;position:relative}
.citypick>summary{list-style:none;cursor:pointer;font-size:12px;padding:6px 11px;
  border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface-2);
  color:var(--text-secondary);white-space:nowrap}
.citypick>summary::-webkit-details-marker{display:none}
.citypick[open]>summary{background:var(--bg-accent);color:var(--text-accent)}
.city-lbl{font-weight:600;color:var(--text-primary)}
.citybox{position:absolute;z-index:12;top:calc(100% + 4px);left:0;width:260px;max-height:300px;
  overflow:auto;background:var(--surface-2);border:1px solid var(--border-strong);
  border-radius:var(--radius-sm);box-shadow:var(--shadow);padding:8px}
.city-filter,.city-extra{width:100%;font-size:12px;padding:6px 8px;margin-bottom:6px;
  border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface-2)}
.city-extra{margin:8px 0 0;border-top:1px solid var(--border)}
.city-grp{font-size:10px;text-transform:uppercase;letter-spacing:.04em;font-weight:700;
  color:var(--text-muted);margin:8px 0 3px}
.city-opt{display:flex;align-items:center;gap:7px;font-size:12.5px;padding:3px 2px;cursor:pointer}
.city-opt:hover{background:var(--surface-1)}

.sv-searchrow{display:flex;align-items:center;gap:8px;margin-bottom:12px}
.sv-search{flex:1;max-width:420px;font-size:13.5px;padding:9px 14px;border-radius:999px;
  border:1px solid var(--border-strong);background:var(--surface-2);color:var(--text-primary)}
.sv-search::placeholder{color:var(--text-muted)}
.sv-searchclear{color:var(--text-muted);font-size:14px;text-decoration:none}

.sv-shoot{display:flex;flex-direction:column;gap:6px;margin-bottom:14px}
.sv-shoot input[type=file]{position:absolute;width:1px;height:1px;opacity:0;overflow:hidden}
.sv-shootbtn{display:block;text-align:center;padding:16px;border:2px dashed var(--border-strong);
  border-radius:var(--radius);background:var(--surface-1);font-size:15px;font-weight:600;
  color:var(--text-accent);cursor:pointer}
.sv-shoot input[type=file]:focus + .sv-shootbtn{outline:2px solid var(--bg-accent)}
.sv-pickhead{font-size:11px;text-transform:uppercase;letter-spacing:.03em;font-weight:700;
  color:var(--text-muted);margin-bottom:6px}
.sv-stoppick{display:flex;flex-direction:column;gap:6px;margin-bottom:14px}
.sv-pickitem{display:flex;align-items:center;gap:10px;padding:11px 12px;cursor:pointer;
  border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface-2)}
.sv-pickitem:has(input:checked){background:var(--bg-accent);border-color:var(--accent)}
.sv-pickitem input{width:20px;height:20px;flex:none}
.sv-pickbody{display:flex;flex-direction:column;gap:2px;font-size:14px}
.sv-uplbtn{width:100%;padding:13px}

/* Service · History and Hardware screens. */
.subtabs a.subtab{text-decoration:none}
.sv-inline{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--text-secondary)}
.sv-inline input{font-size:13px;padding:6px 9px;border:1px solid var(--border);
  border-radius:var(--radius-sm);background:var(--surface-2)}
.sv-tiles{margin:4px 0 16px}
/* Three cards per row left the two wide ones (By task type, By responsible — six and
   seven columns) about 340 px each, so both scrolled sideways inside their card while
   By outcome, three narrow columns, sat next to them wasting the space. Two per row:
   the wide pair takes the first line whole, outcome and city share the second. */
/* min(470px,100%) and not a bare 470px: on a 375 px phone a bare minimum makes the
   grid track wider than the screen and drags the whole page sideways. */
.sv-breakdowns{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(470px,100%),1fr));gap:14px}
.sv-breakdowns .card{margin-bottom:0}
/* Eight columns in "By responsible" need every pixel of the 519 px card; the default
   compact padding put it 72 px over and back into a sideways scroll. */
.sv-breakdowns table.grid.compact th,
.sv-breakdowns table.grid.compact td{padding:8px 6px}
.sv-histtable .sv-desc{max-width:280px;overflow:hidden;display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical}
tr.sv-failed td{background:var(--red-bg)}
tr.sv-cancelled td{opacity:.6}

/* Fleet table. */
.sv-hwtable tr.hw-red.hw-act td{background:var(--red-bg)}
.sv-hwtable tr.hw-amber.hw-act td{background:var(--amber-bg)}
.sv-hwtable tr:not(.hw-act) td{opacity:.75}
.sv-hwtable .badge{margin-bottom:2px}
.sv-hwwrap{position:relative}
/* table.grid clips its rounded corners with overflow:hidden, and ANY ancestor whose
   overflow is not visible cancels position:sticky — that is why the header used to
   scroll away. The card around it keeps the rounding, so nothing looks different. */
table.grid.sv-hwtable{overflow:visible}
.sv-hwtable thead th{position:sticky;top:var(--topbar-h,50px);z-index:3;
  background:var(--surface-1);box-shadow:inset 0 -1px 0 var(--border)}
.filters select[disabled]{opacity:.5;cursor:not-allowed}

/* SLA marks. The date itself stays neutral; only a missed one shouts. */
.sla{font-variant-numeric:tabular-nums}
.sla-overdue{color:var(--red-fg);font-weight:700}
.sla-due_today{color:var(--amber-fg);font-weight:600}
.sla-late{color:var(--red-fg)}
.sla-on_time{color:var(--text-secondary)}
.sv-stop.overdue{border-left:3px solid var(--red-fg)}

/* "Ask service" button on the Week flags — same size as its neighbours, but the
   wrench should read as a different kind of action than a manager task. */
.fv-add.fv-svc { border-color: #7c3aed55; color: #6d28d9; }
.fv-add.fv-svc:hover { background: #7c3aed14; border-color: #7c3aed; }
@media (prefers-color-scheme: dark) {
  .fv-add.fv-svc { color: #c4b5fd; border-color: #7c3aed66; }
}

/* ── the courier's route ─────────────────────────────────────────────────── */
.sv-daysum { display:flex; flex-wrap:wrap; gap:10px; align-items:center; margin:10px 0 14px; }
.sv-route { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:12px; }
.sv-stop { background:var(--card,#fff); border:1px solid var(--line,#e5e7eb); border-radius:12px;
           padding:12px 14px; }
.sv-stop.dragging { opacity:.5; }
.sv-stop.st-done { border-color:#16a34a55; }
.sv-stop.st-skipped { border-color:#f59e0b66; background:#f59e0b0a; }
.sv-stop.st-arrived { border-color:#2563eb66; }
.sv-stophead { display:flex; align-items:flex-start; gap:10px; }
.sv-stopname { flex:1; display:flex; flex-wrap:wrap; align-items:center; gap:6px; }
.sv-seq { display:inline-flex; align-items:center; justify-content:center; min-width:26px;
          height:26px; border-radius:50%; background:var(--chip,#f3f4f6); font-weight:700;
          font-size:13px; cursor:grab; }
.sv-move { display:flex; gap:4px; }
.btn.tiny { padding:2px 7px; font-size:12px; line-height:1.5; }
.sv-vst { text-transform:none; }
.sv-vst-planned { background:#e5e7eb; color:#374151; }
.sv-vst-arrived { background:#dbeafe; color:#1d4ed8; }
.sv-vst-done { background:#dcfce7; color:#15803d; }
.sv-vst-skipped { background:#fef3c7; color:#b45309; }
.sv-job { border-top:1px solid var(--line,#e5e7eb); margin-top:10px; padding-top:10px; }
.sv-job.closed { opacity:.6; }
.sv-jobhead { display:flex; flex-wrap:wrap; align-items:center; gap:6px; }
.sv-jobid { margin-left:auto; font-size:12px; }
.sv-stopfoot { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-top:12px; }
.sv-skip[open] { display:block; width:100%; }
.sv-skip form { margin-top:8px; }

/* ── the dispatcher's day ────────────────────────────────────────────────── */
.sv-lanes { display:flex; flex-direction:column; gap:14px; }
.sv-lanelist { list-style:none; margin:8px 0 0; padding:0; }
.sv-lanelist li { display:flex; flex-wrap:wrap; align-items:center; gap:8px;
                  padding:6px 0; border-top:1px solid var(--line,#f0f1f3); }
.sv-lanelist li.st-done .sv-lanename { text-decoration:line-through; opacity:.7; }
.sv-lanename { font-weight:600; }
.sv-lanejobs { display:flex; flex-wrap:wrap; gap:4px; }
@media (prefers-color-scheme: dark) {
  .sv-vst-planned { background:#37415155; color:#d1d5db; }
  .sv-vst-arrived { background:#1e3a8a66; color:#bfdbfe; }
  .sv-vst-done { background:#14532d66; color:#bbf7d0; }
  .sv-vst-skipped { background:#78350f66; color:#fde68a; }
}

.sv-handover { display:flex; gap:4px; align-items:center; margin-left:auto; }
.sv-handover select, .sv-handover input[type=date] { font-size:12px; padding:2px 4px; }

.sv-tg { display:flex; align-items:center; gap:16px; flex-wrap:wrap; }

.sv-hand-card { display:flex; align-items:center; gap:16px; flex-wrap:wrap; }
.sv-hand { font-size:16px; }
.sv-hand.bad { color:#b91c1c; }
.sv-hand.warn { color:#b45309; }
.sv-plus { color:#15803d; }
.sv-minus { color:#b91c1c; }

/* ── phone (the courier's real screen) ───────────────────────────────────────
   Checked at 375 px on the actual pages, not in theory: the sub-tab row and every
   wide table pushed the whole page sideways, and the buttons a courier taps while
   standing at a station were 24 px tall. */
@media (max-width: 640px) {
  /* Five sub-tabs no longer fit in one line — wrap them instead of dragging the
     page 30 px to the right. */
  .subtabs { flex-wrap: wrap; row-gap: 6px; }

  /* Any wide table scrolls inside its own card. Without this the page itself
     scrolls sideways and the header row drifts away from the data. */
  .card table.grid { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  table.grid.sv-hwtable { display: block; overflow-x: auto; }

  /* Thumb-sized controls. 44 px is the size a finger actually hits; the reorder
     arrows were 22×24 and effectively undraggable in a car. */
  .sv-stop .btn, .sv-stopfoot .btn, .sv-hand-card .btn, .sv-actions .btn,
  .sv-reportfold > summary, .sv-skip > summary {
    min-height: 44px; display: inline-flex; align-items: center; justify-content: center;
  }
  .sv-move .btn.tiny { min-width: 44px; min-height: 44px; font-size: 16px; }
  .sv-stopfoot { gap: 10px; }
  .sv-route .sv-job select, .sv-route .sv-job input, .sv-route .sv-job textarea,
  .sv-hand-card select, .sv-hand-card input { min-height: 40px; font-size: 16px; }
  /* 16 px is not a taste call: below it iOS zooms the page on focus and the
     courier has to pinch back out after every field. */
}

/* ── narrow windows and browser zoom ─────────────────────────────────────────
   `table.grid` in the shared stylesheet is `overflow:hidden`, so a table wider than
   its card is CUT, not scrolled — the columns simply end mid-word. That is invisible
   on a 1440 px monitor and obvious at 150% zoom or in a half-screen window, which is
   how people actually read these pages. Every service table gets its own horizontal
   scroll instead of losing its right-hand columns. */
/* Making the table itself `display:block` is what used to let it scroll instead of
   being clipped by `table.grid{overflow:hidden}` — but a block-level table shrinks to
   its content, so a three-column card sat in the left third of a 519 px card with the
   rest blank, and `width:100%` did not help: the block stretched, the table inside it
   did not. The scroller is a wrapper div now, so the table stays a table and spreads
   its columns across the full width. */
.sv-breakdowns .scroll > table.grid,
.card > .scroll > table.grid { width: 100%; }
.sv-visits table.grid,
.card > table.grid { display: block; overflow-x: auto; max-width: 100%; }

/* Cards size to their own content instead of being stretched to the tallest one in
   the row — a five-row table next to a one-row table left the short card mostly empty. */
.sv-breakdowns{align-items:start;margin-bottom:20px}

/* The fleet table keeps its sticky header while it fits; below that, scrolling the
   table beats clipping it. */
@media (max-width: 1100px) {
  table.grid.sv-hwtable { display: block; overflow-x: auto; }
}

/* Same thumb rule for the rest of the service screens — the task page a courier
   opens from the route, the report form inside it, and the dispatcher's lanes,
   which a lead reads standing in a warehouse, not sitting at a desk.
   16 px on every field is the iOS anti-zoom threshold, not a taste call. */
@media (max-width: 640px) {
  .sv-route li.sv-stop input, .sv-route li.sv-stop select, .sv-route li.sv-stop textarea,
  .sv-reportfold input, .sv-reportfold select, .sv-reportfold textarea,
  .sv-hand-card input, .sv-hand-card select,
  .sv-row input, .sv-row select, .sv-row textarea,
  .sv-handover select, .sv-handover input {
    font-size: 16px; min-height: 44px;
  }
  .sv-reportfold .btn, .sv-reportfold button, .sv-actions .btn, .sv-meta + * .btn,
  .sv-lanelist .btn, .sv-handover .btn, .sv-timeline + form .btn,
  .sv-row .btn, .sv-row button, .sv-form .btn {
    min-height: 44px; display: inline-flex; align-items: center; justify-content: center;
  }
}

/* ── the gap nobody covered: 641–1100 px ─────────────────────────────────────
   The shared top bar wraps only below 640 px and fits only above ~1100 px. In
   between — a half-screen window, an iPad, or a laptop at 125–150% zoom — the nav
   is 1091 px wide and drags the whole page sideways, which is what makes the tables
   look like they are running off the screen. Same wrapping the phone already has,
   applied to that middle band. Lives here, not in style.css, so a deploy of theirs
   cannot quietly drop it. */
/* Band widened to 1340 px on 2026-08-23: an admin with a long name and the Free&Subs
   counter still pushed the bar 58 px past a 1280 px window, and that is the page-level
   sideways scroll people read as "the table runs off the screen" even when the table
   itself fits. */
@media (min-width: 641px) and (max-width: 1340px) {
  .topbar-inner { flex-wrap: wrap; gap: 8px 14px; }
  .topbar nav { width: 100%; flex-wrap: wrap; gap: 5px 8px; }
  .nav-user { margin-left: auto; padding-left: 0; }
}

/* ══ The courier's day — phone first ═══════════════════════════════════════════
   This screen is used standing next to a station, one-handed, in sunlight. So: one
   stop open at a time, full-bleed cards, 48 px controls, and no decoration that does
   not answer "where am I going and what do I do there". */
.cd-head { position: sticky; top: var(--topbar-h, 50px); z-index: 30;
           background: var(--bg, #f5f6f8); padding: 10px 0 8px; margin: -8px 0 12px; }
.cd-titlerow { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.cd-titlerow h1 { margin: 0; font-size: 22px; }
.cd-date input { border: 1px solid var(--border, #e5e7eb); border-radius: 10px;
                 padding: 6px 10px; font-size: 14px; background: var(--surface-0, #fff); }
.cd-bar { height: 6px; border-radius: 999px; background: var(--surface-1, #eceef1);
          margin: 10px 0 8px; overflow: hidden; }
.cd-bar i { display: block; height: 100%; background: #16a34a; transition: width .3s; }
.cd-sub { font-size: 13px; color: var(--text-secondary, #6b7280); display: flex;
          flex-wrap: wrap; gap: 6px; align-items: baseline; }
.cd-sub b { color: var(--text-primary, #111827); }
.cd-warn { color: #b45309; }
.cd-who { margin-left: auto; opacity: .75; }

.cd-list { list-style: none; margin: 0 0 90px; padding: 0; display: flex;
           flex-direction: column; gap: 8px; }
.cd-stop { background: var(--surface-0, #fff); border: 1px solid var(--border, #e5e7eb);
           border-radius: 14px; overflow: hidden; }
.cd-stop.dragging { opacity: .5; }
/* A stop carried by a finger. touch-action/user-select are what stop the page from
   scrolling and the phone from offering "copy" under a long press; the shadow is the
   only way the courier can tell the card is in hand and not just tapped. */
.cd-list.cd-lifting { touch-action: none; -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none; }
.cd-list.cd-lifting .cd-stop.dragging { opacity: 1; position: relative; z-index: 2;
  box-shadow: 0 8px 22px rgba(15,23,42,.22); transform: scale(1.015); }
.cd-stop.st-done { opacity: .72; }
.cd-stop.st-skipped { background: #fffbeb; }
.cd-stop.open { border-color: #1f5fa0; box-shadow: 0 2px 14px rgba(31,95,160,.10); }

/* Collapsed row — the whole thing is the tap target. */
.cd-row { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 60px;
          padding: 10px 12px; background: none; border: 0; text-align: left;
          font: inherit; color: inherit; cursor: pointer; }
.cd-seq { flex: none; width: 30px; height: 30px; border-radius: 50%; font-size: 13px;
          font-weight: 700; display: inline-flex; align-items: center;
          justify-content: center; background: var(--surface-1, #eef0f3); }
.cd-stop.st-done .cd-seq { background: #dcfce7; color: #15803d; }
.cd-stop.st-skipped .cd-seq { background: #fef3c7; color: #b45309; }
.cd-stop.open .cd-seq { background: #1f5fa0; color: #fff; }
.cd-main { flex: 1; min-width: 0; }
.cd-name { display: block; font-weight: 600; font-size: 15px; line-height: 1.25; }
.cd-main .cd-meta { display: block; font-size: 12.5px; color: var(--text-secondary, #6b7280); }
.cd-state { flex: none; font-size: 15px; width: 18px; text-align: center; }
.cd-state.cd-done { color: #16a34a; }
.cd-state.cd-arrived { color: #1f5fa0; }
.cd-state.cd-planned { color: #b91c1c; font-weight: 700; }
.cd-caret { flex: none; color: var(--text-muted, #9ca3af); transition: transform .2s; }
.cd-stop.open .cd-caret { transform: rotate(180deg); }

.cd-body { display: none; padding: 0 12px 12px; }
.cd-stop.open .cd-body { display: block; }

.cd-nav { display: flex; gap: 8px; align-items: center; min-height: 48px; padding: 10px 12px;
          border-radius: 12px; background: var(--bg-accent, #eaf2fb); color: var(--text-accent, #1f5fa0);
          font-weight: 600; font-size: 14px; text-decoration: none; margin-bottom: 10px; }
.cd-nav span { font-weight: 500; }

.cd-job { border-top: 1px solid var(--border, #eceef1); padding-top: 10px; margin-top: 10px; }
.cd-job:first-of-type { border-top: 0; margin-top: 0; }
.cd-job.closed { opacity: .6; }
.cd-jobhead { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 14px; }
.cd-jobid { margin-left: auto; font-size: 12px; color: var(--text-muted, #9ca3af); }
.cd-what { margin: 6px 0; font-size: 14px; line-height: 1.45; }
.cd-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 8px; }
.cd-jobactions { display: flex; gap: 8px; flex-wrap: wrap; }
.cd-report { flex: 1; min-width: 160px; }
.cd-report[open] { width: 100%; }
.cd-report > summary { list-style: none; }
.cd-report > summary::-webkit-details-marker { display: none; }

.cd-actions { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
.cd-more > summary { list-style: none; }
.cd-more > summary::-webkit-details-marker { display: none; }
.cd-form { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.cd-form select, .cd-form input { min-height: 48px; font-size: 16px; padding: 0 12px;
  border: 1px solid var(--border, #e5e7eb); border-radius: 12px; background: var(--surface-0, #fff); }
.cd-move { display: flex; gap: 8px; margin-top: 8px; }
.cd-move form { flex: 1; }
.cd-move .cd-btn { width: 100%; }

/* One button style for the whole screen, thumb-sized by default. */
.cd-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px;
          min-height: 48px; padding: 0 16px; border-radius: 12px; font-size: 15px;
          font-weight: 600; border: 1px solid var(--border, #e5e7eb); cursor: pointer;
          background: var(--surface-0, #fff); color: var(--text-primary, #111827);
          text-decoration: none; }
.cd-btn.primary { background: #1f5fa0; border-color: #1f5fa0; color: #fff; }
.cd-btn.ghost { background: var(--surface-0, #fff); }
.cd-btn.wide { width: 100%; }
.cd-btn[disabled] { opacity: .4; }

.cd-card { background: var(--surface-0, #fff); border: 1px solid var(--border, #e5e7eb);
           border-radius: 14px; padding: 12px; margin-bottom: 10px; }
.cd-cardhead { font-weight: 600; margin-bottom: 6px; }
.cd-office > summary { list-style: none; }
.cd-office > summary::-webkit-details-marker { display: none; }
.cd-later { list-style: none; margin: 0; padding: 0; font-size: 13px; }
.cd-later li { padding: 5px 0; display: flex; gap: 6px; align-items: center; }

/* Always-there dock: where I am going next, and the whole route in one tap. */
.cd-dock { position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
           display: flex; align-items: center; gap: 10px;
           padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
           background: var(--surface-0, #fff); border-top: 1px solid var(--border, #e5e7eb); }
.cd-dockinfo { font-size: 13px; color: var(--text-secondary, #6b7280); min-width: 0;
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cd-dockinfo b { color: var(--text-primary, #111827); }

@media (max-width: 640px) {
  /* Full-bleed: on a 375 px screen the page gutters cost a fifth of the width. */
  .cd-list, .cd-card, .cd-head { margin-left: -14px; margin-right: -14px; }
  .cd-head { padding-left: 14px; padding-right: 14px; }
  .cd-stop, .cd-card { border-radius: 0; border-left: 0; border-right: 0; }
  .cd-titlerow h1 { font-size: 20px; }
}
@media (prefers-color-scheme: dark) {
  .cd-stop.st-skipped { background: #78350f22; }
}

/* The report form, opened inside a stop. It is a flex sibling of the Photo button,
   so without this it renders as a narrow column with the serial fields cut in half —
   which is exactly what a courier meets at the moment they need to type. */
.cd-jobactions { align-items: flex-start; }
.cd-report[open] { flex: 1 0 100%; order: 3; margin-top: 4px; }
.cd-report[open] > summary { width: 100%; margin-bottom: 10px; }
.cd-report .sv-report { display: flex; flex-direction: column; gap: 10px; }
.cd-report .sv-row { display: flex; flex-direction: column; gap: 10px; }
.cd-report label { display: flex; flex-direction: column; gap: 4px; font-size: 13px;
                   color: var(--text-secondary, #6b7280); }
.cd-report select, .cd-report input, .cd-report textarea {
  width: 100%; min-height: 48px; font-size: 16px; padding: 8px 12px;
  border: 1px solid var(--border, #e5e7eb); border-radius: 12px;
  background: var(--surface-0, #fff); color: inherit; }
.cd-report textarea { min-height: 76px; }
.cd-report .sv-pb > summary { min-height: 44px; display: flex; align-items: center;
                              font-weight: 600; color: var(--text-primary, #111827); }
/* Bank rows: label on its own line, then qty and serials side by side — the count is
   short and the serial is long, giving them equal width wastes the screen. */
.cd-report .sv-pbrow { display: grid; grid-template-columns: 90px 1fr; gap: 8px;
                       align-items: center; }
.cd-report .sv-pblbl { grid-column: 1 / -1; font-size: 13px;
                       color: var(--text-secondary, #6b7280); }
.cd-report .sv-report > button, .cd-report .btn {
  min-height: 50px; width: 100%; border-radius: 12px; font-size: 15px; font-weight: 600;
  background: #1f5fa0; border: 1px solid #1f5fa0; color: #fff; }
.cd-report input[type=file] { padding: 12px; min-height: 56px; }

/* On a desktop the same screen is read by a dispatcher looking over a courier's day;
   full-width action buttons across 1200 px look like a mistake. */
@media (min-width: 641px) {
  .cd-btn.wide { max-width: 380px; }
  .cd-actions { align-items: flex-start; }
  .cd-report[open] { max-width: 640px; }
}

/* "Before you go": the numbers a courier needs while still standing at the office —
   how many banks to load, and what the day is made of. */
.cd-plan { background: var(--surface-0, #fff); border: 1px solid var(--border, #e5e7eb);
           border-radius: 14px; padding: 12px; margin-bottom: 10px; }
.cd-plantake { display: flex; align-items: center; gap: 12px; font-size: 14px;
               color: var(--text-secondary, #6b7280); }
/* The number and its icon must not wrap apart — "🔋" on one line and "32" on the
   next reads as two different facts. */
.cd-planbig { font-size: 26px; font-weight: 700; white-space: nowrap; flex: none;
              color: var(--text-primary, #111827); }
.cd-planbits { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.cd-planurgent { background: #fee2e2; color: #b91c1c; border-color: #fecaca; }
.cd-dockhint { font-size: 11.5px; color: var(--text-muted, #9ca3af); }
@media (max-width: 640px) { .cd-plan { margin-left: -14px; margin-right: -14px;
  border-radius: 0; border-left: 0; border-right: 0; } }

/* Serial picker inside the report form. */
.sv-snbtn { grid-column: 1 / -1; min-height: 44px; border-radius: 12px; font-size: 14px;
            font-weight: 600; border: 1px dashed var(--border, #cbd5e1);
            background: var(--surface-1, #f7f8fa); color: var(--text-accent, #1f5fa0);
            cursor: pointer; }
.sv-snlist { grid-column: 1 / -1; display: flex; flex-direction: column; gap: 6px;
             margin-top: 6px; }
.sv-snitem { display: flex; align-items: center; justify-content: space-between; gap: 10px;
             min-height: 48px; padding: 8px 12px; border-radius: 12px; text-align: left;
             border: 1px solid var(--border, #e5e7eb); background: var(--surface-0, #fff);
             font-size: 15px; cursor: pointer; }
.sv-snitem b { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 15px; }
.sv-snitem span { font-size: 12.5px; color: var(--text-secondary, #6b7280); }
.sv-snitem.taken { border-color: #16a34a; background: #f0fdf4; }
.sv-snhint { grid-column: 1 / -1; font-size: 12.5px; color: var(--text-secondary, #6b7280);
             min-height: 0; }
.sv-snhint.ok { color: #15803d; }
.sv-snhint.bad { color: #b91c1c; }

/* Opening hours. Never a blocker — a courier may well have a key or a back door —
   but knowing a venue opens at 17:00 before driving there saves the trip. */
.cd-hours { font-size: 13px; color: var(--text-secondary, #6b7280); margin-bottom: 8px; }
.cd-hours.shut { color: #b45309; font-weight: 600; }
.cd-shut { color: #b45309; }

.cd-offline { position: sticky; top: var(--topbar-h, 50px); z-index: 45;
              background: #fef3c7; color: #92400e; border-bottom: 1px solid #fde68a;
              padding: 10px 14px; font-size: 13px; line-height: 1.4; }
@media (max-width: 640px) { .cd-offline { margin: 0 -14px; } }

/* Task page on a phone: it is opened from the route to check one detail, so the meta
   block becomes a tight label/value grid instead of a two-line entry per field, and
   the on-site buttons get thumb size. */
@media (max-width: 640px) {
  /* Each row is its own two-column grid. `display: contents` looked tidier but every
     stray text node ("· Limassol", "· today") became its own grid cell and jumped into
     the label column. */
  .sv-meta { display: block; }
  .sv-meta > div { display: grid; grid-template-columns: 100px 1fr; gap: 4px 10px;
                   padding: 5px 0; align-items: baseline; }
  .sv-meta .sv-v { min-width: 0; }
  .sv-meta .sv-k { font-size: 12px; text-transform: uppercase; letter-spacing: .02em;
                   color: var(--text-muted, #9ca3af); align-self: baseline; }
  .card-head-right .btn, .card-head-right button { min-height: 44px; }
  .sv-desc-box { margin-top: 10px; }
}

/* ══ Dispatch screens on a phone ══════════════════════════════════════════════
   A lead reads the board standing in a warehouse or sitting in a car, so the table
   turns into cards: same markup, same single source of truth, only the layout flips.
   Column labels come from data-l, so a card never loses which value is which. */
.sv-filterfold > summary { list-style: none; }
.sv-filterfold > summary::-webkit-details-marker { display: none; }
.sv-filterbtn { display: none; }

@media (max-width: 640px) {
  .sv-filterbtn { display: inline-flex; align-items: center; min-height: 44px;
                  padding: 0 16px; margin-bottom: 10px; border-radius: 12px;
                  border: 1px solid var(--border, #e5e7eb); font-weight: 600;
                  background: var(--surface-0, #fff); cursor: pointer; }
  .sv-filterfold .filters { display: grid; grid-template-columns: 1fr; gap: 8px; }
  .sv-filterfold .filters select, .sv-filterfold .filters input:not([type=checkbox]),
  .sv-filterfold .filters .msf, .sv-filterfold .filters .msf-btn,
  .sv-filterfold .filters .btn { min-height: 44px; font-size: 15px; width: 100%; }
  .sv-filterfold .filters .msf-btn { max-width: none; }
  .sv-filterfold .filters .msf-panel { position: static; margin-top: 4px; box-shadow: none;
    left: auto; right: auto; width: auto; min-width: 0; max-width: none; max-height: 50vh; }
  .sv-filterfold .filters .btn { grid-column: 1 / -1; justify-content: center; }

  /* table → cards */
  .scroll { overflow: visible; }
  table.grid.sv-board, .sv-board tbody, .sv-board tr, .sv-board td { display: block; width: auto; }
  .sv-board thead { display: none; }
  .sv-board tr { background: var(--surface-0, #fff); border: 1px solid var(--border, #e5e7eb);
                 border-radius: 14px; padding: 10px 12px; margin: 0 -14px 10px;
                 border-left: 0; border-right: 0; border-radius: 0; }
  .sv-board td { border: 0 !important; padding: 3px 0; white-space: normal; }
  /* Label beside the value, not above it. A stacked label doubles the height of every
     field, and a card of eight fields becomes a screen and a half of scrolling for one
     task. The label column is fixed so the values line up down the card and the eye has
     a single edge to run along. */
  .sv-board td[data-l] { padding: 4px 0; }
  .sv-board td[data-l]::before { content: attr(data-l); display: inline-block;
                                 width: 84px; font-size: 11px; text-transform: uppercase;
                                 letter-spacing: .02em; color: var(--text-muted, #9ca3af);
                                 margin: 0; }
  /* The second line inside a cell — €354 under the tier, "overdue" under the date —
     belongs on the same line as the value it qualifies. */
  .sv-board td[data-l="Value"] > div,
  .sv-board td[data-l="Due"] > div,
  .sv-board td[data-l="Status"] > div { display: inline; margin-left: 6px; }
  .sv-board td[data-l="Value"] .badge { margin-right: 2px; }
  /* the id and the Open button ride along the venue line instead of taking rows */
  .sv-board .sv-c-id { position: absolute; right: 14px; font-size: 12px; }
  .sv-board .sv-c-venue { padding-right: 46px; font-size: 15px; }
  /* Venue and Task carry no label (see below), so they span the whole card width
     instead of starting after an empty label column. */
  .sv-board td.sv-c-venue, .sv-board td[data-l="Task"] { display: block; }
  /* The two fields whose value is a control, not a word: the label sits on its own
     line and the control gets the full width underneath. */
  .sv-board td[data-l="Responsible"]::before { display: block; width: auto;
                                              margin-bottom: 4px; }
  .sv-board .sv-c-mgr { display: none; }            /* the lead knows their managers */
  .sv-board tr { position: relative; }
  .sv-board .sv-c-open .btn { width: 100%; min-height: 44px; justify-content: center;
                              margin-top: 6px; }
  /* Courier and day side by side: stacked they were 134 px of a 484 px card for two
     fields that are read as one answer ("Maaz, Tuesday"). */
  /* padding-right is the point, not decoration: the date column is a fixed width, so
     the gutter comes out of the courier picker beside it and the date stops short of the
     card edge instead of running into it. */
  .sv-board .sv-assign { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 124px);
                         gap: 6px; justify-items: stretch; width: 100%;
                         padding-right: 12px; box-sizing: border-box; }
  .sv-board .sv-assign select, .sv-board .sv-assign input { min-height: 44px;
                                                            font-size: 14px; min-width: 0; }
  /* Both controls fill their track, so the date ends exactly where the card's padding
     ends — the same 12 px the picker starts from on the left. Safari gives a date input
     an intrinsic width of its own and will otherwise draw it short of the edge. */
  .sv-board .sv-assign > * { width: 100%; box-sizing: border-box; justify-self: stretch; }
  .sv-board .sv-c-open .btn { margin-top: 2px; }
  .sv-board .sv-desc { -webkit-line-clamp: 3; }

  /* dispatcher day: one lane per card, stops stacked */
  .sv-lane .card-head { flex-direction: column; align-items: flex-start; gap: 6px; }
  .sv-lane .card-head-right { display: flex; flex-wrap: wrap; gap: 8px; width: 100%; }
  .sv-lanelist li { display: grid; grid-template-columns: 28px 1fr; gap: 4px 8px;
                    padding: 10px 0; }
  .sv-lanelist li > .sv-seq { grid-row: span 2; }
  .sv-lanelist .sv-lanename { font-size: 15px; }
  .sv-lanelist .fv-city, .sv-lanelist .badge, .sv-lanejobs { grid-column: 2; }
  /* One line per stop, not three: courier, day, move. Twenty stops with a stacked
     form underneath each is a screen nobody scrolls to the end of. */
  .sv-handover { grid-column: 2; display: grid; grid-template-columns: 1fr 104px auto;
                 gap: 6px; margin: 6px 0 0; width: 100%; }
  .sv-handover select, .sv-handover input[type=date] { min-height: 40px; font-size: 14px;
                                                       padding: 0 6px; min-width: 0; }
  .sv-handover .btn { min-height: 40px; padding: 0 10px; }
  /* Badges and chips size to their text; stretched to full width they read as bars. */
  .sv-lanelist .badge, .sv-lanelist .fv-city { justify-self: start; }
  .sv-lanelist .sv-lanejobs { flex-wrap: wrap; }
}

/* Подписи «Venue» и «Task» на карточке лишние: название заведения и так первое, а тип
   работы виден по бейджу. Правило идёт последним — при равной специфичности выигрывает
   тот, кто ниже. */
@media (max-width: 640px) {
  .sv-board td.sv-c-venue::before,
  .sv-board td[data-l="Task"]::before { content: none; }
}

/* Camera frame for scanning a bank's barcode. */
.sv-scanbox { grid-column: 1 / -1; margin-top: 8px; display: flex; flex-direction: column;
              gap: 8px; }
.sv-scanbox video { width: 100%; max-height: 260px; object-fit: cover; border-radius: 12px;
                    background: #111827; }
.sv-scanhint { font-size: 12.5px; color: var(--text-secondary, #6b7280); }
.sv-scanbtn { border-style: solid; }

/* Header of the bank picker: when the list was read, and a way to read it again. */
.sv-snhead { display: flex; align-items: center; justify-content: space-between; gap: 8px;
             font-size: 12px; color: var(--text-secondary, #6b7280); padding: 2px 2px 4px; }
.sv-snrefresh { min-height: 36px; padding: 0 10px; border-radius: 10px; font-size: 13px;
                border: 1px solid var(--border, #e5e7eb); background: var(--surface-0, #fff);
                color: var(--text-accent, #1f5fa0); cursor: pointer; }

/* ══ Ближе к менеджерскому порталу ════════════════════════════════════════════
   Оттуда взяты три вещи, из которых и складывается его вид: переключатель периода
   «‹ подпись ›», пастельные плитки с цифрами и карточки с полями по краям вместо
   разметки во всю ширину. */

/* Переключатель дня. Системный date-инпут остаётся в разметке (он и отправляет
   форму), но спрятан внутри кнопки — видна только подпись «Sun, 23 Aug · today». */
.daypick { display: flex; align-items: stretch; gap: 8px; margin: 12px 0 10px; }
.dp-nav { flex: none; width: 46px; border: 1px solid var(--border, #e5e7eb); border-radius: 12px;
          background: var(--surface-0, #fff); color: var(--text-secondary, #6b7280);
          font-size: 20px; line-height: 1; cursor: pointer; }
.dp-nav:hover { background: var(--surface-1, #f3f4f6); color: var(--text-primary, #111827); }
.dp-label { position: relative; flex: 1; min-height: 46px; display: inline-flex;
            align-items: center; justify-content: center; gap: 8px; padding: 0 14px;
            border: 1px solid var(--border, #e5e7eb); border-radius: 12px;
            background: var(--surface-0, #fff); color: var(--text-primary, #111827);
            font-size: 15px; font-weight: 600; cursor: pointer; }
.dp-caret { color: var(--text-muted, #9ca3af); font-size: 12px; }
.dp-label input[type=date] { position: absolute; inset: 0; opacity: 0; width: 100%;
                             height: 100%; border: 0; padding: 0; pointer-events: none; }

/* Плитки с цифрами — как KPI-плитки в карточке менеджера. */
.cd-tiles { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 4px; }
.cd-tile { flex: 1 1 96px; display: flex; flex-direction: column; gap: 2px;
           padding: 9px 12px; border-radius: 12px; background: var(--surface-1, #f1f3f6);
           border: 1px solid transparent; }
.cd-tile.warn { background: #fef3c7; }
.cd-tk { font-size: 11.5px; color: var(--text-secondary, #6b7280); font-weight: 500; }
.cd-tv { font-size: 17px; font-weight: 700; color: var(--text-primary, #111827); }
.cd-who { color: var(--text-secondary, #6b7280); font-size: 13.5px; }
.cd-head h1 { margin: 0; }

@media (max-width: 640px) {
  /* Карточки с полями по краям и скруглением — как на «My week», вместо разметки
     от края до края. Полноширинной остаётся только липкая шапка. */
  .cd-list, .cd-card, .cd-plan { margin-left: 0; margin-right: 0; }
  .cd-stop, .cd-card, .cd-plan { border-radius: 14px; border-left: 1px solid var(--border, #e5e7eb);
                                 border-right: 1px solid var(--border, #e5e7eb); }
  .sv-board tr { margin-left: 0; margin-right: 0; border-radius: 14px;
                 border-left: 1px solid var(--border, #e5e7eb);
                 border-right: 1px solid var(--border, #e5e7eb); margin-bottom: 10px; }
  /* Три плитки в ряд на 375 px: «две и одна на всю ширину» читается как ошибка вёрстки. */
  .cd-tile { flex: 1 1 0; min-width: 0; padding: 8px 10px; }
  .cd-tk { font-size: 11px; }
  .cd-tv { font-size: 16px; }
  .dp-label { font-size: 14.5px; }
}

/* Системные поля даты внутри сервисных экранов приводим к одному виду с остальными
   контролами: та же высота, радиус и рамка, что у селектов и кнопок. Сам календарь
   остаётся системным — он привычный и его не надо учить. */
.sv-handover input[type=date], .sv-board input[type=date], .sv-assign input[type=date],
.cd-form input[type=date], .sv-row input[type=date] {
  border: 1px solid var(--border, #e5e7eb); border-radius: 10px;
  background: var(--surface-0, #fff); color: var(--text-primary, #111827);
  padding: 0 8px; font-size: 14px;
}
.sv-board input[type=date], .sv-assign input[type=date] { min-height: 44px; width: 100%; }

/* Сортировка по колонкам: заголовок — ссылка, стрелка показывает, кто держит порядок. */
.sv-sortable a { display: inline-flex; align-items: center; gap: 4px; color: inherit;
                 text-decoration: none; white-space: nowrap; }
.sv-sortable a:hover { color: var(--text-accent, #1f5fa0); }
.sv-arrow { font-size: 10px; color: var(--text-muted, #9ca3af); }
.sv-sortable.on { color: var(--text-accent, #1f5fa0); }
.sv-sortable.on .sv-arrow { color: var(--text-accent, #1f5fa0); }
.sv-queue { font-size: 11px; font-weight: 500; text-transform: none;
            color: var(--text-muted, #9ca3af); }

/* Строка поиска под заголовками таблицы: то же скругление, что у большого поиска,
   чтобы читалось как одно семейство контролов. */
.sv-findrow th { padding: 6px 8px 10px; background: var(--surface-1, #f7f8fa); }
.sv-find { width: 100%; min-width: 0; min-height: 34px; padding: 4px 7px; font-size: 12.5px;
           border: 1px solid var(--border, #e5e7eb); border-radius: 999px;
           background: var(--surface-0, #fff); color: var(--text-primary, #111827); }
.sv-find:focus { outline: none; border-color: var(--border-accent, #1f5fa0); }
/* The task-number box lives in the narrow "#" column; let it stay narrow on desktop
   instead of widening the column, and go full width inside the phone filter panel. */
.sv-findrow .sv-tid { min-width: 62px; }
.filters .sv-tid { width: 100%; }

/* Прятать строку поиска на телефоне надо селектором не слабее, чем `.sv-board tr`,
   который делает строки блоками, — иначе она выигрывает по специфичности и строка
   с выпадашками вылезает карточкой над списком. */
@media (max-width: 640px) { table.grid.sv-board tr.sv-findrow { display: none; } }

.sv-nothing { padding: 26px 14px; text-align: center; color: var(--text-secondary, #6b7280); }

/* Поиск существует в одном экземпляре на каждой раскладке: на широком экране — в шапке
   таблицы, на телефоне — в свёрнутых фильтрах (там шапки нет). */
.sv-mobsearch { display: none; }
@media (max-width: 640px) {
  .sv-mobsearch { display: block; grid-column: 1 / -1; min-height: 44px; font-size: 15px; }
}

/* ── station value (venue_value): the tier badge and the queue screen ───────── */
/* Four steps, not four colours: A and B are the money and read as strong, C is
   ordinary text, D is deliberately faint — a station that earned nothing should not
   pull the eye on a screen whose whole job is to rank by earnings. */
.badge.tier-A{background:var(--red-bg);color:var(--red-fg);font-weight:700}
.badge.tier-B{background:var(--amber-bg);color:var(--amber-fg);font-weight:600}
.badge.tier-C{background:var(--surface-1);color:var(--text-secondary)}
.badge.tier-D{background:transparent;color:var(--text-muted);border:1px solid var(--border)}

/* A tier tile doubles as a filter: clicking it narrows the queue to that tier. */
.sv-tiles a.kpi-pill{text-decoration:none}
.sv-tiles a.kpi-pill:hover{border-color:var(--accent)}
.sv-tiles a.kpi-pill.on{outline:2px solid var(--accent);outline-offset:-2px}

/* A station somebody is already driving to stays in the list — the queue is the whole
   demand — but steps back so the waiting ones are what you read. */
.sv-queue-tbl tr.sv-q-has{opacity:.62}

/* The queue table carries .sv-board as well, so it inherits the whole table-to-cards
   treatment from the block above — one set of rules, one breakpoint, nothing to keep
   in sync. Only what is specific to this screen lives here. */
@media (max-width: 640px){
  /* The rank is the position in a list you are already reading top-down: on a phone
     it costs a whole line to say what the order already says. */
  .sv-queue-tbl .sv-q-pos{display:none}
  .sv-queue-tbl .sv-tiles{gap:6px}
}

/* ── the board fits the page, no sideways scroll ─────────────────────────────
   Adding the Value column pushed the table to 1152px inside a 1052px page, and a
   dispatch screen you have to scroll sideways hides exactly the columns you came for.
   The width was not in the new column (72px) but in "Responsible & day": a courier
   picker and a date input standing side by side took 352px on their own. Stacking them
   — the same way they already stack on a phone — gives back 166px, which is more than
   the overflow, and Venue and Task get the room instead. */
@media (min-width: 641px){
  .sv-board .sv-assign{display:grid;grid-template-columns:1fr;gap:4px;max-width:186px}
  .sv-board .sv-assign select,
  .sv-board .sv-assign input[type=date]{width:100%;min-height:30px}
  .sv-board input[type=date]{min-height:30px}
}
/* A laptop at 900–1050 px has ~180 px less to give than a desktop, so the same table
   needs the padding and the two clamped columns tightened as well. Below 641 px none of
   this matters — the table is already cards. */
@media (min-width: 641px) and (max-width: 1050px){
  .sv-board.compact th, .sv-board.compact td{padding:7px 6px}
  .sv-board .sv-desc{max-width:170px}
  .sv-board .sv-assign{max-width:146px}
  .sv-board .sv-c-mgr{max-width:92px;white-space:normal}
}

/* The legend is a caption, not a paragraph — the badges must not stretch the line. */
.sv-legend{margin-top:-4px}
.sv-legend .badge{margin:0 2px}

/* "+ New task" sits in the board header, not in the filters. On a phone it goes full
   width — it is the only action on the screen a dispatcher starts from scratch. */
.sv-tabsrow{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.sv-tabsrow .subtabs{margin-bottom:0}
.sv-newtask{margin-left:auto;white-space:nowrap}
.sv-newtask-m{display:none}
@media (max-width: 640px){
  /* On a phone the button leaves the header entirely: up there it sat between the tabs
     and the heading and pushed the counters off the screen. The copy further down runs
     full width immediately above the first task, where a dispatcher is already looking. */
  .sv-tabsrow{display:block;position:relative}
  .sv-tabsrow .sv-newtask{display:none}
  /* Мелкая кнопка выгрузки остаётся на строке заголовка, справа: отдельным этажом под
     словом Forms она читалась как действие над списком, а не над экраном (Лина, 10.09).
     Место под неё освобождает САМ заголовок — тот же .sv-tabsrow несёт ряд вкладок на
     всех сервисных экранах, и общий padding-right ломал бы их перенос. */
  .sv-tabsrow .sv-hdrbtn{position:absolute;top:0;right:0;margin:0}
  .sv-tabsrow .sv-hdrtitle{padding-right:104px}
  .sv-newtask-m{display:block;width:100%;box-sizing:border-box;text-align:center;
    min-height:44px;padding:12px 15px;margin:0 0 12px}
}

/* A withdrawn task is not a failure and not a success — it is work that stopped being
   needed. Grey, and never red: nobody did anything wrong. */
.badge.b-cleared{background:var(--surface-1);color:var(--text-secondary)}
.badge.b-robot{background:var(--bg-accent);color:var(--text-accent)}

/* ── Work done: trips with their jobs nested ─────────────────────────────────
   The group head is a row, not a heading, so the columns stay aligned with the job
   rows underneath it — a separate <h4> above each block would break the grid the eye
   is following down the page. */
.sv-work .sv-triphead td{background:var(--surface-1);border-top:2px solid var(--border);
  font-size:13px;padding:9px 10px}
.sv-work tbody.sv-trip:first-of-type .sv-triphead td{border-top:0}
.sv-work .sv-triphead .badge{margin-left:6px}
.sv-work .sv-triphead .muted{margin-left:6px}
/* Jobs sit under their trip: one indent, nothing louder — they are the detail, the
   trip line is what you scan. */
.sv-work tr.sv-job td:first-child{padding-left:18px}
.sv-work .sv-nojob{padding-left:18px;font-style:italic}
/* Desk work is not a trip and must not look like one. */
.sv-work .sv-deskgroup .sv-triphead td{background:var(--bg-accent);color:var(--text-accent)}
.sv-viewswitch{margin-left:auto}
.sv-work .card-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}

@media (max-width: 640px){
  .sv-viewswitch{width:100%;margin-left:0}
  .sv-work .sv-triphead td{padding:10px 8px}
}

/* The History date range wears the courier's day picker. It sits inside the filter row,
   so it is inline rather than a block of its own, and each end carries its label inside
   the button — "From"/"To" outside would wrap away from the date they belong to. */
.sv-range{display:inline-flex;align-items:center;gap:6px;margin:0}
.sv-range .dp-label{min-height:38px;font-size:13.5px;font-weight:500;padding:0 12px;
  gap:6px;justify-content:flex-start;white-space:nowrap}
.sv-range .dp-pre{color:var(--text-muted, #9ca3af);font-weight:600;font-size:11px;
  text-transform:uppercase;letter-spacing:.03em;margin-right:2px}
.sv-range .dp-dash{color:var(--text-muted, #9ca3af)}
@media (max-width: 640px){
  /* Two dates side by side do not fit a phone once they carry their labels — stacked,
     each gets a full-width 44 px target instead of being squeezed off the screen. */
  .sv-range{width:100%;flex-wrap:wrap;gap:8px}
  .sv-range .dp-label{flex:1 1 100%;min-height:44px;font-size:15px}
  .sv-range .dp-dash{display:none}
}

/* ── the portal's own calendar ────────────────────────────────────────────────
   Replaces the browser's native date popup, which renders in the machine's locale —
   a Mac set to Russian opened "июль 2026 г. · Пн Вт Ср" inside an English-only portal,
   and a native popup can be neither restyled nor re-languaged. Markup and behaviour
   live in templates/service/_daypick.html. */
.dpcal{position:absolute;z-index:120;display:none;width:266px;padding:10px;
  background:var(--surface-0, #fff);border:1px solid var(--border, #e5e7eb);
  border-radius:14px;box-shadow:0 12px 32px rgba(17,24,39,.14)}
.dpcal.on{display:block}
.dpcal-head{display:flex;align-items:center;justify-content:space-between;gap:6px;
  margin-bottom:8px}
.dpcal-title{font-weight:600;font-size:14px}
.dpcal-nav{width:30px;height:30px;border:1px solid var(--border, #e5e7eb);
  border-radius:9px;background:var(--surface-0, #fff);color:var(--text-secondary, #6b7280);
  font-size:16px;line-height:1;cursor:pointer}
.dpcal-nav:hover{background:var(--surface-1, #f3f4f6);color:var(--text-primary, #111827)}
.dpcal-dow,.dpcal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
.dpcal-dow span{text-align:center;font-size:10.5px;font-weight:600;letter-spacing:.03em;
  text-transform:uppercase;color:var(--text-muted, #9ca3af);padding-bottom:4px}
.dpcal-d{height:32px;border:0;border-radius:9px;background:transparent;cursor:pointer;
  font-size:13px;color:var(--text-primary, #111827)}
.dpcal-d:hover{background:var(--surface-1, #f3f4f6)}
/* Days spilling in from the neighbouring months stay clickable but must not compete
   with the month you are actually looking at. */
.dpcal-out{color:var(--text-muted, #9ca3af)}
.dpcal-now{box-shadow:inset 0 0 0 1px var(--accent, #2563eb);font-weight:600}
.dpcal-sel{background:var(--accent, #2563eb);color:#fff;font-weight:600}
.dpcal-sel:hover{background:var(--accent-strong, #1d4ed8)}
.dpcal-foot{display:flex;gap:6px;margin-top:8px;padding-top:8px;
  border-top:1px solid var(--border, #e5e7eb)}
.dpcal-foot button{flex:1;min-height:32px;border:1px solid var(--border, #e5e7eb);
  border-radius:9px;background:var(--surface-0, #fff);font-size:12.5px;cursor:pointer;
  color:var(--text-secondary, #6b7280)}
.dpcal-foot button:hover{background:var(--surface-1, #f3f4f6);color:var(--text-primary, #111827)}

@media (max-width: 640px){
  /* On a phone a popup pinned to the button ends up half off-screen, so it becomes a
     centred sheet with finger-sized days. */
  .dpcal{position:fixed;left:50%!important;top:50%!important;
    transform:translate(-50%,-50%);width:min(320px,calc(100vw - 32px))}
  .dpcal-d{height:40px;font-size:15px}
  .dpcal-foot button{min-height:44px;font-size:14px}
}

/* The bank's record under the serial field. Facts first, verdict second — a courier
   reads the warning, a lead checking the report later reads the numbers. */
.sv-bankfacts{margin-top:2px;font-size:12px;color:var(--text-secondary, #6b7280)}
.sv-bankwarn{margin-top:4px;font-size:12.5px;font-weight:600;color:var(--red-fg, #b91c1c)}

/* The signal glossary under the queue. Folded away by default — it answers a question
   you ask once, and then never again. */
.sv-legendfold{margin:10px 0 6px;font-size:13px}
.sv-legendfold>summary{cursor:pointer;color:var(--text-secondary, #6b7280)}
.sv-signalhelp{display:grid;grid-template-columns:auto 1fr;gap:4px 14px;margin:8px 0 0}
.sv-signalhelp dt{font-weight:600;white-space:nowrap}
.sv-signalhelp dd{margin:0;color:var(--text-secondary, #6b7280)}
@media (max-width: 640px){
  .sv-signalhelp{grid-template-columns:1fr;gap:2px}
  .sv-signalhelp dd{margin-bottom:8px}
}

/* The tier badge carries the money with it on the task page: the letter alone is a
   code, the letter with €354 next to it is an argument. */
.sv-tiereur{margin-left:5px;font-size:12.5px;color:var(--text-secondary, #6b7280)}

/* "Station offline — on you" on the manager's weekly card. Open by default: it is the
   one block here that carries a clock. */
.sv-offblock > summary .flag-label{font-weight:600}
.sv-offrow{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.sv-handoff{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-left:auto}
.sv-handoff select,.sv-handoff input[type=date]{font-size:12px;padding:4px 7px;
  border:1px solid var(--border, #e5e7eb);border-radius:8px;
  background:var(--surface-0, #fff);max-width:190px}
@media (max-width: 640px){
  .sv-handoff{margin-left:0;width:100%}
  .sv-handoff select{flex:1;min-height:40px;font-size:14px}
  .sv-handoff input[type=date]{min-height:40px;font-size:14px}
}

/* The tell my phone block. Hidden until the script knows what this device can do —
   a button that may not work is worse than no button. */
/* [hidden] is a UA rule at zero specificity, so .btn{display:inline-block} and
   .sv-push{display:flex} both win over it and the "hidden" elements stayed on screen.
   Say it again with enough specificity to hold. */
.sv-push[hidden],.sv-pushbtns .btn[hidden],.sv-pushtest[hidden],
.sv-pushnudge[hidden]{display:none}

/* The pointer that replaces the block on the working screens: one quiet line, gone for
   good once this device is subscribed. */
.sv-pushnudge{display:flex;flex-wrap:wrap;gap:4px 8px;align-items:baseline;
  background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--radius-sm);padding:9px 12px;margin:0 0 14px;
  color:var(--text-secondary);font-size:13.5px;text-decoration:none}
.sv-pushnudge:hover{background:var(--surface-2);text-decoration:none}
.sv-pushnudge b{color:var(--text-primary);font-weight:600}

/* My account: the one page that carries the switch itself. */
.acct-wrap{max-width:640px}
.acct-wrap h2{margin:22px 0 6px;font-size:16px}
.acct-form{margin-top:4px}

.sv-push{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:10px;margin-bottom:12px}
.sv-pushbtns{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.sv-pushtest{margin:0}
@media (max-width: 640px){
  .sv-push{flex-direction:column;align-items:stretch}
  .sv-pushbtns .btn,.sv-pushtest .btn{width:100%;min-height:44px;justify-content:center}
  .sv-pushtest{width:100%}
}

/* ── operational request forms ────────────────────────────────────────────── */
.frm-countries{display:flex;gap:8px;margin:6px 0 16px}
.frm-cpill{padding:7px 16px;border-radius:999px;border:1px solid var(--border);
  background:var(--surface-1);color:var(--text-secondary);text-decoration:none;font-size:14px}
.frm-cpill.on{background:var(--accent);color:#fff;border-color:var(--accent)}
.frm{max-width:620px}
.frm-fields{display:flex;flex-direction:column}
.frm-field{margin:0 0 16px}
.frm-label{display:block;font-weight:600;margin-bottom:3px}
.frm-req{color:#b3261e}
.frm-help{color:var(--text-secondary);font-size:12.5px;margin-bottom:6px}
.frm-in{width:100%;box-sizing:border-box;font-size:16px;padding:10px 12px;
  border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface-2)}
.frm-radios{display:flex;flex-wrap:wrap;gap:8px 18px}
.frm-radio{font-size:15px;display:flex;align-items:center;gap:6px}
.frm-send{width:100%;min-height:48px;justify-content:center;font-size:16px;margin-top:4px}
.frm-photos{display:flex;flex-wrap:wrap;gap:10px;margin-top:8px}
.frm-photos img{max-width:180px;max-height:180px;border-radius:8px;border:1px solid var(--border)}
.frm-note{margin-top:12px;background:var(--surface-1);border-radius:var(--radius-sm);padding:10px 12px}
.frm-actions{margin-top:16px;border-top:1px solid var(--border);padding-top:14px}
.frm-actions textarea{width:100%;box-sizing:border-box;font-size:16px;padding:9px 11px;
  border:1px solid var(--border);border-radius:var(--radius-sm);margin-bottom:10px}
.badge.b-new{background:#fef6e7;color:#9a6a00}
.badge.b-in_progress{background:#e7f0fd;color:#1f5fa0}
.badge.b-done{background:#eaf6ec;color:#1e7a34}
.badge.b-rejected{background:var(--surface-1);color:var(--text-secondary)}
@media (max-width:640px){ .frm{max-width:100%} }

.btn.sv-handbtn{background:var(--surface-1)}
.sv-photobtn{width:100%;min-height:46px;border:1px dashed var(--border-strong);border-radius:10px;background:transparent;color:var(--text-secondary);font-weight:600;font-size:14px;margin-top:8px;cursor:pointer}
.sv-photobtn:hover{background:var(--surface-1)}
.sv-serialthumbs{display:flex;gap:8px;flex-wrap:wrap;margin-top:8px}
.sv-serialthumb{position:relative;width:66px;height:66px;border-radius:9px;overflow:hidden;border:1px solid var(--border);background:var(--surface-1)}
.sv-serialthumb img{width:100%;height:100%;object-fit:cover;display:block}
.sv-serialthumb .lbl{position:absolute;left:0;right:0;bottom:0;background:rgba(0,0,0,.55);color:#fff;font-size:9px;text-align:center;padding:1px 2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sv-serialx{position:absolute;top:2px;right:2px;width:20px;height:20px;border:0;border-radius:50%;background:rgba(0,0,0,.6);color:#fff;font-size:13px;line-height:20px;text-align:center;cursor:pointer;padding:0}
.sv-scanrow{display:flex;gap:8px;align-items:flex-end;flex-wrap:wrap;margin-top:10px}
.sv-scanlbl{display:flex;flex-direction:column;gap:3px;font-size:13px;color:var(--text-secondary);font-weight:600}
.sv-scanrow .sv-scandir{min-height:40px;padding:6px 10px;border:1px solid var(--border);border-radius:8px;font-size:14px;background:var(--surface-1)}
.sv-scanrow .sv-scanbtn{flex:1;min-width:200px}
@media (max-width:640px){.sv-scanrow{flex-direction:column;align-items:stretch}.sv-scanrow .sv-scanbtn,.sv-scanrow .sv-scandir{width:100%}}

/* Trips — накопительный итог по выездам. Плитки те же, что на экране дня курьера:
   один и тот же приём для «вот сколько уже» на обоих экранах. */
.tp-tiles { display: flex; gap: 10px; flex-wrap: wrap; margin: 4px 2px 0; }
.tp-tile { background: var(--surface-1, #f6f8fa); border: 1px solid var(--border, #e5e7eb);
  border-radius: 10px; padding: 8px 14px; min-width: 120px; }
.tp-k { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted, #6b7280); }
.tp-v { display: block; font-size: 20px; font-weight: 700; margin-top: 2px; }

/* Отметка места под снимком в задаче. */
.sv-geo{display:block;font-size:11px;line-height:1.3;margin-top:3px;color:var(--text-muted,#6b7280)}
.sv-geo.ok{color:#15803d}
.sv-geo.far{color:#b45309;font-weight:600}
.sv-geo.none{font-style:italic}
.sv-geonote{margin:6px 2px 0}

/* Дубли верхней панели борда. На большом экране эти шесть фильтров стоят в шапке
   таблицы над своими колонками — здесь они только шумят. На телефоне строка в таблице
   скрыта совсем (.sv-findrow display:none ниже 640px), поэтому панель там полная. */
.filters .sv-dup { display: none; }
@media (max-width: 640px) { .filters .sv-dup { display: contents; } }

/* ── Борд без горизонтальной прокрутки ────────────────────────────────────────
   Таблица упиралась в 956 px минимума у админа (у него ещё колонка Country), и на
   окне уже ~980 px появлялась прокрутка. Почти вся лишняя ширина — не в данных, а в
   обвязке: пилюли фильтров в шапке, поле «task #», отступы ячеек и селект
   исполнителя. Ужимаем обвязку, данные не трогаем. */
.sv-findrow .msf-btn { padding: 4px 7px; font-size: 11px; gap: 3px; }
.sv-findrow .sv-tid { min-width: 46px; }
.sv-findrow th { padding: 5px 5px 8px; }
.sv-board .sv-assign select { width: 106px; min-width: 0; }
.sv-board .dt-btn { padding: 4px 7px; font-size: 12px; }
table.grid.sv-board th, table.grid.sv-board td { padding-left: 7px; padding-right: 7px; }

/* «Нужен снимок» — обычная подсказка, которая краснеет, когда на неё наткнулись.
   Раньше это говорил браузер, но над спрятанным полем, то есть в пустоту. */
.sv-needshot { margin: 6px 2px 0; }
.sv-needshot-on { color: var(--red-fg, #c0392b); font-weight: 600; }

/* Вид работы уже написан заголовком задачи внутри — в раскрытой остановке подпись
   в шапке повторяла бы его слово в слово. Свёрнутой она нужна: это единственный способ
   понять, зачем едешь, не открывая точку. */
.cd-stop.open .cd-kinds { display: none; }

/* Крестик на снимке: приложили не тот файл — уберите. */
.sv-photos { position: relative; }
.sv-photodel { border: 0; background: rgba(15,23,42,.62); color: #fff; cursor: pointer;
  border-radius: 999px; width: 26px; height: 26px; line-height: 1; font-size: 13px;
  margin: -34px 0 0 -32px; position: relative; z-index: 2; }
.sv-photodel:hover { background: var(--red-fg, #c0392b); }

/* Снимки, приложенные к задаче, прямо на экране дня — курьер работает здесь. */
.cd-shots { display: flex; gap: 8px; flex-wrap: wrap; margin: 6px 0 2px; }
.cd-shot { position: relative; display: inline-block; }
.cd-shot img { width: 64px; height: 64px; object-fit: cover; border-radius: 10px;
  border: 1px solid var(--border, #e5e7eb); display: block; }
.cd-shotdel { position: absolute; top: -6px; right: -6px; width: 22px; height: 22px;
  border: 0; border-radius: 999px; background: rgba(15,23,42,.72); color: #fff;
  font-size: 12px; line-height: 1; cursor: pointer; padding: 0; }
.cd-shotdel:hover { background: var(--red-fg, #c0392b); }

/* Ответ на выбор снимка в отчёте. Раньше на этом месте была тишина, и тишину курьер
   читал как поломку — Хаммад так и написал: «no file attached» (Лина, 10.09). */
.sv-shotmsg{display:block;margin:4px 0 0}
.sv-shotmsg.sv-shotok{color:var(--ok, #15803d)}
.sv-shotmsg.sv-shotbad{color:var(--bad, #b91c1c)}

/* Отказ, который подавший ещё не открывал. Красным помечена вся строка, а не только
   бейдж: в списке из двадцати заявок глаз ищет цвет, а не слово (Лина, 10.09). */
.fr-unread td{background:var(--bad-bg, #fef2f2)}
.fr-new{display:inline-block;margin-left:5px;padding:0 6px;border-radius:999px;
  background:#b91c1c;color:#fff;font-size:11px;font-weight:700;vertical-align:middle}

/* Причина отказа. Место важное — сразу под шапкой, до полей, — но НЕ красное: отказ по
   заявке это рабочая ситуация, а не авария, и кричать на человека незачем (Лина, 10.09).
   Заметность даёт рамка и положение, а не цвет. */
.frm-reject{margin:12px 0 0;padding:10px 12px;
  border-left:4px solid var(--border, #d1d5db);
  background:var(--surface-1, #f3f4f6);border-radius:0 6px 6px 0}
.frm-reject-h{font-weight:700;color:var(--text-secondary, #4b5563);font-size:13px}
.frm-reject-why{margin-top:4px;white-space:pre-wrap}
