
:root{
  color-scheme: light;
  --bg:#f2f5f9;
  --ink:#0e1726; --ink2:#46536b; --ink3:#334155;
  --sub:#768397; --meta:#97a1b5; --icon-dim:#c2cad8; --nav-idle:#9aa5b8;
  --line:rgba(15,23,42,.07);
  --blue:#2c5ce5; --blue2:#1a3fb0; --blue-bg:#eaf0ff;
  --green:#16a34a; --green-bg:#e7f8ee;
  --amber:#d97706; --amber-ink:#92600b; --amber-meta:#a16207; --amber-bg:#fef3c7; --amber-soft:#fff9ed; --amber-bd:#fde8bf;
  --red:#ef4444; --zone:#eab308; --off:#c3ccda;
  --glass:rgba(255,255,255,.72); --glass-hi:rgba(255,255,255,.86); --glass-bd:rgba(255,255,255,.65);
  --card-sh:0 3px 14px -6px rgba(15,25,45,.14);
  --safe-top:env(safe-area-inset-top,0px); --safe-bot:env(safe-area-inset-bottom,0px);
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html{height:100%}
/* v1.177.0 (Alex): "Holding down on screen elements shouldn't allow select. Eg. When I held
   down my location button on the map to pin location. It selected the whole page." Nothing
   here had ever set user-select, so a long press did what a long press does on any web page
   - and v1.173.0's hold-to-drop-a-pin made that a gesture people are TOLD to perform. The
   chrome is unselectable and the iOS callout is off; selection is handed back below to the
   places where copying the text is the whole point. */
body{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;margin:0;padding:0;-webkit-text-size-adjust:100%;min-height:100vh;min-height:100dvh;min-height:var(--app-h,100dvh);touch-action:manipulation;color:var(--ink);font-family:'Plus Jakarta Sans',system-ui,-apple-system,sans-serif;-webkit-font-smoothing:antialiased;overflow:hidden;background:var(--bg)}
body::before{content:'';position:fixed;inset:0;background:radial-gradient(ellipse 70% 46% at 18% -8%,rgba(44,92,229,.10),transparent 60%),radial-gradient(ellipse 60% 40% at 96% 108%,rgba(227,32,42,.07),transparent 60%);pointer-events:none;z-index:0}
button{font-family:inherit}
::-webkit-scrollbar{width:0;height:0}
.tn-scroll{-ms-overflow-style:none;scrollbar-width:none}
@keyframes tnpulse{0%{transform:scale(1);opacity:.45}70%{transform:scale(2.4);opacity:0}100%{opacity:0}}
@keyframes tnsheet{from{transform:translateY(100%)}to{transform:translateY(0)}}
@keyframes tnpop{from{opacity:0;transform:scale(.94) translateY(6px)}to{opacity:1;transform:scale(1) translateY(0)}}
@keyframes tnfade{from{opacity:0}to{opacity:1}}
@keyframes spin{to{transform:rotate(360deg)}}

/* ===== glass card (TNFM light glass over template geometry) ===== */
.card{background:var(--glass);backdrop-filter:blur(20px) saturate(160%);-webkit-backdrop-filter:blur(20px) saturate(160%);border:1px solid var(--glass-bd);border-radius:22px;padding:18px 16px;box-shadow:var(--card-sh);margin-bottom:16px}
.card.tap{cursor:pointer;transition:transform .12s}
.asn-head{cursor:pointer;transition:transform .12s}
.asn-head:active{transform:scale(.99)}
.asn-acc{max-height:0;overflow:hidden;transition:max-height .3s cubic-bezier(.22,.61,.36,1)}
.asn-card.exp>.asn-head{border-bottom:1px solid var(--line);padding-bottom:14px;margin-bottom:2px}
.card.tap:active{transform:scale(.99)}
.tile{background:linear-gradient(135deg,rgba(255,255,255,.46) 0%,rgba(255,255,255,.1) 45%,transparent 72%),rgba(112,126,148,.24);backdrop-filter:blur(29px) saturate(200%) brightness(1.06);-webkit-backdrop-filter:blur(29px) saturate(200%) brightness(1.06);border-radius:18px;padding:11px 13px;box-shadow:inset 0 1px 0 rgba(255,255,255,.35)}
.tile .k{font-size:10px;color:var(--meta);font-weight:700}
.tile .v{font-size:14px;color:var(--ink);font-weight:700;margin-top:3px}
.sect{display:flex;align-items:center;justify-content:space-between;margin:4px 2px 10px}
.sect .h{font-size:15px;font-weight:800;color:var(--ink)}
.sect .lnk{font-size:12px;font-weight:700;color:var(--blue);cursor:pointer}
.chip{display:inline-flex;align-items:center;font-size:11px;font-weight:700;padding:5px 10px;border-radius:999px;white-space:nowrap}
.chip.ok{color:var(--green);background:rgba(22,163,74,.14)}
.chip.warn{color:var(--amber-meta);background:rgba(217,119,6,.16)}
.chip.blue{color:var(--blue);background:rgba(44,92,229,.13)}
.chip.dim{color:#64748b;background:rgba(100,116,139,.14)}
/* v1.178.0: the payroll row now carries four short chips, so they wrap to the right rather
   than squeezing the name column. .pay-rung is the n/6 ladder position. */
.pay-tags{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:4px;flex-shrink:0;max-width:56%}
.pay-tags .chip{font-size:10.5px;padding:4px 8px}
.pay-rung{font-style:normal;font-weight:800;opacity:.6;margin-left:5px;font-size:9.5px}
/* v1.182.0: the error dashboard. Operator UI - dense, monospaced where it is machine text,
   and deliberately plain: this card is read when something is wrong. */
.err-hd{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.err-hd h3{font-size:15px;font-weight:800;color:var(--ink);margin:0;flex:1}
.err-tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:10px}
.err-tile{background:rgba(118,131,151,.08);border-radius:12px;padding:9px 10px}
.err-tile .k{font-size:9.5px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;color:var(--meta)}
.err-tile .v{font-size:19px;font-weight:800;color:var(--ink);line-height:1.15;margin-top:2px}
.err-spark{display:flex;align-items:flex-end;gap:2px;height:34px;margin-bottom:10px}
.err-spark i{flex:1;background:rgba(227,32,42,.55);border-radius:2px 2px 0 0;min-height:2px;display:block}
.err-spark i.zero{background:rgba(118,131,151,.18)}
.err-row{display:flex;gap:8px;align-items:flex-start;padding:8px 2px;border-bottom:1px solid rgba(118,131,151,.14);cursor:pointer}
.err-row .t{font-size:10.5px;color:var(--meta);font-weight:700;flex:0 0 52px;font-variant-numeric:tabular-nums}
.err-row .m{flex:1;min-width:0}
.err-row .a{font-size:12.5px;font-weight:800;color:var(--ink)}
.err-row .d{font-size:11.5px;color:var(--sub);word-break:break-word}
.err-row .w{font-size:10.5px;color:var(--meta);font-weight:600;margin-top:1px}
.err-trace{background:rgba(118,131,151,.08);border-radius:10px;padding:8px 10px;margin:4px 0 8px;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10.5px;line-height:1.5;
  color:var(--ink2);white-space:pre-wrap;word-break:break-word}
.err-rate{font-size:10.5px;font-weight:800;padding:2px 6px;border-radius:6px;white-space:nowrap}
.err-rate.bad{background:rgba(227,32,42,.14);color:#b3261e}
.err-rate.warn{background:rgba(217,119,6,.16);color:var(--amber-meta)}
.err-rate.dim{background:rgba(118,131,151,.14);color:var(--meta)}
.chip.err{color:#dc2626;background:rgba(220,38,38,.12)}
.chip.up{text-transform:uppercase;letter-spacing:.4px;padding:5px 11px}

.va-x{border:0;background:transparent;padding:6px;margin-left:2px;color:var(--meta);display:flex;align-items:center;cursor:pointer}
.va-x svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2.4;stroke-linecap:round}
/* ===== impersonation banner ===== */
#asBanner{display:none;background:linear-gradient(90deg,#0f2a52,#17356a);color:#fff;text-align:center;padding:7px 14px 8px;font-weight:800;font-size:11px;text-transform:uppercase;letter-spacing:.1em;cursor:pointer}
body.impersonating #asBanner{display:block}
body.impersonating .view{padding-top:calc(114px + var(--safe-top))}

/* ===== views ===== */
.view{position:fixed;top:0;left:0;right:0;height:var(--app-h,100dvh);padding:calc(84px + var(--safe-top)) 14px calc(172px + var(--safe-bot));overflow-y:auto;-webkit-overflow-scrolling:touch;display:none;z-index:10}
.view.active{display:block}
#vSites{padding:0}

/* ===== HOME ===== */
#topBand{position:fixed;top:0;left:0;right:0;z-index:1500;background:#E3202A;padding-top:var(--safe-top);box-shadow:0 8px 22px -12px rgba(150,12,22,.6)}
.tb-main{display:flex;align-items:center;justify-content:space-between;padding:10px 16px 13px;min-height:44px;gap:12px}
.tb-left{flex:1;min-width:0}
.tb-actions{display:flex;align-items:center;gap:10px;flex-shrink:0}
.tb-slot{display:none}
body[data-view=home] .tb-home{display:block}
body[data-view=sites] .tb-sites{display:flex;align-items:center}
body[data-view=sheets] .tb-sheets{display:flex;align-items:center;gap:10px}
.tb-title{font-size:22px;font-weight:800;color:#fff;letter-spacing:-.01em}
.greet .g1{font-size:13px;color:rgba(255,255,255,.78);font-weight:600;line-height:1}
.greet .g2{font-size:22px;color:#fff;font-weight:800;margin-top:4px}
.rnd-btn{position:relative;width:44px;height:44px;border-radius:50%;background:var(--glass-hi);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border:1px solid var(--glass-bd);display:flex;align-items:center;justify-content:center;box-shadow:0 2px 8px -3px rgba(15,25,45,.18);cursor:pointer}
.rnd-btn svg{width:20px;height:20px;stroke:var(--ink3);fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.rnd-btn.spin svg{animation:spin 1s linear infinite}
.avatar{width:44px;height:44px;border-radius:50%;background:linear-gradient(135deg,#2c5ce5,#1a3fb0);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:15px;box-shadow:0 6px 14px -4px rgba(44,92,229,.55);cursor:pointer}
.week{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}
.wd{display:flex;flex-direction:column;align-items:center;gap:7px;padding:8px 0 6px;border-radius:14px}
.wd .dow{font-size:11px;font-weight:600;color:var(--meta)}
.wd .num{font-size:15px;font-weight:700;color:var(--ink)}
.wd .dot{width:5px;height:5px;border-radius:50%;background:transparent}
.wd.today{background:var(--blue)}
.wd.today .dow{color:rgba(255,255,255,.75)}
.wd.today .num{color:#fff}
.wd.today .dot{background:#fff}
.wd.worked .dot{background:var(--green)}
.wd.sched .dot{background:var(--blue)}
.wd.today.worked .dot,.wd.today.sched .dot{background:#fff}
.asn-top{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
.asn-l{display:flex;gap:13px;min-width:0}
.asn-ic{width:44px;height:44px;border-radius:14px;background:var(--blue-bg);display:flex;align-items:center;justify-content:center;flex-shrink:0}
.asn-ic svg{width:22px;height:22px;stroke:var(--blue);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.asn-site{font-size:16px;font-weight:800;color:var(--ink)}
.asn-sub{font-size:13px;color:var(--sub);font-weight:500;margin-top:2px}
.asn-meta{display:flex;gap:20px;margin-top:15px;padding-top:15px;border-top:1px solid var(--line)}
.asn-meta .m .k{font-size:11px;color:var(--meta);font-weight:600;margin-bottom:3px}
.asn-meta .m .v{font-size:14px;color:var(--ink);font-weight:700}
.asn-meta .m .v.ok{color:var(--green)}
.prog{height:10px;border-radius:999px;background:#eef1f6;overflow:hidden}
.prog i{display:block;height:100%;border-radius:999px;background:linear-gradient(90deg,#2c5ce5,#4f8ef0);transition:width .4s ease}
.stat3{display:flex;justify-content:space-between;margin-top:12px}
.stat3 .s{text-align:center}
.stat3 .n{font-size:17px;font-weight:800;color:var(--ink)}
.stat3 .c{font-size:11px;color:var(--meta);font-weight:600}
.tl-row{display:flex;align-items:center;gap:12px;padding:10px 2px}
.tl-row + .tl-row{border-top:1px solid var(--line)}
.tl-dot{width:10px;height:10px;border-radius:50%;flex:0 0 10px}
.tl-dot.in{background:var(--green)} .tl-dot.lo{background:var(--amber)} .tl-dot.li{background:var(--blue)} .tl-dot.out{background:var(--red)}
.tl-dot.open{background:var(--green);position:relative}
.tl-dot.open::after{content:'';position:absolute;inset:0;border-radius:50%;background:var(--green);animation:tnpulse 1.8s ease-out infinite}
.tl-lbl{font-size:14px;font-weight:600;color:var(--ink);flex:1}
.tl-t{font-size:13px;font-weight:700;color:var(--ink2);font-variant-numeric:tabular-nums}
.empty{padding:16px 4px;color:var(--meta);font-size:13px;font-weight:500;text-align:center}
.up-row{background:var(--glass);backdrop-filter:blur(20px) saturate(160%);-webkit-backdrop-filter:blur(20px) saturate(160%);border:1px solid var(--glass-bd);border-radius:18px;padding:14px 16px;box-shadow:0 3px 14px -6px rgba(15,25,45,.12);display:flex;align-items:center;gap:14px;margin-bottom:10px}
.up-date{width:46px;height:46px;border-radius:14px;display:flex;flex-direction:column;align-items:center;justify-content:center;flex-shrink:0}
.up-date .d1{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.4px}
.up-date .d2{font-size:16px;font-weight:800;line-height:1}
.up-b .s{font-size:14px;font-weight:700;color:var(--ink)}
.up-b .t{font-size:12px;color:var(--sub);font-weight:500;margin-top:2px}
.chev{width:18px;height:18px;stroke:var(--icon-dim);fill:none;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}

/* ===== SITES (map) ===== */
#map{position:absolute;inset:0;z-index:1;background:#dfe6ee}
.leaflet-container{background:#dfe6ee;font-family:'Plus Jakarta Sans',sans-serif}
.leaflet-control-attribution{background:rgba(255,255,255,.85)!important;color:rgba(15,23,42,.55)!important;font-size:9px!important}
.leaflet-control-attribution a{color:rgba(15,23,42,.75)!important}
.map-fade{position:absolute;inset:0;z-index:2;pointer-events:none;background:linear-gradient(180deg,rgba(223,230,238,.55) 0%,rgba(223,230,238,0) 18%,rgba(223,230,238,0) 55%,rgba(242,245,249,.35) 100%)}
.map-loc{width:42px;height:42px;border-radius:999px;background:radial-gradient(60% 42% at 30% 6%,rgba(255,255,255,.66),transparent 50%),rgba(255,255,255,.45);backdrop-filter:blur(36px) saturate(200%);-webkit-backdrop-filter:blur(36px) saturate(200%);border:1px solid rgba(255,255,255,.65);box-shadow:0 6px 18px -6px rgba(15,25,45,.28),inset 0 1px 0 rgba(255,255,255,.85);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0}
.map-ctrls{position:absolute;top:calc(78px + var(--safe-top));right:14px;z-index:16;display:flex;flex-direction:column;gap:10px}
/* v1.177.0: belt-and-braces on the button Alex actually held down */
.map-ctrls button{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;touch-action:manipulation}
body.impersonating .map-ctrls{top:calc(110px + var(--safe-top))}
.map-loc svg{width:20px;height:20px;stroke:var(--ink3);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.site-track{position:absolute;left:0;right:0;bottom:calc(146px + var(--safe-bot));display:flex;gap:10px;overflow-x:auto;scroll-snap-type:x mandatory;padding:0 10px;z-index:15;-webkit-overflow-scrolling:touch}
.site-track.single{justify-content:center}
.site-card{scroll-snap-align:center;flex:0 0 calc(100% - 20px);background:linear-gradient(135deg,rgba(255,255,255,.6) 0%,rgba(255,255,255,.14) 42%,transparent 68%),rgba(255,255,255,.42);backdrop-filter:blur(50px) saturate(205%) brightness(1.05);-webkit-backdrop-filter:blur(50px) saturate(205%) brightness(1.05);border:1px solid rgba(255,255,255,.7);border-radius:32px;padding:20px;box-shadow:0 16px 40px -12px rgba(15,25,45,.36),inset 0 1px 0 rgba(255,255,255,.85);cursor:pointer}
.sc-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
.sc-chips{display:flex;align-items:center;gap:8px}
.sc-date{font-size:12px;font-weight:600;color:var(--meta)}
.sc-nm{font-size:20px;font-weight:800;color:var(--ink)}
.sc-ad{font-size:13px;color:var(--sub);font-weight:500;margin-top:3px}
.sc-tiles{display:flex;gap:12px;margin-top:16px}
.sc-tiles .tile{flex:1}
.sc-hint{display:flex;align-items:center;justify-content:center;gap:6px;margin-top:12px;font-size:12px;font-weight:600;color:var(--meta)}
.sc-hint svg{width:14px;height:14px;stroke:var(--meta);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transition:transform .25s}
.sc-head{cursor:pointer}
.wk-row{display:flex;justify-content:center;gap:8px;margin-top:14px}
.wk{width:34px;height:34px;border-radius:50%;background:#eef1f6;color:#9aa4b2;font-size:12.5px;font-weight:800;display:flex;align-items:center;justify-content:center}
.wk.on{background:var(--blue);color:#fff}
.pill-row{display:flex;flex-wrap:wrap;margin-top:12px}
.req-pill{display:inline-block;padding:9px 15px;border-radius:999px;background:rgba(44,92,229,.13);color:var(--blue);font-size:13px;font-weight:800;margin:0 8px 8px 0}
.ppe-pill{display:inline-flex;align-items:center;gap:6px;padding:9px 14px;border-radius:999px;background:#fff;border:1px solid var(--line);color:var(--ink);font-size:13px;font-weight:700;margin:0 8px 8px 0}
.ppe-pill svg{width:15px;height:15px;stroke:var(--green);fill:none;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round;flex:0 0 15px}
.dots{position:absolute;left:0;right:0;bottom:calc(122px + var(--safe-bot));display:flex;align-items:center;justify-content:center;gap:7px;z-index:15}
.dots i{height:7px;width:7px;border-radius:999px;background:rgba(15,25,45,.28);transition:all .2s}
.dots i.on{width:20px;background:var(--blue)}
.today-track{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;cursor:grab}
.today-track.dragging{cursor:grabbing;scroll-snap-type:none}
.site-track.dragging{scroll-snap-type:none}
.today-track .card{scroll-snap-align:start;flex:0 0 100%;margin-bottom:0}
.today-dots{display:flex;align-items:center;justify-content:center;gap:6px;margin:8px 0 16px}
.today-dots i{height:6px;width:6px;border-radius:999px;background:rgba(15,25,45,.22);transition:all .2s}
.today-dots i.on{width:16px;background:var(--blue)}

/* ===== SHEETS ===== */
.sh-pill{display:flex;align-items:center;gap:6px;background:var(--glass-hi);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid var(--glass-bd);padding:8px 12px;border-radius:999px;box-shadow:0 2px 8px -3px rgba(15,25,45,.15);font-size:13px;font-weight:700;color:var(--ink3)}
.hero{background:linear-gradient(135deg,#2c5ce5,#1a3fb0);border-radius:24px;padding:20px;box-shadow:0 12px 26px -10px rgba(44,92,229,.55);margin-bottom:20px;color:#fff;border:1px solid rgba(255,255,255,.25)}
.hero .p{font-size:12px;font-weight:600;color:#c5d5ff}
.hero .big{display:flex;align-items:flex-end;gap:6px;margin-top:6px}
.hero .big b{font-size:40px;font-weight:800;line-height:1;font-variant-numeric:tabular-nums}
.hero .big span{font-size:16px;font-weight:600;color:#c5d5ff;margin-bottom:4px}
.hero .row{display:flex;gap:26px;margin-top:18px}
.hero .row .c{font-size:12px;color:#b9c8e6;font-weight:600}
.hero .row .n{font-size:16px;font-weight:800;margin-top:2px}
.wk-head{display:flex;align-items:center;justify-content:space-between;margin:0 2px 10px}
.wk-head .r{font-size:13px;font-weight:800;color:var(--ink2)}
.wk-head .tt{font-size:13px;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums}
.wk-card{background:var(--glass);backdrop-filter:blur(20px) saturate(160%);-webkit-backdrop-filter:blur(20px) saturate(160%);border:1px solid var(--glass-bd);border-radius:20px;box-shadow:var(--card-sh);overflow:hidden;margin-bottom:20px}
.site-grp{border-top:1px solid rgba(120,134,156,.14)}
.site-grp:first-child{border-top:0}
.site-row{display:flex;align-items:center;gap:10px;padding:13px 16px;cursor:pointer;-webkit-tap-highlight-color:transparent}
.site-row .b{flex:1;min-width:0}
.site-row .s1{font-weight:700;font-size:14px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.site-row .s2{font-size:11.5px;color:var(--meta);font-weight:600}
.site-row .hrs-r{display:flex;align-items:center;gap:4px;font-weight:800;font-size:15px;color:var(--ink);flex:none}
.site-row .chev{width:16px;height:16px;fill:none;stroke:var(--meta);stroke-width:2.4;transition:transform .15s}
.site-grp.open .site-row .chev{transform:rotate(90deg)}
.site-days{display:none}
.site-grp.open .site-days{display:block}
.ts-sum{display:flex;align-items:center;gap:12px;padding:14px 16px}
.ts-sum .b{flex:1;min-width:0}
.ts-sum .s1{font-size:14px;font-weight:700;color:var(--ink)}
.ts-sum .s2{font-size:12px;color:var(--sub);font-weight:500;margin-top:2px}
.ent{display:flex;align-items:center;gap:14px;padding:15px 16px;border-bottom:1px solid var(--line);cursor:pointer}
.ent:last-child{border-bottom:none}
.ent .dcol{width:44px;text-align:center;flex-shrink:0}
.ent .dow{font-size:10px;font-weight:700;color:var(--meta);text-transform:uppercase}
.ent .num{font-size:18px;font-weight:800;color:var(--ink);line-height:1}
.ent .b{flex:1;min-width:0}
.ent .s1{font-size:14px;font-weight:700;color:var(--ink)}
.ent .s2{font-size:12px;color:var(--sub);font-weight:500;margin-top:2px;font-variant-numeric:tabular-nums}
.ent .r{text-align:right;display:flex;align-items:center;gap:8px}
.ent .hrs{font-size:15px;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums}
.ent .st{font-size:11px;font-weight:700}

/* ===== PILL NAV + PUNCH ===== */
.pill-wrap{position:fixed;top:calc(var(--app-h,100dvh) - 96px - var(--safe-bot));bottom:auto;left:50%;transform:translateX(-50%);z-index:2000}
.pill{position:relative;width:304px;height:72px;border-radius:999px;background:linear-gradient(135deg,rgba(255,255,255,.6) 0%,rgba(255,255,255,.15) 40%,transparent 65%),linear-gradient(180deg,rgba(255,255,255,.4),rgba(248,250,252,.5));backdrop-filter:blur(50px) saturate(205%) brightness(1.05);-webkit-backdrop-filter:blur(50px) saturate(205%) brightness(1.05);border:1px solid rgba(255,255,255,.65);box-shadow:0 16px 34px -10px rgba(15,25,45,.28),inset 0 1px 0 rgba(255,255,255,.85)}
.pill-side{position:absolute;top:50%;transform:translateY(-50%);display:flex;flex-direction:column;align-items:center;gap:3px;cursor:pointer;width:48px;background:none;border:none;padding:0;color:var(--nav-idle)}
.pill-side svg{width:24px;height:24px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.pill-side span{font-size:10px;font-weight:700}
.pill-side.l{left:30px} .pill-side.r{right:30px}
.pill-side.on{color:var(--blue)}
#punchBtn{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:110px;height:110px;border-radius:50%;border:5px solid #fff;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;cursor:pointer;padding:0 8px;transition:background .25s,box-shadow .25s}
#punchBtn:active{transform:translate(-50%,-50%) scale(.96)}
#punchBtn .site{display:none}
#punchBtn .w{font-size:15px;font-weight:800;line-height:1.1}
#punchBtn .w1{margin-top:3px}
#punchBtn .el{font-size:11px;font-weight:700;font-variant-numeric:tabular-nums;margin-top:2px;letter-spacing:.5px}
#punchBtn .el:empty{display:none}
.p-ready{background:#16a34a;box-shadow:0 14px 22px -10px rgba(22,163,74,.6);color:#fff}
.p-ready .site,.p-ready .el{color:rgba(255,255,255,.85)}
.p-in{background:#ef4444;box-shadow:0 14px 22px -10px rgba(239,68,68,.6);color:#fff}
.p-in .site,.p-in .el{color:rgba(255,255,255,.85)}
.p-lunch{background:#d97706;box-shadow:0 14px 22px -10px rgba(217,119,6,.6);color:#fff}
.p-lunch .site,.p-lunch .el{color:rgba(255,255,255,.9)}
.p-zone{background:#eab308;box-shadow:0 14px 22px -10px rgba(234,179,8,.55);color:#3d2f04}
.p-zone .site,.p-zone .el{color:rgba(61,47,4,.7)}
.p-off{background:#c3ccda;box-shadow:0 8px 18px -8px rgba(15,25,45,.3),inset 0 0 22px -2px rgba(227,32,42,.55),inset 0 0 6px rgba(227,32,42,.4);color:#4b5666}
.p-off .site,.p-off .el{color:#5f6b7d}

/* ===== punch target pill ===== */
.punch-target{position:fixed;left:50%;top:calc(var(--app-h,100dvh) - 121px - var(--safe-bot));bottom:auto;transform:translate(-50%,-100%);z-index:2001;max-width:80vw;display:none;align-items:center;gap:8px;padding:8px 15px;border-radius:999px;background:radial-gradient(75% 55% at 28% -14%,rgba(255,255,255,.62),transparent 45%),rgba(255,255,255,.44);backdrop-filter:blur(42px) saturate(200%);-webkit-backdrop-filter:blur(42px) saturate(200%);border:1px solid rgba(255,255,255,.65);box-shadow:0 12px 30px -10px rgba(15,25,45,.34),inset 0 1px 0 rgba(255,255,255,.88);white-space:nowrap;overflow:hidden}
.punch-target.show{display:flex}
.punch-target .pt-dot{width:8px;height:8px;border-radius:50%;flex:0 0 8px}
.punch-target .pt-lead{font-size:11px;font-weight:700;color:var(--meta);text-transform:uppercase;letter-spacing:.04em;flex:0 0 auto}
.punch-target .pt-site{font-size:13px;font-weight:800;color:var(--ink);overflow:hidden;text-overflow:ellipsis}

/* ===== sheets (bottom) ===== */
/* ===== tasks (v1.4.0) ===== */
.tk-row{display:flex;align-items:center;gap:12px;padding:11px 8px;border-bottom:1px solid var(--line);cursor:pointer}
.tk-row:last-child{border-bottom:none}
.tk-check{flex:0 0 22px;width:22px;height:22px;border-radius:7px;border:2px solid #c3ccda;background:#fff;cursor:pointer;position:relative;padding:0}
.tk-check.on{background:var(--green);border-color:var(--green)}
.tk-check.on::after{content:'';position:absolute;left:6px;top:2px;width:5px;height:10px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}
.tk-main{flex:1;min-width:0}
.tk-sub{font-size:14px;font-weight:700;color:var(--ink);line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tk-meta{font-size:12px;color:var(--meta);font-weight:600;margin-top:2px;display:flex;align-items:center;gap:5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tk-dot{width:7px;height:7px;border-radius:50%;flex:0 0 7px}
.tk-due{color:var(--amber-meta)}
.tk-arrow{width:16px;height:16px;flex:0 0 16px;stroke:#c3ccda;fill:none;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.tk-note{width:100%;box-sizing:border-box;border:1.5px solid var(--line);border-radius:14px;padding:12px 14px;font-size:14px;font-family:inherit;color:var(--ink);background:#fff;resize:none;min-height:76px;font-weight:500}
.tk-note:focus{outline:none;border-color:var(--blue)}
.tk-photo-btn{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;box-sizing:border-box;padding:13px;border-radius:14px;border:1.5px dashed #c3ccda;background:#fff;color:var(--ink2);font-size:14px;font-weight:700;cursor:pointer;margin-top:10px}
.tk-photo-btn svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.tk-thumb{margin-top:10px;border-radius:14px;overflow:hidden;position:relative;display:none}
.tk-thumb img{width:100%;display:block;max-height:220px;object-fit:cover}
.tk-thumb .rm{position:absolute;top:8px;right:8px;width:30px;height:30px;border-radius:50%;background:rgba(10,16,26,.6);border:none;color:#fff;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;line-height:1}
/* v1.6.0 task thread */
.tk-thread{display:flex;flex-direction:column;gap:7px;padding:4px 0 2px;max-height:300px;overflow-y:auto;-webkit-overflow-scrolling:touch}
.tk-bub{max-width:82%;padding:9px 13px;border-radius:16px;font-size:13.5px;font-weight:500;line-height:1.45;word-wrap:break-word;white-space:pre-wrap}
.tk-bub.mine{align-self:flex-end;background:var(--blue,#2c5ce5);color:#fff;border-bottom-right-radius:5px}
.tk-bub.theirs{align-self:flex-start;background:rgba(255,255,255,.92);color:var(--ink);border:1px solid rgba(14,23,38,.08);border-bottom-left-radius:5px}
.tk-bub .who{display:block;font-size:10.5px;font-weight:800;letter-spacing:.02em;color:var(--sub);margin-bottom:2px}
.tk-bub.mine .who{color:rgba(255,255,255,.75)}
.tk-bub .when{display:block;font-size:10px;font-weight:600;opacity:.65;margin-top:3px}
.tk-bub.pending{opacity:.55}.tk-bub.failed{background:#b3261e;color:#fff}
.tk-empty{font-size:12.5px;color:var(--sub);font-weight:600;padding:6px 2px}

.tk-composer input{flex:1;border:1px solid rgba(14,23,38,.12);border-radius:14px;padding:11px 13px;font:inherit;font-size:14px;background:rgba(255,255,255,.92);color:var(--ink)}
.tk-composer button{border:0;border-radius:14px;background:var(--blue,#2c5ce5);color:#fff;font-weight:800;font-size:13.5px;padding:0 16px;min-width:64px}
.tk-composer button:disabled{opacity:.5}

.tk-mp svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2}
.tk-mp:disabled{opacity:.5}
.tk-img{display:block;max-width:210px;max-height:250px;width:auto;border-radius:12px;margin:2px 0 1px;cursor:zoom-in;background:rgba(0,0,0,.06)}
.tk-bub.mine .tk-img{margin-left:auto}
.tk-imglink{display:inline-flex;align-items:center;gap:5px;font-size:12.5px;font-weight:700;color:var(--blue,#2c5ce5);text-decoration:underline;padding:6px 0}
/* v1.171.0: the master record is TALL (one section per worker), so the card scrolls its
   image and pins the actions to the footer - a lightbox that fits the whole sheet on a
   phone would render it unreadable. */
.mrec-ov{position:fixed;inset:0;z-index:4100;background:rgba(10,16,26,.55);display:flex;align-items:center;justify-content:center;padding:16px;animation:tnfade .2s ease}
@keyframes mrecpop{from{opacity:0;transform:translateY(14px) scale(.97)}to{opacity:1;transform:none}}
.mrec-card{width:min(560px,100%);max-height:calc(100dvh - 32px);max-height:calc(var(--vvh,100dvh) - 32px);display:flex;flex-direction:column;border-radius:26px;overflow:hidden;background:radial-gradient(55% 28% at 28% 0%,rgba(255,255,255,.62),transparent 42%),rgba(248,250,252,.72);backdrop-filter:blur(52px) saturate(200%) brightness(1.08);-webkit-backdrop-filter:blur(52px) saturate(200%) brightness(1.08);border:1px solid rgba(255,255,255,.6);box-shadow:0 22px 54px -18px rgba(15,25,45,.5);animation:mrecpop .22s cubic-bezier(.22,.61,.36,1)}
.mrec-hd{display:flex;align-items:center;gap:10px;padding:14px 16px 10px}
.mrec-ti{font-size:15px;font-weight:800;color:var(--ink);flex:1;min-width:0}
.mrec-sub{font-size:11.5px;font-weight:700;color:var(--sub);margin-top:2px}
.mrec-x{width:32px;height:32px;border-radius:16px;border:0;background:rgba(15,25,45,.08);color:var(--sub);font-size:19px;line-height:1;cursor:pointer;flex:none}
.mrec-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:0 16px;background:rgba(255,255,255,.35)}
.mrec-scroll img{display:block;width:100%;border-radius:12px;box-shadow:0 8px 22px -12px rgba(15,25,45,.45)}
.mrec-ft{padding:12px 16px calc(14px + var(--safe-bot));display:flex;flex-direction:column;gap:9px;border-top:1px solid rgba(255,255,255,.55)}
.mrec-st{font-size:11.5px;font-weight:700;color:var(--sub);min-height:15px}
.mrec-st.ok{color:#16a34a}.mrec-st.err{color:#dc2626}
.mrec-ax{display:flex;gap:8px}
.mrec-ax .b{flex:1;text-align:center;text-decoration:none;border:0;cursor:pointer;border-radius:14px;padding:11px 12px;font-size:12.5px;font-weight:800}
.mrec-dl{background:#E3202A;color:#fff;box-shadow:0 10px 24px -12px rgba(227,32,42,.8)}
.mrec-sh{background:rgba(15,25,45,.07);color:var(--ink)}
.mrec-open{background:rgba(15,25,45,.07);color:var(--ink);display:none}
.tk-lb{position:fixed;inset:0;background:rgba(6,10,20,.92);display:flex;align-items:center;justify-content:center;z-index:4000;padding:16px}
.tk-lb img{max-width:100%;max-height:100%;border-radius:10px}
.tk-lb .x{position:absolute;top:calc(12px + env(safe-area-inset-top));right:16px;width:40px;height:40px;border-radius:20px;border:0;background:rgba(255,255,255,.16);color:#fff;font-size:22px;line-height:1}
.brk-sheet{position:fixed;left:0;right:0;bottom:0;z-index:3010;background:radial-gradient(55% 28% at 28% 0%,rgba(255,255,255,.6),transparent 42%),rgba(248,250,252,.5);backdrop-filter:blur(52px) saturate(200%) brightness(1.09);-webkit-backdrop-filter:blur(52px) saturate(200%) brightness(1.09);border-top:1px solid rgba(255,255,255,.6);border-radius:34px 34px 0 0;padding:10px 18px calc(24px + var(--safe-bot));max-height:calc(var(--vvh,100dvh) * .92);overflow-y:auto;box-shadow:0 -12px 44px rgba(10,16,26,.28),inset 0 1px 0 rgba(255,255,255,.8);animation:tnsheet .3s cubic-bezier(.22,.61,.36,1)}
.brk-grab{width:38px;height:5px;border-radius:3px;background:#c7d0dd;margin:0 auto 14px}
.brk-ttl{font-size:20px;font-weight:800;color:var(--ink);text-align:center}
.brk-sub{font-size:13px;color:var(--meta);font-weight:500;text-align:center;margin:5px 0 16px}
.brk-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.brk-opt{border:0;border-radius:15px;padding:16px;font-size:15px;font-weight:700;color:var(--ink);background:#fff;box-shadow:0 1px 4px rgba(10,16,26,.06);cursor:pointer}
.brk-opt[data-m='0']{grid-column:1 / -1;background:var(--blue-bg);color:var(--blue)}
.brk-cust{width:100%;margin-top:10px;background:var(--ink);color:#fff}
.tk-seg{display:inline-flex;gap:2px;background:#eef1f6;border-radius:10px;padding:3px;margin-left:auto}
.tk-seg-b{border:0;background:transparent;color:var(--meta);font-size:12px;font-weight:700;padding:5px 12px;border-radius:8px;cursor:pointer}
.tk-seg-b.active{background:#fff;color:var(--ink);box-shadow:0 1px 3px rgba(10,16,26,.1)}
.card-timer{font-variant-numeric:tabular-nums;font-weight:800;letter-spacing:.3px}
.tk-check.done{background:var(--green);border-color:var(--green)}
.tk-sticky{position:-webkit-sticky;position:sticky;bottom:calc(6px + var(--safe-bot));box-shadow:0 8px 22px rgba(10,16,26,.18)}
#taskSheet{z-index:2720}
.sheet-ov{position:fixed;inset:0;z-index:2700;background:rgba(10,16,26,.3);display:none;animation:tnfade .25s ease}
.sheet-ov.open{display:block}
.sheet{position:fixed;left:0;right:0;bottom:0;z-index:2710;height:90%;height:calc(var(--vvh,100dvh) * .9);border-radius:36px 36px 0 0;overflow:hidden;display:none;flex-direction:column;background:radial-gradient(55% 28% at 28% 0%,rgba(255,255,255,.62),transparent 42%),rgba(248,250,252,.46);backdrop-filter:blur(52px) saturate(200%) brightness(1.1);-webkit-backdrop-filter:blur(52px) saturate(200%) brightness(1.1);border-top:1px solid rgba(255,255,255,.55);box-shadow:0 -12px 44px rgba(10,16,26,.28),inset 0 1px 0 rgba(255,255,255,.78);animation:tnsheet .34s cubic-bezier(.22,.61,.36,1)}
.sheet.open{display:flex}
.sheet.auto{height:auto;max-height:calc(var(--vvh,100dvh) * .9)}
.pull-bar{flex:0 0 auto;position:relative;padding:12px 0 8px;display:flex;justify-content:center;cursor:grab;touch-action:none;z-index:45}
.pull-bar::before{content:'';width:42px;height:5px;border-radius:999px;background:#cdd5e1}
.sheet-x{position:absolute;right:16px;top:10px;width:34px;height:34px;border-radius:50%;background:radial-gradient(60% 42% at 30% 6%,rgba(255,255,255,.72),transparent 50%),rgba(255,255,255,.4);backdrop-filter:blur(24px) saturate(200%);-webkit-backdrop-filter:blur(24px) saturate(200%);box-shadow:0 4px 14px -4px rgba(15,25,45,.3),inset 0 1px 0 rgba(255,255,255,.8);display:flex;align-items:center;justify-content:center;cursor:pointer;border:1px solid rgba(255,255,255,.6);padding:0;z-index:46}
.sheet-x svg{width:17px;height:17px;stroke:var(--ink3);fill:none;stroke-width:2.4;stroke-linecap:round}
.sheet-body{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:4px 20px calc(28px + var(--safe-bot))}
.grp-h{font-size:14px;font-weight:800;color:var(--ink);margin:22px 2px 10px}
.pill-chip{font-size:13px;font-weight:700;color:var(--blue);background:var(--blue-bg);padding:8px 14px;border-radius:999px;display:inline-block}
.ppe-chip{display:inline-flex;align-items:center;gap:6px;font-size:13px;font-weight:700;color:var(--ink2);background:rgba(255,255,255,.85);border:1px solid #e6ebf2;padding:8px 13px;border-radius:999px}
.ppe-chip svg{width:14px;height:14px;stroke:var(--green);fill:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round}
.chips{display:flex;flex-wrap:wrap;gap:8px}
.wcard{background:linear-gradient(135deg,rgba(255,255,255,.5) 0%,rgba(255,255,255,.11) 45%,transparent 72%),rgba(112,126,148,.27);backdrop-filter:blur(33px) saturate(200%) brightness(1.06);-webkit-backdrop-filter:blur(33px) saturate(200%) brightness(1.06);border-radius:24px;box-shadow:0 4px 16px -8px rgba(15,25,45,.14),inset 0 1px 0 rgba(255,255,255,.4)}
.cert-row{display:flex;align-items:center;gap:12px;padding:14px 0;border-bottom:1px solid var(--line)}
.cert-row:last-child{border-bottom:none}
.cert-ic{width:38px;height:38px;border-radius:11px;background:var(--blue-bg);display:flex;align-items:center;justify-content:center;flex-shrink:0}
.cert-ic svg{width:19px;height:19px;stroke:var(--blue);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.cert-b{flex:1;min-width:0}
.cert-b .n{font-size:14px;font-weight:700;color:var(--ink)}
.cert-b .m{font-size:12px;font-weight:600;margin-top:2px}
.day7{display:flex;gap:7px}
.day7 .d{flex:1;text-align:center;padding:11px 0;border-radius:13px;font-size:12px;font-weight:800}
.big-btn{display:block;width:100%;padding:14px;border-radius:15px;border:none;font-size:15px;font-weight:700;cursor:pointer;margin-top:10px;text-align:center;color:#fff}
.big-btn.blue{background:var(--blue);box-shadow:0 8px 18px -8px rgba(44,92,229,.7)}
.big-btn.green{background:var(--green);box-shadow:0 8px 18px -8px rgba(22,163,74,.7)}
.big-btn.amber{background:var(--amber);box-shadow:0 8px 18px -8px rgba(217,119,6,.7)}
.big-btn.red{background:var(--red);box-shadow:0 8px 18px -8px rgba(239,68,68,.7)}
.big-btn.ghost{background:#e9edf3;color:var(--ink2);box-shadow:none}
.big-btn:disabled{opacity:.5}
.input{width:100%;padding:15px 16px;border-radius:15px;background:#fff;border:1.5px solid #e6ebf2;color:var(--ink);font-size:16px;font-weight:600;font-family:inherit;-webkit-appearance:none;outline:none}
.input:focus{border-color:var(--blue)}
.match-row{display:flex;align-items:center;gap:12px;padding:13px 4px;border-bottom:1px solid var(--line);cursor:pointer}
/* v1.176.0 (Alex): "The avatar bubbles should be the same style as the ones on the filter
   list." There was no bare `.av` rule at all - only this one, scoped to .match-row - so the
   message rows (.mc-row) rendered naked initials with no bubble. Same selector list, one
   definition, so the two cards cannot drift again. */
.match-row .av,.mc-row .av{width:38px;height:38px;border-radius:50%;background:linear-gradient(135deg,#0f2a52,#17356a);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:13px;flex:0 0 38px}
.warn-box{display:flex;gap:10px;align-items:flex-start;background:var(--amber-soft);border:1px solid var(--amber-bd);border-radius:14px;padding:12px 13px;margin-bottom:10px}
.warn-box i{width:7px;height:7px;border-radius:50%;background:var(--amber);margin-top:6px;flex:0 0 7px}
.warn-box span{font-size:13px;font-weight:600;color:var(--amber-ink);line-height:1.45}
.kv{display:flex;justify-content:space-between;gap:12px;padding:11px 2px;border-bottom:1px solid var(--line);font-size:13px}
.kv .k{color:var(--meta);font-weight:600}.kv .v{font-weight:700;color:var(--ink);text-align:right}

/* modal / day popup */
/* v1.96.0 punch time selector: a snap-scrolling column of wall times inside the confirm modal.
   Rows are tapped, not flicked-and-guessed - the committed value is never ambiguous. */
.pt-lab{font-size:11px;font-weight:800;color:var(--meta);letter-spacing:.06em;margin:18px 0 8px}
.pt-split{display:flex;align-items:stretch;gap:8px}
.pt-split .pt-wheel{flex:1 1 0;min-width:0}
.pt-colon{display:flex;align-items:center;font-size:18px;font-weight:800;color:var(--meta);flex:0 0 auto}
.pt-wheel{max-height:172px;overflow-y:auto;-webkit-overflow-scrolling:touch;scroll-snap-type:y proximity;border:1px solid var(--line);border-radius:14px;background:rgba(14,23,38,.03)}
.pt-o{scroll-snap-align:center;display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 14px;cursor:pointer;font-variant-numeric:tabular-nums}
.pt-o+.pt-o{border-top:1px solid rgba(14,23,38,.05)}
.pt-o .pt-t{font-size:17px;font-weight:800;color:var(--ink)}
.pt-o .pt-n{font-size:11px;font-weight:800;color:var(--meta);letter-spacing:.04em;text-transform:uppercase}
.pt-o.on{background:var(--amber-soft)}
.pt-o.on .pt-n{color:var(--amber-bd)}
.modal-ov{position:fixed;inset:0;z-index:3200;background:rgba(10,16,26,.5);display:none;align-items:center;justify-content:center;padding:24px;animation:tnfade .2s ease}
.modal-ov.open{display:flex}
.modal{width:100%;max-width:400px;background:radial-gradient(60% 35% at 28% -8%,rgba(255,255,255,.64),transparent 42%),rgba(255,255,255,.96);backdrop-filter:blur(46px) saturate(200%);-webkit-backdrop-filter:blur(46px) saturate(200%);border:1px solid rgba(255,255,255,.6);border-radius:32px;padding:24px 22px;box-shadow:0 24px 60px -18px rgba(10,16,26,.55),inset 0 1px 0 rgba(255,255,255,.88);animation:tnpop .26s cubic-bezier(.22,.61,.36,1)}
.modal .mic{width:54px;height:54px;border-radius:50%;background:var(--amber-bg);display:flex;align-items:center;justify-content:center;margin-bottom:16px}
.modal .mic svg{width:28px;height:28px;stroke:var(--amber);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.modal h3{font-size:19px;font-weight:800;color:var(--ink);margin:0}
.modal .msub{font-size:13px;color:var(--sub);font-weight:500;margin-top:4px}
.modal .btns{display:flex;gap:12px;margin-top:22px}
.modal .btns .big-btn{flex:1;margin-top:0}
.daycard{width:100%;max-width:400px;background:radial-gradient(60% 35% at 28% -8%,rgba(255,255,255,.64),transparent 42%),rgba(255,255,255,.96);backdrop-filter:blur(46px) saturate(200%);-webkit-backdrop-filter:blur(46px) saturate(200%);border:1px solid rgba(255,255,255,.55);border-radius:32px;overflow:hidden;box-shadow:0 24px 60px -18px rgba(10,16,26,.55),inset 0 1px 0 rgba(255,255,255,.88);animation:tnpop .26s cubic-bezier(.22,.61,.36,1)}
.daycard .hd{background:linear-gradient(135deg,#2c5ce5,#1a3fb0);padding:20px;color:#fff;position:relative}
.daycard .hd .x{position:absolute;right:14px;top:14px;width:30px;height:30px;border-radius:50%;background:rgba(255,255,255,.18);display:flex;align-items:center;justify-content:center;cursor:pointer}
.daycard .hd .x svg{width:15px;height:15px;stroke:#fff;fill:none;stroke-width:2.6;stroke-linecap:round}
.daycard .hd .d1{font-size:12px;font-weight:600;color:#c5d5ff}
.daycard .hd .d2{font-size:20px;font-weight:800;margin-top:3px}
.daycard .hd .d3{font-size:13px;color:#c5d5ff;font-weight:500;margin-top:2px}
.daycard .bd{padding:20px}
.io{display:flex;align-items:stretch}
.io .c{flex:1;text-align:center}
.io .k{font-size:11px;color:var(--meta);font-weight:700}
.io .v{font-size:22px;font-weight:800;margin-top:4px;font-variant-numeric:tabular-nums}
.io .sep{width:1px;background:#eef1f6}
.tile3{display:flex;gap:10px;margin-top:18px}
.tile3 .tile{flex:1;text-align:center;padding:12px}
.zone-note{display:flex;align-items:center;gap:10px;margin-top:14px;padding:12px 14px;border-radius:14px}
.zone-note svg{width:18px;height:18px;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}
.zone-note span{font-size:13px;font-weight:600}

#toast{position:fixed;left:50%;bottom:calc(172px + var(--safe-bot));transform:translateX(-50%) translateY(20px);z-index:3200;background:rgba(255,255,255,.95);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid var(--glass-bd);border-radius:999px;padding:11px 18px;font-size:12.5px;font-weight:700;color:var(--ink);opacity:0;pointer-events:none;transition:all .25s;box-shadow:0 12px 30px rgba(15,25,45,.22);max-width:86vw;text-align:center}
#toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
#toast.err{color:#dc2626}
#toast.ok{color:var(--green)}
.fo-inp{width:100%;box-sizing:border-box;border:1px solid var(--line);border-radius:14px;padding:12px 14px;font:inherit;font-size:15px;background:rgba(255,255,255,.72);color:var(--ink);margin-top:6px}
textarea.fo-inp{min-height:92px;resize:vertical}
.fo-lab{font-size:11px;font-weight:700;color:var(--meta);letter-spacing:.04em;margin-top:12px}
.tsi-btn,.at-btn{background:none;border:0;color:var(--blue);font:inherit;font-size:13px;font-weight:700;padding:0;cursor:pointer}
.big-btn.red{background:#E3202A;color:#fff;box-shadow:0 8px 18px -8px rgba(227,32,42,.7)}
body.modal-open .punch-target,body.modal-open .pill-wrap{opacity:0;pointer-events:none;transition:opacity .15s}
.fo-ttl{font-size:20px;font-weight:800;color:var(--ink);margin-bottom:4px}
.fo-sub{font-size:13px;color:var(--sub);font-weight:500;margin-bottom:8px}
.daycard .io .iodt{font-size:12px;font-weight:700;color:var(--meta);margin:3px 0 1px}
#railNav{display:none}
#homeGreet{display:none}
.gs-pin{background:#fff;border:1.5px solid rgba(15,25,45,.3);border-radius:10px;padding:3px 9px;font-size:11px;font-weight:700;color:#0e1726;box-shadow:0 4px 12px rgba(15,25,45,.3);white-space:nowrap;display:inline-block}
.gs-pin-person{border-radius:999px;background:#17356a;color:#fff;border-color:rgba(255,255,255,.5)}
.gs-pin-opp{opacity:.85;background:#eef2f8}
.gs-pin-acct{border-color:#E3202A}

/* ===== v1.23 responsive: collapsible icon rail (>=768px) ===== */
@keyframes tnsheetd{from{opacity:0;transform:translate(-50%,-47%)}to{opacity:1;transform:translate(-50%,-50%)}}
@media (min-width:768px){
  body{--railw:84px}
  body.railx{--railw:220px}
  /* rail chrome: icons stacked; header content hidden */
  #topBand{top:0;bottom:0;right:auto;width:var(--railw);display:flex;flex-direction:column;box-shadow:8px 0 22px -12px rgba(120,10,18,.55);transition:width .18s ease;background:#C41A23;z-index:2900}
  .tb-main{display:none}
  #railNav{display:flex;flex-direction:column;flex:1;min-height:0;padding:12px 10px calc(16px + var(--safe-bot));gap:6px;overflow:visible}
  #rnBrand{display:flex;align-items:center;justify-content:center;gap:9px;padding:8px 0 4px;min-height:34px}
  #rnBrand svg{width:24px;height:21px;flex:none;filter:drop-shadow(0 3px 8px rgba(0,0,0,.28))}
  #rnBrand .lbl{display:none;font-size:14px;font-weight:800;letter-spacing:.1em;color:#fff;white-space:nowrap}
  body.railx #rnBrand{justify-content:flex-start;padding-left:14px}
  #rnBrand{cursor:pointer}
  body.railx #rnBrand .lbl{display:block}
  .rn-top{display:flex;flex-direction:column;gap:6px;margin-top:4px}
  .rn-bot{display:flex;flex-direction:column;gap:6px;margin-top:auto}
  .rn-it{position:relative;display:flex;align-items:center;justify-content:center;gap:12px;border:none;background:none;color:rgba(255,255,255,.78);padding:12px 10px;border-radius:14px;cursor:pointer;font-family:inherit;min-height:46px}
  .rn-it svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex:none}
  .rn-it .lbl{display:none;font-size:13px;font-weight:700}
  .rn-it.on{color:#fff;background:rgba(255,255,255,.2)}
  body.railx .rn-it{justify-content:flex-start;padding:12px 14px}
  body.railx .rn-it .lbl{display:block}
  #rnAvatar{width:34px;height:34px;border-radius:50%;background:rgba(255,255,255,.22);color:#fff;font-weight:800;font-size:13px;display:flex;align-items:center;justify-content:center;flex:none}
  #rnCollapse{position:absolute;top:50%;right:0;transform:translateY(-50%);width:24px;height:72px;min-height:0;padding:0;border:none;border-radius:12px 0 0 12px;background:transparent;color:rgba(255,255,255,.85);display:flex;align-items:center;justify-content:center;z-index:6}
  #rnCollapse svg{transition:transform .18s ease}
  body.railx #rnCollapse svg{transform:rotate(180deg)}
  /* view-as banner spans the content top */
  #asBanner{position:fixed;top:0;left:var(--railw);right:0;z-index:1600;transition:left .18s ease}
  /* content clears the rail */
  .view{left:var(--railw);padding-top:calc(26px + var(--safe-top));padding-bottom:calc(48px + var(--safe-bot));transition:left .18s ease}
  body.impersonating .view{padding-top:calc(62px + var(--safe-top))}
  #vHome,#vSheets{padding-left:max(20px,calc(50vw - var(--railw)/2 - 380px));padding-right:max(20px,calc(50vw - var(--railw)/2 - 380px))}
  #homeGreet{display:block;margin:2px 2px 16px}
  #homeGreet .g1{font-size:13px;color:var(--sub);font-weight:600;line-height:1}
  #homeGreet .g2{font-size:24px;color:var(--ink);font-weight:800;margin-top:4px}
  .map-ctrls{top:calc(20px + var(--safe-top))}
  body.impersonating .map-ctrls{top:calc(56px + var(--safe-top))}
  /* punch: smaller, overlapping the rail edge; current-site chip directly right */
  .pill-wrap{left:calc(var(--railw) + (100vw - var(--railw))/2);right:auto;top:auto;bottom:calc(22px + var(--safe-bot));transform:translateX(-50%);width:auto;z-index:2100;transition:left .18s ease}
  .pill{width:auto;height:auto;border-radius:0;background:none;border:none;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none;display:block}
  .pill-side{display:none}
  #punchBtn{position:static;transform:none;width:80px;height:80px;border-width:4px}
  #punchBtn:active{transform:scale(.96)}
  #punchBtn .w{font-size:12.5px}
  #punchBtn .el{font-size:10px}
  .punch-target{left:calc(var(--railw) + (100vw - var(--railw))/2);right:auto;top:auto;bottom:calc(108px + var(--safe-bot));transform:translateX(-50%);max-width:44vw;transition:left .18s ease}
  #toast{left:calc(50% + var(--railw)/2);bottom:calc(56px + var(--safe-bot))}
  /* dialogs centered over the content region */
  .sheet{left:calc(50% + var(--railw)/2);right:auto;top:50%;bottom:auto;width:min(680px,calc(94vw - var(--railw)));height:auto;max-height:min(76vh,820px);border-radius:30px;border:1px solid rgba(255,255,255,.6);transform:translate(-50%,-50%);animation:tnsheetd .28s cubic-bezier(.22,.61,.36,1)}
  .sheet.auto{max-height:min(76vh,820px)}
  .brk-sheet{left:calc(50% + var(--railw)/2);right:auto;top:50%;bottom:auto;width:min(560px,calc(94vw - var(--railw)));border-radius:30px;transform:translate(-50%,-50%);animation:tnsheetd .28s cubic-bezier(.22,.61,.36,1);padding-bottom:24px}
  /* profile = popover right of the avatar button */
  #profSheet{left:calc(var(--railw) + 14px);right:auto;top:auto;bottom:calc(14px + var(--safe-bot));transform:none;width:min(420px,calc(96vw - var(--railw)));max-height:min(78vh,720px);border-radius:24px;animation:tnpop .22s cubic-bezier(.22,.61,.36,1)}
  /* carousels */
  .today-track{gap:12px}
  .today-track .card{flex:0 0 calc(50% - 6px)}
  .site-card{flex:0 0 430px}
  .site-track{padding:0 max(10px,calc(50% - 215px))}
  /* dock panels slide out from UNDER the rail (rail z is higher); no page dim; view resizes */
  #gsSheet,#acctPanel{position:fixed;left:var(--railw);right:auto;top:0;bottom:0;width:min(420px,58vw);height:auto;max-height:none;transform:translateX(-100%);transition:transform .22s cubic-bezier(.22,.61,.36,1),left .18s ease;z-index:2600;border-radius:0 26px 26px 0;border-left:none;display:flex;flex-direction:column;box-shadow:14px 0 34px -14px rgba(15,25,45,.4)}
  #gsSheet{display:flex!important}
  #gsSheet.dockopen,#acctPanel.dockopen{transform:translateX(0)}
  body.dockon .view{left:calc(var(--railw) + min(420px,58vw))}
  body.dockon #asBanner{left:calc(var(--railw) + min(420px,58vw))}
}
@media (max-width:767px){#acctPanel{display:none}}
@media (min-width:1100px){
  #vHome{padding-left:max(24px,calc(50vw - var(--railw)/2 - 570px));padding-right:max(24px,calc(50vw - var(--railw)/2 - 570px))}
  .bd-img{height:250px}
  #vSheets{padding-left:max(24px,calc(50vw - var(--railw)/2 - 570px));padding-right:max(24px,calc(50vw - var(--railw)/2 - 570px))}
  #sheetList{column-count:2;column-gap:22px}
  #sheetList>*{break-inside:avoid;-webkit-column-break-inside:avoid}
  .sheet{width:min(720px,calc(90vw - var(--railw)))}
}
@media (hover:hover) and (pointer:fine){
  .rnd-btn:hover,.avatar:hover{filter:brightness(1.12)}
  .site-card:hover{transform:translateY(-2px);transition:transform .15s}
  .pill-side:hover{filter:brightness(1.06)}
  .card,.wk-card{transition:box-shadow .15s}
  button{cursor:pointer}
}
/* ===== v1.39.0 floating cards (XR port, desktop/tablet only) ===== */
@media (min-width:768px){
#psOv{pointer-events:none;background:transparent !important;backdrop-filter:none !important;-webkit-backdrop-filter:none !important}
.sheet.float{position:fixed;left:auto;right:auto;top:auto;bottom:auto;transform:none;animation:none;overflow:visible;max-height:min(78vh,860px);touch-action:none}
.sheet.float .sheet-body{overflow-y:auto;min-height:0;touch-action:pan-y}
.sheet.float input,.sheet.float textarea,.sheet.float select{touch-action:auto}
.sheet.float.window-dragging,.sheet.float.window-resizing{transition:none;user-select:none}
.sheet.float.window-dragging{box-shadow:0 24px 64px -12px rgba(10,16,26,.45)}
.win-handle{position:absolute;z-index:12}
.win-handle.corner{width:30px;height:30px}
.win-h-nw{top:-4px;left:-4px;cursor:nwse-resize}
.win-h-ne{top:-4px;right:-4px;cursor:nesw-resize}
.win-h-sw{bottom:-4px;left:-4px;cursor:nesw-resize}
.win-h-se{bottom:-4px;right:-4px;cursor:nwse-resize}
.win-handle.edge{}
.win-h-n{top:-4px;left:28px;right:28px;height:10px;cursor:ns-resize}
.win-h-s{bottom:-4px;left:28px;right:28px;height:10px;cursor:ns-resize}
.win-h-w{left:-4px;top:28px;bottom:28px;width:10px;cursor:ew-resize}
.win-h-e{right:-4px;top:28px;bottom:28px;width:10px;cursor:ew-resize}
.sheet.float .pull-bar{cursor:grab}
.sheet.float.window-dragging .pull-bar{cursor:grabbing}
}
@media (max-width:767px){.win-handle{display:none}}
/* ===== v1.39.3 punch-cluster hide (desktop/tablet only) ===== */
@media (min-width:768px){
#punchHide{position:absolute;top:50%;right:-46px;transform:translateY(-50%);width:34px;height:34px;border-radius:50%;border:1px solid rgba(255,255,255,.6);background:radial-gradient(60% 42% at 30% 6%,rgba(255,255,255,.72),transparent 50%),rgba(255,255,255,.4);backdrop-filter:blur(24px) saturate(200%);-webkit-backdrop-filter:blur(24px) saturate(200%);box-shadow:0 4px 14px -4px rgba(15,25,45,.3);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;color:var(--sub)}
#punchHide svg,#punchShow svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
#punchShow{display:none;position:fixed;right:18px;bottom:calc(22px + var(--safe-bot));z-index:2100;width:40px;height:40px;border-radius:50%;border:1px solid rgba(255,255,255,.6);background:radial-gradient(60% 42% at 30% 6%,rgba(255,255,255,.72),transparent 50%),rgba(255,255,255,.4);backdrop-filter:blur(24px) saturate(200%);-webkit-backdrop-filter:blur(24px) saturate(200%);box-shadow:0 6px 18px -6px rgba(15,25,45,.35);align-items:center;justify-content:center;cursor:pointer;padding:0;color:var(--sub)}
body.punch-hidden .pill-wrap,body.punch-hidden .punch-target,body.punch-hidden #siteTrack,body.punch-hidden #siteDots{display:none}
body.punch-hidden #punchShow{display:flex}
body.modal-open #punchShow{opacity:0;pointer-events:none}
}
@media (max-width:767px){#punchHide,#punchShow{display:none !important}}
/* ===== v1.40.0 map filter drawer (desktop/tablet only) ===== */
@media (min-width:768px){
#fltDrawer{position:fixed;top:14px;right:0;bottom:14px;width:min(420px,60vw);z-index:2705;transform:translateX(calc(100% - 15px));transition:transform .22s cubic-bezier(.22,.61,.36,1);background:none;border:0;box-shadow:none;padding:0;border-radius:0}
#fltDrawer.open{transform:translateX(0)}
#fltDrawer.tn-dwr-front{z-index:2706}
#fltList{flex:1;min-height:0;overflow-y:auto;margin-top:6px}
#fltDeep{max-height:40%;overflow-y:auto;flex-shrink:0}
}
/* v1.166.0 (Alex): "The filter slider should be sliding in from the right, also similar
   layout at the desktop view slid in from the right of the map page." It was
   display:none below 768px, so phones had no filter panel at all - same geometry as the
   message centre, mirrored. */
@media (max-width:767px){
#fltDrawer{position:fixed;top:var(--dwrTop);bottom:var(--dwrBot);right:0;left:auto;width:min(90vw,440px);z-index:2705;display:flex;align-items:stretch;transform:translateX(calc(100% - 15px));transition:transform .35s cubic-bezier(.22,1,.36,1);background:none;border:0;box-shadow:none;padding:0;border-radius:0}
#fltDrawer.open{transform:translateX(0)}
#fltDrawer.tn-dwr-front{z-index:2706}
#fltList{flex:1;min-height:0;overflow-y:auto;margin-top:6px}
#fltDeep{max-height:40%;overflow-y:auto;flex-shrink:0}
}
#fltResCard{position:fixed;top:14px;right:calc(var(--fltw,min(420px,60vw)) + 22px);width:min(460px,calc(94vw - var(--fltw,min(420px,60vw)) - 40px));max-height:calc(100% - 28px);z-index:2600;display:none;flex-direction:column;border-radius:26px;background:radial-gradient(55% 28% at 28% 0%,rgba(255,255,255,.62),transparent 42%),rgba(248,250,252,.6);backdrop-filter:blur(52px) saturate(200%) brightness(1.08);-webkit-backdrop-filter:blur(52px) saturate(200%) brightness(1.08);border:1px solid rgba(255,255,255,.55);box-shadow:0 18px 44px -18px rgba(15,25,45,.45);padding:16px 16px 12px;animation:tnfade .18s ease}
#fltResCard.open{display:flex}
@media (max-width:767px){#fltResCard{display:none !important}}
.sheet.mb-snap{transition:height .2s cubic-bezier(.22,.61,.36,1),max-height .2s cubic-bezier(.22,.61,.36,1)}
/* v1.98.0 (Alex): "Shouldn't have that background. Card should be seamless." At rest the header
   is exactly the card - no veil, no blur, no seam. The veil still exists, because the title has
   to stay readable over content scrolling under it, but it only fades in once the card is
   actually scrolled, which is never the state you see when a card opens. */
.sh-stick{position:sticky;top:0;z-index:30;margin:0 -20px 4px;padding:2px 96px 8px 20px;background:transparent;transition:background .18s linear}
.sh-stick.stuck{background:linear-gradient(rgba(248,250,252,.5),rgba(248,250,252,.22) 78%,rgba(248,250,252,0));backdrop-filter:blur(26px) saturate(190%);-webkit-backdrop-filter:blur(26px) saturate(190%)}
/* ===== v1.54.0 map UI: controls shift for the filter drawer; zoom-to-extent autozoom toggle ===== */
.map-ctrls{transition:transform .22s cubic-bezier(.22,.61,.36,1)}
@media (min-width:768px){body.flt-open .map-ctrls{transform:translateX(calc(-1 * (var(--fltw, min(420px,60vw)) + 16px)))}}
.map-loc.on{background:radial-gradient(60% 42% at 30% 6%,rgba(255,255,255,.72),transparent 50%),rgba(227,32,42,.18);border-color:rgba(227,32,42,.55)}
.map-loc.on svg{stroke:#E3202A}

/* ===== v1.45.0 Message Center ===== */
.rn-badge{position:absolute;top:50%;right:7px;transform:translateY(-50%);min-width:16px;height:16px;padding:0 4px;border-radius:8px;background:#E3202A;color:#fff;font-size:10px;font-weight:800;display:flex;align-items:center;justify-content:center;line-height:1}
/* v1.173.0: XR's header - the title and its count on the left, the scope pills top right
   on the SAME row, then the line filters under both. */
.mc-hd{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin:2px 0 8px}
.mc-hd-t{min-width:0;flex:1}
.mc-hd h2{font-size:19px;font-weight:800;margin:0}
.mc-hd-sub{font-size:11px;font-weight:700;color:var(--meta);margin-top:2px;text-transform:uppercase;letter-spacing:.02em}
.mc-scopes{display:flex;gap:5px;flex:0 0 auto;flex-wrap:wrap;justify-content:flex-end;max-width:62%}
.mc-chans{display:flex;gap:5px;flex-wrap:wrap;margin:0 0 9px}
#fltChips .ppe-pill{font-size:11px;font-weight:800;padding:4px 9px;margin:0;gap:4px}
.mc-chan{font-size:11px;font-weight:800;color:var(--sub);padding:4px 9px;border-radius:999px;background:rgba(118,131,151,.10);border:1px solid rgba(118,131,151,.22);cursor:pointer;white-space:nowrap}
.mc-chan.on{background:rgba(15,25,45,.86);border-color:rgba(15,25,45,.86);color:#fff}
.mc-chan b{font-weight:800;opacity:.72;margin-left:3px}
.mc-tab{font-size:12px;font-weight:700;color:var(--sub);padding:5px 11px;border-radius:999px;background:rgba(118,131,151,.12);cursor:pointer}
.mc-tab.on{background:#E3202A;color:#fff}
/* v1.175.0 (Alex): "The list should differentiate between the channel to which the messages
   belong to as per the same color coding." XR v6.3.80's `.row.line-*` border, hex for hex. */
.mc-row{display:flex;align-items:center;gap:11px;padding:11px 16px 11px 13px;border-bottom:1px solid rgba(118,131,151,.14);cursor:pointer;position:relative;border-left:3px solid rgba(148,163,184,.25)}
.mc-row.line-dispatch{border-left-color:#0a84ff}
.mc-row.line-dispatch2{border-left-color:#5e9eff}
.mc-row.line-dispatch3{border-left-color:#0a5bbf}
.mc-row.line-payroll{border-left-color:#34c759}
.mc-row.line-onboarding{border-left-color:#84a047}
.mc-row.line-none{border-left-color:rgba(148,163,184,.25)}
/* the header stays put; only this scrolls, and the search starts tucked above the fold */
/* v1.176.0 (Alex): "The color coding should be on the left edge of the screen." The stripe
   was on .mc-row, but the row sits inside the drawer body's 16px padding, so the colour
   floated in from the edge. Bleed the scroller out to the body's own edge and let the ROWS
   carry the inset - which is exactly how XR gets it there (`.row{padding:10px 20px}` in a
   list with no padding of its own). The search keeps its inset so it still lines up with
   the header above it. */
.mc-list-scroll{flex:1 1 auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;margin:0 -16px;padding:0}
#mcListSheet .sheet-body{display:flex;flex-direction:column;overflow:hidden}
#mcListQ{margin:0}
/* the composer is furniture, not content - the thread scrolls under it */
#mcSheet .sheet-body{display:flex;flex-direction:column;overflow:hidden;min-height:0}
#mcSheet .mc-pane{flex:1 1 auto;min-height:0}
#mcSheet .mc-thread{flex:1 1 auto;min-height:0;max-height:none}
.mc-name-row{display:flex;align-items:center;gap:7px;min-width:0}
.mc-name-row #mcName{font-size:17px;font-weight:800;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* v1.179.0 (Alex): "Open contact button beside the x mobile. Then the call button beside
   open contact." They used to sit in the sheet BODY on the row under the X, so the window
   had two right-hand control clusters stacked on each other. In the pull bar now, parked
   left of the X (16px edge + 34px button + 8px gap = 58px) and ordered call - contact so
   that left to right it reads call, contact, X. */
.mc-hd-acts{display:flex;align-items:center;gap:7px;flex-shrink:0}
#mcSheet .pull-bar .mc-hd-acts{position:absolute;right:58px;top:10px;z-index:47}
/* v1.180.0 (Alex): "Call and contact button should be our regular UI button as well, not a
   flat button." They were a flat grey disc, which read as foreign the moment v1.179.0 sat
   them next to the X. TNP's regular round button is the glass one - .sheet-x, .map-loc and
   #punchShow all share it - and this recipe is READ OUT OF .sheet-x by the build rather than
   restated here, so the four controls cannot drift apart. */
.mc-act{width:34px;height:34px;border-radius:50%;background:radial-gradient(60% 42% at 30% 6%,rgba(255,255,255,.72),transparent 50%),rgba(255,255,255,.4);backdrop-filter:blur(24px) saturate(200%);-webkit-backdrop-filter:blur(24px) saturate(200%);box-shadow:0 4px 14px -4px rgba(15,25,45,.3),inset 0 1px 0 rgba(255,255,255,.8);border:1px solid rgba(255,255,255,.6);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0}
.mc-act svg{width:17px;height:17px;stroke:var(--sub);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.mc-act:disabled{opacity:.35;cursor:default}
.mc-act-call svg{stroke:#16a34a}
/* v1.180.0: the green lives on the glyph, not on a flat fill - the .map-loc.on idiom. */
/* XR's send circle takes the colour of the line it will send from */
.mc-send-bar[data-line="dispatch"] .mc-send-btn:not(:disabled){background:#0a84ff}
.mc-send-bar[data-line="dispatch2"] .mc-send-btn:not(:disabled){background:#5e9eff}
.mc-send-bar[data-line="dispatch3"] .mc-send-btn:not(:disabled){background:#0a5bbf}
.mc-send-bar[data-line="payroll"] .mc-send-btn:not(:disabled){background:#34c759}
.mc-send-bar[data-line="onboarding"] .mc-send-btn:not(:disabled){background:#84a047}
/* unread + empty composer: the circle stays live and pulses, and a tap clears the unread */
.mc-send-btn.mark-read{opacity:1}
.mc-send-btn.mark-read svg{display:none}
.mc-send-btn.mark-read::after{content:"✓";color:#fff;font-size:17px;font-weight:800;line-height:1}
@keyframes mcReadPulse{0%,100%{box-shadow:0 0 0 0 rgba(255,255,255,0)}50%{box-shadow:0 0 0 5px rgba(255,255,255,.28)}}
.mc-send-btn.mark-read{animation:mcReadPulse 1.9s ease-in-out infinite}
.mc-line-wrap{position:relative;display:inline-flex}
.mc-line-pill.dispatch{background:rgba(10,132,255,.18);color:#0a5bbf;border-color:rgba(10,132,255,.35)}
.mc-line-pill.dispatch2{background:rgba(94,158,255,.18);color:#2f6fd0;border-color:rgba(94,158,255,.35)}
.mc-line-pill.dispatch3{background:rgba(10,91,191,.2);color:#08418a;border-color:rgba(10,91,191,.35)}
.mc-line-pill.payroll{background:rgba(52,199,89,.18);color:#1d7c3e;border-color:rgba(52,199,89,.35)}
.mc-line-pill.onboarding{background:rgba(132,160,71,.2);color:#5a7028;border-color:rgba(132,160,71,.38)}
.mc-row.unread .mc-row-name{font-weight:800}
.mc-row.unread::before{content:"";position:absolute;left:5px;top:50%;transform:translateY(-50%);width:6px;height:6px;border-radius:50%;background:#0a84ff}
.mc-row.unread.alert::before{background:#E3202A}
.mc-row-name{font-size:14px;font-weight:700;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mc-row-sub{font-size:12px;color:var(--meta);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* v1.176.0 (Alex): "The filter list buttons / tags should be the same size as the tags on
   the list. They shouldn't be different sizes tags on the two cards." There were THREE
   scales in play across two cards that sit side by side - .mc-badge 10px/2px 7px, .chip
   11px/5px 10px and .ppe-pill 13px/9px 14px. The row tags now share .chip's metrics and the
   filter's status buttons share .mc-chan's, so each kind of control is one size everywhere. */
.mc-badge{font-size:11px;font-weight:700;padding:5px 10px;border-radius:999px}
.mc-badge.red{background:rgba(227,32,42,.14);color:#c01824}.mc-badge.amber{background:rgba(217,119,6,.16);color:#b45309}.mc-badge.blue{background:var(--blue-bg);color:var(--blue)}.mc-badge.slate{background:rgba(118,131,151,.16);color:var(--sub)}
.mc-pane{display:flex;gap:0;align-items:stretch;min-height:0}
.mc-col-thread{flex:1 1 0;min-width:0;display:flex;flex-direction:column;min-height:0}
.mc-col-info{display:none}
.mc-thread{max-height:46vh;overflow-y:auto;display:flex;flex-direction:column;gap:6px;padding:4px 2px;min-height:0}
.mc-divider{display:none}
.mc-search-top{padding:2px 16px 8px}
.mc-search{width:100%;box-sizing:border-box;border:1px solid var(--line);border-radius:999px;background:var(--card);color:var(--ink);font:inherit;font-size:13px;padding:8px 14px;outline:none}
.mc-search:focus{border-color:var(--blue)}
.mc-list-items{min-height:calc(100% + 1px)}
.side-resize{position:absolute;top:0;bottom:0;width:12px;cursor:col-resize;z-index:6;touch-action:none;-webkit-user-select:none;user-select:none}
.side-resize-r{right:-3px}
.side-resize-l{left:-3px}
/* v1.49.0: Payroll module */
.pay-wknav{width:30px;height:30px;border-radius:10px;border:1px solid var(--line);background:var(--card);color:var(--ink);font-size:16px;font-weight:800;cursor:pointer;line-height:1}
.pay-tile{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:10px 12px}
.pay-tile .k{font-size:10px;color:var(--meta);font-weight:700;text-transform:uppercase}
.pay-tile .v{font-size:20px;color:var(--ink);font-weight:800;margin-top:2px}
.pay-row{display:flex;align-items:center;gap:11px;padding:11px 6px;border-bottom:1px solid rgba(118,131,151,.14);cursor:pointer}
.pr-pane{display:flex;flex-direction:column;gap:14px;min-height:0}
.pr-col-img img{max-width:100%;border-radius:14px;border:1px solid var(--line);cursor:zoom-in}
.pr-day{display:grid;grid-template-columns:var(--pr-cols,140px 150px 150px 64px 96px 30px);gap:6px;align-items:center;padding:7px 4px;border-bottom:1px solid rgba(118,131,151,.14);font-size:13px}
#prRows{overflow-x:auto}
.pr-colh{position:absolute;top:0;right:-3px;width:10px;height:100%;cursor:col-resize;z-index:3;touch-action:none}
.pr-day input{border:1px solid var(--line);border-radius:9px;padding:6px 7px;font:inherit;font-size:12.5px;background:var(--card);color:var(--ink);width:100%;box-sizing:border-box}
.pr-day .conf{font-size:10px;font-weight:800;text-align:center;border-radius:8px;padding:3px 0}
.pr-day.rejected{opacity:.45;text-decoration:line-through}
.pr-ts-card{border:1.5px solid var(--line);border-radius:14px;padding:12px;margin-bottom:8px;cursor:pointer}
.pr-ts-card.linked{border-color:var(--green)}
.pr-ts-card.warn{border-color:#d97706}
.ts-sf{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:9px;border:1px solid var(--line);color:var(--sub);flex-shrink:0;cursor:pointer;text-decoration:none}
.ts-sf svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.ts-sf:hover{color:var(--blue);border-color:var(--blue)}
@media (min-width:768px){
.pr-pane{flex-direction:row;align-items:flex-start}
.pr-col-img{flex:0 0 42%;max-width:460px;position:sticky;top:0}
.pr-col-main{flex:1;min-width:0}
#prSheet.open{width:min(1020px,calc(96vw - var(--railw)))}
}
/* v1.48.0: slider-card track deprecated — markers are the selection surface */
#siteTrack,#siteDots{display:none!important}
#gsAreaBtn{position:absolute;top:16px;left:50%;transform:translateX(-50%);z-index:1100;border:none;border-radius:999px;padding:9px 18px;background:#fff;color:var(--ink);font:inherit;font-size:13px;font-weight:800;box-shadow:0 6px 18px -6px rgba(15,25,45,.45);cursor:pointer}
#gsAreaBtn:active{transform:translateX(-50%) scale(.97)}
/* v1.177.0: text you might legitimately want to copy stays selectable. */
input,textarea,select,[contenteditable="true"],.mc-b,.mc-b-time,.bd-body,#bdBody,.tk-note,.note-body,.pr-sum,.sel-ok{-webkit-user-select:text;user-select:text;-webkit-touch-callout:default}
.mc-b{max-width:82%;padding:8px 12px;border-radius:16px;font-size:14px;line-height:1.35;word-break:break-word;white-space:pre-wrap}
.mc-b-out{align-self:flex-end;background:#0a84ff;color:#fff;border-bottom-right-radius:5px}
.mc-b-in{align-self:flex-start;background:rgba(118,131,151,.16);color:var(--ink);border-bottom-left-radius:5px}
.mc-b-time{font-size:10px;color:var(--meta);font-weight:600;margin-top:2px}
.mc-b-time.out{align-self:flex-end}
/* v1.179.0 (Alex): "TNFM XR's text input area and message thread extends more to the side
   of the window. The text input area extends towards the bottom with the radius along the
   bottom corners." Ported from XR verbatim - .thread-send-bar is 16px at rest and
   16px 16px 45px 45px on a phone, sitting in a card whose bottom padding drops to
   max(0px, safe-area - 19px). The 45px echoes the screen's own corner curvature, and the
   safe-area inset moves INSIDE the bar, which is what makes it taller as well as lower.
   TNP's side padding was 20px on the body plus 2px on the thread; XR gives the desktop
   card 18px and a phone less than that. */
@media (max-width:767px){
  #mcSheet .sheet-body{padding-left:10px;padding-right:10px;
    padding-bottom:max(0px,calc(var(--safe-bot) - 19px))}
  #mcSheet .mc-thread{padding-left:6px;padding-right:6px}
  /* v1.180.0 (Alex): "The send button and + button should be at the bottom of the card."
     v1.179.0 carried the safe-area inset INSIDE the bar to make it taller, but the bar is
     align-items:flex-end - which aligns to the bottom of the CONTENT box - so the circles
     ended up floating 44px above the bar's own bottom edge on a notched phone. That padding
     was not XR's: XR keeps padding:8px 10px and lets the sheet's padding-bottom carry the
     safe area, which is exactly why its send circle sits on the edge. The height comes from
     the textarea floor below instead, which is what XR's manual-drag floor does. */
  #mcSheet .mc-send-bar{margin-bottom:0;border-radius:16px 16px 45px 45px}
  #mcSheet .mc-send-bar textarea{min-height:64px}
  #mcSheet .mc-line-row{margin:6px 0 4px}
}
@media (min-width:768px){#mcSheet .sheet-body{padding-left:18px;padding-right:18px}}
.mc-line-row{margin:8px 0 6px;flex-shrink:0;display:flex;justify-content:center}
.mc-send-bar{flex-shrink:0}
.mc-line-pill{font-size:12px;font-weight:700;border:1px solid var(--line);border-radius:999px;padding:5px 12px;background:var(--card);color:var(--ink)}
/* v1.176.0 (Alex): "Same design of the text input area with the rounded bottom corners and
   send button inside the text input area." XR's .thread-send-bar is ONE bordered rounded box
   containing a transparent, border-less textarea and the send circle; TNP had two separate
   controls side by side, which is why it never read as the reference. */
/* v1.184.0 (Alex): "The send text entry should be on top of the buttons, not within it."
   Column: full-width textarea on top, the action row under it. */
.mc-send-bar{display:flex;flex-direction:column;align-items:stretch;gap:6px;padding:8px 10px;background:var(--card);border:1px solid var(--line);border-radius:16px;margin:3px 0 0}
.mc-act-row{display:flex;gap:8px;align-items:center}
.mc-act-row .mc-send-btn{margin-left:auto}
.mc-send-bar textarea{flex:1;min-height:36px;max-height:120px;resize:none;border:0;outline:0;border-radius:0;padding:8px 4px;font:inherit;font-size:14px;line-height:1.4;background:transparent;color:var(--ink)}
.mc-send-bar textarea::placeholder{color:var(--meta)}
/* the + and the send circle are the same control at two ends of the box, so they share every
   rule including the per-line colour below */
.mc-send-btn,.mc-photo-btn,.mc-ai-btn{width:34px;height:34px;flex-shrink:0;border-radius:50%;border:none;background:#0a84ff;display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0}
/* v1.180.0 (Alex): "Make the + button a regular white button." The send circle keeps the
   line colour because that colour MEANS something - which TNL number the text leaves on -
   while + only opens a file picker, so it takes the same regular round button as call and
   contact. Same recipe, same source. */
.mc-photo-btn,.mc-ai-btn{background:radial-gradient(60% 42% at 30% 6%,rgba(255,255,255,.72),transparent 50%),rgba(255,255,255,.4);backdrop-filter:blur(24px) saturate(200%);-webkit-backdrop-filter:blur(24px) saturate(200%);box-shadow:0 4px 14px -4px rgba(15,25,45,.3),inset 0 1px 0 rgba(255,255,255,.8);border:1px solid rgba(255,255,255,.6)}
.mc-send-btn:disabled,.mc-photo-btn:disabled{opacity:.4;cursor:default}
.mc-send-btn svg,.mc-photo-btn svg{width:16px;height:16px;stroke:#fff;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.mc-photo-btn svg{stroke-width:2.4;stroke:var(--ink3)}
/* XR's AI bubble glyph: the cyan four-point star, filled not stroked. */
.mc-ai-btn svg{fill:#0891b2;stroke:none;width:15px;height:15px}
.mc-ai-btn.loading{animation:mcAiPulse 1.2s ease-in-out infinite}
@keyframes mcAiPulse{0%,100%{transform:scale(1)}50%{transform:scale(.88)}}
/* v1.184.0: the AI summary overlay - XR .ai-summary-overlay/.ai-summary-card, restated in
   TNP's own variables. Absolute over the message sheet, card pinned to the top. */
.mc-ai-ov{position:absolute;inset:0;z-index:60;background:rgba(248,250,252,.85);backdrop-filter:blur(12px) saturate(160%);-webkit-backdrop-filter:blur(12px) saturate(160%);border-radius:inherit;display:flex;align-items:flex-start;justify-content:center;padding:24px 16px;opacity:0;pointer-events:none;transition:opacity .18s ease}
.mc-ai-ov.open{opacity:1;pointer-events:auto}
.mc-ai-card{width:100%;max-width:560px;background:var(--card);border:1px solid var(--line);border-radius:18px;padding:16px 18px;box-shadow:0 12px 32px rgba(15,23,42,.18);display:flex;flex-direction:column;gap:12px;max-height:100%;overflow-y:auto}
.mc-ai-hd{display:flex;align-items:center;gap:8px;font-weight:800;font-size:15px;color:var(--ink)}
.mc-ai-hd .sheet-x{margin-left:auto}
.mc-ai-badge{background:#0891b2;color:#fff;font-size:10px;font-weight:800;padding:2px 7px;border-radius:999px;letter-spacing:.4px}
.mc-ai-sec h4{margin:0 0 4px;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.5px;color:var(--meta)}
.mc-ai-sec div{font-size:13.5px;line-height:1.5;color:var(--ink)}
.mc-ai-sug{background:rgba(8,145,178,.08);border:1px solid rgba(8,145,178,.22);border-radius:12px;padding:10px 12px}
.mc-ai-load{font-size:13px;color:var(--sub);padding:6px 0 2px}
.mc-ai-acts{display:flex;gap:10px;justify-content:flex-end}
.mc-ai-acts .big-btn{width:auto;padding:10px 16px;margin:0}
.mc-day{align-self:center;font-size:10px;font-weight:700;color:var(--meta);background:rgba(118,131,151,.12);padding:2px 10px;border-radius:999px;margin:4px 0}
@media (min-width:768px){
#mcSheet.open{width:min(920px,calc(94vw - var(--railw)));height:min(87vh,860px)}
#mcSheet .sheet-body{display:flex;flex-direction:column;overflow:hidden}
#mcSheet #mcPane{flex:1;min-height:0}
.mc-col-info{display:block;flex:0 0 40%;min-width:0;padding-left:16px;overflow-y:auto;min-height:0}
.mc-thread{flex:1;max-height:none;min-height:0}
.mc-divider{display:block;flex:0 0 14px;position:relative;align-self:stretch;cursor:col-resize;touch-action:none;-webkit-user-select:none;user-select:none}
.mc-divider::before{content:"";position:absolute;left:50%;top:0;bottom:0;width:1px;background:rgba(118,131,151,.28);transform:translateX(-50%);transition:background .15s,width .15s}
.mc-divider:hover::before{background:rgba(118,131,151,.62);width:2px}
#mcPane.mc-resizing{cursor:col-resize}
#mcPane.mc-resizing .mc-divider::before{background:#60a5fa;width:2px}
}
/* ===== v1.39.1 viewport clamp (G60): no --app-h consumer may exceed the true dynamic viewport ===== */
@media (max-width:767px){
@supports (height:100dvh){
.view{height:min(var(--app-h,100dvh),100dvh)}
.pill-wrap{top:calc(min(var(--app-h,100dvh),100dvh) - 96px - var(--safe-bot))}
.punch-target{top:calc(min(var(--app-h,100dvh),100dvh) - 121px - var(--safe-bot))}
}
}

/* ===== v1.67.0 G-15 preview/editor + payroll home dashboard ===== */
.pr-strip{display:flex;gap:8px;margin-top:8px;overflow-x:auto;padding-bottom:4px}
.pr-thumb{position:relative;flex:0 0 64px;height:64px;border:2px solid var(--line);border-radius:10px;overflow:hidden;cursor:pointer;background:var(--card)}
.pr-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.pr-thumb.on{border-color:#2c5ce5}
.pr-thumb .b{position:absolute;left:0;right:0;bottom:0;font-size:9px;font-weight:800;color:#fff;background:rgba(15,23,42,.55);padding:1px 4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ph-tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(118px,1fr));gap:8px;margin-top:12px}
.ph-tile{cursor:pointer}
.ph-tile.mut .v{color:var(--meta)}
.ph-tile:active{transform:scale(.98)}
.pe-tools{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-bottom:8px}
.pe-tools .tbtn{border:1px solid var(--line);background:var(--card);color:var(--ink);border-radius:10px;padding:7px 11px;font-size:12.5px;font-weight:700;cursor:pointer;display:inline-flex;align-items:center;gap:5px}
.pe-tools .tbtn.on{border-color:#2c5ce5;color:#2c5ce5;background:rgba(44,92,229,.10)}
.pe-tools .cdot{width:20px;height:20px;border-radius:50%;border:2px solid var(--line);cursor:pointer;display:inline-block}
.pe-tools .cdot.on{border-color:var(--ink)}
.pe-wrap{position:relative;background:#0b1220;border:1px solid var(--line);border-radius:12px;overflow:auto;max-height:min(62vh,640px);display:flex;align-items:flex-start;justify-content:center}
#peCanvas,.pe-wrap canvas{max-width:100%;height:auto;display:block;touch-action:none;cursor:crosshair}
.pe-wrap img{max-width:100%}

/* v1.68.0 Time Punch ranges */
.tp-chip{border:0;cursor:pointer;font-weight:700;background:rgba(118,131,151,.12);color:var(--sub)}
.tp-chip.on{background:rgba(44,92,229,.14);color:#2c5ce5}
#tpRangeWrap{display:none}
#tpRangeWrap.on{display:flex}

/* v1.69.0 (no new rules — st card reuses wcard/chip) */

/* v1.70.0 master timesheet grid */
.st-scroll{overflow-x:auto;padding-bottom:4px}
.st-grid{display:grid;gap:2px 4px;align-items:center;min-width:540px}
.st-grid .st-hd{font-size:9.5px;font-weight:800;color:var(--meta);letter-spacing:.04em;padding:4px 2px;border-bottom:2px solid var(--line);align-self:stretch;display:flex;align-items:flex-end}
.st-grid .st-c{text-align:center;font-size:12px;font-weight:600;color:var(--ink2);font-variant-numeric:tabular-nums;padding:8px 1px}.st-grid .st-hd.st-c{font-size:9.5px;font-weight:800;color:var(--meta);padding:4px 2px;justify-content:center}.st-grid .st-cin{padding:3px 1px}
.st-grid .st-nm{font-size:12.5px;font-weight:700;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:8px 2px}
.st-grid .st-b{font-weight:800;color:var(--ink)}
.st-grid .st-row{cursor:pointer;border-bottom:1px solid rgba(118,131,151,.10)}
.st-grid .st-days{grid-column:1/-1;border-bottom:1px solid var(--line);padding:5px 2px;background:rgba(118,131,151,.05);border-radius:8px}
.st-dl{display:flex;justify-content:space-between;gap:8px;font-size:12px;font-weight:600;color:var(--ink2);padding:3px 4px;align-items:center}
/* v1.102.0 (Alex): "The timesheet can be wider." Bleed past the sheet body's 20px padding - 28px
   of extra grid on every screen, most of a day column on a phone. */
#stList,.stb-hd{margin-left:-14px;margin-right:-14px}
/* v1.102.0 (Alex): "the hours and edit needs to all be on one row... even on narrower screens it
   should scale down the font to fit". The rows used to flex-wrap, so on a phone the lunch field
   and its heading dropped to their own lines and one punch took three rows. nowrap + the two time
   inputs sharing the leftover space (min-width:0 is what actually lets a flex item shrink below
   its content) + clamp() type. The head repeats the row's proportions so the labels stay over
   their own columns at every width. */
.st-erow,.st-ehd{display:flex;flex-wrap:nowrap;align-items:center;gap:5px;padding:3px 2px}
.st-erow .st-dt,.st-ehd .st-dt{flex:0 0 auto;width:clamp(36px,12%,64px);font-size:clamp(9px,2.5vw,12px);font-weight:700;color:var(--ink);overflow:hidden;white-space:nowrap}
.st-erow .st-ri,.st-erow .st-ro2,.st-ehd .h-t{flex:1 1 0;min-width:0}
.st-erow .st-rl,.st-ehd .h-l{flex:0 0 auto;width:clamp(40px,15%,66px);min-width:0}
.st-erow input{margin:0;padding:5px 3px;font-size:clamp(9.5px,2.8vw,13px);text-align:center}
.st-erow .st-sep,.st-ehd .st-sep{flex:0 0 auto;color:var(--meta);font-weight:700;font-size:clamp(9px,2.4vw,12px)}
.st-ehd{font-size:clamp(7.5px,2.1vw,9.5px);font-weight:800;color:var(--meta);letter-spacing:.05em}
.st-ehd span{text-align:center;overflow:hidden;white-space:nowrap}
/* ===== v1.76 mobile bottom bar ===== */
#mbar{position:fixed;left:50%;right:auto;transform:translateX(-50%);bottom:calc(14px + var(--safe-bot));z-index:1999;display:none;gap:0;overflow:hidden;width:auto;max-width:calc(100vw - 24px);padding:6px 8px;border-radius:27px;background:rgba(255,255,255,.86);backdrop-filter:blur(40px) saturate(190%) brightness(1.04);-webkit-backdrop-filter:blur(40px) saturate(190%) brightness(1.04);border:1px solid rgba(255,255,255,.72);box-shadow:0 12px 32px -10px rgba(15,25,45,.32),0 2px 8px -3px rgba(15,25,45,.14)}
#mbar::-webkit-scrollbar{display:none}
/* v1.91.0: equal-width slots => uniform icon spacing by construction, and no scrolling. */
.mb-it{flex:1 1 64px;min-width:0;display:flex;flex-direction:column;align-items:center;gap:3px;padding:5px 2px 4px;border:none;background:none;cursor:pointer;color:var(--nav-idle);border-radius:14px}
.mb-gap{flex:0 0 92px}
/* v1.104.0: the badge anchors to the nav button, which had no positioning context of its own. */
.mb-it{position:relative}
.mb-bdg{position:absolute;top:3px;right:9px;min-width:15px;height:15px;padding:0 4px;border-radius:8px;background:#E3202A;color:#fff;font-size:9px;font-weight:800;display:flex;align-items:center;justify-content:center;line-height:1}
/* One panel per site, snapped, with the scrollbar hidden - it is a swipe surface, not a list. */
.ap-swipe{display:flex;gap:12px;overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.ap-swipe::-webkit-scrollbar{display:none}
.ap-pan{flex:0 0 100%;scroll-snap-align:center;min-width:0}
/* the clone keeps .sheet-body, whose padding and scroll belong to a sheet, not to a panel */
.ap-pan .sheet-body{padding:0;overflow:visible;flex:none}
/* v1.104.1: the v1.102.0 width bleed is sized against .sheet-body's 20px padding, which a panel
   does not have - left alone it hangs outside the panel box and .ap-swipe's overflow cuts the
   worker name off the left and the Approve button off the right. Inside a panel there is no sheet
   chrome to bleed into, so the bleed is zeroed and .ap-swipe reclaims the same 14px either side
   instead, which puts the grid back at the width it has in the standalone sheet. */
.ap-pan #stList,.ap-pan .stb-hd{margin-left:0;margin-right:0}
.ap-pan .sh-stick{margin-left:0;margin-right:0;padding-left:0;padding-right:0}
.ap-swipe{margin-left:-14px;margin-right:-14px}
.ap-pan{padding-left:14px;padding-right:14px}
.ap-dots{display:flex;gap:6px;justify-content:center;margin-top:10px}
.ap-dot{width:7px;height:7px;border-radius:50%;background:rgba(118,131,151,.32)}
.ap-dot.on{background:var(--blue)}
.mb-slot{flex:1 1 64px}
.mb-it span{max-width:100%;overflow:hidden;text-overflow:ellipsis}
.mb-it svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.mb-it span{font-size:9.5px;font-weight:700;white-space:nowrap}
.mb-it.on{color:var(--blue)}
.wd .dotc{width:5px;height:5px;border-radius:50%;background:#16a34a;margin-top:2px}
.sup-w{font-size:12px;color:var(--sub);font-weight:700;margin-top:2px}
@media (max-width:767px){
#mbar{display:flex}
.pill-side{display:none}
.pill{width:auto;height:auto;background:none;border:none;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none}
.pill-wrap{left:50%;right:auto;transform:translateX(-50%);top:auto;bottom:calc(12px + var(--safe-bot))}
#punchBtn{position:static;transform:none;width:84px;height:84px;border-width:4px;padding:0 4px}
#punchBtn:active{transform:scale(.96)}
#punchBtn .w{font-size:11.5px}
#punchBtn .el{font-size:9.5px;margin-top:1px}
.punch-target{left:50%;right:auto;top:auto;bottom:calc(104px + var(--safe-bot));transform:translateX(-50%);max-width:80vw}
body.modal-open #mbar{opacity:0;pointer-events:none;transition:opacity .15s}
}
/* ===== v1.94.0 messages pull tab (left edge, XR-style) ===== */

body.modal-open .tn-dwr-tab,body.sliding .tn-dwr-tab{opacity:0;pointer-events:none}
/* ===== v1.93.0 nav overflow popover ===== */
#moreBd{position:fixed;left:0;top:0;right:0;bottom:0;z-index:2002;display:none;background:transparent}
#moreBd.on{display:block}
#morePop{position:fixed;right:12px;bottom:calc(96px + var(--safe-bot));z-index:2003;display:none;
  min-width:186px;max-width:min(68vw,260px);padding:6px;border-radius:16px;
  background:rgba(255,255,255,.97);backdrop-filter:blur(30px) saturate(180%);-webkit-backdrop-filter:blur(30px) saturate(180%);
  border:1px solid rgba(255,255,255,.75);box-shadow:0 18px 40px -12px rgba(15,25,45,.42),0 2px 8px -3px rgba(15,25,45,.16);
  transform-origin:100% 100%;animation:morePopIn .13s ease-out}
#morePop.on{display:block}
@keyframes morePopIn{from{opacity:0;transform:scale(.94) translateY(6px)}to{opacity:1;transform:none}}
.mb-more{display:flex;align-items:center;gap:10px;width:100%;padding:9px 10px;border:0;background:none;cursor:pointer;
  border-radius:11px;color:var(--ink);font-weight:700;font-size:13.5px;text-align:left}
.mb-more+.mb-more{margin-top:1px}
.mb-more:active{background:rgba(118,131,151,.14)}
/* the nav's icon rules are scoped to .mb-it — without an equivalent here every icon draws at its
   intrinsic size and solid-filled, which is what turned the More menu into black discs. */
.mb-more svg{width:20px;height:20px;flex:0 0 20px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;color:var(--nav-idle)}
/* ===== v1.92.0 master timesheet: phone-fit view A + week-calendar view B ===== */
/* view B */
.stb-hd{display:grid;grid-template-columns:repeat(7,1fr);gap:3px;padding:0 2px 4px;border-bottom:2px solid var(--line)}
.stb-hd div{text-align:center;font-size:9.5px;font-weight:800;color:var(--meta);letter-spacing:.04em}
.stb-w{margin-top:10px;border:1px solid var(--line);border-radius:14px;overflow:hidden;background:var(--card)}
.stb-sub{display:flex;align-items:center;gap:8px;padding:8px 10px;background:rgba(118,131,151,.07);cursor:pointer}
.stb-nm{flex:1;min-width:0;font-size:13.5px;font-weight:800;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.stb-ro{font-size:10px;font-weight:800;color:var(--meta);font-variant-numeric:tabular-nums;white-space:nowrap}
.stb-ro b{color:var(--ink);font-size:11.5px}
.stb-ap{border:0;cursor:pointer;background:var(--green);color:#fff;font-weight:800;font-size:10.5px;padding:6px 12px;border-radius:999px;white-space:nowrap}
.stb-ap[disabled]{background:rgba(118,131,151,.18);color:var(--meta);cursor:default}
.stb-days{display:grid;grid-template-columns:repeat(7,1fr);gap:3px;padding:8px 6px;cursor:pointer}
.stb-d{text-align:center;font-size:12.5px;font-weight:700;color:var(--ink2);font-variant-numeric:tabular-nums;padding:5px 0;border-radius:9px;background:rgba(118,131,151,.06)}
/* v1.101.0 (Alex): "Empty days would still have the darker background with the dash in it." It
   was background:none - a hole in the row rather than a cell with nothing in it. Darker than a
   worked day, deliberately: the gap is the thing worth noticing. */
.stb-d.z{color:var(--sub);background:rgba(118,131,151,.14)}
/* the day letter sits above the number and keeps its own colour - inheriting the cell's would
   fade it out on exactly the empty days it most needs to label */
.stb-d .stb-dw{display:block;font-size:9px;font-weight:800;color:var(--meta);letter-spacing:.06em;line-height:1;margin-bottom:3px}
.stb-d.in{color:var(--green);font-weight:800}
.stb-d small{display:block;font-size:8px;font-weight:700;color:var(--meta)}
.stb-body{border-top:1px solid var(--line);padding:6px 8px 10px}
.stb-lk{font-size:10px;font-weight:800;color:var(--meta)}
@media (max-width:767px){
.st-grid{min-width:0}
.st-grid .st-nm{font-size:11.5px;padding:8px 1px}
.st-grid .st-c{font-size:11px;padding:8px 0}
.st-grid .st-hd{font-size:8.5px}
}
/* ===== v1.89.0 slide to punch ===== */
/* The rail is a fixed overlay sized to the capsule at hold time rather than a child of #mbar,
   so the nav's own children (and every probe assertion that walks them) stay untouched. */
#punchBtn{touch-action:none;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
#mbar .mb-it{transition:opacity .16s}
#mbar.sliding{overflow:hidden;background:rgba(255,255,255,.94)}
#mbar.sliding .mb-it{opacity:0;pointer-events:none}
#slRail{position:fixed;left:0;top:0;width:0;height:0;z-index:1999;display:none;align-items:center;padding:0 12px;border-radius:27px;pointer-events:none}
#slRail.on{display:flex}
.sl-lead{display:none;font-size:10px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--meta);white-space:nowrap}
.sl-t{position:absolute;top:50%;transform:translateY(-50%);font-size:11px;font-weight:800;white-space:nowrap;padding:6px 11px;border-radius:999px;background:rgba(118,131,151,.16);color:var(--sub);transition:background .14s,color .14s,transform .14s}
#slPunch{left:10px}
#slPunch.hot{background:#16a34a;color:#fff;transform:translateY(-50%) scale(1.07)}
#slCheck{right:10px}
#slCheck.hot{background:#2c5ce5;color:#fff;transform:translateY(-50%) scale(1.07)}
#slPunch.out.hot{background:#ef4444}
#punchBtn.sl-drag{box-shadow:0 18px 30px -12px rgba(15,25,45,.55)}
#punchBtn.sl-back{transition:transform .18s cubic-bezier(.2,.8,.3,1)}
#slideCard{position:fixed;left:12px;right:12px;bottom:calc(106px + var(--safe-bot));z-index:2002;display:none;padding:10px 14px;border-radius:16px;background:radial-gradient(75% 55% at 24% -12%,rgba(255,255,255,.6),transparent 46%),rgba(255,255,255,.58);backdrop-filter:blur(42px) saturate(200%);-webkit-backdrop-filter:blur(42px) saturate(200%);border:1px solid rgba(255,255,255,.7);box-shadow:0 14px 34px -12px rgba(15,25,45,.42)}
#slideCard.show{display:block}
#slideCard .sc-t{font-size:14px;font-weight:800;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#slideCard .sc-s{font-size:11.5px;font-weight:600;color:var(--meta);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
body.sliding .punch-target{display:none}
.p-pick{background:#768397;box-shadow:0 14px 22px -10px rgba(118,131,151,.6);color:#fff}
.p-pick .site,.p-pick .el{color:rgba(255,255,255,.85)}
/* ===== v1.77.2 payroll band glass ===== */
#paySheet .sh-stick{background:transparent}
#paySheet .sh-stick.stuck{background:linear-gradient(rgba(248,250,252,.38),rgba(248,250,252,.14) 55%,rgba(248,250,252,0));backdrop-filter:blur(16px) saturate(165%);-webkit-backdrop-filter:blur(16px) saturate(165%)}
/* v1.113.0: editor reject + greyed blanks + week-nav pending dots */
.st-erow.st-off{opacity:.45}
.st-erow.st-rej{position:relative}
.st-erow.st-rej .input{text-decoration:line-through;color:#E3202A;opacity:.6}
.st-erow.st-rej:after{content:"";position:absolute;left:4px;right:30px;top:50%;border-top:1.5px solid rgba(227,32,42,.55);pointer-events:none}
.st-rx{width:22px;height:22px;border-radius:50%;border:1.5px solid var(--meta);background:none;color:var(--meta);font-size:13px;font-weight:800;line-height:1;flex:0 0 auto;cursor:pointer;padding:0}
.st-rx:hover{color:#E3202A;border-color:#E3202A}
/* v1.119.0: the REAL iOS fix - fr tracks floor at min-content, so the grid columns are minmax(0,)-capped
   inline; these rules make the inputs themselves slim enough to read at that width */
#dayAdj .fo-inp{min-width:0;width:100%;box-sizing:border-box;-webkit-appearance:none;appearance:none;padding:10px 8px;font-size:14px;border-radius:10px}
#dayAdj input::-webkit-date-and-time-value{text-align:left}
/* v1.118.0: editor rows that cannot save are dim; the check/lock glyphs are markers, not buttons */
.st-erow.st-lkd .input{opacity:.55}
.st-erow .st-rx.st-apx{border-color:#16a34a;color:#16a34a;cursor:default;display:inline-flex;align-items:center;justify-content:center}
.st-erow .st-rx.st-lkx{border:0;cursor:default;font-size:12px;display:inline-flex;align-items:center;justify-content:center}
/* v1.115.0 (Alex): the arrow itself glows red when pending approvals live in that direction */
#stPrev.st-wglow,#stNext.st-wglow{border-color:#E3202A!important;animation:stGlow 1.6s ease-in-out infinite}
#stPrev.st-wglow svg,#stNext.st-wglow svg{stroke:#E3202A!important}
@keyframes stGlow{0%,100%{box-shadow:0 0 0 1.5px rgba(227,32,42,.35),0 0 8px 1px rgba(227,32,42,.3)}50%{box-shadow:0 0 0 1.5px rgba(227,32,42,.55),0 0 14px 4px rgba(227,32,42,.55)}}
/* ==== v1.123.0: left drawers, attention glows, assignment links ==== */
@media (max-width:767px){
  /* v1.166.0 (Alex): the message centre and the filter become XR-style edge drawers.
   Geometry lifted from XR v6.3.80 .map-drawer - inset top/bottom so the header and the
   tab bar stay visible, 90vw capped at 440px, 26px radius on the inner corners only. */
:root{--dwrTop:96px;--dwrBot:calc(84px + var(--safe-bot,0px))}
@media (min-width:768px){:root{--dwrTop:18px;--dwrBot:18px}}
/* XR v6.3.37 pull bar: a VERTICAL 4x75 bar on the drawer's outer edge, not the 42x5
   horizontal grab pill a bottom sheet uses. The alert pulse is XR's tnfmPullAlert. */
@keyframes tnfmPullAlert{0%,100%{background:rgba(227,32,42,.5);box-shadow:0 0 3px rgba(227,32,42,.25)}50%{background:#E3202A;box-shadow:0 0 14px rgba(227,32,42,.9)}}
#mcListSheet .pull-bar,#fltDrawer .tn-pull{position:absolute;top:50%;width:4px;height:75px;padding:0;border-radius:2px;background:rgba(120,130,145,.55);transform:translateY(-50%);pointer-events:none;z-index:46;display:block;transition:opacity .25s ease}
#mcListSheet .pull-bar::before{content:none}
#mcListSheet .pull-bar{right:7px;left:auto}
#fltDrawer .tn-pull{left:7px;right:auto}
#mcListSheet.unread .pull-bar,#fltDrawer.unread .tn-pull{animation:tnfmPullAlert 2.4s ease-in-out infinite}
/* v1.169.0 (Alex): "it retracts a bit then slides in again... should just slide into
   position from where I let go. Same inertia as TNFM XR." A keyframe cannot do that - it
   always replays from its `from`. XR parks the drawer with a 15px tab peeking and moves it
   with a TRANSITION; `.dragging` drops the transition so an inline transform can follow the
   finger, and clearing it on release lets the transition finish from wherever it is. */
/* v1.177.0 (Alex): "Message window should be on top of the message list and filter list
   panels." The drawers were minted at 2720 and .sheet is 2710, so every window opened FROM
   a drawer opened UNDER it. 2705 keeps them above the shared overlay #psOv (2700) - they
   have to be, or it eats their taps - and below every sheet. .tn-dwr-front is the
   most-recently-addressed drawer, so the two of them alternate rather than being decided
   by DOM order. */
.tn-dwr{position:fixed;top:var(--dwrTop);bottom:var(--dwrBot);width:min(90vw,440px);z-index:2705;display:flex;align-items:stretch;will-change:transform}
/* v1.183.0: the drawer is now the ONLY message centre, so on a desktop it has to read as a
   primary panel rather than a phone artefact carried over. It clears the rail and takes the
   width the dock panel used to have. */
@media (min-width:768px){
  .tn-dwr.left{left:var(--railw);width:min(460px,52vw)}
  .tn-dwr.left.open{transform:translateX(0)}
  #mcListSheet .tn-dwr-body{padding:16px 18px calc(14px + var(--safe-bot,0px))}
}
.tn-dwr.tn-dwr-front{z-index:2706}
.tn-dwr.left{left:0;right:auto;transform:translateX(calc(-100% + 15px));transition:transform .35s cubic-bezier(.22,1,.36,1)}
.tn-dwr.right{right:0;left:auto;transform:translateX(calc(100% - 15px));transition:transform .35s cubic-bezier(.22,1,.36,1)}
.tn-dwr.left.open,.tn-dwr.right.open{transform:translateX(0)}
.tn-dwr.dragging{transition:none}
#fltDrawer.dragging{transition:none}
.tn-dwr-inner{display:flex;width:100%;height:100%;align-items:stretch;min-width:0}
.tn-dwr.left .tn-dwr-inner{flex-direction:row-reverse}
.tn-dwr.right .tn-dwr-inner{flex-direction:row}
/* XR v6.3.38: a full-height grab COLUMN (big touch target) with the bar drawn at its
   vertical centre - same 15px closed peek. */
.tn-dwr-tab{flex:0 0 15px;width:15px;align-self:stretch;background:transparent;border:0;padding:0;display:flex;align-items:center;justify-content:center;cursor:grab;touch-action:none;user-select:none;-webkit-user-select:none;position:relative}
.tn-dwr-tab .pull-bar{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:4px;height:75px;padding:0;border-radius:2px;background:rgba(120,130,145,.55);pointer-events:none;display:block;transition:opacity .25s ease}
.tn-dwr-tab .pull-bar::before{content:none}
.tn-dwr-tab.glow-red .pull-bar{animation:tnfmPullAlert 2.4s ease-in-out infinite}
/* "Don't need grab bar or x when expanded" - XR hides the bar on touch once open; the
   swipe-away gesture replaces the X, so that goes too. */
@media (hover:none) and (pointer:coarse){
.tn-dwr.open .tn-dwr-tab .pull-bar{opacity:0;transition:opacity .2s ease .2s}
.tn-dwr.open .sheet-x{display:none}
}
.tn-dwr-body{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;overflow:hidden;background:radial-gradient(55% 28% at 28% 0%,rgba(255,255,255,.62),transparent 42%),rgba(248,250,252,.6);backdrop-filter:blur(52px) saturate(200%) brightness(1.08);-webkit-backdrop-filter:blur(52px) saturate(200%) brightness(1.08);border:1px solid rgba(255,255,255,.55);box-shadow:0 18px 44px -16px rgba(15,25,45,.42),inset 0 1px 0 rgba(255,255,255,.7);position:relative;padding:14px 16px calc(12px + var(--safe-bot,0px))}
.tn-dwr.left .tn-dwr-body{border-radius:0 26px 26px 0;border-left:0}
.tn-dwr.right .tn-dwr-body{border-radius:26px 0 0 26px;border-right:0}
.tn-dwr .sheet-body{flex:1 1 auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;touch-action:pan-y;padding:0}
/* v1.173.0: the tab is a real 15px column of the inner flex row again (v1.169.0 had to pin
   it absolutely because the drawer stacked its content in a COLUMN). #fltRz keeps the
   desktop resize edge, so it must sit above the body it overlays. */
#fltDrawer .tn-dwr-body{padding:18px 18px calc(14px + var(--safe-bot,0px))}
#fltDrawer #fltRz{z-index:4}
@media (max-width:767px){#fltRz{display:none}}

}
@keyframes tnsheetl{from{transform:translateX(-103%)}to{transform:translateX(0)}}
.st-y{box-shadow:inset 0 0 0 2px rgba(250,204,21,.7);background:rgba(250,204,21,.16)!important;border-radius:9px}
@keyframes stpulse{0%,100%{box-shadow:inset 0 0 0 2px rgba(250,204,21,.9),0 0 3px rgba(250,204,21,.3)}50%{box-shadow:inset 0 0 0 2px rgba(250,204,21,.35),0 0 13px rgba(250,204,21,.8)}}
.st-c.st-cin,.stb-d.in{animation:stpulse 2.6s ease-in-out infinite}
.st-asg{cursor:pointer;text-decoration:underline;text-decoration-color:rgba(44,92,229,.45);text-underline-offset:3px}
/* ==== v1.124.0: XR card stops (12.5 / 60 / 90 vh) + cascade ==== */
@media (max-width:767px){
  .sheet.snapcard{--snapH:calc(var(--vvh,100dvh)*.6);height:var(--snapH);max-height:none;transition:height .35s cubic-bezier(.22,1,.36,1)}
  .sheet.snapcard[data-snap="collapsed"]{--snapH:calc(var(--vvh,100dvh)*.125)}
  .sheet.snapcard[data-snap="expanded"]{--snapH:calc(var(--vvh,100dvh)*.9)}
  .sheet.snapcard.sheet-back{height:calc(var(--snapH) + 16px);filter:brightness(.96) saturate(.92)}
  .sheet.snapcard .pull-bar{touch-action:none;cursor:grab}
}
/* ==== v1.125.0: Site Board + weekly recurrence ==== */
.bd-add{border:1.5px solid var(--line,#e2e8f0);background:var(--card,#fff);color:var(--ink);border-radius:999px;padding:4px 12px;font-size:12px;font-weight:700;cursor:pointer}
.bd-card{min-width:86%;max-width:86%;padding:0;overflow:hidden;scroll-snap-align:start}
.bd-card:only-child{min-width:100%;max-width:100%}
#boardWrap{margin-bottom:14px}
.bd-cbody{padding:14px}
.bd-img{width:100%;height:150px;object-fit:cover;display:block}
#homeCols{display:flex;gap:22px;align-items:flex-start}
#studioSheet{height:min(90vh,1040px);max-height:none}
#artSheet.aeOn{height:min(94vh,1100px);max-height:none}
@media (min-width:768px){#artSheet.aeOn{width:min(880px,calc(94vw - var(--railw)))}}
@media (min-width:1100px){body.hasBoard #homeColR{padding-top:38px}}
#homeColL,#homeColR{flex:1 1 0;min-width:0}
.bd-t{font-size:15px;font-weight:800;color:var(--ink);margin-top:2px}
.bd-m{font-size:11.5px;color:var(--meta);font-weight:600;margin-top:4px}
.bd-ic{width:34px;height:34px;border-radius:10px;display:flex;align-items:center;justify-content:center;flex:none}
.bd-ic svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.bd-ic.ev{background:#eef2ff;color:#4338ca}.bd-ic.nt{background:#fef3c7;color:#b45309}
.rec-d{width:34px;height:34px;border-radius:50%;border:1.5px solid var(--line,#e2e8f0);background:var(--card,#fff);color:var(--sub);font-size:12px;font-weight:800;cursor:pointer}
.rec-d.on{background:#E3202A;border-color:#E3202A;color:#fff}
.bc-lb{font-size:12px;color:var(--sub);font-weight:700;min-width:64px}
/* ==== v1.128.0: account + contact imagery ==== */
.acct-logo{width:100%;height:100%;object-fit:cover;border-radius:inherit;display:block}
.ava-img{width:100%;height:100%;object-fit:cover;border-radius:50%;display:block}
.ct-ava{width:56px;height:56px;border-radius:50%;object-fit:cover;display:block;margin-bottom:8px}
.site-ph{width:132px;height:92px;border-radius:12px;object-fit:cover;flex:none;cursor:pointer}
#sitePhotos{gap:8px}
