/* Motion site redesign, 2026-10 — design tokens and shared pieces.
   Deep black, glass surfaces, one flat cyan. No gradient text, no aura. */

:root {
  --bg: #000000;
  --bg-2: #0a0a0c;
  --glass: rgba(255, 255, 255, 0.06);
  --glass-2: rgba(255, 255, 255, 0.10);
  --glass-solid: rgba(22, 22, 25, 0.78);
  --stroke: rgba(255, 255, 255, 0.10);
  --stroke-hi: rgba(255, 255, 255, 0.20);
  --text: #f5f5f7;
  --text-2: #a1a1aa;
  --text-3: #8a8a93;   /* about 5.9:1 on black: readable at 12px (was #6e6e76, 4.1:1) */
  --cyan: #00e5ff;
  --on-cyan: #00161a;
  --live: #30d158;
  --purple: #a855f7;
  --purple-soft: #c4b5fd;
  --orange: #ff9f0a;

  --r-xl: 28px;
  --r-l: 22px;
  --r-m: 16px;
  --r-s: 12px;
  --pill: 999px;

  --display: 'Syne', system-ui, sans-serif;
  --body: 'Outfit', -apple-system, system-ui, sans-serif;

  --page-x: 16px;
  --max: 1280px;
}

* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--text); font-family: var(--body); -webkit-font-smoothing: antialiased; overflow-x: hidden; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
img { display: block; }
::-webkit-scrollbar { display: none; }
* { scrollbar-width: none; }

/* Glass. PERFORMANCE RULE (2026-10-11): live blur (backdrop-filter) is expensive on phones,
   and dozens of blurred chips and tags made scrolling stutter. `.glass` and `.glass-solid` are
   translucent fills with no live blur; on black they look the same. Add `.blur` only to the few
   surfaces that float over moving content: top bar, tab bar, app prompt, sticky filters,
   the hero caption and pop-up sheets. Never on the map (it redraws every frame). */
.glass {
  background: var(--glass);
  border: 1px solid var(--stroke);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
.glass-solid {
  background: rgba(18, 18, 22, 0.88);
  border: 1px solid var(--stroke);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 20px 60px rgba(0, 0, 0, 0.6);
}
.blur { -webkit-backdrop-filter: blur(24px) saturate(150%); backdrop-filter: blur(24px) saturate(150%); }
.glass-solid.blur { background: var(--glass-solid); }

.icon-btn {
  width: 44px; height: 44px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform 160ms ease, background 160ms ease;
}
.icon-btn:active { transform: scale(0.94); }
.icon-btn svg { width: 20px; height: 20px; stroke: var(--text); fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.btn-cyan {
  background: var(--cyan); color: var(--on-cyan);
  border-radius: var(--pill); font-weight: 600; font-size: 16px;
  height: 52px; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 0 24px; transition: transform 160ms ease, filter 160ms ease;
}
.btn-cyan:hover { filter: brightness(1.06); }
.btn-cyan:active { transform: scale(0.98); }
.btn-ghost {
  border-radius: var(--pill); font-weight: 500; font-size: 15px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 0 18px;
  transition: background 160ms ease, transform 160ms ease;
}
.btn-ghost:hover { background: var(--glass-2); }
.btn-ghost:active { transform: scale(0.98); }

/* THE LOGO: the Motion pill with the orbiting cyan sweep. Appears once on every screen.
   - .sweep            the frame.
   - .sweep > .pill-in the body: dark glass with a top highlight.
   - .sweep > .ring    a 1.5px rim on top of the body. Its mask is STATIC (it never changes);
                       inside it a large square gradient (.ring > i) ROTATES with `transform`
                       only, so the browser turns it on the GPU and never repaints. (2026-10-11:
                       the earlier animated conic angle repainted every frame and glitched on
                       phones over the map.) */
.sweep { position: relative; display: inline-flex; border-radius: var(--pill); box-shadow: 0 10px 30px rgba(0,0,0,0.45); isolation: isolate; }
.sweep > .pill-in { position: relative; z-index: 1; display: flex; align-items: center; flex: 1; min-width: 0; border-radius: inherit;
  background: rgba(10,10,14,0.82);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.12), inset 0 0 0 1px rgba(255,255,255,0.08); }
.sweep > .ring { position: absolute; inset: 0; z-index: 2; border-radius: inherit; padding: 1.5px; pointer-events: none; overflow: hidden;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask-composite: exclude; }
.sweep > .ring > i { position: absolute; left: 50%; top: 50%; width: 170%; aspect-ratio: 1; translate: -50% -50%;
  background: conic-gradient(from 0deg, transparent 0 68%, rgba(0,229,255,0.45) 80%, rgba(0,229,255,1) 90%, rgba(0,229,255,0.45) 97%, transparent 100%);
  animation: sweep 6s linear infinite; will-change: transform; }
@keyframes sweep { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.logo-pill { height: 44px; }
.logo-pill > .pill-in { justify-content: center; padding: 0 22px; }
.logo-pill .wm { font-family: var(--display); font-weight: 800; font-size: 21px; letter-spacing: -0.02em; line-height: 1; padding-bottom: 2px;
  background: linear-gradient(135deg, var(--purple) 0%, var(--cyan) 100%); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; }
@media (prefers-reduced-motion: reduce) { .sweep > .ring > i { animation: none; } }

/* Ambient: faint colour behind the glass. Soft radial fills, no blur filter (a 140px blur on
   four animated 600px circles was the single heaviest thing on phones). They drift slowly on
   desktop only. */
.ambient { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.ambient i { position: absolute; border-radius: 50%; }
.ambient i:nth-child(1) { width: 900px; height: 900px; background: radial-gradient(closest-side, rgba(58,14,110,0.30), transparent); top: -35%; left: -35%; }
.ambient i:nth-child(2) { width: 700px; height: 700px; background: radial-gradient(closest-side, rgba(0,229,255,0.07), transparent); top: 0; right: -40%; }
.ambient i:nth-child(3) { width: 1000px; height: 1000px; background: radial-gradient(closest-side, rgba(26,5,48,0.55), transparent); bottom: -55%; left: 0; }
.ambient i:nth-child(4) { width: 600px; height: 600px; background: radial-gradient(closest-side, rgba(0,229,255,0.05), transparent); top: 45%; left: -35%; }
.ambient b { position: absolute; inset: 0; opacity: 0.035; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .ambient i { animation: orb 26s ease-in-out infinite; will-change: transform; }
  .ambient i:nth-child(2) { animation-duration: 30s; animation-delay: -5s; }
  .ambient i:nth-child(3) { animation-duration: 22s; animation-delay: -10s; }
  .ambient i:nth-child(4) { animation-duration: 28s; animation-delay: -15s; }
}
@keyframes orb { 0%, 100% { transform: translate(0,0) scale(1); } 25% { transform: translate(60px,-40px) scale(1.1); } 50% { transform: translate(-30px,50px) scale(0.95); } 75% { transform: translate(40px,20px) scale(1.05); } }

/* Segmented control (dates) */
.seg { display: inline-flex; padding: 4px; border-radius: var(--pill); gap: 2px; }
.seg button {
  height: 40px; padding: 0 16px; border-radius: var(--pill); font-size: 15px; font-weight: 500; color: var(--text-2);
  transition: background 180ms ease, color 180ms ease; white-space: nowrap;
}
.seg button[aria-selected="true"] { background: var(--text); color: #000; font-weight: 600; }
.seg button:hover:not([aria-selected="true"]) { color: var(--text); }

/* A segmented row that scrolls sideways (the day strip): fades out at the edge instead of cutting a word. */
.seg.strip { max-width: 100%; overflow-x: auto; scroll-snap-type: x proximity; -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent); }
.seg.strip button { flex: 0 0 auto; scroll-snap-align: start; }
.seg.strip button:last-child { margin-right: 22px; }

/* Chips (genres) */
.chips { display: flex; gap: 8px; overflow-x: auto; scroll-snap-type: x proximity; padding: 2px var(--page-x); margin: 0 calc(-1 * var(--page-x)); -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 40px), transparent); }
.chip { height: 36px; padding: 0 14px; border-radius: var(--pill); font-size: 14px; font-weight: 500; color: var(--text-2); white-space: nowrap; scroll-snap-align: start; transition: background 160ms ease, color 160ms ease; flex: 0 0 auto; }
.chip[aria-pressed="true"] { background: var(--purple); color: #fff; font-weight: 600; border-color: transparent; }
.chip .n { margin-left: 6px; font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.chip[aria-pressed="true"] .n { color: rgba(255,255,255,0.75); }
.chip:hover:not([aria-pressed="true"]) { color: var(--text); background: var(--glass-2); }

/* Event card */
.card { display: block; min-width: 0; }
.card .art { position: relative; aspect-ratio: 4 / 5; border-radius: var(--r-l); overflow: hidden; background: var(--bg-2); border: 1px solid var(--stroke); transition: transform 200ms ease, border-color 200ms ease; }
.card .art img { width: 100%; height: 100%; object-fit: cover; }
/* No flyer: the event's accent colour (when the engine has one) with the venue's initial.
   MotionClock.noArt(e) writes it; plain text inside .noart still looks right. */
.noart { position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: flex-end; gap: 2px; padding: 14px; overflow: hidden;
  background: radial-gradient(120% 90% at 100% 0%, rgba(255,255,255,0.10), transparent 60%), var(--accent, #16161b);
  color: var(--accent-ink, var(--text-2)); font: 600 13px/1.25 var(--body); }
.noart b { font: 800 clamp(34px, 9vw, 64px)/0.9 var(--display); letter-spacing: -0.04em; opacity: 0.9; }
.noart span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: 0.8; }
.card .tag { position: absolute; top: 10px; left: 10px; height: 26px; padding: 0 10px; border-radius: var(--pill); font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; display: inline-flex; align-items: center; gap: 6px; }
.card .tag.soldout { color: #ff3b6b; }
.card .tag.pick { top: auto; bottom: 10px; color: var(--purple-soft); }
.card .tag.pick::before, .pickmark::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--purple); }
/* "Motion pick": a small purple mark, never a badge that covers the flyer. */
.pickmark { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-style: normal; font-weight: 600; letter-spacing: 0.02em; color: var(--purple-soft); white-space: nowrap; }
.card .heart { position: absolute; top: 8px; right: 8px; width: 36px; height: 36px; }
.card .heart svg { width: 18px; height: 18px; }
.card .body { padding: 10px 2px 0; }
.card h3 { margin: 0; font-family: var(--body); font-weight: 600; font-size: 15px; line-height: 1.3; letter-spacing: -0.01em; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.card .meta { margin-top: 4px; font-size: 13px; color: var(--text-2); display: flex; gap: 6px; align-items: center; min-width: 0; }
.card .meta .v { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card .meta .t { color: var(--text); font-variant-numeric: tabular-nums; flex: 0 0 auto; }
@media (hover: hover) {
  .card:hover .art { transform: translateY(-3px); border-color: var(--stroke-hi); }
}

/* Floating tab bar, phone only */
.tabbar { position: fixed; left: 50%; bottom: calc(14px + env(safe-area-inset-bottom)); transform: translateX(-50%); display: flex; gap: 4px; padding: 6px; border-radius: var(--pill); z-index: 40; transition: transform 260ms cubic-bezier(.2,.8,.2,1); }
/* One bottom element at a time: while the app prompt shows, the tab bar steps down out of view. */
body.appbar-on .tabbar { transform: translate(-50%, calc(100% + 40px)); }
.tabbar a, .tabbar button { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; width: 78px; height: 52px; border-radius: var(--pill); font-size: 11px; font-weight: 500; color: var(--text-2); transition: background 160ms ease, color 160ms ease; }
.tabbar a svg, .tabbar button svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.tabbar a[aria-current] { background: var(--glass-2); color: var(--text); }

/* App prompt, phone only, and only once the App Store link exists (never on Android).
   It takes the tab bar's place; the page script shows one of the two at a time. */
.appbar { position: fixed; left: 12px; right: 12px; bottom: calc(14px + env(safe-area-inset-bottom)); display: flex; align-items: center; gap: 12px; padding: 10px 10px 10px 12px; border-radius: 20px; z-index: 39; transform: translateY(calc(100% + 120px)); transition: transform 320ms cubic-bezier(.2,.8,.2,1); }
.appbar.in { transform: translateY(0); }
.appbar .ico { width: 44px; height: 44px; border-radius: 12px; background: #fff; color: #000; font-family: var(--display); font-weight: 800; font-size: 20px; display: flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.appbar .txt { flex: 1; min-width: 0; }
.appbar .txt b { display: block; font-weight: 600; font-size: 14px; }
.appbar .txt span { display: block; font-size: 12px; color: var(--text-2); }
.appbar .open { height: 36px; padding: 0 16px; font-size: 14px; }
.appbar .x { width: 32px; height: 32px; }
.appbar .x svg { width: 14px; height: 14px; }

/* Desktop top bar */
/* The Motion pill sits dead centre (ruling 10, 2026-10-11): it is taken out of the row and
   centred on the bar, so the nav (left) and search / sign-in (right) can never push it. */
.topbar { position: sticky; top: 0; z-index: 30; display: none; }
.topbar .in { position: relative; max-width: var(--max); margin: 0 auto; height: 68px; display: flex; align-items: center; gap: 12px; padding: 0 24px; }
.topbar .in > .logo-pill { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); }
.topbar nav { display: flex; gap: 4px; }
.topbar nav a { height: 36px; padding: 0 14px; border-radius: var(--pill); display: inline-flex; align-items: center; font-size: 15px; color: var(--text-2); transition: background 160ms ease, color 160ms ease; }
.topbar nav a:hover { color: var(--text); background: var(--glass); }
.topbar nav a[aria-current] { color: var(--text); background: var(--glass-2); }
.topbar .spacer { flex: 1; }
.topbar .search { width: clamp(160px, 22vw, 280px); height: 38px; border-radius: var(--pill); display: flex; align-items: center; gap: 8px; padding: 0 14px; color: var(--text-3); font-size: 14px; white-space: nowrap; overflow: hidden; text-align: left; cursor: pointer; transition: color 160ms ease, border-color 160ms ease; }
.topbar .search:hover { color: var(--text-2); border-color: var(--stroke-hi); }
.topbar .search svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; flex: 0 0 auto; }
.topbar .search span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.topbar .search kbd { margin-left: auto; font: 12px var(--body); color: var(--text-3); border: 1px solid var(--stroke); border-radius: 6px; padding: 1px 6px; }

/* Phone header */
.ph { display: flex; align-items: center; justify-content: space-between; height: 44px; margin-top: calc(12px + env(safe-area-inset-top)); padding: 0 var(--page-x); position: relative; z-index: 2; }
.ph > .logo-pill { position: absolute; left: 50%; top: 0; transform: translateX(-50%); }
.ph > [data-search] { margin-left: auto; }

@media (min-width: 821px) {
  :root { --page-x: 24px; }
  .tabbar, .appbar, .ph { display: none; }
  .topbar { display: block; }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0ms !important; animation: none !important; }
}

/* ---- Accounts (W14): sign-in and the account menu. Desktop = card + anchored menu, phone = sheets. ---- */
.avatar { width: 30px; height: 30px; border-radius: 50%; background: var(--purple); color: #fff; font-weight: 700; font-size: 14px; display: inline-flex; align-items: center; justify-content: center; box-shadow: 0 0 0 2px rgba(0,0,0,0.6), 0 0 0 3.5px rgba(168,85,247,0.5); }
[data-account].is-in { padding: 0 6px; }
.heart.on svg { fill: #ff3b6b; stroke: #ff3b6b; }
.handle { width: 36px; height: 5px; border-radius: 3px; background: rgba(255,255,255,0.25); margin: 0 auto 12px; }

.auth { position: fixed; inset: 0; z-index: 100; background: rgba(0,0,0,0.55); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); opacity: 0; transition: opacity 200ms ease; display: flex; align-items: flex-end; justify-content: center; }
.auth.in { opacity: 1; }
.auth-card { position: relative; width: 100%; padding: 10px 20px calc(24px + env(safe-area-inset-bottom)); border-radius: 28px 28px 0 0; transform: translateY(30px); transition: transform 240ms cubic-bezier(.2,.8,.2,1); }
.auth.in .auth-card { transform: translateY(0); }
.auth-card .x { position: absolute; top: 14px; right: 14px; width: 34px; height: 34px; }
.auth-card .x svg { width: 14px; height: 14px; }
.auth-logo { display: flex; justify-content: center; margin: 6px 0 18px; }
.auth-step { display: flex; flex-direction: column; gap: 12px; }
.auth-step h2 { margin: 0; font-family: var(--display); font-weight: 800; font-size: 26px; letter-spacing: -0.03em; }
.auth-step p { margin: 0; color: var(--text-2); font-size: 15px; line-height: 1.45; }
.auth-step small { color: var(--text-3); font-size: 12px; text-align: center; }
.auth-step small a { color: var(--text-2); text-decoration: underline; }
.auth-field { display: flex; height: 52px; border-radius: var(--r-m); padding: 0 16px; }
.auth-field input { flex: 1; min-width: 0; background: none; border: 0; outline: 0; color: var(--text); font: 17px var(--body); }
.auth-field:focus-within { border-color: var(--purple); box-shadow: 0 0 0 3px rgba(168,85,247,0.25); }
.auth-code { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; }
.auth-code input { height: 56px; text-align: center; font: 600 24px var(--body); color: var(--text); background: var(--glass); border: 1px solid var(--stroke); border-radius: var(--r-s); outline: 0; }
.auth-code input:focus { border-color: var(--purple); box-shadow: 0 0 0 3px rgba(168,85,247,0.25); }

.menu-wrap { position: fixed; inset: 0; z-index: 100; opacity: 0; transition: opacity 180ms ease; }
.menu-wrap.in { opacity: 1; }
.menu { position: absolute; left: 8px; right: 8px; bottom: 8px; padding: 10px 10px calc(14px + env(safe-area-inset-bottom)); border-radius: 26px; transform: translateY(24px); transition: transform 220ms cubic-bezier(.2,.8,.2,1); }
.menu-wrap.in .menu { transform: translateY(0); }
.menu-me { display: flex; align-items: center; gap: 12px; padding: 6px 10px 14px; }
.menu-me .avatar { width: 40px; height: 40px; font-size: 17px; }
.menu-me b { display: block; font-weight: 600; font-size: 15px; }
.menu-me span:last-child { display: block; font-size: 12px; color: var(--text-3); }
.menu-h { font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-3); padding: 12px 10px 4px; }
.menu-row { display: flex; align-items: center; gap: 12px; padding: 11px 10px; border-radius: 14px; font-size: 15px; transition: background 140ms ease; }
.menu-row:hover { background: var(--glass-2); }
.menu-row svg { width: 20px; height: 20px; stroke: var(--text-2); fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.menu-row .n { margin-left: auto; font-size: 13px; color: var(--text-3); }
.menu-row .n.hot { color: var(--cyan); font-weight: 600; }
.menu-row.bm b { display: block; font-weight: 600; font-size: 15px; }
.menu-row.bm div span { display: block; font-size: 12px; color: var(--text-3); }
.menu-row.quiet { color: var(--text-2); }
.bm-ico { width: 36px; height: 36px; border-radius: 10px; background: var(--purple) center/cover; color: #fff; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.menu-cta { display: flex; gap: 8px; padding: 8px 10px 10px; }
.menu-cta .btn-ghost { flex: 1; height: 40px; font-size: 14px; padding: 0 10px; }

@media (min-width: 821px) {
  .auth { align-items: center; }
  .auth-card { width: 420px; border-radius: 28px; padding: 24px 28px 28px; transform: translateY(0) scale(0.96); }
  .auth.in .auth-card { transform: scale(1); }
  .auth-card .handle, .menu .handle { display: none; }
  .menu { left: auto; right: 24px; bottom: auto; top: 72px; width: 340px; border-radius: 22px; transform: translateY(-8px) scale(0.98); transform-origin: top right; }
}

[hidden] { display: none !important; }

/* Sign-in and hearts stay hidden until the real login works (ruling 7, card W14).
   account.js adds .signin-on to <html> only when the site config says signin: true. */
html:not(.signin-on) [data-account], html:not(.signin-on) .heart { display: none !important; }

/* Read by screen readers and search engines, not drawn. */
.sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* In the top bar the pill body reads a touch lighter than the bar. */
.topbar .sweep > .pill-in { background: rgba(255,255,255,0.07); }

/* Sold out (ruling 2026-10-09): a button you can see but not press. */
.btn-cyan.soldout { background: transparent; color: #ff3b6b; border: 1.5px solid rgba(255,59,107,0.55); pointer-events: none; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 700; }
