/* ============================================================
   DOOR-TO-DOOR SURVEY — field web app
   CONFIDENTIAL · Government of Tamil Nadu

   A self-contained field-instrument stylesheet, distinct from the desktop
   console's app.css on purpose: this module is used on a phone at the
   doorstep (52px tap targets, bottom tabs, drawer, offline-sync badge), a
   different device context from the map consoles.

   Two deliberate departures from the reference mockup it is based on:
     1. NO external fonts. The reference pulled Space Grotesk / IBM Plex from
        Google — which this build's CSP (font-src 'self') blocks, and which
        would leak to Google which device a surveyor is using. System stacks
        carry the same instrument feel through weight and letter-spacing.
     2. Contrast tokens lifted to WCAG AA. The mockup's --muted and the
        faint step captions failed 4.5:1; tests/ui/test_contrast.py audits
        this page like every other, so they are corrected at the token.
   ============================================================ */
:root{
  /* BLUE + WHITE palette (reference GIS-report brand). Tokens stay named
     --indigo* so the whole stylesheet re-themes from here. */
  --ink:#111834;
  --ink-2:#28315A;
  --muted:#5A6487;          /* blue-gray, clears AA on white/paper */
  --indigo:#2A50D8;         /* PRIMARY — royal blue */
  --indigo-deep:#1E3A8A;    /* deeper navy blue: headings, mid rail stop */
  --indigo-tint:#E7ECFC;    /* soft blue chip/tint */
  --paper:#F5F7FE;          /* near-white page background, faintest blue */
  --card:#FFFFFF;
  --line:#DBE2F4;
  --line-soft:#EAEFFB;
  --hivis:#1D4ED8;          /* accent blue — tags, focus, marks */
  --hivis-ink:#1E3A8A;      /* text-on-tint blue */
  --hivis-tint:#DCE6FB;
  --coral:#E5654F;          /* reference coral accent (tenant / region pill) — white text clears AA */
  --coral-ink:#A83B29;      /* text-on-tint coral, clears 4.5:1 on --coral-tint */
  --coral-tint:#FBE8E4;
  --verified:#0E8A5F;
  --verified-ink:#0A6B4A;
  --verified-tint:#E3F5ED;
  --alert:#D93B3B;
  --alert-tint:#FCEAEA;
  --faint:#646d90;          /* was #9AA2C0 — captions/placeholders, lifted to clear 4.5:1 on white */

  --r-sm:6px; --r-md:10px; --r-lg:16px;
  --shadow-1:0 1px 2px rgba(16,23,51,.06), 0 2px 8px rgba(16,23,51,.05);
  --shadow-2:0 8px 28px rgba(16,23,51,.12);
  --rail-w:250px;
  --tap:52px;

  /* ONE font family across the whole app (labels, values, IDs, numbers). The
     old monospace --f-data is folded into the same system sans so nothing looks
     like a different typeface. --f-tamil stays only for Tamil script. */
  --f-display:system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  --f-body:system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  --f-data:system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  --f-tamil:'Noto Sans Tamil',system-ui,sans-serif;
}
*{box-sizing:border-box;margin:0;padding:0}
[hidden]{display:none!important}
html,body{height:100%}
body{
  font-family:var(--f-body);
  font-size:15px;line-height:1.5;color:var(--ink);
  background:var(--paper);
  -webkit-font-smoothing:antialiased;
  overscroll-behavior-y:none;
}
button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer;background:none;border:none}
a{color:inherit;text-decoration:none}
:focus-visible{outline:3px solid var(--hivis);outline-offset:2px;border-radius:4px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ============================================================ SHELL */
.app{display:flex;min-height:100dvh}

.rail{
  width:var(--rail-w);flex:0 0 var(--rail-w);
  background:linear-gradient(180deg,#3B5BE0 0%,var(--indigo-deep) 58%,#152874 100%);color:#fff;
  display:flex;flex-direction:column;
  position:sticky;top:0;height:100dvh;z-index:60;
  box-shadow:1px 0 0 rgba(255,255,255,.06), 4px 0 24px rgba(9,20,45,.25);
}
.rail-brand{padding:16px 16px 14px;display:flex;gap:11px;align-items:center;border-bottom:1px solid rgba(255,255,255,.12)}
.mark{
  width:40px;height:40px;flex:0 0 40px;border-radius:9px;
  background:#fff;color:var(--indigo-deep);
  display:grid;place-items:center;font-family:var(--f-display);font-weight:700;font-size:15px;letter-spacing:.02em;
  overflow:hidden;
}
.mark img{width:34px;height:34px;object-fit:contain;display:block}
.rail-brand > span{display:flex;flex-direction:column;min-width:0}
.brand-t{display:block;font-family:var(--f-display);font-weight:700;font-size:14.5px;letter-spacing:-.01em;line-height:1.2}
.brand-s{display:block;font-size:10.5px;color:rgba(255,255,255,.6);letter-spacing:.06em;text-transform:uppercase;margin-top:2px;white-space:nowrap}

.avatar{width:40px;height:40px;flex:0 0 40px;border-radius:50%;background:linear-gradient(160deg,#8FB0FA,#2A50D8);color:#fff;display:grid;place-items:center;font-family:var(--f-display);font-weight:700;font-size:15px}
.u-name{font-weight:600;font-size:15px}
.u-role{font-size:11.5px;color:rgba(255,255,255,.66)}

/* Claude-style account area — pinned to the bottom of the rail (rail-nav has
   flex:1 above it). Identity on top, My Profile + Sign out beneath. */
.rail-account{padding:10px;border-top:1px solid rgba(255,255,255,.14)}
.acct-user{display:flex;align-items:center;gap:11px;padding:6px 8px 10px}
.acct-user .avatar{width:36px;height:36px;flex:0 0 36px;font-size:14px}
.acct-meta{min-width:0}
.acct-meta .u-name{font-weight:700;font-size:14px;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.acct-meta .u-role{font-size:11.5px;color:rgba(255,255,255,.7)}
.acct-actions{display:flex;flex-direction:column;gap:3px}
.acct-link{
  display:flex;align-items:center;gap:10px;width:100%;text-align:left;
  padding:9px 10px;border-radius:9px;font-size:13.5px;font-weight:600;
  color:rgba(255,255,255,.9);transition:background .15s,color .15s;
}
.acct-link svg{flex:0 0 16px;opacity:.85}
.acct-link:hover{background:rgba(255,255,255,.13);color:#fff}
.acct-out{color:#FFD9D2}
.acct-out:hover{background:rgba(217,59,59,.28);color:#fff}

.rail-nav{flex:1;overflow-y:auto;padding:10px 10px 20px}
.nav-group{margin-top:14px}
.nav-label{
  font-size:10px;letter-spacing:.13em;text-transform:uppercase;
  color:rgba(255,255,255,.66);padding:0 10px 7px;font-weight:700;  /* .66 clears AA on the deeper-blue rail */
}
.nav-item{
  position:relative;display:flex;align-items:center;gap:11px;width:100%;
  padding:11px 12px;border-radius:10px;font-size:14px;color:rgba(255,255,255,.82);
  transition:background .16s,color .16s,box-shadow .16s;text-align:left;
}
.nav-item svg{flex:0 0 18px;opacity:.8;transition:opacity .16s,color .16s}
.nav-item:hover{background:rgba(255,255,255,.1);color:#fff}
.nav-item:hover svg{opacity:1}
/* Active: a translucent highlight with a gold accent bar + gold icon — reads as
   selected on the navy rail without a jarring flat-white block. */
.nav-item[aria-current="page"]{
  background:rgba(255,255,255,.15);color:#fff;font-weight:700;
  box-shadow:inset 3px 0 0 #93C5FD, 0 2px 8px rgba(1,50,50,.3);
}
.nav-item[aria-current="page"] svg{opacity:1;color:#93C5FD}
.nav-count{margin-left:auto;font-family:var(--f-data);font-size:11px;font-weight:700;background:rgba(255,255,255,.18);padding:2px 8px;border-radius:20px}
.nav-item[aria-current="page"] .nav-count{background:#93C5FD;color:var(--indigo-deep)}
.nav-back{color:#CBD3F5}
.nav-back:hover{background:rgba(255,255,255,.09);color:#fff}

.rail-foot{padding:12px;border-top:1px solid rgba(255,255,255,.12)}
.rail-foot .fv{font-size:11px;color:rgba(255,255,255,.55);padding:2px 10px;letter-spacing:.04em}

/* --- main column --- */
.main{flex:1;min-width:0;display:flex;flex-direction:column}

.topbar{
  position:sticky;top:0;z-index:50;
  background:rgba(255,255,255,.94);backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:12px;
  padding:10px 20px;min-height:60px;
}
.hamburger{display:none;width:40px;height:40px;border-radius:9px;align-items:center;justify-content:center}
.backbtn{width:38px;height:38px;border-radius:9px;display:none;align-items:center;justify-content:center;color:var(--ink-2)}
.backbtn:hover{background:var(--paper)}
.backbtn.on{display:flex}
.crumb{font-family:var(--f-display);font-weight:700;font-size:17px;letter-spacing:-.015em}
.crumb small{display:block;font-family:var(--f-body);font-weight:400;font-size:12px;color:var(--muted);letter-spacing:0}

.scope{display:flex;align-items:center;gap:8px;margin-left:auto}

/* SAMPLE compliance marker — carried on every screen, like the desktop console.
   A screenshot of a generated survey with nothing saying it is generated is the
   outcome it prevents. */
.sample-flag{
  display:inline-flex;align-items:center;gap:7px;height:34px;padding:0 12px;
  border-radius:9px;font-size:12px;font-weight:700;letter-spacing:.02em;
  background:var(--hivis-tint);color:var(--hivis-ink);border:1px solid #F3D89A;cursor:help;
}
.sample-flag .dotm{width:8px;height:8px;border-radius:2px;background:var(--hivis);flex:none}

.sync{
  display:flex;align-items:center;gap:8px;height:34px;padding:0 12px;
  border-radius:9px;font-size:13px;font-weight:600;
  background:var(--indigo-tint);color:var(--indigo-deep);border:1px solid #CfD4F0;
}
.sync .dot{width:8px;height:8px;border-radius:50%;background:var(--indigo);animation:pulse 2s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}

/* overflow-wrap:anywhere makes long UNSPACED strings (e.g. comma-joined owner
   names "SAKUNTHALA,RAMESH…") break instead of blowing past their box and
   forcing a horizontal scroll on a phone. overflow-x:clip is the final guard so
   no page can ever scroll sideways — it applies to every pane inside .viewport,
   so the whole app fits its screen. Inherited overflow-wrap covers all text. */
.viewport{flex:1;padding:22px;max-width:1500px;width:100%;overflow-wrap:anywhere;overflow-x:clip}
.screen{display:none}
.screen.on{display:block;animation:fade .22s ease}
@keyframes fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* ============================================================ PRIMITIVES */
.card{background:var(--card);border:1px solid var(--line);border-radius:14px;box-shadow:0 1px 2px rgba(23,53,123,.04),0 10px 26px -14px rgba(23,53,123,.16)}
.card-h{padding:16px 20px 16px 22px;border-bottom:1px solid var(--line-soft);display:flex;align-items:center;gap:12px;position:relative}
.card-h::before{content:"";position:absolute;left:0;top:16px;bottom:16px;width:4px;border-radius:0 4px 4px 0;background:linear-gradient(180deg,var(--indigo),var(--indigo-deep))}
.card-h h3{font-family:var(--f-display);font-size:16px;font-weight:800;letter-spacing:-.015em;color:var(--indigo-deep)}
.card-h p{font-size:12.5px;color:var(--muted);margin-top:2px}
.card-b{padding:18px}

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  height:44px;padding:0 18px;border-radius:10px;font-weight:600;font-size:14.5px;
  transition:transform .1s,box-shadow .15s,background .15s;
  /* A button label is a short control word — never let it break mid-word
     (the page-wide overflow-wrap:anywhere would otherwise split "Prev"/"Next"). */
  white-space:nowrap;overflow-wrap:normal;
}
.btn:active{transform:translateY(1px)}
/* Clean, flat, modern button — solid brand teal with a soft lift shadow. */
.btn-primary{background:var(--indigo);color:#fff;box-shadow:0 1px 2px rgba(20,70,64,.14),0 8px 20px -8px rgba(40,169,158,.55)}
.btn-primary:hover{background:#2246C0;box-shadow:0 2px 4px rgba(20,70,64,.16),0 12px 26px -8px rgba(40,169,158,.6)}
.btn-ghost{border:1px solid var(--line);background:#fff;color:var(--ink-2)}
.btn-ghost:hover{border-color:var(--indigo);color:var(--indigo)}
.btn-go{background:var(--verified);color:#fff;box-shadow:0 2px 0 #0A6B4A}
.btn-go:hover{background:#12996A}
.btn-block{width:100%}
.btn-lg{height:var(--tap);font-size:15.5px}

.chip{
  display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 10px;
  border-radius:20px;font-size:12px;font-weight:700;letter-spacing:.01em;
  white-space:nowrap;flex:none;
}
.chip-amber{background:var(--hivis-tint);color:var(--hivis-ink)}
.chip-green{background:var(--verified-tint);color:var(--verified-ink)}
.chip-red{background:var(--alert-tint);color:#A82727}
.chip-ink{background:var(--indigo-tint);color:var(--indigo-deep)}

.mono{font-family:var(--f-data);letter-spacing:-.02em}

/* ============================================================ FORM FIELDS */
.grid{display:grid;gap:16px}
.g2{grid-template-columns:1fr 1fr}
.g3{grid-template-columns:repeat(3,1fr)}
.span2{grid-column:span 2}

.field{position:relative;display:block}
/* One line, always. The label is absolutely positioned over the field, so a
   long one used to WRAP onto a second line and sit on top of the value the
   surveyor had typed — unreadable, and invisible to the contrast test because
   the colours are fine and only the layout collides. Bounded on the right and
   clipped instead. */
.field > .lbl{
  position:absolute;top:8px;left:14px;right:14px;font-size:10.5px;font-weight:700;
  letter-spacing:.07em;text-transform:uppercase;color:var(--faint);pointer-events:none;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.field .req{color:var(--hivis-ink);font-weight:700;margin-left:2px}
.field input,.field select,.field textarea,.fake{
  width:100%;min-height:56px;padding:23px 14px 9px;
  border:1px solid var(--line);border-radius:11px;background:#fff;
  font-size:15px;transition:border-color .14s,box-shadow .14s;
  box-shadow:inset 0 1px 2px rgba(23,53,123,.03);
}
.field textarea{min-height:88px;resize:vertical}
.field input::placeholder,.field textarea::placeholder{color:var(--faint)}
.field input:hover,.fake:hover{border-color:#B9C1DA}
.field input:focus,.field select:focus,.field textarea:focus,.fake:focus-visible{
  outline:none;border-color:var(--indigo);box-shadow:0 0 0 3.5px rgba(40,169,158,.18)
}
.field.err input,.field.err .fake{border-color:var(--alert);background:#FFFCFC}
.field.err > .lbl{color:var(--alert)}
.field .hint{font-size:11.5px;color:var(--muted);margin-top:5px;display:block}
.field.mono input{font-family:var(--f-data);font-size:16px;letter-spacing:.02em}

/* MIS quick-filter results (wizard step 1) — instant matches, tap to auto-fill */
/* Ward-roll matches float as a DROPDOWN under the search box (anchored to the
   relative .field) instead of pushing the whole form down. */
.mis-results{position:absolute;left:0;right:0;top:calc(100% + 2px);z-index:30;
  border:1px solid var(--line);border-radius:var(--r-md);
  overflow:hidden;max-height:232px;overflow-y:auto;box-shadow:var(--shadow-2);background:#fff}
.mis-hit{display:block;width:100%;text-align:left;padding:11px 13px;
  border-bottom:1px solid var(--line-soft);background:#fff;cursor:pointer}
.mis-hit:last-child{border-bottom:none}
.mis-hit:hover,.mis-hit:focus-visible{background:var(--paper)}
.mis-hit .mh-id{display:block;font-family:var(--f-data);font-weight:700;font-size:13.5px;color:var(--indigo-deep)}
.mis-hit .mh-own{display:block;font-size:13px;color:var(--ink);margin-top:2px}
.mis-hit .mh-sub{display:block;font-size:11.5px;color:var(--muted);margin-top:2px}
.mis-none{padding:13px;font-size:13px;color:var(--muted)}

.fake{
  display:flex;align-items:center;justify-content:space-between;text-align:left;
  cursor:pointer;font-size:15px;
}
.fake .val{color:var(--ink)}
.fake .val.ph{color:var(--faint)}
.fake svg{flex:0 0 16px;color:var(--muted)}

/* iOS-style segmented control: one track, a sliding white pill for the choice. */
.seg{display:flex;gap:0;padding:4px;border-radius:12px;background:var(--indigo-tint);border:1px solid var(--line-soft)}
.seg input{position:absolute;opacity:0;width:0;height:0}
.seg label{
  flex:1;min-width:0;min-height:42px;display:flex;align-items:center;justify-content:center;gap:8px;
  border-radius:9px;background:transparent;
  font-size:14px;font-weight:600;color:var(--muted);cursor:pointer;transition:all .16s;padding:0 12px;
}
.seg label:hover{color:var(--indigo-deep)}
.seg input:checked + label{
  background:#fff;color:var(--indigo-deep);font-weight:700;
  box-shadow:0 2px 6px -1px rgba(23,53,123,.20),0 0 0 1px rgba(23,53,123,.04);
}
.seg input:focus-visible + label{outline:3px solid var(--hivis);outline-offset:2px}
.seg-l{font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:var(--muted);font-weight:700;margin-bottom:7px;display:block}

.switch-row{display:flex;align-items:center;gap:14px;padding:16px 18px;border-bottom:1px solid var(--line-soft)}
.switch-row:last-child{border-bottom:none}
.switch-row h4{font-family:var(--f-display);font-size:14.5px;font-weight:700;color:var(--indigo-deep)}
.switch-row p{font-size:12.5px;color:var(--muted)}
.sw{position:relative;width:48px;height:28px;flex:0 0 48px;margin-left:auto}
.sw input{position:absolute;opacity:0;width:100%;height:100%;margin:0;cursor:pointer;z-index:2}
.sw i{position:absolute;inset:0;background:#B6BDD6;border-radius:20px;transition:background .18s}
.sw i::after{content:"";position:absolute;top:3px;left:3px;width:22px;height:22px;background:#fff;border-radius:50%;transition:transform .18s;box-shadow:0 1px 3px rgba(0,0,0,.25)}
.sw input:checked + i{background:var(--verified)}
.sw input:checked + i::after{transform:translateX(20px)}
.sw input:focus-visible + i{outline:3px solid var(--hivis);outline-offset:2px}

/* ============================================================ STEPPER TABS */
/* Progress stepper: each step's icon is a badge, joined by a connector line;
   the current step fills blue, completed steps go green. */
.wtabs{display:flex;background:#fff;border:1px solid var(--line);border-radius:14px;padding:14px 10px;box-shadow:0 1px 2px rgba(23,53,123,.04),0 10px 26px -16px rgba(23,53,123,.16)}
.wtab{
  flex:1;display:flex;flex-direction:column;align-items:center;gap:9px;padding:2px 4px;
  color:var(--muted);font-size:12.5px;font-weight:600;position:relative;background:transparent;
}
.wtab svg{
  width:42px;height:42px;padding:11px;border-radius:50%;box-sizing:border-box;position:relative;z-index:1;
  background:var(--indigo-tint);color:var(--indigo);
  transition:background .18s,color .18s,box-shadow .18s,transform .18s;
}
.wtab:hover svg{transform:translateY(-1px)}
/* the connector rail between one badge and the next */
.wtab:not(:last-child)::before{content:"";position:absolute;top:26px;left:calc(50% + 24px);right:calc(-50% + 24px);height:2px;background:var(--line);z-index:0}
.wtab[aria-current="step"]{color:var(--indigo-deep);font-weight:800}
.wtab[aria-current="step"] svg{background:var(--indigo);color:#fff;box-shadow:0 6px 14px -3px rgba(40,169,158,.5)}
.wtab.done{color:var(--verified-ink)}
.wtab.done svg{background:var(--verified-tint);color:var(--verified)}
.wtab.done:not(:last-child)::before{background:var(--verified)}

.wfoot{display:flex;gap:12px;justify-content:space-between;margin-top:16px}
.wfoot .right{margin-left:auto}

/* ============================================================ GALLERY */
.gempty{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;
  padding:38px 20px;border:1.5px dashed #B9C1DA;border-radius:var(--r-md);background:#FAFBFE;
}
.gempty .gi{width:88px;height:76px;border-radius:12px;background:var(--indigo);position:relative;display:grid;place-items:center;color:#fff}
.gempty .gi::after{content:"";position:absolute;right:-10px;bottom:-8px;width:70px;height:60px;border-radius:12px;background:var(--indigo-deep);z-index:-1}
.gempty b{color:var(--indigo-deep);font-size:15px;font-weight:700}
.gempty small{color:var(--muted);font-size:12.5px}
.gthumbs{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:12px;margin-top:14px}
.gthumb{position:relative;aspect-ratio:4/3;border-radius:var(--r-md);overflow:hidden;
  background:repeating-linear-gradient(45deg,#7C86AE 0 14px,#8F98BC 14px 28px)}
.gthumb button{position:absolute;top:6px;right:6px;width:26px;height:26px;border-radius:50%;background:rgba(16,23,51,.78);color:#fff;display:grid;place-items:center}
.gthumb-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.gthumb span{position:absolute;left:0;right:0;bottom:0;padding:6px 8px;font-size:11px;color:#fff;background:linear-gradient(transparent,rgba(16,23,51,.88))}

/* ============================================================ FLOOR LEDGER */
.ledger{border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden}
.lrow{display:grid;grid-template-columns:118px 1fr 1fr 96px 40px;gap:12px;align-items:center;padding:12px 14px;border-bottom:1px solid var(--line-soft);font-size:13.5px}
.lrow:last-child{border-bottom:none}
.lrow.head{background:var(--paper);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-weight:700}
.lrow .fl{font-family:var(--f-display);font-weight:700}
.lrow .area{font-family:var(--f-data);text-align:right}
.lrow .del{width:32px;height:32px;border-radius:8px;display:grid;place-items:center;color:var(--muted)}
.lrow .del:hover{background:var(--alert-tint);color:var(--alert)}
.ltot{display:flex;align-items:center;gap:10px;padding:12px 14px;background:var(--indigo-tint);font-size:13.5px;font-weight:700;color:var(--indigo-deep)}
.ltot .n{margin-left:auto;font-family:var(--f-data);font-size:16px}

/* ============================================================ MAP (schematic) */
.mfilters{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:14px;align-items:stretch}
.mfilters .field{flex:1;min-width:180px}
.mfilters .btn{height:var(--tap)}
.mempty{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow-1);
  min-height:min(58dvh,440px);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;padding:40px 20px;text-align:center;
}
.mempty .pin{width:96px;height:96px;border-radius:20px;background:var(--indigo-tint);display:grid;place-items:center;color:var(--indigo)}
.mempty b{font-size:15.5px;color:var(--muted);font-weight:600}
.mapwrap{position:relative;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line);background:#DDE3EE;height:min(70dvh,620px)}
/* DIRECT child only. As `.mapwrap svg` this stretched EVERY icon inside the map
   — the base-map button's 16px glyph filled the whole button and pushed its
   label out past the background, which read as "the icon and label are
   misaligned". Control icons must keep their own width/height attributes. */
.mapwrap > svg{width:100%;height:100%;display:block}
.parcel{cursor:pointer;transition:filter .15s}
.parcel:hover{filter:brightness(1.12)}
.mapbar{position:absolute;left:12px;right:12px;top:12px;display:flex;gap:8px;flex-wrap:wrap}
.legend{
  position:absolute;left:12px;bottom:12px;background:rgba(255,255,255,.96);border-radius:10px;
  padding:10px 12px;font-size:12px;display:grid;gap:6px;box-shadow:var(--shadow-1);color:var(--ink-2);
}
.legend div{display:flex;align-items:center;gap:8px}
.legend i{width:12px;height:12px;border-radius:3px;display:block}
/* Sits ABOVE MapLibre's zoom control, not on top of it. Both were pinned to
   bottom-right, and MapLibre's control group paints over an unstacked sibling,
   so the right half of this button was swallowed and did nothing when tapped.
   Raised clear of the zoom group and the attribution strip, with a z-index that
   actually puts it in front. */
.locate{
  position:absolute;right:12px;bottom:96px;width:54px;height:54px;border-radius:50%;
  background:var(--indigo);color:#fff;display:grid;place-items:center;
  box-shadow:var(--shadow-2);z-index:4;
}
.locate svg{width:24px;height:24px}


/* Footprint popup — the actions offered when a building is tapped. */
.maplibregl-popup-content{border-radius:14px;padding:14px;box-shadow:var(--shadow-2)}
/* MapLibre's default close button is ~18px in the very corner — unhittable with
   a thumb, which is the only pointer this app ever gets. Given a real 38px tap
   target, and the header padded so the title never runs under it. */
.maplibregl-popup-close-button{
  width:38px;height:38px;top:3px;right:3px;border-radius:9px;
  font-size:21px;line-height:1;color:var(--muted);background:transparent;
  display:grid;place-items:center}
.maplibregl-popup-close-button:hover{background:var(--paper);color:var(--ink)}
.fp-pop{min-width:200px;font-family:var(--f-body)}
.fp-pop .fp-id{font-family:var(--f-data);font-weight:700;font-size:13px;
  color:var(--indigo-deep);word-break:break-all;padding-right:34px}
.fp-pop .fp-sub{font-size:11.5px;color:var(--muted);margin:3px 0 9px}
/* 40px tall — comfortably tappable with a thumb without dominating the map. */
.fp-btn{display:flex;align-items:center;justify-content:center;gap:7px;width:100%;
  min-height:40px;padding:0 12px;border-radius:9px;font-size:13px;
  font-weight:700;line-height:1;margin-top:7px}
/* Icons carry an EXPLICIT size. Without this the `.mapwrap svg{width:100%}`
   rule (the map's own placeholder graphic) inflates every icon inside the map
   to fill its button — which is what turned these into giant glyphs. */
.fp-btn svg{width:15px;height:15px;flex:none}
.fp-btn.fp-go{background:var(--indigo);color:#fff;box-shadow:0 2px 0 var(--indigo-deep)}
.fp-btn.fp-go:hover{filter:brightness(1.06)}

/* Base map control — a chip in the map's top bar.
   flex:none is load-bearing: .mapbar is a flex row, so without it the button
   shrinks below its own content and the nowrap label spills OUT of its
   background — the icon sits in the pill and the words float beside it. The
   long scope chip is the one allowed to shrink (and ellipsis) instead. */
.mapctl{display:inline-flex;align-items:center;gap:7px;flex:none;height:32px;
  padding:0 13px;border-radius:8px;
  background:rgba(255,255,255,.96);color:var(--indigo-deep);box-shadow:var(--shadow-1);
  font-size:12px;font-weight:600;line-height:1;white-space:nowrap}
.mapctl svg{flex:none;display:block;width:16px;height:16px}
.mapctl.on{background:var(--indigo);color:#fff}
.mapctl:hover{filter:brightness(.98)}
.mapbar .chip{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ============================================================ DASHBOARD */
.tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.tile{
  position:relative;background:var(--ink);color:#fff;border-radius:var(--r-lg);
  padding:18px 16px 15px;text-align:left;overflow:hidden;transition:transform .14s,box-shadow .16s;
  border:2px solid transparent;
}
.tile:hover{transform:translateY(-2px);box-shadow:var(--shadow-2)}
.tile .ti{width:34px;height:34px;border-radius:9px;display:grid;place-items:center;background:rgba(255,255,255,.14);margin-bottom:12px}
.tile b{display:block;font-family:var(--f-display);font-size:15px;font-weight:700;letter-spacing:-.01em}
.tile span{font-size:11.5px;color:rgba(255,255,255,.62);display:block;margin-top:2px}
.tile[aria-pressed="true"]{border-color:var(--verified)}
.tile[aria-pressed="true"] b{color:#93C5FD}
.tile .on-mark{position:absolute;top:12px;right:12px;width:20px;height:20px;border-radius:50%;background:var(--verified);display:none;place-items:center;color:#fff;font-size:11px}
.tile[aria-pressed="true"] .on-mark{display:grid}

/* Work-type toggle (Property Tax / WSS & UGSS / UGSS Tax) — mirrors the
   reference app's dashboard tabs. A segmented pill; the selected tab is a
   raised white chip. */
.wt-toggle{display:flex;gap:5px;background:var(--indigo-tint);border:1px solid var(--line-soft);border-radius:13px;padding:5px;margin-bottom:16px}
.wt-tab{flex:1;min-width:0;height:40px;border-radius:9px;font-weight:700;font-size:13px;letter-spacing:-.01em;color:var(--muted);white-space:nowrap;transition:background .15s,color .15s,box-shadow .15s}
.wt-tab[aria-selected="true"]{background:#fff;color:var(--indigo-deep);box-shadow:var(--shadow-1)}
.wt-tab:not([aria-selected="true"]):hover{color:var(--indigo-deep)}

.ways{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.way{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:26px 18px 20px;
  text-align:center;box-shadow:var(--shadow-1);transition:border-color .15s,transform .14s;
}
.way:hover{border-color:var(--indigo);transform:translateY(-2px)}
.way .wi{width:76px;height:76px;margin:0 auto 14px;border-radius:18px;display:grid;place-items:center;background:var(--indigo-tint);color:var(--indigo)}
.way b{font-family:var(--f-display);font-size:15.5px;font-weight:700;color:var(--indigo-deep)}
.way p{font-size:12.5px;color:var(--muted);margin-top:4px}

.counts{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.count{border-radius:var(--r-lg);padding:18px;color:#fff;box-shadow:var(--shadow-1)}
.count .n{font-family:var(--f-display);font-size:34px;font-weight:700;line-height:1}
.count .l{font-size:13px;opacity:.9;margin-top:5px}
.count.total{background:var(--indigo)}
/* Darker than the marker green: white body text on #0E8A5F measured 4.36:1,
   just under AA. This tile carries a label as well as the big number. */
.count.today{background:#0b7350}

/* ============================================================ TABLES + LIST */
.tbl{width:100%;border-collapse:collapse;font-size:13.5px}
.tbl th{text-align:left;font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);padding:10px 14px;border-bottom:1px solid var(--line);background:var(--paper);font-weight:700}
.tbl td{padding:12px 14px;border-bottom:1px solid var(--line-soft)}
.tbl tr:hover td{background:#FAFBFE}
.tbl .id{font-family:var(--f-data);font-weight:600}

.reclist{display:none;gap:10px;grid-template-columns:minmax(0,1fr)}
.rec{min-width:0;background:#fff;border:1px solid var(--line);border-radius:var(--r-md);padding:13px 14px;box-shadow:var(--shadow-1)}
.rec-m span{min-width:0;overflow-wrap:anywhere}
.rec-t{display:flex;align-items:center;gap:10px}
.rec-id{font-family:var(--f-data);font-weight:600;font-size:14px}
.rec-n{font-size:14px;font-weight:500;margin-top:3px}
.rec-m{font-size:12px;color:var(--muted);margin-top:4px;display:flex;gap:12px;flex-wrap:wrap}

/* Property / All Tax pager */
.ptpager{display:flex;align-items:center;justify-content:center;gap:16px;padding:14px;border-top:1px solid var(--line-soft);flex-wrap:wrap}
.ptpager .btn{height:38px;flex:none}
.ptpager .ptpage{font-size:12.5px;color:var(--muted);font-weight:600;min-width:0;text-align:center}
.tbl td .pt-num{font-family:var(--f-data)}

/* the honest-submission notice, in the app's voice */
.attest{
  margin-top:16px;padding:14px 16px;border-radius:var(--r-md);
  background:var(--hivis-tint);border:1px solid #F3D89A;color:var(--hivis-ink);
  font-size:12.5px;line-height:1.55;
}
.attest strong{color:#6d4705}

/* ============================================================ MOBILE CHROME */
.tabbar{display:none}
.actionbar{display:none}
.scrim{position:fixed;inset:0;background:rgba(16,23,51,.5);z-index:70;opacity:0;pointer-events:none;transition:opacity .2s}
.scrim.on{opacity:1;pointer-events:auto}

.sheet{
  position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);width:min(420px,92vw);
  background:#fff;border-radius:var(--r-lg);z-index:80;box-shadow:var(--shadow-2);
  display:none;overflow:hidden;
}
.sheet.on{display:block}
.sheet-h{padding:16px 18px;border-bottom:1px solid var(--line-soft);font-family:var(--f-display);font-weight:700;color:var(--indigo-deep)}
.sheet-l{max-height:min(58dvh,420px);overflow-y:auto;padding:6px}
.opt{width:100%;display:flex;align-items:center;gap:12px;padding:13px 12px;border-radius:9px;font-size:15px;text-align:left}
.opt:hover{background:var(--paper)}
.opt .rd{width:20px;height:20px;flex:0 0 20px;border-radius:50%;border:2px solid #B6BDD6}
.opt[aria-selected="true"]{background:var(--indigo-tint);font-weight:600;color:var(--indigo-deep)}
.opt[aria-selected="true"] .rd{border-color:var(--indigo);box-shadow:inset 0 0 0 4px var(--indigo)}
.sheet-f{padding:12px 14px;border-top:1px solid var(--line-soft);display:flex;gap:22px;justify-content:flex-end}
.sheet-f button{background:none;color:var(--indigo);font-weight:700;font-size:14px;letter-spacing:.08em;text-transform:uppercase;height:auto;padding:6px 2px}
.sheet-f button:hover{color:var(--indigo-deep);text-decoration:underline}
.plainlist .opt .rd{display:none}
.plain-title{padding:18px 20px 6px;color:var(--muted);font-size:14px}

.toast{
  position:fixed;left:50%;bottom:96px;transform:translate(-50%,20px);z-index:90;
  background:var(--ink);color:#fff;padding:12px 18px;border-radius:10px;font-size:14px;
  opacity:0;pointer-events:none;transition:all .25s;box-shadow:var(--shadow-2);max-width:min(440px,92vw);
}
.toast.on{opacity:1;transform:translate(-50%,0)}

/* ============================================================ RESPONSIVE */
@media (max-width:880px){
  body{font-size:16px}
  .rail{
    /* z-index:80 is the FIX for "can't use the menu": the scrim is z-index 70,
       and the drawer's base z-index was 60 — so an open drawer sat BEHIND the
       scrim and every tap on a nav item hit the scrim (which closes the drawer)
       instead of the item. The interactive drawer must sit ABOVE its own scrim,
       like the bottom sheet (also z-index 80) does. */
    position:fixed;left:0;top:0;height:100dvh;transform:translateX(-100%);z-index:80;
    transition:transform .24s cubic-bezier(.4,0,.2,1);width:288px;flex-basis:288px;
  }
  .rail.on{transform:none}
  .hamburger{display:flex}
  .topbar.sub .hamburger{display:none}
  .topbar{padding:8px 12px;gap:8px;min-height:56px}
  .crumb{font-size:16px}
  .scope{margin-left:auto;gap:6px}
  .sample-flag span.txt{display:none}
  .sync span.txt{display:none}
  .viewport{padding:12px 12px 150px}
  .g2,.g3{grid-template-columns:1fr}
  .span2{grid-column:auto}

  .wtab{font-size:11px;padding:10px 2px;gap:4px}

  .lrow{grid-template-columns:1fr auto;gap:6px 12px;padding:14px}
  .lrow.head{display:none}
  .lrow .fl{grid-column:1;font-size:15px}
  .lrow .del{grid-row:1;grid-column:2}
  .lrow .use,.lrow .con{grid-column:1;font-size:13px;color:var(--muted)}
  .lrow .area{grid-column:2;text-align:right;font-size:14px}

  .tbl{display:none}
  .reclist{display:grid}
  /* Pager on a phone: page text on its own centred line, Prev + Next side by
     side below it (instead of Next orphaning to a second row). */
  .ptpager .ptpage{flex-basis:100%;order:-1;margin-bottom:2px}

  .tabbar{
    display:flex;position:fixed;left:0;right:0;bottom:0;z-index:60;
    background:rgba(255,255,255,.97);backdrop-filter:blur(12px);
    border-top:1px solid var(--line);padding:6px 4px calc(6px + env(safe-area-inset-bottom));
  }
  .tab{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;padding:7px 2px;border-radius:10px;font-size:10.5px;color:var(--muted);font-weight:600}
  .tab[aria-current="page"]{color:var(--indigo)}
  .tab[aria-current="page"] .ic{background:var(--indigo-tint)}
  .ic{width:44px;height:26px;border-radius:20px;display:grid;place-items:center;transition:background .15s}
  .tab-add .ic{background:var(--indigo);color:#fff;width:52px;height:34px;margin-top:-14px;box-shadow:var(--shadow-2)}
  .tab-add[aria-current="page"] .ic{background:var(--indigo-deep)}

  /* Wizard Back/Next. Sized DOWN from --tap (52px): stacked on top of the 62px
     tab bar it was 135px of permanent chrome on an 852px phone — a sixth of the
     screen spent on two buttons, taken from the form the surveyor is filling in.
     44px is still the recommended minimum tap target, so nothing gets harder to
     hit; the bar just stops shouting. */
  .actionbar{
    display:flex;gap:10px;position:fixed;left:0;right:0;bottom:calc(62px + env(safe-area-inset-bottom));
    z-index:55;padding:9px 12px 11px;background:rgba(255,255,255,.98);backdrop-filter:blur(12px);
    border-top:1px solid var(--line);box-shadow:0 -6px 18px rgba(16,23,51,.07);
  }
  /* Bigger, bolder, clearly-separated Back/Next — easy one-handed taps at the
     doorstep. Back is a distinct outlined button (not a faint ghost); Next is
     the prominent primary action. */
  /* Back and Next are EQUAL width (50/50) — same-size buttons. */
  .actionbar .btn{flex:1 1 0;height:50px;font-size:15.5px;font-weight:700;border-radius:13px}
  .actionbar .btn-back{border:1.5px solid var(--line);color:var(--ink-2)}
  .desk-actions{display:none}

  .tiles{grid-template-columns:1fr 1fr 1fr;gap:8px}
  .tile{padding:12px 10px}
  .tile .ti{width:28px;height:28px;margin-bottom:8px}
  .tile b{font-size:12.5px}
  .tile span{display:none}
  .ways{grid-template-columns:1fr 1fr;gap:10px}
  .way{padding:18px 10px 14px}
  .way .wi{width:56px;height:56px;border-radius:14px;margin-bottom:10px}
  .way b{font-size:13.5px}
  .way p{display:none}
  .counts{grid-template-columns:1fr 1fr}
  /* City and Ward SIDE BY SIDE with the button on its own row. Forcing each
     field to 100% stacked them into three rows of chrome above the map, which
     on a phone left the map a letterbox and pushed the button off-screen. */
  .mfilters{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:10px}
  .mfilters .field{min-width:0;flex:none}
  .mfilters .btn{grid-column:1/-1;width:100%}

  .sheet{
    left:0;right:0;bottom:0;top:auto;transform:translateY(100%);width:100%;
    border-radius:20px 20px 0 0;transition:transform .26s cubic-bezier(.4,0,.2,1);display:block;
    padding-bottom:env(safe-area-inset-bottom);
  }
  .sheet.on{transform:none}
  .sheet-h{padding-top:20px;position:relative}
  .sheet-h::before{content:"";position:absolute;top:8px;left:50%;transform:translateX(-50%);width:40px;height:4px;border-radius:4px;background:var(--line)}
  .sheet-l{max-height:52dvh}
  .opt{padding:15px 12px}
  /* ---- the map screen on a phone -------------------------------------
     A surveyor standing at a door needs MAP, not furniture. The filter row
     above was slimmed, so the map gets that height back; every overlay is
     shrunk and pulled to the corners, and the tap targets stay >=44px. */
  .mapwrap{height:calc(100dvh - 208px);min-height:420px}

  .mapbar{left:8px;right:8px;top:8px;gap:6px}
  /* The scope chip truncates instead of pushing Base map onto its own row. */
  .mapbar .chip{max-width:56%;height:28px;font-size:11px;padding:0 9px}
  .mapctl{height:28px;padding:0 10px;font-size:11px;gap:5px}
  .mapctl svg{width:14px;height:14px}

  /* The legend was covering a quarter of the map. Compact, and out of the way
     of the zoom control and the locate button. */
  .legend{left:8px;bottom:8px;padding:7px 9px;font-size:11px;gap:5px;border-radius:9px}
  .legend i{width:10px;height:10px}

  /* Pinch-to-zoom is how a phone zooms, so MapLibre's +/- group is redundant
     here — and it sat in the same corner as the locate button, swallowing taps
     on it. Hidden on touch layouts; the ATTRIBUTION control stays, because OSM
     requires it. Locate then owns the corner, clear of the attribution strip. */
  .maplibregl-ctrl-bottom-right .maplibregl-ctrl-group{display:none}
  .locate{width:48px;height:48px;right:8px;bottom:44px}
  .locate svg{width:22px;height:22px}

  /* Footprint popup: never wider than the phone. */
  .maplibregl-popup{max-width:calc(100vw - 32px)!important}
  .fp-pop{min-width:0}
}
@media (min-width:881px){.m-only{display:none!important}}
@media (max-width:880px){.d-only{display:none!important}}

/* ===========================================================================
 * WRONG-DOOR NOTICE — a signed-in OFFICE account that opened the field app.
 * Not an error state: the account is valid, it simply belongs on the officer
 * console. Full-screen, calm, one clear way onward. See showFieldDenied().
 * ======================================================================== */
.field-denied{
  position:fixed; inset:0; display:grid; place-items:center;
  padding:24px; background:var(--paper); z-index:9999;
}
.field-denied .fd-card{
  width:min(440px,100%); background:var(--card); border:1px solid var(--line);
  border-radius:var(--r-lg); padding:32px 28px; text-align:center;
  box-shadow:0 10px 30px rgba(23,53,123,.10);
}
.field-denied .fd-mark{
  width:60px; height:60px; margin:0 auto 14px; border-radius:14px;
  display:grid; place-items:center; font-size:30px; line-height:1;
  color:var(--indigo-deep); background:var(--indigo-tint);
}
.field-denied .fd-title{
  margin:0 0 10px; font:600 20px/1.2 var(--f-display); color:var(--indigo-deep);
}
.field-denied .fd-body{
  margin:0 0 20px; font:15px/1.55 var(--f-body); color:var(--ink-2);
}
.field-denied .fd-btn{
  display:block; width:100%; margin:10px 0 0; padding:13px 16px;
  border-radius:var(--r-md); border:1px solid transparent; cursor:pointer;
  font:600 15px/1 var(--f-display); text-decoration:none;
  background:var(--indigo); color:#fff; box-sizing:border-box;
}
.field-denied .fd-btn.ghost{
  background:transparent; color:var(--indigo-deep); border-color:var(--line);
}
.field-denied .fd-hint{
  margin:14px 0 0; font:14px/1.5 var(--f-body); color:var(--muted);
}

/* ===========================================================================
 * ADMINISTRATION — surveyor progress chips, progress table, review queue.
 * Admins-only screen (see applyAdminUi / #s-admin). Visible at every width, so
 * it does NOT reuse .reclist (which is mobile-only cards).
 * ======================================================================== */
.adm-stats{
  display:flex; flex-wrap:wrap; gap:10px; margin:0 0 16px;
}
.adm-chip{
  flex:1 1 92px; min-width:92px; padding:12px 14px; border-radius:var(--r-md);
  background:var(--indigo-tint); border:1px solid var(--line-soft);
  display:flex; flex-direction:column; gap:2px;
}
.adm-chip .ac-n{ font:700 22px/1 var(--f-data); color:var(--indigo-deep); }
.adm-chip .ac-l{ font:600 11px/1 var(--f-display); letter-spacing:.04em;
  text-transform:uppercase; color:var(--muted); }

.rev-list{ display:grid; gap:10px; padding:12px; }
.rev-item{
  display:flex; align-items:center; gap:12px; padding:12px 14px;
  border:1px solid var(--line); border-radius:var(--r-md); background:var(--card);
}
.rev-item .rev-main{ flex:1 1 auto; min-width:0; }
.rev-item .rev-top{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.rev-item .rev-door{ font:600 15px/1.2 var(--f-display); color:var(--ink); }
.rev-item .rev-sub{ margin-top:4px; font:13px/1.4 var(--f-body); color:var(--muted); }
.rev-item .rev-act{ display:flex; gap:8px; flex:0 0 auto; }

.btn-sm{ padding:8px 12px; font-size:13px; border-radius:var(--r-sm); }
.btn-approve{ background:var(--verified); color:#fff; border:1px solid transparent; }
.btn-approve:hover{ background:var(--verified-ink); }
.btn-reject{ background:#fff; color:var(--alert); border:1px solid var(--line); }
.btn-reject:hover{ border-color:var(--alert); background:var(--alert-tint); }

@media (max-width:540px){
  .rev-item{ flex-direction:column; align-items:stretch; }
  .rev-item .rev-act{ justify-content:flex-end; }
}

/* Live-refresh indicator on the admin panel (pulsing green "Live"). */
.adm-live{
  display:inline-flex; align-items:center; gap:6px; margin-left:auto;
  font:700 11px/1 var(--f-display); letter-spacing:.04em; text-transform:uppercase;
  color:var(--verified-ink); background:var(--verified-tint);
  padding:5px 10px; border-radius:20px;
}
.adm-live .alv-dot{
  width:7px; height:7px; border-radius:50%; background:var(--verified);
  box-shadow:0 0 0 0 rgba(14,138,95,.5); animation:alvpulse 1.8s ease-out infinite;
}
@keyframes alvpulse{
  0%{box-shadow:0 0 0 0 rgba(14,138,95,.5)}
  70%{box-shadow:0 0 0 7px rgba(14,138,95,0)}
  100%{box-shadow:0 0 0 0 rgba(14,138,95,0)}
}
/* When the Live pill is present, don't let the Refresh button also grab the
   auto margin — the pill owns the right-alignment. */
.adm-live + #admRefresh{ margin-left:10px; }

/* ===== Survey dashboard: ward coverage + review-status breakdown ===== */
.adm-cover{ display:grid; gap:16px; margin:4px 0 18px; }
@media (min-width:760px){ .adm-cover{ grid-template-columns:1fr 1fr; } }
.cov-block{ }
.cov-head{ display:flex; justify-content:space-between; align-items:baseline; gap:10px;
  font:700 12px/1 var(--f-display); letter-spacing:.03em; text-transform:uppercase;
  color:var(--muted); margin-bottom:8px; }
.cov-head .cov-fig{ text-transform:none; letter-spacing:0; font-weight:700;
  font-family:var(--f-data); color:var(--indigo-deep); }
.cov-bar{ height:12px; border-radius:8px; background:var(--indigo-tint); overflow:hidden; }
.cov-bar > span{ display:block; height:100%; border-radius:8px;
  background:linear-gradient(90deg,#2A50D8,#93C5FD); min-width:3px; transition:width .4s ease; }
.stat-bar{ display:flex; height:12px; border-radius:8px; overflow:hidden; background:var(--line-soft); }
.stat-bar .sb{ height:100%; }
.stat-bar .sb-appr{ background:var(--verified); }
.stat-bar .sb-pend{ background:var(--hivis); }
.stat-bar .sb-rej{ background:var(--alert); }
.stat-leg{ display:flex; flex-wrap:wrap; gap:14px; margin-top:9px;
  font:600 12px/1 var(--f-body); color:var(--ink-2); }
.stat-leg i{ display:inline-block; width:10px; height:10px; border-radius:3px; margin-right:6px; vertical-align:middle; }
.stat-leg .lg-appr{ background:var(--verified); }
.stat-leg .lg-pend{ background:var(--hivis); }
.stat-leg .lg-rej{ background:var(--alert); }

/* ===== Live camera (#3): full-screen in-app capture, geo-stamped ===== */
.cam-modal{ position:fixed; inset:0; z-index:2000; background:#000; }
.cam-video{ width:100%; height:100%; object-fit:cover; background:#000; }
.cam-geo{
  position:absolute; top:14px; left:14px; right:14px;
  background:rgba(0,0,0,.5); color:#fff; font:600 13px/1.3 var(--f-data);
  padding:8px 12px; border-radius:10px; text-align:center; pointer-events:none;
}
.cam-bar{
  position:absolute; bottom:0; left:0; right:0; height:130px;
  display:flex; align-items:center; justify-content:center;
  background:linear-gradient(0deg, rgba(0,0,0,.65), transparent);
}
.cam-x{
  position:absolute; left:22px; bottom:52px; width:46px; height:46px; border-radius:50%;
  background:rgba(255,255,255,.16); color:#fff; font-size:20px; display:grid; place-items:center;
}
.cam-x:hover{ background:rgba(255,255,255,.3); }
.cam-shutter{
  width:76px; height:76px; border-radius:50%; background:transparent;
  border:4px solid #fff; display:grid; place-items:center; cursor:pointer;
}
.cam-shutter span{ width:60px; height:60px; border-radius:50%; background:#fff; transition:transform .1s; }
.cam-shutter:active span{ transform:scale(.86); }
.cam-note{
  position:absolute; right:20px; bottom:58px; color:#fff; font:700 12px/1 var(--f-display);
  background:rgba(40,169,158,.9); padding:7px 11px; border-radius:20px;
}

/* ============================================================ DETAIL OVERLAY
   Shared read-only detail for Added Projects + UGSS Work (filled by JS). */
.dt-modal{position:fixed;inset:0;z-index:1500;background:rgba(16,23,51,.5);display:flex;align-items:flex-end;justify-content:center}
.dt-card{background:var(--card);width:100%;max-width:560px;max-height:88dvh;border-radius:18px 18px 0 0;display:flex;flex-direction:column;box-shadow:var(--shadow-2);animation:dtUp .24s cubic-bezier(.4,0,.2,1)}
@keyframes dtUp{from{transform:translateY(24px);opacity:.6}to{transform:none;opacity:1}}
@media(min-width:640px){.dt-modal{align-items:center}.dt-card{border-radius:16px}}
.dt-head{display:flex;align-items:center;gap:12px;padding:15px 18px;border-bottom:1px solid var(--line-soft);cursor:grab;user-select:none;touch-action:none}
.dt-head:active{cursor:grabbing}
/* Float mode (Property Information on the map): no blocking scrim — the map
   stays visible AND interactive — and the card is a draggable panel top-right. */
.dt-modal.dt-float{background:transparent;pointer-events:none}
.dt-modal.dt-float .dt-card{pointer-events:auto;position:absolute;top:16px;right:16px;left:auto;bottom:auto;margin:0;width:min(380px,92vw);max-height:calc(100dvh - 32px);border-radius:16px}
.dt-head h3{font-family:var(--f-display);font-size:16px;color:var(--indigo-deep);margin:0}
.dt-x{margin-left:auto;width:34px;height:34px;border-radius:8px;color:var(--muted);font-size:16px;display:grid;place-items:center}
.dt-x:hover{background:var(--paper);color:var(--ink)}
.dt-body{padding:14px 18px 22px;overflow-y:auto}
.dt-row{display:flex;justify-content:space-between;gap:16px;padding:8px 0;border-bottom:1px dashed var(--line-soft);font-size:13.5px}
.dt-row .k{color:var(--muted);flex:none}
.dt-row .v{font-weight:600;text-align:right;overflow-wrap:anywhere}
.dt-sec{font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--faint);margin:16px 0 4px}

/* ============================================================ UGSS CONTROLS */
.ugseg{display:flex;gap:6px;background:var(--indigo-tint);border:1px solid var(--line-soft);border-radius:11px;padding:5px}
.ugseg label{flex:1;min-width:0;min-height:44px;display:flex;align-items:center;justify-content:center;gap:6px;border-radius:8px;font-weight:700;font-size:13px;color:var(--ink-2);cursor:pointer;text-align:center;transition:background .15s,color .15s,box-shadow .15s}
.ugseg input{position:absolute;opacity:0;pointer-events:none}
.ugseg label:has(input:checked){background:#fff;color:var(--indigo-deep);box-shadow:var(--shadow-1)}
.ugseg5 label{font-family:var(--f-data);font-size:15px}
.ck{display:flex;align-items:center;gap:10px;min-height:44px;font-size:14px;color:var(--ink-2);cursor:pointer}
.ck input{width:20px;height:20px;accent-color:var(--indigo);flex:none}

/* Footprint popup — MIS/owner block shown under the GIS ID on tap */
.fp-mis{margin-top:7px;padding-top:7px;border-top:1px dashed var(--line)}
.fp-mis-o{font-weight:700;font-size:13px;color:var(--ink);overflow-wrap:anywhere}
.fp-mis-r{font-size:11px;color:var(--muted);margin-top:2px}

/* ============================================================ TRACE TOOLBAR
   Draw a missed building's outline on the map. */
.trace-bar{position:absolute;left:12px;right:12px;bottom:12px;z-index:40;
  background:rgba(255,255,255,.98);backdrop-filter:blur(10px);border:1px solid var(--line);
  border-radius:14px;box-shadow:var(--shadow-2);padding:10px 12px;display:flex;flex-direction:column;gap:9px}
.trace-hint{font-size:12.5px;font-weight:700;color:var(--indigo-deep);text-align:center}
.trace-acts{display:flex;gap:8px}
.trace-acts .btn{flex:1 1 0;height:46px;font-size:14px;font-weight:700;border-radius:11px}

/* ============================================================ ADMIN PANELS
   14-day trend · usage mix · live activity feed. */
.trend{display:flex;align-items:flex-end;gap:5px;height:120px;padding:6px 2px}
.tr-bar{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:3px;min-width:0;height:100%}
.tr-bar>span{width:100%;max-width:22px;border-radius:4px 4px 0 0;background:linear-gradient(180deg,#5B8DEF,#2A50D8)}
.tr-bar em{font-size:10px;font-style:normal;color:var(--muted);font-weight:700}
.tr-bar b{font-size:9px;font-weight:600;color:var(--faint)}
.usage-bars{display:flex;flex-direction:column;gap:8px;padding:4px 2px}
.ub-row{display:flex;align-items:center;gap:10px;font-size:12.5px}
.ub-l{flex:0 0 34%;color:var(--ink-2);font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ub-bar{flex:1;height:10px;background:var(--line-soft);border-radius:6px;overflow:hidden}
.ub-bar>span{display:block;height:100%;border-radius:6px;background:linear-gradient(90deg,#2A50D8,#5B8DEF)}
.ub-n{flex:none;color:var(--muted)}
.feed{display:flex;flex-direction:column;gap:0}
.fd-item{display:flex;align-items:center;gap:9px;padding:8px 4px;border-bottom:1px solid var(--line-soft);font-size:12.5px}
.fd-item:last-child{border-bottom:none}
.fd-dot{width:8px;height:8px;border-radius:50%;flex:none;background:var(--muted)}
.fd-pending{background:#F2C037}.fd-approved{background:#2E9E5B}.fd-rejected{background:#E24A3B}
.fd-main{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600;color:var(--ink)}
.fd-by{color:var(--muted);font-weight:400}
.fd-when{flex:none;color:var(--faint);font-size:11px}


/* ============ ADMIN PHASE 2 ============ */
/* PHASE 2 — review queue: per-row select, bulk bar, and detail-modal extras. */
.rev-item .rev-check{ display:flex; align-items:center; flex:0 0 auto; }
.rev-item .rev-check input{ width:16px; height:16px; accent-color:var(--verified); }
.rev-item .rev-main[role=button]{ cursor:pointer; }
.rev-bulk{ display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  margin:2px 12px 12px; padding:10px 12px; border:1px solid var(--line);
  border-radius:var(--r-md); background:var(--paper); }
.rev-bulk[hidden]{ display:none; }
.rev-bulk .rev-bulk-all{ display:flex; align-items:center; gap:6px; font-size:13px; color:var(--ink-2); }
.rev-bulk .rev-bulk-all input{ width:16px; height:16px; accent-color:var(--verified); }
.rev-bulk .rev-bulk-n{ font-size:13px; color:var(--muted); }
.rev-bulk .rev-bulk-act{ margin-left:auto; display:flex; gap:8px; }
.dt-photos{ display:flex; gap:8px; overflow-x:auto; padding-bottom:10px; margin-bottom:6px; }
.dt-photo{ flex:0 0 auto; display:block; border:1px solid var(--line); border-radius:10px; overflow:hidden; }
.dt-photo img{ width:96px; height:96px; object-fit:cover; display:block; background:var(--paper); }
.dt-actions{ display:flex; gap:8px; margin-top:16px; }
.dt-actions .btn{ flex:1; }

/* ============ ADMIN PHASE 3 ============ */
[{"insert_after": ".stat-leg .lg-rej{ background:var(--alert); }", "code": "\n/* ===== Work assignment & territory (survey.manage) ===== */\n.asg-form{ margin-bottom:14px; }\n.asg-list{ display:flex; flex-direction:column; }\n.asg-item{ display:flex; align-items:center; gap:14px;\n  padding:14px 16px; border-top:1px solid var(--line-soft); }\n.asg-item .asg-main{ flex:1 1 auto; min-width:0; }\n.asg-item .asg-top{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }\n.asg-item .asg-who{ font:600 15px/1.2 var(--f-display); color:var(--ink); }\n.asg-item .asg-sub{ margin-top:6px; font:13px/1.4 var(--f-body); color:var(--muted); }\n.asg-item .asg-act{ display:flex; gap:8px; flex:0 0 auto; }\n@media (max-width:560px){\n  .asg-item{ flex-direction:column; align-items:stretch; }\n  .asg-item .asg-act{ justify-content:flex-end; }\n}\n"}]

/* ============ ADMIN PHASE 4 ============ */

/* ===========================================================================
 * DATA QUALITY & FRAUD (QC) — survey.manage-gated panel in #s-admin.
 * Three sub-lists (missing data / duplicates / anomalies); every row is a
 * tappable link (data-detail) into the shared survey-detail modal.
 * ======================================================================== */
.qc-sec{ padding:4px 0 14px; border-top:1px solid var(--line-soft); }
.qc-sec:first-child{ border-top:0; padding-top:0; }
.qc-sech{ display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; margin:10px 0 10px; }
.qc-sech h4{ margin:0; font:700 14px/1.2 var(--f-display); color:var(--ink); }

.qc-list{ display:grid; gap:8px; }
.qc-item{
  display:flex; align-items:center; gap:12px; padding:10px 12px; cursor:pointer;
  border:1px solid var(--line); border-radius:var(--r-md); background:var(--card);
  width:100%; text-align:left;
}
.qc-item:hover{ border-color:var(--indigo-deep); background:var(--indigo-tint); }
.qc-item .qc-main{ flex:1 1 auto; min-width:0; }
.qc-item .qc-top{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.qc-item .qc-id{ font:600 14px/1.2 var(--f-data); color:var(--ink); }
.qc-item .qc-sub{ margin-top:4px; font:13px/1.4 var(--f-body); color:var(--muted); }
.qc-item .qc-go{ flex:0 0 auto; font:700 18px/1 var(--f-display); color:var(--muted); }

.qc-dups{ display:grid; gap:10px; }
.qc-group{
  padding:10px 12px; border:1px solid var(--line-soft); border-radius:var(--r-md);
  background:var(--indigo-tint); display:grid; gap:8px;
}
.qc-group .qc-ghead{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.qc-group .qc-gkey{ font:700 13px/1 var(--f-data); color:var(--indigo-deep); }
.qc-group .qc-gn{ margin-left:auto; font:600 12px/1 var(--f-display); color:var(--muted); }
.qc-group .qc-item{ background:var(--card); }

.qc-velocity{ margin:0 0 12px; }
.qc-velocity .tbl td.qc-hot{ color:#A82727; font-weight:700; background:var(--alert-tint); }


/* ============ ADMIN PHASE 5 ============ */

/* Phase 5 — Surveyors + Reports panels in #s-admin (field app). */
.usr-form{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px 14px;margin-bottom:14px}
.usr-form .usr-actions{grid-column:1/-1;display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.usr-act{display:flex;gap:6px;justify-content:flex-end;white-space:nowrap}
.rep-block{padding:14px 0;border-top:1px solid var(--line-soft)}
.rep-block:first-child{border-top:0;padding-top:2px}
.rep-block h4{margin:0;font-size:14px;color:var(--ink,inherit)}
.rep-head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:2px}
.rep-controls{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.rep-in{height:34px;padding:0 10px;border:1px solid var(--line);border-radius:9px;background:var(--card);color:inherit;font:inherit;max-width:180px}
.rep-in.rep-wide{flex:1 1 220px;min-width:200px;max-width:none}
@media (max-width:640px){.usr-form{grid-template-columns:1fr}}


/* ============ ADMIN PHASE 6 ============ */
/* ---- Phase 6: notifications bell (topbar) ---- */
.notif-bell{position:relative;margin-left:auto;width:38px;height:38px;border-radius:9px;
  display:inline-flex;align-items:center;justify-content:center;color:var(--ink-2);
  border:1px solid transparent;background:transparent;cursor:pointer;
  transition:background .15s,border-color .15s}
.notif-bell:hover{background:var(--paper);border-color:var(--line)}
.notif-count{position:absolute;top:2px;right:2px;min-width:16px;height:16px;padding:0 4px;
  border-radius:9px;background:var(--alert);color:#fff;font:700 10px/16px var(--f-data);
  text-align:center;box-shadow:0 0 0 2px var(--card)}

/* ---- Phase 6: admin two-up layout (also lays out the existing trend/usage pair) ---- */
.adm-grid{display:grid;gap:16px;grid-template-columns:1fr;margin-top:16px}
@media (min-width:900px){.adm-grid{grid-template-columns:1fr 1fr}}

/* ---- Phase 6: audit trail lists ---- */
.aud-sec{font:700 10.5px/1 var(--f-display);letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted);margin:14px 0 8px}
.aud-sec:first-child{margin-top:0}
.aud-list{display:flex;flex-direction:column;gap:0;max-height:320px;overflow-y:auto}
.aud-row{display:flex;align-items:center;gap:9px;padding:8px 2px;font-size:12.5px;
  border-bottom:1px solid var(--line-soft)}
.aud-row:last-child{border-bottom:none}
.aud-op{flex:none;font:700 10px/1 var(--f-data);letter-spacing:.03em;text-transform:uppercase;
  padding:3px 7px;border-radius:var(--r-sm);background:var(--indigo-tint);color:var(--indigo-deep)}
.aud-INSERT,.aud-allowed{background:var(--verified-tint);color:var(--verified-ink)}
.aud-UPDATE,.aud-masked{background:var(--hivis-tint);color:var(--hivis-ink)}
.aud-DELETE,.aud-denied,.aud-rate_limited{background:var(--alert-tint);color:#A82727}
.aud-main{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-weight:600;color:var(--ink)}
.aud-by{color:var(--muted);font-weight:400}
.aud-when{flex:none;color:var(--faint);font-size:11px}

/* ---- Phase 6: notification list (rendered in the shared #dtModal) ---- */
.ntf{padding:12px 2px;border-bottom:1px solid var(--line-soft)}
.ntf:last-child{border-bottom:none}
.ntf-b{font-size:14px;color:var(--ink);line-height:1.5}
.ntf-un .ntf-b{font-weight:600}
.ntf-m{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:6px;
  font-size:11.5px;color:var(--muted)}
.ntf-read{color:var(--verified-ink);font-weight:600}
.ntf-un{position:relative;padding-left:12px}
.ntf-un::before{content:"";position:absolute;left:0;top:15px;width:6px;height:6px;border-radius:50%;
  background:var(--indigo)}