
  :root{
    --green:#1e7a32; --green-dark:#155c24; --green-light:#e8f3ec; --lime:#8cc63f; --charcoal:#181818;
    --amber:#b45309; --amber-light:#fef3e2;
    --blue:#1d4ed8; --blue-light:#e7edfd;
    --gray:#6b7280; --gray-light:#f3f4f6; --border:#e5e7eb;
    --red:#b91c1c; --ink:#111827;
  }
  *{box-sizing:border-box; margin:0; padding:0; -webkit-tap-highlight-color:transparent;}
  body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif; background:#f8faf9; color:var(--ink); padding-bottom:84px;}
  header{background:var(--charcoal); color:#fff; padding:12px 16px; position:sticky; top:0; z-index:50; display:flex; align-items:center; justify-content:space-between; gap:8px; border-bottom:3px solid var(--lime);}
  header .brand-wrap{display:flex; align-items:center; gap:10px;}
  header h1{font-size:1.02rem; font-weight:800; letter-spacing:1.5px; line-height:1.1;}
  header h1 .tree-word{color:#fff;}
  header h1 .llc{display:block; font-size:.62rem; letter-spacing:3px; color:var(--lime); font-weight:700;}
  header .sub{font-size:.7rem; opacity:.8; font-weight:400; letter-spacing:.3px;}
  .role-switch{display:flex; background:rgba(255,255,255,.15); border-radius:999px; padding:3px; gap:2px;}
  .role-switch button{border:0; background:transparent; color:#fff; font-size:.72rem; font-weight:600; padding:6px 10px; border-radius:999px; cursor:pointer; white-space:nowrap;}
  .role-switch button.active{background:var(--lime); color:var(--charcoal);}
  main{max-width:860px; margin:0 auto; padding:16px;}
  h2{font-size:1.15rem; margin-bottom:12px;}
  h3{font-size:.95rem; margin-bottom:8px;}

  /* Bottom nav */
  nav.bottom{position:fixed; bottom:0; left:0; right:0; background:#fff; border-top:1px solid var(--border); display:flex; z-index:50; box-shadow:0 -2px 10px rgba(0,0,0,.05);}
  nav.bottom button{flex:1; border:0; background:transparent; padding:9px 2px 10px; font-size:.68rem; color:var(--gray); cursor:pointer; display:flex; flex-direction:column; align-items:center; gap:3px; font-weight:600;}
  nav.bottom button .ico{font-size:1.35rem; line-height:1;}
  nav.bottom button.active{color:var(--green);}

  .card{background:#fff; border:1px solid var(--border); border-radius:14px; padding:14px; margin-bottom:12px; box-shadow:0 1px 3px rgba(0,0,0,.04);}
  .muted{color:var(--gray); font-size:.85rem;}
  .small{font-size:.78rem;}
  .row{display:flex; align-items:center; gap:8px; flex-wrap:wrap;}
  .spread{justify-content:space-between;}
  .price{font-weight:800; color:var(--green); font-size:1.05rem;}

  .pill{display:inline-block; padding:3px 10px; border-radius:999px; font-size:.7rem; font-weight:700; letter-spacing:.3px;}
  .pill.bid{background:var(--amber-light); color:var(--amber);}
  .pill.approved{background:var(--blue-light); color:var(--blue);}
  .pill.scheduled{background:#ede9fe; color:#6d28d9;}
  .pill.completed{background:#fef9c3; color:#a16207;}
  .pill.paid{background:var(--green-light); color:var(--green);}

  .btn{display:inline-flex; align-items:center; justify-content:center; gap:8px; border:0; border-radius:12px; padding:12px 18px; font-size:.95rem; font-weight:700; cursor:pointer; background:var(--green); color:#fff;}
  .btn:active{transform:scale(.98);}
  .btn.secondary{background:#fff; color:var(--green); border:2px solid var(--green);}
  .btn.gray{background:var(--gray-light); color:var(--ink); border:1px solid var(--border);}
  .btn.blue{background:var(--blue);}
  .btn.small-btn{padding:8px 12px; font-size:.8rem; border-radius:10px;}
  .btn.huge{width:100%; padding:22px; font-size:1.35rem; border-radius:18px;}
  .btn.full{width:100%;}

  /* WAVE 194 — THE PIPE. The job pipeline drawn as a smashed Z: a top run for
     the office's half, an elbow that sweeps back carrying the one number
     somebody has to act on, and a bottom run for the field's half. Both runs
     read left to right on purpose — see the note above PIPE_TOP in app.js.
     Below 700px the Z gives up and the pipe runs straight down, because five
     segments across a phone is 68 pixels each.

     WAVE 195 — refined after looking at it on a real screen. The first cut drew
     the elbow as three butt-joined borders, which left square notches at both
     corners; the arrowhead was 18px of triangle hanging off a 5px line; and the
     note sat in the middle of a full-width horizontal, so the whole connector
     read as a labelled horizontal rule rather than a pipe coming back. The
     bends are proper radiused corners now, the arrowhead is scaled to the line,
     and the note sits in the crook beside the drop — where the thing it is
     about actually happens. The runs got a tube gradient so they read as pipe
     rather than as a table. */
  .pipe{--pipe:#b8c9bd; --pipe-lip:#dae5dd; margin:2px 0 14px;}
  .pipe-row{display:flex; align-items:stretch; border:4px solid var(--pipe); border-radius:20px; overflow:hidden;
    background:linear-gradient(180deg,#fff 0%,#f7faf8 55%,#edf3ef 100%);
    box-shadow:inset 0 2px 0 rgba(255,255,255,.9), inset 0 -7px 11px -7px rgba(31,60,40,.22);}
  .pipe .seg{flex:1 1 0; min-width:0; background:transparent; border:0; border-left:2px solid var(--pipe-lip); padding:9px 5px 10px; cursor:pointer; font:inherit; color:var(--ink); text-align:center;}
  .pipe .seg:first-child{border-left:0;}
  .pipe .seg:hover{background:rgba(30,122,50,.07);}
  /* the open stage reads as the section the work is sitting in, not as a hole
     punched in the pipe — a tint plus a band of colour along the floor */
  .pipe .seg.active{background:linear-gradient(180deg,#eaf4ec,#d5e8db); box-shadow:inset 0 -4px 0 var(--green);}
  .pipe .seg .nm{display:block; font-size:.66rem; font-weight:800; color:var(--gray); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
  .pipe .seg .ct{display:block; font-size:1.4rem; font-weight:800; line-height:1.2;}
  .pipe .seg .vl{display:block; font-size:.63rem; font-weight:700; color:var(--gray); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
  .pipe .seg.active .nm, .pipe .seg.active .ct{color:var(--green-dark);}
  .pipe .seg.active .vl{color:var(--green);}
  /* the connector: two radiused corners, not three straight borders meeting at
     square notches. .bend comes down at the right and runs back; .turn takes it
     round and drops into the bottom run. */
  .pipe-elbow{position:relative; height:52px;}
  .pipe-elbow i{position:absolute; display:block; border:0 solid var(--pipe);}
  /* both drops run a few pixels INTO the runs they join. Measured at 0 gap and
     it still read as floating: a line that stops exactly at a wall looks parted
     from it, and the arrowhead was too small to bridge the last six pixels.
     .pipe-elbow is positioned and .pipe-row is not, so these paint over the
     wall and the joint closes. */
  .pipe-elbow .bend{left:40px; right:26px; top:-4px; height:26px; border-right-width:4px; border-bottom-width:4px; border-bottom-right-radius:14px;}
  .pipe-elbow .turn{left:26px; width:18px; top:22px; height:26px; border-left-width:4px; border-top-width:4px; border-top-left-radius:14px;}
  .pipe-elbow .turn::after{content:''; position:absolute; left:-5px; bottom:-8px; width:0; height:0; border:7px solid transparent; border-bottom:0; border-top-color:var(--pipe);}
  .pipe-elbow .note{position:absolute; left:56px; top:25px; background:#fff; border:1px solid var(--border); border-radius:999px; padding:3px 12px; font:inherit; font-size:.72rem; font-weight:700; color:var(--gray); white-space:nowrap; cursor:pointer;}
  .pipe-elbow .note.warn{background:var(--amber-light); border-color:#e3c79c; color:var(--amber);}
  /* insurance hangs OFF the pipe — it is not a stage, so it is not a segment,
     and the dashed wall says so at a glance */
  .pipe-spur{display:block; width:100%; margin-top:12px; text-align:left; background:#fff; border:2px dashed var(--pipe); border-radius:14px; padding:9px 13px; font:inherit; font-size:.8rem; font-weight:700; color:var(--ink); cursor:pointer;}
  .pipe-spur .why{font-weight:400; font-size:.72rem; opacity:.6;}
  .pipe-spur:hover{background:rgba(30,122,50,.07);}
  .pipe-spur.active{background:var(--green); border-style:solid; border-color:var(--green); color:#fff;}
  @media (max-width:700px){
    .pipe-row{flex-direction:column; border-radius:16px; background:linear-gradient(180deg,#fff,#f4f8f5);}
    .pipe .seg{border-left:0; border-top:2px solid var(--pipe-lip); display:flex; align-items:baseline; gap:10px; text-align:left; padding:10px 14px;}
    .pipe .seg:first-child{border-top:0;}
    .pipe .seg .nm{flex:1; font-size:.8rem; color:var(--ink);}
    .pipe .seg .ct{font-size:1.1rem;}
    .pipe .seg.active .nm{color:var(--green-dark);}
    .pipe-elbow{height:42px;}
    .pipe-elbow .bend{display:none;}
    .pipe-elbow .turn{left:calc(50% - 2px); width:0; top:0; height:36px; border-top-width:0; border-top-left-radius:0;}
    .pipe-elbow .note{left:50%; top:8px; transform:translateX(-50%);}
    .pipe-spur .why{display:block; margin-top:2px;}
  }
  /* WAVE 194 — the .stages chip strip that stood here is GONE, and so is its
     one caller. Nothing else in the app drew it (grepped before deleting). */

  input[type=text], input[type=tel], input[type=number], input[type=date], input[type=password], textarea, select{
    width:100%; padding:12px; border:1.5px solid var(--border); border-radius:10px; font-size:1rem; background:#fff; font-family:inherit;
  }
  textarea{min-height:110px; resize:vertical;}
  label.field{display:block; font-size:.78rem; font-weight:700; color:var(--gray); margin:12px 0 5px; text-transform:uppercase; letter-spacing:.4px;}

  .photo-strip{display:flex; gap:8px; flex-wrap:wrap; margin-top:10px;}
  .photo-strip .ph{width:74px; height:74px; border-radius:10px; background:var(--green-light); display:flex; align-items:center; justify-content:center; font-size:1.6rem; border:1px solid var(--border); position:relative; overflow:hidden;}
  .photo-strip .ph img{width:100%; height:100%; object-fit:cover;}

  /* Mike mode */
  .mike-step{background:#fff; border:2px solid var(--border); border-radius:18px; padding:18px; margin-bottom:14px;}
  .mike-step.done{border-color:var(--green);}
  .step-num{display:inline-flex; width:34px; height:34px; border-radius:50%; background:var(--green); color:#fff; align-items:center; justify-content:center; font-weight:800; font-size:1.1rem; margin-right:10px;}
  .mike-step h3{display:flex; align-items:center; font-size:1.15rem; margin-bottom:10px;}
  .mic-btn{width:100%; padding:20px; border-radius:16px; border:2px dashed var(--green); background:var(--green-light); color:var(--green); font-size:1.15rem; font-weight:800; cursor:pointer; margin-bottom:10px;}
  .mic-btn.listening{background:#fee2e2; border-color:var(--red); color:var(--red); animation:pulse 1.2s infinite;}
  @keyframes pulse{50%{opacity:.6;}}
  .ai-box{background:linear-gradient(135deg,#eef7f1,#e7edfd); border:1.5px solid #c7d8ff; border-radius:14px; padding:14px; margin-top:12px;}
  .ai-box .tag{font-size:.72rem; font-weight:800; color:var(--blue); letter-spacing:.5px;}

  .toast{position:fixed; bottom:96px; left:50%; transform:translateX(-50%); background:var(--ink); color:#fff; padding:12px 20px; border-radius:12px; font-size:.9rem; font-weight:600; z-index:10001; opacity:0; transition:opacity .3s; pointer-events:none; max-width:90%; text-align:center;}
  .toast.show{opacity:1;}

  .search{margin-bottom:12px;}
  .cust-row{display:flex; justify-content:space-between; align-items:center; gap:10px; padding:13px 2px; border-bottom:1px solid var(--border); cursor:pointer;}
  .cust-row:last-child{border-bottom:0;}
  .cust-row > .row{flex:1; min-width:0; flex-wrap:nowrap;}
  .cust-row > .row > div:last-child{min-width:0;}
  .cust-row .muted.small{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
  .cust-row > div:last-child{flex-shrink:0; white-space:nowrap;}
  /* WAVE 127 — the team list, which is a cust-row with one more column. The
     state gets a fixed width and sits LEFT inside it, so every chip starts on
     the same line down the page; a bit more air between rows and a touch less
     between a man's name and what he is. */
  .team-row{padding:11px 0; gap:12px;}
  /* WAVE 127b — THE ONE THAT WAS ACTUALLY CROOKED. .emp-ring carries margin:0 auto
     so it can centre itself in the crew grid. Inside a flex ROW an auto margin does
     not centre — it EATS the leftover space, and the leftover space on this row is
     whatever the man's name did not use. So the face slid right by a different
     amount on every line, further for the short names, and the names started
     wherever their own face had stopped. Pinned flat here: the faces make one
     straight column down the left edge and every name begins at the same place. */
  .team-row .emp-ring{margin:0; flex:0 0 auto;}
  .team-row > .row{gap:11px; align-items:center;}
  .team-row > .row > div:last-child{flex:1 1 auto; min-width:0; text-align:left;}
  .team-row .team-state{flex-shrink:0; width:92px; display:flex; justify-content:flex-start; text-align:left;}
  .team-row .team-state .crew-tag{white-space:nowrap;}
  .team-row b{display:block; line-height:1.25;}
  .team-row .muted.small{margin-top:1px;}
  @media (max-width:380px){ .team-row .team-state{width:84px;} .team-row .team-state .crew-tag{padding:2px 6px; font-size:.66rem;} }
  .avatar{width:40px; height:40px; border-radius:50%; background:var(--green-light); color:var(--green); display:flex; align-items:center; justify-content:center; font-weight:800; flex-shrink:0;}

  .day-head{font-size:.8rem; font-weight:800; color:var(--gray); text-transform:uppercase; letter-spacing:.5px; margin:16px 0 8px;}
  .crew-tag{background:#ede9fe; color:#6d28d9; border-radius:6px; padding:2px 8px; font-size:.7rem; font-weight:700;}

  .clock-big{font-size:2.4rem; font-weight:800; text-align:center; margin:6px 0 2px; font-variant-numeric:tabular-nums;}
  .punch{display:flex; justify-content:space-between; padding:10px 2px; border-bottom:1px solid var(--border); font-size:.85rem;}
  .punch:last-child{border-bottom:0;}
  .gps-chip{background:var(--green-light); color:var(--green); border-radius:6px; padding:2px 8px; font-size:.7rem; font-weight:700;}

  .modal-bg{position:fixed; inset:0; background:rgba(0,0,0,.45); z-index:10000; display:none; align-items:flex-end; justify-content:center;}
  .modal-bg.open{display:flex;}
  .modal{background:#fff; border-radius:20px 20px 0 0; width:100%; max-width:560px; max-height:88vh; overflow-y:auto; padding:20px 18px 30px;}
  .modal h3{font-size:1.1rem;}
  .banner{background:var(--amber-light); border:1px solid #f6ddb9; color:#7c4a10; border-radius:12px; padding:11px 13px; font-size:.82rem; margin-bottom:14px; line-height:1.45;}
  .banner.green{background:var(--green-light); border-color:#cfe5d8; color:var(--green-dark);}
  .hidden{display:none !important;}
  a.linky{color:var(--blue); font-weight:600; text-decoration:none;}

  /* ---- login ---- */
  .login-screen{min-height:100vh; display:flex; align-items:center; justify-content:center; background:var(--charcoal); padding:20px;}
  .login-card{background:#fff; border-radius:20px; padding:34px 26px; width:100%; max-width:380px; text-align:center; border-bottom:5px solid var(--lime);}
  .login-card input{text-align:left;}
  .login-card label{text-align:left;}
  .login-brand{font-weight:800; letter-spacing:2px; font-size:1.2rem; margin:10px 0 18px;}
  .login-brand span{display:block; color:var(--green); letter-spacing:5px; font-size:.7rem;}
  header .signout{background:transparent; border:1.5px solid rgba(255,255,255,.3); color:#fff; border-radius:9px; padding:6px 11px; font-size:1rem; cursor:pointer;}
  .skeleton{background:linear-gradient(90deg,#eee 25%,#f7f7f7 50%,#eee 75%); background-size:200% 100%; animation:sk 1.2s infinite; border-radius:10px; height:74px; margin-bottom:12px;}
  @keyframes sk{0%{background-position:200% 0}100%{background-position:-200% 0}}
  .photo-strip .ph{cursor:pointer;}

/* ---- wave 1: companies, tags, workflow ---- */
  /* ---- two companies ---- */
  body.co-at{ --green:#d96b12; --green-dark:#a84f08; --green-light:#fdeedd; --lime:#f08a1d; }
  .co-bar{display:flex; gap:6px; padding:8px 16px; background:#fff; border-bottom:1px solid var(--border); justify-content:center;}
  .co-bar button{flex:1; max-width:230px; border:2px solid var(--border); background:#fff; border-radius:10px; padding:8px; font-weight:800; font-size:.78rem; cursor:pointer; color:#6b7280; letter-spacing:.5px;}
  .co-bar button.qt-on{background:#e8f3ec; border-color:#1e7a32; color:#155c24;}
  .co-bar button.at-on{background:#fdeedd; border-color:#d96b12; color:#a84f08;}
  .co-bar button.lan-on{background:#fdf3e3; border-color:#b45309; color:#92400e;}
  body.co-lan{ --green:#b45309; --green-dark:#92400e; --green-light:#fdf3e3; --lime:#f59e0b; }
  .co-chip{display:inline-block; border-radius:5px; padding:1px 6px; font-size:.6rem; font-weight:800; letter-spacing:.4px; vertical-align:1px; margin-right:3px;}
  .co-chip.qt{background:#e8f3ec; color:#155c24; border:1px solid #bfe0c5;}
  .co-chip.at{background:#fdeedd; color:#a84f08; border:1px solid #f3cfa5;}

  /* ---- tags ---- */
  .tag-chip{display:inline-flex; align-items:center; gap:4px; padding:3px 9px; border-radius:999px; font-size:.68rem; font-weight:700; border:1.5px solid transparent; margin:2px; cursor:pointer; user-select:none;}
  .tag-chip .x{opacity:.55; font-weight:800;}
  .tc-equip{background:#fde8d7; color:#9a3f0c; border-color:#f3c9a8;}      /* equipment: orange */
  .tc-cond{background:#dbeffe; color:#0b5394; border-color:#b3d8f5;}      /* weather/conditions: blue */
  .tc-work{background:#e2f3e5; color:#1e6b2f; border-color:#bfe0c5;}      /* work type: green */
  .tc-loc{background:#efe5fb; color:#6023a8; border-color:#d8c2f2;}       /* location: purple */
  .tc-species{background:#fdf3c9; color:#8a6d00; border-color:#f0dd8e;}   /* species: yellow */
  .tag-chip.pick{opacity:.45; filter:grayscale(.4);}
  .tag-chip.pick.on{opacity:1; filter:none; outline:2px solid rgba(0,0,0,.15);}
  .tag-group-label{font-size:.68rem; font-weight:800; color:var(--gray); text-transform:uppercase; letter-spacing:.6px; margin:10px 0 3px;}
  .dur-chip{display:inline-block; background:#eef2ff; color:#3730a3; border-radius:6px; padding:2px 8px; font-size:.7rem; font-weight:800;}
  /* ---- bid request cards ---- */
  .req-card{background:#fff; border:2px solid var(--lime); border-radius:16px; padding:16px; margin-bottom:12px; cursor:pointer; box-shadow:0 2px 6px rgba(0,0,0,.06);}
  .req-card .when{background:var(--green-light); color:var(--green-dark); border-radius:8px; padding:3px 9px; font-size:.72rem; font-weight:700;}
  .office-note{background:#fff8e1; border:1px dashed #e0c368; border-radius:10px; padding:9px 11px; font-size:.8rem; color:#6b5310; margin-top:8px;}

  /* ---- checklist ---- */
  .chk{display:flex; align-items:center; gap:9px; padding:7px 4px; font-size:.92rem; font-weight:600;}
  .chk .dot{width:24px; height:24px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:.8rem; flex-shrink:0; background:#fee2e2; color:var(--red);}
  .chk.ok .dot{background:var(--green-light); color:var(--green);}
  .chk.ok{color:var(--green-dark);}

  .pill.review{background:#fee2e2; color:#b91c1c;}
  .pill.stump_ready, .pill.stump_sched{background:#f5e6d3; color:#7c4a10;}
  .pill.cleanup_ready, .pill.cleanup_sched{background:#dcfce7; color:#15803d;}
  .pill.stump_ready, .pill.stump_sched{background:#f5e6d3; color:#7c4a10;}
  .pill.cleanup_ready, .pill.cleanup_sched{background:#dcfce7; color:#15803d;}
  .prod-card{background:linear-gradient(135deg,#14532d,#1e7a32); color:#fff; border-radius:16px; padding:16px; margin-bottom:12px;}
  .prod-card .big{font-size:2rem; font-weight:800;}
  .prod-card .lbl{font-size:.68rem; letter-spacing:1px; opacity:.85; font-weight:700;}
  .prod-card .wk{border-top:1px solid rgba(255,255,255,.25); margin-top:10px; padding-top:10px; display:flex; justify-content:space-between; align-items:center;}
  .dur-chip{display:inline-block; background:#eef2ff; color:#3730a3; border-radius:6px; padding:2px 8px; font-size:.7rem; font-weight:800;}
  .br-match{display:flex; justify-content:space-between; align-items:center; gap:8px; padding:9px 10px; border:1px solid var(--border); border-top:0; cursor:pointer; background:#fff; font-size:.82rem;}
  .br-match:first-child{border-top:1px solid var(--border); border-radius:10px 10px 0 0;}
  .br-match:last-child{border-radius:0 0 10px 10px;}
  .br-match:hover{background:var(--green-light);}
  .charcoal-fix{}

/* ================= WAVE 2 — SCHEDULER ================= */
.sched-toggle{display:flex; gap:6px; margin-bottom:12px;}
.sched-toggle button{flex:1; border:1.5px solid var(--border); background:#fff; border-radius:10px; padding:9px 6px; font-size:.78rem; font-weight:800; color:var(--gray); cursor:pointer;}
.sched-toggle button.active{background:var(--charcoal); border-color:var(--charcoal); color:var(--lime);}
.map-wrap{position:relative; border:1px solid var(--border); border-radius:12px; overflow:hidden; background:#f0f4ef;}
.cal-head{display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:10px;}
.cal-head b{font-size:.95rem;}
.cal-head select{width:auto; padding:7px 10px; font-size:.85rem;}
.cal-nav{display:flex; gap:6px;}
.cal-nav button{border:1px solid var(--border); background:#fff; border-radius:8px; width:32px; height:32px; font-size:1rem; cursor:pointer;}
.cal-grid{display:grid; grid-template-columns:repeat(7,1fr); gap:3px;}
.cal-dow{font-size:.62rem; font-weight:800; color:var(--gray); text-align:center; padding:3px 0; text-transform:uppercase;}
.cal-cell{min-height:64px; border:1px solid var(--border); border-radius:7px; padding:3px; font-size:.68rem; background:#fafafa;}
.cal-cell.other{opacity:.4;}
.cal-cell.today{border-color:var(--green); border-width:2px; background:var(--green-light);}
.cal-cell .d{font-weight:800; font-size:.66rem; color:var(--gray);}
.cal-cell.dragover{background:#dcf1e2; border-color:var(--green); border-style:dashed;}
.cal-job{background:var(--green); color:#fff; border-radius:5px; padding:1px 5px; margin-top:2px; font-size:.6rem; font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; cursor:pointer;}
.cal-job.crewB{background:#6d28d9;}
.cal-job.unapproved{background:#b91c1c;}
.week-col{min-height:130px;}
.sched-legend{display:flex; gap:14px; margin-top:8px; font-size:.72rem; color:var(--gray); align-items:center; flex-wrap:wrap;}
.sched-legend .sw{display:inline-block; width:12px; height:12px; border-radius:3px; margin-right:4px; vertical-align:-1px;}
.day-grid{position:relative; border-left:52px solid transparent;}
.day-slot{height:22px; border-top:1px solid #f0f0f0; position:relative;}
.day-slot.hour{border-top:1.5px solid #ddd;}
.day-slot .hlabel{position:absolute; left:-50px; top:-8px; font-size:.62rem; color:var(--gray); width:44px; text-align:right;}
.day-job{position:absolute; left:2px; right:6px; background:var(--green); color:#fff; border-radius:8px; padding:5px 9px; font-size:.72rem; font-weight:700; cursor:grab; box-shadow:0 2px 6px rgba(0,0,0,.18); overflow:hidden; z-index:5;}
.day-job.crewB{background:#6d28d9;}
.day-job.unapproved{background:#b91c1c;}
.day-job .sub{font-weight:400; font-size:.65rem; opacity:.9;}
.day-drive{position:absolute; left:14px; right:20px; background:repeating-linear-gradient(45deg,#f3f4f6,#f3f4f6 6px,#e5e7eb 6px,#e5e7eb 12px); color:#4b5563; border-radius:6px; font-size:.62rem; font-weight:700; display:flex; align-items:center; justify-content:center; z-index:4; border:1px dashed #cbd5e1;}
.slot-dragover{background:#dcf1e2 !important;}
.leaflet-div-icon{background:transparent; border:none;}

/* ================= WAVE 3 — INBOX ================= */
.nav-badge{position:absolute; top:-6px; right:-12px; background:#dc2626; color:#fff; font-size:.62rem; font-weight:800; border-radius:999px; min-width:17px; height:17px; display:inline-flex; align-items:center; justify-content:center; padding:0 4px;}
.bottom button .ico{position:relative;}
.thread-row{padding:12px 14px;}
.msg-wrap{background:#ece5dd; border:1px solid var(--border); border-radius:14px; padding:14px 12px; margin-top:10px; max-height:52vh; overflow-y:auto; display:flex; flex-direction:column; gap:7px;}
.bubble{max-width:78%; padding:8px 12px; border-radius:14px; font-size:.88rem; line-height:1.4; position:relative; box-shadow:0 1px 1px rgba(0,0,0,.08);}
.bubble.in{background:#fff; align-self:flex-start; border-bottom-left-radius:4px;}
.bubble.out{background:#d9fdd3; align-self:flex-end; border-bottom-right-radius:4px;}
body.co-at .bubble.out{background:#ffe8d6;}
.bubble .when{display:block; font-size:.62rem; color:#7d8a80; text-align:right; margin-top:3px;}
.sr-chip{font-size:.72rem !important; max-width:100%; white-space:normal; text-align:left; line-height:1.35;}

/* ================= WAVE 4 — MONEY (A/R, P&L, Reports, Mailers) ================= */
.hub-stat{display:flex; justify-content:space-between; align-items:center; padding:8px 4px; border-bottom:1px solid var(--border); font-size:.84rem;}
.hub-stat:last-child{border-bottom:0;}
.kpi-row{display:grid; grid-template-columns:repeat(auto-fit,minmax(140px,1fr)); gap:10px; margin-bottom:14px;}
.kpi{background:#fcfcfb; border:1px solid var(--border); border-radius:14px; padding:12px 14px;}
.kpi .k-lbl{font-size:.66rem; font-weight:800; letter-spacing:.6px; color:#898781; text-transform:uppercase;}
.kpi .k-val{font-size:1.55rem; font-weight:800; color:#0b0b0b; margin:2px 0;}
.kpi .k-sub{font-size:.72rem; color:#52514e;}
.chart-card{background:#fcfcfb; border:1px solid var(--border); border-radius:14px; padding:14px; margin-bottom:14px; position:relative;}
.chart-card h3{margin-bottom:2px;}
.chart-sub{font-size:.72rem; color:#898781; margin-bottom:10px;}
.viz-tip{position:absolute; background:#0b0b0b; color:#fff; font-size:.72rem; font-weight:600; padding:5px 9px; border-radius:7px; pointer-events:none; opacity:0; transition:opacity .12s; z-index:20; white-space:nowrap;}
.geo-flex{display:flex; gap:16px; align-items:center; flex-wrap:wrap;}
.geo-table{flex:1; min-width:230px; border-collapse:collapse; font-size:.8rem;}
.geo-table td{padding:5px 6px; border-bottom:1px solid #e1e0d9;}
.geo-table td.num{text-align:right; font-variant-numeric:tabular-nums;}
.swatch{display:inline-block; width:11px; height:11px; border-radius:3px; margin-right:6px; vertical-align:-1px;}
.tf-select{width:auto !important; padding:7px 10px !important; font-size:.82rem !important;}
.mail-table{width:100%; border-collapse:collapse; font-size:.78rem;}
.mail-table th{text-align:left; font-size:.66rem; color:#898781; text-transform:uppercase; letter-spacing:.5px; padding:6px; border-bottom:1.5px solid #c3c2b7;}
.mail-table td{padding:7px 6px; border-bottom:1px solid #e1e0d9; font-variant-numeric:tabular-nums;}
.mail-table td.num, .mail-table th.num{text-align:right;}
.sugg{border-left:5px solid var(--green); background:#fff; border-radius:10px; border-top:1px solid var(--border); border-right:1px solid var(--border); border-bottom:1px solid var(--border); padding:12px 14px; margin-bottom:10px;}
.sugg .s-kind{font-size:.66rem; font-weight:800; letter-spacing:.6px; color:var(--green);}
.sugg.expand{border-left-color:#2a78d6;}
.sugg.expand .s-kind{color:#2a78d6;}
.sugg.react{border-left-color:#eb6834;}
.sugg.react .s-kind{color:#eb6834;}
#printArea{display:none;}
body.print-mode header, body.print-mode nav.bottom, body.print-mode main, body.print-mode .co-bar, body.print-mode .modal-bg, body.print-mode .toast{display:none !important;}
body.print-mode #printArea{display:block !important; padding:20px; font-size:12px;}
.chg-box{background:#fffbeb; border:2px solid #f59e0b; border-radius:12px; padding:12px; margin:10px 0;}
.chg-box .hd{font-size:.72rem; font-weight:800; color:#92400e; letter-spacing:.5px; margin-bottom:6px;}
.chg-box li{font-size:.82rem; margin-left:18px; margin-bottom:3px;}
.chg-flag{display:inline-block; background:#f59e0b; color:#fff; border-radius:6px; padding:2px 8px; font-size:.66rem; font-weight:800; letter-spacing:.4px;}

/* ================= WAVE 5 — EQUIPMENT ================= */
.eq-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(240px,1fr)); gap:12px; background:#f7f3ea; border:2px solid #e2d9c3; border-radius:14px; padding:14px; background-image:radial-gradient(#d9cfae 1px, transparent 1px); background-size:22px 22px;}
.eq-card{margin-bottom:0; border-left:5px solid var(--green);}
.eq-photo{height:110px; background:#eef2ec; border-radius:10px; display:flex; align-items:center; justify-content:center; font-size:2.6rem; overflow:hidden;}
.eq-bar{height:8px; background:#e5e7eb; border-radius:999px; margin:6px 0 3px; overflow:hidden;}
.eq-fill{height:100%; background:var(--green); border-radius:999px;}
.chip-btn{border:none; background:none; cursor:pointer; padding:0;}
.inv-row{display:flex; align-items:center; gap:8px; padding:8px 0; border-bottom:1px solid var(--border); font-size:.85rem;}
.inv-row:last-of-type{border-bottom:0;}
.inv-row select{width:auto; padding:6px 8px; font-size:.78rem;}

/* ================= WAVE 7 — HOME HUB ================= */
.hub-grid{display:grid; grid-template-columns:1fr 1fr; gap:12px;}
@media (max-width:760px){ .hub-grid{grid-template-columns:1fr;} }
.hub-full{grid-column:1 / -1;}
.wx-chips{display:flex; gap:6px; flex-wrap:wrap; margin-bottom:10px;}
.wx-chips button{border:1.5px solid var(--border); background:#fff; border-radius:999px; padding:6px 12px; font-size:.76rem; font-weight:700; color:#52514e; cursor:pointer;}
.wx-chips button.on{background:var(--charcoal); color:var(--lime); border-color:var(--charcoal);}
.wx-chips .pipe{border-style:dashed;}
.wx-row{display:grid; grid-template-columns:repeat(7,1fr); gap:4px; text-align:center;}
.wx-day{background:#fcfcfb; border:1px solid var(--border); border-radius:10px; padding:8px 2px;}
.wx-day .d{font-size:.64rem; font-weight:800; color:#898781;}
.wx-day .i{font-size:1.4rem; margin:3px 0;}
.wx-day .hi{font-weight:800; font-size:.82rem;}
.wx-day .lo{color:#898781; font-size:.72rem;}
.wx-day .rn{font-size:.64rem; color:#1d4ed8; font-weight:700; margin-top:2px;}
.map-legend{display:flex; gap:10px; flex-wrap:wrap; margin-top:8px; font-size:.72rem; color:#52514e;}
.map-legend .dot{display:inline-block; width:11px; height:11px; border-radius:50%; border:2px solid #fff; box-shadow:0 0 0 1px rgba(0,0,0,.15); margin-right:4px; vertical-align:-1px;}
.map-legend .leg{cursor:pointer; user-select:none; border:1px solid transparent; border-radius:8px; padding:2px 6px;}
.map-legend .leg.off{opacity:.35; text-decoration:line-through;}
.map-legend .leg:hover{border-color:var(--border); background:#fff;}
.day-switch{display:flex; gap:5px; margin-top:8px; flex-wrap:wrap;}
.day-switch button{border:1.5px solid var(--border); background:#fff; border-radius:8px; padding:6px 10px; font-size:.72rem; font-weight:700; color:#52514e; cursor:pointer;}
.day-switch button.on{background:var(--green); border-color:var(--green); color:#fff;}
.zoom-btn{border:1.5px solid var(--border); background:#fff; border-radius:8px; width:34px; height:34px; font-size:1rem; cursor:pointer; font-weight:800;}
.modal.full{max-width:96vw; width:96vw; max-height:94vh; height:94vh; border-radius:16px;}
.ok-pill{display:inline-block; border-radius:6px; padding:2px 8px; font-size:.68rem; font-weight:800;}
.ok-pill.yes{background:var(--green-light); color:var(--green);}
.ok-pill.no{background:#fee2e2; color:#b91c1c;}
.hub-stat{cursor:pointer;}
.hub-stat b.warn{color:#b45309;}
.hub-stat b.bad{color:#b91c1c;}
.hub-stat b.ok{color:var(--green);}

/* ================= WAVE 8 — TEAM CARDS ================= */
.team-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(320px,1fr)); gap:12px;}
.tcard{margin-bottom:0;}
.tcard .tf-name{font-weight:800; font-size:1rem; border:1.5px solid transparent; padding:6px 8px; border-radius:8px; flex:1;}
.tcard .tf-name:hover, .tcard .tf-name:focus{border-color:var(--border);}
.tf-grid{display:grid; grid-template-columns:1fr 1fr; gap:6px 10px;}
.tf-grid .field{margin-top:6px;}
.pw-box{display:flex; gap:6px; align-items:center; background:#f6f6f2; border:1px solid var(--border); border-radius:10px; padding:8px;}
.pw-box .pw-now{font-family:ui-monospace,Menlo,Consolas,monospace; font-weight:700; font-size:.9rem; min-width:90px; flex-shrink:0;}
.pw-box input{flex:1; min-width:80px;}
.switch{position:relative; width:40px; height:22px; flex-shrink:0; display:inline-block;}
.switch input{opacity:0; width:0; height:0; position:absolute;}
.switch .sl{position:absolute; inset:0; background:#d1d5db; border-radius:999px; transition:.2s; cursor:pointer;}
.switch .sl:before{content:""; position:absolute; width:16px; height:16px; left:3px; top:3px; background:#fff; border-radius:50%; transition:.2s;}
.switch input:checked + .sl{background:var(--green);}
.switch input:checked + .sl:before{transform:translateX(18px);}

/* ================= WAVE 9 — EQUIPMENT COLORS & FOLDERS ================= */
.folder-card{cursor:pointer;}
.folder-card:hover{box-shadow:0 3px 12px rgba(0,0,0,.12);}
.eq-colorpick{width:34px; height:30px; padding:2px; border:1.5px solid var(--border); border-radius:8px; cursor:pointer; background:#fff;}
.eq-move{width:100%; margin-top:8px; padding:7px 8px; font-size:.76rem; border:1.5px solid var(--border); border-radius:8px; color:var(--gray);}

/* ================= WAVE 11 — DOCUMENTS ================= */
.doc-preview{border:1px solid var(--border); border-radius:12px; background:#e8e8e4; padding:14px; margin-top:8px; max-height:420px; overflow-y:auto;}
.doc{background:#fff; box-shadow:0 2px 10px rgba(0,0,0,.15); padding:34px 38px; font-family:Georgia,'Times New Roman',serif; color:#1c1c1c; max-width:640px; margin:0 auto; font-size:.85rem; line-height:1.5;}
.doc-head{display:flex; justify-content:space-between; align-items:flex-start; border-bottom:4px solid var(--accent); padding-bottom:14px; margin-bottom:18px;}
.doc-co{font-family:system-ui,sans-serif; font-weight:800; font-size:1.35rem; letter-spacing:2px; color:var(--dark);}
.doc-co-sub{font-family:system-ui,sans-serif; font-size:.62rem; letter-spacing:4px; color:var(--accent); font-weight:700;}
.doc-kind{font-family:system-ui,sans-serif; font-weight:800; font-size:1.1rem; color:var(--accent); letter-spacing:2px; text-align:right;}
.doc-no{color:#888; font-size:.8rem; letter-spacing:0;}
.doc-meta{display:flex; justify-content:space-between; gap:20px; margin-bottom:18px;}
.doc-lbl{font-family:system-ui,sans-serif; font-size:.6rem; font-weight:800; letter-spacing:1px; color:#999; margin-bottom:2px;}
.doc-table{width:100%; border-collapse:collapse; margin:6px 0 14px;}
.doc-table th{font-family:system-ui,sans-serif; font-size:.62rem; letter-spacing:1px; color:#999; text-align:left; border-bottom:2px solid var(--dark); padding:6px 4px;}
.doc-table td{padding:12px 4px; border-bottom:1px solid #e5e5e0; vertical-align:top;}
.doc-table .r{text-align:right;}
.doc-desc{color:#555; margin-top:6px; font-size:.8rem;}
.doc-amt{font-size:1rem; font-weight:700; white-space:nowrap;}
.doc-total td{border-bottom:none; border-top:2px solid var(--dark); font-size:1.05rem;}
.doc-paid{font-family:system-ui,sans-serif; display:inline-block; border:3px solid var(--accent); color:var(--accent); font-weight:800; letter-spacing:2px; padding:8px 18px; border-radius:8px; transform:rotate(-3deg); margin:4px 0 10px;}
.doc-foot{margin-top:16px; color:#555; font-size:.78rem;}
.doc-foot p{margin-bottom:8px;}
.doc-contact{font-family:system-ui,sans-serif; border-top:1px solid #e5e5e0; padding-top:10px; margin-top:10px; font-size:.7rem; color:#999; letter-spacing:.3px;}
body.print-mode #printArea .doc{box-shadow:none; max-width:100%;}

/* ================= WAVE 11 — CHECK PRINTING (check-on-top) ================= */
.check-sheet{background:#fff; font-family:'Courier New',monospace; color:#111;}
.check-top{position:relative; height:3.4in; padding:.35in .45in; border-bottom:1px dashed #bbb;}
.check-no{position:absolute; top:.32in; right:.55in; font-weight:700; font-family:system-ui,sans-serif;}
.ck-company{position:absolute; top:.45in; left:.75in; font-family:system-ui,sans-serif; font-size:11px; font-weight:700; line-height:1.35;}
.ck-bank{position:absolute; top:.45in; left:4.2in; font-family:system-ui,sans-serif; font-size:10px; line-height:1.35; text-align:center;}
.ck-date{position:absolute; top:1.05in; right:.9in; font-size:12px;}
.ck-lbl{font-size:9px; font-weight:700;}
.ck-payline{position:absolute; top:1.45in; left:.55in; right:.55in; font-size:11px;}
.check-payee{display:inline-block; min-width:4.2in; font-size:13px; padding:0 4px 2px;}
.check-amtbox{float:right; padding:4px 10px; font-size:13px; font-weight:700;}
.check-words{position:absolute; top:2.05in; left:.55in; right:.55in; font-size:12px; padding-bottom:2px;}
.check-memo{position:absolute; top:2.7in; left:.55in; right:.55in; font-size:11px;}
.check-sig{float:right; text-align:center; font-size:11px;}
.check-stub{height:3.4in; padding:.4in .45in; border-bottom:1px dashed #bbb; font-family:system-ui,sans-serif; font-size:13px; line-height:1.7;}
body.print-mode #printArea .check-sheet{width:8.5in;}
@media print{ body.print-mode #printArea{padding:0 !important;} }

/* ================= CHECK PRINT ALIGNMENT — measurements from the paper's true edge ================= */
@media print{
  @page{ margin:0; }
  body.print-mode #printArea{ padding:0.5in !important; }                 /* documents & reports keep a nice margin */
  body.print-mode #printArea:has(.check-sheet){ padding:0 !important; }   /* checks: field positions = inches from the paper edge */
  .check-top{ height:3.5in; }
}

/* ================= CHECK PRINT — hard one-page guarantee ================= */
@media print{
  html, body.print-mode{ margin:0 !important; padding:0 !important; }
  body.print-mode #printArea .check-sheet{ width:8.5in; height:10.9in; overflow:hidden; page-break-inside:avoid; page-break-after:avoid; }
  body.print-mode #printArea .check-sheet .check-top{ height:3.5in; }
  body.print-mode #printArea .check-sheet .check-stub{ height:3.6in; box-sizing:border-box; }
}

/* ================= WAVE 15 — VISUAL CHECK DESIGNER ================= */
.ck-design{position:relative; width:100%; aspect-ratio:8.5/3.5; border:2px dashed var(--border); border-radius:8px; margin-top:10px;
  background:#fff center/100% 100% no-repeat; overflow:hidden; touch-action:none; font-family:'Courier New',monospace; user-select:none;}
.ck-chip{position:absolute; cursor:grab; white-space:nowrap; padding:1px 3px; border:1px dashed rgba(30,122,50,.6); border-radius:4px;
  background:rgba(255,255,255,.6); line-height:1.2; max-width:96%;}
.ck-chip:active{cursor:grabbing;}
.ck-chip.sel{border:2px solid #1e7a32; background:rgba(190,242,100,.4); z-index:5;}
.ck-nudge{display:flex; gap:6px; align-items:center; margin-top:8px; flex-wrap:wrap;}
.ck-nudge button{min-width:40px;}

/* ================= WAVE 18 — TEAM HUB ================= */
.emp-dock{position:fixed; left:0; right:0; bottom:62px; background:#fff; border-top:1.5px solid var(--border);
  padding:8px 12px calc(8px + env(safe-area-inset-bottom)); display:flex; gap:12px; overflow-x:auto; align-items:flex-start;
  z-index:49; box-shadow:0 -4px 14px rgba(0,0,0,.07);}
/* ================= WAVE 68 — WHOSE CREW IS HE ON =================
   These two never follow the company theme. --green is redefined to orange
   under body.co-at, which is why every face on the board used to turn orange
   the moment you looked at Advanced. */
:root{ --qt-mark:#1e7a32; --at-mark:#d96b12; }
.emp-ring{position:relative; border-radius:50%; padding:2px; box-sizing:border-box;
  cursor:pointer; flex-shrink:0; margin:0 auto; display:block;}
.emp-ring.co-qt{background:var(--qt-mark);}
.emp-ring.co-at{background:var(--at-mark);}
/* works for both outfits — half and half, straight down the middle */
.emp-ring.co-both{background:linear-gradient(90deg, var(--qt-mark) 0 50%, var(--at-mark) 50% 100%);}
.emp-ring .nav-badge{position:absolute; top:-3px; right:-3px; z-index:2;}
.emp-bubble{position:relative; width:100%; height:100%; border-radius:50%;
  background:#e8f0e9 center/cover no-repeat; color:#155c24; font-weight:800;
  display:flex; align-items:center; justify-content:center; overflow:hidden;}
.emp-ring.co-qt .emp-bubble{background-color:#e8f3ec; color:#155c24;}
.emp-ring.co-at .emp-bubble{background-color:#fdeedd; color:#a84f08;}
.emp-ring.co-both .emp-bubble{background-image:linear-gradient(90deg,#e8f3ec 0 50%,#fdeedd 50% 100%); color:#2f3a2f;}

/* ================= WAVE 19 — APP LOCK ================= */
#lockOv{position:fixed; inset:0; background:var(--paper, #f7f6f2); z-index:20000; display:flex; align-items:center; justify-content:center;}

/* ================= VIEW-AS BANNER ================= */
.viewas-bar{position:fixed; top:0; left:0; right:0; background:#6d28d9; color:#fff; z-index:10002; padding:10px 14px; text-align:center; font-weight:800; font-size:.85rem; cursor:pointer; box-shadow:0 2px 10px rgba(0,0,0,.3);}
body.viewing-as #appHeader{margin-top:40px;}

/* WAVE 126 — THE HAT RACK. Deliberately a different colour from View As above:
   purple means you are looking at somebody ELSE and the buttons are disarmed;
   amber means you are still you, with all your rights, on a different set of
   screens — and anything you press really happens. Two bars that meant almost
   the same thing in the same colour would be worse than one. */
.hat-bar{position:fixed; top:0; left:0; right:0; background:#b45309; color:#fff; z-index:10002; padding:10px 14px; text-align:center; font-weight:800; font-size:.85rem; cursor:pointer; box-shadow:0 2px 10px rgba(0,0,0,.3);}
body.wearing-hat #appHeader{margin-top:40px;}
.hat-pick{display:block; width:100%; text-align:left; margin-top:8px; padding:11px 13px; border:1px solid var(--border); border-radius:11px; background:var(--card,#fff); font-size:.92rem; font-weight:700; cursor:pointer;}
.hat-pick .sub{display:block; font-weight:500; font-size:.72rem; color:#6b7280; margin-top:2px;}
.hat-pick.on{border-color:#b45309; box-shadow:inset 0 0 0 1px #b45309;}

/* WAVE 75 — "you are being recorded right now", where a man can see it. Grey
   is the honest resting state: he said yes, and it is half past eight at night
   so nothing is being saved. */
.loc-chip{display:inline-block; margin-left:6px; padding:2px 8px; border-radius:999px; font-size:.66rem; font-weight:800; background:#eef1f4; color:#4b5563; border:1px solid #d7dce2; cursor:pointer; white-space:nowrap;}
.loc-chip.on{background:#e8f4ec; color:#146c33; border-color:#a9d8bb;}

/* WAVE 30 — inbox dock zones: trees left · construction right · office bottom middle */
.emp-dock{display:block; max-height:200px; overflow-y:auto;}
/* WAVE 68 — everything down the middle. Pushed to the outside edges it fell
   apart on a phone: two ragged columns with a hole between them. */
/* WAVE 69 §2 — the dock groups by CREW, each with its badge and name. Wave 68
   grouped the tree men by outfit, which was right when a crew was just a
   colour; now that men are stood on crews the useful question here is who is
   with who today. No resting mode: everybody starts on the main crew, so this
   is one heading most of the time and splits when the men actually split. */
.dock-groups{display:flex; flex-wrap:wrap; justify-content:center; gap:10px 14px; align-items:flex-start;}
.dock-group{display:flex; flex-direction:column; align-items:center; gap:5px;
  padding:5px 9px 4px; border-radius:11px; background:#fafaf9; border:1px solid var(--border);}
.dock-faces{display:flex; flex-wrap:wrap; gap:8px; justify-content:center;}
.dock-lbl{max-width:180px; font-size:.58rem; font-weight:800; color:var(--muted); letter-spacing:.06em; text-align:center;}

/* WAVE 32b — drag-to-reorder sites */
.drag-handle{cursor:grab; font-size:1.15rem; color:var(--muted); padding:4px 8px; user-select:none; -webkit-user-select:none; flex-shrink:0;}
.drag-handle:active{cursor:grabbing;}
.lan-site-card.dragging{opacity:.65; outline:2px dashed #b45309; box-shadow:0 8px 20px rgba(0,0,0,.15);}

/* WAVE 35 — schedule: board + map stacked on the LEFT, calendar on the RIGHT */
.sched-v2{grid-template-columns:1.15fr 1fr;}
.sched-left{display:flex; flex-direction:column; gap:14px; min-width:0;}
.sched-right{min-width:0;}
@media (max-width:900px){ .sched-v2{grid-template-columns:1fr;} }

/* WAVE 36 — appointment ghosts: there, but not real yet */
.cal-job.ghost{opacity:.5; background:transparent; border:1.5px dashed #6b7280; color:#374151; cursor:pointer;}
.day-job.ghost{opacity:.45; background:rgba(107,114,128,.12); border:2px dashed #6b7280; color:#1f2937; cursor:pointer;}
.cal-job.ghost:hover,.day-job.ghost:hover{opacity:.8;}

/* ================= WAVE 62 — THE LINES ================= */
.line-wrap{display:grid; grid-template-columns:repeat(auto-fill,minmax(300px,1fr)); gap:12px;}
.line-card{background:var(--card,#fff); border:1px solid var(--border); border-radius:14px; overflow:hidden;}
.line-head{padding:11px 13px; background:#f7f9f7; border-bottom:1px solid var(--border);}
.line-row{display:flex; gap:10px; align-items:flex-start; padding:10px 13px; border-bottom:1px solid var(--border); cursor:pointer;}
.line-row:last-of-type{border-bottom:0;}
.line-row:active{background:#f2f6f2;}
.line-row.current{background:#f4faf5;}
.line-row.rolling{background:#eefaf0; border-left:4px solid var(--green);}
.line-rank{width:26px; flex:none; text-align:center; font-weight:800; color:#6b7280; padding-top:2px;}
.line-row.current .line-rank{color:var(--green); font-size:1.05rem;}

/* ================= WAVE 63 — THE SWITCH AND THE DECK ================= */
.line-switch{display:flex; gap:10px; align-items:center; padding:9px 13px; border-top:1px solid var(--border);
  background:#f1f2f1; transition:background .3s;}
.line-switch.on{background:#e8f7ec;}
.switch-btn{flex:none; width:52px; height:29px; border-radius:999px; border:2px solid #cbd5e1; background:#e5e7eb;
  position:relative; cursor:pointer; transition:background .25s, border-color .25s; padding:0;}
.switch-btn.on{background:var(--green,#087134); border-color:var(--green,#087134);}
.switch-btn:disabled{opacity:.4; cursor:not-allowed;}
.switch-knob{position:absolute; top:2px; left:2px; width:21px; height:21px; border-radius:50%; background:#fff;
  box-shadow:0 1px 3px rgba(0,0,0,.3); transition:transform .25s;}
.switch-btn.on .switch-knob{transform:translateX(23px);}
/* the line itself goes green while it is live */
.line-card:has(.line-switch.on){border-color:var(--green,#087134); box-shadow:0 0 0 1px rgba(8,113,52,.18);}
.line-card:has(.line-switch.on) .line-head{background:#e8f7ec;}

/* the deck — an off-centre hand of cards waiting to be picked up */
.deck-wrap{padding:9px 13px; border-top:1px dashed var(--border);}
.deck{position:relative; padding-bottom:8px;}
.deck-card{background:#fff; border:1px solid var(--border); border-radius:10px; padding:9px 11px; cursor:pointer;
  margin-left:calc(var(--i,0) * 7px); margin-top:-2px; position:relative; z-index:calc(40 - var(--i,0));
  box-shadow:0 2px 5px rgba(0,0,0,.09); transition:transform .14s, box-shadow .14s;}
.deck-card:first-child{margin-top:0;}
.deck-card:hover,.deck-card:active{transform:translateX(6px) translateY(-2px); box-shadow:0 5px 14px rgba(0,0,0,.16); z-index:60;}

/* ================= WAVE 64 — THE CREW ON A LIVE LINE ================= */
.line-art-wrap{background:linear-gradient(180deg,#f3f8f3 0%,#e9f4ea 100%); border-top:1px solid var(--border);
  border-bottom:1px solid var(--border); overflow:hidden; line-height:0;}
.line-art-wrap svg{display:block;}


/* ================= WAVE 68 — THE X ON EVERY WINDOW =================
   Sticky so it stays reachable in a long window that has been scrolled, and it
   floats so the content that follows flows around it rather than under it. */
.modal-x{position:sticky; top:-6px; float:right; z-index:5; margin:-8px -4px 0 8px;
  width:34px; height:34px; border-radius:50%; border:1px solid var(--border);
  background:#fff; color:#444; font-size:1rem; line-height:1; cursor:pointer;
  display:flex; align-items:center; justify-content:center; box-shadow:0 1px 4px rgba(0,0,0,.12);}
.modal-x:hover{background:#f3f4f6; color:#111;}
.modal-x:active{transform:scale(.94);}

/* WAVE 129 — THE GREY IS GONE. Wave 69 dimmed a stump or finishing card that
   was on the board before the tree crew had finished, and wrote in this very
   comment that it did NOT mean locked. Nobody read the comment. Grey on a phone
   in the sun reads as "off", and the men were treating perfectly workable jobs
   as untouchable. It is a PICTURE now, not a fade: a tree still standing means
   nobody has been yet, a tree on its side means a crew is on it, a stump means
   grind it, a pile of brush means come and get it. See .job-mark below. */
/* WAVE 69c — a crew on an override, and the one job that put them there */
.hot-banner{margin-top:7px; background:#fee2e2; border:1px solid #fca5a5; color:#7f1d1d;
  border-radius:9px; padding:7px 10px; font-size:.74rem; font-weight:600; line-height:1.35;}
.line-row.hot{background:#fff1f0; border-left:4px solid #b91c1c;}
.line-row.hot .line-rank{color:#b91c1c;}
/* WAVE 77 — a crew on the Inbox map. Green while they are on a job, grey and
   quiet when they are sat at the lot with nothing on. */
.crew-pin{width:30px; height:30px; border-radius:50%; background:#1e7a32; border:2.5px solid #fff;
  box-shadow:0 2px 6px rgba(0,0,0,.35); display:flex; align-items:center; justify-content:center;
  font-size:15px; line-height:1;}
.crew-pin.idle{background:#9ca3af;}

/* WAVE 74 — a nudge, not an order. The closest job to where the crew will be
   standing, said quietly under the switch. Nothing moves until somebody taps. */
.next-nudge{margin-top:7px; background:#eff6ff; border:1px solid #bfdbfe; color:#1e3a8a;
  border-radius:9px; padding:7px 10px; font-size:.74rem; line-height:1.35;}

/* ===== WAVE 69 — THE POSTER BOARDS =====================================
   One board per kind of crew, with that kind's crews thumb-tacked underneath.
   Two tree crews hang under ONE tree board; a third adds a column beside them.
   A board never disappears — not with no crews, not with no work. The crew
   line vanishing on a quiet afternoon is the thing this replaces. */
.boards{display:flex; flex-direction:column; gap:18px; margin-top:22px;}
/* the cork and the dotted texture are lifted from the OLD schedule board that
   Wave 62 deleted — that pinned-note look is exactly what "thumb tack poster
   board" means, and its CSS was still sitting dead in this file. Its `.board`
   also carried min-height:600px, which silently stretched every one of these
   to 600px tall until it was removed. */
.board{border:2px solid #e2d9c3; border-radius:14px; padding:10px 10px 12px;
  background:#f7f3ea; background-image:radial-gradient(#d9cfae 1px, transparent 1px);
  background-size:22px 22px;}
.board-head{display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  padding:6px 6px 10px; border-bottom:1px dashed #d9cfbb; margin-bottom:8px;}
.board-head .pin{font-size:1.05rem; line-height:1;}
.board-head b{font-size:1.02rem;}
/* the crews hang side by side and wrap onto a new row on a phone */
.board-crews{display:flex; gap:12px; align-items:flex-start; flex-wrap:wrap;}
.board-crews > .line-card{flex:1 1 290px; min-width:0; background:var(--card,#fff);}
.board-crews > .card{flex:1 1 290px;}
/* the three boards read as three different jobs, not three copies of one —
   a tint over the same cork, so they still look like one wall */
.board-tree{border-color:#cfe0d2;}
.board-stump{border-color:#e2d9c3;}
.board-cleanup{border-color:#cdd9e4;}
.board-tree .board-head b{color:var(--green-dark,#155c24);}
.board-stump .board-head b{color:#7c5a1e;}
.board-cleanup .board-head b{color:#1e4f7c;}
/* the cards hang ON the board, so they get the pinned-note shadow */
.board-crews > .line-card{box-shadow:2px 3px 8px rgba(0,0,0,.13);}
/* The deck was drawn as a STACK — each card nudged `--i * 7px` right and
   overlapping the one above. That reads well inside a 290px crew card and
   falls apart stretched across a whole board. On a board they are notes
   pinned side by side instead, wrapping onto the next row. */
.board > .deck-wrap{border-top:0; padding:2px 4px 10px;}
.board .deck{display:flex; flex-wrap:wrap; gap:10px; padding-bottom:0;}
.board .deck-card{margin:0; flex:0 1 236px; max-width:100%;}
@media (max-width:520px){ .board .deck-card{flex:1 1 100%;} }
@media (max-width:520px){
  .boards{gap:14px; margin-top:14px;}
  .board{padding:8px 8px 10px;}
}

/* WAVE 69b — the fixed marks for the teams that are not crews. Sales, subs,
   maintenance and LAN never sit on a line, so their badge is a chip beside
   the name rather than a crew logo. */
.team-chip{display:inline-block; margin-left:5px; font-size:.95rem; line-height:1; vertical-align:-1px;}

/* WAVE 83 said "one visual language for the tree crew has not been yet", and it
   was right about wanting one language and wrong about which one. WAVE 129 kept
   the principle and swapped the dimming for .job-mark — the deck card and the
   line row wear the same mark, so a job looks the same in the pile it waits in
   and on the crew it lands on. */

/* WAVE 85 — room to pin things up. The deck on a board was squeezed into
   2px of top padding under the heading, so the cards read as a cramped strip
   rather than a poster board with notes on it. The stump deck inside a crew
   card looks right because it is small on purpose; stretched across a whole
   board it wanted air. Taller cards, more space above the crews, and a wider
   flex basis so a card holds an address on one line instead of wrapping. */
.board > .deck-wrap{padding:10px 6px 16px; min-height:96px;}
.board .deck{gap:12px;}
.board .deck-card{flex:0 1 272px; padding:11px 13px; line-height:1.4;}
.board .deck-card b{font-size:1rem;}
/* the pinned-notes area keeps its own ground so an empty board still reads as
   a board with space on it, not as a heading with nothing underneath */
.board > .deck-wrap:not(:has(.deck-card)){min-height:56px;}
@media (max-width:520px){
  /* WAVE 110 — min-height:0 removed. It was the one rule that gave the pinned
     space back on a phone, which is the screen the crew actually hold, and it
     now contradicts the Wave 110 block at the foot of this file. Two rules
     fighting where the later one happens to win is not a decision, it is a
     coin toss waiting for somebody to reorder the file. */
  .board > .deck-wrap{padding:8px 4px 12px;}
  .board .deck-card{flex:1 1 100%;}
}

/* ================= WAVE 108 — DRAW ON THE PICTURE ================= */
/* The little corner handle on every thumbnail. The photograph itself still
   opens full size on a tap; this is its own button, sat in the corner. */
.photo-strip .ph .ph-mk{position:absolute; right:2px; bottom:2px; width:26px; height:26px; border-radius:8px;
  background:rgba(17,24,39,.72); color:#fff; font-size:.85rem; display:flex; align-items:center; justify-content:center;
  cursor:pointer; z-index:2; line-height:1;}
.photo-strip .ph .ph-mk:active{background:var(--green);}

/* The marker takes the whole screen. A drawing surface inside a bottom sheet
   fights the sheet for every finger-drag, and the sheet wins. */
.pm-wrap{position:fixed; inset:0; z-index:10100; background:#0b0f14; display:flex; flex-direction:column;
  overscroll-behavior:none;}
.pm-top{display:flex; align-items:center; justify-content:space-between; gap:8px; padding:10px 12px;
  background:var(--charcoal); color:#fff; font-size:.9rem; flex:0 0 auto;}
.pm-x, .pm-done{border:none; border-radius:10px; padding:10px 14px; font-weight:800; font-size:.9rem; cursor:pointer;}
.pm-x{background:rgba(255,255,255,.14); color:#fff;}
.pm-done{background:var(--lime); color:var(--charcoal);}
.pm-stage{flex:1 1 auto; min-height:0; display:flex; align-items:center; justify-content:center; padding:6px; overflow:hidden;}
/* touch-action:none is the whole trick — without it the phone reads a drawing
   stroke as a scroll and the line never appears. */
.pm-stage canvas{max-width:100%; max-height:100%; touch-action:none; border-radius:6px; background:#000;
  box-shadow:0 4px 18px rgba(0,0,0,.5);}

.pm-tools{flex:0 0 auto; background:#151b23; padding:8px 10px calc(10px + env(safe-area-inset-bottom)); border-top:1px solid #263140;}
.pm-row{display:flex; gap:6px; align-items:center; justify-content:space-between; margin-bottom:8px;}
.pm-tool{flex:1; display:flex; flex-direction:column; align-items:center; gap:2px; padding:9px 2px;
  background:#1f2937; color:#cbd5e1; border:2px solid transparent; border-radius:12px; font-size:1.15rem; cursor:pointer;}
.pm-tool span{font-size:.6rem; font-weight:700; letter-spacing:.2px;}
.pm-tool.on{background:#0f2f1c; border-color:var(--lime); color:#fff;}
.pm-colors{justify-content:flex-start; gap:10px;}
.pm-color{width:38px; height:38px; border-radius:50%; border:3px solid #334155; cursor:pointer; padding:0;}
.pm-color.on{border-color:#fff; transform:scale(1.12);}
.pm-tools input#pmNote{width:100%; padding:12px; border-radius:12px; border:1.5px solid #334155;
  background:#0b0f14; color:#fff; font-size:1rem;}
.pm-tools input#pmNote::placeholder{color:#64748b;}

/* Slides up only when a label is being placed, so the note box underneath is
   never covered while he is typing in it. */
.pm-textbar{position:absolute; left:0; right:0; bottom:0; display:none; gap:6px; padding:12px;
  background:var(--charcoal); z-index:2;}
.pm-textbar.open{display:flex;}
.pm-textbar input{flex:1; padding:12px; border-radius:12px; border:1.5px solid #334155; background:#0b0f14; color:#fff; font-size:1rem;}

/* ================= WAVE 110 — ROOM ON THE BOARD ==================
   "More board space above each of the 3 lines so there is more space, and the
   job cards pop up in that blank space when a job is approved."

   The deck was a thin strip that collapsed to nothing on a phone — the very
   screen the crew hold. It is a pinned-up area now: it keeps its height with
   nothing on it, so the empty space reads as SPACE FOR SOMETHING rather than
   as a board that failed to load. Cork tint and a dashed edge, because a man
   should be able to tell at a glance where the board ends and the crews
   begin.                                                                    */
.board > .deck-wrap{
  min-height:132px;
  padding:12px 10px 16px;
  background:rgba(180,150,100,.055);
  border:1px dashed rgba(150,120,80,.34);
  border-radius:11px;
  margin-bottom:12px;
}
/* WAVE 129 — THREE BOARDS, THREE TINTS, ONE SHAPE. Green for the trees, yellow
   for the Stump Boyz, blue for the Finishing Crew. The tint is the ONLY thing
   that differs — same padding, same min-height, same dashed edge — so they read
   as three jobs on one wall rather than three different designs.

   The stump board had no rule at all and wore the cork default above it, which
   is why it looked like a different thing from the green one. And the blue was
   too weak to survive being laid over that cork: at 5% over a warm ground it
   came out grey, which is not a colour, it is the absence of one. Both were
   checked against the real stylesheet in a browser, side by side and empty —
   the state where a tint is all there is to look at. */
.board-tree    > .deck-wrap{background:rgba(30,122,50,.055); border-color:rgba(30,122,50,.26);}
.board-stump   > .deck-wrap{background:rgba(202,138,4,.085); border-color:rgba(180,120,10,.34);}
.board-cleanup > .deck-wrap{background:rgba(37,99,235,.075); border-color:rgba(30,79,124,.30);}
/* An empty board still keeps most of its room — a card has to have somewhere
   to appear, and a space that grows only once something is in it makes the
   whole page jump the moment a job is approved. */
.board > .deck-wrap:not(:has(.deck-card)){min-height:104px;}
.board > .deck-wrap:not(:has(.deck-card)) .muted{opacity:.75;}

/* On a phone it keeps the room. This is the one place the old rules gave the
   space back (min-height:0), and a phone is what the crew are holding. */
@media (max-width:520px){
  .board > .deck-wrap{min-height:120px; padding:11px 7px 14px;}
  .board > .deck-wrap:not(:has(.deck-card)){min-height:92px;}
}

/* The crew's own view of the board: one board, one line, nothing to tune. */
.board-crews > .line-card{flex:1 1 290px;}

/* ================= WAVE 112 — MOVING CARDS BY HAND =================
   touch-action:none is on the GRIP ALONE. Put it on the card and the board
   stops scrolling, because the board is nothing but cards; leave it off the
   grip and the browser scrolls instead of dragging. This one line is the whole
   reason there is a grip at all. */
.grip{
  flex:0 0 auto; width:30px; align-self:stretch; min-height:34px;
  display:flex; align-items:center; justify-content:center;
  color:#9ca3af; font-size:1.05rem; letter-spacing:-1px; cursor:grab;
  touch-action:none; user-select:none; -webkit-user-select:none;
  border-radius:8px;
}
.grip:active{cursor:grabbing; background:rgba(0,0,0,.06);}
.grip.frozen{cursor:default; color:#c4b5fd; font-size:.8rem;}
.deck-grip{position:absolute; top:4px; right:4px; width:26px; min-height:26px; align-self:auto;
  background:rgba(0,0,0,.05);}
.deck-card{position:relative;}

/* What is being dragged: a copy under the thumb, and the original left behind
   greyed so it is obvious where it came from. */
.drag-ghost{
  position:fixed !important; z-index:10200; pointer-events:none;
  opacity:.94; transform:rotate(1.4deg) scale(1.02);
  box-shadow:0 12px 28px rgba(0,0,0,.32); margin:0 !important;
}
.drag-src{opacity:.34;}

/* Where it may land. A crew lights up only when the card belongs on that
   board — a tree card over the stump crew gets nothing, on purpose. */
.line-card.drop-ok{outline:3px dashed var(--green); outline-offset:3px; background:var(--green-light);}
.line-row.drop-line{box-shadow:inset 0 3px 0 var(--green);}

/* Ticking several. */
.pick-box{flex:0 0 auto; width:30px; display:flex; align-items:center; justify-content:center; font-size:1.05rem;}
.deck-card .pick-box{position:absolute; top:4px; right:4px; width:26px;}
.line-row.picked, .deck-card.picked{background:var(--green-light); outline:2px solid var(--green); outline-offset:-2px;}

/* The bar sits above the bottom nav, not under it. */
.pick-bar{
  position:sticky; bottom:0; z-index:70; margin-top:14px;
  background:#fff; border:2px solid var(--green); border-radius:14px 14px 0 0;
  padding:10px 12px calc(12px + env(safe-area-inset-bottom));
  box-shadow:0 -6px 18px rgba(0,0,0,.14);
}

/* ============ WAVE 129 — THE TREE, THE STUMP AND THE BRUSH PILE ============
   One mark, drawn the same on a deck card, a line row, the crew's day screen
   and the office job sheet. It replaces the Wave 69 grey, which said "future"
   to the person who wrote it and "switched off" to everybody else.

     🌳            the tree is still standing — nobody has been yet
     🌳 rotated    a crew is on it right now (the row names them)
     🪵            tree down, this stump wants grinding
     🌿            tree down, there is a load to pick up
     ✅            that crew's part is finished

   The tree on its side is a rotation, not a second glyph: no emoji font
   anywhere ships a felled tree, and rotating the one everybody already reads
   as "tree" is what makes it obvious rather than something to be taught. */
.job-mark{display:inline-block; line-height:1; font-size:1.05rem; vertical-align:-1px;}
.job-mark.spin{transform:rotate(90deg);}
.line-rank .job-mark{font-size:1.15rem;}
.deck-card b .job-mark{margin-right:3px;}

/* ---------------------------------------------------------- his work, on top
   The stump grinder opens a job and sees every stump on that property before
   anything else; the finishing crew sees every pile. Big enough to recognise a
   stump in a yard from the truck, which a 74px bid thumbnail is not. */
.work-strip{display:flex; gap:10px; flex-wrap:wrap; margin-top:8px;}
.work-strip .ph{
  position:relative; overflow:hidden; cursor:pointer;
  flex:0 1 148px; height:130px; border-radius:12px;
  border:2px solid var(--border); background:var(--green-light);
}
@media (max-width:520px){ .work-strip .ph{flex:1 1 44%; height:124px;} }
.work-strip .ph img{width:100%; height:100%; object-fit:cover; display:block;}
.work-strip .ph .ph-n{
  position:absolute; left:5px; top:5px; min-width:22px; height:22px; padding:0 6px;
  border-radius:7px; background:rgba(17,24,39,.72); color:#fff;
  font-size:.72rem; font-weight:700; line-height:22px; text-align:center;
}
/* Ticked off. Dimmed HERE is right and dimmed on a job card was wrong, because
   this dim means "you did that one", which is the only thing it can mean. */
.work-strip .ph.done{border-color:var(--green); }
.work-strip .ph.done img{opacity:.42; filter:grayscale(.55);}
/* The UNticked one has to read as a button sitting on a photograph, not as a
   watermark. Checked over a mid-tone image in a browser: at 92% white with a
   hairline border the pale ⬜ glyph disappeared into its own chip. */
.work-strip .ph .ph-tick{
  position:absolute; right:5px; bottom:5px; width:32px; height:32px; border-radius:9px;
  background:#fff; border:2px solid #6b7280; box-shadow:0 1px 5px rgba(0,0,0,.3);
  display:flex; align-items:center; justify-content:center; font-size:1.05rem;
}
.work-strip .ph.done .ph-tick{background:var(--green); border-color:var(--green); color:#fff;}
.work-head{display:flex; align-items:baseline; justify-content:space-between; gap:10px; flex-wrap:wrap;}

/* WAVE 129 — 🪵 in the OTHER bottom corner of a bid thumbnail: "this one is a
   stump wanting ground". Off it is the same dark handle as ✏️; on it goes
   amber and the whole tile takes a ring, so a salesman can see at a glance
   which of nine pictures he has marked without tapping through them. */
.photo-strip .ph .ph-stump{right:auto; left:2px; background:rgba(17,24,39,.62);}
.photo-strip .ph .ph-stump.on{background:#b45309; color:#fff;}
.photo-strip .ph.is-stump{border-color:#b45309; box-shadow:inset 0 0 0 2px #b45309;}

/* WAVE 129 — where the 👍 sits. On a line row it centres in the row's own
   flex; on a deck card it pins to the bottom-right corner, opposite the tick
   box that claims the top-right in selection mode, and the card makes room for
   it so it can never land on the address. */
.line-row > [data-thumb]{align-self:center; flex:0 0 auto; margin-left:4px;}
.deck-card > [data-thumb]{position:absolute; right:6px; bottom:6px; z-index:3;}
.deck-card:has([data-thumb]){padding-bottom:30px;}

/* ============ WAVE 130 — TEST MODE ========================================
   Red, and deliberately not the amber of a hat or the purple of View As. Those
   two change WHOSE SCREEN you are on. This one changes whether any of it is
   real, which is a bigger thing, so it gets the loudest colour in the app and
   it never scrolls away. */
.test-bar{
  position:fixed; top:0; left:0; right:0; z-index:10003;
  background:#b91c1c; color:#fff; padding:10px 14px; text-align:center;
  font-weight:800; font-size:.85rem; line-height:1.35; cursor:pointer;
  box-shadow:0 2px 10px rgba(0,0,0,.34);
}
/* Same mechanism the hat bar already uses — push the header, not the body, or
   the two disagree about where the top of the page is. */
body.in-test-mode #appHeader{margin-top:44px;}
/* Both at once is legitimate, and it is exactly the thing this wave is for:
   the owner wearing a foreman's hat to test the foreman's screens. They stack,
   and the test bar stays on top because it outranks the hat. */
body.in-test-mode.wearing-hat #appHeader{margin-top:88px;}
body.in-test-mode .hat-bar{top:44px;}

/* A real bid request during a test: it landed, it is waiting, and nobody may
   touch it until the test is over. Greyed HERE is right — this one really is
   switched off, which is the opposite of the Wave 69 case. */
.req-card.req-locked{background:#f8fafc; opacity:.72; border-style:dashed; cursor:not-allowed;}
.req-card .req-lock{
  background:#fee2e2; color:#7f1d1d; border:1px solid #fca5a5; border-radius:8px;
  padding:5px 9px; margin-bottom:7px; font-size:.72rem; font-weight:700;
}

/* ---- WAVE 154 — the insurance packet document ----
   .pk-anch is the DocuSign anchor: real text, white on white, so it is in the
   PDF for DocuSign to find and invisible to the customer who signs it. Never
   give it display:none — a hidden element does not make it into the print. */
.pk-anch{color:#fff; font-size:6pt; letter-spacing:0; user-select:none;}
.pk-doc{font-size:.82rem;}
.pk-head{text-align:center; border-bottom:3px solid var(--dark); padding-bottom:10px; margin-bottom:14px;}
.pk-co{font-family:system-ui,sans-serif; font-weight:800; font-size:1.25rem; letter-spacing:2px;}
.pk-sub{font-family:system-ui,sans-serif; font-size:.68rem; color:#555; margin-top:3px;}
.pk-title{font-family:system-ui,sans-serif; font-weight:800; letter-spacing:2px; text-align:center; font-size:1rem; margin:4px 0;}
.pk-state{text-align:center; font-size:.72rem; color:#666; margin-bottom:12px;}
.pk-warn{border:2px solid #8a1f1f; color:#8a1f1f; background:#fdf0f0; padding:8px 10px; font-size:.72rem; font-family:system-ui,sans-serif; margin-bottom:14px;}
.pk-sec{margin:12px 0; page-break-inside:avoid;}
.pk-sec p{margin:5px 0 0;}
.pk-ph{font-family:system-ui,sans-serif; font-size:.6rem; letter-spacing:1px; color:#b91c1c; margin-top:4px;}
.pk-note{font-family:system-ui,sans-serif; font-size:.66rem; color:#666; margin-top:6px;}
.pk-grid{display:flex; flex-wrap:wrap; gap:10px 18px; margin-top:8px;}
.pk-blank{flex:1 1 240px; border-bottom:1px solid #333; padding-bottom:14px; position:relative;}
.pk-lbl{position:absolute; left:0; bottom:-14px; font-family:system-ui,sans-serif; font-size:.6rem; letter-spacing:1px; color:#777;}
.pk-inline{border-bottom:1px solid #333; padding:0 6px;}
.pk-foot{margin-top:22px; border-top:1px solid #ccc; padding-top:8px; font-family:system-ui,sans-serif; font-size:.62rem; color:#888; text-align:center;}

/* ---- WAVE 155 — the real packet's pages ---- */
.pk-page{page-break-after:always; padding-bottom:10px;}
.pk-page:last-of-type{page-break-after:auto;}
.pk-h2{font-family:system-ui,sans-serif; font-weight:800; letter-spacing:1px; font-size:.95rem; border-bottom:2px solid var(--dark); padding-bottom:4px; margin:16px 0 10px;}
.pk-lead{font-style:italic; margin:6px 0 14px;}
.pk-flag{font-family:system-ui,sans-serif; font-weight:800; letter-spacing:2px; color:#8a1f1f; text-align:center; margin:8px 0;}
.pk-rows{display:flex; flex-wrap:wrap; gap:22px 18px; margin:14px 0 18px;}
.pk-f{display:inline-block; border-bottom:1px solid #333; padding-bottom:14px; position:relative;}
.pk-fl{position:absolute; left:0; bottom:-13px; font-family:system-ui,sans-serif; font-size:.58rem; letter-spacing:.5px; color:#777; white-space:nowrap;}
.pk-slot{border:1px dashed #999; padding:18px; text-align:center; font-family:system-ui,sans-serif; font-size:.8rem; color:#555;}
.pk-rates{width:100%; border-collapse:collapse; margin:10px 0; font-size:.72rem;}
.pk-rates th{font-family:system-ui,sans-serif; font-size:.6rem; letter-spacing:1px; text-align:left; border-bottom:2px solid var(--dark); padding:5px 4px;}
.pk-rates td{border-bottom:1px solid #e5e5e0; padding:5px 4px; vertical-align:top;}

/* ================= WAVE 165 — THE STAGING TINT ================= */
/* The class is set by the detector in index.html, on staging, on Vercel branch
   previews and on localhost. Production never gets the class, so it never gets
   the colour — that is the deliberate failure direction.
   The blue sits behind the white cards, so it reads at the edges and between
   them without changing the contrast of anything you actually read. */
html.is-staging body{ background:#dbeafe; }
/* The cards cover most of the body on a phone, so the header's lime rule turns
   blue too — otherwise the screen the crews use would look identical to live. */
html.is-staging header{ border-bottom-color:#2563eb; }
/* WAVE 165a — THE LOGIN SCREEN COVERED THE TINT.
   Found by actually loading staging: .login-screen is a full-height charcoal
   div, so it paints straight over the blue body. That left the two sites
   identical at the exact moment it matters most — the sign-in, before anyone
   has looked at a single record. The sign-in screen carries the colour too. */
html.is-staging .login-screen{ background:#12233d; }
html.is-staging .login-card{ border-bottom-color:#2563eb; }

/* ================= WAVE 179 — THE CALENDAR COMES BACK =================
   Wave 2's calendar CSS survived the Wave 62 cull intact (.cal-grid, .cal-cell,
   .cal-dow, .cal-head, .cal-nav are all still above). These are the pieces the
   NEW calendar needs that the old one never had: the poster board across the
   top, a card that carries its own height, and the grip on its bottom edge.
   The old .board / .bcard cork-board is deliberately NOT restored — Wave 69
   took .board over for the crew poster boards and restoring it would break
   those. */
.cal-poster{background:#fffdf5; border:1px solid #e8ddb8; border-radius:14px; padding:11px 13px; margin-bottom:14px;}
.cal-poster.dragover{background:#f6f9f2; border-color:var(--green,#087134); border-style:dashed;}
.cal-poster-head{display:flex; flex-direction:column; gap:2px; margin-bottom:8px;}
.cal-poster-row{display:flex; gap:8px; overflow-x:auto; padding-bottom:4px; align-items:flex-start; min-height:34px;}
.cal-poster-row .cal-card{flex:0 0 auto; min-width:150px; max-width:210px;}
.cal-wrap{background:#fff; border:1px solid var(--border); border-radius:14px; padding:12px;}
.cal-cell{display:flex; flex-direction:column; gap:2px; min-height:96px; overflow:hidden;}
.cal-cell-top{display:flex; align-items:center; justify-content:space-between; gap:4px;}
.cal-open{border:0; background:transparent; cursor:pointer; font-size:.78rem; line-height:1; padding:1px 3px; color:var(--gray,#6b7280); border-radius:5px;}
.cal-open:hover{background:#eef2ee; color:#111;}
.cal-card{background:var(--green,#087134); color:#fff; border-radius:6px; padding:3px 6px; font-size:.62rem; font-weight:700;
  cursor:grab; overflow:hidden; position:relative; box-shadow:0 1px 3px rgba(0,0,0,.16);}
.cal-card:active{cursor:grabbing;}
.cal-card.dragging{opacity:.45; outline:2px dashed #fff;}
/* WAVE 229 — on a crew already. Slate instead of green so it reads as a
   different kind of thing at a glance, and the cursor never promises a drag
   that will not happen. */
.cal-card.crewed{background:var(--slate,#475569); cursor:pointer;}
.cal-card.crewed:active{cursor:pointer;}
.cal-card.sizing{outline:2px solid #fff; box-shadow:0 4px 12px rgba(0,0,0,.3);}
.cal-card-in{display:flex; flex-direction:column; gap:1px; line-height:1.25; pointer-events:none;}
.cal-card b{font-size:.66rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display:block;}
.cal-town{opacity:.85; font-weight:400; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.cal-hrs{opacity:.9; font-weight:700;}
/* the bottom edge you pull on. 7px is small on screen and still a real target
   for a finger, because the card above it does not take pointer events. */
.cal-grip{position:absolute; left:0; right:0; bottom:0; height:7px; cursor:ns-resize; touch-action:none;
  background:linear-gradient(180deg,rgba(255,255,255,0) 0%,rgba(255,255,255,.45) 100%);}
.cal-grip:hover{background:rgba(255,255,255,.6);}
@media (max-width:760px){
  .cal-cell{min-height:74px;}
  .cal-card{font-size:.58rem;}
}

/* ================= WAVE 181 — the week strip on the crew board ============= */
.wk-strip{display:flex;gap:6px;overflow-x:auto;padding:2px 0 8px;-webkit-overflow-scrolling:touch;}
.wk-day{flex:0 0 auto;min-width:64px;text-align:center;padding:7px 8px;border:1px solid var(--border);
  border-radius:10px;background:var(--card);line-height:1.25;}
.wk-day.wk-today{border-color:#1e7a32;box-shadow:inset 0 0 0 1px #1e7a32;}
.wk-day.wk-noday{background:#f8fafc;border-style:dashed;}
.wk-dow{font-size:.62rem;text-transform:uppercase;letter-spacing:.03em;color:var(--muted);font-weight:700;}
.wk-num{font-size:1.05rem;font-weight:800;}
.wk-n{font-size:.62rem;color:var(--muted);white-space:nowrap;}
/* the drop highlight has to read from a thumb's length away, on a phone, outside */
.wk-day.day-ok{background:#dcfce7;border-color:#1e7a32;transform:scale(1.06);}
.parked-note{margin:6px 12px 10px;padding:8px 10px;border:1px dashed var(--border);border-radius:9px;
  background:#f8fafc;font-size:.74rem;color:#334155;cursor:pointer;}
.parked-note:active{background:#eef2f7;}
