/* ------------------------------------------------------------------
   My Fantasy Fest — shared design system

   Night is the identity: near-black with a violet cast, neon pink, violet,
   teal and electric blue. Dark is the DEFAULT, not the alternative — a page
   with no preference expressed still gets night.

   Day exists for one reason: this is an outdoor tool, and a neon-on-black
   map is unreadable in Key West sun at 2pm. It keeps the same accents,
   darkened to hold contrast on paper.

   Every colour is a token on :root first, then redefined per theme state, so
   nothing renders one theme's text on the other's ground.
   ------------------------------------------------------------------ */
:root{
  /* ---- night (default) ---- */
  /* --bg doubles as the island fill, so it has to sit clearly above --water
     or the map reads as one black rectangle. Water goes navy, land violet. */
  --bg:#0a0714; --surface:#140e21; --surface2:#1e162e; --border:#372549;
  --street:#31234a; --street-major:#553c80; --street-edge:#7658a6;
  --water:#03101f; --park:#11241c; --beach:#241d2e; --cem:#171226;
  --bldg:#1b1129; --bldg-edge:#4a3269; --district:#8a76ab;
  --ink:#f4eefc; --muted:#a493bd; --faint:#b9a6ce;
  --amber:#ffb020; --flamingo:#ff2e88; --violet:#b06bff; --cyan:#00e5d0; --mint:#2ee6a8;
  --lime:#c2f24a; --blue:#5c8cff;
  --shadow:0 10px 40px rgba(0,0,0,.7);
  --glow:0 0 10px currentColor;
  --maxw:1080px;
  /* the smallest thing a thumb should have to hit */
  --tap:44px;
  color-scheme:dark;
}
/* Daylight, ONLY when the reader picks it from the toggle.

   Deliberately not wired to prefers-color-scheme. Most phones sit on light all
   day, and a visitor whose phone does would otherwise never see what this site
   actually looks like. Night is the brand; daylight is the escape hatch for
   reading the map in the sun, and it stays opt-in. */
:root[data-theme="light"]{
  --bg:#f4f0f7; --surface:#ffffff; --surface2:#ebe4f2; --border:#c8bad8;
  --street:#ffffff; --street-major:#ffffff; --street-edge:#9c8ab2;
  --water:#bacfe6; --park:#cbdec2; --beach:#e8dcc4; --cem:#dcd3e3;
  --bldg:#ddd3e7; --bldg-edge:#9784af; --district:#7e6c97;
  --ink:#140b1d; --muted:#54475f; --faint:#64536f;
  --amber:#8a5008; --flamingo:#b8005a; --violet:#5d16bd; --cyan:#0a6069; --mint:#0a5f42;
  --lime:#455e0c; --blue:#1d3cb8;
  --shadow:0 6px 24px rgba(40,20,60,.18);
  --glow:none;
  color-scheme:light;
}

/* ---------- typefaces ----------
   All self-hosted. Google Fonts was a render-blocking request to a third party
   on every page load, which is the worst kind of dependency for an audience on
   hotel wi-fi — and it fails outright on a network that blocks Google. These
   are the same faces, served from the same folder as everything else.

   The two wordmark faces are subsetted to the fifteen letters of
   "My Fantasy Fest": Bungee 14 KB -> 1.1 KB, Great Vibes 42 KB -> 3.4 KB. They
   contain ONLY those letters, so using them for other text gives blanks.

   All four families are OFL; the licences ship in this folder.
   font-display:swap so text is readable immediately and reflows when the face
   arrives, rather than sitting invisible. */
@font-face{font-family:"MFF Script";src:url(fonts/great-vibes-wordmark.woff2) format("woff2");
  font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"MFF Sign";src:url(fonts/bungee-wordmark.woff2) format("woff2");
  font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:Anton;src:url(fonts/anton.woff2) format("woff2");
  font-weight:400;font-style:normal;font-display:swap}
/* variable weight axis: one file covers every weight the site uses */
@font-face{font-family:Karla;src:url(fonts/karla.woff2) format("woff2-variations");
  font-weight:100 900;font-style:normal;font-display:swap}
@font-face{font-family:"IBM Plex Mono";src:url(fonts/plexmono.woff2) format("woff2");
  font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"IBM Plex Mono";src:url(fonts/plexmono-600.woff2) format("woff2");
  font-weight:600;font-style:normal;font-display:swap}

*{box-sizing:border-box}
[hidden]{display:none!important}
html,body{margin:0;padding:0}
/* 17px base, not 16: a good part of this group is over fifty and reading it
   outdoors at night. Everything else is sized off this. */
body{background:var(--bg);color:var(--ink);
  font-family:Karla,system-ui,-apple-system,"Segoe UI",sans-serif;font-size:17px;line-height:1.55;
  -webkit-text-size-adjust:100%}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
a{color:inherit}
:focus-visible{outline:2px solid var(--flamingo);outline-offset:2px;border-radius:4px}
img{max-width:100%}

/* ---------- site chrome ----------
   Phone: a slim title bar at the top and the navigation as a tab bar at the
   bottom, in the thumb zone. Desktop: one conventional bar across the top.
   Nothing important lives in a top corner on a phone, because top corners are
   where a browser's own chrome, a notch, or an embedding app covers you. */
.sitebar{position:sticky;top:0;z-index:60;background:var(--surface);
  border-bottom:1px solid var(--border);padding-top:env(safe-area-inset-top,0px);
  -webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}
.sitebar .inner{max-width:var(--maxw);margin:0 auto;padding:8px 16px;display:flex;align-items:center;gap:14px}
/* ---------- the wordmark ----------
   Two voices on one sign, which is how the good neon on Duval is lettered:
   a cursive script for "My" and a fat signage face for FANTASY FEST. */
.wordmark{display:flex;flex-direction:column;gap:2px;text-decoration:none;flex:0 0 auto;min-width:0}
.wordmark b{display:flex;align-items:baseline;gap:5px;font-weight:400;line-height:1;white-space:nowrap;
  font-size:19px}
.wordmark .my{font-family:"MFF Script",cursive;font-size:1.9em;line-height:.8;color:var(--flamingo);
  position:relative;top:.05em;padding-right:.04em;
  text-shadow:0 0 5px color-mix(in srgb,var(--flamingo) 70%,transparent),
              0 0 16px color-mix(in srgb,var(--flamingo) 55%,transparent)}
.wordmark .ff{font-family:"MFF Sign",Anton,Impact,sans-serif;font-size:.86em;letter-spacing:.005em;
  text-transform:uppercase;color:var(--ink);
  text-shadow:0 0 10px color-mix(in srgb,var(--cyan) 42%,transparent)}
:root[data-theme="light"] .wordmark .my,
:root[data-theme="light"] .wordmark .ff{text-shadow:none}
.wordmark .tagline{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:9px;letter-spacing:.17em;
  text-transform:uppercase;color:var(--faint);white-space:nowrap}

.sitenav{margin-left:auto;min-width:0;display:flex;gap:2px;align-items:center}
.sitenav a{flex:0 0 auto;text-decoration:none;font-size:15px;padding:9px 13px;border-radius:9px;
  color:var(--muted);white-space:nowrap;display:flex;align-items:center;gap:6px}
.sitenav a .ico{display:none}
.sitenav a:hover{background:var(--surface2);color:var(--ink)}
.sitenav a[aria-current="page"]{background:var(--surface2);color:var(--ink);font-weight:700;
  box-shadow:inset 0 0 0 1px var(--border)}
.sitenav .count{font-family:"IBM Plex Mono",monospace;font-size:11px;min-width:17px;height:17px;
  border-radius:99px;background:var(--flamingo);color:#fff;display:none;place-items:center;padding:0 5px}
.sitenav .count.on{display:grid}
.themebtn{flex:0 0 auto;width:var(--tap);height:var(--tap);display:grid;place-items:center;
  border:1px solid var(--border);border-radius:10px;background:var(--surface2);font-size:15px;color:var(--muted)}

@media (max-width:719px){
  /* extra top padding because the script's swash rises well above its line
     box — with the tight line-height it needs the bar to give it room */
  .sitebar .inner{padding:12px 14px 8px;gap:10px}
  .wordmark b{font-size:16.5px}
  .wordmark .tagline{font-size:8.5px;letter-spacing:.13em}
  /* the toggle is a utility, not a feature — it should not compete with the
     wordmark for the only two things in the top bar */
  .themebtn{border-color:transparent;background:none;width:40px;height:40px;font-size:16px}
  /* the nav leaves the top bar entirely and becomes a bottom tab bar */
  .sitenav{position:fixed;left:0;right:0;bottom:0;z-index:70;margin:0;background:var(--surface);
    border-top:1px solid var(--border);display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:0;
    padding:4px 4px calc(4px + env(safe-area-inset-bottom,0px));
    box-shadow:0 -6px 24px rgba(0,0,0,.35)}
  .sitenav a{flex-direction:column;gap:3px;justify-content:center;padding:7px 1px 6px;border-radius:10px;
    font-size:9.5px;letter-spacing:.03em;text-transform:uppercase;min-height:var(--tap);position:relative}
  .sitenav a .ico{display:block;font-size:17px;line-height:1}
  .sitenav a .wide{display:none}
  .sitenav a[aria-current="page"]{background:none;color:var(--flamingo);box-shadow:none}
  .sitenav a[aria-current="page"] .ico{text-shadow:var(--glow)}
  .sitenav .count{position:absolute;top:1px;right:calc(50% - 22px);font-size:10px}
  /* room for the tab bar so the last line of every page stays readable */
  body{padding-bottom:calc(60px + env(safe-area-inset-bottom,0px))}
}
@media (min-width:720px){
  .sitenav a .narrow{display:none}
}

.unofficial{background:var(--bg);border-bottom:1px solid var(--border);
  font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.05em;color:var(--faint);text-align:center;
  padding:5px 16px;line-height:1.4}
.unofficial b{color:var(--muted);font-weight:400}

/* ---------- layout ----------
   Sections are generously spaced on purpose. The first version of this site
   put everything within a thumb's reach of everything else and read as a wall. */
/* Sections are deliberately far apart and the measure is deliberately short.
   The complaint every round has been that it feels packed, and the cause is
   almost always the same two things: not enough air between blocks, and lines
   of text running too wide to scan. */
/* padding-INLINE only. `padding:0 22px` here is more specific than the
   `section{padding-block:...}` rule below, so it was silently zeroing every
   section's vertical spacing — which is why the page kept reading as packed
   however much air I added to that rule. */
.wrap{max-width:var(--maxw);margin:0 auto;padding-inline:22px}
.wrap.narrow{max-width:700px}
section{padding-block:clamp(46px,9vw,76px)}
h1,h2,h3{text-wrap:balance;margin:0 0 .5em}
h1{font-family:Anton,Impact,sans-serif;font-weight:400;font-size:clamp(38px,10vw,68px);line-height:.98;
  letter-spacing:.01em;text-transform:uppercase}
h1 em{font-style:normal;color:var(--flamingo);text-shadow:var(--glow)}
h2{font-family:Anton,Impact,sans-serif;font-weight:400;font-size:clamp(25px,5.4vw,34px);line-height:1.08;
  text-transform:uppercase;letter-spacing:.02em}
h3{font-size:19px;font-weight:700;line-height:1.25}
p{margin:0 0 1.1em;max-width:60ch}
.lede{font-size:clamp(17px,2.1vw,19px);color:var(--muted);max-width:50ch;line-height:1.6}
.eyebrow{font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--violet);margin:0 0 14px}
.rule{height:1px;background:var(--border);border:0;margin:0}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;border:1px solid var(--border);
  background:var(--surface2);border-radius:12px;padding:12px 20px;font-size:16px;font-weight:700;
  text-decoration:none;min-height:var(--tap)}
.btn.primary{background:var(--flamingo);border-color:var(--flamingo);color:#fff;box-shadow:0 0 18px -4px var(--flamingo)}
.btn.ghost{background:none}
.btn:disabled{opacity:.5;cursor:default}
.btnrow{display:flex;gap:10px;flex-wrap:wrap}
@media (max-width:480px){.btnrow .btn{flex:1 1 100%}}

/* The generic `.card` component that used to live here was deleted. Nothing on
   the site used it any more except, by accident, the map's filter panel, whose
   own rules never set `display` — so it picked up `display:flex` from here and
   laid its five sections out in a row off the side of the screen. If a shared
   component name is ever needed again, give it a prefix. */

/* ---------- event rows (shared by nights + list + map sheet) ---------- */
.evt{display:block;width:100%;text-align:left;border:1px solid var(--border);border-radius:14px;
  padding:16px 18px;background:var(--surface);margin-bottom:12px}
.evt:last-child{margin-bottom:0}
/* The time was 13px against a 17px title, which made the one thing you scan
   for the smallest thing on the card. They now sit a hair apart. */
.evt .t{display:flex;gap:11px;align-items:baseline}
.evt .time{font-family:"IBM Plex Mono",monospace;font-size:15px;color:var(--cyan);flex:0 0 auto;
  min-width:78px;font-variant-numeric:tabular-nums}
.evt .ti{font-weight:700;font-size:16px;line-height:1.35}
/* Venue only, and it comes AFTER the badges now. It used to carry the
   category name as well, which put three clauses and a dot on one line. */
.evt .meta{font-size:13.5px;color:var(--muted);margin-top:8px;display:flex;flex-wrap:wrap;gap:6px 10px;align-items:center}
/* Tags sit on their own row so every card's badges start at the same left
   edge. Trailing them after the category sentence put them wherever that
   sentence happened to end, which read as scattered down a list. */
.evt .tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px;align-items:center}
.evt .blurb{font-size:14.5px;color:var(--muted);margin-top:9px;line-height:1.5}
.dotc{width:9px;height:9px;border-radius:50%;background:currentColor;display:inline-block;flex:0 0 auto;
  box-shadow:var(--glow)}
.badge{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.07em;text-transform:uppercase;
  border:1px solid currentColor;border-radius:5px;padding:2px 6px;white-space:nowrap}
.badge.free{color:var(--mint)}
.badge.pay{color:var(--amber)}
.badge.adult{color:var(--violet)}
.badge.couples{color:var(--flamingo)}
.badge.got{color:var(--mint)}
.badge.want{color:var(--amber)}
/* the category, moved off the dot line and in with the other badges */
.badge.cat{border-style:dashed}

/* ---------- save control ----------
   These were 3px-tall pills. They are now real buttons, because the whole
   point is tapping them one-handed while walking. */
.saverow{display:flex;gap:8px;align-items:center;margin-top:12px;flex-wrap:wrap}
.save,.tick,.rm{border:1px solid var(--border);border-radius:99px;padding:9px 16px;font-size:14px;
  font-weight:600;background:var(--surface2);display:inline-flex;align-items:center;gap:6px;min-height:var(--tap)}
.save[aria-pressed="true"]{background:var(--flamingo);border-color:var(--flamingo);color:#fff}
.tick[data-s="got"]{background:var(--mint);border-color:var(--mint);color:#04140e}
.tick[data-s="want"]{background:var(--amber);border-color:var(--amber);color:#1d1204}
.rm{color:var(--muted);font-weight:400}

/* ---------- day rail ---------- */
.days{display:flex;gap:7px;overflow-x:auto;padding:2px 0 10px;scrollbar-width:none;
  -webkit-user-select:none;user-select:none;-webkit-overflow-scrolling:touch}
.days::-webkit-scrollbar{display:none}
.day{flex:0 0 auto;border:1px solid var(--border);background:var(--surface2);border-radius:12px;
  padding:7px 12px 8px;text-align:center;min-width:58px;min-height:var(--tap)}
.day .dow{display:block;font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--muted)}
.day .num{display:block;font-family:Anton,Impact,sans-serif;font-size:19px;line-height:1.15}
.day .ct{display:block;font-family:"IBM Plex Mono",monospace;font-size:10px;color:var(--faint)}
.day[aria-pressed="true"]{background:var(--flamingo);border-color:var(--flamingo);
  box-shadow:0 0 16px -4px var(--flamingo)}
.day[aria-pressed="true"] .dow,.day[aria-pressed="true"] .num,.day[aria-pressed="true"] .ct{color:#fff}

/* ---------- notes ---------- */
.note{font-size:15px;color:var(--muted);background:var(--surface);border:1px solid var(--border);
  border-left:3px solid var(--amber);border-radius:0 12px 12px 0;padding:17px 20px;margin:14px 0;line-height:1.55}
.note b{color:var(--ink);display:block;margin-bottom:2px}
.note.warn{border-left-color:var(--flamingo)}
.note.good{border-left-color:var(--cyan)}

/* ---------- footer ---------- */
footer.site{border-top:1px solid var(--border);background:var(--surface);margin-top:40px;
  padding-block:26px;padding-bottom:calc(26px + env(safe-area-inset-bottom,0px))}
footer.site .inner{max-width:var(--maxw);margin:0 auto;padding:0 20px;display:flex;gap:26px;flex-wrap:wrap;
  font-size:14px;color:var(--muted)}
/* footer links are still links people tap with a thumb */
footer.site a{color:var(--muted);display:inline-block;padding:7px 2px}
footer.site .fine{font-size:13px;max-width:58ch;line-height:1.55}
@media (max-width:719px){footer.site{margin-bottom:0}}

@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* ---------- first-visit notice ---------- */
.mz-scrim{position:fixed;inset:0;z-index:200;background:color-mix(in srgb,var(--bg) 86%,transparent);
  backdrop-filter:blur(6px);display:flex;align-items:center;justify-content:center;padding:16px;
  overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain}
.mz-modal{background:var(--surface);border:1px solid var(--border);border-radius:18px;box-shadow:var(--shadow);
  max-width:500px;width:100%;padding:26px 24px;margin:auto}
.mz-modal h2{margin-bottom:12px}
.mz-modal p{font-size:15.5px;color:var(--muted);line-height:1.55}
.mz-modal p b{color:var(--ink)}
.mz-points{list-style:none;margin:18px 0 0;padding:0;display:grid;gap:14px}
.mz-points li{font-size:15px;color:var(--muted);line-height:1.5;padding-left:18px;position:relative}
.mz-points li:before{content:"";position:absolute;left:0;top:9px;width:6px;height:6px;border-radius:50%;
  background:var(--flamingo);box-shadow:var(--glow);color:var(--flamingo)}
.mz-points li b{color:var(--ink)}
.mz-fine{font-size:12.5px;color:var(--faint);margin:16px 0 0}

/* Launch accessibility and account controls. */
.account-link{font-weight:700;font-size:13px;white-space:nowrap;color:var(--ink);padding:9px;border:1px solid var(--border);border-radius:9px;text-decoration:none}
.policy-links{margin-top:12px;line-height:1.9}
input,textarea,select{font:inherit;color:var(--ink);background:var(--surface2);border:1px solid var(--border);border-radius:10px;padding:12px;min-height:44px;max-width:100%;box-sizing:border-box}
button:disabled{opacity:.65;cursor:wait}
button:focus-visible,a:focus-visible,input:focus-visible,textarea:focus-visible,select:focus-visible,summary:focus-visible{outline:3px solid var(--cyan);outline-offset:3px}
#account-notice{position:fixed;z-index:200;bottom:calc(85px + env(safe-area-inset-bottom));left:50%;transform:translateX(-50%);background:var(--ink);color:var(--bg);padding:14px 20px;border-radius:12px;max-width:min(90vw,580px);box-shadow:var(--shadow)}
[hidden]{display:none!important}
.day[aria-pressed=true],.day.on,.day.active{color:#160817}
.day[aria-pressed=true] .dow,.day[aria-pressed=true] .date,.day.on .dow,.day.on .date{color:#160817}
@media(max-width:719px){.sitebar .inner{gap:6px}.account-link{font-size:11px;padding:7px}.sitenav{grid-template-columns:repeat(5,1fr)}.wordmark .tagline{font-size:9px;letter-spacing:.08em}}
@media print{.sitebar,.unofficial,.saverow,footer,#account-notice{display:none!important}body{padding:0;background:white;color:black}.evt{break-inside:avoid}}

.map-credit{position:absolute;left:5px;bottom:5px;z-index:12;font-size:10px;background:var(--bg);color:var(--ink);padding:3px 6px;border-radius:4px}

html:not([data-theme="light"]) .btn.primary,html:not([data-theme="light"]) .day[aria-pressed="true"] *,html:not([data-theme="light"]) .when[aria-pressed="true"] *{color:#160817!important;opacity:1!important}
html[data-theme="light"] .day[aria-pressed="true"] *,html[data-theme="light"] .when[aria-pressed="true"] *{color:#fff!important;opacity:1!important}

button:disabled{cursor:not-allowed;opacity:.6;box-shadow:none}

/* Readable event hierarchy and bottom-aligned actions across all event views. */
.evt{display:flex;flex-direction:column;gap:0}
.evt .event-when{display:flex;align-items:center;gap:10px;margin-bottom:9px;flex-wrap:wrap}
.evt .event-when .time:empty{display:none}
.evt .t{display:block}.evt .ti{font-family:Karla,sans-serif;font-size:18px;line-height:1.35;overflow-wrap:anywhere}
.evt .time{min-width:0;font-size:12px;color:var(--muted)}
.time-tbd{color:var(--muted);border-color:var(--border);background:var(--surface2);font-size:10px;text-shadow:none}
.evt .saverow{margin-top:auto;padding-top:16px}
.saverow a{text-decoration:none}.ticket-link{color:var(--cyan)}
.ticket-check{display:flex;gap:9px;align-items:center;min-height:44px;font-size:14px;cursor:pointer;color:var(--muted)}
.ticket-check input{width:19px;height:19px;accent-color:var(--mint);flex:0 0 auto;margin:0}
.ticket-check:has(input:checked){color:var(--mint)}
.ticket-check[hidden]{display:none!important}
