/* The map shell — the sidebar, the closure card, the closure list, the sign-in
   overlay. Everything the permits map page is made of that is not the map.

   No tokens here. This file used to open with its own `:root` carrying the
   retired brand palette (`--blue:#2B35FF`, `--navy:#0B0C2A`), which platform.css
   then overrode — leaving the variables current but every hardcoded literal in
   this file a generation behind, so the closure card drew one navy and the
   picker panel beside it drew another. platform.css owns the palette; this file
   spends it.

   Load order in base.html: style.css, road-picker.css, then platform.css last. */
* { box-sizing: border-box; }
/* dvh, not vh: on iOS Safari the address bar is inside 100vh, so the map's
   bottom edge and the sign-in card both sat under it until the user scrolled. */
html, body { height: 100dvh; margin: 0; }
body {
  display: flex;
  font: 14px/1.5 var(--font-sans);
  color: var(--navy);
  background: var(--background);
}
#map { flex: 1; min-width: 0; }
#sidebar {
  width: 400px; max-width: 45vw; height: 100%;
  overflow-y: auto; background: var(--surface);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
}
#sidebar header {
  padding: 14px 16px 12px; border-bottom: 1px solid var(--border); background: var(--surface);
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand-logo { width: 34px; height: 34px; flex: none; }
.brand-text { display: flex; flex-direction: column; line-height: 1.2; }
.brand-mark { font-size: 19px; font-weight: 700; letter-spacing: -0.3px; color: var(--navy); }
.brand-mark b { color: var(--blue); font-weight: 800; }
.brand-sub { font-size: 10.5px; text-transform: uppercase; letter-spacing: 1.3px; color: var(--muted); }
#userbox { margin-top: 12px; }
.userbox-title { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--muted); margin-bottom: 5px; }
#login-form { display: flex; gap: 6px; flex-wrap: wrap; }
#login-form[hidden], #whoami[hidden], section[hidden], #public-note[hidden] { display: none; }
#login-form input { flex: 1; min-width: 90px; padding: 7px 9px; border: 1px solid var(--border); border-radius: 6px; }
button {
  background: var(--blue); color: #fff; border: none; border-radius: 6px;
  padding: 8px 13px; font-weight: 600; font-family: inherit; cursor: pointer;
}
/* No button:hover here. platform.css brightens every button on the platform,
   and a second colour written in this file is what made the map shell's buttons
   change hue on hover while the module shells' merely darkened. The two
   exceptions below (#btn-suggest, #login-btn) are their own colours and keep
   their own hovers; the closure card's approve/reject pair does the same. */
button.linkish { background: none; color: var(--blue); padding: 0 4px; text-decoration: underline; font-weight: 600; }
button.linkish:hover { background: none; color: var(--navy); }
.pill {
  background: var(--blue-light); color: var(--blue); border-radius: 99px; padding: 2px 10px;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.8px;
}
section { padding: 12px 16px; }
h2 { font-size: 14px; margin: 14px 0 8px; color: var(--navy); border-bottom: 1px solid var(--border); padding-bottom: 5px; }
.hint, .note { font-size: 12.5px; color: var(--muted); }
.note { padding: 12px 16px; }
label { display: block; margin: 8px 0 0; font-weight: 600; font-size: 12.5px; color: var(--navy); }
input, select, textarea {
  width: 100%; padding: 7px 9px; margin-top: 4px;
  border: 1px solid var(--border); border-radius: 6px; font: inherit; background: var(--surface);
  color: var(--navy);
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--blue-mid); outline-offset: -1px; border-color: var(--blue); }
.row { display: flex; gap: 8px; margin-top: 12px; }
.row button { flex: 1; }
#btn-suggest { background: var(--navy); }
#btn-suggest:hover { background: color-mix(in srgb, var(--navy) 88%, #fff); }
.err { color: var(--danger); font-size: 12.5px; margin-top: 6px; }
.sel-list { font-size: 12.5px; background: var(--background); border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; margin: 6px 0; }
.sel-item { display: flex; justify-content: space-between; padding: 2px 0; }
.sel-item .rm { color: var(--danger); cursor: pointer; font-weight: 700; }
/* closure-kind key for the map lines - colours mirror map.js's line-color match */
.ck-legend { font-size: 12.5px; margin: 6px 0 2px; }
.ck-legend .ck-row { display: flex; align-items: center; gap: 8px; padding: 2px 0; }
.ck-legend .ck-line { width: 18px; height: 4px; border-radius: 2px; flex: none; }
/* Review-queue legend. These two swatches are grey on purpose: what they
   distinguish is in force (solid) from awaiting review (dashed), and colour on this
   map already means closure kind. Both selectors match .ck-legend .ck-line's
   specificity so the dashes are not flattened by its background. */
.ck-legend .ck-line-solid { background: #6B7280; }
.ck-legend .ck-line-pending {
  background-image: repeating-linear-gradient(to right, #6B7280 0 5px, transparent 5px 9px);
}
.permit-list { display: flex; flex-direction: column; gap: 6px; margin: 8px 0; }
.permit-card {
  background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--blue-mid);
  border-radius: 8px; padding: 9px 11px; cursor: pointer; font-size: 12.5px;
}
.permit-card:hover { border-color: var(--blue); }
/* The row whose closure is open on the map. Neutral on purpose: the left border
   already encodes the status, and a second colour here would fight it. */
.permit-list a.is-on .permit-card { background: #F2F4FA; border-color: #9aa2c4;
  box-shadow: inset 0 0 0 1px #9aa2c4; }
.permit-card .ref { font-weight: 700; color: var(--navy); }
.permit-card.status-approved { border-left-color: var(--success); }
.permit-card.status-submitted { border-left-color: var(--warning); }
.permit-card.status-rejected { border-left-color: var(--danger); }
.permit-card.status-active { border-left-color: #2563EB; }
.permit-card.status-completed { border-left-color: var(--success); }
.permit-card.status-cancelled { border-left-color: var(--muted); }
.status-tag { float: right; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.8px; font-weight: 700; }
.status-approved .status-tag { color: var(--success); }
.status-submitted .status-tag { color: var(--warning); }
.status-rejected .status-tag { color: var(--danger); }
.status-active .status-tag { color: #2563EB; }
.status-completed .status-tag { color: var(--success); }
.status-cancelled .status-tag { color: var(--muted); }
#result, #officer-detail { margin-top: 10px; }
.box {
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 12px; margin: 8px 0; font-size: 12.5px;
}
.box h3 { margin: 0 0 6px; font-size: 13px; color: var(--navy); }
.box.warn { border-color: var(--danger); background: #FEF2F2; }
.box.good { border-color: var(--success); background: #ECFDF5; }
.win { display: flex; justify-content: space-between; padding: 3px 0; border-bottom: 1px dashed var(--border); }
.win:last-child { border-bottom: none; }
.win .when { font-weight: 700; }
.conflict { padding: 4px 0; border-bottom: 1px dashed var(--border); }
footer { margin-top: auto; padding: 12px 16px; font-size: 11px; color: var(--muted); border-top: 1px solid var(--border); }
footer .foot-brand { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
footer .foot-brand img { height: 16px; }
.maplibregl-popup-content { font: 12.5px/1.45 var(--font-sans); border-radius: 8px; }

/* Full-screen application sign-in (matches the demo gate) */
#login-overlay {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  background: radial-gradient(1200px 600px at 50% -10%,
    color-mix(in srgb, var(--navy) 82%, #fff) 0%, var(--navy) 55%);
}
#login-overlay[hidden] { display: none; }
.login-card {
  background: #fff; border-radius: 16px; padding: 38px 36px 26px;
  width: 100%; max-width: 410px; text-align: center;
}
.login-logo { display: block; height: 32px; margin: 0 auto 22px; }
.login-tag {
  display: block; color: var(--blue); background: var(--blue-light);
  font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  padding: 5px 0; border-radius: 6px; margin-bottom: 20px;
}
.login-h1 { font-size: 19px; font-weight: 600; margin: 0 0 6px; color: var(--navy); }
.login-sub { color: var(--muted); font-size: 13px; margin: 0 0 24px; }
.login-card #login-form { display: flex; flex-direction: column; align-items: stretch; text-align: left; }
.login-card #login-form label, .login-card #login-form input, .login-card #login-form button { width: 100%; display: block; }
.login-lbl {
  display: block; color: var(--navy); font-size: 11.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .03em; margin-bottom: 6px;
}
.login-card input {
  width: 100%; padding: 11px 14px; border: 1px solid var(--border); border-radius: 9px;
  font-size: 14px; font-family: inherit; margin: 0 0 15px; outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.login-card input:focus { border-color: var(--blue); box-shadow: 0 0 0 2px rgba(22,64,255,.2); }
#login-btn {
  width: 100%; padding: 12px; background: var(--blue); color: #fff; border: none;
  border-radius: 9px; font-size: 15px; font-weight: 600; font-family: inherit;
  cursor: pointer; transition: background .15s; margin-top: 4px;
}
#login-btn:hover { background: var(--blue-ink); }
#login-btn:disabled { opacity: .7; cursor: default; }
.login-card .err { margin-top: 14px; background: #FBE7E7; border-radius: 8px; padding: 9px 12px; }
.login-card .err:empty { display: none; }
.login-hint { color: var(--muted); font-size: 11.5px; margin: 16px 0 0; line-height: 1.5; }
.login-skip {
  background: none; border: none; color: var(--blue); font-size: 12.5px; font-weight: 600;
  cursor: pointer; margin-top: 18px; padding: 6px; font-family: inherit;
}
.login-skip:hover { text-decoration: underline; background: none; }
#signin-prompt[hidden] { display: none; }
#signin-prompt button { width: 100%; }

/* Django-template-specific additions (messages framework, server-rendered forms) */
.messages { list-style: none; margin: 0; padding: 0; }
.messages li { padding: 8px 12px; border-radius: 8px; margin: 0 0 8px; font-size: 12.5px; }
.messages li.success { background: #ECFDF5; border: 1px solid var(--success); color: var(--success); }
.messages li.error { background: #FEF2F2; border: 1px solid var(--danger); color: var(--danger); }
.errorlist { list-style: none; margin: 4px 0 0; padding: 0; color: var(--danger); font-size: 12.5px; }
.decision-form textarea { margin-bottom: 8px; }
.pagination { display: flex; gap: 8px; margin-top: 10px; font-size: 12.5px; }
nav.top-links { display: flex; gap: 18px; margin-top: 10px; flex-wrap: wrap; }
nav.top-links a {
  display: inline-flex; align-items: center; gap: 5px; padding: 2px 0 5px;
  color: var(--muted); text-decoration: none; font-weight: 600; font-size: 12.5px;
  border-bottom: 2px solid transparent; transition: color .12s, border-color .12s;
}
nav.top-links a .ic { font-size: 13px; line-height: 1; opacity: .85; }
nav.top-links a:hover { color: var(--navy); text-decoration: none; }
nav.top-links a.active { color: var(--blue); border-color: var(--blue); font-weight: 700; }
nav.top-links a.active .ic { opacity: 1; }

/* ---------------------------------------------------------------- closure card
   The map popup for a road closure. Built to answer "can I drive there" at a
   glance: a coloured header carrying the verdict, then the facts that follow
   from it. The colour is the same one the line is drawn in, so the card and the
   road it describes read as one thing. */
/* max-height: a card on a short window (a laptop, the queue's card with its decision
   footer) scrolls inside itself rather than growing past the map. overflow x stays
   hidden so the coloured header keeps its rounded corners. */
.cl-popup .maplibregl-popup-content{padding:0;overflow:hidden auto;border-radius:12px;
  max-height:calc(100dvh - 40px);box-shadow:0 10px 30px var(--shadow-navy-deep)}
.cl-popup .maplibregl-popup-close-button{color:#fff;font-size:19px;padding:2px 8px 0 0}
.cl-card{font:13px/1.5 var(--font,"Segoe UI",-apple-system,Roboto,Arial,sans-serif);width:308px}
.cl-top{padding:10px 14px;color:#fff}
.cl-state{display:block;font-size:10.5px;font-weight:700;letter-spacing:.9px;
  text-transform:uppercase;opacity:.85}
.cl-head{display:block;font-size:16px;font-weight:800;line-height:1.25;margin-top:1px}
.cl-body{padding:12px 14px 13px}
.cl-road{font-size:14px;font-weight:700;color:var(--navy)}
.cl-mean{margin:3px 0 11px;color:var(--muted)}
.cl-fact{display:flex;justify-content:space-between;gap:14px;padding:5px 0;
  border-top:1px solid var(--border-soft)}
.cl-fact span{color:var(--muted-soft);flex:none}
/* Times, distances and durations, stacked in a column that updates as the
   reader moves between closures — fixed-width figures so they do not jitter. */
.cl-fact b{color:var(--navy);font-weight:600;text-align:right;font-variant-numeric:tabular-nums}
.cl-div{margin:11px 0 0;padding:8px 10px;border-radius:8px;background:var(--blue-light);
  color:var(--blue);font-weight:600}
.cl-div-none{background:#FEF2F2;color:#B91C1C}
.cl-desc{margin:11px 0 0;padding-top:10px;border-top:1px solid var(--border-soft);color:var(--muted)}
.cl-ref{margin-top:11px;color:var(--muted-soft);font-size:11.5px;letter-spacing:.3px;
  font-variant-numeric:tabular-nums}

/* What to DO about the closure, at the foot of the card — the review queue's cards
   only (permit_list.html). Last, deliberately: the decision comes after reading the
   closure, not before it. Approve and Reject share a row because they are one choice,
   and both are stated in full colour rather than one being the quiet option — the
   green/red pair here is the same one the application page uses. */
.cl-actions{margin-top:12px;padding-top:11px;border-top:1px solid #eceef5;
  display:flex;flex-direction:column;gap:8px}
.cl-actions textarea{width:100%;box-sizing:border-box;resize:vertical;font:inherit;
  font-size:12.5px;padding:7px 9px;border:1px solid var(--border);border-radius:8px}
.cl-act-row{display:flex;gap:8px;margin-top:8px}
.cl-act-row button{flex:1;padding:8px 0}
/* Beats `button:hover{background:var(--blue)}`: a colour is the whole point of these
   two, and blue here would also collide with the "no closure" closure kind. */
.cl-actions button.cl-act-yes, .cl-actions button.cl-act-yes:hover{background:#059669}
.cl-actions button.cl-act-no, .cl-actions button.cl-act-no:hover{background:#DC2626}
.cl-act-open{display:block;text-align:center;font-size:12.5px;font-weight:600}

/* Closure list in the sidebar — the way in to a specific closure. Rows carry the
   same colour as the line on the map, so the two read as one thing. */
.cl-list{margin:8px 0 4px;display:flex;flex-direction:column;gap:4px}
.cl-item{display:flex;align-items:center;gap:9px;width:100%;padding:7px 8px;
  background:#fff;border:1px solid var(--border);border-radius:9px;
  cursor:pointer;text-align:left;font:inherit;transition:border-color .12s,box-shadow .12s}
/* The global `button` rule paints buttons brand-blue on hover. That is wrong
   here twice over: these rows are list items rather than actions, and blue is
   already spoken for as the "no closure" kind. Both states below therefore stay
   neutral and let the kind bar carry the only colour in the row. */
.cl-item:hover{background:#F7F8FC;border-color:#c3c8dd;box-shadow:0 2px 8px rgba(2,2,58,.07)}
.cl-item.is-on{background:#F2F4FA;border-color:#9aa2c4;box-shadow:inset 0 0 0 1px #9aa2c4}
.cl-item.is-on .cl-item-road{color:var(--navy)}
.cl-item:focus-visible{outline:2px solid var(--blue-mid);outline-offset:1px}
.cl-item-bar{width:4px;align-self:stretch;border-radius:3px;flex:none}
.cl-item-text{display:flex;flex-direction:column;min-width:0;flex:1}
.cl-item-road{font-weight:700;font-size:12.5px;color:var(--navy);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cl-item-meta{font-size:11.5px;color:var(--muted-soft);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cl-item-now{flex:none;font-size:9.5px;font-weight:800;letter-spacing:.6px;
  text-transform:uppercase;color:#DC2626;background:#FDF3F3;border-radius:20px;padding:2px 7px}

/* Status filter tabs are styled platform-wide in platform.css, together with the
   ARIA tab strips, so both read as the same control. Nothing here: this file
   loads before it, and a second copy would only drift. */

/* ============================================================================
   Narrow screens.

   This file had no media query at all, and the shell it describes is a flex ROW:
   a 400px sidebar beside a map that takes the rest. `max-width:45vw` meant that
   on a 390px phone the whole apply form — permit type, closure kind, two
   datetime pickers, a description box — rendered in a 175px column, and the map
   got the other 215px. This is the applicant's main page and the officer's
   review queue, so it is the worst place on the platform for that to be true.

   Below 860px the row becomes a column: map first with a bounded height, then
   the sidebar as ordinary page content. The document scrolls as one thing rather
   than two panes scrolling inside a fixed viewport, which is the behaviour a
   phone expects and the only one that lets a long form reach its submit button.
   ============================================================================ */
@media (max-width: 860px) {
  /* Release the viewport lock: the page, not its panes, does the scrolling. */
  html, body { height: auto; min-height: 100dvh; }
  body { flex-direction: column; }

  /* .map-wrap and .rp-panel are laid out in road-picker.css, which loads AFTER
     this file — their narrow-screen rules have to live there or they lose the
     cascade. Only the two things this file owns are set here. */
  #map { height: clamp(240px, 42dvh, 420px); width: 100%; }

  #sidebar {
    order: 2;
    width: 100%; max-width: none; height: auto;
    overflow-y: visible;
    border-right: none; border-top: 1px solid var(--border);
  }

  /* 400px of brand, bell, role pill, language switch and five nav links in a
     390px column: let the row wrap instead of clipping the product's name. */
  .brand { flex-wrap: wrap; }
  .brand-text { min-width: 0; }
  .brand-mark, .brand-sub { overflow-wrap: anywhere; }

  /* A popup measured against the old viewport lock could stand taller than the
     map it points at. */
  .cl-popup .maplibregl-popup-content { max-height: 60dvh; }
}

/* The sign-in card is the one thing that should stay centred in the viewport at
   any width; it just needs room to breathe once the screen is short. */
@media (max-width: 520px) {
  .login-card { padding: 28px 22px 20px; border-radius: 14px; }
  #login-overlay { padding: 12px; }
  /* Two panes' worth of chrome in a 390px column: the brand block wraps rather
     than squeezing the bell and the language switch off the edge. */
  .brand { flex-wrap: wrap; }
  nav.top-links { gap: 12px; }
}
