/* The Ignite project page (3.0, rebuild plan Phase 1). Its own looks only, every one built from tokens.css; the shared
   pieces (glass, strip, drill, pipe, seg, subtabs, chip, status, pop, table.t, cards) come from components.css. Design:
   rebuild/kit/project.html. Every class here starts with pj- so nothing on another screen can pick it up. */

/* ---- header: title, job number, status, the facts line; actions on the right */
.pj-ph { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 14px; }
.pj-t { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 2px; }
.pj-t h1 { margin: 0; font-size: var(--fs-h1); font-weight: var(--fw-bold); letter-spacing: -.02em; text-wrap: balance; }
.pj-meta { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 6px; font-size: 13px; color: var(--muted); }
.pj-meta a { color: var(--ink-2); font-weight: var(--fw-semi); text-decoration: none; }
.pj-meta a:hover { text-decoration: underline; }
.pj-meta .who { display: inline-flex; align-items: center; gap: 6px; }
/* D03 (w17ignite): the Overview's PM and date quick edits open on a row of their own under the meta line */
.pj-meta .qe-edit { flex: 1 1 100%; color: var(--ink-2); }
.pj-meta .qe-edit > .hint { flex: 1 1 100%; margin: 0; }
.pj-meta .qe-edit input[type="date"] { width: auto; min-width: 17ch; }
.pj-meta .qe-edit .select-wrap { min-width: 240px; }
.pj-meta .qe-edit #pjPoIn { width: auto; min-width: 26ch; }
.pj-meta .pj-po-src { font-size: 12px; }
@media (max-width: 640px) {
  .pj-meta .qe-edit #pjPoIn { flex: 1 1 100%; min-width: 0; }
  .pj-meta .qe-edit .select-wrap { flex: 1 1 100%; }
  .pj-meta .qe-edit input[type="date"] { flex: 1 1 calc(50% - 40px); min-width: 0; }
}
.pj-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.pj-actions .btn.icon { width: 40px; }
.pj-talk-btn em { font-style: normal; font-size: 11px; font-weight: var(--fw-x); min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--r-pill);
  background: var(--accent-ink); color: var(--on-ink); display: inline-grid; place-items: center; }   /* the text-safe accent, with the theme's own contrast colour on it */

/* ---- section bar: Overview · Field · Money · Paperwork · Plan, then that section's sub-tabs */
.pj-secbar { display: grid; gap: 4px; }
.pj-secbar .seg { justify-self: start; }
.pj-secbar .seg button { height: 34px; padding: 0 16px; font-size: 13.5px; }

/* ---- body: the open tab on the left, the Discussion panel on the right */
.pj-body { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: var(--gap); align-items: start; }
.pj-body.talk-off { grid-template-columns: minmax(0, 1fr); }
.pj-body.talk-off .pj-talk { display: none; }
.pj-col { display: grid; gap: var(--gap); min-width: 0; }
.pj-sec h2 { margin: 0; font-size: var(--fs-l); font-weight: var(--fw-x); }
.pj-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; margin-bottom: 12px; }
.pj-top.tight { margin-bottom: 6px; }
.pj-top.flush { margin-bottom: 0; }
.pj-sub { margin: 0 0 12px; font-size: 13px; color: var(--muted); max-width: 72ch; }

/* ---- Needs doing */
.pj-need { display: grid; grid-template-columns: 8px minmax(0, 1fr) auto 128px; align-items: center; gap: 14px; padding: 12px 0; border-top: 1px solid var(--hair); }
.pj-need > .btn { grid-column: 4; justify-self: stretch; justify-content: center; }   /* one button width, so every amount ends on the same line */
.pj-need:first-of-type { border-top: 0; padding-top: 4px; }
.pj-need .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--faint); }
.pj-need .dot.warn { background: var(--warn); } .pj-need .dot.bad { background: var(--bad); } .pj-need .dot.info { background: var(--info); }
.pj-need b { font-weight: var(--fw-bold); }
.pj-need .amt { font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; }
.pj-need .flags { margin-top: 8px; }
.pj-clear { margin: 0; color: var(--muted); font-size: 13.5px; }

/* ---- a quantity split into its parts: cost vs margin; billed this year vs before it (3.0 pay-ar — payments are in SAGE) */
.pj-bar { display: flex; gap: 2px; height: 12px; padding: 2px; border-radius: var(--r-pill); background: var(--well); box-shadow: inset 0 1px 2px rgba(16,24,40,.12); margin-top: 14px; }
.pj-bar i { display: block; flex: 0 0 var(--part, 0); border-radius: var(--r-pill); box-shadow: inset 0 1px 0 rgba(255,255,255,.5); animation: pj-grow var(--t-pour) both; }
.pj-bar i.rest { flex: 1 1 0; }
@keyframes pj-grow { from { flex-basis: 0; } }
.pj-c-cost { background: linear-gradient(180deg, var(--water-bad-a), var(--water-bad-b)); }
.pj-c-margin, .pj-c-year { background: linear-gradient(180deg, var(--water-ok-a), var(--water-ok-b)); }
.pj-c-prior { background: linear-gradient(180deg, var(--water-a), var(--water-b)); }
.pj-c-ready { background: var(--warn); } .pj-c-none { background: var(--hair-2); }
.pj-legend { margin-top: 12px; display: grid; }
.pj-legend > div { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 8px 0; border-top: 1px solid var(--hair); font-size: 13.5px; }
.pj-legend > div:first-child { border-top: 0; }
.pj-legend span { display: inline-flex; align-items: center; gap: 8px; color: var(--ink-2); min-width: 0; }
.pj-legend span i { width: 8px; height: 8px; border-radius: 3px; flex: none; }
.pj-legend small { color: var(--faint); font-size: 12px; font-weight: var(--fw-semi); }
.pj-legend b { font-variant-numeric: tabular-nums; }
.pj-legend b.ok { color: var(--ok); } .pj-legend b.bad { color: var(--bad); }
.pj-legend .tot { font-weight: var(--fw-bold); }
.pj-legend .tot span { color: var(--ink); font-weight: var(--fw-bold); }
.pj-from { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 12px; }   /* where a card's figures come from */
.pj-head-num { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 6px 12px; }

/* ---- bid items: progress per item; over-run warning; work marked without a ticket */
.pj-done { display: flex; flex-wrap: wrap; gap: 4px 18px; font-size: 13px; color: var(--muted); }
.pj-done b { color: var(--ink); font-variant-numeric: tabular-nums; }
.pj-bigpipe { height: 12px; margin-top: 10px; }
.pj-prog { display: flex; align-items: center; gap: 8px; }
.pj-prog .pipe { flex: 1 1 auto; height: 6px; min-width: 60px; }
.pj-prog b { width: 46px; text-align: right; font-variant-numeric: tabular-nums; font-size: 12.5px; }
th.pj-prog-h { width: 170px; }
.pj-item { font-weight: var(--fw-bold); color: var(--ink); }   /* a pay item's name: a door to its row in Pay Items */
.pj-bigpipe + .flags { margin-top: 14px; }
.pj-mark-ok { color: var(--ok); font-weight: var(--fw-semi); }
.pj-mark-x { color: var(--muted); font-weight: var(--fw-semi); }
.pj-notes { white-space: pre-wrap; font-size: 13.5px; color: var(--ink-2); margin: 0; }

/* ---- job site brief */
.pj-brief { display: grid; gap: 0; }
.pj-brief > div { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 12px; padding: 9px 0; border-top: 1px solid var(--hair); font-size: 13.5px; }
.pj-brief > div:first-child { border-top: 0; }
.pj-brief .k { color: var(--muted); font-weight: var(--fw-semi); }
.pj-brief .v { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; min-width: 0; }
/* a finger at any width (w22touch, 10/27): a row's source link and the next row's sat 38px apart, so each one's 44px reach ran
   into the other's — the rows open to 44 centre to centre — and "See the day →" (22px of words) gets the reach a door has */
@media (pointer: coarse) {
  .pj-brief > div { padding-block: 12px; }
  .pj-brief .v > a:not(.src, .btn, .chip) { position: relative; }
  .pj-brief .v > a:not(.src, .btn, .chip)::after { content: ""; position: absolute; inset: calc(50% - var(--tap) / 2) min(-4px, calc(50% - var(--tap) / 2)); }
}

/* ---- links (Field › Crew & Customer Links) */
.pj-link { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 8px; align-items: center; margin-top: 10px; }
.pj-link .input { font-family: ui-monospace, Menlo, monospace; font-size: 12.5px; }
.pj-link .btn { height: var(--ctl); }

/* ---- the 2.x tab bodies that still draw their own markup sit inside one plain area */
.pj-tab { min-width: 0; }

/* ---- Discussion: a panel on the right; slides in over the page below 1100 px */
.pj-talk { position: sticky; top: calc(var(--tn-stuck, 0px) + 14px); display: flex; flex-direction: column; max-height: calc(100vh - 28px - var(--tn-stuck, 0px)); overflow: hidden; }
@media (min-width: 1101px) { body.has-aimsly .pj-talk { max-height: calc(100vh - 100px); } }   /* stops above Aimsly's corner, so her button never sits on the message box */
.pj-talk header { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 14px 14px 12px 16px; border-bottom: 1px solid var(--hair); }
.pj-talk header h2 { margin: 0; font-size: var(--fs-l); font-weight: var(--fw-x); }
.pj-talk header .btn { flex: none; }   /* the close button keeps its tap size beside the hint text */
.pj-talk-body { flex: 1 1 auto; overflow: auto; padding: 14px 16px; display: grid; gap: 14px; align-content: start; }
.pj-talk-scrim { display: none; position: fixed; inset: 0; z-index: 65; border: 0; padding: 0; background: rgba(11,18,32,.3);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); cursor: pointer; }

@media (max-width: 1180px), (pointer: coarse) {   /* touch: the section bar and the icon button at a full tap */
  .pj-secbar .seg button { height: var(--tap); }
  .pj-actions .btn.icon { width: var(--tap); }
}
@media (max-width: 1100px) {
  .pj-body, .pj-body.talk-off { grid-template-columns: minmax(0, 1fr); }
  .pj-talk, .pj-body.talk-off .pj-talk { display: flex; position: fixed; z-index: 70; top: 10px; right: 10px; bottom: 10px; width: min(380px, calc(100vw - 20px)); max-height: none;
    transform: translateX(calc(100% + 24px)); transition: transform 500ms cubic-bezier(.34,1.12,.5,1); }
  .pj.talk-open .pj-talk { transform: none; }
  .pj.talk-open .pj-talk-scrim { display: block; }
}
@media (max-width: 640px) {
  .pj-need { grid-template-columns: 8px minmax(0, 1fr) auto; }
  .pj-need .btn { grid-column: 2 / -1; justify-self: start; }
  .pj-brief > div { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .pj-link { grid-template-columns: minmax(0, 1fr) auto; }
  .pj-link .input { grid-column: 1 / -1; }
  .pj-secbar .seg { justify-self: stretch; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .pj-secbar .seg button { padding: 0 2px; font-size: 12.5px; min-width: 0; }
  .pj-actions { width: 100%; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) var(--tap); }
  .pj-actions > .btn.primary { grid-column: 1 / -1; justify-content: center; }   /* the main action on its own row, full width */
  .pj-actions > .btn, .pj-actions .anchor > .btn { width: 100%; justify-content: center; }
  .pj-actions .btn.icon { width: var(--tap); }
}
@media (max-width: 360px) {   /* the narrowest phones: the five section names fit in a smaller face, not a new word */
  .pj-secbar .seg button { font-size: 11px; letter-spacing: -.01em; padding: 0 1px; }
}

/* ---- Field › Tickets (3.0): the crew's link, the job's tickets (a card each on a phone), the test results */
.pj-tkbar { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 10px 14px; }
.pj-tkbar h2 { margin: 0; display: flex; align-items: baseline; gap: 8px; }
.pj-tkbar .actions { display: flex; flex-wrap: wrap; gap: 8px; }
.pj-tick { width: 40px; }
.pj-hit { display: inline-grid; place-items: center; cursor: pointer; }
.pj-hit input { width: 16px; height: 16px; margin: 0; accent-color: var(--ink); }
.pj-who { display: inline-flex; color: inherit; text-decoration: none; }
.pj-who:hover .who > span:last-child { text-decoration: underline; }
.pj-tk .cards .card, .pj-tests .cards .card { display: grid; gap: 8px; margin: 0; }
.pj-tkname { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; min-width: 0; }
.pj-tkrow { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; }
.pj-tk .status { min-width: 128px; }
#pjTests:empty { display: none; }
#pjTests h2 { margin: 0; }
@media (max-width: 1180px), (pointer: coarse) {
  .pj-hit { min-width: 44px; min-height: 44px; margin: -10px; justify-content: center; }   /* centred: the kit's label:has(> checkbox) flex would put the box at its left (w27b review) */
  .pj-hit input { width: 22px; height: 22px; }
}
@media (max-width: 640px) { .pj-tkbar .actions, .pj-tkbar .actions .btn { width: 100%; justify-content: center; } }
.pj-stack { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--gap); min-width: 0; }   /* one track that never grows past the page: a long option in a select made the take-off's phone cards 545px wide at 375 */
.pj-tk a.name { font-weight: var(--fw-bold); color: var(--ink); }

/* ---- Money › Est. vs Actual (3.0): pace by item, then the resources the crews carried against the bid's kits */
.pj-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px 14px; margin: 0; }
.pj-facts dt { font-size: 12px; font-weight: var(--fw-semi); color: var(--muted); margin-bottom: 2px; }
.pj-facts dd { margin: 0; font-size: 13px; font-variant-numeric: tabular-nums; }
.pj-stack .phone-cards h2, .pj-stack .pj-sec h2 { margin: 0; }
.pj-stack .phone-cards .pad .pj-sub { margin-top: 4px; }
.pj-rsl { list-style: none; margin: 10px 0 0; padding: 0; display: grid; }
.pj-rsl li { display: grid; grid-template-columns: 96px minmax(0, 1.4fr) minmax(0, 1fr) 90px 100px 32px; gap: 6px 12px; align-items: center; padding: 8px 0; border-top: 1px solid var(--hair); }
.pj-rsl li:first-child { border-top: 0; }
.pj-rsadd { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, .7fr) minmax(0, .8fr) minmax(0, 1.5fr) minmax(150px, 1.2fr) auto; gap: 10px 12px; align-items: end; margin-top: 14px; }
.pj-rsadd .field { margin-bottom: 0; }
@media (max-width: 1180px) {
  .pj-rsadd { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pj-rsadd .pj-rsitem { grid-column: 1 / -1; }
  .pj-rsadd .btn { justify-content: center; }
}
@media (max-width: 640px) {
  .pj-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pj-rsl li { grid-template-columns: minmax(0, 1fr) auto; }
  .pj-rsl li > :nth-child(1), .pj-rsl li > :nth-child(3) { grid-column: 1 / -1; }
}
.pj-prod td:first-child { min-width: 220px; }
.pj-stack a.name { font-weight: var(--fw-bold); color: var(--ink); }
@media (max-width: 640px) { .pj-facts > :last-child:nth-child(odd) { grid-column: 1 / -1; } }   /* an odd last fact takes the row: never 2 + 1 */
.pj-tkbar > div:first-child { flex: 1 1 360px; min-width: 0; }
/* ---- Field › Photos and Money › Bid Variance (3.0) */
.pj-photos { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; margin-top: 8px; }
.pj-photos figure { margin: 0; display: grid; gap: 4px; min-width: 0; align-content: start; }
.pj-photos img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--r-m); border: 1px solid var(--hair); background: var(--well); }
.pj-photos figcaption { font-size: 12px; overflow-wrap: anywhere; }
.pj-phacts { display: flex; flex-wrap: wrap; gap: 4px; }
.pj-phline { padding-top: 12px; margin-top: 12px; border-top: 1px solid var(--hair); }
.pj-phline:first-of-type { margin-top: 4px; }
.pj-sec .pj-top h2 { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
tr.pj-over td:first-child, .card.pj-over { box-shadow: inset 3px 0 0 var(--warn); }
.pj-stack table.t tfoot td { border-top: 1px solid var(--hair); }
@media (max-width: 640px) { .pj-photos { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.pj-nowrap { white-space: nowrap; }

/* ---- pop-ups opened from the project page's tabs (3.0, projtabs): the kit's fields inside the app's .modal */
.pj-modal { display: grid; gap: 12px; }
.pj-modal h2 { margin: 0; font-size: var(--fs-xl); }
.pj-modal h3 { margin: 6px 0 0; font-size: var(--fs-l); }
.pj-modal p { margin: 0; }
.pj-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 12px; }
.pj-form .wide { grid-column: 1 / -1; }
.pj-modalacts { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; }
.pj-grow { flex: 1 1 auto; }
.pj-phlist { display: grid; gap: 8px; }
.pj-phrow { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: center; }
@media (max-width: 640px) { .pj-form { grid-template-columns: minmax(0, 1fr); } .pj-modalacts .btn { flex: 1 1 calc(50% - 4px); justify-content: center; } .pj-modalacts .pj-grow:empty { display: none; } }

/* ---- a tick box with its words (a checkbox the kit has no component for) */
.pj-pichk { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; min-width: 0; }
.pj-pichk input { width: 16px; height: 16px; margin: 0; flex: none; accent-color: var(--ink); }
.pj-pichk.off { opacity: .5; cursor: not-allowed; }
.pj button.chip { border: 0; cursor: pointer; font-family: inherit; }
.pj button.chip:hover { filter: brightness(.96); }

/* ---- Plan › Pay Items (3.0): the bid schedule edited in place — each item a row of its numbers, then a row of where its
   price comes from and what the crew is asked about it; a card each on a phone */
.pj-pit .pj-pino { width: 80px; }
.pj-pit .pj-pino .input { padding-left: 8px; padding-right: 8px; }   /* a change order's "CO-12" reads whole (w17-change-orders) */
.pj-pit .pj-piunit { width: 120px; }
.pj-pit .pj-pinum { width: 92px; }
.pj-pit .input, .pj-pit .select, .pj-picard .input, .pj-picard .select { height: 34px; }
.pj-pit tbody tr.pj-pirow td { border-bottom: 0; padding-bottom: 2px; }
.pj-pit tbody tr.pj-pisub td { padding-top: 4px; padding-bottom: 14px; }
.pj-pit tr.child td:first-child, .pj-picard.child { box-shadow: inset 3px 0 0 var(--hair-2); }
.pj-pidesc { display: flex; align-items: center; gap: 8px; min-width: 220px; }
.pj-pidesc .input { flex: 1 1 auto; min-width: 0; }
.pj-piarrow { color: var(--faint); flex: none; }
.pj-pitot { font-weight: var(--fw-bold); white-space: nowrap; }
.pj-pit tfoot td { border-top: 1px solid var(--hair); }
.pj-book { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; font-size: 11.5px; margin: 0 0 8px; }
.pj-book .was { color: var(--muted); text-decoration: line-through; }
.pj-book .off { color: var(--ink-2); font-weight: var(--fw-bold); }
.pj-book .src { margin: 0; }
.pj-piv > .chip { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pj-book .btn.sm { height: 24px; padding: 0 8px; font-size: 11.5px; }
.pj-piset { display: grid; grid-template-columns: minmax(0, .75fr) minmax(0, 1fr) minmax(0, 1.35fr) minmax(0, 1fr); gap: 8px 12px; }
.pj-piset:has(> :nth-child(5)) { grid-template-columns: minmax(0, .75fr) minmax(0, 1fr) minmax(0, 1.35fr) minmax(0, 1fr) minmax(0, 1fr); }
.pj-piset .field { gap: 3px; min-width: 0; }
.pj-piset .field > label, .pj-piset .field > .label { font-size: 11.5px; color: var(--muted); font-weight: var(--fw-semi); }
.pj-piv { min-height: 34px; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-size: 13px; }
.pj-picard { display: grid; gap: 10px; margin: 0; }
.pj-piform { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 10px; }
.pj-piform .wide { grid-column: 1 / -1; }
.pj-piform .field { gap: 3px; min-width: 0; }
.pj-pitotc { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.pj-pitotc b { font-variant-numeric: tabular-nums; }
.pj-pi2 > .pj-sec { min-width: 0; }
.pj-fuel { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 12px; align-items: start; }
.pj-fuel .field > label { min-height: 34px; display: flex; align-items: flex-end; }
.pj-fuel > .pj-pichk { grid-column: 1 / -1; }
.pj-fuelitems { margin-top: 10px; }
.pj-mobf { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 12px; margin-bottom: 10px; }
.pj-mobf .wide { grid-column: 1 / -1; }
.pj-mobl { list-style: none; margin: 8px 0 0; padding: 0; display: grid; }
.pj-mobl li { display: grid; grid-template-columns: 36px minmax(0, 1.2fr) minmax(0, 1fr) auto minmax(0, 1fr) auto; gap: 4px 10px; align-items: center; padding: 7px 0; border-top: 1px solid var(--hair); font-size: 13px; }
.pj-mobl li:first-child { border-top: 0; }
.pj-mobl .r { text-align: right; }
/* minimum charges and the fuel's items: one summary line that opens a list of ticks */
.pj-mint .pj-minq, .pj-mint .pj-minr { width: 110px; }
.pj-mint .pj-minu { width: 104px; }
.pj-mint td { vertical-align: top; }
.pj-mint .input, .pj-mint .select { height: 34px; }
.pj-minitems summary { cursor: pointer; font-size: 13px; font-weight: var(--fw-semi); padding: 7px 0; list-style-position: inside; }
.pj-minlist { display: grid; gap: 6px; padding: 6px 0 2px; max-height: 240px; overflow: auto; }
.pj-mincard { display: grid; gap: 10px; margin: 0; }
/* add a pay item: the Master Items search, its answers under it, then the row it fills */
.pj-pifind { position: relative; }
.pj-pihits { left: 0; right: 0; top: 64px; max-height: 340px; overflow: auto; }
.pj-pihits button { height: auto; min-height: 44px; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 12px; padding: 6px 10px; }
.pj-pihits button .hint { grid-column: 1; }
.pj-pihits button b { grid-column: 2; grid-row: 1 / span 2; align-self: center; white-space: nowrap; }
.pj-pihitd { font-weight: var(--fw-semi); }
.pj-pihint { margin: 0; padding: 8px 10px; }
#piPicked { margin: 8px 0 12px; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.pj-piadd { display: grid; grid-template-columns: 90px minmax(0, 2fr) 132px 132px 132px auto; gap: 10px 12px; align-items: end; }
/* a change order's add row has its button below the change-order fields, so no empty sixth track (w17-change-orders) */
@media (min-width: 1181px) { .pj-piadd:not(:has(> .btn)) { grid-template-columns: 90px minmax(0, 2fr) 132px 132px 132px; } }
@media (max-width: 1180px) {
  .pj-piset, .pj-piset:has(> :nth-child(5)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pj-piset > :nth-child(5):last-child { grid-column: 1 / -1; }   /* five settings: 2 + 2 + 1 across the row, never an orphan */
  .pj-piadd { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-flow: row dense; }
  .pj-piadd .pj-piadd-d { grid-column: 1 / -1; }
  .pj-piadd .btn { grid-column: 1 / -1; justify-content: center; }
}
@media (max-width: 1180px), (pointer: coarse) {
  .pj-pichk input { width: 22px; height: 22px; }
  .pj-pit .input, .pj-pit .select, .pj-picard .input, .pj-picard .select, .pj-mint .input, .pj-mint .select { height: var(--tap); }
  .pj-mobl li > a { position: relative; }   /* the mobilization row's Ticket link: a thumb's reach, the row no taller */
  .pj-mobl li > a::after { content: ""; position: absolute; inset: calc(50% - var(--tap) / 2) -8px; }
}
@media (max-width: 640px) {
  .pj-fuel > .pj-pichk { height: var(--tap); }
  /* w45-12 (W43 design review): six cells in a three-column grid with two forced onto "2 / -1" dropped the chip into the 36px number column
     and the billed figure into a 0px one ("36px 261px 0px", 103px tall at 375). Placed by name: the number down the left; the date and
     what was billed on the first line; how long it had been off under the date; the chip and the ticket link on the last. */
  .pj-mobl li { grid-template-columns: 36px minmax(0, 1fr) auto; grid-template-areas: "n date bill" "n off off" "n chip tix"; }
  .pj-mobl li > :nth-child(1) { grid-area: n; align-self: start; }
  .pj-mobl li > :nth-child(2) { grid-area: date; }
  .pj-mobl li > :nth-child(3) { grid-area: off; }
  .pj-mobl li > :nth-child(4) { grid-area: chip; }
  .pj-mobl li > :nth-child(5) { grid-area: bill; }
  .pj-mobl li > :nth-child(6) { grid-area: tix; justify-self: end; }
}

/* ---- Plan › Take-Off (3.0): the shapes as a segmented strip, each take-off a table of inputs (a card a line on a phone),
   AIMS Trace, the Locations list, the add and the upload */
.pj-tostrip { flex: 1 1 100%; min-width: 0; }
.pj-toseg { max-width: 100%; }
.pj-tot td { white-space: nowrap; }
.pj-tot .input, .pj-tot .select, .pj-tocard .input, .pj-tocard .select { height: 34px; }
.pj-tot .pj-tomh .input { min-width: 112px; }
.pj-tot .pj-toqty .input { min-width: 92px; }
/* the quantity and its unit on one line (w43b b5) */
.pj-qtyrow { display: flex; align-items: center; gap: 8px; }
.pj-qtyrow .input { flex: 1 1 auto; min-width: 0; }
.pj-tounit { flex: none; white-space: nowrap; }
.pj-tot .pj-tosz .input { min-width: 84px; }
.pj-tot .pj-toar .input, .pj-tot .pj-toc .input, .pj-tot .pj-tof.text .input { min-width: 120px; }
.pj-tot .pj-tof.number .input { min-width: 112px; }
.pj-tot .pj-tof.date .input { min-width: 140px; }
.pj-tot .pj-tof.select .select, .pj-tot .pj-toty .select { min-width: 130px; }
.pj-tot .pj-toit { min-width: 310px; white-space: normal; }
.pj-tot .pj-toq { max-width: 220px; overflow: hidden; text-overflow: ellipsis; }
.pj-toitem { display: flex; gap: 6px; align-items: center; }
.pj-toitem > .select-wrap.block { flex: 1 1 auto; min-width: 0; }
.pj-toadd { width: 56px; }
.pj-toextras { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.pj-toextra { height: auto; min-height: 22px; white-space: normal; }
.pj-toextra button { border: 0; background: none; padding: 0; color: var(--muted); cursor: pointer; display: inline-flex; }
.pj-toextra button:hover { color: var(--bad); }
.pj-todone { color: var(--ok); display: inline-flex; vertical-align: middle; }
.pj-tick-ok { color: var(--ok); font-weight: var(--fw-bold); white-space: nowrap; }
tr.pj-todone-row td { background: color-mix(in srgb, var(--ok) 7%, transparent); }
.pj-tocard { display: grid; gap: 10px; margin: 0; }
.pj-tocard.done { box-shadow: inset 3px 0 0 var(--ok); }
.pj-trl { list-style: none; margin: 0; padding: 0; display: grid; }
.pj-trl li { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 6px 14px; align-items: center; padding: 9px 0; border-top: 1px solid var(--hair); }
.pj-trl li:first-child { border-top: 0; }
.pj-trl li > span:first-child { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; min-width: 0; }
.pj-toup { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: center; }
.pj-toup .input[type=file] { padding: 6px 10px; }
#toCsvStatus:empty { display: none; }
#toCsvStatus { margin: 8px 0 0; }
/* the Locations list: one line per place at a desk, name and Edit then a 2 × 2 of figures on a phone */
.pj-locadd { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; margin-bottom: 10px; }
.pj-locfilter { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 8px 10px; align-items: center; margin-bottom: 8px; }
#pjLocCount:empty { display: none; }
.pj-locl { list-style: none; margin: 0; padding: 0; display: grid; }
.pj-locl li { display: grid; grid-template-columns: minmax(0, 2fr) 100px 110px minmax(0, 1fr) minmax(0, 1fr) 70px; gap: 6px 12px; align-items: center; padding: 9px 0; border-top: 1px solid var(--hair); font-size: 13px; }
.pj-locl.compact li { grid-template-columns: minmax(0, 2fr) 100px 110px minmax(0, 1fr) minmax(0, 1fr); }
.pj-locl li:first-child { border-top: 0; }
.pj-locl .pj-lochead { font-size: 11.5px; font-weight: var(--fw-semi); color: var(--muted); padding-top: 0; }
.pj-locname { min-width: 0; }
.pj-locact { text-align: right; }
@media (max-width: 1180px), (pointer: coarse) {
  .pj-tot .input, .pj-tot .select, .pj-tocard .input, .pj-tocard .select { height: var(--tap); }
}
@media (max-width: 640px) {
  .pj-trl li { grid-template-columns: minmax(0, 1fr); }
  .pj-trl li .actions .btn { flex: 1 1 0; justify-content: center; }
  .pj-toup { grid-template-columns: minmax(0, 1fr); }
  .pj-toup .btn { justify-content: center; }
  .pj-locfilter { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); }
  .pj-locfilter #pjLocCount { grid-column: 1 / -1; }
  .pj-locl li, .pj-locl.compact li { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pj-locl .pj-lochead { display: none; }
  .pj-locl li > [data-l]::before { content: attr(data-l); display: block; font-size: 11.5px; font-weight: var(--fw-semi); color: var(--muted); }
  .pj-locl .pj-locname { grid-column: 1; }
  .pj-locl .pj-locact { grid-column: 2; grid-row: 1; }
  .pj-locl.compact .pj-locname { grid-column: 1 / -1; }
}

/* ---- Field › Crew Day (3.0, project-tabs.js): the day's controls, the map, the walk-rounds, person by person */
.pj-cdnav { display: flex; align-items: center; gap: 6px; }
.pj-cdnav .input { width: auto; }
.pj-cdset { flex: 1 1 100%; display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 18px; }
.pj-cdfence { min-width: 240px; flex: 0 1 320px; }
.pj-cdfrom { display: flex; flex-direction: column; gap: 2px; padding-bottom: 8px; }
.pj-cdset > .pj-pichk { min-height: var(--ctl); }
.pj-cdmap { height: 380px; border-radius: var(--r-l); overflow: hidden; border: 1px solid var(--hair); margin-bottom: 8px; background: var(--well); isolation: isolate; }   /* Leaflet's controls stay under pop-ups (2.x had it) */
.pj-cdppl { list-style: none; margin: 0; padding: 0; display: grid; }
.pj-cdp { padding: 12px 0; border-top: 1px solid var(--hair); display: grid; gap: 6px; }
.pj-cdp:first-child { border-top: 0; padding-top: 2px; }
.pj-cdp p { margin: 0; }
.pj-cdph { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 12px; }
.pj-cdchips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.pj-cdstops { list-style: none; margin: 0; padding: 0 0 0 10px; border-left: 2px solid var(--hair-2); display: grid; gap: 4px; }
.pj-cdstops li { display: grid; grid-template-columns: 64px minmax(0, 1fr) auto; gap: 8px; align-items: baseline; font-size: 13px; }
.pj-cdstops li.warn { color: var(--warn); }
@media (max-width: 1180px), (pointer: coarse) { .pj-cdnav .btn.icon { width: var(--tap); height: var(--tap); } }
@media (max-width: 1180px) { .pj-cdmap { height: 320px; } }
@media (max-width: 640px) { .pj-cdnav { width: 100%; } .pj-cdnav .input { flex: 1 1 auto; } .pj-cdfence { flex: 1 1 100%; } .pj-cdmap { height: 280px; } }

/* ---- Money › Forecast (3.0) */
.pj-fcset { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px 12px; align-items: end; margin-bottom: 10px; }
.pj-fct .input { height: 34px; max-width: 180px; margin-left: auto; }
.pj-fct tfoot td { border-top: 1px solid var(--hair); }
.pj-fcdiff { font-weight: var(--fw-bold); }
.pj-fcdiff.ok { color: var(--ok); } .pj-fcdiff.warn { color: var(--warn); } .pj-fcdiff.bad { color: var(--bad); }
@media (max-width: 980px) { .pj-fcset { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 640px) { .pj-fc .phone-cards table.t.pj-fct { display: table; } .pj-fct .input { height: var(--tap); } }   /* two columns fit a phone: the month table stays a table */

/* ---- Paperwork › Badging & Certs (3.0) */
.pj-accbadge { align-items: flex-start; margin-bottom: 14px; }
.pj-accbadge input { margin-top: 3px; }
.pj-accbadge > span { display: grid; gap: 2px; }
.pj-accreq { border: 0; margin: 0 0 10px; padding: 0; display: grid; gap: 8px; }
.pj-accreq legend { padding: 0; margin-bottom: 8px; }
.pj-acclist { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 10px 18px; }
.pj-accexp .input { max-width: 170px; height: 34px; }
.pj-accadd { display: grid; grid-template-columns: minmax(0, 1fr) 200px auto; gap: 10px 12px; align-items: end; border-top: 1px solid var(--hair); }
@media (max-width: 640px) { .pj-accadd { grid-template-columns: minmax(0, 1fr); } .pj-accadd .btn { justify-content: center; } }

/* ---- Paperwork › Checklist (3.0) */
.pj-pwna { margin-top: 12px; }
.pj-pwt .pj-pwdue .input { max-width: 170px; height: 34px; }
.pj-pwby { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.pj-pwrow { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; }
.pj-pw .cards .card { display: grid; gap: 8px; margin: 0; }
.pj-pwadd { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; border-top: 1px solid var(--hair); }

/* ---- Paperwork › Site & Contacts (3.0) */
.pj-si .cards .card { display: grid; gap: 6px; margin: 0; }
.pj-span2 { grid-column: 1 / -1; }
.pj-sithird { align-items: flex-start; margin-bottom: 12px; }
.pj-sithird input { margin-top: 3px; }
.pj-sithird > span { display: grid; gap: 2px; }
.pj-siadd .pj-form { margin-bottom: 12px; }
.pj-sipick { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: start; }
.pj-ingrp { padding-top: 10px; margin-top: 10px; border-top: 1px solid var(--hair); }
.pj-ingrp:first-of-type { border-top: 0; margin-top: 0; padding-top: 0; }
.pj-ingrp h3 { margin: 0 0 8px; font-size: 12px; font-weight: var(--fw-bold); color: var(--muted); text-transform: none; }
.pj-infields { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px 14px; }
.pj-infields .field { min-width: 0; }
.pj-ynu { align-self: flex-start; }
.pj-gear { display: grid; gap: 6px; padding: 6px 0; }
.pj-gear .pj-pichk { align-items: flex-start; }
.pj-gear .pj-pichk input { margin-top: 3px; }
.pj-gear .pj-pichk > span { display: grid; gap: 1px; }
.pj-gearf { display: grid; grid-template-columns: 90px minmax(0, 1fr); gap: 8px; padding-left: 24px; }
.pj-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; }
.pj-dump { margin-bottom: 8px; }
.pj-water { margin-bottom: 8px; }
.pj-water:last-child { margin-bottom: 0; }
:is(#pjWater, #pjDump) > .flags { margin-bottom: 10px; }   /* Site & Contacts › Water (2.4.0): the picker and the hydrant / meter / permit words, two across */
@media (max-width: 640px) { .pj-water { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 1180px) { .pj-infields { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 1180px), (pointer: coarse) { .pj-ynu button { height: var(--tap); } }
@media (max-width: 640px) { .pj-infields { grid-template-columns: minmax(0, 1fr); } .pj-sipick { grid-template-columns: minmax(0, 1fr); } .pj-sipick .btn { justify-content: center; } .pj-pwadd { grid-template-columns: minmax(0, 1fr) auto; } }
.pj-gearcols { columns: 3 240px; column-gap: 24px; }
.pj-gearcat { break-inside: avoid; padding: 8px 0 6px; }
.pj-gearcat h3 { margin: 0 0 4px; font-size: 12px; font-weight: var(--fw-bold); color: var(--muted); }
.pj-ctform { grid-template-columns: repeat(4, minmax(0, 1fr)); align-items: end; }
.pj-ctform .wide { grid-column: span 2; }
.pj-ctform #ct_companyRow { grid-column: 1 / -1; }
.pj-siadd .pj-ctform .pj-pichk { min-height: var(--ctl); }
.pj-infields .pj-span2 { grid-column: span 2; }
#siStart { max-width: 200px; }
@media (max-width: 1180px) { .pj-ctform { grid-template-columns: repeat(2, minmax(0, 1fr)); } .pj-ctform .wide { grid-column: 1 / -1; } }
@media (max-width: 640px) { .pj-ctform { grid-template-columns: minmax(0, 1fr); } .pj-infields .pj-span2 { grid-column: auto; } .pj-gearcols { columns: 1; } }

/* ---- the job's own area on a map (geofence-editor.js, opened from Field › Crew Day; 3.0) */
.modal.pj-gf { max-width: 980px; display: grid; gap: 10px; }
.pj-gf h2 { margin: 0; font-size: var(--fs-xl); }
.pj-gf p { margin: 0; }
.pj-gf-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.pj-gf-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.pj-gf-tools .seg button { display: inline-flex; align-items: center; gap: 6px; }
.pj-gf-hint { font-size: 13px; color: var(--ink-2); background: var(--well); border-radius: var(--r-m); padding: 9px 12px; }
.pj-gf-map { height: 440px; border-radius: var(--r-l); overflow: hidden; border: 1px solid var(--hair); background: var(--well); cursor: crosshair; position: relative; z-index: 0; isolation: isolate; }
.pj-gf-list { display: grid; gap: 6px; }
.pj-gf-list:empty { display: none; }
.pj-gf-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 10px; align-items: center; min-height: 48px; padding: 6px 10px; border: 1px solid var(--hair); border-radius: var(--r-m); font-size: 13.5px; }
.pj-gf-what { display: flex; align-items: center; gap: 6px; white-space: nowrap; min-width: 0; }
.pj-gf-what .input { width: 84px; height: 34px; }
.pj-gf-num { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--ink); color: var(--on-ink); font-size: 11.5px; font-weight: var(--fw-x); }
.pj-gf-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 12px; }
.pj-gf-btns { display: flex; gap: 8px; margin-left: auto; }
.pj-gf-vtxw { background: none; border: none; }
.pj-gf-vtx { position: relative; display: block; width: 14px; height: 14px; border-radius: 50%; background: #fff; border: 3px solid #16447e; box-shadow: 0 1px 4px rgba(15,30,60,.4); }
.pj-gf-vtx::after { content: ''; position: absolute; inset: -15px; border-radius: 50%; }   /* a 44px grab pad around a 14px dot */
.pj-gf-vtx.first { border-color: #eb6834; }
@media (max-width: 760px) {
  .pj-gf-map { height: 320px; }
  .pj-gf-tools { display: grid; grid-template-columns: 1fr 1fr; }
  .pj-gf-tools .seg { grid-column: 1 / -1; display: grid; grid-template-columns: 1fr 1fr; }
  .pj-gf-tools .btn { justify-content: center; height: var(--tap); }
  .pj-gf-tools .btn.danger { grid-column: 1 / -1; }
  .pj-gf-btns { width: 100%; } .pj-gf-btns .btn { flex: 1 1 0; justify-content: center; }
}

/* ---- design review 10/22 (projtabs): the 2.x .field margin inside the kit's grids, stacks with an empty slot, touch reach,
   multi-line ticks, the take-off grid's first two columns held while it scrolls sideways */
.pj .field, .pj-modal .field { margin-bottom: 0; }
.pj-stack > :empty { display: none; }   /* an empty SewerAI panel slot doubled the gap above AIMS Trace */
.pj-pichk.pj-accbadge, .pj-pichk.pj-sithird, .pj-gear .pj-pichk { align-items: flex-start; }
.pj-dump.one .field { grid-column: 1 / -1; max-width: 320px; }
.pj-narrow .input { max-width: 200px; }
.pj-tot th:nth-child(-n+2), .pj-tot td:nth-child(-n+2) { position: sticky; z-index: 1; background: var(--surface); }
.pj-tot th:first-child, .pj-tot td:first-child { left: 0; min-width: 64px; width: 64px; }
.pj-tot th:nth-child(2), .pj-tot td:nth-child(2) { left: 64px; box-shadow: 1px 0 0 var(--hair); }
.pj-tot tr.pj-todone-row td:nth-child(-n+2) { background: color-mix(in srgb, var(--ok) 7%, var(--surface)); }
@media (max-width: 1180px), (pointer: coarse) {
  .pj-pichk { min-height: var(--tap); }
  .pj-minitems summary { min-height: var(--tap); display: flex; align-items: center; }
  .pj-cdstops .btn.sm { height: var(--tap); }
}
@media (max-width: 640px) {
  .pj-piset { grid-auto-flow: row dense; }
  .pj-piset > .field:has(select) { grid-column: 1 / -1; }   /* a picker's words need the row: "Auto: Pipe run" was cut at 375 */
  .pj-minform { grid-template-columns: repeat(3, minmax(0, 1fr)); }   /* Minimum, Unit and Rate on one row */
}

/* ---- Ignite's own pop-up helper (3.0, w9ignite): app.js promptModal, inside the app's .modal (confirmModal is the kit's sxConfirm since w10retire) */
.modal:has(> .pj-prompt) { max-width: 480px; }
.pj-reqd { margin: 0; font-size: 12.5px; font-weight: var(--fw-semi); color: var(--bad); }

/* ---- Schedule dialogs (3.0, w9ignite sdlg): app.js — the entry (Add/Edit Schedule Entry), Copy to other days, Mark
   cancelled, Reschedule, Already on the schedule, Double-booked, Paperwork isn't complete, Schedule a Project, the day
   board's run and "this day or the whole job", the week board's run question and "which days is X on", two jobs a day
   and the second job. All inside the app's .modal as .pj-modal pop-ups; every class here starts with scd-. */
.modal:has(> .scd-entry) { max-width: 1040px; }
.modal:has(> .scd-run) { max-width: 780px; }
.modal:has(> .scd-ask) { max-width: 480px; }
.modal:has(> .scd-pd), .modal:has(> .scd-pw) { max-width: 560px; }
.pj-modal h2 > .i { margin-right: 8px; vertical-align: -2px; }
.scd-ask h2 > .i { color: var(--warn); }
.scd-pw h2 > .i { color: var(--bad); }
.pj-modal .scd-h { margin: 6px 0 0; font-size: 12px; font-weight: var(--fw-bold); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.scd-col > .scd-h:first-child { margin-top: 0; }
:is(.scd-col, .pj-modal) > .seg { justify-self: start; }
.scd-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 28px; align-items: start; }
.scd-col { display: grid; gap: 12px; min-width: 0; align-content: start; }
.scd-inline { display: flex; gap: 8px; min-width: 0; }
.scd-inline .input { flex: 1 1 auto; min-width: 0; }
.scd-inline .btn { flex: none; }
.scd-checks { display: flex; flex-wrap: wrap; gap: 6px 16px; }
.pj-modal .field .pj-pichk, .scd-checks .pj-pichk { font-size: 13px; font-weight: var(--fw-med); color: var(--ink); }
.scd-tickrow { align-items: flex-start; }
.scd-tickrow > input { margin-top: 2px; }
.scd-times { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px 12px; }
.scd-depart { display: grid; gap: 5px; }
.scd-depart > .select-wrap { max-width: 440px; }
.scd-money { max-width: 200px; }
.scd-plan { display: grid; gap: 6px; }
.scd-plan > .hint, .scd-col > .hint, .pj-modal > .hint { margin: 0; }
.scd-picker { max-height: 180px; overflow-y: auto; padding: 4px 12px; border: 1px solid var(--hair-2); border-radius: var(--r-m); background: var(--glass-a); }
.scd-line { display: flex; align-items: center; gap: 8px; padding: 6px 0; font-size: 13px; color: var(--ink); cursor: pointer; }
.scd-item-l { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.scd-item .input { width: 92px; flex: 0 0 92px; height: 32px; }
.scd-item-u { flex: 0 0 38px; }
.scd-total { margin: 0; font-size: 13px; color: var(--muted); }
.scd-total b { color: var(--ink); font-variant-numeric: tabular-nums; }
/* the tick list: a find box once it is long, "All branches" when another yard's units are hidden, a scroll box of rows */
.scd-tl { border: 1px solid var(--hair-2); border-radius: var(--r-m); background: var(--glass-a); overflow: hidden; min-width: 0; }
.scd-tl-all { display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 8px 12px; border-bottom: 1px solid var(--hair); font-size: 13px; font-weight: var(--fw-semi); color: var(--ink); cursor: pointer; }
.scd-tl .scd-tl-find { display: block; width: 100%; height: 38px; min-height: 0; margin: 0; padding: 0 12px; border: 0; border-bottom: 1px solid var(--hair); border-radius: 0; background: transparent; box-shadow: none; font-size: 13px; color: var(--ink); }
.scd-tl .scd-tl-find:focus { outline: none; background: var(--well); }
.scd-tl-rows { max-height: var(--h, 196px); overflow-y: auto; padding: 4px 12px; }
.scd-tick { display: flex; align-items: center; gap: 8px; padding: 6px 0; font-size: 13px; color: var(--ink); min-width: 0; cursor: pointer; }
.scd-tick-l { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.scd-tick i { flex: 0 1 auto; font-style: normal; font-size: 11.5px; font-weight: var(--fw-semi); color: var(--warn); text-align: right; }
.scd-tl-none { margin: 6px 0; }
.scd-tl-rows:has(> .scd-tick:not([hidden])) > .scd-tl-none { display: none; }
:is(.scd-tl-all, .scd-tick, .scd-line, .scd-dayrow) input[type="checkbox"] { width: 16px; height: 16px; min-height: 0; margin: 0; flex: none; accent-color: var(--ink); }
/* the day squares: a square a day, rows of seven; the tick box covers the square, a ticked square fills in */
.scd-weeks { display: grid; gap: 6px; grid-auto-rows: 1fr; }   /* every row as tall as the one with a month name in it */
.scd-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.scd-day { position: relative; display: grid; justify-items: center; align-content: start; gap: 1px; min-width: 0; min-height: 50px; padding: 7px 2px 6px;
  border: 1px solid var(--hair-2); border-radius: 11px; background: var(--glass-a); font-size: 11px; font-weight: var(--fw-bold); color: var(--muted);
  cursor: pointer; user-select: none; transition: background var(--t-quick), border-color var(--t-quick), color var(--t-quick); }
.scd-day b { font-size: 15px; line-height: 1.15; color: var(--ink); }
.scd-day i { font-style: normal; font-size: 9.5px; font-weight: var(--fw-bold); letter-spacing: .02em; color: var(--muted); }
.scd-day input { position: absolute; inset: 0; width: 100%; height: 100%; min-height: 0; margin: 0; opacity: 0; cursor: pointer; }
.scd-day.wknd { background: var(--well); }
.scd-day:hover:not(.own) { border-color: var(--ink-2); }
.scd-day:has(input:checked) { background: var(--ink); border-color: var(--ink); color: var(--on-ink); }
.scd-day:has(input:checked) :is(b, i) { color: var(--on-ink); }
.scd-day:has(input:focus-visible) { outline: 2px solid var(--ink); outline-offset: 2px; }
.scd-day.own { opacity: .5; border-style: dashed; cursor: default; }
.scd-day.own input { cursor: default; }
.scd-dow .scd-day { min-height: 44px; align-content: center; }
/* "which days is X on": one row a day — the tick, the day, its hours, what else they are on */
.scd-dayrows { display: grid; gap: 6px; }
.scd-dayrow { display: grid; grid-template-columns: auto 84px 150px minmax(0, 1fr); align-items: center; gap: 10px; min-height: 44px; padding: 8px 12px;
  border: 1px solid var(--hair-2); border-radius: var(--r-m); background: var(--glass-a); font-size: 12.5px; cursor: pointer; }
.scd-dayrow:has(input:checked:not(:disabled)) { border-color: var(--ink); background: var(--well); }
.scd-dayrow.has { opacity: .6; cursor: default; }
.scd-dayrow i { font-style: normal; font-size: 11.5px; color: var(--muted); }
.scd-dayrow.clash i { color: var(--warn); font-weight: var(--fw-semi); }
/* the run question */
.scd-runtools { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.scd-sep { width: 1px; height: 20px; margin: 0 2px; background: var(--hair-2); }
.scd-count { margin-left: auto; font-size: 12px; font-weight: var(--fw-semi); color: var(--muted); }
.scd-more { padding-top: 10px; border-top: 1px solid var(--hair); }
.scd-more > summary { cursor: pointer; font-size: 13px; min-height: 32px; }
.scd-more[open] > summary { margin-bottom: 10px; }
.scd-same { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0 0 12px; }
/* notes, boxes and lists */
.scd-note { margin: 6px 0 0; padding: 7px 10px; border-radius: var(--r-m); font-size: 12.5px; }
.scd-note.warn { background: var(--warn-bg); color: var(--warn); }
.scd-note.ok { padding: 0; color: var(--ok); font-weight: var(--fw-semi); }
.scd-box { padding: 10px 12px; border: 1px solid var(--hair); border-radius: var(--r-m); background: var(--well); }
.scd-box .hint { margin: 0; }
.scd-list { display: grid; gap: 3px; margin: 0; padding-left: 18px; max-height: 220px; overflow-y: auto; font-size: 13px; }
/* the double-booked notice (2.4.0): who clashes, each with "Remove from <the other job>" beside it; nothing asked */
.scd-ccl { list-style: none; padding-left: 0; gap: 0; max-height: 320px; }
.scd-ccl .scd-cc { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 6px 12px; padding: 8px 0; border-top: 1px solid var(--hair); }
.scd-ccl .scd-cc:first-child { border-top: 0; }
.scd-ccl .scd-cc > span:first-child { flex: 1 1 220px; min-width: 0; }
.scd-ccl .scd-cc .btn { max-width: 100%; height: auto; min-height: var(--ctl); padding-block: 6px; white-space: normal; text-align: left; }
.scd-pre { white-space: pre-line; }
.scd-ok { color: var(--ok); font-weight: var(--fw-semi); }
.scd-warn { color: var(--warn); font-weight: var(--fw-semi); }
.scd-bad { margin: 0; color: var(--bad); font-weight: var(--fw-semi); }
.scd-sum { display: grid; gap: 8px; padding: 12px 14px; border-radius: var(--r-l); background: var(--well); font-size: 13px; }
.scd-sum p { margin: 0; }
.scd-sumtop { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 10px; }
.scd-chips { display: flex; flex-wrap: wrap; gap: 6px; }
/* two jobs a day: the drive strip (on both boards and in the second-job pop-up) and the "1 of 2" tag */
.scd-drive { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 2px 8px; margin: 4px 0; padding: 4px 8px;
  border: 1px dashed var(--hair-2); border-radius: 8px; background: var(--well); font-size: 11.5px; color: var(--muted); }
.scd-drive.warn { border-color: var(--warn-line); background: var(--warn-bg); color: var(--warn); }
.scd-drive b { font-weight: var(--fw-semi); }
.pj-modal .scd-drive { margin: 0; padding: 8px 12px; font-size: 13px; }
.scd-tag { display: inline-block; margin: 0 6px 3px 0; padding: 1px 7px; border-radius: var(--r-pill); background: var(--info-bg); color: var(--info); font-size: 10.5px; font-weight: var(--fw-x); letter-spacing: .02em; white-space: nowrap; }
/* on a board card: why a double-booking was allowed; a borrowed hand (info) or one of ours lent out (warn) */
.scd-why { display: block; margin-top: 3px; font-size: 11px; color: var(--muted); overflow-wrap: anywhere; }
.scd-loan { display: inline-block; justify-self: start; margin-top: 2px; padding: 1px 7px; border-radius: var(--r-pill); background: var(--info-bg); color: var(--info);
  font-size: 10.5px; font-weight: var(--fw-semi); line-height: 1.5; white-space: normal; }
.scd-loan.out { background: var(--warn-bg); color: var(--warn); }
/* the ⇄ beside a name on either board: this hand is borrowed or lent out today, the reason in its title (was styles.css .loan-mark) */
.scd-loanmark { color: var(--info); font-weight: 700; cursor: help; }
@media (max-width: 1180px), (pointer: coarse) {
  .scd-tick, .scd-line { min-height: var(--tap); padding: 4px 0; }
  .scd-item .input { height: var(--tap); }
  .scd-more > summary { min-height: var(--tap); display: flex; align-items: center; gap: 6px; }
}
@media (max-width: 900px) {
  .scd-cols { grid-template-columns: minmax(0, 1fr); }
  /* 2.x makes every phone tick box 24px wide (!important); the lists' boxes follow it, square */
  :is(.scd-tl-all, .scd-tick, .scd-line, .scd-dayrow) input[type="checkbox"] { height: 24px; flex-basis: 24px; }
}
@media (max-width: 640px) {
  .scd-times { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .scd-inline { flex-wrap: wrap; } .scd-inline .btn { flex: 1 1 100%; justify-content: center; }
  .scd-week { gap: 4px; }
  .scd-day { padding: 6px 0 5px; min-height: 46px; font-size: 10px; }
  .scd-day b { font-size: 13px; }
  .scd-dayrow { grid-template-columns: auto minmax(0, 1fr); gap: 2px 10px; }
  .scd-dayrow > :nth-child(n+3) { grid-column: 2; }
  .scd-count { flex-basis: 100%; margin-left: 0; }
  .scd-sep { display: none; }
  .scd-money { max-width: none; }
}

/* ---- Schedule views (3.0, w9ignite sview): app.js — the mini calendar, the Month grid, the shop and on-call bars and
   the on-call pop-ups, the off-board tags on every view (on call, time off, the shop), Push, Time Off and its pop-ups, and
   the Parking lot. Built from the kit's own pieces (sc-bar, sc-note, strip, chip, status, table.t, phone-cards, flags,
   .pj-modal); every class here starts with scv-. */
.scv-who { display: inline-flex; align-items: center; gap: 6px; min-width: 0; color: inherit; font-weight: var(--fw-semi); text-decoration: none; vertical-align: middle; }
.scv-who > span:last-child { overflow-wrap: anywhere; }
a.scv-who:hover > span:last-child { text-decoration: underline; }
.scv-warn { color: var(--warn); font-weight: var(--fw-semi); }
.scv-loaded { font-size: .62em; font-weight: var(--fw-semi); letter-spacing: 0; color: var(--muted); white-space: nowrap; }
.scv-night { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; font-weight: var(--fw-semi); color: var(--info); white-space: nowrap; }
.scv-nowrap { white-space: nowrap; }
/* the mini calendar beside the four figures: the month, Monday first, today ringed, the days on screen shaded, a dot on
   days with work; on a phone it folds to the current week */
.scv-mc { width: 260px; padding: 10px 12px 12px; display: grid; gap: 4px; align-content: start; min-width: 0; }
.scv-mch { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.scv-mch b { font-size: 13px; font-weight: var(--fw-bold); }
.scv-mcnav { all: unset; width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; color: var(--muted); cursor: pointer; }
.scv-mcnav:hover { background: var(--well); color: var(--ink); }
.scv-mcnav:focus-visible, .scv-mcd:focus-visible, .scv-mct:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.scv-mcg { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px 0; text-align: center; }
.scv-mcwk { display: contents; }
.scv-mcwd { font-size: 10.5px; font-weight: var(--fw-bold); color: var(--muted); padding: 2px 0 3px; }
.scv-mcd { all: unset; position: relative; height: 26px; border-radius: 7px; font-size: 12px; font-weight: var(--fw-semi); color: var(--ink); font-variant-numeric: tabular-nums; text-align: center; cursor: pointer; }
.scv-mcd:hover { background: var(--well); }
.scv-mcd.out { color: var(--faint); }
.scv-mcd.inview { background: var(--well); border-radius: 0; }
.scv-mcd.today { font-weight: var(--fw-x); }
.scv-mcd.today::after { content: ""; position: absolute; left: 50%; top: 50%; width: 24px; height: 24px; transform: translate(-50%, -50%); border-radius: 50%;
  box-shadow: 0 0 0 1.5px var(--accent); pointer-events: none; }   /* the ring round today */
.scv-mcd.work::before { content: ""; position: absolute; left: 50%; bottom: 1px; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: var(--accent); }
.scv-mct { display: none; }
@media (max-width: 1180px) { .scv-mc { width: auto; } }
@media (min-width: 641px) and (max-width: 1180px) { .sc-top:has(> .scv-mc) { grid-template-columns: minmax(0, 1fr) 248px; } }   /* a tablet keeps the month beside the four figures */
@media (max-width: 640px) { .sc-top > .scv-mc { order: -1; } }   /* a phone: the week strip of the calendar first */
@media (max-width: 640px) {
  .scv-mcd { height: var(--tap); font-size: 14px; }
  .scv-mcd.today::after { width: 34px; height: 34px; }
  .scv-mcnav { width: var(--tap); height: var(--tap); }
  .scv-mcg.folded .scv-mcwk:not(.cur) { display: none; }
  .scv-mct { all: unset; display: flex; align-items: center; justify-content: center; gap: 6px; min-height: var(--tap); font-size: 13px; font-weight: var(--fw-semi); color: var(--accent-ink); cursor: pointer; }
}
/* a finger at any width (w22touch, 10/27): seven days side by side leave no room for a reach (a day was 33×26 on an iPad
   and 34 across at 1366), so a touch screen gets the phone's calendar — 44px days and arrows, folded to the current week
   with "Show the month" under it — in a column seven fingertips wide. A mouse at any width keeps the month as it was. */
@media (pointer: coarse) {
  .scv-mcd { height: var(--tap); font-size: 14px; }
  .scv-mcd.today::after { width: 34px; height: 34px; }
  .scv-mcnav { width: var(--tap); height: var(--tap); }
  .scv-mcg.folded .scv-mcwk:not(.cur) { display: none; }
  .scv-mct { all: unset; display: flex; align-items: center; justify-content: center; gap: 6px; min-height: var(--tap); font-size: 13px; font-weight: var(--fw-semi); color: var(--accent-ink); cursor: pointer; }
}
@media (pointer: coarse) and (min-width: 641px) {
  .scv-mc { width: calc(7 * var(--tap) + 24px); }
  .sc-top:has(> .scv-mc) { grid-template-columns: minmax(0, 1fr) calc(7 * var(--tap) + 24px); }
}
/* the shop and on-call bars (kit sc-bar): a label, who, and the bar's own buttons at its right end */
.scv-bar .lbl { display: inline-flex; align-items: center; gap: 6px; }
.scv-bar .lbl .i { color: var(--muted); }
.scv-bartext { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.scv-barend { margin-left: auto; display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.scv-oc { box-shadow: inset 3px 0 0 var(--warn), var(--shadow); }
.scv-ocp { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; }
.scv-tel { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; font-weight: var(--fw-semi); }
/* the on-call pop-ups */
.modal:has(> .scv-ocm) { max-width: 560px; }
.scv-oclist { list-style: none; margin: 0; padding: 0; display: grid; }
.scv-oclist li { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "who btn" "meta btn"; gap: 2px 12px; align-items: center; padding: 10px 0; border-top: 1px solid var(--hair); }
.scv-oclist li:first-child { border-top: 0; }
.scv-oclist .scv-who { grid-area: who; }
.scv-ocmeta { grid-area: meta; display: flex; flex-wrap: wrap; gap: 2px 10px; font-size: 12.5px; }
.scv-oclist .btn { grid-area: btn; }
/* off the board: on call, time off and the shop on a day — dashed, because they are not jobs */
.scv-off { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.scv-off.card { flex-direction: row; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.scv-offi { all: unset; box-sizing: border-box; display: grid; gap: 1px; min-width: 0; padding: 5px 8px; border-radius: 10px; border: 1.5px dashed var(--hair-2);
  background: var(--glass-a); font-size: 11.5px; color: var(--ink-2); cursor: pointer; text-decoration: none; }
.scv-offi b { font-size: 10.5px; font-weight: var(--fw-x); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.scv-offi span { overflow-wrap: anywhere; }
.scv-offi:hover { background: var(--well); text-decoration: none; }
.scv-offi:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.scv-offi.oncall { border-color: var(--warn-line); } .scv-offi.oncall b { color: var(--warn); }
.scv-offi.pto { border-color: var(--info-line); } .scv-offi.pto b { color: var(--info); }
.scv-off.card .scv-offi { padding: 8px 12px; font-size: 13px; }
.scv-off.mini { gap: 3px; }
.scv-off.mini .scv-offi { display: flex; align-items: baseline; gap: 4px; padding: 2px 6px; border-radius: 7px; font-size: 11px; white-space: nowrap; overflow: hidden; }
.scv-off.mini .scv-offi b { font-size: 10px; letter-spacing: .04em; }
/* the Month grid: a square a day, Monday first */
.scv-month { padding: 10px; display: grid; gap: 6px; }
.scv-mhead, .scv-mgrid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.scv-mhead span { font-size: 11px; font-weight: var(--fw-bold); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); text-align: center; }
.scv-mday { display: flex; flex-direction: column; gap: 4px; min-width: 0; min-height: 108px; padding: 6px; border-radius: 12px; background: var(--well); }
.scv-mday.wknd { background: transparent; box-shadow: inset 0 0 0 1px var(--hair); }
.scv-mday.today { box-shadow: inset 0 0 0 2px var(--accent); }
.scv-mday.dim > * { opacity: .5; }
.scv-mdh { display: flex; align-items: center; justify-content: space-between; gap: 4px; }
.scv-mdh a { display: inline-flex; align-items: baseline; gap: 5px; padding: 2px 4px; border-radius: 7px; color: var(--ink); text-decoration: none; }
.scv-mdh a b { font-size: 13.5px; font-weight: var(--fw-x); font-variant-numeric: tabular-nums; }
.scv-mdh a span { font-size: 10.5px; font-weight: var(--fw-semi); color: var(--muted); display: none; }
.scv-mdh a:hover { background: var(--hair); text-decoration: none; }
.scv-madd { all: unset; width: 26px; height: 26px; border-radius: 8px; display: grid; place-items: center; color: var(--muted); cursor: pointer; }
.scv-madd:hover { background: var(--hair); color: var(--ink); }
.scv-madd:focus-visible, .scv-ment:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.scv-ment { all: unset; box-sizing: border-box; display: block; width: 100%; padding: 3px 7px; border-radius: 7px; background: var(--glass-a); border: 1px solid var(--glass-edge);
  box-shadow: inset 3px 0 0 var(--ok); font-size: 11.5px; font-weight: var(--fw-semi); color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; }
.scv-ment i { font-style: normal; font-weight: var(--fw-med); color: var(--muted); margin-left: 5px; }
.scv-ment:hover { background: var(--surface); }
.scv-ment.part { box-shadow: inset 3px 0 0 var(--warn); }
.scv-ment.none { box-shadow: none; border: 1px dashed var(--bad-line); background: var(--bad-bg); }
.scv-ment.cancelled { box-shadow: none; border-style: dashed; color: var(--muted); text-decoration: line-through; }
.scv-mmore { font-size: 11.5px; font-weight: var(--fw-semi); color: var(--muted); padding: 0 4px; }
.scv-mnote { margin: 0; }
@media (max-width: 900px) { .scv-mday { min-height: 84px; padding: 4px; } .scv-mhead, .scv-mgrid { gap: 4px; } }
@media (max-width: 640px) {   /* a list of the month's own days */
  .scv-mhead { display: none; }
  .scv-mgrid { grid-template-columns: minmax(0, 1fr); }
  .scv-mday { min-height: 0; padding: 8px 10px; }
  .scv-mday.dim { display: none; }
  .scv-mdh a { min-height: var(--tap); align-items: center; }
  .scv-mdh a span { display: inline; }
  .scv-madd { width: var(--tap); height: var(--tap); }
  .scv-ment { padding: 0 10px; min-height: 36px; display: flex; align-items: center; font-size: 13px; }
  .scv-mmore { min-height: var(--tap); display: flex; align-items: center; }
}
.scv-daytools .hint { flex: 1 1 260px; }
/* Push, Time Off, the Parking lot: a panel's head (its title and a word), its list, its cards */
.scv-lede { margin: 0; max-width: 110ch; }
.scv-phead { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; }
.scv-phead h3 { margin: 0; font-size: var(--fs-l); font-weight: var(--fw-x); }
:is(.scv-plog, .scv-pto, .scv-park) > .scv-phead { padding: 14px 16px 6px; }
.scv-pempty { margin: 0; padding: 4px 16px 16px; }
.scv-pcard { display: grid; gap: 6px; margin: 0; }   /* 2.x gives every .card a 16px bottom margin; the kit's .cards list spaces them */
.scv-pcard a.name { font-weight: var(--fw-bold); color: var(--ink); }
@media (min-width: 901px) and (pointer: fine) { :is(.scv-asked, .scv-pto) .status { min-height: 0; } }   /* 2.x's select { min-height: 36px } stretched the kit's 28px status; phones keep their 44px reach */
.scv-pcardtop { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 10px; }
.scv-ppick { display: grid; gap: 12px; }
.scv-pdates { display: grid; grid-template-columns: repeat(2, minmax(0, 220px)); gap: 10px 12px; }
.scv-pauto { display: grid; gap: 8px; padding-top: 12px; border-top: 1px solid var(--hair); }
.scv-pauto summary { cursor: pointer; font-size: 13px; font-weight: var(--fw-semi); color: var(--accent-ink); }
.scv-pauto p { margin: 0; }
.scv-pautolist { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 8px 16px; }
.scv-pautorow { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); align-items: center; gap: 8px; font-size: 13px; }
.scv-plist { display: grid; gap: 10px; }
.scv-pday { margin: 8px 0 0; font-size: 12px; font-weight: var(--fw-bold); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.scv-prows { list-style: none; margin: 0; padding: 0; display: grid; }
.scv-prow { display: grid; grid-template-columns: minmax(200px, 1fr) minmax(0, 2fr); gap: 4px 16px; padding: 10px 0; border-top: 1px solid var(--hair); font-size: 13px; }
.scv-prow:first-child { border-top: 0; }
.scv-prow > .hint, .scv-prow > .scv-ptext, .scv-prow > .scv-pbody { grid-column: 2; }
.scv-ppreview { display: grid; gap: 8px; margin: 12px 0; padding: 12px 0; border-block: 1px solid var(--hair); }
@media (max-width: 560px) { .scv-ppreview .scv-phead .select-wrap { order: 3; flex: 1 1 100%; } .scv-ppreview .scv-phead .select { width: 100%; } }
.scv-ppreview .scv-phead { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.scv-ppreview .scv-phead h3 { margin: 0; margin-right: auto; }
.scv-pnot { display: grid; gap: 8px; padding-top: 10px; border-top: 1px solid var(--hair); }
.scv-pnot > summary { cursor: pointer; display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: var(--fw-bold); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.scv-pnot[open] > summary { margin-bottom: 8px; }
.scv-pnotwhy { display: grid; gap: 6px; }
.scv-pnotwhy + .scv-pnotwhy { margin-top: 10px; }
.scv-pnotreason { margin: 0; font-size: 13px; font-weight: var(--fw-bold); }
.scv-pnotreason .hint { font-weight: var(--fw-reg, 400); }
.scv-pnames { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 6px 16px; }
.scv-pnames > li { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; min-width: 0; font-size: 13px; }
.scv-pbody { margin: 0; padding: 10px 12px; border-radius: var(--r-m); background: var(--well); font: 12.5px/1.5 var(--font); white-space: pre-wrap; overflow-wrap: anywhere; }
.scv-pwho { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.scv-pjobs { display: grid; gap: 2px; }
.scv-ptext summary { cursor: pointer; font-size: 12.5px; font-weight: var(--fw-semi); color: var(--accent-ink); }
.scv-ptext pre { margin: 6px 0 0; padding: 10px 12px; border-radius: var(--r-m); background: var(--well); font: 12.5px/1.5 var(--font); white-space: pre-wrap; overflow-wrap: anywhere; }
/* Time Off */
.scv-ptohead { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 10px 16px; }
.scv-ptohead .hint { margin: 0; flex: 1 1 420px; max-width: 110ch; }
.scv-asked { display: grid; gap: 6px; box-shadow: inset 3px 0 0 var(--warn), var(--shadow); }
.scv-asklist { list-style: none; margin: 0; padding: 0; display: grid; }
.scv-asklist > li { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 16px; padding: 10px 0; border-top: 1px solid var(--hair); }
.scv-asklist > li:first-child { border-top: 0; }   /* direct children only: an ask's own flags list (w17-ask-reasons) is a list too */
.scv-askwho { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 10px; min-width: 0; flex: 1 1 320px; font-size: 13px; }
.scv-asknote { flex: 1 1 100%; font-size: 13px; color: var(--ink-2); font-style: italic; }
.scv-asknone { flex: 1 1 100%; font-size: 12.5px; color: var(--muted); }
/* the Paid/Unpaid pick keeps one width, so every ask's column and buttons line up row to row (design review, wave 18) */
.scv-askacts > .select-wrap { flex: none; width: 96px; }
.scv-askacts > .select-wrap > select { width: 100%; }
/* w17-ask-reasons: the numbers beside an ask — a compact flags list under the person, the full width of their column */
.scv-askwho > .ask-flags, .scv-askwho > .ask-facts { flex: 1 1 100%; margin: 4px 0 0; }
.ask-flags > li { padding: 6px 10px; font-size: 12.5px; }
.scv-askacts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.modal:has(> .scv-ptom) { max-width: 560px; }
.modal:has(> .scv-ptodeny) { max-width: 480px; }
/* the Parking lot */
.scv-park { box-shadow: inset 3px 0 0 var(--info), var(--shadow); }
.scv-parkacts { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.scv-parkacts .input { width: 160px; height: 32px; }
@media (max-width: 900px) {   /* six columns with a date box and two buttons do not fit a tablet: the cards from here down */
  .scv-park > .table-wrap { display: none; }
  .scv-park .cards { display: flex; flex-direction: column; gap: 8px; }
}
@media (max-width: 1180px), (pointer: coarse) {
  .scv-offi { min-height: 32px; }
  .scv-parkacts .input { height: var(--tap); }
  .scv-ptext summary, .scv-pauto summary, .scv-pnot > summary { min-height: var(--tap); display: flex; align-items: center; }
}
@media (max-width: 760px) {
  .scv-prow { grid-template-columns: minmax(0, 1fr); }
  .scv-prow > .hint, .scv-prow > .scv-ptext, .scv-prow > .scv-pbody { grid-column: 1; }
  .scv-pautorow { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
  .scv-bar .scv-barend { margin-left: 0; width: 100%; }
  .scv-barend .btn { flex: 1 1 0; justify-content: center; }
  .scv-pdates { grid-template-columns: minmax(0, 1fr); }
  .scv-plist .actions .btn, .scv-ptohead > .btn { flex: 1 1 100%; justify-content: center; }
  .scv-askacts { width: 100%; }
  .scv-askacts .btn { flex: 1 1 0; justify-content: center; }
  .scv-parkacts .input { flex: 1 1 100%; width: auto; }
  .scv-parkacts .btn { flex: 1 1 0; justify-content: center; }
  .scv-daytools .btn { flex: 1 1 calc(50% - 4px); justify-content: center; }
  .scv-daytools .hint { flex-basis: 100%; }
  :is(.scv-plog, .scv-pto, .scv-park) > .table-wrap { display: none; }   /* the cards stand in for the table */
}

/* ---- Ignite office pieces (3.0, w9ignite office): app.js — the Shop ticket, Turned-down work and its Log, Ready to close?,
   Quick Call-In, New / Duplicate / Edit project, Mark work, the test forms and Correct a test, Notify customers, the RFI
   page and its New / Send pop-ups, Move / Send / Close out a ticket, and the 90-day crew performance panels. Pages are a
   column of glass panels; pop-ups are .pj-modal inside the app's .modal. Every class here starts with igo-. */
.igo { display: flex; flex-direction: column; gap: var(--gap); min-width: 0; }
.igo p, .igo-sec p, .pj-modal .igo-list p { margin: 0; }
.igo .field, .igo-sec .field { margin-bottom: 0; }   /* 2.x gives every .field a bottom margin; the panels' own gap spaces them */
.igo h2, .igo-sec h2 { margin: 0; font-size: var(--fs-l); font-weight: var(--fw-x); }
.igo-sec { display: grid; gap: 10px; min-width: 0; }
.igo-top { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 6px 12px; min-width: 0; }
.igo-top > h2 { margin: 0; }
.igo-grow { flex: 1 1 220px; min-width: 0; }
.igo-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-left: auto; }
.igo-btns { display: flex; flex-wrap: wrap; gap: 6px; }
.igo-list { list-style: none; margin: 0; padding: 0; display: grid; min-width: 0; }
.igo-list > li { padding: 10px 0; border-top: 1px solid var(--hair); min-width: 0; }
.igo-list > li:first-child { border-top: 0; padding-top: 0; }
.igo-list > li:last-child { padding-bottom: 0; }
.igo-pre { margin: 4px 0 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.igo-full { justify-self: start; justify-content: center; min-width: 240px; }   /* full width on touch screens (below) */
.igo-short { max-width: 240px; }
.igo-who { font-size: var(--fs-l); }
.igo-name { font-weight: var(--fw-bold); color: var(--ink); }
.igo-start { align-self: flex-start; }
.igo-stack { display: grid; gap: 6px; }
.igo-sep { padding-top: 12px; border-top: 1px solid var(--hair); }
.igo-linkrow { display: flex; gap: 8px; align-items: center; }
.igo-linkrow .input { flex: 1 1 auto; min-width: 0; }
.igo-titlerow { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.igo-callout { padding: 10px 12px; border-radius: var(--r-m); border: 1px solid var(--warn-line); background: var(--warn-bg); color: var(--ink); }
.igo-warntext, .igo-warn { color: var(--warn); font-weight: var(--fw-semi); }
.igo-bad { color: var(--bad); font-weight: var(--fw-semi); }
.igo-warn { margin-top: 4px; font-size: 12.5px; }
/* a link that does something on this screen (not a page): "+ They're not in the book", "use all of it" */
.igo-linkbtn { padding: 0; border: 0; background: none; font: inherit; font-size: 12.5px; font-weight: var(--fw-semi); color: var(--accent-ink); cursor: pointer; text-align: left; text-decoration: underline; text-underline-offset: 2px; }
.igo-linkbtn:hover { color: var(--ink); }
/* pop-ups: widths; a tick row whose words run to two lines */
.modal:has(> :is(.igo-narrow, .igo-tkco)) { max-width: 520px; }
.modal:has(> :is(.igo-co, .igo-ci2, .igo-dup)) { max-width: 780px; }
.modal:has(> :is(.igo-np, .igo-ep, .igo-nt)) { max-width: 820px; }
.igo-chk2 { align-items: flex-start; }
.igo-chk2 > input { margin-top: 2px; }
.igo-chk2 > span { display: grid; gap: 1px; min-width: 0; }
.igo-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 12px; }
.igo-form3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px 12px; }
.igo-times { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px 12px; }
.pj-modal h3.igo-h3 { margin: 6px 0 0; font-size: var(--fs-m); font-weight: var(--fw-bold); }
.pj-modal .pj-form > .field, .pj-modal .igo-pair > .field, .pj-modal .igo-form3 > .field, .pj-modal .igo-times > .field { min-width: 0; }
/* the Shop ticket: one unit a row */
.igo-unit .igo-top { align-items: center; }
/* Turned-down work: the filters in a row, figures over the table */
.igo-filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 12px; }
.igo-filters .field { flex: 0 1 180px; min-width: 0; }
.igo-filters .field:last-child { flex-basis: 260px; }
.igo .value.igo-vtext { font-size: 18px; letter-spacing: 0; line-height: 1.3; overflow-wrap: anywhere; }
.igo-card { display: grid; gap: 6px; margin: 0; }
/* Ready to close?: one job a row, its "Not yet" answers under it */
.igo-corow .igo-top { align-items: flex-start; }
.igo-colater { display: grid; gap: 10px; margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--hair-2); }
/* Quick Call-In: who called, the send-out link, and the Master Items picker on step two */
.igo-pickbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.igo-pickbar .input { flex: 1 1 240px; max-width: 320px; }
.igo-axes { display: grid; gap: 8px; }
.igo-axis { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 6px 10px; align-items: baseline; }
.igo-facets { display: flex; flex-wrap: wrap; gap: 6px; }
button.igo-facet { border: 0; cursor: pointer; font-family: inherit; height: 28px; }
button.igo-facet:hover { filter: brightness(.96); }
button.igo-facet[aria-pressed="true"] { background: var(--ink); color: var(--on-ink); }
.igo-facet em { font-style: normal; font-weight: var(--fw-bold); color: var(--muted); margin-left: 2px; }
.igo-facet[aria-pressed="true"] em { color: inherit; opacity: .8; }
.igo-scroll { max-height: 240px; overflow: auto; border: 1px solid var(--hair); border-radius: var(--r-m); }
.igo-vars { display: flex; flex-wrap: wrap; gap: 4px; }
.igo-lnf { display: grid; grid-template-columns: repeat(2, minmax(0, 150px)); gap: 8px 12px; margin-top: 6px; }
/* Duplicate: the carry-over ticks, read down two columns; a part that rides on another sits under it */
.igo-dupparts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-flow: column; grid-template-rows: repeat(var(--rows, 10), auto); gap: 6px 18px; }
.igo-dupparts .pj-pichk { padding: 4px 0; }
.igo-dupparts .igo-dep { padding-left: 24px; }
/* the test forms: Correct a test under the sheets; Pass / Fail in the pop-up */
.igo-tstrow { display: grid; grid-template-columns: 160px minmax(0, 1fr); gap: 6px 12px; align-items: baseline; padding-top: 8px; border-top: 1px solid var(--hair); }
.igo-tst .pj-form > .field:last-child:nth-child(odd) { grid-column: 1 / -1; }   /* an odd last reading spans the row: no orphan */
.igo-pfrow { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.igo-pf.pass .thumb { background: var(--ok); }
.igo-pf.fail .thumb { background: var(--bad); }
/* Notify customers: one job a row — its tick and name, who is told, when and what */
.igo-chan { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.igo-ntlist { max-height: 44vh; overflow: auto; }
.igo-ntrow { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, .9fr); gap: 4px 14px; align-items: start; font-size: 13px; }
.igo-ntrow > div { display: grid; gap: 1px; min-width: 0; }
.igo-ntrow.off { opacity: .6; grid-template-columns: minmax(0, 1fr); }
.igo-result { display: grid; gap: 8px; padding: 10px 12px; border-radius: var(--r-m); background: var(--well); border-left: 4px solid var(--hair-2); }
.igo-result.ok { border-left-color: var(--ok); } .igo-result.warn { border-left-color: var(--warn); } .igo-result.bad { border-left-color: var(--bad); }
.igo-result .chip { margin-right: 4px; }
/* the 90-day crew performance panels (perfPanels: Time › Performance and a person's profile) */
.igo-perfwhen { margin: 0; }
.igo-perf .top { min-height: 36px; align-items: flex-start; }
.igo-kvs { margin: 0; display: grid; }
.igo-kv { display: grid; grid-template-columns: 170px minmax(0, 1fr); gap: 2px 12px; padding: 8px 0; border-top: 1px solid var(--hair); }
.igo-kv:first-child { border-top: 0; padding-top: 0; }
.igo-kv dt { font-size: 12.5px; color: var(--muted); font-weight: var(--fw-semi); }
.igo-kv dd { margin: 0; min-width: 0; }
.igo-kvs + .hint { margin-top: 10px; }
@media (max-width: 1180px), (pointer: coarse) {
  .igo-linkbtn { min-height: var(--tap); display: inline-flex; align-items: center; }
}
@media (max-width: 1180px) {
  .igo-full { justify-self: stretch; width: 100%; }
}
@media (max-width: 1180px), (pointer: coarse) {
  .igo-ntrow .pj-pichk, .igo-colater .pj-pichk, .igo-dupparts .pj-pichk { min-height: var(--tap); }
}
@media (max-width: 640px) {
  .igo-form3, .igo-pair { grid-template-columns: minmax(0, 1fr); }
  .igo-times { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .igo-dupparts { grid-template-columns: minmax(0, 1fr); grid-auto-flow: row; grid-template-rows: none; }
  .igo-axis, .igo-tstrow, .igo-kv { grid-template-columns: minmax(0, 1fr); }
  .igo-ntrow { grid-template-columns: minmax(0, 1fr); padding-left: 0; }
  .igo-ntrow > div:not(:first-child) { padding-left: 24px; }
  .igo-filters .field { flex: 1 1 140px; }
  .igo-pickbar .input { max-width: none; }
  .igo-lnf { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .igo-corow .igo-acts { flex: 1 1 100%; margin-left: 0; }
  .igo-corow .igo-acts .btn { flex: 1 1 0; justify-content: center; }
}

/* ---- SewerAI (3.0, w9ignite side): the Take-Off panel and its column, the Deliverables tab and the pop-ups
   (public/sewerai-ui.js). The kit's panels, strip, chips, pipe and table.t do the work; these place them. Verify Day's
   footage flags are in tickets.css. Every class starts with swr-. */
.swr-cell { min-width: 126px; }
.swr-c1 { display: flex; align-items: center; gap: 10px; white-space: nowrap; }
.swr-c2 { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-top: 3px; }
.swr-link { all: unset; display: inline-flex; align-items: center; gap: 4px; color: var(--accent-ink); font-weight: var(--fw-semi); cursor: pointer; border-radius: 4px; position: relative; }
.swr-link:hover { text-decoration: underline; }
.swr-link:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.swr-rev { font-weight: var(--fw-bold); color: var(--ink-2); }
.swr-strip { border-radius: var(--r-m); box-shadow: inset 0 0 0 1px var(--hair); }
.swr-foot { margin: 12px 0 0; }
.swr-rep { margin-top: 12px; }
.swr-rep .hint { margin: 0; }
.swr-bad, .swr-prog b.swr-bad { color: var(--bad); }
.swr-run, .swr-nowrap { white-space: nowrap; }
.swr-run { font-weight: var(--fw-semi); }
.swr-barcell { min-width: 150px; }
.swr-padtop { padding-bottom: 4px; }
.swr-sub { margin: 4px 0 0; }
.swr-card { display: grid; gap: 6px; }
.swr-cardtop { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; }
.swr-cardacts { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; }
.swr-empty .empty { padding: 24px 12px; }
.swr-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* pop-ups: the picker, Needs a decision, the two lists, a line's inspections, OK — no video needed */
.modal:has(> .swr-wide) { max-width: 760px; }
.swr-dlg h3 { margin: 4px 0 0; font-size: var(--fs-m); font-weight: var(--fw-bold); display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.swr-rows { list-style: none; margin: 0; padding: 0; display: grid; }
.swr-row { display: flex; align-items: center; justify-content: space-between; gap: 8px 12px; padding: 10px 0; border-top: 1px solid var(--hair); min-width: 0; }
.swr-row:first-child { border-top: 0; }
.swr-insp { align-items: flex-start; }
.swr-main { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.swr-end { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px; flex: none; }
.swr-facts { margin: 4px 0 0; }
.swr-scroll { max-height: 46vh; overflow: auto; border: 1px solid var(--hair); border-radius: var(--r-m); }
.swr-scroll > .swr-rows { padding: 0 12px; }
.swr-scroll .empty, .swr-more { padding: 14px 0; }
.swr-group { display: grid; gap: 2px; padding: 8px 12px; border: 1px solid var(--hair); border-radius: var(--r-m); }
@media (max-width: 1180px), (pointer: coarse) { .swr-link::after { content: ""; position: absolute; inset: -12px -4px; } }   /* a 44px reach without a taller table */
@media (max-width: 640px) {
  .swr-insp { flex-wrap: wrap; }   /* a line's inspection: Watch and Unlink take the row under it */
  .swr-insp .swr-end { width: 100%; justify-content: flex-start; }
  .swr-insp .swr-end .btn { flex: 1 1 0; justify-content: center; }
  .swr-acts { width: 100%; }
  .swr-acts .btn { flex: 1 1 auto; justify-content: center; }
}

/* ---- maps (3.0, w9ignite): the Crew Day tab replays a crew's trail on a Leaflet map — the same vendored build Sentry and
   Apex use, fetched by ensureLeaflet() (shared.js) the first time a map is drawn. Its labels take the page's own type; this
   was index.html's one-line <style>, moved here so the shell carries no looks of its own. */
.leaflet-container { font: inherit; }

/* ---- Ignite › Projects on a phone (3.0, w10trace): every door on a project card is a 44px reach — the project, its
   customer and branch, the Paperwork chip (ignite-home.js wraps it in .ih-chiplink so the pill stays a pill), the status
   and Archive / Restore. Scoped to #projCards, so the table above is untouched. Belongs in the kit's ih- section
   (rebuild/kit/components.css) once w10retire hands the kit back; it lives here only because the kit was closed this wave. */
.ih-chiplink { display: inline-flex; align-items: center; }
.ih-chiplink:hover { text-decoration: none; }
.ih-chiplink:hover .chip { filter: brightness(.96); }
@media (max-width: 1180px) {
  .ih #projCards .ih-cardtop { align-items: center; }
}
@media (max-width: 1180px), (pointer: coarse) {
  .ih #projCards .ih-cardtop > a.name { display: inline-flex; align-items: center; min-height: var(--tap); min-width: 0; overflow-wrap: anywhere; }
}
@media (max-width: 1180px) {
  .ih #projCards .card > .hint { display: flex; flex-wrap: wrap; align-items: center; column-gap: 4px; }
}
@media (max-width: 1180px), (pointer: coarse) {
  .ih #projCards .card > .hint > :is(a, .src) { display: inline-flex; align-items: center; justify-content: center; min-height: var(--tap); min-width: var(--tap); }
  .ih #projCards .status { height: var(--tap); }
  .ih #projCards .ih-cardact .btn { min-height: var(--tap); }
}
/* a finger at any width (w22touch, 10/27): the Paperwork chip under a project's name in the table was 18px tall — it
   reaches 44 now, in the 26px the touch layout already leaves between the name and the line under it */
@media (pointer: coarse) {
  .ih .hint > a.ih-chiplink { position: relative; }
  .ih .hint > a.ih-chiplink::after { content: ""; position: absolute; inset: calc(50% - var(--tap) / 2) min(-4px, calc(50% - var(--tap) / 2)); }
}

/* ---- New Project — Intake (app.js newProjectModal, 3.0 w10trace): the Services ticks in even columns, 4 → 2 → 1, and the
   two-column fields on shared lines. Each field takes three rows of the form (subgrid) — its label, its box, its hint — so
   a label that wraps or a hint on one side moves its neighbour with it: across a row every label, every box and every
   hint starts level, and Work Order · Retainage (one .igo-pair in a column) share those rows too. One column on a phone,
   where there is no neighbour to line up with. Edit Project carries the same Services field, so it gets the same ticks. */
:is(.igo-np, .igo-ep) .scd-checks { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px 16px; }
:is(.igo-np, .igo-ep) .scd-checks .pj-pichk { min-width: 0; overflow-wrap: anywhere; }
@media (max-width: 700px) { :is(.igo-np, .igo-ep) .scd-checks { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 340px) { :is(.igo-np, .igo-ep) .scd-checks { grid-template-columns: minmax(0, 1fr); } }
@media (min-width: 641px) {
  .igo-np .pj-form { row-gap: 0; }
  .igo-np .pj-form > :is(.field, .igo-pair), .igo-np .igo-pair > .field { display: grid; grid-row: span 3; grid-template-rows: subgrid; row-gap: 0; align-items: start; }
  .igo-np .pj-form > :is(.field, .igo-pair) { padding-bottom: 10px; }   /* the form's row gap, under each field's last row */
  .igo-np .pj-form .field > :first-child { margin-bottom: 5px; }        /* label → box, as the kit's .field gap */
  .igo-np .pj-form .field > .hint { margin-top: 5px; }                  /* box → hint */
}

/* ---- Plan › Take-Off on a phone (3.0, w10trace): a line's card carries the SewerAI column too — the newest inspection's
   date (it opens the line's inspections), the report, footage against the bid and the worst grade. sewerai-ui.js fills
   it and unhides it once the mirror has something to say. It is the dl's last fact, so when it stays hidden the fact
   before it is the one that spans an odd row (the "odd last fact takes the row" rule above). */
.pj-tocard .swr-cell { min-width: 0; }
.pj-tocard .swr-c1 { flex-wrap: wrap; white-space: normal; row-gap: 2px; }
@media (max-width: 640px) { .pj-facts > :nth-child(odd):has(+ .pj-tosai[hidden]:last-child) { grid-column: 1 / -1; } }

/* Ready to Invoice teal and Invoiced navy (CHANGE-LOG #1/#11) are the kit's .chip/.status tones since the fix round. */

/* ---- Projects list sorting (whole-site test 10/23, F-w11vp-6): 3.0 folds Job # under Project, Branch under Customer and
   BDM under PM, so each of those headings holds two of the kit's .ih-sort buttons; only the one in use takes the sorted
   heading's ink. A phone shows cards, not headings, so it gets Sort by (a select and a direction button) instead. */
.igo-sort2 { display: inline-flex; align-items: center; gap: 0 6px; white-space: nowrap; }   /* one line: the two sorts never split a heading in two (820) */
.igo-dot { color: var(--faint); }
.igo-sort2 > .ih-sort:not(.igo-on) { color: inherit; }
.igo-sort2 > .ih-sort:not(.igo-on) span { color: var(--faint); }
.igo-psort { display: none; }
@media (max-width: 640px) {
  /* wraps (w26fix): in Spanish "Ordenar por" + "Proyecto" + "De la A a la Z" is wider than a 320 or 360 phone, and the select was left 22px
     wide. The picker keeps room for its longer choices (148px: "N.º de trabajo"); the direction button drops under it when it
     must and then takes the row. */
  .igo-psort { display: flex; flex-wrap: wrap; }
  .igo-psort-l { flex: none; font-size: 12.5px; font-weight: var(--fw-semi); color: var(--muted); white-space: nowrap; }
  .igo-psort .select-wrap { flex: 1 1 148px; min-width: 148px; }
  .igo-psort .btn { flex: 1 1 auto; }
}

/* ---- design review 10/23 (w11design; f2ignite): spacing and orphans on Ignite's own screens ---------------------------
   Schedule › Push: the box's panels sat 0px apart (K4) — they keep the page's rhythm. */
#pushBox { display: grid; gap: var(--gap); }
/* Schedule: the four money tiles stretched to the month calendar's height (~215px around one line each, S1). */
/* the four figures stretch to the month calendar's height again, and the row of figures sits in the middle of it, so the strip is as tall as the
   calendar beside it (S1 had it start-aligned: a 117px strip next to a 220px month, w29d 010/080/081) */
@media (min-width: 1181px) { .sc-top:has(> #schedCards) { align-items: stretch; } .sc-top > #schedCards { align-content: center; } }
/* Schedule head on a phone: Notify customers | Schedule a project share their row whole, Push to crews takes the next (K6). */
@media (max-width: 640px) { .sc-head .actions > .btn:not(#pushBtn) { flex: 1 1 0; justify-content: center; } }
/* Field › Crew Day: where the clock-in area's size comes from sits under the area, not floating mid-row; the job's ticks
   take the column beside it (S14, K7 2 + 1 at 820). One column on a phone. */
.pj-cdset { display: grid; grid-template-columns: minmax(240px, 320px) minmax(0, 1fr); gap: 6px 18px; align-items: end; }
.pj-cdset > .pj-cdfence { grid-column: 1; grid-row: 1; flex: none; min-width: 0; }
.pj-cdset > .pj-cdfrom { grid-column: 1; grid-row: 2; padding-bottom: 0; }
.pj-cdset > .pj-cdfrom:empty { display: none; }
.pj-cdset > .pj-pichk { grid-column: 2; grid-row: 1; justify-self: start; }
.pj-cdset > #sfyJobSwitch { grid-column: 2; grid-row: 2; justify-self: start; }
@media (max-width: 640px) {
  .pj-cdset { grid-template-columns: minmax(0, 1fr); }
  /* an empty job switch takes no grid row (26px under the tick against 17px above, w30b review) */
  .pj-cdset > #sfyJobSwitch:empty { display: none; }
  /* the desktop rules above name each child (0,2,0), so a bare `> *` lost to them: the tick still asked for column 2, the grid
     grew an implicit second track and the area/size text was squeezed to ~60px (w29d 166). Name the same children. */
  .pj-cdset > .pj-cdfence, .pj-cdset > .pj-cdfrom, .pj-cdset > .pj-pichk, .pj-cdset > #sfyJobSwitch { grid-column: 1; grid-row: auto; }
}
/* Money › Est. vs Actual: on a tablet the add row's Add took half a row alone (1 + 2 + 2 + 1, K7) — it takes the row. */
@media (max-width: 1180px) { .pj-rsadd > .btn { grid-column: 1 / -1; } }
/* touch reach (w15polish K3): Contacts' "Primary" tick was a 36px row */
@media (max-width: 1180px), (pointer: coarse) { .pj-pichk, .pj-cdset > .pj-pichk, .pj-siadd .pj-ctform .pj-pichk { min-height: var(--tap); } }   /* and where a row sets it to the 36px box */
/* touch reach (w15polish K3): New project's service facets are 28px chips with the kit's 44px reach, but their rows were 6px
   apart, so the next row's reach took the taps (34 reachable). 16px between rows: each chip's 44 is its own */
@media (max-width: 1180px), (pointer: coarse) { .igo-facets { row-gap: 16px; } }

/* ---- change orders and the contract (w17-change-orders, wave 18) -------------------------------------------------------
   Plan › Pay Items: a change order's line under its item (agreed, approved by, why — or what it still needs), the Contract
   panel's four figures (the kit's .strip, 4 → 2 → 1), and the change-order fields of the add form and its pop-up.
   Plan › Contract: the contract on the proposal's paper (print.css .q-sheet), scrolled sideways on a phone, alone on paper. */
.pj-co { display: flex; align-items: flex-start; gap: 6px 10px; font-size: 12.5px; margin: 0 0 8px; }
.pj-co .pj-cot { flex: 1 1 auto; min-width: 0; padding-top: 2px; }
.pj-co.warn { color: var(--warn); font-weight: var(--fw-semi); }
.pj-co .i { flex: none; margin-top: 4px; }
.pj-co .btn { flex: none; margin-top: -4px; }
.pj-cbar > .pad { padding-bottom: 12px; }
.pj-cbar .pj-top { padding-bottom: 0; }
.pj-cstrip { border-top: 1px solid var(--hair); }
.pj-cflags { margin: 0; padding: 12px 16px 14px; }
.pj-coform { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px 12px; margin-top: 12px; }
.pj-coform .field.wide { grid-column: 1 / -1; }
.pj-coform .pj-cowho { margin: 4px 0 0; }
.pj-coflip { margin-top: 12px; }
.pj-coform + .actions { margin-top: 14px; }
@media (max-width: 640px) { .pj-coform { grid-template-columns: minmax(0, 1fr); } }
.pj-cdocwrap { overflow-x: auto; border-radius: var(--r-l); }
.pj-cdoc { margin-bottom: 0; }
.pj-cdoc .pj-cwas { font-size: 10.5px; color: #5d6679; margin-top: 2px; }
.pj-cdoc .pj-crev { font-size: 9.5px; font-weight: 700; letter-spacing: .04em; color: #b26a00; text-transform: uppercase; }
.pj-cdoc tr.pj-cgone td { color: #8a93a6; }
.pj-cdoc tr.pj-cgone td:nth-child(2) { text-decoration: line-through; }
.pj-cdoc tr.pj-cgone .pj-cwas, .pj-cdoc tr.pj-cgone .pj-crev { text-decoration: none; display: inline-block; }
.pj-cdoc .pj-cgap { margin-top: 18px; }
.pj-cdoc .pj-ctot { margin: 12px 0 0 auto; width: 60%; }
.pj-cdoc .pj-ctot td { border-bottom: 0; padding: 4px 8px; }
.pj-cdoc .pj-cfoot { margin-top: 22px; }
@media (max-width: 640px) { .pj-cdoc .pj-ctot { width: 100%; } }   /* after the 60% above, or it loses */
@media print {
  body.pj-print-contract .pj > :not(.pj-body), body.pj-print-contract .pj-body > :not(.pj-col), body.pj-print-contract .pj-talk-scrim,
  body.pj-print-contract .pj-cview > :not(.pj-cdocwrap) { display: none !important; }
  body.pj-print-contract .pj-body, body.pj-print-contract .pj-col, body.pj-print-contract .pj-cview { display: block; }
  body.pj-print-contract .pj-cdocwrap { overflow: visible; }
  body.pj-print-contract .pj-cdoc { box-shadow: none; margin: 0 auto; }
}

/* ---- touch reach: Ignite's leftovers from the site-wide sweep (wave 18; rebuild/reports/w18platform/touch-sweep/compare.md)
   44×44 on touch at ≤1180, nothing moved for a mouse: the kit's pseudo-element reach (.src::after) on a lone link, and where
   two reaches met, the lines open so each keeps its own 44 (the kit's "rows open to 44 centre to centre"). */
@media (max-width: 1180px), (pointer: coarse) {
  /* an empty state's link — the Dashboard's "Build the schedule →" was 19px tall */
  #app .empty > a:not(.btn, .chip, .src) { position: relative; }
  #app .empty > a:not(.btn, .chip, .src)::after { content: ""; position: absolute; inset: calc(50% - var(--tap) / 2) min(-4px, calc(50% - var(--tap) / 2)); }
  /* a phone card's line of links under its head — Tickets (the job · the customer), Pay Apps (the job · the customer, which
     wraps to two lines at 375) and Customer Surveys: each link is a thumb tall and wraps as one piece, so its 44px reach no
     longer meets the head's above or the next line's (31–35px) */
  :is(#tixCards, #mnCards, .ppl .cards) > .card > .hint:has(> a) { display: flex; flex-wrap: wrap; align-items: center; column-gap: .3em; }
  :is(#tixCards, #mnCards, .ppl .cards) > .card > .hint > a { display: inline-flex; align-items: center; min-height: var(--tap); }   /* a link wraps as one piece */
  .ppl .cards > .card > .ih-cardtop:has(> a.name) { min-height: var(--tap); }   /* a survey's job name over its customer (30px) */
}

/* ig-ipad-tables (Jordan, 10/26 evening: "Show the customer and crew lead only in their own columns on touch iPads"). Money ›
   Pay Apps at 1180 and under carried the customer as a second link under the job's name and number (the kit's mn-tab-on);
   with a finger it keeps its own Customer column instead, at every width the table shows at (641 up), and the job cell is the
   job's name over its number. A pay app has no crew lead. Gross and Retainage still fold away; a mouse keeps the stacked cell. */
@media (pointer: coarse) {
  .mn th.mn-cust, .mn td.mn-cust { display: table-cell; }
  .mn .mn-custin { display: none; }
}
/* the cells close up so the extra column fits a portrait iPad without the table scrolling sideways (12px → 6px a side; 4px on
   an iPad mini's 744): the table is the panel's width at 744, 768, 820, 1024 and 1180 (818 wide in 786 at 820 with the 2.x padding) */
@media (max-width: 1180px) and (pointer: coarse) {
  .mn table.mn-list > :is(thead, tbody) > tr > :is(th, td) { padding-left: 6px; padding-right: 6px; }
  .mn table.mn-list > :is(thead, tbody) > tr > :is(th, td):last-child { padding-right: 12px; }   /* Balance's figures keep the panel's edge */
}
/* Net and Balance read as one string 12px apart ("$44,790.93 $44,790.93", design review 10/26): figures get 12px before them where
   there is room. At 744 there is none, and an iPad mini's job numbers break at their hyphen there (a nowrap needs 8px more). */
@media (min-width: 761px) and (max-width: 1180px) and (pointer: coarse) {
  .mn table.mn-list > :is(thead, tbody) > tr > :is(th, td).r { padding-left: 12px; }
}
/* at 320 a list's segmented filter keeps its words in its lane: Projects' "Abiertos · Cerrados · Archivados", Tickets › Review —
   the top bar's Everyone | Mine precedent (components.css .island.filters); buttons stay 44px tall (w25es design review, 10/28) */
@media (max-width: 360px) { .ih-row .seg button { padding: 0 8px; font-size: 12px; } }
@media (max-width: 760px) and (pointer: coarse) {
  .mn table.mn-list > :is(thead, tbody) > tr > :is(th, td):not(:last-child) { padding-left: 4px; padding-right: 4px; }
}

/* w45-1 (W43 design review, finding 1): the Generate-a-pay-app footers (the Choose-tickets step, the job's Pay Apps door) carry
   [Projects] · the count · Cancel · Bill everything reviewed · Generate. The count used to ask for 220px, so the row needed 775 in a
   734 modal and "Generate the pay app" orphaned onto a second line. The count now takes only what is left (0 basis), so the four
   buttons and the words share one row from 560 up; under 560 each button is a full-width thumb target and the count is a line of
   its own above them, never a ragged 2+2 or a lone button. */
.mn-modalacts > .mn-grow { flex: 1 1 0; }
@media (max-width: 560px) {
  .mn-modalacts > .btn { flex: 1 1 100%; }
  .mn-modalacts > .mn-grow { flex-basis: 100%; order: -1; text-align: center; }
}

/* ---- several at once (2.4.0, Jordan 2026-10-29): the bar over Take-Off and Pay Items — Select all, Clear, the count, then
   what to do with the ticked rows — the tick column, and "+ Add items"' list of the job's items */
.pj-bulkpad { padding-top: 0; padding-bottom: 12px; }
.pj-pis > .pj-bulkpad { padding-top: 14px; }
.pj-bulk { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
.pj-bulkn { margin-left: 4px; font-variant-numeric: tabular-nums; color: var(--muted); }
.pj-bulkc { min-width: 0; font-size: 12.5px; }
.pj-bulkacts { display: flex; flex-wrap: wrap; gap: 8px; margin-left: auto; }
.pj-bulk .btn:disabled { opacity: .45; cursor: default; }
th.pj-topick, td.pj-topick { width: 40px; padding-right: 0; }
.pj-pit td.pj-topick { vertical-align: top; padding-top: 20px; }
.ih-cardtop .pj-tick { flex: none; width: auto; }
.pj-hit.pj-hitw { display: inline-flex; gap: 6px; align-items: center; margin: 0; padding: 0 8px; min-height: 28px; border: 1px solid var(--hair); border-radius: var(--r-pill); font-size: 12.5px; font-weight: var(--fw-semi); color: var(--ink-2); }
.pj-tkname .pj-tick { margin-right: 2px; }
.pj-picard .ih-cardtop > b { flex: 1 1 auto; min-width: 0; }
.pj-tobl { max-height: 52vh; overflow-y: auto; margin-top: 2px; border: 1px solid var(--hair); border-radius: var(--r-m); }
.pj-tobi { display: flex; gap: 10px; align-items: flex-start; padding: 9px 12px; border-top: 1px solid var(--hair); cursor: pointer; }
.pj-tobi:first-child { border-top: 0; }
.pj-tobi:hover { background: var(--well); }
.pj-tobi[hidden] { display: none; }
.pj-tobi input { flex: none; width: 16px; height: 16px; margin: 2px 0 0; accent-color: var(--ink); }
.pj-tobi > span { display: grid; gap: 1px; min-width: 0; }
.pj-tobi .hint { font-size: 12px; }
@media (max-width: 640px) {
  .pj-bulkacts { margin-left: 0; width: 100%; }
  .pj-bulkacts .btn { flex: 1 1 calc(50% - 4px); justify-content: center; }
}
@media (pointer: coarse) {
  .pj-tobi { min-height: var(--tap); align-items: center; }
  .pj-tobi input { width: 22px; height: 22px; margin: 0; }
}

/* ---- Take-Off never scrolls sideways (2.4.0, Jordan 2026-10-29: "make it so it doesn't scroll horizontal"). Under 1440 each
   line is a card (a laptop, a tablet, a phone), four fields across from 900. At 1440 and up the table, whose boxes take
   their column's width and whose headings wrap — unless its panel is still too narrow for it (the Discussion open beside
   the page leaves ~1070px; a layout with many columns): project-plan.js measures each table after it paints and on a
   resize, and a table wider than its panel is shown as its cards (.pj-cards). */
@media (max-width: 1439px) {
  .pj-to .phone-cards table.t.pj-tot { display: none; }
  .pj-to .phone-cards .cards { display: flex !important; flex-direction: column; gap: 8px; }
}
.pj-to .phone-cards.pj-cards table.t.pj-tot { display: none; }
.pj-to .phone-cards.pj-cards .cards { display: flex !important; flex-direction: column; gap: 8px; }
@media (min-width: 900px) {   /* four across, wrapping: the Item takes two, the rest one each, a row's last fields share what is left */
  .pj-to .pj-tocard .pj-piform { display: flex; flex-wrap: wrap; gap: 8px 10px; }
  .pj-to .pj-tocard .pj-piform > .field { flex: 1 1 calc(25% - 7.5px); }
  .pj-to .pj-tocard .pj-piform > .field.pj-fitem { flex-basis: calc(50% - 5px); }
  .pj-to .pj-tocard .pj-facts { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.pj-tocard .ih-cardtop { align-items: center; }
@media (min-width: 1440px) {
  .pj-to table.pj-tot { width: 100%; }
  .pj-to table.pj-tot th { white-space: normal; font-size: 11px; line-height: 1.25; }
  .pj-to table.pj-tot :is(th, td) { padding-left: 5px; padding-right: 5px; }
  .pj-to table.pj-tot td :is(.input, .select) { min-width: 0; width: 100%; padding-left: 8px; padding-right: 8px; }
  /* …but a select keeps the room for its chevron, and the "+" add-item select its own 56px (w27hb APP-PATCHES 1) */
  .pj-to table.pj-tot td .select-wrap .select { padding-right: 30px; }
  .pj-to table.pj-tot td .pj-toadd { width: 56px; }
  .pj-toitem > .select-wrap:not(.block) { flex: none; }
  .pj-to table.pj-tot td.pj-tof :is(.input, .select), .pj-to table.pj-tot td:is(.pj-toar, .pj-toc) .input { min-width: 6em; }
  .pj-to table.pj-tot td.pj-tomh .input { min-width: 6.8em; }
  .pj-to table.pj-tot td.pj-toqty .input { min-width: 4.6em; }
  .pj-to table.pj-tot td.pj-tof.date .input { min-width: 7.5em; }
  .pj-to table.pj-tot td.pj-toit { min-width: 220px; }
  .pj-to table.pj-tot td.pj-toq { max-width: 120px; }
  .pj-to table.pj-tot td.pj-toc { min-width: 90px; }
  /* it fits its panel here, so nothing is held while it scrolls: the first columns sit in the row like the rest */
  .pj-to table.pj-tot :is(th, td):nth-child(-n+3) { position: static; background: transparent; box-shadow: none; }
  .pj-to table.pj-tot.tk :is(th, td):first-child { min-width: 40px; width: 40px; }
  .pj-to table.pj-tot.tk :is(th, td):nth-child(2) { min-width: 52px; width: 52px; }
  .pj-to table.pj-tot td.pj-tosz .input { min-width: 4.4em; }
  .pj-to table.pj-tot tr.pj-todone-row td:nth-child(-n+3) { background: color-mix(in srgb, var(--ok) 7%, transparent); }
}
@media (pointer: coarse) { .pj-hit.pj-hitw { min-height: var(--tap); padding: 0 12px; } }

/* 2.4.1's office test pop-ups (spark & pull and the four schema forms) and Add a test: section headings, a pull or a row
   in its own well, the surfaces as ticks — the pop-up is wider than the three-form one, so its rows read in fours */
.modal:has(> .igo-tstx) { max-width: 720px; }
.igo-tst .igo-tsth { margin: 6px 0 0; font-size: 12px; font-weight: var(--fw-bold); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.igo-tstrowbox { display: grid; gap: 6px; padding: 10px 12px; border: 1px solid var(--hair); border-radius: var(--r-m); background: var(--well); }
.igo-tst4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.igo-tstchecks { display: flex; flex-wrap: wrap; gap: 6px 16px; }
@media (max-width: 640px) { .igo-tst4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .igo-tstchecks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* w51b: a mobilization on no ticket yet (the choice of ticket and its one button) and the job's subcontractor agreements */
.mn-mobadd { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
.mn-mobadd .select-wrap { min-width: 200px; }
.pj-subs { list-style: none; margin: 0; padding: 0; display: grid; }
.pj-subs li { display: grid; grid-template-columns: minmax(0, 1fr) auto auto auto auto; align-items: center; gap: 14px; padding: 10px 0; border-top: 1px solid var(--hair); }
.pj-subs li:first-child { border-top: 0; padding-top: 0; }
@media (max-width: 760px) { .pj-subs li { grid-template-columns: minmax(0, 1fr) auto; } .pj-subs li > :nth-child(n+3) { grid-column: 1 / -1; } }

/* Money › Costs and Cost Review (w53c): a Sage bill's "Tie to a PO" / "Untie" buttons under the line that says which PO it is against and why. */
.mn-tie { display: flex; flex-wrap: wrap; gap: 4px 6px; margin-top: 6px; }
.mn-tie-now { margin: 0 0 10px; font-weight: 600; }
