/* ============================================================
   MASV app v1.1 - GET FREAKY 2026 "NEON NIGHTMARE" skin
   Palette pulled from the official key art: electric-blue chrome,
   hot pink neon, slime-LED green dates, deep purple city dark.
   Liquid-glass surfaces + floating nav carry over from v1.0.
   ============================================================ */

:root {
  --neonlit: drop-shadow(0 0 6px rgba(255, 43, 214, .85)) drop-shadow(0 0 18px rgba(255, 43, 214, .5));
  --bg: #07030f;
  --bg2: #0d0618;
  --ink: #f4f0ff;
  --dim: rgba(226, 218, 255, .72);
  --faint: rgba(226, 218, 255, .56);
  --pink: #ff2bd6;
  --magenta: #e535ff;
  --violet: #8b3dff;
  --blue: #3f7dff;
  --cyan: #41c8ff;
  --green: #b6ff3f;
  --orange: #ff8a2a;
  --grad: linear-gradient(92deg, #3f7dff 0%, #a92bff 48%, #ff2bd6 100%);
  --grad-cta: linear-gradient(92deg, #ff2bd6, #8b3dff);
  --glass: rgba(26, 13, 46, .55);
  --glass2: rgba(32, 16, 58, .42);
  --gbrd: rgba(255, 255, 255, .09);
  --gbrd2: rgba(255, 255, 255, .14);
  --radius: 20px;
  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
}

* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
/* keyboard focus: a neon ring, only for keyboard users (touch taps never show it) */
:focus-visible { outline: 2px solid var(--pink); outline-offset: 3px; border-radius: 6px; }
:focus:not(:focus-visible) { outline: none; }
/* never put overflow-y on html/body - detaches position:fixed on iOS (v1.0 rule) */
html { scrollbar-gutter: stable; }
/* no rubber-band on the document: iOS otherwise drags the fixed glow layers and
   exposes their edges as hard lines above the app bar / below the footer */
html { background: var(--bg); overscroll-behavior: none; }
body {
  font-family: "Chakra Petch", "Helvetica Neue", sans-serif;
  /* flat on purpose: every glow lives in the fixed .amb / .fog layers, which
     extend past the viewport, so iOS rubber-banding never exposes a clipped edge */
  background: var(--bg);
  color: var(--ink);
  min-height: 100vh;
  min-height: 100svh;
  overflow-x: hidden; overscroll-behavior: none;
}
img { display: block; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; }

h1, h2, .wm { font-family: "Saira Condensed", "Chakra Petch", sans-serif; }

/* ---------- ambient neon orbs ---------- */
.amb { position: fixed; inset: 0; z-index: 0; pointer-events: none; }   /* no overflow clip: see body */
.amb i { position: absolute; border-radius: 50%; filter: blur(110px); opacity: .4; }
.amb .a { width: 64vw; height: 64vw; left: -24vw; top: -14vw; background: #ff2bd6; }
.amb .b { width: 56vw; height: 56vw; right: -22vw; top: 12vh; background: #2b5fd9; opacity: .38; }
.amb .c { width: 60vw; height: 60vw; left: -18vw; bottom: -22vw; background: #8b3dff; opacity: .3; }
.amb .d { width: 34vw; height: 34vw; right: -8vw; bottom: -10vw; background: #b6ff3f; opacity: .12; }

/* ---------- Halloween layer ---------- */
.ghosts { position: fixed; inset: 0; z-index: 1; pointer-events: none; }
/* Halloween lives on the festival tabs only - the label home stays clean */
body[data-view="home"] .ghosts, body[data-view="home"] .fog, body[data-view="home"] .flash,
body[data-view="home"] .eyes, body[data-view="home"] .nav-peek { display: none !important; }
.gh {
  position: absolute; width: 34px; color: #fff; opacity: 0;
  filter: drop-shadow(0 0 10px rgba(255, 255, 255, .45)) drop-shadow(0 0 22px rgba(255, 43, 214, .35));
  animation: drift 38s linear infinite;
}
.gh.g1 { left: 12%; }
.gh.g2 { left: 62%; width: 24px; animation-duration: 46s; animation-delay: -14s; }
.gh.g3 { left: 84%; width: 42px; animation-duration: 52s; animation-delay: -28s; }
.gh.g5 { display: none; }
.gh.g4 { left: 34%; width: 22px; animation-duration: 41s; animation-delay: -7s; }
.gh.g5 { left: 72%; width: 46px; animation-duration: 57s; animation-delay: -39s; }
body.nightmare .gh.g5 { display: block; }
.gh.pk { display: none; }
@keyframes candle { 0%, 100% { opacity: 1; } 37% { opacity: .7; } 52% { opacity: .95; } 74% { opacity: .6; } }
/* up and gently across, fading in low and out near the top */
@keyframes drift {
  0%   { transform: translate3d(0, 106vh, 0) rotate(-5deg); opacity: 0; }
  10%  { opacity: 0; }
  22%  { opacity: .13; }
  50%  { transform: translate3d(26px, 52vh, 0) rotate(4deg); opacity: .16; }
  88%  { opacity: .08; }
  100% { transform: translate3d(-14px, -18vh, 0) rotate(-3deg); opacity: 0; }
}
/* easter-egg swarm */
.boo { position: fixed; inset: 0; z-index: 90; pointer-events: none; overflow: hidden; }
.bg-gh {
  position: absolute; bottom: -60px; width: var(--sz, 24px); color: #fff;
  filter: drop-shadow(0 0 12px rgba(255, 43, 214, .6));
  animation: boo 4s cubic-bezier(.25, .6, .3, 1) forwards;
}
@keyframes boo {
  0%   { transform: translate3d(0, 0, 0) scale(.6) rotate(0); opacity: 0; }
  14%  { opacity: .95; }
  100% { transform: translate3d(var(--drift, 0), -112vh, 0) scale(1) rotate(8deg); opacity: 0; }
}
.roster.shuffling .rcard { animation: shuf .55s ease; }
@keyframes shuf { 0% { transform: scale(.86) rotate(-4deg); opacity: .4; } 100% { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .gh, .bg-gh, .roster.shuffling .rcard { animation: none; }
  .gh { opacity: .07; }
}

.grain {
  position: fixed; inset: 0; z-index: 1; pointer-events: none; opacity: .05; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.7'/%3E%3C/svg%3E");
}

/* LED slime-green digits, like the OCT 23-24-25 lockup on the art */
.led {
  color: var(--green);
  text-shadow: 0 0 14px rgba(150, 255, 46, .6), 0 0 34px rgba(150, 255, 46, .25);
  letter-spacing: .12em;
  font-weight: 700;
}

/* ---------- pre-drop password gate ---------- */
/* .locked is set by the inline script in index.html before first paint, so the
   festival never flashes behind the gate. The gate itself is hidden by default
   and only shown while locked - if the script never runs, the app opens rather
   than trapping everyone behind a dead form. */
.pwgate { display: none; }
html.locked .pwgate {
  position: fixed; inset: 0; z-index: 300;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
  padding: 24px; text-align: center;
  background:
    radial-gradient(80vw 50vh at 50% 20%, rgba(255, 43, 214, .16), transparent 60%),
    radial-gradient(70vw 50vh at 50% 90%, rgba(63, 125, 255, .14), transparent 60%),
    #07030f;
}
html.locked #splash, html.locked .auth, html.locked .app, html.locked .amb, html.locked .grain { display: none !important; }
.pw-logo { width: min(160px, 44vw); opacity: .95; margin-bottom: 6px; }
.pw-t { font-family: "Saira Condensed", sans-serif; font-size: 30px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; }
.pw-s { font-size: 13px; color: var(--dim); margin-bottom: 8px; }
.pw-form { display: flex; gap: 8px; width: min(340px, 100%); }
.pw-form input {
  flex: 1; min-width: 0; padding: 12px 14px; border-radius: 12px;
  background: rgba(10, 5, 22, .65); border: 1px solid var(--gbrd); color: var(--ink);
  font-family: inherit; font-size: 16px; outline: none;
}
.pw-form input:focus { border-color: rgba(255, 43, 214, .55); }
.pw-form button {
  flex: none; padding: 12px 20px; border: 0; border-radius: 12px; cursor: pointer;
  background: var(--grad-cta); color: #fff; font-family: inherit;
  font-size: 13px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
}
.pw-err { font-size: 13px; color: #ff9db1; }

/* ---------- splash ---------- */
/* ---------- the intro ----------
   Quiet and brand-first (user call): embers and fog on canvas, the MASV mark
   breathes in, then the real Get Freaky lockup fades up and its neon layer
   flickers alive, then the app. Tap to skip. */
#splash {
  position: fixed; inset: 0; z-index: 200; background: #040209; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  transition: opacity .5s ease;
}
#splash.hide { opacity: 0; pointer-events: none; }
#spfx { position: absolute; inset: 0; width: 100%; height: 100%; }
.sp-stage { position: relative; display: grid; place-items: center; }
.sp-stage > * { grid-area: 1 / 1; }   /* mark and lockup share one cell: they swap, never stack */
.splash-logo { width: min(215px, 56vw); opacity: 0; filter: drop-shadow(0 0 26px rgba(255, 43, 214, .35)); }
.sp-stage.in .splash-logo { animation: sp-breathe 1.1s ease forwards; }
@keyframes sp-breathe { 0% { opacity: 0; transform: scale(.92); filter: brightness(2.2) drop-shadow(0 0 40px rgba(255, 43, 214, .6)); } 100% { opacity: 1; transform: none; filter: brightness(1) drop-shadow(0 0 26px rgba(255, 43, 214, .35)); } }
.sp-stage.in.swap .splash-logo { animation: sp-out .5s ease forwards; }
@keyframes sp-out { to { opacity: 0; transform: scale(1.08); filter: brightness(1.8) drop-shadow(0 0 40px rgba(255, 43, 214, .5)); } }
.sp-gf { width: min(250px, 64vw); opacity: 0; }
.sp-stage.tag .sp-gf { opacity: 1; transition: opacity .5s ease; animation: sp-pulse 2.6s ease-in-out .5s infinite; }
@keyframes sp-pulse { 0%, 100% { transform: scale(1); filter: drop-shadow(0 0 10px rgba(255, 43, 214, .25)); } 50% { transform: scale(1.025); filter: drop-shadow(0 0 22px rgba(255, 43, 214, .5)); } }
.sp-gf .gflock img { width: 100%; }
@media (prefers-reduced-motion: reduce) {
  /* same sequence, plain fades: MASV in, MASV out, Get Freaky in (no keyframe motion) */
  #spfx { display: none; }
  .sp-stage .splash-logo { animation: none !important; opacity: 0; transition: opacity .4s ease; }
  .sp-stage.in .splash-logo { opacity: 1; }
  .sp-stage.in.swap .splash-logo { opacity: 0; }
  .sp-gf { opacity: 0; transition: opacity .4s ease; }
  .sp-stage.tag .sp-gf { opacity: 1; animation: sp-pulse 2.6s ease-in-out .5s infinite; }
}
.splash-bar { position: absolute; bottom: calc(44px + var(--sab)); width: 130px; height: 3px; border-radius: 3px; background: rgba(255, 255, 255, .12); overflow: hidden; }
.splash-bar span { display: block; height: 100%; width: 40%; border-radius: 3px; background: var(--grad); animation: sbar 1s ease-in-out infinite; }
@keyframes sbar { 0% { transform: translateX(-110%); } 100% { transform: translateX(340%); } }

/* ============================================================
   GATE
   ============================================================ */
.auth { position: fixed; inset: 0; z-index: 50; overflow-y: auto; -webkit-overflow-scrolling: touch; }
/* the gate: a quiet gradient with the ghosts drifting over it (user call 8/24:
   the photo read as hectic). MASV + the flickering lockup carry the screen. */
.auth-bg {
  position: fixed; inset: 0; z-index: -1;
  background:
    radial-gradient(120% 70% at 50% -10%, rgba(139, 61, 255, .45) 0%, rgba(139, 61, 255, 0) 60%),
    radial-gradient(90% 60% at 50% 110%, rgba(255, 43, 214, .28) 0%, rgba(255, 43, 214, 0) 60%),
    linear-gradient(180deg, #1a0a2e 0%, #0c0418 55%, #07030f 100%);
}
body.gated .ghosts { z-index: 60; }   /* float over the gate, under nothing that matters (pointer-events none) */
.auth-x {
  position: fixed; top: calc(12px + var(--sat)); right: 14px; z-index: 5; width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--gbrd2); background: rgba(255, 255, 255, .07); color: var(--ink); cursor: pointer; padding: 9px;
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.auth-x svg { width: 100%; height: 100%; display: block; }
.auth-x:active { transform: scale(.92); }
.auth-inner {
  min-height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  padding: calc(26px + var(--sat)) 22px calc(30px + var(--sab));
}
.auth-logo { text-align: center; margin-bottom: 18px; }
.auth-masv { width: min(150px, 40vw); margin: 0 auto 16px; opacity: .96; }
/* The logo is two stacked layers so the pink script can flicker on its own:
   gf-chrome.webp (the GET FREAKY letters) and gf-neon.webp (the NEON NIGHTMARE
   script), split out of gf-logo.png by colour. They are pixel-aligned copies of
   the same canvas, so absolute-positioning the neon over the chrome registers
   exactly with no maths. */
.gflock { position: relative; display: block; margin: 0 auto; }
.gflock img { width: 100%; height: auto; display: block; }
.gflock .gf-neon {
  position: absolute; inset: 0;
  /* a real tube sits lit with a hot halo, and stutters rather than fades */
  filter: drop-shadow(0 0 6px rgba(255, 43, 214, .85)) drop-shadow(0 0 18px rgba(255, 43, 214, .5));
  animation: neonflicker 5.5s infinite steps(1, end);
}
@keyframes neonflicker {
  0%, 8%    { opacity: 1;   filter: var(--neonlit); }
  9%        { opacity: .22; filter: none; }
  10%       { opacity: 1;   filter: var(--neonlit); }
  27%       { opacity: .55; filter: drop-shadow(0 0 3px rgba(255,43,214,.45)); }
  28%       { opacity: 1;   filter: var(--neonlit); }
  41%       { opacity: .18; filter: none; }
  42%       { opacity: 1;   filter: var(--neonlit); }
  43%       { opacity: .35; filter: none; }
  44%, 55%  { opacity: 1;   filter: var(--neonlit); }
  56%       { opacity: .5;  filter: drop-shadow(0 0 3px rgba(255,43,214,.4)); }
  57%       { opacity: 1;   filter: var(--neonlit); }
  71%       { opacity: .25; filter: none; }
  72%       { opacity: 1;   filter: var(--neonlit); }
  73%       { opacity: .4;  filter: none; }
  74%, 88%  { opacity: 1;   filter: var(--neonlit); }
  89%       { opacity: .15; filter: none; }
  90%, 100% { opacity: 1;   filter: var(--neonlit); }
}
/* the neon stutter stays on under Reduce Motion: it is an opacity flicker, not movement (user call 8/24) */

.auth-gf { width: min(330px, 84vw); filter: drop-shadow(0 6px 30px rgba(43, 95, 217, .5)); }
.auth-logo .sub { margin-top: 14px; font-size: 15px; }
.auth-logo .sub2 { margin-top: 7px; font-size: 11px; letter-spacing: .3em; color: var(--dim); font-weight: 600; }

.auth-card {
  width: min(420px, 100%);
  background: var(--glass);
  border: 1px solid var(--gbrd);
  border-radius: var(--radius);
  backdrop-filter: blur(22px) saturate(1.4);
  -webkit-backdrop-filter: blur(22px) saturate(1.4);
  padding: 18px 18px 20px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .5);
}
.auth-tabs { display: flex; gap: 4px; background: rgba(255, 255, 255, .06); border-radius: 12px; padding: 4px; margin-bottom: 16px; }
.auth-tab {
  flex: 1; text-align: center; padding: 9px 0; border-radius: 9px; font-size: 13px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--dim); cursor: pointer; transition: all .18s;
}
.auth-tab.on { background: var(--grad-cta); color: #fff; box-shadow: 0 4px 18px rgba(255, 43, 214, .35); }

.field { margin-bottom: 12px; }
.field label { display: block; font-size: 11px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); margin-bottom: 6px; }
.field label .opt { opacity: .55; font-weight: 500; letter-spacing: .05em; text-transform: none; }
.field input {
  width: 100%; background: rgba(10, 5, 22, .6); border: 1px solid var(--gbrd); border-radius: 12px;
  color: var(--ink); font-family: inherit; font-size: 16px; padding: 12px 13px; outline: none; transition: border .18s;
}
.field input:focus { border-color: rgba(255, 43, 214, .55); box-shadow: 0 0 0 3px rgba(255, 43, 214, .14); }
.pw-wrap { position: relative; }
.pw-wrap input { padding-right: 46px; }
.pw-eye {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  background: none; border: 0; color: var(--dim); width: 36px; height: 36px; cursor: pointer; padding: 7px;
}
.pw-eye svg { width: 100%; height: 100%; }
.pw-eye .eye-off { display: none; }
.pw-eye.show .eye-open { display: none; }
.pw-eye.show .eye-off { display: block; }

.optin { display: none; gap: 10px; margin: 2px 0 14px; cursor: pointer; }
.optin.on { display: flex; }
.optin input { margin-top: 3px; accent-color: var(--pink); flex: none; width: 16px; height: 16px; }
.optin-t { font-size: 12px; color: var(--dim); line-height: 1.45; }
.optin-t b { color: var(--ink); font-weight: 600; }
.optin-fine { display: block; margin-top: 5px; font-size: 10px; color: var(--faint); line-height: 1.5; }

.auth-forgot { text-align: right; margin: -4px 0 10px; }
.auth-forgot a { font-size: 12px; color: var(--dim); cursor: pointer; }
.auth-btn {
  width: 100%; border: 0; border-radius: 14px; padding: 14px 0; cursor: pointer;
  background: var(--grad-cta); color: #fff; font-size: 15px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  box-shadow: 0 8px 28px rgba(255, 43, 214, .35);
  transition: transform .15s, filter .2s;
}
.auth-btn:active { transform: scale(.975); }
.auth-btn[disabled] { filter: grayscale(.6) brightness(.7); }
.auth-notice { margin-top: 12px; font-size: 13px; line-height: 1.5; border-radius: 10px; padding: 10px 12px; }
.auth-notice.err { background: rgba(255, 59, 92, .12); border: 1px solid rgba(255, 59, 92, .35); color: #ff9db1; }
.auth-notice.ok { background: rgba(182, 255, 63, .09); border: 1px solid rgba(182, 255, 63, .3); color: #d3ff8e; }
.auth-notice a { color: var(--ink); text-decoration: underline; cursor: pointer; }

/* guest mode: a black button right under the card, same shape as the CTA (user call 8/24) */
.auth-guest {
  width: min(420px, 100%); margin-top: 12px; border-radius: 14px; padding: 14px 0; cursor: pointer;
  background: #07030f; border: 1px solid rgba(255, 255, 255, .14); color: var(--ink);
  font-family: inherit; font-size: 14px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  transition: transform .15s;
}
.auth-guest:active { transform: scale(.975); }
.auth-legal { margin-top: 14px; font-size: 11px; color: var(--faint); text-align: center; max-width: 340px; line-height: 1.5; }
.auth-legal a { text-decoration: underline; }

/* ============================================================
   APP CHROME
   ============================================================ */
.app { position: relative; z-index: 2; min-height: 100vh; min-height: 100svh; }

.appbar {
  position: sticky; top: 0; z-index: 40;
  padding: calc(10px + var(--sat)) 16px 10px;
  background: rgba(7, 3, 15, .66);
  backdrop-filter: blur(28px) saturate(1.7);
  -webkit-backdrop-filter: blur(28px) saturate(1.7);
  border-bottom: 1px solid rgba(255, 255, 255, .07);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05);
}
.appbar-top { display: flex; align-items: center; justify-content: space-between; }
.bar-actions { display: flex; align-items: center; gap: 8px; }
.brand { display: flex; align-items: center; gap: 12px; min-width: 0; }
.brand .b-masv { height: 15px; }
.brand .sep { width: 1px; height: 22px; background: rgba(255, 255, 255, .18); }
/* the GF chrome logo is dark navy - lift it off the dark bar with glow + brightness */
.brand .b-gf {
  height: 34px;
  filter: brightness(1.45) saturate(1.2)
    drop-shadow(0 0 8px rgba(130, 175, 255, .75))
    drop-shadow(0 0 20px rgba(255, 43, 214, .35));
}
.acct-btn {
  width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--gbrd2);
  background: var(--glass2); color: var(--ink); cursor: pointer; padding: 11px;
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.acct-btn svg { width: 100%; height: 100%; }

.cd { display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap;
  cursor: pointer; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.cd .u {
  min-width: 56px; text-align: center; padding: 6px 8px 7px; border-radius: 12px;
  background: var(--glass2); border: 1px solid var(--gbrd);
}
.cd .u b { display: block; font-family: "Saira Condensed", sans-serif; font-size: 21px; font-weight: 800; color: var(--green); text-shadow: 0 0 12px rgba(150, 255, 46, .5); line-height: 1; }
.cd .u s { display: block; text-decoration: none; font-size: 10px; letter-spacing: .22em; color: var(--faint); margin-top: 3px; text-transform: uppercase; }
.cd .cap { flex-basis: 100%; text-align: center; font-size: 10px; letter-spacing: .34em; color: var(--dim); font-weight: 700; margin-top: 4px; }
/* held state of the countdown easter egg */
.cd .cap.reveal { font-size: 10px; letter-spacing: .22em; animation: capin .2s ease; }
@keyframes capin { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }

/* ---------- views ---------- */
.view { display: none; padding: 16px 16px calc(122px + var(--sab)); max-width: 560px; margin: 0 auto; }
.view.active { display: block; position: relative; z-index: 3; animation: vin .32s cubic-bezier(.2, .8, .3, 1); }
@keyframes vin { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.vhead { margin: 6px 2px 14px; }
.eyebrow { font-size: 10px; letter-spacing: .3em; text-transform: uppercase; color: var(--pink); font-weight: 700; margin-bottom: 6px; text-shadow: 0 0 16px rgba(255, 43, 214, .5); }
.vhead h1 { font-size: 40px; font-weight: 800; text-transform: uppercase; letter-spacing: .02em; line-height: 1; color: #f4f0ff; display: flex; align-items: center; gap: 12px; }
.h1-ic { display: inline-flex; width: 30px; height: 30px; color: var(--pink); filter: drop-shadow(0 0 10px rgba(255, 43, 214, .7)); }
.h1-ic svg { width: 100%; height: 100%; }
.vhead .sub { margin-top: 6px; font-size: 13px; color: var(--dim); }

.sect-label { font-size: 11px; font-weight: 700; letter-spacing: .26em; text-transform: uppercase; color: var(--dim); margin: 22px 2px 10px; }
.sect-label:first-of-type { margin-top: 18px; }

/* ---------- label / roster (home) ---------- */
.label-head { position: relative; text-align: center; padding: 10px 4px 20px; }
.hv-hero { position: relative; overflow: visible; }
.lh-logo { width: min(190px, 52vw); margin: 0 auto 16px; }
.lh-t {
  font-family: "Saira Condensed", sans-serif; font-size: 38px; font-weight: 800;
  text-transform: uppercase; letter-spacing: .02em; line-height: 1;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.lh-s { margin: 10px auto 0; max-width: 330px; font-size: 13px; line-height: 1.6; color: var(--dim); }

.album {
  display: flex; gap: 12px; align-items: center; padding: 12px;
  border-radius: 18px; border: 1px solid transparent;
  background:
    linear-gradient(150deg, rgba(255, 43, 214, .13), rgba(63, 125, 255, .09)) padding-box,
    linear-gradient(var(--glass), var(--glass)) padding-box,
    linear-gradient(135deg, rgba(255, 43, 214, .55), rgba(139, 61, 255, .35) 45%, rgba(255, 255, 255, .1)) border-box;
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  box-shadow: 0 8px 30px rgba(255, 43, 214, .16); transition: transform .15s;
}
.album:active { transform: scale(.985); }
/* a watch card: only the play button is live, so the body gives no tap feedback */
.album.watch { cursor: default; -webkit-tap-highlight-color: transparent; }
.album.watch:active { transform: none; }
.album.watch .al-play { cursor: pointer; }
.al-art { flex: none; width: 88px; height: 88px; border-radius: 12px; border: 1px solid var(--gbrd2);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .45); }
/* the text column is exactly the art's height: kicker, two-to-three line title, one meta line */
.al-body { flex: 1; min-width: 0; height: 88px; display: flex; flex-direction: column; justify-content: center; gap: 3px; }
.al-k { font-size: 10px; letter-spacing: .24em; text-transform: uppercase; color: var(--green); font-weight: 700; }
.al-t { font-family: "Saira Condensed", sans-serif; font-size: 15.5px; font-weight: 800; line-height: 1.05;
  letter-spacing: .01em; text-transform: uppercase; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.al-m { display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--dim); white-space: nowrap; overflow: hidden; }
.al-more { display: inline-flex; align-items: center; gap: 1px; color: var(--pink); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; font-size: 10px; }
.al-more svg { width: 12px; height: 12px; }
.al-play { flex: none; width: 46px; height: 46px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: var(--grad-cta); color: #fff; box-shadow: 0 6px 20px rgba(255, 43, 214, .42); transition: transform .14s; }
.al-play:active { transform: scale(.93); }
.al-play svg { width: 18px; height: 18px; display: block; }
/* the announce-window SOON card (lineup hidden:true) */
.tba-card { padding: 34px 20px; border-radius: 18px; text-align: center; background: var(--glass2); border: 1px solid var(--gbrd); }
.sect-label .cnt { color: var(--faint); letter-spacing: .1em; margin-left: 6px; }

.roster { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }

/* ---------- featured video (home) ----------
   Same glass recipe as the release card. The frame holds the muted loop and a
   single play button; the row under it carries the title + a Spotify pill, so
   nothing sits on top of the native controls once the full cut is playing. */
.fvid {
  padding: 8px 8px 10px; margin-bottom: 12px; border-radius: 20px; border: 1px solid transparent;
  background:
    linear-gradient(150deg, rgba(255, 43, 214, .13), rgba(63, 125, 255, .09)) padding-box,
    linear-gradient(var(--glass), var(--glass)) padding-box,
    linear-gradient(135deg, rgba(255, 43, 214, .55), rgba(139, 61, 255, .35) 45%, rgba(255, 255, 255, .1)) border-box;
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  box-shadow: 0 8px 30px rgba(255, 43, 214, .16);
}
.fv-frame { position: relative; aspect-ratio: 16 / 9; border-radius: 14px; overflow: hidden; background: #0a0518; border: 1px solid var(--gbrd2); }
.fv-frame video { width: 100%; height: 100%; object-fit: cover; display: block; background: #0a0518; }
.fv-tap { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; border: 0; cursor: pointer; color: #fff;
  background: radial-gradient(60% 60% at 50% 50%, rgba(7, 3, 15, .22), rgba(7, 3, 15, 0) 70%); -webkit-tap-highlight-color: transparent; }
.fvid.playing .fv-tap { display: none; }
.fv-full { display: none; width: 100%; height: 100%; object-fit: contain; background: #000; }
.fvid.playing .fv-full { display: block; }
.fvid.playing .fv-v { display: none; }
.fv-play { position: absolute; left: 50%; top: 50%; width: 58px; height: 58px; margin: -29px 0 0 -29px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; background: var(--grad-cta); color: #fff;
  box-shadow: 0 8px 26px rgba(255, 43, 214, .45); transition: transform .14s; }
.fv-tap:active .fv-play { transform: scale(.93); }
.fv-play svg { width: 22px; height: 22px; display: block; }
.fv-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 4px 10px 6px; }
.fv-txt { min-width: 0; }
.fv-k { font-size: 10px; letter-spacing: .24em; text-transform: uppercase; color: var(--green); font-weight: 700; }
.fv-t { font-family: "Saira Condensed", sans-serif; font-size: 24px; font-weight: 800; line-height: 1; letter-spacing: .02em;
  text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin: 2px 0 3px; }
.fv-s { font-size: 11.5px; color: var(--dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* the same card inside an artist profile sheet: flush, no outer glass (the sheet is the glass) */
.fv-sheet { padding: 0; margin: 0 0 14px; background: none; border: 0; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
.fv-sheet .fv-row { padding: 0 0 8px; }
.fv-sheet .fv-t { font-size: 18px; }
.fv-sp { flex: none; display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 13px 0 10px; border-radius: 999px;
  font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: #fff;
  background: rgba(255, 255, 255, .08); border: 1px solid var(--gbrd2); }
.fv-sp:active { transform: scale(.96); }
.fv-sp svg { width: 16px; height: 16px; color: #1ed760; }

/* ---------- discovery deck (home) ----------
   One artist per screen, swipe for the next. The track is a native scroll-snap
   row - every card is the full track width so scrollLeft / width is the index.
   Off-centre cards sit back (scaled, dimmed) so the swipe reads as a deck, not
   a list. The avatar strip underneath is the overview and the jump list. */
.disco-label { display: flex; align-items: baseline; justify-content: space-between; }
.disco-pos { font-family: "Saira Condensed", sans-serif; font-size: 13px; font-weight: 700; letter-spacing: .12em; color: var(--faint); }
.disco { position: relative; margin: 0 -16px; }
/* "Swipe" badge straddling the bottom of the ring, first visit only */
.disco-hint {
  position: absolute; left: 50%; top: calc(min(56vw, 220px) + 56px); transform: translateX(-50%) translateY(-50%);
  display: none; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 999px; z-index: 2; pointer-events: none;
  background: rgba(16, 8, 32, .92); border: 1px solid rgba(255, 43, 214, .55); color: var(--ink);
  font-size: 10px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .5), 0 0 16px rgba(255, 43, 214, .35);
}
.disco-hint.show { display: inline-flex; animation: hint-in .35s ease; }
.disco-hint i { font-style: normal; font-size: 15px; line-height: 1; color: var(--pink); }
.disco-hint i:first-child { animation: hint-l 1.1s ease-in-out infinite; }
.disco-hint i:last-child { animation: hint-r 1.1s ease-in-out infinite; }
@keyframes hint-in { from { opacity: 0; transform: translateX(-50%) translateY(-30%); } to { opacity: 1; transform: translateX(-50%) translateY(-50%); } }
@keyframes hint-l { 0%, 100% { transform: translateX(0); opacity: .5; } 50% { transform: translateX(-4px); opacity: 1; } }
@keyframes hint-r { 0%, 100% { transform: translateX(0); opacity: .5; } 50% { transform: translateX(4px); opacity: 1; } }
/* the nudge: snap off for a beat so a short programmatic scroll can show the next card's edge */
.disco-track.nudging { scroll-snap-type: none; }
/* all-artists list under the deck */
.alist { display: grid; gap: 8px; }
.al-row {
  display: flex; align-items: center; gap: 12px; width: 100%; padding: 9px 12px 9px 9px; text-align: left; cursor: pointer;
  background: var(--glass2); border: 1px solid var(--gbrd); border-radius: 14px; color: var(--ink); font-family: inherit; transition: transform .15s;
}
.al-row:active { transform: scale(.985); }
.al-av { flex: none; width: 40px; height: 40px; border-radius: 50%; overflow: hidden; position: relative; background: var(--glass2); border: 1px solid var(--gbrd); }
.al-av img { width: 100%; height: 100%; object-fit: cover; }
.al-av .ini { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-family: "Saira Condensed", sans-serif; font-size: 15px; font-weight: 800; color: rgba(226, 218, 255, .72); }
.al-n { flex: 1; min-width: 0; font-size: 14px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.al-row .chev { flex: none; width: 16px; height: 16px; color: var(--faint); }
.al-row .chev svg { width: 100%; height: 100%; }
@media (prefers-reduced-motion: reduce) { .disco-hint i { animation: none; } }
.disco-track {
  display: flex; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch; scrollbar-width: none; overscroll-behavior-x: contain;
  /* room for the ring's glow (34px up, ~70px down): the scroller clips
     vertically, so the glow gets padding and negative margins, never a hard edge */
  padding: 40px 0 72px; margin: -34px 0 -58px;
}
.disco-track::-webkit-scrollbar { display: none; }
.disco-card { flex: 0 0 100%; min-width: 0; scroll-snap-align: center; scroll-snap-stop: always; padding: 0 22px; text-align: center; }
/* the static panel under the rings: name, meta, bio, actions. Swaps with a short rise. */
.disco-info { padding: 0 22px; text-align: center; }
.disco-words.swap { animation: info-swap .28s ease; }
@keyframes info-swap { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .disco-words.swap { animation: none; } }
/* no transform/opacity on the snap item itself - WebKit rasterised a half-clipped
   photo mid-swipe. The dimming lives on an inner wrapper. */
.disco-in { opacity: .45; transition: opacity .3s ease; }
.disco-card.is-on .disco-in { opacity: 1; }
.disco-hit { display: block; width: 100%; min-height: 40px; padding: 0; border: 0; background: none; cursor: pointer; color: var(--ink); font-family: inherit; }
.disco-hit:active .disco-ring { transform: scale(.97); }
.disco-ring {
  display: block; width: min(56vw, 220px); aspect-ratio: 1; margin: 0 auto; padding: 3px; border-radius: 50%;
  background: conic-gradient(from 210deg, #ff2bd6, #8b3dff 40%, #3f7dff 65%, #ff2bd6);
  box-shadow: 0 0 0 7px rgba(255, 43, 214, .05), 0 16px 44px rgba(139, 61, 255, .32), 0 0 30px rgba(255, 43, 214, .26);
  transition: transform .15s;
}
.disco-img {
  display: block; width: 100%; height: 100%; border-radius: 50%; overflow: hidden; position: relative;
  border: 3px solid var(--bg); background: var(--glass2);
}
.disco-img img { width: 100%; height: 100%; object-fit: cover; }
.disco-img .ini { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: "Saira Condensed", sans-serif; font-size: 64px; font-weight: 800; color: rgba(226, 218, 255, .72);
  background: linear-gradient(150deg, rgba(255, 43, 214, .18), rgba(63, 125, 255, .12)); text-shadow: 0 0 18px rgba(255, 43, 214, .35); }
.disco-n { display: block; margin-top: 0; font-family: "Saira Condensed", sans-serif; font-size: 34px; font-weight: 800;
  text-transform: uppercase; letter-spacing: .02em; line-height: 1; text-wrap: balance; text-shadow: 0 0 24px rgba(255, 43, 214, .35); }
.disco-m { margin-top: 7px; font-size: 10px; letter-spacing: .2em; text-transform: uppercase; color: var(--faint); font-weight: 700; }
.disco-bio { margin: 12px auto 0; max-width: 330px; font-size: 13px; line-height: 1.55; color: var(--dim);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.disco-btns { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 16px; }
/* just a play button (user call): round, gradient, the song lives in aria-label */
.disco-play {
  display: inline-flex; align-items: center; justify-content: center; width: 54px; height: 54px; border-radius: 50%;
  background: var(--grad-cta); color: #fff; box-shadow: 0 8px 24px rgba(255, 43, 214, .42); transition: transform .14s;
}
.disco-play:active { transform: scale(.94); }
.disco-play svg { width: 22px; height: 22px; margin-left: 1px; }
.disco-btns .soc { margin: 0; width: 44px; }
/* the strip sits ABOVE the deck (user call 8/23): overview first, then the card */
.disco-strip {
  display: flex; gap: 12px; overflow-x: auto; scrollbar-width: none; padding: 12px 16px 14px; margin: -8px 0 16px;   /* breathing room before the big ring (user call 8/24) */
  -webkit-overflow-scrolling: touch; scroll-behavior: smooth;
}
.disco-strip::-webkit-scrollbar { display: none; }
.disco-dot {
  flex: none; width: 62px; height: 62px; padding: 0; border-radius: 50%; overflow: hidden; cursor: pointer;
  border: 2px solid rgba(255, 255, 255, .08); background: var(--glass2); opacity: .5; position: relative;
  transition: opacity .2s, border-color .2s, transform .2s, box-shadow .2s;
}
.disco-dot img { width: 100%; height: 100%; object-fit: cover; }
.disco-dot .ini { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: "Saira Condensed", sans-serif; font-size: 19px; font-weight: 800; color: rgba(226, 218, 255, .72); }
/* five dots fit on one line - centre them; a longer live roster still scrolls from the left edge */
.disco-dot:first-child { margin-left: auto; }
.disco-dot:last-child { margin-right: auto; }
.disco-dot.on { opacity: 1; border-color: var(--pink); transform: scale(1.1); box-shadow: 0 0 16px rgba(255, 43, 214, .6); }
@media (prefers-reduced-motion: reduce) { .disco-card { transition: none; } .disco-strip { scroll-behavior: auto; } }
.rcard {
  /* min-width:0 matters: grid items default to min-width:auto, so the nowrap genre
     line below was widening its column and pushing the whole grid off-screen. */
  display: block; width: 100%; min-width: 0; padding: 0; border: 0; background: none; cursor: pointer; text-align: center;
  font-family: inherit; color: var(--ink); transition: transform .15s;
}
.rcard:active { transform: scale(.96); }
.r-img {
  display: block; position: relative; aspect-ratio: 1; border-radius: 50%; overflow: hidden;
  border: 1px solid var(--gbrd); background: var(--glass2); margin-bottom: 8px;
}
.r-img img { width: 100%; height: 100%; object-fit: cover; }
/* B2B circle: 45-degree diagonal split so neither face gets guillotined */
.face2 { position: relative; display: block; width: 100%; height: 100%; }
.face2 img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.face2 img:first-child { clip-path: polygon(0 0, 0 100%, 100% 100%); }   /* first face on the LEFT (Caspa), diagonal bottom-left to top-right (user call 8/24) */
.face2 img:last-child { clip-path: polygon(0 0, 100% 0, 100% 100%); }    /* second face on the right (Distinct Motive) */
span.as-img.face2 { display: flex; overflow: hidden; }
/* no photo: the initial carries the tile, so it is set big rather than lost in
   the middle of an empty circle */
.r-img .ini {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: "Saira Condensed", sans-serif; font-size: 42px; font-weight: 800; letter-spacing: .02em;
  color: rgba(226, 218, 255, .72);
  background: linear-gradient(150deg, rgba(255, 43, 214, .18), rgba(63, 125, 255, .12));
  text-shadow: 0 0 18px rgba(255, 43, 214, .35);
}
.r-n { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; min-width: 0; font-size: 12px; font-weight: 700; line-height: 1.25;
  overflow: hidden; }
.r-m { display: block; min-width: 0; font-size: 10px; color: var(--faint); margin-top: 2px; line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* artist sheet - artwork and name side by side so the name gets the full width
   and stops orphaning one word onto a second line */
.as-top { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
.as-img {
  flex: none; width: 84px; height: 84px; border-radius: 16px; object-fit: cover;
  border: 1px solid var(--gbrd2); box-shadow: 0 4px 14px rgba(255, 43, 214, .22);   /* stays inside the sheet padding */
}
.as-ini { display: flex; align-items: center; justify-content: center; background: var(--glass2);
  font-family: "Saira Condensed", sans-serif; font-size: 30px; font-weight: 800; color: var(--faint); }
.as-id { flex: 1; min-width: 0; }
.as-name {
  font-size: 26px !important; line-height: 1.05; margin-bottom: 8px !important;
  overflow-wrap: anywhere; hyphens: none;
}
.as-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.as-chip {
  font-size: 10px; font-weight: 600; padding: 4px 8px; border-radius: 999px;
  background: rgba(255, 43, 214, .14); border: 1px solid rgba(255, 43, 214, .3); color: #ffb3ec;
}
.as-chip.dim { background: rgba(255, 255, 255, .06); border-color: var(--gbrd); color: var(--dim); }
.as-bio { font-size: 13px; line-height: 1.6; color: var(--dim); margin-bottom: 14px; }

.as-track {
  display: flex; align-items: center; gap: 12px; padding: 11px 13px; border-radius: 14px;
  background: linear-gradient(120deg, rgba(29, 185, 84, .14), rgba(255, 43, 214, .08)), var(--glass2);
  border: 1px solid rgba(29, 185, 84, .32);
}
.as-play {
  flex: none; width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: #1db954; color: #06210f; box-shadow: 0 0 16px rgba(29, 185, 84, .5);
}
.as-play svg { width: 14px; height: 14px; margin-left: 2px; }
.as-tb { flex: 1; min-width: 0; }
.as-k { display: block; font-size: 10px; letter-spacing: .18em; text-transform: uppercase; color: var(--faint); margin-bottom: 2px; }
.as-tb b { display: block; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.as-go { flex: none; font-size: 10px; font-weight: 800; letter-spacing: .16em; color: #7ef2a6; }
.sh-at { text-transform: none; letter-spacing: .01em; color: var(--dim); font-weight: 600; margin-left: 4px; }

/* Get Freaky header on the festival page (the app bar is MASV-only now) */
.gf-head { text-align: center; margin-bottom: 14px; }
.gf-mark { width: min(300px, 78vw); margin-bottom: 14px; }
.gf-mark .gf-chrome { filter: brightness(1.3) saturate(1.15) drop-shadow(0 0 12px rgba(130, 175, 255, .55)); }
/* the other festival tabs carry the mark small - the page title does the talking */
.gf-mark.sm { width: min(190px, 52vw); margin-bottom: 6px; }

/* ---------- home ---------- */
.hero {
  position: relative; display: block; border-radius: 22px; overflow: hidden; cursor: pointer;
  border: 1px solid var(--gbrd2);
  box-shadow: 0 10px 44px rgba(139, 61, 255, .3), 0 4px 22px rgba(255, 43, 214, .18);
}
.hero img { width: 100%; height: auto; }
.hero .hero-cta {
  position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%);
  padding: 8px 16px; border-radius: 999px; white-space: nowrap;
  background: rgba(7, 3, 15, .66); border: 1px solid rgba(255, 255, 255, .2);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  font-size: 11px; font-weight: 800; letter-spacing: .22em;
}
.hero .arr { color: var(--green); }

.tickets { display: grid; gap: 10px; }
.tik {
  position: relative; display: flex; align-items: center; gap: 13px; padding: 15px 14px 15px 18px;
  background: var(--glass); border: 1px solid var(--gbrd); border-radius: 16px;
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  overflow: hidden; transition: transform .15s;
}
.tik:active { transform: scale(.98); }
.tik::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--tikc, var(--pink)); box-shadow: 0 0 18px var(--tikc, var(--pink)); }
.tik .t-body { flex: 1; min-width: 0; }
.tik .t-tier { display: block; font-family: "Saira Condensed", sans-serif; font-size: 19px; font-weight: 800; letter-spacing: .04em; }
.tik .t-sub { display: block; font-size: 12px; color: var(--dim); margin-top: 2px; }
/* the ticket CTA is the money button - it gets the tier colour, a lit edge and a
   slow sheen sweeping across it, so it reads as the live thing on the page */
.tik .t-go {
  position: relative; flex: none; overflow: hidden;
  font-size: 11px; font-weight: 800; letter-spacing: .14em; padding: 10px 16px; border-radius: 999px;
  color: #0a0518; background: linear-gradient(100deg, var(--tikc), #fff 58%, var(--tikc));
  background-size: 220% 100%; animation: sheen 4.5s ease-in-out infinite;
  box-shadow: 0 4px 18px color-mix(in srgb, var(--tikc) 55%, transparent), inset 0 1px 0 rgba(255, 255, 255, .55);
  border: 0;
}
@keyframes sheen { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
.tik { position: relative; overflow: hidden; }
/* a soft wash of the tier colour bleeding in from the marker edge */
.tik::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, color-mix(in srgb, var(--tikc) 20%, transparent), transparent 46%);
}
.tik > * { position: relative; z-index: 1; }
@media (prefers-reduced-motion: reduce) { .tik .t-go { animation: none; background-position: 0 50%; } }
.pay-note { margin-top: 9px; font-size: 11px; color: var(--faint); text-align: center; }

.linklist { display: grid; gap: 9px; }
.lrow {
  display: flex; align-items: center; gap: 12px; padding: 13px 14px;
  background: var(--glass2); border: 1px solid var(--gbrd); border-radius: 14px;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); transition: transform .15s;
}
.lrow:active { transform: scale(.98); }
.lrow.svcline:active { transform: none; }   /* static info rows, not links */
.lrow .ic {
  position: relative; flex: none; width: 34px; height: 34px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .07); border: 1px solid var(--gbrd); color: var(--lc, var(--cyan));
}
/* iOS notification badge - how many days the pass covers */
.lrow .ic .badge {
  position: absolute; top: -6px; right: -6px; min-width: 19px; height: 19px; padding: 0 5px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 999px; background: #ff3b30; border: 2px solid #0b0518;
  color: #fff; font-style: normal; font-size: 11px; font-weight: 700; line-height: 1;
  box-shadow: 0 2px 8px rgba(255, 59, 48, .5);
}
.lrow .ic svg { width: 17px; height: 17px; }
.lrow .l-body { flex: 1; min-width: 0; }
.lrow .l-t { display: block; font-size: 14px; font-weight: 700; }
.lrow .l-s { display: block; font-size: 12px; color: var(--dim); margin-top: 1px; }
.lrow .l-s2 { display: block; font-size: 12px; color: var(--faint); margin-top: 4px; line-height: 1.4; }
.lrow .l-s .l-hl { color: var(--green); font-weight: 700; font-style: normal; text-shadow: 0 0 10px rgba(182, 255, 63, .35); }
.lrow .chev { flex: none; color: var(--faint); }

.info-meta { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; margin-bottom: 9px; }
.im {
  padding: 12px 12px; border-radius: 14px; background: var(--glass2); border: 1px solid var(--gbrd); text-align: center;
}
.im b { display: block; font-family: "Saira Condensed", sans-serif; font-size: 17px; font-weight: 800; letter-spacing: .03em; }
.im span { display: block; font-size: 10px; letter-spacing: .2em; text-transform: uppercase; color: var(--faint); margin-top: 3px; }

/* signup incentive card */
.perks {
  margin-bottom: 6px; padding: 16px 15px 15px; border-radius: 18px;
  background: linear-gradient(165deg, rgba(255, 43, 214, .12), rgba(63, 125, 255, .08)), var(--glass);
  border: 1px solid rgba(255, 43, 214, .3);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  box-shadow: 0 8px 30px rgba(255, 43, 214, .14);
}
.pk-h { margin-bottom: 13px; }
.pk-eyebrow { display: block; font-size: 10px; letter-spacing: .28em; text-transform: uppercase; color: var(--green); font-weight: 700; text-shadow: 0 0 12px rgba(150, 255, 46, .5); }
.pk-t { display: block; margin-top: 4px; font-family: "Saira Condensed", sans-serif; font-size: 21px; font-weight: 800; text-transform: uppercase; letter-spacing: .02em; }
.pk-list { display: grid; gap: 8px; margin-bottom: 13px; }
.pk { display: flex; gap: 10px; align-items: flex-start; }
.pk-ic { flex: none; width: 6px; height: 6px; margin-top: 7px; border-radius: 50%; background: var(--lc, var(--pink)); box-shadow: 0 0 8px var(--lc, var(--pink)); }   /* plain bullets (user call 8/24) */
.pk-ic svg { display: none; }
.pk-b { flex: 1; min-width: 0; }
.pk-b b { display: block; font-size: 13px; font-weight: 700; line-height: 1.3; }
.pk-b i { display: block; font-style: normal; font-size: 12px; color: var(--dim); margin-top: 2px; line-height: 1.45; }
.pk-cta { width: 100%; }
.pk-alt {
  display: block; width: 100%; margin-top: 4px; padding: 12px 0; min-height: 44px; cursor: pointer;
  background: none; border: 0; color: var(--dim); font-family: inherit; font-size: 12px;
  text-decoration: underline; text-underline-offset: 3px;
}

/* 9:16 recap video loops - GF 2025 aftermath */
.vidrow { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; margin-bottom: 9px; }
.vid {
  position: relative; display: block; aspect-ratio: 9 / 16; border-radius: 14px; overflow: hidden;
  border: 1px solid var(--gbrd); background: #0a0518;
}
.vid video { width: 100%; height: 100%; object-fit: cover; display: block; }

/* horizontal photo strip - GF 2025 aftermath */
.gallery {
  display: flex; gap: 9px; overflow-x: auto; -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity; padding-bottom: 6px; margin: 0 -16px; padding-left: 16px; padding-right: 16px;
  scrollbar-width: none;
}
.gallery::-webkit-scrollbar { display: none; }
.gallery img {
  flex: none; height: 158px; width: auto; border-radius: 14px;
  border: 1px solid var(--gbrd); scroll-snap-align: start;
}

.socials { display: flex; gap: 10px; margin-top: 12px; justify-content: center; }
/* round social buttons - used on Home and as the artist-sheet actions */
/* social glyphs, gain.fm lander style: bare icons, muted white, no disc behind
   them. 44px hit area so they stay tappable at the small visual size. */
.soc {
  width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
  background: none; border: 0; color: rgba(255, 255, 255, .55);
  transition: color .18s, transform .14s;
}
.soc svg { width: 23px; height: 23px; }
.soc:hover { color: #fff; }
.soc:active { color: #fff; transform: scale(.92); }
.socials { gap: 18px; }
.socbtns { display: flex; gap: 22px; justify-content: center; margin-top: 18px; }

/* album sheet + tracklist */
.alb-head { display: flex; gap: 14px; align-items: center; margin-bottom: 16px; }
.alb-art { flex: none; width: 88px; height: 88px; border-radius: 12px; border: 1px solid var(--gbrd2); }
.alb-meta { flex: 1; min-width: 0; }
.alb-t { font-size: 21px !important; line-height: 1.12; margin: 4px 0 8px !important; }
.tracks { display: grid; gap: 2px; }
.trk { display: flex; align-items: baseline; gap: 8px; padding: 8px 10px; border-radius: 10px; color: var(--ink); }
.trk:active { background: rgba(255, 255, 255, .07); }
.trk-b { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 6px; overflow: hidden; white-space: nowrap; }
.trk-n { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; }
.trk-a { font-size: 11px; color: var(--faint); flex: none; }
.trk-d { flex: none; font-size: 12px; color: var(--faint); font-variant-numeric: tabular-nums; }

/* in-app embed sheet */
.emb-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.emb-head b { font-family: "Saira Condensed", sans-serif; font-size: 20px; text-transform: uppercase; letter-spacing: .02em; }
.emb-out { font-size: 11px; color: var(--dim); text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }
.emb {
  width: 100%; height: min(62vh, 520px); border: 1px solid var(--gbrd); border-radius: 14px;
  background: #fff; display: block;
}

/* the Get Freaky button at the foot of Home: the real lockup on a dark card */
.gf-home-cta {
  display: block; width: 100%; margin: 34px 0 0; padding: 22px 18px 18px;
  border-radius: 22px; border: 1px solid rgba(255, 43, 214, .35);
  background: linear-gradient(180deg, rgba(40, 10, 50, .75), rgba(12, 4, 22, .9));
  box-shadow: 0 10px 40px rgba(0, 0, 0, .5), 0 0 30px rgba(255, 43, 214, .18), inset 0 1px 0 rgba(255, 255, 255, .06);
  color: var(--ink); text-align: center; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: transform .15s ease, box-shadow .2s ease;
}
.gf-home-cta:active { transform: scale(.985); box-shadow: 0 6px 24px rgba(0, 0, 0, .5), 0 0 40px rgba(255, 43, 214, .3); }
.gf-home-cta .gflock { width: min(230px, 62vw); }
.gf-home-go { display: block; margin-top: 12px; font-size: 11px; font-weight: 800; letter-spacing: .22em; text-transform: uppercase; color: var(--pink); }
.foot-brand { margin-top: 30px; text-align: center; }
.foot-brand img { width: 120px; margin: 0 auto 9px; opacity: .85; }
.foot-brand span { display: block; font-size: 10px; letter-spacing: .24em; text-transform: uppercase; color: var(--faint); }
/* the logo says MASV Music Group already - the line above it only says "Presented by" */
.foot-brand .pb { margin-bottom: 8px; }
.foot-brand .pb + img { margin-bottom: 0; }
.foot-brand i { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 6px; font-style: normal; font-size: 10px; color: rgba(226, 218, 255, .22); letter-spacing: .1em; }
.foot-pk { display: inline-flex; width: 14px; height: 14px; color: rgba(255, 138, 42, .45); transition: color .3s, filter .3s; }
.foot-pk svg { width: 100%; height: 100%; }
body.nightmare .foot-pk { color: var(--orange); filter: drop-shadow(0 0 6px rgba(255, 138, 42, .9)); }
/* a ghost that peeks up from behind the nav pill, then ducks (gf-app.js fires .up every 45-80s) */
.nav-peek { position: fixed; left: calc(50% + 96px); bottom: calc(12px + var(--sab) + 28px); z-index: 59; width: 26px; color: #fff;
  opacity: 0; pointer-events: none; filter: drop-shadow(0 0 10px rgba(255, 255, 255, .5)); transform: translateY(30px); }
.nav-peek.up { animation: nav-peek 2.6s ease-in-out; }
@keyframes nav-peek { 0% { transform: translateY(30px); opacity: 0; } 25% { transform: translateY(-14px); opacity: .9; } 45% { transform: translateY(-10px); } 70% { transform: translateY(-14px); opacity: .9; } 100% { transform: translateY(30px); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .nav-peek { display: none; } }

/* ---------- shows ---------- */
.stat-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; margin-bottom: 16px; }
.stat { padding: 12px 6px; text-align: center; background: var(--glass2); border: 1px solid var(--gbrd); border-radius: 14px; }
.stat b { display: block; font-family: "Saira Condensed", sans-serif; font-size: 24px; font-weight: 800; line-height: 1; }
.stat span { display: block; font-size: 10px; letter-spacing: .22em; text-transform: uppercase; color: var(--faint); margin-top: 4px; }

.feat {
  position: relative; border-radius: 20px; overflow: hidden; margin-bottom: 20px;
  border: 1px solid var(--gbrd2);
  background: var(--glass);
  box-shadow: 0 12px 40px rgba(255, 43, 214, .2), 0 6px 24px rgba(63, 125, 255, .18);
}
.feat .f-img { position: relative; }
.feat .f-img img { width: 100%; height: auto; }
.feat .f-img::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, transparent 55%, rgba(13, 6, 24, .96) 100%); }
.feat .f-tag {
  position: absolute; top: 10px; left: 10px; z-index: 2;
  font-size: 10px; font-weight: 800; letter-spacing: .2em; padding: 6px 10px; border-radius: 999px;
  background: var(--grad-cta); box-shadow: 0 4px 16px rgba(255, 43, 214, .5);
}
.feat .f-body { position: relative; padding: 0 16px 16px; margin-top: -34px; z-index: 2; }
.feat .f-date { font-size: 13px; }
.feat .f-title { font-family: "Saira Condensed", sans-serif; font-size: 27px; font-weight: 800; text-transform: uppercase; letter-spacing: .02em; margin-top: 4px; }
.feat .f-meta { font-size: 12px; color: var(--dim); margin-top: 3px; }
.feat .f-btns { display: flex; gap: 9px; margin-top: 13px; }
.sc-btn {
  display: inline-block; text-align: center; padding: 12px 18px; border-radius: 13px; cursor: pointer;
  background: var(--grad-cta); color: #fff; font-size: 12px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  box-shadow: 0 6px 22px rgba(255, 43, 214, .35); border: 0; transition: transform .15s;
}
.sc-btn:active { transform: scale(.97); }
.sc-btn.ghost { background: rgba(255, 255, 255, .08); border: 1px solid var(--gbrd2); box-shadow: none; }
.feat .f-btns .sc-btn { flex: 1; }

.month-label { font-size: 11px; font-weight: 700; letter-spacing: .3em; text-transform: uppercase; color: var(--dim); margin: 20px 2px 10px; display: flex; align-items: center; gap: 10px; }
.month-label::after { content: ""; flex: 1; height: 1px; background: linear-gradient(90deg, rgba(255, 255, 255, .14), transparent); }

.shows-list { display: grid; gap: 9px; }
.srow {
  display: flex; align-items: center; gap: 12px; padding: 10px;
  background: var(--glass2); border: 1px solid var(--gbrd); border-radius: 16px;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); transition: transform .15s;
}
.srow:active { transform: scale(.985); }
.srow .s-img { flex: none; width: 62px; height: 62px; border-radius: 12px; overflow: hidden; border: 1px solid var(--gbrd); }
.srow .s-img img { width: 100%; height: 100%; object-fit: cover; }
.srow .s-body { flex: 1; min-width: 0; }
.srow .s-t { display: block; font-size: 14px; font-weight: 700; line-height: 1.25; overflow: hidden; text-overflow: ellipsis; }
.srow .s-d { display: block; font-size: 12px; font-weight: 700; color: var(--green); margin-top: 3px; }
.srow .s-m { display: block; font-size: 12px; color: var(--dim); margin-top: 2px; }
.srow .s-m b { color: var(--green); font-weight: 700; }
/* door policy, straight off the Tixr listing */
.srow .s-m .age {
  font-style: normal; font-size: 10px; font-weight: 700; letter-spacing: .06em;
  padding: 2px 6px; margin-left: 4px; border-radius: 999px;
  background: rgba(255, 255, 255, .09); border: 1px solid var(--gbrd); color: var(--dim);
}
.srow .s-right { flex: none; text-align: right; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.srow .s-price { font-size: 11px; font-weight: 700; color: var(--ink); padding: 4px 9px; border-radius: 999px; background: rgba(255, 255, 255, .08); border: 1px solid var(--gbrd); }
.srow .chev { color: var(--faint); }
.chev svg { width: 15px; height: 15px; display: block; }
.shows-foot { margin: 20px 0 22px; text-align: center; font-size: 11px; color: var(--faint); }

/* ---------- lineup ---------- */
.poster {
  display: block; border-radius: 20px; overflow: hidden; border: 1px solid var(--gbrd2); margin-bottom: 14px;
  box-shadow: 0 10px 40px rgba(139, 61, 255, .28), 0 4px 20px rgba(255, 43, 214, .16);
}
.poster img { width: 100%; height: auto; }
.search {
  width: 100%; margin-bottom: 14px; padding: 12px 14px; border-radius: 13px;
  background: rgba(10, 5, 22, .6); border: 1px solid var(--gbrd); color: var(--ink);
  font-family: inherit; font-size: 15px; outline: none;
}
.search:focus { border-color: rgba(255, 43, 214, .5); }
.search::placeholder { color: var(--faint); }

.acts { display: grid; gap: 8px; }
.act {
  display: flex; align-items: center; gap: 11px; padding: 8px 12px 8px 8px;
  background: var(--glass2); border: 1px solid var(--gbrd); border-radius: 14px;
  transition: transform .15s, border-color .2s;
}
.act:active { transform: scale(.985); }
.a-img {
  flex: none; position: relative; width: 46px; height: 46px; border-radius: 50%; overflow: hidden;
  border: 1px solid var(--gbrd2); background: var(--glass);
}
.a-img img { width: 100%; height: 100%; object-fit: cover; }
.a-img .ini {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: "Saira Condensed", sans-serif; font-size: 16px; font-weight: 800; color: var(--faint);
}
.act .a-n { flex: 1; min-width: 0; font-size: 15px; font-weight: 600; }
.act .a-p { flex: none; width: 15px; height: 15px; color: var(--faint); }
.act .a-p svg { width: 100%; height: 100%; display: block; }

/* headliners and special guests get the billing weight the poster gives them:
   a big portrait with the name over it, rather than another row in the list */
.acts.head, .acts.guest { grid-template-columns: 1fr 1fr; }
.acts.head .act, .acts.guest .act {
  position: relative; display: block; padding: 0; overflow: hidden; border-radius: 18px;
  border-color: rgba(255, 43, 214, .38);
}
.acts.guest .act { border-color: rgba(65, 200, 255, .32); }
.acts.head .a-img, .acts.guest .a-img {
  width: 100%; height: auto; aspect-ratio: 1; border-radius: 0; border: 0;
}
.acts.head .act::after, .acts.guest .act::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 38%, rgba(10, 5, 22, .92) 100%);
}
.acts.head .a-n, .acts.guest .a-n {
  position: absolute; left: 0; right: 0; bottom: 9px; z-index: 2; padding: 0 8px; text-align: center;
  font-family: "Saira Condensed", sans-serif; font-weight: 800; text-transform: uppercase; letter-spacing: .02em;
  text-shadow: 0 2px 12px rgba(0, 0, 0, .9);
}
.acts.head .a-n { font-size: 21px; }
.acts.guest .a-n { font-size: 16px; }
.acts.head .a-p, .acts.guest .a-p {
  position: absolute; top: 8px; right: 8px; z-index: 2; width: 22px; height: 22px; padding: 6px;
  border-radius: 50%; background: rgba(8, 4, 18, .6); border: 1px solid rgba(255, 255, 255, .28); color: #fff;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.empty { padding: 26px 16px; text-align: center; font-size: 13px; color: var(--faint); }

/* ---------- map ---------- */
.mapwrap { position: relative; }
.mapframe {
  height: min(92vw, 540px); overflow: auto; -webkit-overflow-scrolling: touch;
  border-radius: 20px; border: 1px solid var(--gbrd2); background: #0a0518;
  box-shadow: 0 10px 40px rgba(139, 61, 255, .25), 0 4px 18px rgba(255, 43, 214, .15);
  overscroll-behavior: contain; scrollbar-width: none;
}
.mapframe::-webkit-scrollbar { display: none; }
.maplayer { position: relative; width: 100%; }
.mapframe img { width: 100%; min-width: 100%; height: auto; display: block; }
/* pin overlay: invisible until a key row is tapped, so the art reads clean by default */
.pins { position: absolute; inset: 0; pointer-events: none; }
.pin { position: absolute; width: 26px; height: 26px; margin: -13px 0 0 -13px; border-radius: 50%; opacity: 0; transition: opacity .2s; }
.pins .pin.lit {
  opacity: 1; border: 2.5px solid #fff;
  box-shadow: 0 0 0 3px rgba(255, 43, 214, .55), 0 0 18px 4px rgba(255, 43, 214, .8);
  animation: pinpulse 1.5s ease-out infinite;
}
@keyframes pinpulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.18); } }
.map-zoom { position: absolute; right: 10px; bottom: 10px; display: flex; flex-direction: column; gap: 7px; }
.map-zoom button {
  width: 36px; height: 36px; border-radius: 12px; cursor: pointer;
  background: rgba(12, 6, 26, .8); border: 1px solid var(--gbrd2); color: var(--ink);
  font-size: 19px; font-weight: 700; line-height: 1;
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.map-hint { margin-top: 10px; text-align: center; font-size: 11px; color: var(--faint); }
/* Experiences popout: the gallery as a 2-up grid inside the sheet */
.xp-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 14px; }
.xp-grid img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 12px; border: 1px solid var(--gbrd); }
.sheet .pk-list { text-align: left; }
.sheet .acc { text-align: left; }

/* stage list - numbers now, names when the lineup lands */
.stagelist { display: grid; gap: 8px; }
.stg {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px;
  background: var(--glass2); border: 1px solid var(--gbrd); border-radius: 14px;
}
.stg .n {
  flex: none; width: 34px; height: 34px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  font-family: "Saira Condensed", sans-serif; font-size: 18px; font-weight: 800; color: #0a0518;
  background: var(--sc, var(--pink)); box-shadow: 0 0 16px var(--sc, var(--pink));
}
.stg .sb { flex: 1; min-width: 0; }
.stg .sb b { display: block; font-size: 14px; font-weight: 700; }
.stg .sb i { display: block; font-style: normal; font-size: 12px; color: var(--dim); margin-top: 1px; }

/* printed-icon legend */
.mapkey { display: grid; grid-template-columns: repeat(2, 1fr); gap: 7px; }
.mk {
  display: flex; align-items: center; gap: 9px; padding: 8px 10px; width: 100%;
  background: var(--glass2); border: 1px solid var(--gbrd); border-radius: 12px;
  cursor: pointer; font-family: inherit; text-align: left; transition: border-color .18s, background .18s, transform .12s;
}
.mk:active { transform: scale(.97); }
.mk.on { border-color: rgba(255, 43, 214, .65); background: rgba(255, 43, 214, .12); }
.mk.on .kl { color: var(--ink); }
.mk .kl { flex: 1; min-width: 0; }
.mk .kn { flex: none; font-size: 10px; font-weight: 700; color: var(--faint); }
.mapkey-note { margin-top: 10px; text-align: center; font-size: 12px; color: var(--green); font-weight: 600; letter-spacing: .04em; }
.mk .kc {
  flex: none; width: 26px; height: 26px; border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  background: var(--kc); border: 1px solid rgba(0, 0, 0, .35);
}
.mk .kc svg { width: 15px; height: 15px; display: block; color: #0d0618; }
.mk span { font-size: 12px; color: var(--dim); font-weight: 600; }
.tba-kick { font-size: 11px; font-weight: 800; letter-spacing: .26em; color: var(--dim); margin-bottom: 10px; }
.tba-big { font-family: "Saira Condensed", sans-serif; font-size: 74px; font-weight: 800; line-height: 1; }
.tba-sub { margin: 14px auto 0; max-width: 300px; font-size: 13px; color: var(--dim); line-height: 1.6; }

.venue-card {
  margin-top: 12px; padding: 16px; border-radius: 16px; text-align: center;
  background: var(--glass2); border: 1px solid var(--gbrd);
}
.vc-name { font-family: "Saira Condensed", sans-serif; font-size: 20px; font-weight: 800; }
.vc-addr { font-size: 12px; color: var(--dim); margin-top: 4px; }
.vc-map { position: relative; display: block; width: 100%; margin-top: 12px; padding: 0; border: 1px solid var(--gbrd2); border-radius: 14px; overflow: hidden; background: #0b0518; cursor: pointer; }
.vc-map img { width: 100%; display: block; }
.vm-more { position: absolute; right: 10px; bottom: 10px; padding: 6px 12px; border-radius: 999px; font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ink); background: rgba(10, 4, 24, .74); border: 1px solid var(--gbrd2); }
.vm-dot { position: absolute; width: 14px; height: 14px; margin: -7px 0 0 -7px; border-radius: 50%; background: #3fa9ff; border: 2.5px solid #fff; box-shadow: 0 0 0 4px rgba(63, 169, 255, .25), 0 0 14px rgba(63, 169, 255, .8); pointer-events: none; }
.vm-wrap { position: relative; border-radius: 14px; overflow: hidden; border: 1px solid var(--gbrd2); }
.vm-wrap img { width: 100%; display: block; }
.vc-btn { display: inline-flex; align-items: center; gap: 8px; }
.vc-nav { width: 15px; height: 15px; color: var(--pink); filter: drop-shadow(0 0 6px rgba(255, 43, 214, .6)); }
.vc-btn {
  display: inline-flex; margin-top: 12px; padding: 10px 18px; border-radius: 999px; font-size: 11px; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase; color: var(--pink);
  background: rgba(7, 3, 15, .55); border: 1px solid rgba(255, 43, 214, .6);
  box-shadow: 0 0 14px rgba(255, 43, 214, .18);   /* outline pill, same family as the travel rows (user call 8/24) */
}
.vc-btn .vc-nav { color: var(--pink); filter: none; }
/* travel rows: the same outline pill on the right instead of a chevron */
.lrow .l-go {
  flex: none; padding: 9px 14px; border-radius: 999px; font-size: 11px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: var(--pink); background: rgba(7, 3, 15, .55); border: 1px solid rgba(255, 43, 214, .6); box-shadow: 0 0 14px rgba(255, 43, 214, .18);
}
.map-cta { margin-top: 22px; text-align: center; }
.mc-title { font-size: 12px; letter-spacing: .2em; text-transform: uppercase; color: var(--dim); font-weight: 700; margin-bottom: 11px; }

/* ---------- nav ---------- */
.nav {
  /* centred WITHOUT transform: a transformed fixed element loses viewport
     anchoring in WebKit mid-scroll (the pill floated into the page on iPhone,
     seen 8/23 night) - left/right + margin auto pins it to the real viewport */
  position: fixed; left: 0; right: 0; margin: 0 auto; width: max-content;
  bottom: calc(12px + var(--sab)); z-index: 60;
  display: flex; align-items: center; gap: 6px;
  padding: 7px 12px;
  background: rgba(16, 8, 32, .72);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 999px;
  backdrop-filter: blur(30px) saturate(1.8);
  -webkit-backdrop-filter: blur(30px) saturate(1.8);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 14px 44px rgba(0, 0, 0, .55), 0 2px 14px rgba(255, 43, 214, .1);
}
/* IG-style: icons only, the pink ring rides whichever tab is selected */
.nav button { background: none; border: 0; cursor: pointer; padding: 0; }
.nav .nring {
  display: flex; align-items: center; justify-content: center;
  width: 50px; height: 50px; border-radius: 50%;
  border: 2px solid transparent; color: var(--dim);
  transition: border-color .22s, box-shadow .22s, color .22s, background .22s;
}
.nav .nring svg { width: 22px; height: 22px; }
/* the centre tab (MASV) reads a touch larger - it is the app's home */
.nav button.center .nring { width: 56px; height: 56px; }
.nav .masv-m { width: 29px; height: 29px; }
.nav button.center.active .masv-m { filter: drop-shadow(0 0 6px rgba(255, 255, 255, .5)); }
.nav button.center.active .masv-m .chev { filter: drop-shadow(0 0 5px rgba(255, 43, 214, .95)); }
.nav .nring img { opacity: .55; transition: opacity .22s; }
.nav button.active .nring {
  color: #fff;
  border-color: rgba(255, 43, 214, .85);
  background: radial-gradient(circle at 32% 28%, rgba(255, 255, 255, .13), rgba(255, 255, 255, .02)), var(--glass);
  box-shadow: 0 0 22px rgba(255, 43, 214, .5), inset 0 0 14px rgba(255, 43, 214, .12);
}
.nav button.active .nring img { opacity: 1; }
/* the pumpkin tab is a jack-o'-lantern: picked = lit from inside, orange */
.nav button[data-view="fest"].active .nring { color: var(--orange); border-color: rgba(255, 138, 42, .9);
  box-shadow: 0 0 22px rgba(255, 138, 42, .55), inset 0 0 14px rgba(255, 138, 42, .14); }
.nav button[data-view="fest"].active .nring svg { filter: drop-shadow(0 0 8px rgba(255, 138, 42, .95)); animation: candle 3.3s ease-in-out infinite; }
.nav button.active .nring svg { filter: drop-shadow(0 0 7px rgba(255, 43, 214, .8)); }

/* ---------- account sheet ---------- */
.modal { position: fixed; inset: 0; z-index: 80; display: none; }
.modal.open { display: block; }
.scrim { position: absolute; inset: 0; background: rgba(4, 2, 10, .6); backdrop-filter: blur(9px); -webkit-backdrop-filter: blur(9px); }
.sheet {
  /* match the app column (.view is max-width 560) so on a desktop window the
     sheet stays a phone-width panel instead of stretching across the screen */
  /* centred with auto margins, NOT translateX(-50%): the slide-up keyframe
     below owns `transform`, and a translateX there made the sheet open on the
     right half of a desktop window and snap to the middle when it finished */
  position: absolute; left: 0; right: 0; margin: 0 auto;
  width: min(560px, 100%); bottom: 0; max-height: 82vh;
  display: flex; flex-direction: column; overflow: hidden;   /* body scrolls in .sheet-scroll; grab/X/title stay put */
  background: rgba(18, 9, 34, .96);
  border-top: 1px solid rgba(255, 255, 255, .14);
  border-radius: 26px 26px 0 0;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07), 0 -18px 60px rgba(0, 0, 0, .5);
  padding: 12px 20px calc(26px + var(--sab));
  backdrop-filter: blur(26px); -webkit-backdrop-filter: blur(26px);
  animation: sheetup .28s ease;
}
@keyframes sheetup { from { transform: translateY(40px); opacity: 0; } to { transform: none; opacity: 1; } }
.sheet .grab { flex: none; width: 40px; height: 4px; border-radius: 4px; background: rgba(255, 255, 255, .18); margin: 2px auto 16px; }
.sheet-scroll { overflow-y: auto; min-height: 0; scrollbar-width: none; }
.sheet-scroll::-webkit-scrollbar { display: none; }
.sheet-head { flex: none; padding-bottom: 10px; margin-bottom: 12px; border-bottom: 1px solid var(--gbrd); }
.sheet .sheet-head h2 { margin-bottom: 0; }
.sheet-x { position: absolute; top: 14px; right: 14px; width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--gbrd2);
  background: rgba(255, 255, 255, .08); color: var(--dim); cursor: pointer; padding: 8px; z-index: 3;
  display: flex; align-items: center; justify-content: center; transition: color .15s, transform .12s; }
.sheet-x svg { width: 100%; height: 100%; }
.sheet-x:active { transform: scale(.92); color: var(--ink); }
.sheet-x + * { margin-top: 30px; }   /* the first thing in a sheet clears the close button */
.sheet h2 { font-size: 24px; font-weight: 800; text-transform: uppercase; letter-spacing: .03em; margin-bottom: 14px; }
.acct-row { margin-bottom: 11px; }
.acct-row label { display: block; font-size: 10px; letter-spacing: .18em; text-transform: uppercase; color: var(--faint); margin-bottom: 4px; }
.acct-row .val { font-size: 15px; }
.acct-row input {
  width: 100%; background: rgba(10, 5, 22, .6); border: 1px solid var(--gbrd); border-radius: 11px;
  color: var(--ink); font-family: inherit; font-size: 15px; padding: 10px 12px; outline: none;
}
.sheet-btns { display: grid; gap: 9px; margin-top: 18px; }
.sheet-btns.faq-top { margin: 0 0 14px; }
.sh-btn {
  display: block; width: 100%; padding: 13px 14px; border-radius: 13px; border: 1px solid var(--gbrd2); cursor: pointer;
  background: rgba(255, 255, 255, .07); color: var(--ink);
  font-family: inherit; font-size: 13px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sh-btn.primary { background: var(--grad-cta); border: 0; box-shadow: 0 6px 20px rgba(255, 43, 214, .3); }
.sh-btn.danger { color: #ff8fa5; border-color: rgba(255, 59, 92, .4); background: rgba(255, 59, 92, .08); }
.sheet .note { margin-top: 12px; font-size: 12px; color: var(--faint); line-height: 1.5; text-align: center; }

/* small screens */
@media (max-width: 360px) {
  .cd .u { min-width: 50px; }
  .vhead h1 { font-size: 34px; }
}

/* ============================================================
   v1.1 additions: calendar, hearts, show + info sheets, spider
   ============================================================ */

/* ---- calendar with dots ---- */

/* ---- hearts ---- */
.rwrap { position: relative; }
.fav {
  position: absolute; top: -2px; right: -2px; width: 40px; height: 40px; padding: 11px;
  border-radius: 50%; cursor: pointer; z-index: 2;
  background: rgba(8, 4, 18, .66); border: 1px solid rgba(255, 255, 255, .22); color: rgba(255, 255, 255, .7);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  transition: transform .16s, color .16s, border-color .16s;
}
.fav svg { width: 100%; height: 100%; display: block; }
.fav.on { color: var(--pink); border-color: rgba(255, 43, 214, .7); fill: var(--pink); }
.fav.on svg { fill: var(--pink); }
.fav:active { transform: scale(.86); }
.favbtn {
  display: flex; align-items: center; justify-content: center; gap: 9px; width: 100%; margin-top: 16px;
  padding: 13px 0; border-radius: 13px; cursor: pointer; font-family: inherit;
  font-size: 13px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  background: rgba(255, 255, 255, .07); border: 1px solid var(--gbrd2); color: var(--ink);
}
.favbtn svg { width: 17px; height: 17px; }
.favbtn.on { background: rgba(255, 43, 214, .16); border-color: rgba(255, 43, 214, .6); color: #ffb3ec; }
.favbtn.on svg { fill: var(--pink); color: var(--pink); }
.fav-note { font-size: 12px; color: var(--dim); margin-bottom: 10px; line-height: 1.5; }

/* ---- show sheet ---- */
/* the whole show sheet fits without a scroll (user call 8/24): the square flyer
   is capped by height and everything under it is one size down */
.show-art { display: block; width: auto; max-width: 100%; max-height: 38vh; margin: 0 auto 10px; border-radius: 14px; border: 1px solid var(--gbrd2); }
.show-art + .alb-t { font-size: 19px; margin-bottom: 8px; }
.show-art ~ .as-chips .as-chip { font-size: 11px; padding: 4px 10px; }
.show-art ~ .buy { padding: 12px; font-size: 13px; }
.show-art.wide { aspect-ratio: 2 / 1; object-fit: cover; }
.show-venue { margin: 10px 0; padding: 9px 12px; border-radius: 12px; background: var(--glass2); border: 1px solid var(--gbrd); }
.show-venue b { display: block; font-size: 14px; }
.show-venue span { display: block; font-size: 11px; color: var(--dim); margin-top: 2px; }
.buy {
  display: block; width: 100%; padding: 15px 0; border-radius: 14px; text-align: center;
  background: linear-gradient(96deg, #2f7dff, #4aa8ff); color: #fff;
  font-size: 14px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  box-shadow: 0 8px 26px rgba(47, 125, 255, .45);
}
.buy:active { transform: scale(.985); }
.buy-sm {
  flex: none; font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  padding: 7px 12px; border-radius: 999px; color: #fff;
  background: linear-gradient(96deg, #2f7dff, #4aa8ff); box-shadow: 0 3px 12px rgba(47, 125, 255, .4);
}
.srow { width: 100%; text-align: left; font-family: inherit; color: var(--ink); cursor: pointer; }

/* ---- info sheets ---- */
.acc { display: grid; gap: 7px; }
.ac { background: var(--glass2); border: 1px solid var(--gbrd); border-radius: 12px; padding: 11px 13px; }
.ac summary { cursor: pointer; font-size: 14px; font-weight: 700; list-style: none; }
.ac summary::-webkit-details-marker { display: none; }
.ac summary::after { content: "+"; float: right; color: var(--faint); font-weight: 400; }
.ac[open] summary::after { content: "\2212"; }
.ac p { margin-top: 8px; font-size: 13px; line-height: 1.6; color: var(--dim); }
.bag { padding: 10px 12px; border-radius: 11px; background: var(--glass2); border: 1px solid var(--gbrd); }
.bag b { display: block; font-size: 13px; }
.bag span { display: block; font-size: 12px; color: var(--dim); margin-top: 2px; }
.pills { display: flex; flex-wrap: wrap; gap: 6px; }
.pills span { font-size: 11px; padding: 5px 10px; border-radius: 999px; border: 1px solid var(--gbrd); color: var(--dim); }
.pills.ok span { background: rgba(182, 255, 63, .08); border-color: rgba(182, 255, 63, .3); color: #d3ff8e; }
.pills.no span { background: rgba(255, 59, 92, .08); border-color: rgba(255, 59, 92, .3); color: #ff9db1; }
.sheet-note { margin-top: 10px; font-size: 11px; color: var(--faint); line-height: 1.55; text-align: center; }
.sheet-note a { text-decoration: underline; }
.al-hp { width: 14px; height: 14px; margin-right: 6px; vertical-align: -2px; }

/* ---- spider: abseils in on first open, then hangs and sways ----
   Three nested motions so none fight over `transform`: .spider drops (translateY
   with a spring overshoot), .sp-swing pendulums from the top of the silk, and
   .sp-legs flexes for a beat every 11s so it reads as alive rather than a sticker.
   Silk is a gradient - invisible where it leaves the app bar, bright and pink
   where it meets the spinnerets. Glow is the house --neonlit recipe, toned down. */
/* Off by default (user call 8/23) - the spiders only come out in Nightmare mode. */
.spider { display: none; position: fixed; top: 0; right: 22px; z-index: 5; pointer-events: none; width: 50px;
  animation: sp-drop 3.6s cubic-bezier(.22, 1.2, .36, 1) .6s both; }
body.nightmare .spider { display: none; }   /* spiders retired 8/24 (user call) */
.sp-swing { transform-origin: 50% 0; animation: sp-sway 7s ease-in-out 4.2s infinite alternate; }
.sp-thread { display: block; width: 1.5px; height: 64px; margin: 0 auto;
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, .22) 35%, rgba(255, 255, 255, .55) 92%, rgba(255, 43, 214, .9) 100%); }
.spider svg { display: block; width: 50px; height: auto; overflow: visible;
  filter: drop-shadow(0 0 5px rgba(255, 43, 214, .55)) drop-shadow(0 0 14px rgba(139, 61, 255, .38)); }
.sp-legs { transform-origin: 48px 36px; animation: sp-twitch 11s ease-in-out 6s infinite; }
@keyframes sp-drop {
  0%   { transform: translateY(-120px); opacity: 0; }
  12%  { opacity: 1; }
  60%  { transform: translateY(7px); }
  78%  { transform: translateY(-4px); }
  92%  { transform: translateY(1.5px); }
  100% { transform: translateY(0); opacity: 1; }
}
@keyframes sp-sway { from { transform: rotate(-2.6deg); } to { transform: rotate(2.6deg); } }
/* tap: it drops 90px on its silk, dangles, climbs back (gf-app.js toggles .dangle) */
.sp-thread { transition: height .9s cubic-bezier(.2, .9, .3, 1.25); }
.spider.dangle .sp-thread { height: 154px; }
.spider.startle .sp-legs { animation: sp-startle .5s ease-out; }
@keyframes sp-startle { 0% { transform: scale(1); } 30% { transform: scale(1.16, .88); } 60% { transform: scale(.94, 1.06); } 100% { transform: scale(1); } }
/* Nightmare mode brings two more, smaller, on their own timing */
.spider.s2, .spider.s3 { display: none; }
body.nightmare .spider.s2, body.nightmare .spider.s3 { display: none; }
.spider.s2 { right: auto; left: 16px; width: 34px; animation-delay: 2.2s; }
.spider.s2 .sp-thread { height: 30px; }
.spider.s2 .sp-swing { animation-duration: 5.5s; animation-delay: 5.8s; }
.spider.s3 { right: 118px; width: 26px; animation-delay: 4.6s; }
.spider.s3 .sp-thread { height: 22px; }
.spider.s3 .sp-swing { animation-duration: 8.5s; animation-delay: 8.2s; }
@keyframes sp-twitch { 0%, 93%, 100% { transform: scale(1); } 95.5% { transform: scale(1.06, .96); } 97.5% { transform: scale(.98, 1.02); } }
@media (prefers-reduced-motion: reduce) { .spider, .sp-swing, .sp-legs { animation: none; } }


/* ---------- ambient spooky layer ----------
   Fog, lightning and a neon buzz on the page titles. All transform/opacity so
   the GPU composites them; nothing here lays out or repaints the page. */
/* the box runs 60vh past the bottom of the screen so a rubber-band scroll can
   never drag its edge into view (the old 40vh box drew a hard line) */
.fog { position: fixed; left: -20vw; right: -20vw; top: 60vh; bottom: -60vh; z-index: 1; pointer-events: none; }
.fog i { position: absolute; inset: 0; opacity: .8; }
.fog i.a { background:
    radial-gradient(60vw 26vh at 20% 40%, rgba(170, 120, 255, .2), transparent 70%),
    radial-gradient(50vw 22vh at 65% 44%, rgba(255, 43, 214, .13), transparent 70%),
    radial-gradient(70vw 30vh at 95% 38%, rgba(120, 140, 255, .15), transparent 70%);
  animation: fog-a 70s ease-in-out infinite alternate; }
.fog i.b { background:
    radial-gradient(55vw 24vh at 40% 46%, rgba(255, 255, 255, .06), transparent 70%),
    radial-gradient(45vw 20vh at 85% 42%, rgba(139, 61, 255, .17), transparent 70%);
  animation: fog-b 95s ease-in-out infinite alternate; }
.fog i.c { display: none; background:
    radial-gradient(65vw 30vh at 30% 46%, rgba(255, 43, 214, .16), transparent 70%),
    radial-gradient(60vw 26vh at 80% 44%, rgba(182, 255, 63, .07), transparent 70%);
  animation: fog-a 55s ease-in-out infinite alternate-reverse; }
body.nightmare .fog i { opacity: 1; }
body.nightmare .fog i.c { display: block; }
@keyframes fog-a { from { transform: translate3d(-6vw, 0, 0); } to { transform: translate3d(8vw, -2vh, 0); } }
@keyframes fog-b { from { transform: translate3d(7vw, 1vh, 0); } to { transform: translate3d(-9vw, -1vh, 0); } }
.flash { position: fixed; inset: 0; z-index: 70; pointer-events: none; opacity: 0;
  background: radial-gradient(120vw 80vh at 70% -10%, rgba(236, 226, 255, .9), rgba(139, 61, 255, .35) 45%, transparent 75%); }
.flash.on { animation: flash .7s ease-out; }
body.nightmare .flash.on { animation: flash-n .8s ease-out; }
@keyframes flash { 0% { opacity: 0; } 8% { opacity: .12; } 16% { opacity: .02; } 24% { opacity: .08; } 40%, 100% { opacity: 0; } }
@keyframes flash-n { 0% { opacity: 0; } 8% { opacity: .22; } 16% { opacity: .04; } 26% { opacity: .16; } 44%, 100% { opacity: 0; } }
/* page titles buzz like a tube with a loose contact, once every 11s */
.lh-t, .vhead h1 { animation: neon-buzz 11s linear infinite; }
@keyframes neon-buzz { 0%, 61.9%, 63.3%, 65.1%, 100% { opacity: 1; } 62.4% { opacity: .7; } 64.4% { opacity: .84; } }
/* a pair of eyes that opens somewhere dark, blinks, and is gone */
.eyes { position: fixed; z-index: 2; width: 26px; height: 8px; pointer-events: none; display: flex; justify-content: space-between; animation: peek 3.6s ease-in-out forwards; }
.eyes i { width: 8px; height: 8px; border-radius: 50%; background: var(--pink);
  box-shadow: 0 0 8px var(--pink), 0 0 18px rgba(255, 43, 214, .7); animation: blink 3.6s linear forwards; }
@keyframes peek { 0% { opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } 100% { opacity: 0; } }
@keyframes blink { 0%, 38%, 44%, 70%, 75%, 100% { transform: scaleY(1); } 41%, 72.5% { transform: scaleY(.1); } }
/* the big heart on the hearts tab beats; tap it 5x and it races (gf-app.js) */
.hv-heart { animation: heartbeat 2.4s ease-in-out infinite; }
.hv-heart.race { animation-duration: .6s; }
@keyframes heartbeat { 0%, 30%, 100% { transform: scale(1); } 8% { transform: scale(1.12); } 16% { transform: scale(1); } 22% { transform: scale(1.08); } }
/* swarm variants share the #boo stage with the ghosts */
.bg-pk { position: absolute; top: -70px; width: var(--sz, 24px); color: var(--orange);
  filter: drop-shadow(0 0 12px rgba(255, 138, 42, .75)); animation: rain 3.8s cubic-bezier(.3, .1, .6, 1) forwards; }
.bg-pk svg { width: 100%; height: auto; display: block; }
@keyframes rain { 0% { transform: translate3d(0, 0, 0) rotate(-12deg); opacity: 0; } 12% { opacity: 1; } 100% { transform: translate3d(var(--drift, 0), 118vh, 0) rotate(16deg); opacity: 0; } }
.bg-ht { position: absolute; bottom: -60px; width: var(--sz, 22px); color: var(--pink);
  filter: drop-shadow(0 0 12px rgba(255, 43, 214, .8)); animation: boo 3.6s cubic-bezier(.25, .6, .3, 1) forwards; }
.bg-ht svg { width: 100%; height: auto; display: block; }
.toast { position: fixed; left: 50%; bottom: calc(92px + var(--sab)); transform: translateX(-50%) translateY(8px); z-index: 85;
  padding: 10px 16px; border-radius: 999px; background: rgba(16, 8, 32, .9); border: 1px solid rgba(255, 43, 214, .5);
  color: var(--ink); font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
  box-shadow: 0 8px 30px rgba(0, 0, 0, .5), 0 0 18px rgba(255, 43, 214, .3); opacity: 0; transition: opacity .25s, transform .25s; pointer-events: none; }
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .fog i, .lh-t, .vhead h1, .hv-heart, .eyes, .eyes i { animation: none; }
  .flash.on, body.nightmare .flash.on { animation: none; }
  .bg-pk, .bg-ht { display: none; }
}

/* ---- more easter eggs ---- */
body.possessed { animation: possess 2.6s ease; }
@keyframes possess {
  0%, 100% { filter: none; }
  10% { filter: hue-rotate(60deg) saturate(1.6); }
  22% { filter: invert(1) hue-rotate(180deg); }
  26% { filter: none; }
  40% { filter: hue-rotate(-70deg) contrast(1.3); }
  55% { filter: none; }
  70% { filter: invert(1); }
  74% { filter: none; }
}
@media (prefers-reduced-motion: reduce) { body.possessed { animation: none; } }

/* ---- live-content surfaces ---- */
.notice {
  position: sticky; top: 0; z-index: 45; padding: 10px 16px; text-align: center;
  font-size: 13px; font-weight: 600; line-height: 1.45;
  background: rgba(63, 125, 255, .18); border-bottom: 1px solid rgba(63, 125, 255, .4); color: #cfe0ff;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}
.notice.warn { background: rgba(255, 138, 42, .18); border-bottom-color: rgba(255, 138, 42, .45); color: #ffd2ab; }
.notice.alert { background: rgba(255, 59, 92, .2); border-bottom-color: rgba(255, 59, 92, .5); color: #ffbcc7; }
.fav-note.clash { color: #ffbcc7; background: rgba(255, 59, 92, .12); border: 1px solid rgba(255, 59, 92, .35);
  padding: 10px 12px; border-radius: 11px; }
.fav-note.ok { color: #d3ff8e; }

/* ---- hearts: the page has a body before anyone has hearted anything ---- */
.hv-hero {
  text-align: center; padding: 28px 20px 24px; border-radius: 22px;
  border: 1px solid rgba(255, 43, 214, .28);
  background: linear-gradient(160deg, rgba(255, 43, 214, .14), rgba(63, 125, 255, .08)), var(--glass);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  box-shadow: 0 10px 36px rgba(255, 43, 214, .14);
}
.hv-heart { display: block; width: 58px; height: 58px; margin: 0 auto 14px; color: var(--pink);
  filter: drop-shadow(0 0 10px rgba(255, 43, 214, .8)) drop-shadow(0 0 26px rgba(255, 43, 214, .45)); }
.hv-heart svg { width: 100%; height: 100%; fill: currentColor; stroke: none; }
.hv-t { font-family: "Saira Condensed", sans-serif; font-size: 30px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .02em; line-height: 1; }
.hv-p { margin: 10px auto 0; max-width: 310px; font-size: 13px; line-height: 1.6; color: var(--dim); }
.hv-cta { margin-top: 18px; padding: 13px 22px; }
/* compact lineup button under the festival poster (user call 8/24) */
.gf-lineup-wrap { text-align: center; margin: 12px 0 6px; }
.gf-lineup-wrap.mid { margin: 14px 0 4px; }
.gf-lineup-cta { padding: 10px 20px; font-size: 11px; border-radius: 999px; }
.hv-steps { display: grid; gap: 8px; }
#myFavs .perks { margin-top: 14px; }
.hv-step { display: flex; align-items: center; gap: 13px; padding: 12px 14px; border-radius: 14px;
  background: var(--glass2); border: 1px solid var(--gbrd); font-size: 13px; line-height: 1.4; }
.hv-step b { flex: none; width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-family: "Saira Condensed", sans-serif; font-size: 15px; font-weight: 800; color: #0a0518;
  background: var(--green); box-shadow: 0 0 14px rgba(182, 255, 63, .45); }
.hv-nights { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; }
.hv-night { padding: 13px 8px 12px; text-align: center; border-radius: 14px; background: var(--glass2); border: 1px solid var(--gbrd); }
.hv-night b { display: block; font-family: "Saira Condensed", sans-serif; font-size: 24px; font-weight: 800; line-height: 1;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.hv-night span { display: block; margin-top: 4px; font-size: 12px; font-weight: 700; }
.hv-night i { display: block; margin-top: 6px; font-style: normal; font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--faint); }
.hv-night.lit { border-color: rgba(182, 255, 63, .4); }
.hv-night.lit i { color: var(--green); }
.r-set { display: block; font-size: 10px; color: var(--green); margin-top: 2px; font-weight: 700; letter-spacing: .04em; }

/* push opt-in row */
.push-row { width: 100%; text-align: left; cursor: pointer; font-family: inherit; color: var(--ink); }
.push-row:disabled { opacity: .6; }

/* ============================================================
   SHOWS MAP - Salt Lake valley, drawn not tiled
   ============================================================ */
.vfilter {
  display: flex; gap: 7px; margin: 16px 0;
  overflow-x: auto; flex-wrap: nowrap;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}
.vfilter::-webkit-scrollbar { display: none; }
.vchip { flex: 0 0 auto; white-space: nowrap; }
.vchip {
  font: inherit; font-size: 12px; font-weight: 600; color: var(--dim);
  background: var(--glass2); border: 1px solid var(--gbrd);
  border-radius: 999px; padding: 10px 14px; min-height: 40px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
}
.vchip i { font-style: normal; color: var(--faint); font-size: 11px; }
.vchip.on {
  color: #0b0614; background: var(--green); border-color: transparent;
}
.vchip.on i { color: rgba(11, 6, 20, .6); }

/* ---------- liquid glass (user call: premium, shiny, iOS-glass) ----------
   One recipe: a specular sheen across the top half, a hairline top light, an
   inner floor shadow, and the existing neon glow underneath. */
.sc-btn, .al-play, .disco-play, .pk-cta, .t-go, .vc-btn, .sh-btn.primary {
  position: relative; overflow: hidden; isolation: isolate;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18), inset 0 -6px 12px rgba(10, 4, 24, .22), 0 6px 22px rgba(255, 43, 214, .35);
}
.sc-btn::before, .al-play::before, .disco-play::before, .pk-cta::before, .vc-btn::before, .sh-btn.primary::before {
  content: ""; position: absolute; left: 6%; right: 6%; top: 2px; height: 46%; border-radius: 999px; z-index: -1;
  background: linear-gradient(rgba(255, 255, 255, .1), rgba(255, 255, 255, 0));
}
.sc-btn.ghost, .vc-btn { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), inset 0 -4px 10px rgba(10, 4, 24, .2); }
.tik, .lrow, .album, .hv-step, .al-row, .acard, .hv-night, .stat {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08), 0 8px 26px rgba(0, 0, 0, .32);
}
.album { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), 0 8px 30px rgba(255, 43, 214, .16); }

/* ---------- polish pass: one touch language, one card language ----------
   Every tappable compresses the same amount; every glass card carries the same
   hairline top light. Transform-only, so nothing lays out or breaks. */
.lrow:active, .al-row:active, .tik:active, .hv-step:active, .vchip:active, .soc:active { transform: scale(.98); }
.al-play:active, .disco-play:active, .pk-cta:active { transform: scale(.965); }
.lrow, .al-row, .tik, .hv-step, .vchip { transition: transform .16s ease, border-color .18s ease; }
.feat, .hv-hero, .perks { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .09), 0 12px 40px rgba(0, 0, 0, .35); }


/* ---- App Store install cell (#asBar), ported from the root app 8/25 ----
   iOS "thick material" on purpose - it should read as the App Store's offer, not the
   festival's, so no --grad / neon borders here. Pinned above the pill nav (12px + 64px)
   and above the auth wall (50) but under .flash (70) / .modal (80) / .boo (90). */
.asbar { position: fixed; left: 0; right: 0; margin: 0 auto;
  bottom: calc(90px + var(--sab)); z-index: 65;
  max-width: 480px; width: calc(100% - 32px);
  display: none; align-items: center; gap: 12px; padding: 11px 13px;
  border-radius: 18px; border: 1px solid rgba(255,255,255,.10);
  background: rgba(28,28,30,.86); -webkit-backdrop-filter: blur(22px) saturate(180%); backdrop-filter: blur(22px) saturate(180%);
  box-shadow: 0 18px 44px rgba(0,0,0,.55); }
.asbar.show { display: flex; }
.asb-x { flex: none; width: 22px; height: 22px; padding: 0; border: none; background: transparent;
  color: rgba(235,235,245,.5); cursor: pointer; display: grid; place-items: center; }
.asb-x svg { width: 13px; height: 13px; display: block; }
.asb-x:active { transform: scale(.88); }
.asb-icon { flex: none; width: 54px; height: 54px; border-radius: 12px; display: block;
  border: 1px solid rgba(255,255,255,.12); background: #05060d; }
.asb-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.asb-txt b { font-size: 15px; font-weight: 600; color: #fff; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.asb-txt span { font-size: 12px; color: rgba(235,235,245,.6);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.asb-txt i { font-style: normal; font-size: 11px; color: rgba(235,235,245,.45); }
.asb-get { flex: none; text-decoration: none; border-radius: 999px;
  background: rgba(120,120,128,.32); color: #0a84ff;
  font-size: 13px; font-weight: 800; letter-spacing: .02em; text-transform: uppercase;
  padding: 8px 22px; line-height: 1.15; }
.asb-get:active { background: rgba(120,120,128,.5); transform: scale(.96); }
