/**
 * The v2 booth picker: layout, states and motion (spec §6.2–6.5).
 *
 * Every state is a colour AND a shape AND a word. The old picker's amber pill
 * measured 4.2:1 against its background, under the 4.5:1 line; every pill
 * here is checked by tests/test-vendor-map-ui.php against the same formula.
 *
 * Motion is opt-out: one prefers-reduced-motion block at the end zeroes every
 * animation and transition, so the picker never moves for someone who asked
 * it not to.
 *
 * Booth paths on the map are drawn by lawn-view.js and carry
 * `ppa-lawn-booth is-<state>` (+ `is-selected`, `is-hover`); the rules for them live here
 * because the timings are one system with the card and the list.
 */

.ppa-lp { --lp-brand:#732982; --lp-brand-2:#5B21B6; --lp-orange:#b45309; --lp-ink:#1f2937;
  position:relative; font-size:16px; color:var(--lp-ink); }
.ppa-lp *, .ppa-lp *::before, .ppa-lp *::after { box-sizing:border-box; }
.ppa-lp .screen-reader-text { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }

/* The gradient <svg> only carries <defs>. Out of flow, so it is never the
   first desktop grid item and never pushes the map into the 360px column. */
.ppa-lp-defs { position:absolute; width:0; height:0; overflow:hidden; }

/* ---- stage: the map with the cards floating over it ---- */
.ppa-lp-stage { position:relative; height:48vh; min-height:300px; border-radius:14px; overflow:hidden;
  border:1px solid #e5e7eb; background:#1e2a24; }
.ppa-lp-map { position:absolute; inset:0; }
.ppa-lp-map:focus-visible { outline:3px solid #2563eb; outline-offset:-3px; }

/* ---- pills: glyph + word, every pair >= 4.5:1 ---- */
.ppa-lp-pill { display:inline-flex; align-items:center; gap:5px; font-size:13px; font-weight:600;
  padding:3px 9px; border-radius:999px; white-space:nowrap; line-height:1.4; }
.ppa-lp-pill.is-available{color:#0B5A2A;background:#DCF5E4}
.ppa-lp-pill.is-held{color:#7A4400;background:#FDEFD2}
.ppa-lp-pill.is-holding{color:#5B21B6;background:#EDE9FE}
.ppa-lp-pill.is-taken{color:#374151;background:#E5E7EB}
.ppa-lp-pill.is-mine{color:#FFFFFF;background:linear-gradient(135deg,#732982,#5B21B6)}

/* ---- list pane ---- */
.ppa-lp-listpane { background:#fff; border:1px solid #e5e7eb; border-radius:14px; padding:12px 14px 14px; margin-top:12px; }
.ppa-lp-grip { display:none; }

/* ---- list header: search, Show, Area, toggles, result line ----
   Organiser: "can we improve how this part looks and functions?" The old
   header was one run of identical pills holding two selections, a half-width
   search whose placeholder was cut off, and no word on what matched. Now: the
   portal's look (the theme's type, purple for what is chosen, 12px radii, soft
   shadows); two controls that read as two -- a label each, a grey track with a
   sliding white thumb -- toggles as outlined pills, and a result line.
   .ppa-lp-chips / .ppa-lp-rowchips are styled as the tracks too, so a page
   printed before this header still looks like one during a deploy. */
.ppa-lp-headrow { display:flex; align-items:center; justify-content:space-between; gap:8px; margin:0 0 10px; }
.ppa-lp-h { font-size:16px; font-weight:700; margin:0; }
.ppa-lp-filtbtn { display:none; }
.ppa-lp-ico { flex:none; }

.ppa-lp-search { position:relative; }
.ppa-lp-search input { width:100%; min-height:44px; padding:10px 42px 10px 40px; font:inherit; font-size:16px; color:var(--lp-ink);
  background:#f8fafc; border:1px solid #e2e8f0; border-radius:12px; -webkit-appearance:none; appearance:none;
  transition:border-color 150ms ease, box-shadow 150ms ease, background-color 150ms ease; }
.ppa-lp-search input::-webkit-search-cancel-button { -webkit-appearance:none; display:none; }
.ppa-lp-search input::placeholder { color:#8a94a6; opacity:1; }
.ppa-lp-search input:hover { border-color:#cbd5e1; }
.ppa-lp-search input:focus { outline:none; background:#fff; border-color:#7c3aed; box-shadow:0 0 0 3px rgba(124,58,237,.18); }
.ppa-lp-search-ico { position:absolute; left:13px; top:50%; transform:translateY(-50%); color:#64748b; pointer-events:none; }
.ppa-lp-kbd { position:absolute; right:10px; top:50%; transform:translateY(-50%); min-width:22px; padding:0 6px; border:1px solid #e2e8f0;
  border-bottom-width:2px; border-radius:6px; background:#fff; color:#64748b; font:600 12px/18px ui-monospace, SFMono-Regular, Menlo, monospace;
  text-align:center; pointer-events:none; }
.ppa-lp-search input:focus ~ .ppa-lp-kbd, .ppa-lp-search input:not(:placeholder-shown) ~ .ppa-lp-kbd { display:none; }
.ppa-lp-qclear { position:absolute; right:6px; top:50%; transform:translateY(-50%); width:32px; height:32px; display:inline-flex;
  align-items:center; justify-content:center; padding:0; border:0; border-radius:999px; background:transparent; color:#475569; cursor:pointer; }
.ppa-lp-qclear:hover { background:#e2e8f0; color:var(--lp-ink); }
.ppa-lp-qclear[hidden] { display:none; }
.ppa-lp-qclear:focus-visible { outline:3px solid #2563eb; outline-offset:0; }

.ppa-lp-filters { display:flex; flex-wrap:wrap; align-items:center; gap:8px 10px; margin:10px 0 0; }
.ppa-lp-fgroup { display:flex; align-items:center; gap:8px; min-width:0; max-width:100%; }
.ppa-lp-fgroup[hidden] { display:none; }
.ppa-lp-flabel { flex:none; min-width:2.7em; font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:#64748b; }
.ppa-lp-chips, .ppa-lp-rowchips, .ppa-lp-seg { position:relative; display:inline-flex; gap:2px; padding:3px; margin:0; background:#f1f5f9;
  border-radius:12px; max-width:100%; overflow-x:auto; scrollbar-width:none; }
.ppa-lp-seg::-webkit-scrollbar { display:none; }
.ppa-lp-segthumb { position:absolute; left:0; top:3px; bottom:3px; width:0; border-radius:9px; background:#fff; pointer-events:none;
  box-shadow:0 1px 3px rgba(15,23,42,.14), 0 0 0 1px rgba(124,58,237,.14);
  transition:transform 220ms cubic-bezier(.2,.8,.2,1), width 220ms cubic-bezier(.2,.8,.2,1); }
.ppa-lp-chip { position:relative; z-index:1; flex:0 0 auto; min-height:34px; padding:6px 12px; border:0; border-radius:9px; background:transparent;
  font:inherit; font-size:14px; font-weight:600; color:#475569; white-space:nowrap; cursor:pointer; transition:color 150ms ease; }
.ppa-lp-chip:hover { color:var(--lp-ink); }
.ppa-lp-chip[aria-checked="true"], .ppa-lp-chip[aria-pressed="true"] { color:#5B21B6; }
.ppa-lp-chip:focus-visible { outline:2px solid #7c3aed; outline-offset:-2px; }
.ppa-lp-chip-n { display:inline-block; min-width:1.7em; margin-left:3px; padding:0 5px; border-radius:999px; background:rgba(15,23,42,.07);
  font-size:12px; line-height:18px; font-variant-numeric:tabular-nums; text-align:center; }
.ppa-lp-chip[aria-checked="true"] .ppa-lp-chip-n { background:#ede9fe; color:#5B21B6; }

.ppa-lp-toggle { display:inline-flex; align-items:center; gap:6px; min-height:34px; padding:6px 12px; border:1px solid #e2e8f0; border-radius:999px;
  background:#fff; font:inherit; font-size:13px; font-weight:600; color:#475569; cursor:pointer; white-space:nowrap;
  transition:background-color 150ms ease, color 150ms ease, border-color 150ms ease; }
.ppa-lp-toggle[hidden] { display:none; }
.ppa-lp-toggle:hover { border-color:#c4b5fd; color:var(--lp-ink); }
.ppa-lp-toggle[aria-pressed="true"] { background:#f3e8ff; border-color:#a78bfa; color:#5B21B6; }
.ppa-lp-toggle:focus-visible { outline:3px solid #2563eb; outline-offset:2px; }

.ppa-lp-result { display:flex; align-items:center; justify-content:space-between; gap:8px; min-height:24px; margin:10px 0 0;
  font-size:13px; color:#64748b; }
.ppa-lp-clear, .ppa-lp-emptyclear { flex:none; padding:2px 0; border:0; background:none; font:inherit; font-size:13px; font-weight:600;
  color:#6D28D9; cursor:pointer; text-decoration:underline; text-underline-offset:2px; }
.ppa-lp-clear[hidden] { display:none; }
.ppa-lp-clear:focus-visible, .ppa-lp-emptyclear:focus-visible { outline:3px solid #2563eb; outline-offset:2px; border-radius:4px; }

.ppa-lp-list { list-style:none; margin:10px 0 0; padding:0; max-height:52vh; overflow:auto;
  border:1px solid #e5e7eb; border-radius:10px; }
.ppa-lp-list li { border-bottom:1px solid #f1f5f9; }
.ppa-lp-list li:last-child { border-bottom:0; }
.ppa-lp-list li[hidden] { display:none; }
.ppa-lp-row { display:flex; align-items:center; gap:12px; width:100%; min-height:56px;
  padding:10px 12px; background:#fff; border:0; text-align:left; font:inherit; color:var(--lp-ink); cursor:pointer;
  transition:background-color 150ms ease; }
.ppa-lp-row:hover { background:#f8fafc; }
.ppa-lp-row[aria-pressed="true"] { background:#f3e8ff; box-shadow:inset 4px 0 0 var(--lp-brand); }
.ppa-lp-row:focus-visible { outline:3px solid #2563eb; outline-offset:-3px; }
.ppa-lp-row.is-dim .ppa-lp-lab, .ppa-lp-row.is-dim .ppa-lp-meta { color:#4b5563; }
.ppa-lp-lab { font-weight:700; min-width:3.2em; }
.ppa-lp-meta { color:#475569; font-size:14px; flex:1; }
.ppa-lp-empty { padding:22px 16px; color:#475569; text-align:center; font-size:14px; }
.ppa-lp-empty-t { margin-right:4px; }

/* ---- detail card: 280ms drop-in, not a modal ---- */
.ppa-lp-card, .ppa-lp-yours { position:absolute; left:12px; bottom:12px; z-index:1000; width:min(360px, calc(100% - 24px));
  background:#fff; border-radius:14px; padding:16px 16px 14px; box-shadow:0 10px 30px rgba(15,23,42,.25);
  opacity:0; transform:translateY(20px);
  transition:transform 280ms cubic-bezier(.2,.8,.2,1), opacity 280ms cubic-bezier(.2,.8,.2,1); }
/* A confirmed vendor keeps the "yours" card up from boot, and opening a booth
   does not hide it, so the detail card must paint over it. */
.ppa-lp-card { z-index:1001; }
.ppa-lp-card[hidden], .ppa-lp-yours[hidden] { display:none; }
.ppa-lp-card.is-in, .ppa-lp-yours.is-in { opacity:1; transform:translateY(0); }
.ppa-lp-card:focus, .ppa-lp-yours:focus { outline:3px solid #2563eb; outline-offset:2px; }
.ppa-lp-card-x { position:absolute; top:6px; right:6px; width:44px; height:44px; font-size:24px;
  background:none; border:0; cursor:pointer; line-height:1; color:var(--lp-ink); }
.ppa-lp-card-h, .ppa-lp-yours-h { margin:0 40px 6px 0; font-size:20px; }
.ppa-lp-card-pill { margin:0 0 8px; }
.ppa-lp-card-meta { margin:0 0 6px; color:#475569; font-size:14px; }
.ppa-lp-card-near { display:flex; flex-wrap:wrap; gap:6px; margin:0 0 8px; }
.ppa-lp-card-near[hidden], .ppa-lp-card-desc[hidden], .ppa-lp-ringwrap[hidden] { display:none; }
.ppa-lp-near { font-size:12px; padding:2px 8px; border-radius:999px; background:#f1f5f9; color:#334155; }
.ppa-lp-card-desc { margin:0 0 8px; color:#475569; font-size:14px; }
.ppa-lp-card-note { color:#4b5563; font-size:14px; margin:10px 0 0; min-height:1.2em; }
.ppa-lp-pair-select { display:block; width:100%; margin-top:7px; padding:8px 10px; border:1px solid #cbd5e1;
  border-radius:8px; background:#fff; color:#1e293b; font:inherit; }
.ppa-lp-card-actions { display:flex; gap:8px; flex-wrap:wrap; }
.ppa-lp-card-actions button { flex:1 1 auto; min-height:48px; padding:10px 16px; font-size:16px; font-weight:600;
  border-radius:12px; border:1px solid #cbd5e1; background:#f1f5f9; color:var(--lp-ink); cursor:pointer; }
.ppa-lp-card-actions button[hidden] { display:none; }
.ppa-lp-card-actions .ppa-lp-hold, .ppa-lp-card-actions .ppa-lp-confirm { background:#6D28D9; border-color:#6D28D9; color:#fff; }
.ppa-lp-card-actions button:focus-visible { outline:3px solid #2563eb; outline-offset:2px; }

/* ---- countdown ring ---- */
.ppa-lp-ringwrap { display:flex; align-items:center; gap:10px; margin:0 0 10px; }
.ppa-lp-ring { width:44px; height:44px; transform:rotate(-90deg); }
.ppa-lp-ring-track { fill:none; stroke:#EDE9FE; stroke-width:3; }
.ppa-lp-ring-arc { fill:none; stroke:#5B21B6; stroke-width:3; stroke-linecap:round; transition:stroke-dashoffset 1s linear; }
.ppa-lp-ring-time { font-weight:700; font-variant-numeric:tabular-nums; color:#5B21B6; }

/* ---- "yours" card: 400ms drop-in ---- */
.ppa-lp-yours { border-top:4px solid var(--lp-brand);
  transition:transform 400ms cubic-bezier(.2,.8,.2,1), opacity 400ms cubic-bezier(.2,.8,.2,1); }
.ppa-lp-yours-sub { margin:0 0 10px; color:#475569; font-size:14px; }
.ppa-lp-yours-actions { display:flex; gap:8px; flex-wrap:wrap; }
.ppa-lp-yours-actions a { display:inline-flex; align-items:center; min-height:44px; padding:8px 14px; border-radius:10px;
  border:1px solid #cbd5e1; background:#fff; color:var(--lp-ink); text-decoration:none; font-weight:600; font-size:15px; }
.ppa-lp-yours-actions a[hidden] { display:none; }
.ppa-lp-yours-actions a:focus-visible { outline:3px solid #2563eb; outline-offset:2px; }

/* ---- status line ---- */
.ppa-lp-status { margin:12px 0 0; font-weight:600; }

/* ---- booths on the map (paths from lawn-view.js) ---- */
.ppa-lp-map .ppa-lawn-booth { transition:stroke-width 200ms ease, fill 200ms ease, stroke 200ms ease, filter 200ms ease, fill-opacity 200ms ease, stroke-opacity 200ms ease; }
.ppa-lp-map .ppa-lawn-booth.is-available { fill:#ffffff; fill-opacity:.92; stroke:#b45309; stroke-width:1.5; }
.ppa-lp-map .ppa-lawn-booth.is-held { fill:#FDEFD2; fill-opacity:.9; stroke:#7A4400; stroke-width:1.5; stroke-dasharray:4 3; }
.ppa-lp-map .ppa-lawn-booth.is-held-mine { fill:#732982; fill-opacity:.9; stroke:#EDE9FE; stroke-width:2;
  animation:ppa-lp-pulse 1.6s ease-in-out infinite; }
.ppa-lp-map .ppa-lawn-booth.is-taken { fill:#374151; fill-opacity:.9; stroke:#111827; stroke-width:1; }
.ppa-lp-map .ppa-lawn-booth.is-mine { fill:url(#ppa-lp-mine-gradient); fill-opacity:1; stroke:#ffffff; stroke-width:2; }
/* The chosen booth: a deep-purple outline with a white halo and a purple glow,
   raised above its neighbours (lawn-view brings it to front), its number
   emphasised, and one ring out when it is chosen (lawn-view pulse()). The halo
   keeps it readable on every fill -- the purple of "yours" included -- and a
   held booth keeps its dashes. Organiser: the selected booth "isn't the focal
   point" as a 3px stroke of its state colour. */
.ppa-lp-map .ppa-lawn-booth.is-selected { stroke:#4C1D95; stroke-width:4; stroke-opacity:1;
  filter:drop-shadow(0 0 1.5px #fff) drop-shadow(0 0 7px rgba(124,58,237,.9)); }
.ppa-lp-map .ppa-lawn-booth-label.is-selected { color:#4C1D95; font-size:13px; font-weight:800; text-shadow:0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff; }
.ppa-lp.is-confirming .ppa-lawn-booth.is-mine { animation:ppa-lp-confirm 0.9s ease-out 1; }

/* ---- which block is it: a booth a list row points at, or under the mouse ----
   lawn-view.js hover(). A teal outline that breathes: "this one", not "yours"
   (brand purple) and not "chosen" (the purple outline). Never on the chosen
   booth itself: a list click leaves the mouse on its row, and the teal painted
   over the selection until the mouse moved. Its number is emphasised, or, when the
   booth is too small to carry one, a tag names it. A booth out of view gets a
   pill on the map's edge pointing at it; the map itself never moves. */
.ppa-lp-map .ppa-lawn-booth.is-hover:not(.is-selected) { stroke:#0e7490; stroke-width:3; stroke-opacity:1; stroke-dasharray:none;
  filter:drop-shadow(0 0 3px rgba(34,211,238,.95)); animation:ppa-lp-glow 1.4s ease-in-out infinite; }
.ppa-lp-map .ppa-lawn-booth-label.is-hover:not(.is-selected) { color:#0e7490; font-size:13px; text-shadow:0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff; }
.ppa-lp-map .ppa-lawn-booth-tip { background:#0e7490; color:#fff; border:0; font-weight:700; font-size:12px; padding:2px 7px;
  box-shadow:0 2px 6px rgba(15,23,42,.35); }
.ppa-lp-map .ppa-lawn-booth-tip::before { border-top-color:#0e7490; }
.ppa-lp-map .ppa-lawn-edge { position:absolute; z-index:800; display:inline-flex; align-items:center; gap:5px; transform:translate(-50%,-50%);
  padding:3px 9px 3px 7px; border-radius:999px; background:#0e7490; color:#fff; font:700 13px/1.3 system-ui, -apple-system, sans-serif;
  box-shadow:0 2px 6px rgba(15,23,42,.35); pointer-events:none; animation:ppa-lp-fade 150ms ease-out; }
.ppa-lp-map .ppa-lawn-edge[hidden] { display:none; }
.ppa-lp-map .ppa-lawn-edge-arrow { display:block; width:12px; height:12px; flex:none; }
.ppa-lp-row.is-maphover { background:#ecfeff; box-shadow:inset 4px 0 0 #0e7490; }

/* ---- who took a booth, and finding vendors by name ----
   Names reach only a viewer the server allows (an approved vendor this year,
   or an admin); none of this shows for anyone else. The row keeps its size
   line and puts the name under it, cut short with an ellipsis -- the whole
   name is in the title. */
.ppa-lp-rowtext { flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.ppa-lp-occ { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13px; font-weight:600; color:#6B21A8; }
.ppa-lp-occ[hidden] { display:none; }
.ppa-lp-card-occ { margin:0 0 8px; }
.ppa-lp-card-occ[hidden], .ppa-lp-card-nearby[hidden] { display:none; }
/* The name replaces "Already taken.": its empty line would only leave a gap. */
.ppa-lp-card-occ:not([hidden]) ~ .ppa-lp-card-note:empty { display:none; }
.ppa-lp-occ-line { display:block; font-size:16px; line-height:1.35; overflow-wrap:anywhere; }
.ppa-lp-occ-name { font-weight:700; }
.ppa-lp-occ-extra { display:flex; flex-wrap:wrap; align-items:center; gap:6px 12px; margin-top:6px; }
.ppa-lp-occ-cat { display:inline-flex; align-items:center; gap:4px; padding:2px 9px; border-radius:999px; background:#F3E8FF; color:#6B21A8; font-size:12px; font-weight:600; }
.ppa-lp-occ-link { font-size:14px; font-weight:600; color:#6D28D9; text-decoration:underline; text-underline-offset:2px; }
.ppa-lp-occ-link:focus-visible { outline:3px solid #2563eb; outline-offset:2px; border-radius:4px; }
.ppa-lp-card-nearby { display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin:10px 0 0; padding-top:10px; border-top:1px solid #e5e7eb;
  font-size:14px; color:#334155; }
.ppa-lp-nearby-t { margin-right:2px; }
.ppa-lp-nearby-b { min-width:48px; min-height:40px; padding:4px 12px; border-radius:999px; border:1px solid #c4b5fd; background:#fff;
  font:inherit; font-size:15px; font-weight:700; color:#5B21B6; cursor:pointer; }
.ppa-lp-nearby-b:hover { background:#f5f3ff; border-color:#a78bfa; }
.ppa-lp-nearby-b:focus-visible { outline:3px solid #2563eb; outline-offset:2px; }

/* The search's results: Booths, then Vendors, under the box. */
.ppa-lp-sugg { position:absolute; left:0; right:0; top:calc(100% + 6px); z-index:30; max-height:min(340px, 50vh); overflow-y:auto;
  padding:6px 0; background:#fff; border:1px solid #e2e8f0; border-radius:12px; box-shadow:0 12px 32px rgba(15,23,42,.18); }
.ppa-lp-sugg[hidden] { display:none; }
.ppa-lp-sugg-g + .ppa-lp-sugg-g { margin-top:4px; padding-top:4px; border-top:1px solid #f1f5f9; }
.ppa-lp-sugg-h { padding:6px 14px 4px; font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:#64748b; }
.ppa-lp-sugg-o { display:flex; align-items:center; gap:10px; min-height:44px; padding:6px 14px; font-size:15px; color:var(--lp-ink); cursor:pointer; }
.ppa-lp-sugg-o:hover { background:#f8fafc; }
.ppa-lp-sugg-o.is-active { background:#f3e8ff; box-shadow:inset 3px 0 0 var(--lp-brand); }
.ppa-lp-sugg-lab { flex:none; min-width:2.8em; font-weight:700; }
.ppa-lp-sugg-sub, .ppa-lp-sugg-name { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ppa-lp-sugg-sub { color:#475569; font-size:14px; }
.ppa-lp-sugg-name { font-weight:600; }
.ppa-lp-sugg-ico { flex:none; width:1.4em; text-align:center; }
.ppa-lp-sugg-st { flex:none; font-size:12px; font-weight:600; color:#374151; }
.ppa-lp-sugg-st.is-available { color:#0B5A2A; }
.ppa-lp-sugg-st.is-held { color:#7A4400; }
.ppa-lp-sugg-st.is-holding, .ppa-lp-sugg-st.is-mine { color:#5B21B6; }
.ppa-lp-sugg-booth { flex:none; padding:2px 8px; border-radius:999px; background:#f1f5f9; color:#334155; font-size:12px; font-weight:700; white-space:nowrap; }
.ppa-lp-hl { padding:0 1px; border-radius:3px; background:#FDE68A; color:inherit; }

/* The list's filters on the map: what they leave out is dimmed, not hidden, so
   the lawn still reads; the chosen booth and a pointed-at one never dim. */
.ppa-lp-map .ppa-lawn-booth.is-dim:not(.is-selected):not(.is-hover) { fill-opacity:.22; stroke-opacity:.35; }
.ppa-lp-map .ppa-lawn-booth-label.is-dim:not(.is-selected):not(.is-hover) { opacity:.35; }

@keyframes ppa-lp-pulse {
  0%   { stroke-opacity:1;  stroke-width:2; }
  50%  { stroke-opacity:.35; stroke-width:6; }
  100% { stroke-opacity:1;  stroke-width:2; }
}
@keyframes ppa-lp-confirm {
  0%   { stroke-opacity:1; stroke-width:3; }
  100% { stroke-opacity:0; stroke-width:28; }
}
@keyframes ppa-lp-glow {
  0%, 100% { filter:drop-shadow(0 0 2px rgba(34,211,238,.95)); }
  50%      { filter:drop-shadow(0 0 7px rgba(34,211,238,.6)); }
}
@keyframes ppa-lp-fade { from { opacity:0; } to { opacity:1; } }

@media (hover:hover) and (pointer:fine) {
  .ppa-lp-map .ppa-lawn-booth:hover { filter:drop-shadow(0 3px 4px rgba(0,0,0,.45)); }
}

/* ---- phone: map on top, list in a drag-up sheet (snap 40% / 85%) ----
   The sheet is one scroller: at 40vh the search and chips alone can fill it,
   so a list that scrolled on its own would shrink to nothing. Chips scroll
   sideways and the heading is kept for screen readers only, so a whole row
   shows at 40vh on a 667px phone. The cards sit above the sheet (spec §6.2)
   so Release / Confirm are never underneath it, and the detail card above the
   "yours" card. The grip sticks to the top of the sheet: it is the only way to
   snap between 40% and 85%, so it cannot scroll away with the rows. The page reserves the 40vh the
   sheet covers with an in-flow spacer at the end of body (the one rule outside
   .ppa-lp: space after the picker has to be on the document, or the footer
   stays under the sheet). It is a spacer, not body padding, because the Verno
   theme pins body to height:100% with padding:0 !important, so padding would
   be overridden and, even forced, would sit below a fixed-height box rather
   than after the content that overflows it. Browsers without :has() reserve
   the space inside the picker instead. */
@media (max-width:859px) {
  body:has(.ppa-lp)::after { content:""; display:block; height:calc(40vh + 12px); }
  @supports not selector(:has(*)) { .ppa-lp { padding-bottom:calc(40vh + 12px); } }
  .ppa-lp-listpane { position:fixed; left:0; right:0; bottom:0; z-index:1001; margin:0; border-radius:16px 16px 0 0;
    box-shadow:0 -8px 24px rgba(15,23,42,.2); transition:height 280ms cubic-bezier(.2,.8,.2,1);
    overflow-x:hidden; overflow-y:auto; overscroll-behavior:contain; padding-top:0; }
  .ppa-lp-listpane[data-snap="40"] { height:40vh; }
  .ppa-lp-listpane[data-snap="85"] { height:85vh; }
  .ppa-lp-grip { display:block; position:sticky; top:0; z-index:1; width:100%; min-height:28px; background:#fff; border:0; padding:6px 0; cursor:grab; touch-action:none; }
  .ppa-lp-grip span { display:block; width:44px; height:5px; border-radius:3px; background:#cbd5e1; margin:0 auto; }
  .ppa-lp-grip:focus-visible { outline:3px solid #2563eb; outline-offset:-3px; }
  .ppa-lp-h { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; margin:0; }
  /* The header stays pinned under the grip while the rows scroll. The search
     is always there; the filters fold behind a Filters button with a count. */
  .ppa-lp-head { position:sticky; top:28px; z-index:1; display:grid; grid-template-columns:1fr auto; align-items:center; gap:6px;
    margin:0 -14px; padding:0 14px 8px; background:#fff; box-shadow:0 1px 0 #eef2f7; }
  .ppa-lp-headrow { display:contents; }
  /* The search keeps the whole width (its placeholder fits); Filters sits on the result line. */
  .ppa-lp-search { grid-column:1 / -1; grid-row:1; }
  .ppa-lp-search input { padding-right:38px; }
  .ppa-lp-filtbtn { display:inline-flex; grid-column:2; grid-row:2; align-items:center; gap:5px; min-height:40px; padding:0 10px;
    border:1px solid #e2e8f0; border-radius:12px; background:#fff; font:inherit; font-size:14px; font-weight:600; color:#475569; cursor:pointer; }
  .ppa-lp-filtbtn[aria-expanded="true"] { background:#f3e8ff; border-color:#a78bfa; color:#5B21B6; }
  .ppa-lp-filtbtn:focus-visible { outline:3px solid #2563eb; outline-offset:2px; }
  .ppa-lp-filtn { min-width:20px; height:20px; padding:0 6px; border-radius:999px; background:#6D28D9; color:#fff; font-size:12px; line-height:20px; text-align:center; }
  .ppa-lp-filtn[hidden] { display:none; }
  .ppa-lp-filters { grid-column:1 / -1; grid-row:3; display:none; margin:0 0 2px; }
  .ppa-lp-head.is-filters-open .ppa-lp-filters { display:flex; }
  .ppa-lp-result { grid-column:1; grid-row:2; margin:0; flex-wrap:wrap; justify-content:flex-start; column-gap:6px; }
  .ppa-lp-chip, .ppa-lp-toggle { min-height:40px; }
  .ppa-lp-kbd { display:none; }
  .ppa-lp-list { max-height:none; overflow:visible; }
  .ppa-lp-stage { height:48vh; }
  .ppa-lp-card, .ppa-lp-yours { position:fixed; left:12px; right:12px; bottom:12px; z-index:1002; width:auto;
    max-height:calc(100vh - 24px); overflow-y:auto; }
  .ppa-lp-card { z-index:1003; }
  /* The results end inside the sheet, whichever snap it is at (the grip and the search sit above them). */
  .ppa-lp-sugg { max-height:max(140px, calc(40vh - 96px)); }
  .ppa-lp-listpane[data-snap="85"] .ppa-lp-sugg { max-height:calc(85vh - 96px); }
  .ppa-lp-nearby-b { min-height:44px; }
}

/* ---- desktop: the map fills, a 360px list pane beside it ----
   The query is on width alone, so a landscape phone (932x430) or a scaled
   laptop (1093x513) lands here too. The list is the keyboard and screen-reader
   way to pick a booth (spec §6.5), so it keeps a floor of about four rows
   however short the screen; the pane is not height-bound and the page scrolls
   to it. Above the floor the list ends level with the map: --lp-headroom is the
   header above it plus the pane's padding, measured by lawn-picker.js because
   the header holds more or less (no Area control on a one-row lawn, no toggles
   without distances or doubles); 294px is the full header. The map keeps its
   480px floor only while that fits the screen, so it never outgrows the
   viewport and traps the page scroll under Leaflet's drag. */
@media (min-width:860px) {
  .ppa-lp { display:grid; grid-template-columns:1fr 360px; gap:16px; align-items:start; }
  .ppa-lp-stage { grid-column:1; grid-row:1; height:70vh; min-height:min(480px, calc(100vh - 32px)); }
  .ppa-lp-listpane { grid-column:2; grid-row:1; margin-top:0; }
  .ppa-lp-list { max-height:max(240px, calc(70vh - var(--lp-headroom, 294px))); }
  .ppa-lp-status { grid-column:1 / -1; }
}

/* ---- reduced motion: instant state changes (spec §6.4) ---- */
@media (prefers-reduced-motion:reduce) {
  .ppa-lp *, .ppa-lp *::before, .ppa-lp *::after { animation:none !important; transition:none !important; }
}
