/* FestLocator — dark neon festival theme. Dependency-free (Leaflet via CDN). */
:root {
  --bg: #0b0e1a;
  --bg2: #121732;
  --panel: #161c38;
  --panel2: #1d2547;
  --line: #2a3358;
  --ink: #eef1fb;
  --ink-dim: #97a0c4;
  --accent: #b14bff;     /* electric violet */
  --accent2: #36e0ff;    /* cyan */
  --hot: #ff4d8d;        /* magenta-pink */
  --spotify: #1db954;
  --gold: #ffd24d;
  --radius: 14px;
  --shadow: 0 16px 40px rgba(0,0,0,.45);
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --topH: 62px;
  --toolH: 52px;
}
* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: var(--sans); color: var(--ink); background: var(--bg);
  display: flex; flex-direction: column; overflow: hidden;
}
button { font-family: inherit; }
.hidden { display: none !important; }

/* ---------- topbar ---------- */
#topbar {
  height: var(--topH); flex: 0 0 auto; display: flex; align-items: center; gap: 16px;
  padding: 0 18px; background: linear-gradient(100deg, #14091f, #0b0e1a 60%);
  border-bottom: 1px solid var(--line); z-index: 30;
}
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--ink); }
.brand .logo { font-size: 24px; filter: drop-shadow(0 0 8px var(--accent)); }
.brand-text { display: flex; flex-direction: column; line-height: 1.05; }
.brand-text strong { font-size: 1.25rem; letter-spacing: .3px; }
.brand-text .accent { background: linear-gradient(90deg, var(--accent), var(--accent2)); -webkit-background-clip: text; background-clip: text; color: transparent; }
.brand-text small { color: var(--ink-dim); font-size: .68rem; letter-spacing: .14em; text-transform: uppercase; }

.search-box { flex: 1; max-width: 540px; margin: 0 auto; position: relative; display: flex; align-items: center; }
.search-box .search-ic { position: absolute; left: 14px; opacity: .6; font-size: 14px; }
#search {
  width: 100%; height: 42px; padding: 0 16px 0 38px; border-radius: 999px;
  background: var(--panel); border: 1px solid var(--line); color: var(--ink); font-size: 15px;
}
#search:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(177,75,255,.22); }

.top-actions { display: flex; align-items: center; gap: 10px; }
.hamb { display: none; border: 1px solid var(--line); border-radius: 10px; width: 42px; height: 42px;
  background: rgba(11,14,26,.92); color: var(--ink); cursor: pointer;
  align-items: center; justify-content: center; flex: 0 0 auto; }
.hamb:hover, .hamb[aria-expanded="true"] { border-color: var(--accent); }
.btn { border: 0; border-radius: 999px; padding: 10px 18px; font-weight: 700; font-size: 14px; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn-spotify { background: var(--spotify); color: #04210f; }
.btn-spotify .sp-logo { width: 18px; height: 18px; fill: currentColor; flex: 0 0 auto; }
.btn-ghost { background: transparent; color: var(--ink-dim); border: 1px solid var(--line); }
.btn-ghost:hover { color: var(--ink); border-color: var(--accent); }
.btn-accent { background: linear-gradient(90deg, var(--accent), var(--hot)); color: #fff;
  box-shadow: 0 6px 16px rgba(177,75,255,.28); }
.btn-accent:hover { filter: brightness(1.08); }

/* ---------- toolbar ---------- */
#toolbar {
  height: var(--toolH); flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between;
  gap: 14px; padding: 0 18px; background: var(--bg2); border-bottom: 1px solid var(--line); z-index: 20;
}
.filters { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.filter { height: 36px; padding: 0 12px; border-radius: 10px; background: var(--panel); color: var(--ink);
  border: 1px solid var(--line); font-size: 14px; cursor: pointer; }
.filter:focus { outline: none; border-color: var(--accent); }
.mine-toggle { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; font-size: 14px; font-weight: 600;
  background: linear-gradient(90deg, rgba(177,75,255,.16), rgba(54,224,255,.16)); border: 1px solid var(--accent);
  padding: 6px 12px; border-radius: 10px; color: var(--ink); }
.mine-toggle input { accent-color: var(--accent); width: 16px; height: 16px; }
.result-meta { color: var(--ink-dim); font-size: 13px; white-space: nowrap; }
.result-meta #count { color: var(--ink); font-weight: 800; font-size: 15px; }
#matchMeta { color: var(--gold); font-weight: 700; }

/* ---------- main layout ---------- */
#app { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: 380px 1fr; position: relative; }
#sidebar { background: var(--bg); border-right: 1px solid var(--line); overflow-y: auto; min-height: 0; }
.fest-list { list-style: none; margin: 0; padding: 8px; }
.fest-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px 14px; margin-bottom: 8px; cursor: pointer; position: relative; transition: border-color .15s, transform .08s;
}
.fest-card:hover { border-color: var(--accent); }
.fest-card.active { border-color: var(--accent2); box-shadow: 0 0 0 1px var(--accent2), 0 8px 22px rgba(54,224,255,.12); }
.fest-card.has-mine { border-left: 3px solid var(--gold); }
.fest-card .fc-name { font-weight: 800; font-size: 16px; margin-bottom: 3px; display: block; text-decoration: none; }
.fest-card a.fc-name, .fest-card a.fc-name:link, .fest-card a.fc-name:visited { color: var(--ink); text-decoration: none; }
.fest-card a.fc-name:hover { color: var(--accent2); }
.fest-card .fc-meta { color: var(--ink-dim); font-size: 13px; display: flex; flex-wrap: wrap; gap: 4px 10px; }
.fc-camp { cursor: default; }
.fest-card .fc-tags { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 6px; }
.tag { font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 999px; background: var(--panel2); color: var(--ink-dim); }
.tag.genre { color: var(--accent2); border: 1px solid rgba(54,224,255,.3); background: rgba(54,224,255,.07); }
.mine-badge { position: absolute; top: 10px; right: 40px; background: linear-gradient(90deg, var(--gold), #ff9b3d);
  color: #2a1a00; font-weight: 800; font-size: 11px; padding: 3px 9px; border-radius: 999px; box-shadow: 0 2px 8px rgba(255,210,77,.3); }
/* save (♥) button — top-right of every card; badges shift left to make room */
.fest-card .fc-name { padding-right: 26px; }
.fc-save { position: absolute; top: 6px; right: 8px; background: none; border: none; cursor: pointer;
  font-size: 20px; line-height: 1; color: var(--ink-dim); padding: 2px 4px; transition: color .12s, transform .08s; }
.fc-save:hover { color: var(--hot); transform: scale(1.15); }
.fc-save.on { color: var(--hot); }

/* finished festivals — shown greyed when "Include past" is on */
.fest-card.past { opacity: .5; filter: grayscale(.6); }
.fest-card.past:hover { opacity: .8; border-color: var(--line); }
.past-badge { position: absolute; top: 10px; right: 40px; background: var(--line); color: var(--ink-dim);
  font-weight: 700; font-size: 10px; letter-spacing: .04em; text-transform: uppercase; padding: 3px 8px; border-radius: 999px; }
/* neutral styling for the past-toggle so it doesn't read as the accent "my artists" feature */
.past-toggle { background: var(--panel); border-color: var(--line); color: var(--ink-dim); font-weight: 600; }
.past-toggle input { accent-color: var(--ink-dim); }

#mapWrap { position: relative; min-height: 0; }
#map { position: absolute; inset: 0; background: #0a0d18; }
/* full-page map toggle (issue #25) — top-right; the open detail panel (z 600) may cover it */
.map-full { position: absolute; top: 12px; right: 12px; z-index: 590; width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center; border-radius: 10px; cursor: pointer;
  background: rgba(11,14,26,.92); border: 1px solid var(--line); color: var(--ink); }
.map-full:hover { border-color: var(--accent); }
.map-full .ic-exit { display: none; }
body.mapfull .map-full .ic-exit { display: block; }
body.mapfull .map-full .ic-expand { display: none; }
body.mapfull #topbar, body.mapfull #toolbar, body.mapfull #sidebar, body.mapfull #sitefoot { display: none; }
body.mapfull #app { grid-template-columns: 1fr; }
/* dates disclaimer moved to the right (the view switch owns the bottom-left corner);
   bottom offset clears Leaflet's attribution line */
.seed-note { position: absolute; right: 12px; bottom: 34px; z-index: 500; background: rgba(11,14,26,.85);
  border: 1px solid var(--line); color: var(--ink-dim); font-size: 11px; padding: 6px 10px; border-radius: 8px; max-width: 320px; }

/* leaflet marker pin */
.pin { width: 26px; height: 26px; border-radius: 50% 50% 50% 0; transform: rotate(-45deg);
  background: var(--accent); border: 2px solid #fff; box-shadow: 0 2px 8px rgba(0,0,0,.5); }
.pin.mine { background: var(--gold); }
.pin.past { background: #5a6080; border-color: #aab; opacity: .65; }
.pin.active { background: var(--accent2); transform: rotate(-45deg) scale(1.25); z-index: 1000; }
.leaflet-popup-content-wrapper { background: var(--panel); color: var(--ink); border-radius: 12px; border: 1px solid var(--line); }
.leaflet-popup-tip { background: var(--panel); }
.leaflet-popup-content { margin: 12px 14px; }
.pop-name { font-weight: 800; font-size: 15px; }
.pop-meta { color: var(--ink-dim); font-size: 12px; margin-top: 2px; }
.pop-link { color: var(--accent2); font-weight: 700; cursor: pointer; font-size: 13px; margin-top: 6px; display: inline-block; }
.pop-mine { color: var(--gold); font-weight: 700; font-size: 12px; margin-top: 6px; }

/* ---------- detail panel ---------- */
.detail {
  position: absolute; top: 0; right: 0; bottom: 0; width: min(440px, 92%); z-index: 600;
  background: var(--bg2); border-left: 1px solid var(--line); box-shadow: var(--shadow);
  overflow-y: auto; padding: 22px 22px 30px; transform: translateX(0);
}
.detail-close { position: absolute; top: 14px; right: 14px; width: 36px; height: 36px; border-radius: 10px;
  background: var(--panel); border: 1px solid var(--line); color: var(--ink); font-size: 16px; cursor: pointer; }
.d-name { font-size: 1.6rem; font-weight: 800; margin: 4px 40px 6px 0; line-height: 1.15; }
.d-loc { color: var(--ink-dim); font-size: 15px; }
.d-dates { display: inline-block; margin: 12px 0 8px; background: linear-gradient(90deg, rgba(177,75,255,.18), rgba(54,224,255,.18));
  border: 1px solid var(--accent); border-radius: 10px; padding: 8px 14px; font-weight: 700; }
.d-tags { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 14px; }
.d-section-h { font-size: 12px; text-transform: uppercase; letter-spacing: .12em; color: var(--ink-dim); margin: 18px 0 10px; }
.d-mine-banner { background: linear-gradient(90deg, rgba(255,210,77,.16), rgba(255,155,61,.10)); border: 1px solid var(--gold);
  border-radius: 12px; padding: 12px 14px; margin: 6px 0 4px; }
.d-mine-banner b { color: var(--gold); }
.lineup { display: flex; flex-wrap: wrap; gap: 8px; }
/* lineup chips — same look as the static festival pages (user preference 2026-07-08) */
.artist { font-size: 14px; padding: 6px 13px; border-radius: 20px; background: rgba(255,255,255,.06); border: 1px solid var(--line); color: var(--ink); }
.artist.add { cursor: pointer; transition: border-color .12s, background .12s; }
.artist.add:hover { border-color: #2ee6c8; }
.artist.mine { background: linear-gradient(120deg, rgba(177,75,255,.28), rgba(54,224,255,.2)); border-color: #2ee6c8; color: #fff; font-weight: 700; }
.artist.mine::after { content: " \2605"; color: var(--gold); }  /* ★ — a lost backslash once rendered this as "°5" (issue #26) */
.lu-hint { font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--ink-dim); font-size: 11px; }
.d-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; margin-top: 20px; }
.d-btn { display: inline-flex; align-items: center; gap: 8px; text-decoration: none;
  font-weight: 800; padding: 12px 20px; border-radius: 999px; }
.d-tickets { background: linear-gradient(90deg, var(--hot), var(--accent)); color: #fff; box-shadow: 0 8px 22px rgba(177,75,255,.32); }
.d-tickets:hover { filter: brightness(1.08); }
.d-stay, .d-fly, .d-ride { background: rgba(255,255,255,.06); color: var(--ink); border: 1px solid var(--line); font-size: 14px; padding: 11px 18px; }
.d-stay:hover, .d-fly:hover, .d-ride:hover { border-color: var(--accent2); background: rgba(255,255,255,.1); }
.d-officialsite { color: var(--accent2); font-weight: 700; text-decoration: none; font-size: 14px; }
.d-officialsite:hover { text-decoration: underline; }
.d-save { cursor: pointer; font-weight: 800; font-size: 14px; padding: 11px 18px; border-radius: 999px;
  background: var(--panel2); color: var(--ink); border: 1px solid var(--line); transition: border-color .12s, color .12s; }
.d-save:hover { border-color: var(--hot); color: var(--hot); }
.d-save.on { border-color: var(--hot); color: var(--hot); background: rgba(177,75,255,.1); }
.d-share { cursor: pointer; font-weight: 800; font-size: 14px; padding: 11px 18px; border-radius: 999px;
  background: rgba(255,255,255,.06); color: var(--ink); border: 1px solid var(--line); transition: border-color .12s, background .12s; }
.d-share:hover { border-color: var(--accent2); background: rgba(255,255,255,.1); }
.lineup-tba { color: var(--ink-dim); font-style: italic; }
/* map preview: about excerpt, est chip, "+N more", and the primary "Open full page" button */
.d-about { color: var(--ink-dim); font-size: 14px; line-height: 1.55; margin: 12px 0 2px; }
.d-est { color: var(--accent2); font-weight: 700; font-size: 13px; }
.d-camp { color: var(--mint, #2ee6c8); font-weight: 600; font-size: 13px; }
/* meta row under the date box — mirrors the festival page's meta line */
.d-meta { display: flex; flex-wrap: wrap; gap: 4px 18px; margin: 0 0 6px; color: #2ee6c8; font-weight: 600; font-size: 14px; }
.artist.more { color: var(--ink-dim); background: transparent; border-style: dashed; }
/* quiet, same recipe as Save festival — non-monetized actions stay secondary */
.d-full { background: var(--panel2); color: var(--ink); border: 1px solid var(--line); font-weight: 800; transition: border-color .12s, color .12s; }
.d-full:hover { border-color: var(--accent2); color: var(--accent2); }
/* festival photos (official og:image previews, hotlinked with credit) */
.d-photos { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 18px; }
.d-photos a { display: block; border-radius: 12px; overflow: hidden; border: 1px solid var(--line); }
.d-photos a:only-child { grid-column: 1 / -1; }
.d-photos img { display: block; width: 100%; height: 130px; object-fit: cover; }
.d-photos a:only-child img { height: 180px; }
.d-photo-credit { color: var(--ink-dim); font-size: 11px; margin-top: 6px; }

/* close (✕) buttons — dark like the map zoom buttons */
body.psy .detail-close, body.psy .modal-close {
  background: rgb(11,14,26); border: 1px solid var(--line); color: var(--ink);
}
body.psy .detail-close:hover, body.psy .modal-close:hover {
  background: var(--panel2); color: var(--accent2);
}

/* keep map controls below the detail panel (z=600) so they never overlap it */
.leaflet-top, .leaflet-bottom { z-index: 550; }

/* blend the attribution banner into the dark map */
body.psy .leaflet-control-attribution {
  background: rgba(11,14,26,.65); color: rgba(185,166,232,.55);
  font-size: 10px; padding: 2px 8px; border-radius: 8px 0 0 0;
}
body.psy .leaflet-control-attribution a { color: rgba(185,166,232,.7); }

/* map zoom buttons — dark to match the theme */
body.psy .leaflet-bar { border-color: var(--line); }
body.psy .leaflet-bar a {
  background: rgb(11,14,26); color: var(--ink); border-bottom-color: var(--line);
}
body.psy .leaflet-bar a:hover { background: var(--panel2); color: var(--accent2); }
body.psy .leaflet-bar a.leaflet-disabled { background: rgb(11,14,26); color: #4a4560; }

/* map marker tooltip */
.pin-tip { background: rgb(11,14,26); color: var(--ink); border: 1px solid var(--accent);
  border-radius: 10px; padding: 7px 11px; font-size: 13px; line-height: 1.35;
  box-shadow: 0 6px 18px rgba(0,0,0,.5); }
.pin-tip::before { display: none; }   /* drop leaflet's default white arrow */

/* facilities chips (camping / RV / water / …) in the detail panel */
.amens { display: flex; flex-wrap: wrap; gap: 8px; }
.amen { font-size: 13px; padding: 6px 11px; border-radius: 999px; background: var(--panel);
  border: 1px solid var(--line); color: var(--ink); }
.amen.yes { border-color: rgba(46,230,200,.45); }
.amen.no { color: var(--ink-dim); opacity: .7; }

/* ---------- connected pill + toast ---------- */
.connected-pill { position: fixed; left: 18px; bottom: 16px; z-index: 700; background: var(--panel); border: 1px solid var(--spotify);
  border-radius: 999px; padding: 8px 14px; font-size: 13px; display: flex; align-items: center; gap: 10px; box-shadow: var(--shadow); }
.connected-pill #connectedText b { color: var(--spotify); }
.link-btn { background: none; border: 0; color: var(--ink-dim); cursor: pointer; text-decoration: underline; font-size: 12px; }
.toast { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); z-index: 1600;
  background: var(--panel2); border: 1px solid var(--accent); color: var(--ink); padding: 12px 18px; border-radius: 12px;
  box-shadow: var(--shadow); font-size: 14px; max-width: 90vw; }

/* ---------- My Artists modal ---------- */
.modal { position: fixed; inset: 0; z-index: 1500; background: rgba(5,7,16,.72); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center; padding: 20px; }
/* the modal itself never scrolls — only the artist-chip list inside does */
.modal-card { position: relative; width: 100%; max-width: 560px; max-height: 92vh; overflow: hidden;
  display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--line); border-radius: 16px; padding: 24px; box-shadow: var(--shadow); }
.modal-close { position: absolute; top: 14px; right: 14px; width: 34px; height: 34px; border: 0; border-radius: 9px;
  background: var(--panel2); color: var(--ink); font-size: 15px; cursor: pointer; }
.wl-title { margin: 0 0 6px; font-size: 1.4rem; }
.wl-lead { color: var(--ink-dim); font-size: 13px; line-height: 1.5; margin: 0 0 16px; }
.wl-account { background: var(--bg); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; margin: 22px 0 16px; }
.wl-acct-row { display: flex; gap: 8px; }
.wl-acct-row input { flex: 1; padding: 9px 12px; border-radius: 10px; border: 1px solid var(--line); background: var(--panel); color: var(--ink); font: inherit; }
.wl-acct-row input:focus { outline: none; border-color: var(--accent); }
.wl-acct-hint { display: block; color: var(--ink-dim); font-size: 11.5px; line-height: 1.5; margin-top: 8px; }
.wl-acct-in { font-size: 14px; }
.wl-acct-in b { color: var(--accent2); }
.wl-acct-alerts { display: flex; align-items: center; gap: 8px; margin-top: 10px;
  font-size: 12.5px; color: var(--ink-dim); cursor: pointer; }
.wl-acct-alerts input { accent-color: var(--accent2); width: 15px; height: 15px; cursor: pointer; }

.wl-add-row { display: flex; gap: 8px; margin-bottom: 14px; }
.wl-add-row input, .wl-imp-row input { flex: 1; padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--bg); color: var(--ink); font: inherit; }
.wl-add-row input:focus, .wl-imp-row input:focus { outline: none; border-color: var(--accent); }
.wl-list { display: flex; flex-wrap: wrap; gap: 7px; min-height: 10px;
  max-height: 132px; overflow-y: auto; scrollbar-width: thin; padding-right: 2px; }
.wl-empty { color: var(--ink-dim); font-size: 13px; margin: 4px 0 0; }
.wl-chip { display: inline-flex; align-items: center; gap: 4px; background: var(--panel2); border: 1px solid var(--line);
  border-radius: 999px; padding: 5px 6px 5px 12px; font-size: 13px; }
.wl-chip.hit { border-color: var(--gold); }
.wl-chip.hit > span:first-child::before { content: "★ "; color: var(--gold); }
/* "Keep FestLocator ad-free" support link (footer on static pages, topbar button on the map).
   The ❤ alone flows through the My-Artists gradient (issue #30) — text stays quiet. */
.foot-donate .hrt, .btn-donate .hrt {
  background: linear-gradient(100deg, var(--accent), var(--accent2), #ff6a2b, var(--accent)) 0 0 / 300% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: psy-slide 9s linear infinite;
}
.btn-donate .lbl { white-space: nowrap; }
@media (max-width: 1150px) {   /* tight topbar: heart-only button, label in the tooltip */
  .btn-donate .lbl { display: none; }
  .btn-donate { padding: 10px 13px; font-size: 16px; }
}

/* ---------- calendar view (issue #35): swaps with the map, same filters ---------- */
/* map/calendar switch — bottom-left corner of the view, where the seed note used to live */
#viewSwitch { position: absolute; left: 394px; bottom: 14px; z-index: 590; display: flex; gap: 4px;
  padding: 4px; border-radius: 999px; background: rgba(11,14,26,.94); border: 1px solid var(--line);
  box-shadow: 0 8px 30px rgba(0,0,0,.45); }
#viewSwitch button { border: 0; border-radius: 999px; padding: 8px 18px; font-weight: 700; font-size: 13px;
  cursor: pointer; background: transparent; color: var(--ink-dim); white-space: nowrap;
  display: inline-flex; align-items: center; gap: 7px; }
#viewSwitch .vs-ic { flex: 0 0 auto; }
#viewSwitch button:not(.on) .vs-ic { opacity: .75; }
#viewSwitch button.on {
  background: linear-gradient(100deg, rgba(154,77,255,.45), rgba(46,230,200,.32)); color: #fff; }
#viewSwitch button:not(.on):hover { color: var(--ink); }
body.mapfull #viewSwitch { left: 14px; }
@media (max-width: 820px) { #viewSwitch { left: 14px; } }
#calWrap { display: none; }
body.calview #mapWrap { display: none; }
body.calview #calWrap { display: flex; flex-direction: column; min-height: 0; background: var(--bg); }
.cal-head { display: flex; align-items: center; justify-content: center; gap: 18px; padding: 12px 16px; }
#calTitle { font-size: 20px; font-weight: 800; min-width: 220px; text-align: center; text-transform: capitalize; }
.cal-nav { width: 38px; height: 38px; border-radius: 10px; background: var(--panel); border: 1px solid var(--line);
  color: var(--ink); font-size: 22px; cursor: pointer; line-height: 1; }
.cal-nav:hover { border-color: var(--accent); }
/* exit full-screen from the calendar (the map's ⛶/✕ lives in the hidden #mapWrap) */
.cal-exitfull { display: none; position: absolute; top: 12px; right: 12px; width: 38px; height: 38px;
  border-radius: 10px; background: rgba(11,14,26,.92); border: 1px solid var(--line);
  color: var(--ink); cursor: pointer; align-items: center; justify-content: center; z-index: 5; }
.cal-exitfull:hover { border-color: var(--accent); }
body.mapfull .cal-exitfull { display: flex; }
#calWrap { position: relative; }
.cal-wd { position: relative; height: 30px; margin: 0 26px; border-bottom: 1px solid var(--line); }
.tl-mk { position: absolute; top: 4px; font-size: 11px; letter-spacing: .22em; color: var(--ink-dim);
  border-left: 1px solid var(--line2, #3d3272); padding-left: 8px; }
#calGrid { flex: 1; overflow-y: auto; padding: 10px 26px 18px; }
.tl-rows { position: relative; min-height: 100%; }
.tl-line { position: absolute; top: 0; bottom: 0; border-left: 1px dashed rgba(61,50,114,.6); }
.tl-line.now { border-left: 1px dashed rgba(46,230,200,.55); }
.tl-row { position: relative; height: 34px; }
.tl-bar { position: absolute; top: 6px; height: 21px; border-radius: 11px; border: 0; cursor: pointer; padding: 0; }
.tl-bar.all { background: rgba(154,77,255,.28); box-shadow: inset 0 0 0 1px #5b2bb8; }
.tl-bar.all:hover { box-shadow: inset 0 0 0 1px var(--accent); }
.tl-bar.mine { background: linear-gradient(100deg, rgba(154,77,255,.6), rgba(46,230,200,.45));
  box-shadow: inset 0 0 0 1px var(--accent2), 0 0 14px rgba(46,230,200,.25); }
.tl-bar.sav { background: rgba(255,206,77,.32); box-shadow: inset 0 0 0 1px var(--gold); }
.tl-lbl { position: absolute; top: 8px; font-size: 14px; font-weight: 600; white-space: nowrap;
  cursor: pointer; text-shadow: 0 2px 10px rgba(0,0,0,.9); max-width: 34%; overflow: hidden;
  text-overflow: ellipsis; }
.tl-lbl.flip { text-align: right; }
.tl-lbl.all { color: #cfc8f2; } .tl-lbl.all:hover { color: var(--ink); }
.tl-lbl.mine { color: #c9fff2; } .tl-lbl.sav { color: #ffe9ad; }
.tl-empty { padding: 40px 0; text-align: center; color: var(--ink-dim); }
@media (max-width: 820px) {
  #calGrid { padding: 8px 12px 14px; }
  .cal-wd { margin: 0 12px; }
  .tl-lbl { font-size: 12px; max-width: 42%; }
  #calTitle { font-size: 16px; min-width: 150px; }
}

/* matched artists glow like the My Artists button (issue #18) */
body.psy .wl-chip.hit {
  background:
    linear-gradient(100deg, rgba(154,77,255,.4), rgba(46,230,200,.28), rgba(255,106,43,.22), rgba(154,77,255,.4))
      0 0 / 300% 100%,
    rgb(11,14,26);
  border-color: var(--accent);
  animation: psy-slide 9s linear infinite, psy-glow 4s ease-in-out infinite;
}
.wl-chip button { border: 0; background: transparent; color: var(--ink-dim); cursor: pointer; font-size: 16px; line-height: 1; padding: 0 3px; }
.wl-chip button:hover { color: var(--hot); }
.wl-summary { color: var(--gold); font-size: 13px; font-weight: 700; margin: 6px 0 2px; min-height: 10px; }
.wl-imports { border-top: 1px solid var(--line); margin-top: 8px; padding-top: 14px; }
.wl-imports-h { font-size: 12px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-dim); margin-bottom: 10px; }
/* Imports + account sections are <details>: expanded on desktop, collapsed by default on
   phones (app.js) so the whole dialog fits without clipping. Chevron replaces the marker. */
.wl-imports > summary, .wl-acct-guest > summary { cursor: pointer; list-style: none; user-select: none; }
.wl-imports > summary::-webkit-details-marker, .wl-acct-guest > summary::-webkit-details-marker { display: none; }
.wl-imports > summary::after, .wl-acct-guest > summary::after {
  content: "▸"; display: inline-block; margin-left: 7px; color: var(--ink-dim);
  font-size: 11px; transition: transform .15s; }
.wl-imports[open] > summary::after, .wl-acct-guest[open] > summary::after { transform: rotate(90deg); }
.wl-imports:not([open]) > summary, .wl-acct-guest:not([open]) > summary { margin-bottom: 0; }
/* import services as full-width rows (issue #45: the 3-card grid overflowed the
   dialog at narrow widths) — a single column of rows can't escape the modal */
.imp-list { display: flex; flex-direction: column; }
.imp-row { display: flex; align-items: flex-start; gap: 12px; padding: 11px 0;
  border-bottom: 1px solid rgba(255,255,255,.05); }
.imp-row:last-child { border-bottom: 0; padding-bottom: 4px; }
.imp-row:first-child { padding-top: 2px; }
.imp-name { flex: 0 0 128px; font-size: 14px; font-weight: 700; padding-top: 7px; white-space: nowrap; }
.imp-acts { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.imp-btn { padding: 8px 12px; font-size: 12.5px; border-radius: 9px; white-space: nowrap; }
.imp-acts > .imp-btn { align-self: stretch; }
.imp-inline { display: flex; gap: 6px; min-width: 0; }
.imp-inline input { flex: 1; min-width: 0; padding: 7px 10px; border-radius: 9px; font-size: 12.5px;
  border: 1px solid var(--line); background: var(--panel); color: var(--ink); font-family: inherit; }
.imp-inline input:focus { outline: none; border-color: var(--accent); }
@media (max-width: 480px) {
  .imp-row { flex-direction: column; gap: 6px; }
  .imp-name { flex: none; padding-top: 0; }
  .imp-acts { width: 100%; }
  /* phones: if the dialog still outgrows the screen (long artist list, keyboard up),
     scroll the card rather than clipping the bottom */
  .modal-card { overflow-y: auto; }
}
.wl-acct-h { font-size: 12px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-dim); font-weight: 700; margin-bottom: 10px; }
.wl-imp-btns { display: flex; flex-wrap: wrap; gap: 8px; }
.beta { font-size: 10px; background: rgba(0,0,0,.25); border-radius: 5px; padding: 1px 5px; margin-left: 2px; text-transform: uppercase; letter-spacing: .04em; }
.wl-note { color: var(--ink-dim); font-size: 11.5px; line-height: 1.5; margin: 12px 0 0; }
.wl-foot { margin-top: 16px; text-align: right; }
.count-pill { background: rgba(0,0,0,.28); border-radius: 999px; padding: 0 7px; font-size: 12px; margin-left: 2px; }

/* ---------- site footer ---------- */
#sitefoot { flex: 0 0 auto; height: 30px; display: flex; align-items: center; justify-content: space-between;
  padding: 0 18px; font-size: 12px; color: var(--ink-dim); border-top: 1px solid var(--line); background: var(--bg); z-index: 750; }
#sitefoot nav { display: flex; align-items: center; gap: 18px; }
/* language picker (topbar, shows the language code) */
.lang-sel { background: rgba(11,14,26,.92); color: var(--ink-dim); border: 1px solid var(--line);
  border-radius: 999px; padding: 9px 10px; font-size: 13px; font-weight: 700;
  font-family: inherit; cursor: pointer; }
.lang-sel:hover { color: var(--ink); border-color: var(--accent); }
.lang-sel:focus { outline: none; border-color: var(--accent); }
#sitefoot a { color: var(--ink-dim); text-decoration: none; }
#sitefoot a:hover { color: var(--accent2); }
.foot-attr { display: inline-flex; align-items: center; gap: 6px; }
.foot-attr .sp-logo-sm { width: 14px; height: 14px; fill: var(--spotify); flex: 0 0 auto; }
.foot-credit { color: var(--ink-dim); opacity: .85; }
.foot-credit a { text-decoration: underline; }
@media (max-width: 640px) { #sitefoot { font-size: 11px; padding: 0 10px; }
  #sitefoot nav { gap: 12px; } }

/* ---------- legal / privacy page ---------- */
.legal h2 { margin: 26px 0 8px; font-size: 1.15rem; color: var(--accent2); }
.legal p, .legal li { color: var(--ink-dim); line-height: 1.6; }
.legal ul { padding-left: 20px; }
.legal a { color: var(--accent2); }
.legal .updated { font-size: 13px; color: var(--ink-dim); opacity: .8; }

/* ---------- scrollbars ---------- */
#sidebar::-webkit-scrollbar, .detail::-webkit-scrollbar { width: 10px; }
#sidebar::-webkit-scrollbar-thumb, .detail::-webkit-scrollbar-thumb { background: #2c3768; border-radius: 8px; }

/* ---------- submission form page ---------- */
body.page-form { display: block; overflow: auto; background: radial-gradient(1200px 600px at 70% -10%, #1a1030, var(--bg) 60%); }
.form-wrap { max-width: 760px; margin: 28px auto 60px; padding: 0 18px; }
.form-card { background: var(--panel); border: 1px solid var(--line); border-radius: 18px; padding: clamp(22px, 4vw, 40px); box-shadow: var(--shadow); }
.form-card h1 { margin: 0 0 8px; font-size: clamp(1.7rem, 1rem + 2vw, 2.4rem); }
.form-card h1 + .form-lead { color: var(--ink-dim); margin: 0 0 22px; line-height: 1.55; }
.field { display: flex; flex-direction: column; gap: 7px; margin-bottom: 16px; }
.field > span { font-size: 14px; font-weight: 700; color: var(--ink); }
.field > span i { color: var(--hot); font-style: normal; }
.field > span small { font-weight: 500; color: var(--ink-dim); }
.field input, .field textarea {
  font: inherit; font-size: 15px; padding: 11px 13px; border-radius: 10px;
  background: var(--bg2); border: 1px solid var(--line); color: var(--ink); width: 100%;
}
.field input:focus, .field textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(177,75,255,.2); }
.field textarea { resize: vertical; }
.field-row { display: flex; gap: 14px; }
.field-row .field { flex: 1; }
.pick-map { height: 240px; border-radius: 12px; overflow: hidden; border: 1px solid var(--line); cursor: crosshair; }
.latlng-row { display: flex; gap: 10px; margin-top: 8px; align-items: center; flex-wrap: wrap; }
.latlng-row input { flex: 1; min-width: 120px; }
.latlng-readout { font-size: 12px; color: var(--ink-dim); white-space: nowrap; }
.chip-group { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { cursor: pointer; user-select: none; font-size: 13px; font-weight: 600; padding: 7px 13px;
  border-radius: 999px; background: var(--panel2); border: 1px solid var(--line); color: var(--ink-dim); }
.chip.on { background: linear-gradient(90deg, rgba(177,75,255,.25), rgba(54,224,255,.2)); border-color: var(--accent); color: var(--ink); }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.form-err { color: var(--hot); font-size: 14px; min-height: 18px; margin-bottom: 8px; font-weight: 600; }
.btn-lg { padding: 13px 24px; font-size: 16px; }
#submitBtn { width: 100%; justify-content: center; }
.thanks { text-align: center; padding: 20px 0; }
.thanks-ic { font-size: 54px; }
.thanks h2 { margin: 6px 0; }
.thanks p { color: var(--ink-dim); margin-bottom: 18px; }
.thanks .btn { margin-right: 12px; }

/* ============================================================
   PSYCHEDELIC THEME — active when <body> has the .psy class
   (✦ Psy button in the topbar; persisted in localStorage fl_theme)
   ============================================================ */
body.psy {
  --bg: #0e0526;
  --bg2: #160a36;
  --panel: #1e0d45;
  --panel2: #2a1260;
  --line: #5b2bb8;
  --ink: #f4f0ff;
  --ink-dim: #b9a6e8;
  --accent: #9a4dff;     /* electric violet */
  --accent2: #2ee6c8;    /* deep teal */
  --hot: #ff6a2b;        /* burnt orange */
  --gold: #ffb52e;       /* amber */
  --shadow: 0 16px 40px rgba(30,5,70,.6);
  /* the pin-eye: psychedelic eye with a map-pin tail (tip at bottom center) */
  --pin-eye: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 46"><path d="M13 23 L20 44 L27 23 Z" fill="%235b2bb8" stroke="%232a1260" stroke-width="1.2"/><path d="M2 14 Q20 -5 38 14 Q20 33 2 14 Z" fill="%23f4f0ff" stroke="%232a1260" stroke-width="1.6"/><circle cx="20" cy="14" r="9.5" fill="%23ff6a2b"/><circle cx="20" cy="14" r="7.4" fill="%23ffb52e"/><circle cx="20" cy="14" r="5.6" fill="%232ee6c8"/><circle cx="20" cy="14" r="3.8" fill="%239a4dff"/><circle cx="20" cy="14" r="2" fill="%2312042e"/><circle cx="18.9" cy="12.9" r=".8" fill="%23fff"/></svg>');
  --pin-eye-gold: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 46"><path d="M13 23 L20 44 L27 23 Z" fill="%23a06a00" stroke="%235a3a00" stroke-width="1.2"/><path d="M2 14 Q20 -5 38 14 Q20 33 2 14 Z" fill="%23fff6dd" stroke="%235a3a00" stroke-width="1.6"/><circle cx="20" cy="14" r="9.5" fill="%23ff9b3d"/><circle cx="20" cy="14" r="7.4" fill="%23ffd24d"/><circle cx="20" cy="14" r="5.6" fill="%23f6ff00"/><circle cx="20" cy="14" r="3.8" fill="%23ff6a2b"/><circle cx="20" cy="14" r="2" fill="%232a1a00"/><circle cx="18.9" cy="12.9" r=".8" fill="%23fff"/></svg>');
}

/* small inline pin-eye used instead of the 📍 emoji on cards / detail / tooltips */
.pin-ic { display: inline-block; width: 12px; height: 14px; vertical-align: -2px;
  background: var(--pin-eye) center/contain no-repeat; }

@keyframes psy-slide { from { background-position: 0% 50%; } to { background-position: 300% 50%; } }
@keyframes psy-hue   { to { filter: hue-rotate(360deg); } }
@keyframes psy-glow  { 0%,100% { box-shadow: 0 0 10px rgba(154,77,255,.45); }
                       50%     { box-shadow: 0 0 24px rgba(46,230,200,.5); } }
/* chrome: "festival-page clean" (2026-07-08 review) — flat near-black bars with thin
   violet borders, matching the static festival pages. The psy character now lives in
   the CONTENT (eye pins, gradient wordmark, genre chips), not the chrome. The old
   squiggle/nebula chrome layers were reviewed as too busy and removed. */
body.psy #topbar {
  background: #0b0e1a;
  animation: none;
  border-bottom: 1px solid #2b2454;
}
body.psy #toolbar { background: #0b0e1a; border-bottom: 1px solid #2b2454; }
body.psy .brand-text small { color: #cfc8ea; }
body.psy .brand .logo {
  font-size: 0; width: 46px; height: 52px; line-height: 0;
  /* clean-theme brand: bigger mark, no glow — just a soft grounding shadow */
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.5));
}
/* the blink is a real eyelid: a closed-lid overlay inside the SVG flashes visible.
   Only the eye closes — the pin below never moves. One single + one quick double per 9s. */
.pin-eye .lid { opacity: 0; animation: eye-blink 9s linear infinite; }
@keyframes eye-blink {
  0%, 40.5%, 43.5%, 82.5%, 85.5%, 90.5%, 93.5%, 100% { opacity: 0; }
  41%, 43%, 83%, 85%, 91%, 93% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .pin-eye .lid { animation: none; }
}
body.psy .brand-text strong, body.psy .d-name, body.psy .wl-title, body.psy .form-card h1 {
  font-family: "Righteous", var(--sans); font-weight: 400; letter-spacing: .8px;
}
/* wordmark gradient — fixed violet→teal, identical to the static festival pages */
body.psy .brand-text .accent {
  background: linear-gradient(90deg, #9a4dff, #2ee6c8);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* topbar ghost buttons (+ Add a festival, Back to map): dark opaque over the nebula */
body.psy #topbar .btn-ghost { background: rgba(11,14,26,.92); }

/* primary action buttons (My Artists, Add, Submit festival):
   dark glass with a slow-flowing violet/teal/ember gradient */
body.psy .btn-accent {
  background:
    linear-gradient(100deg, rgba(154,77,255,.4), rgba(46,230,200,.28), rgba(255,106,43,.22), rgba(154,77,255,.4))
      0 0 / 300% 100%,
    rgb(11,14,26);
  border: 1px solid var(--accent); color: var(--ink); box-shadow: none;
  animation: psy-slide 9s linear infinite, psy-glow 4s ease-in-out infinite;
}
body.psy #search:focus { border-color: var(--accent2); box-shadow: 0 0 0 3px rgba(46,230,200,.22); }
body.psy .mine-toggle:not(.past-toggle) { background: linear-gradient(90deg, rgba(154,77,255,.2), rgba(46,230,200,.16)); }

/* sidebar + panels: flat, like the festival pages (squiggles/nebula removed) */
body.psy #sidebar { background: var(--bg); }
body.psy .form-card { background: rgb(11,14,26); }  /* Add-a-festival + privacy card */
body.psy .modal-card { background: rgb(11,14,26); }
body.psy .detail { background: rgb(11,14,26); box-shadow: none; }
/* the open detail panel casts the same 26px gradient shadow onto the map as the
   sidebar does (strip pinned to the panel's left edge, under the pins) */
body.psy #app:has(.detail:not(.hidden))::after {
  content: ""; position: absolute; top: 0; bottom: 0;
  right: min(440px, 92%); width: 26px; z-index: 550; pointer-events: none;
  background: linear-gradient(270deg, rgba(0,0,0,.45), transparent);
}
@media (max-width: 820px) {
  body.psy #app:has(.detail:not(.hidden))::after { display: none; }  /* panel is full-width on mobile */
}
body.psy #search { background: rgb(11,14,26); }

/* cards + tags: bioluminescent glow */
body.psy .fest-card { background: rgba(255,255,255,.045); }  /* flat panel, like festival-page nodes */
body.psy .fest-card:hover { border-color: var(--accent2);
  box-shadow: 0 0 14px rgba(46,230,200,.3), 0 0 30px rgba(154,77,255,.2); }
body.psy .fest-card.active { border-color: var(--accent2);
  box-shadow: 0 0 0 1px var(--accent2), 0 0 24px rgba(46,230,200,.3); }
body.psy .tag.genre { border-color: rgba(46,230,200,.4); background: rgba(46,230,200,.08); }

/* map: hue-shifted tiles + rainbow pins */
body.psy #map { background: #0b041f; }
/* land near-black (like the topbar #0b0e1a) while the nebula gradient overlay above
   keeps the color; tuned by sampling land pixels against the topbar value */
body.psy .leaflet-tile { filter: brightness(1.75) sepia(.75) hue-rotate(200deg) saturate(2.2) brightness(.32) contrast(1.08); }
/* subtle shadow the sidebar casts onto the map's left edge (under the pins) */
body.psy #mapWrap::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: 26px; z-index: 460; pointer-events: none;
  background: linear-gradient(90deg, rgba(0,0,0,.45), transparent); }

/* nebula glow over the tiles, under the pins (leaflet marker pane is z=600) */
body.psy #mapWrap::after { content: ""; position: absolute; inset: 0; z-index: 450;
  pointer-events: none; mix-blend-mode: screen;
  background:
    radial-gradient(55% 75% at 72% 18%, rgba(46,230,200,.22), transparent 62%),
    radial-gradient(65% 85% at 15% 85%, rgba(255,106,43,.18), transparent 60%),
    radial-gradient(80% 100% at 40% 45%, rgba(110,40,220,.35), transparent 70%);
  background-size: 160% 160%, 160% 160%, 140% 140%;
  animation: psy-nebula 26s ease-in-out infinite;
}
@keyframes psy-nebula { 0%,100% { background-position: 0% 0%, 100% 100%, 50% 50%; }
                        50%     { background-position: 40% 30%, 60% 60%, 30% 60%; } }
/* markers are pin-eyes; the tail tip lands exactly on the divIcon anchor:
   box 26x26, anchor [13,26] → a 28x32 pin at margin -6px/-1px puts the tip there */
body.psy .pin {
  width: 28px; height: 32px; margin: -6px 0 0 -1px;
  border: 0; border-radius: 0; box-shadow: none;
  transform: none; transform-origin: 50% 100%;
  background: var(--pin-eye) center/contain no-repeat;
  filter: drop-shadow(0 2px 5px rgba(0,0,0,.65));
}
body.psy .pin.mine { background-image: var(--pin-eye-gold); }
body.psy .pin.past { filter: grayscale(.85) opacity(.55) drop-shadow(0 2px 5px rgba(0,0,0,.5)); }
body.psy .pin.active { transform: scale(1.35);
  filter: drop-shadow(0 0 7px #2ee6c8) drop-shadow(0 2px 5px rgba(0,0,0,.5)); }

/* detail + modal */
/* Get tickets = My Artists twin (user pick 2026-07-08): dark glass, flowing gradient,
   violet border, white text at the same 700 weight (the .d-btn 800 read too thick) */
body.psy .d-tickets, body.psy .d-money {
  background:
    linear-gradient(100deg, rgba(154,77,255,.4), rgba(46,230,200,.28), rgba(255,106,43,.22), rgba(154,77,255,.4))
      0 0 / 300% 100%,
    rgb(11,14,26);
  border: 1px solid var(--accent); color: var(--ink); box-shadow: none; font-weight: 700;
  animation: psy-slide 9s linear infinite, psy-glow 4s ease-in-out infinite;
}
.d-tickets .tik, .d-money .tik { flex: 0 0 auto; }
.d-actions .d-tickets { flex: 1 1 100%; justify-content: center; }
body.psy .modal { background: rgba(10,3,30,.78); }

/* accessibility: no motion for users who opt out */
@media (prefers-reduced-motion: reduce) {
  body.psy, body.psy * { animation: none !important; }
}

/* mobile: filters collapse behind a toggle button (hidden on desktop) */
.filter-toggle { display: none; }

/* ---------- responsive ---------- */
@media (max-width: 820px) {
  /* z 1300: the dropdown must beat Leaflet's internal controls (z up to 1000) */
  #topbar { position: relative; z-index: 1300; flex-wrap: wrap; height: auto; padding: 10px 14px; gap: 10px; }
  .seed-note { display: none; }             /* too crowded on phones; caveat stays on desktop */
  /* row 2: search + the Filters toggle share the line */
  .search-box { order: 3; flex: 1 1 calc(100% - 116px); max-width: none; min-width: 0; }
  .brand { flex: 1; }
  /* top actions live behind the hamburger (top-right) */
  .hamb { display: flex; }
  .top-actions { display: none; position: absolute; top: 100%; right: 10px; z-index: 1200;
    flex-direction: column; align-items: stretch; gap: 8px; padding: 12px;
    background: rgb(11,14,26); border: 1px solid var(--line); border-radius: 14px;
    box-shadow: 0 18px 50px rgba(0,0,0,.6); min-width: 240px; }
  .top-actions.open { display: flex; }
  .top-actions .btn { justify-content: flex-start; }
  .btn-donate .lbl { display: inline; }     /* the menu has room for the full label */
  .btn-donate { padding: 10px 18px; font-size: 14px; }
  .filter-toggle { display: inline-flex; align-items: center; gap: 6px; height: 42px; order: 4;
    flex: 0 0 auto; padding: 0 14px; border-radius: 999px; background: rgb(11,14,26); color: var(--ink);
    border: 1px solid var(--line); font-size: 14px; font-family: inherit; cursor: pointer; }
  .filter-toggle .ft-arrow { transition: transform .15s; }
  #filterToggle[aria-expanded="true"] .ft-arrow { transform: rotate(180deg); }
  #filterToggle[aria-expanded="true"] { border-color: var(--accent); }
  #toolbar .filters { display: none; flex-basis: 100%; }
  #toolbar.filters-open .filters { display: flex; }
  #app { grid-template-columns: 1fr; grid-template-rows: 1fr; }
  /* mobile: map full, list as a bottom sheet toggle */
  #sidebar { position: absolute; inset: auto 0 0 0; height: 46%; z-index: 15; border-right: 0; border-top: 1px solid var(--line);
    border-radius: 16px 16px 0 0; }
  #mapWrap { grid-row: 1; }
  .detail { width: 100%; }
  .toolbar, #toolbar { flex-wrap: wrap; height: auto; padding: 8px 14px; gap: 8px; }
  .result-meta { width: 100%; }
  .welcome-steps { grid-template-columns: 1fr; }
  .welcome-card { padding: 26px 20px 22px; }
}

/* ===== first-visit onboarding overlay ===== */
.welcome { position: fixed; inset: 0; z-index: 1800; background: rgba(5,7,16,.78); backdrop-filter: blur(5px);
  display: flex; align-items: center; justify-content: center; padding: 20px; }
.welcome.hidden { display: none; }
.welcome-card { position: relative; width: 100%; max-width: 620px; max-height: 90vh; overflow-y: auto;
  background: radial-gradient(700px 320px at 80% -20%, rgba(177,75,255,.22), transparent 60%), var(--panel);
  border: 1px solid var(--line); border-radius: 22px; padding: 34px 34px 26px; box-shadow: var(--shadow);
  text-align: center; animation: wc-pop .28s cubic-bezier(.2,.9,.3,1.2); }
@keyframes wc-pop { from { transform: translateY(14px) scale(.97); opacity: 0; } to { transform: none; opacity: 1; } }
.welcome-badge { width: 54px; height: 54px; margin: 0 auto 14px; border-radius: 16px; font-size: 26px;
  display: flex; align-items: center; justify-content: center; color: #fff;
  background: linear-gradient(135deg, var(--accent), var(--accent2)); box-shadow: 0 10px 28px rgba(177,75,255,.4); }
.welcome-card h2 { margin: 0 0 8px; font-size: 26px; line-height: 1.15; }
.welcome-card h2 .accent { background: linear-gradient(90deg, var(--accent), var(--accent2));
  -webkit-background-clip: text; background-clip: text; color: transparent; }
.wc-lead { margin: 0 auto 22px; max-width: 460px; color: var(--ink-dim); font-size: 15px; }
.welcome-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 0 0 24px; text-align: left; }
.wc-step { background: rgba(255,255,255,.04); border: 1px solid var(--line); border-radius: 14px; padding: 14px 14px 16px;
  display: flex; flex-direction: column; gap: 4px; }
.wc-step .wc-ic { font-size: 24px; }
.wc-step b { font-size: 14px; }
.wc-step small { color: var(--ink-dim); font-size: 12px; line-height: 1.35; }
.welcome-actions { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }
.welcome-actions .btn { font-size: 15px; padding: 13px 22px; }
.wc-skip { display: inline-block; margin-top: 16px; font-size: 13px; }

/* the footer dragonfly — a quiet resident; wings flutter for a beat every ~11s */
.dfly { vertical-align: -5px; margin-left: 10px; opacity: .55; }
.dfly-wings { transform-origin: 24px 11px; animation: dfly-flutter 11s ease-in-out infinite; }
@keyframes dfly-flutter {
  0%, 87%, 100% { transform: scaleY(1); }
  89%, 93%, 97% { transform: scaleY(.55); }
  91%, 95% { transform: scaleY(1.12); }
}
@media (prefers-reduced-motion: reduce) { .dfly-wings { animation: none; } }

/* marker clusters — the brand eye-pin, sized by crowd, with a count badge */
.fl-cluster-wrap { background: none; }
.fl-cluster {
  width: 100%; height: 100%; position: relative;
  background: var(--pin-eye) center/contain no-repeat;
  filter: drop-shadow(0 2px 5px rgba(0,0,0,.55));
}
.fl-cluster .cnt {
  position: absolute; top: -7px; right: -10px; min-width: 21px; height: 21px;
  padding: 0 5px; border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 12px; color: var(--ink); line-height: 1;
  background: linear-gradient(120deg, rgba(154,77,255,.55), rgba(46,230,200,.4)), rgb(11,14,26);
  border: 1.5px solid #9a4dff;
  box-shadow: 0 0 10px rgba(154,77,255,.5), 0 1px 4px rgba(0,0,0,.5);
}
.fl-cluster.mid .cnt { border-color: #2ee6c8; box-shadow: 0 0 10px rgba(46,230,200,.45), 0 1px 4px rgba(0,0,0,.5); }
.fl-cluster.big .cnt { border-color: #ffb52e; font-size: 13px;
  box-shadow: 0 0 12px rgba(255,181,46,.45), 0 1px 4px rgba(0,0,0,.5); }

/* mobile footer: one near-invisible row — © + the essential links only
   (credits/disclosure remain on desktop + every festival page) */
@media (max-width: 700px) {
  #sitefoot { height: 20px; padding: 0 10px; gap: 10px; font-size: 9.5px;
    justify-content: center; overflow: hidden; }
  #sitefoot .dfly, #sitefoot .foot-credit { display: none; }
  #sitefoot nav { gap: 10px; }
}

.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
