/* The source of truth for every colour, size, and radius on the site. All three
   pages link this file; DESIGN.md holds the doctrine, this holds the values.

   --line is for decorative rules (header, footer, containers); --line-strong is for the
   boundary of anything you can type in or click, which WCAG 1.4.11 requires to hit 3:1.

   --paint is Denver's bike-lane paint (Pantone 802 C), checked against the real
   thing rather than converted on trust. It is deliberately NOT
   a theme token — it's a physical reference, identical in light and dark, and it only
   appears on the map where real paint would be. It measures 1.93:1 on white, so it can
   never carry text or take white text; the UI green below is the same hue darkened
   until it can. */
:root{--green:#007c00;--green-dark:#006300;--paint:#44d62c;--ink:#111827;--muted:#6b7280;--line:#e5e7eb;--line-strong:#858fa0;--bg:#fff;--ok-text:#006300;--err:#b3261e;--placeholder:#f3f4f6;--on-green:#fff}
*{box-sizing:border-box}
/* form and .grid declare a display, which otherwise beats the UA stylesheet's
   [hidden] rule and leaves hidden elements on screen. */
[hidden]{display:none!important}
body{margin:0;font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;color:var(--ink);background:var(--bg);line-height:1.55}
header{position:sticky;top:0;background:var(--bg);border-bottom:1px solid var(--line);z-index:1100}
.hwrap{max-width:720px;margin:0 auto;padding:12px 16px;display:flex;justify-content:space-between;align-items:center;gap:12px}
.brand{font-weight:700;color:var(--green);text-decoration:none;font-size:1.05rem}
.hnav{display:flex;gap:16px;align-items:center}
/* padding, not margin: WCAG 2.5.8 measures the target box, and the bare line box
   is 23.6px — just under the 24px minimum. */
.hlink{color:var(--ink);text-decoration:none;font-size:.95rem;padding:4px 0}
.hlink:hover{color:var(--green)}
.hlink[aria-current=page]{color:var(--green);font-weight:600}
main{max-width:720px;margin:0 auto;padding:0 16px 48px}
h1{font-size:1.8rem;line-height:1.2;font-weight:800;margin:28px 0 10px}
h2{font-size:1.3rem;font-weight:700;margin:36px 0 6px}
.muted{color:var(--muted);margin:0 0 16px}
.btn{display:inline-block;background:var(--green);color:var(--on-green);border:0;border-radius:8px;padding:12px 20px;font-size:1rem;font-weight:600;text-decoration:none;cursor:pointer;text-align:center}
.btn:hover{background:var(--green-dark)}
.btn:disabled{opacity:.6;cursor:wait}
@media (max-width:480px){.btn{display:block;width:100%}}
form{border:1px solid var(--line);border-radius:10px;padding:16px;display:flex;flex-direction:column;gap:14px}
label,.flabel{font-weight:600;font-size:.95rem;display:flex;flex-direction:column;gap:5px}
label em,.flabel em{font-style:normal;font-weight:400;font-size:.8rem;color:var(--muted)}
/* Labels that exist for screen readers only, where the visible affordance carries the meaning. */
.vh{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
input,textarea{width:100%;font:inherit;font-size:16px;padding:10px 12px;border:1px solid var(--line-strong);border-radius:8px;background:var(--bg);color:var(--ink)}
input:focus,textarea:focus{outline:2px solid var(--green);border-color:var(--green)}
/* The offset is load-bearing: on .btn the ring would sit on the green fill at
   1:1 contrast. Offsetting puts it on --bg, where it reads 5:1. */
a:focus-visible,button:focus-visible{outline:2px solid var(--green);outline-offset:2px}
::placeholder{color:var(--muted);opacity:1}
.btnrow{display:flex;gap:8px}
.pickbtn{flex:1;font:inherit;font-size:.95rem;background:var(--bg);color:var(--ink);border:1px solid var(--line-strong);border-radius:8px;padding:11px 10px;cursor:pointer}
.pickbtn:hover{border-color:var(--green);color:var(--green)}
/* A checkbox is the one control that reads across rather than down, and 24px keeps
   the target at the WCAG 2.5.8 minimum. */
.check{flex-direction:row;align-items:flex-start;gap:10px}
.check input{width:24px;height:24px;flex-shrink:0;padding:0;margin:0}
#gps-note{font-size:.85rem;font-weight:400;margin:0;min-height:1.2em}
#gps-note.ok{color:var(--ok-text)}
#preview img{max-width:100%;max-height:280px;border-radius:8px;border:1px solid var(--line)}
.searchrow{display:flex;gap:8px}
/* min-width:0 releases the flex floor — a flex item defaults to min-width:auto,
   which for an input is its ~200px min-content width and overflows at 320px. */
.searchrow input{flex:1;min-width:0}
.searchrow button{flex-shrink:0;background:var(--bg);color:var(--ink);border:1px solid var(--line-strong);border-radius:8px;padding:0 16px;font:inherit;font-size:.95rem;cursor:pointer}
.searchrow button:hover{border-color:var(--green);color:var(--green)}
#results{display:flex;flex-direction:column;gap:4px}
#results button{text-align:left;font:inherit;font-size:.95rem;background:var(--bg);border:1px solid var(--line-strong);border-radius:8px;padding:10px;cursor:pointer;color:var(--ink)}
#results button:hover{border-color:var(--green)}
/* max-height, not a media query: a phone in landscape is ~360px tall, where a
   fixed 300px map is the whole screen. Never binds on desktop. */
.map{height:300px;max-height:60dvh;border:1px solid var(--line);border-radius:10px;z-index:0}
#pin-label{font-size:.85rem;font-weight:400;margin:0;min-height:1.2em;color:var(--muted)}
#pin-label.ok{color:var(--ok-text);font-weight:600}
/* Every async status reserves its line, so text appearing under a thumb never
   shifts what's beneath it. */
.status{margin:0;font-weight:600;min-height:1.2em}
.status.ok{color:var(--ok-text)}
.status.err{color:var(--err)}
/* Focus lands here after a submit, so it needs a ring of its own. */
.status:focus-visible{outline:2px solid var(--green);outline-offset:2px}
#rmap,#smap{margin-bottom:14px}
/* Shape and symbols supplement the red/green map status colors. */
.status-pin{background:none;border:0}
.status-pin svg{display:block;width:30px;height:40px;overflow:visible}
.status-pin.dirty{color:var(--err)}
.status-pin.swept{color:var(--green)}
.status-pin .pin-body{fill:currentColor;stroke:var(--bg);stroke-width:2}
.status-pin text{fill:var(--bg);font:700 20px system-ui,sans-serif}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:14px}
.card{border:1px solid var(--line);border-radius:10px;overflow:hidden}
.card img{width:100%;aspect-ratio:4/3;object-fit:cover;display:block;background:var(--placeholder)}
/* The 1px gap shows --line through it: the same hairline rule the rest of the
   system draws. Left is before, right is after — the reading order does the work,
   and the alt text says it outright. */
.card .pair{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line)}
.card .pair a{display:block}
.card div{padding:10px 12px}
.card .loc{font-weight:600;margin:0 0 2px;font-size:.95rem}
.card .notes{margin:0 0 4px;color:var(--muted);font-size:.85rem}
.card .meta{margin:0;color:var(--muted);font-size:.78rem}
.card .meta a{color:var(--green)}
/* Totals are a ruled list at body size: no card, no icon, no bar, nothing bigger
   than the text around it. The numbers are the evidence; making them loud is the
   tell that they aren't. */
.totals{margin:0 0 8px;padding:0;border-top:1px solid var(--line)}
.totals>div{display:flex;justify-content:space-between;align-items:baseline;gap:16px;padding:8px 0;border-bottom:1px solid var(--line)}
.totals dt{margin:0}
.totals dd{margin:0;font-weight:700;font-variant-numeric:tabular-nums;text-align:right}
.popup{font-family:inherit;max-width:180px}
.popup img{width:100%;border-radius:6px;display:block;margin-bottom:4px}
.popup p{margin:0;font-size:.85rem;font-weight:600}
footer{border-top:1px solid var(--line);color:var(--muted);text-align:center;padding:24px 16px 40px;font-size:.9rem}
footer a{color:var(--green)}

/* Dark mode follows the system setting only — no toggle, no stored preference. */
@media (prefers-color-scheme:dark){
/* --paint is absent here on purpose: paint doesn't have a dark variant. */
:root{--green:#6ad45a;--green-dark:#7de86e;--ink:#e5e7eb;--muted:#9ca3af;--line:#2c3444;--line-strong:#5a6680;--bg:#0b1220;--ok-text:#6ad45a;--err:#f28b82;--placeholder:#1a2231;--on-green:#06240f}
/* Leaflet ships a light theme; override from here so vendor/leaflet stays pristine.
   The filter must sit on the tile pane, not the container, or it would also invert
   the markers, popups, and controls drawn on top. */
.leaflet-tile-pane{filter:invert(1) hue-rotate(180deg)}
.leaflet-container{background:var(--bg)}
.leaflet-bar a{background:var(--bg);color:var(--ink);border-bottom-color:var(--line)}
.leaflet-bar a:hover,.leaflet-bar a:focus{background:var(--line);color:var(--ink)}
.leaflet-bar a.leaflet-disabled{background:var(--placeholder);color:var(--muted)}
.leaflet-touch .leaflet-bar{border-color:var(--line)}
.leaflet-container .leaflet-control-attribution{background:color-mix(in srgb,var(--bg) 80%,transparent);color:var(--muted)}
.leaflet-container .leaflet-control-attribution a{color:var(--green)}
.leaflet-popup-content-wrapper,.leaflet-popup-tip{background:var(--bg);color:var(--ink)}
.leaflet-container a.leaflet-popup-close-button{color:var(--muted)}
/* marker-shadow.png is a black blur — a smudge against a dark map, so dim it. */
.leaflet-shadow-pane{opacity:.35}
}

/* Keep both reporting actions visible and usable on narrow phones. */
.hwrap,.hnav{flex-wrap:wrap}
.flow-choices{display:flex;flex-wrap:wrap;gap:12px;margin:20px 0 12px}
.flow-choices .btn{flex:1}
.team-photo{display:block;width:100%;height:auto;border-radius:10px;margin-top:16px}
#report{scroll-margin-top:110px}

.flabel p{font-weight:400}
main a:not(.btn){color:var(--green)}

/* All-time sweep totals. */
.sweep-badges{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin:24px 0}
.sweep-badges>div{border:1px solid var(--line);border-radius:10px;padding:16px 8px;text-align:center}
.sweep-badges dt{font-size:.85rem;font-weight:600}
.sweep-badges dd{margin:8px 0 0;font-size:1.6rem;font-weight:750;font-variant-numeric:tabular-nums;line-height:1.2}
#progress{scroll-margin-top:110px}
@media (max-width:380px){.sweep-badges{gap:6px}.sweep-badges dd{font-size:1.3rem}.sweep-badges dt{font-size:.8rem}}

:root{--sweep-recent:#007c00;--sweep-aging:#507653;--sweep-old:#737b76}
.sweep-recent{color:var(--sweep-recent)}
.sweep-aging{color:var(--sweep-aging)}
.sweep-old{color:var(--sweep-old)}
.status-pin.swept.sweep-recent{color:var(--sweep-recent)}
.status-pin.swept.sweep-aging{color:var(--sweep-aging)}
.status-pin.swept.sweep-old{color:var(--sweep-old)}
@media(prefers-color-scheme:dark){:root{--sweep-recent:#6ad45a;--sweep-aging:#8dab87;--sweep-old:#a3aaa5}}
.map-expand,.map-legend{background:var(--bg);color:var(--ink);border:1px solid var(--line-strong);border-radius:8px;padding:8px;font:inherit}
.map-expand{cursor:pointer;font-weight:600}
.map-legend{font-size:12px;line-height:1.7}
.legend-dirty{color:var(--err)}
.map.map-expanded{position:fixed!important;inset:0;width:100vw;height:100dvh;max-height:none;z-index:2000;border:0;border-radius:0;margin:0!important}
.entry-actions{display:flex;gap:10px;flex-wrap:wrap;margin:8px 0 0;font-size:.85rem}
.text-button{border:0;padding:0;background:none;color:var(--green);font:inherit;text-decoration:underline;cursor:pointer}
.edit-diff{border-collapse:collapse;width:100%;table-layout:fixed;margin:20px 0}
.edit-diff th,.edit-diff td{border:1px solid var(--line);padding:8px;text-align:left;vertical-align:top;overflow-wrap:anywhere;white-space:pre-wrap}
