/* Gravity Techno — landing stylesheet, built from the approved mockup. */

/* ============================================================
   GRAVITY — shared mockup foundation
   Tokens derived from gravitycph.dk (tangerine #FF520E,
   Clash Display + DM Sans) and tightened for conversion work.
   ============================================================ */


:root {
  /* surfaces */
  --ink:        #08080A;
  --ink-2:      #101013;
  --ink-3:      #17171C;
  --bone:       #F2EDE4;
  --line:       rgba(255,255,255,.10);
  --line-2:     rgba(255,255,255,.18);

  /* text */
  --fg:         #FFFFFF;
  --fg-2:       rgba(255,255,255,.66);
  --fg-3:       rgba(255,255,255,.42);

  /* action vs urgency — deliberately separated so the buy button
     never competes with a scarcity badge for the same attention */
  --action:     #FF520E;   /* Gravity tangerine — buy actions only */
  --action-hi:  #FF6B33;
  --urgent:     #FFB020;   /* amber — price rises, low stock */
  --gone:       #FF4438;   /* sold out */
  --ok:         #34D07F;

  --r-sm: 8px;
  --r:    14px;
  --r-lg: 22px;
  --r-pill: 999px;

  --display: 'Clash Display', 'Helvetica Neue', Arial, sans-serif;
  --body: 'DM Sans', -apple-system, 'Segoe UI', Roboto, sans-serif;

  --pad: clamp(20px, 5vw, 72px);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--ink);
  color: var(--fg);
  font-family: var(--body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; }

.wrap { width: 100%; max-width: 1280px; margin-inline: auto; padding-inline: var(--pad); }

/* ---------- type ---------- */
.display {
  font-family: var(--display);
  font-weight: 600;
  line-height: .86;
  letter-spacing: -.035em;
  text-transform: uppercase;
  margin: 0;
}
.eyebrow {
  font-size: 11px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--fg-3);
  font-weight: 500;
  margin: 0;
}
.lede { font-size: clamp(15px, 1.5vw, 18px); line-height: 1.55; color: var(--fg-2); margin: 0; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 16px 28px;
  border-radius: var(--r-pill);
  font-weight: 700; font-size: 15px; letter-spacing: .01em;
  transition: transform .18s cubic-bezier(.2,.8,.2,1), background-color .18s, box-shadow .18s;
  white-space: nowrap;
}
.btn:active { transform: scale(.975); }
.btn-primary { background: var(--action); color: #fff; box-shadow: 0 6px 30px -8px rgba(93,221,76,.45); }
.btn-primary:hover { background: var(--action-hi); }
/* Bootstrap loads across the whole site and its own .btn sets
   `border: var(--bs-btn-border-width) solid var(--bs-btn-border-color)`.
   Our primary button shares the class name .btn-primary with Bootstrap's, so
   it inherited Bootstrap's blue (#0d6efd) and every filled button — the hero
   CTA, the sticky bar, the ticket card — wore a thin blue ring. Stating a
   transparent border here keeps the geometry Bootstrap expects and takes the
   colour away; the ghost button paints its own back in on the next line. */
.btn { border: 1px solid transparent; }
.btn-ghost { border: 1px solid var(--line-2); color: var(--fg); }
.btn-ghost:hover { border-color: #fff; }
.btn-lg { padding: 19px 34px; font-size: 16px; }
.btn-block { display: flex; width: 100%; }

/* ---------- badges ---------- */
.badge {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  padding: 6px 12px; border-radius: var(--r-pill);
  border: 1px solid var(--line-2);
}
.badge-gone   { color: var(--gone);   border-color: rgba(255,68,56,.4);   background: rgba(255,68,56,.08); }
.badge-live   { color: var(--ok);     border-color: rgba(52,208,127,.4);  background: rgba(52,208,127,.08); }
.badge-urgent { color: var(--urgent); border-color: rgba(255,176,32,.4);  background: rgba(255,176,32,.10); }

.dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.dot-pulse { animation: pulse 1.8s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity: 1 } 50% { opacity: .25 } }

/* ---------- payment strip ---------- */
.pay { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pay span {
  font-size: 10px; font-weight: 700; letter-spacing: .06em;
  padding: 5px 9px; border-radius: 5px;
  border: 1px solid var(--line); color: var(--fg-3);
}
.pay .mp { color: #fff; border-color: rgba(255,255,255,.35); }


/* ---------- utility ---------- */
.hairline { height: 1px; background: var(--line); border: 0; margin: 0; }
.stack > * + * { margin-top: var(--gap, 16px); }
.muted { color: var(--fg-2); }
.tnum { font-variant-numeric: tabular-nums; }
.sr { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }

/* sticky mobile buy bar — shared across all three directions */
.buybar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  display: flex; align-items: center; gap: 14px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  background: rgba(8,8,10,.86);
  backdrop-filter: blur(20px) saturate(1.4);
  border-top: 1px solid var(--line);
  transform: translateY(110%);
  transition: transform .35s cubic-bezier(.2,.8,.2,1);
}
.buybar.in { transform: translateY(0); }
.buybar .price { font-family: var(--display); font-size: 20px; font-weight: 600; line-height: 1; }
.buybar .price small { display:block; font-family: var(--body); font-size: 10px; letter-spacing:.14em; text-transform: uppercase; color: var(--fg-3); font-weight: 500; margin-bottom: 4px; }
.buybar .btn { flex: 1; }

/* =====================================================================
   TECHNO
   ================================================================== */

/* ===== GRAVITY TECHNO — the anti-Opera ====================================
   Same Gravity bones as page.html (shutter type, reveal, sticky buy bar) with
   three deliberate inversions:

   1. ONE colour. Opera runs four semantic colours (tangerine / amber / red /
      green). Techno runs black, white, greys and #5DDD4C. Green means "press
      this" and nothing else. Sold out is grey and struck through, not red.
      Urgency is a green pulse, not amber. That single rule is what makes the
      page read industrial without redrawing a thing.
   2. Data goes mono. Clash Display still carries the headlines — that is the
      family resemblance to Opera — but every number, time, price and label
      sits in JetBrains Mono. Opera narrates its facts; Techno displays them.
   3. The proof inverts. Opera sells accolades. Down here accolades are a
      liability, so #artist ships in three switchable variants — see the
      section comment.
   ========================================================================== */

:root {
  --ink:      #050506;
  --ink-2:    #0C0C0F;
  --ink-3:    #141419;

  /* the whole palette. green = buy, and nothing else uses it */
  /* The accent is the only colour on the page, and it changes per event: the
     template writes --tx onto <main> from a colour field. Everything else is
     mixed from it, so one value repaints buttons, rules, glows and the shader.
     --tx-ink is the text that sits on top of the accent; it is set alongside
     --tx because whether that should be near-black or white depends on how
     light the chosen colour is, which CSS cannot decide on its own. */
  --tx:       #5DDD4C;
  --tx-hi:    color-mix(in srgb, var(--tx) 72%, #ffffff);
  --tx-dim:   color-mix(in srgb, var(--tx) 15%, transparent);
  --tx-ink:   #04140A;

  --action:   var(--tx);
  --action-hi:var(--tx-hi);

  --fg-2:     rgba(255,255,255,.70);
  --fg-3:     rgba(255,255,255,.50);
  --line:     rgba(255,255,255,.09);
  --line-2:   rgba(255,255,255,.17);

  --mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  --brand-h: 104px;
  --bar-h: 92px;
}
body { padding-bottom: var(--bar-h); background: var(--ink); }

/* green needs dark ink on top of it — it is a light colour, unlike tangerine */
/* Two classes, not one. base.css also styles .btn-primary, and relying on this
   sheet simply coming later held in the mockup but is a coin toss in the theme,
   where the armour block and half a dozen plugin sheets are in the cascade
   too. The accent belongs to this page, so this page states it outright. */
/* Two classes, not one. base.css also styles .btn-primary with the shared
   tangerine, and relying on this sheet merely coming later holds in the mockup
   but is a coin toss in the theme, where the armour block and half a dozen
   plugin sheets are in the cascade too. The accent belongs to this page, so
   this page states it outright. */
.btn.btn-primary { background-color: var(--tx); color: var(--tx-ink);
  box-shadow: 0 6px 34px -10px color-mix(in srgb, var(--tx) 65%, transparent); }
.btn.btn-primary:hover { background-color: var(--tx-hi); }
.btn { border-radius: 4px; font-weight: 700; letter-spacing: .02em; }
.btn-ghost { border-radius: 4px; }
.btn-mono { font-family: var(--mono); font-size: 13px; letter-spacing: .08em; text-transform: uppercase; }

/* ---------- pinned wordmark ---------- */
.topbrand {
  position: fixed; top: 0; left: 0; right: 0; z-index: 45;
  display: flex; align-items: center; justify-content: center;
  padding: 20px 16px 18px; pointer-events: none;
  background: linear-gradient(180deg, rgba(5,5,6,.9) 0%, rgba(5,5,6,.5) 55%, transparent 100%);
  transition: padding .3s, background-color .3s, backdrop-filter .3s;
}
/* Unmasked, this is simply the logo file drawn at its own proportions — which
   is also the fallback where masks are missing. --glogo-ar comes from the
   template, which reads the file's real dimensions. */
.topbrand .glogo { display: block; width: clamp(150px, 15vw, 220px);
  aspect-ratio: var(--glogo-ar, 6 / 1);
  background: var(--glogo) no-repeat center / contain;
  transition: width .3s; }

/* The wordmark takes the event's accent.
   The PNG is one flat colour on transparency, so its alpha is the shape and
   nothing else. Used as a mask it stops being green artwork and becomes a
   stencil: the accent is painted through it, and changing the event's colour
   changes the logo along with everything else. */
@supports ((-webkit-mask-image: url(#a)) or (mask-image: url(#a))) {
  .topbrand .glogo {
    background: var(--tx);
    -webkit-mask: var(--glogo) no-repeat center / contain;
    mask: var(--glogo) no-repeat center / contain;
  }
}

/* Only one wordmark at the top of a landing page.
   The site header centres its own logo a few pixels below this one, so the two
   sat on top of each other. The burger and the basket stay where they are —
   it is only the logo in the middle that goes.

   Matched with :has() rather than a body class: this theme's header has
   body_class() commented out, so WordPress puts no classes on <body> anywhere
   on the site, and turning that back on would change every other page. The
   second selector is there for the day someone restores it. */
body:has(main.gravity-techno) header .header_center,
body.gravity-techno-page header .header_center { display: none !important; }
/* The admin bar is fixed to the top of the viewport too, and this bar starts
   at 0 — so for anyone logged in it swallowed the "Gravity" line above the
   wordmark, and the page looked as if the logo were only half there. Matched
   with :has() because this theme has body_class() commented out, so the usual
   .admin-bar class never arrives. WordPress uses the same two heights. */
body:has(#wpadminbar) .topbrand { top: 32px; }
@media screen and (max-width: 782px) {
  body:has(#wpadminbar) .topbrand { top: 46px; }
}

.topbrand.stuck { padding: 11px 16px; background: rgba(5,5,6,.92);
  backdrop-filter: blur(20px) saturate(1.2); border-bottom: 1px solid var(--line); }
.topbrand.stuck .glogo { width: clamp(118px, 10.5vw, 160px); }

/* ---------- hero ---------- */
.hero { position: relative; height: calc(100svh - var(--bar-h)); width: 100%;
  display: flex; flex-direction: column; overflow: hidden;
  padding-top: var(--brand-h); padding-bottom: 8px; }
.hero video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0;
  filter: grayscale(.72) contrast(1.22) brightness(.62); }
.hero::before {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(70% 46% at 50% 54%, rgba(5,5,6,.82) 0%, rgba(5,5,6,.66) 52%, rgba(5,5,6,.16) 88%, transparent 100%),
    linear-gradient(180deg, rgba(5,5,6,.78) 0%, rgba(5,5,6,.28) 26%, rgba(5,5,6,.18) 66%, rgba(5,5,6,.3) 100%);
}
/* the grid is green here, not white — cheapest way to stamp the sub-brand
   onto footage that was shot for a different night */
.hero .fx { position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background-image:
    linear-gradient(rgba(255,255,255,.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.055) 1px, transparent 1px);
  background-size: 56px 56px; background-position: center;
  -webkit-mask-image: radial-gradient(118% 76% at 50% 44%, #000 18%, rgba(0,0,0,.35) 55%, transparent 82%);
  mask-image: radial-gradient(118% 76% at 50% 44%, #000 18%, rgba(0,0,0,.35) 55%, transparent 82%);
}
.hero .stack { position: relative; z-index: 3; flex: 1; display: flex; flex-direction: column;
  padding-bottom: 42px;
  align-items: center; justify-content: center; text-align: center;
  padding: 0 var(--pad); gap: clamp(13px, 2.1vh, 24px); }
.presents { margin: 0 0 -.1em; font-family: var(--mono); font-size: clamp(10px, 1.1vw, 12px);
  font-weight: 700; letter-spacing: .38em; text-indent: .38em; text-transform: uppercase; color: var(--tx); }

/* ---------- shutter type — the shared Gravity motif ---------- */
.shut { position: relative; display: inline-grid; margin: 0;
  font-family: var(--display); font-weight: 500; text-transform: uppercase;
  letter-spacing: -.05em; line-height: .82; }
.shut > span { grid-area: 1/1; display: block;
  clip-path: inset(calc(var(--i) * 16.667%) 0 calc((5 - var(--i)) * 16.667%) 0); }
.shut > span:nth-child(odd)  { --d: -.34em; --dl: -.05em; }
.shut > span:nth-child(even) { --d: .34em;  --dl: .05em; }
.anim .shut > span { opacity: 0 }
.anim .shut.go > span { animation: shutter .85s cubic-bezier(.19,1,.22,1) calc(var(--i) * 85ms + .1s) both }
.anim .shut.loop.go > span { animation:
  shutter .85s cubic-bezier(.19,1,.22,1) calc(var(--i) * 85ms + .1s) both,
  shutterLoop 3s cubic-bezier(.4,0,.2,1) calc(var(--i) * 60ms + 2s + var(--lo, 0s)) infinite; }
.anim .shut.loop.go::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(180deg, color-mix(in srgb, var(--tx) 60%, transparent) 0 1px, transparent 1px calc(100% / 6));
  opacity: 0; animation: seams 3s ease-out calc(2s + var(--lo, 0s)) infinite;
}
@keyframes shutter { from { transform: translateX(var(--d)); opacity: 0 } to { transform: none; opacity: 1 } }
@keyframes shutterLoop { 0%,64% { transform: none } 76% { transform: translateX(var(--dl)) } 90%,100% { transform: none } }
@keyframes seams { 0%,62% { opacity: 0 } 76% { opacity: .3 } 92%,100% { opacity: 0 } }
/* Scoped to the page. Unqualified, this rule also caught the site footer's
   own heading — `<h3 class="title">WE MAKE VILNIUS DANCE</h3>` — and blew it
   up to 126px on one unwrapping line, straight across the footer menu. The
   class is the site's, not this page's; only this page's copy is ours to
   size. */
.gravity-techno .title { font-size: clamp(40px, 8.2vw, 126px); white-space: nowrap }

.shim { background-image: linear-gradient(100deg,
    #fff 0 40%, var(--tx) 47%, color-mix(in srgb, var(--tx) 22%, #ffffff) 51%, var(--tx) 55%, #fff 62% 100%);
  background-size: 250% 100%; background-position: 170% 0;
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
  animation: shim 6s linear infinite; }
@keyframes shim { 0% { background-position: 170% 0 } 77%, 100% { background-position: -70% 0 } }

.pitch { font-size: clamp(14px, 1.5vw, 18px); line-height: 1.5; color: rgba(255,255,255,.88);
  margin: 0; max-width: 46ch; }
.pitch b { color: #fff; font-weight: 500; }
/* Date, time, room, age. The four things someone checks before they decide,
   so they are set to be read across a room rather than found: bigger than the
   caption they were, bold, and near-white instead of the muted grey the rest
   of the small print uses. */
.metarow { display: flex; flex-wrap: wrap; gap: 8px 0; margin: 0; padding: 0; list-style: none; justify-content: center; }
.metarow li { font-family: var(--mono); font-size: clamp(13.5px, 1.15vw, 16px); font-weight: 700;
  letter-spacing: .03em; text-transform: uppercase;
  color: rgba(255,255,255,.86); padding-right: 16px; margin-right: 16px;
  border-right: 1px solid var(--line-2); white-space: nowrap; }
.metarow li:last-child { border-right: 0; margin-right: 0; padding-right: 0; }
.metarow b { color: #fff; font-weight: 700; }
.heroctas { display: flex; gap: 11px; flex-wrap: wrap; justify-content: center; }

/* ---------- set times — the live page's "Know when they play" ---------- */
.settimes { display: grid; grid-template-columns: repeat(auto-fit, minmax(178px, 1fr)); gap: 1px;
  background: var(--line); border: 1px solid var(--line); margin-top: clamp(26px, 3.5vw, 40px); }
.slot { background: var(--ink-2); padding: 24px 20px; display: flex; flex-direction: column; gap: 9px; }
.slot .t { font-family: var(--mono); font-size: 12px; font-weight: 700; letter-spacing: .16em; color: var(--tx); }
.slot .n { font-family: var(--display); font-size: clamp(17px, 1.9vw, 22px); font-weight: 500;
  text-transform: uppercase; letter-spacing: -.03em; line-height: 1.05; }
.slot.tba .n { color: var(--fg-3); }
.slot.head { background-color: var(--tx); }
.slot.head .t, .slot.head .n { color: var(--tx-ink); }
.heroproof { margin: 0; font-family: var(--mono); font-size: 12px; color: var(--tx); letter-spacing: .02em; }
.heroproof i { display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background-color: var(--tx); margin-right: 8px; animation: pulse 1.8s ease-in-out infinite; vertical-align: middle; }
.raveLink { font-family: var(--mono); font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--fg-2); border-bottom: 1px solid var(--line-2); padding-bottom: 3px; }
.raveLink:hover { color: #fff; border-color: #fff; }
.scroll-hint { position: absolute; bottom: 13px; left: 50%; transform: translateX(-50%); z-index: 3;
  font-family: var(--mono); font-size: 9px; letter-spacing: .34em; text-transform: uppercase; color: var(--fg-3); }
.pl { width: 15px; height: 15px; fill: currentColor; }


/* ---------- section headings: a numbered slug and a two-tone head ----------
   The number is the reader's position in the night, not decoration: it tells
   you how much is left. The heading splits white / green, so the second line
   carries the point and the first only sets it up. The sweep is one pass of
   light when the block lands — deliberately a sweep and not a strobe, because
   rapid flashing is a genuine seizure risk on a page nobody can warn you
   about first. */
.slug { font-family: var(--mono); font-size: 11px; letter-spacing: .24em; text-transform: uppercase;
  color: var(--fg-3); margin: 0 0 20px; display: flex; align-items: center; gap: 14px; }
.slug b { color: var(--tx); font-weight: 500; }
.slug::after { content: ''; flex: 1; height: 1px; background: var(--line); }
h2.head, .head { font-family: var(--display); font-weight: 500; text-transform: uppercase;
  letter-spacing: -.045em; line-height: .86; font-size: clamp(32px, 5.8vw, 86px);
  margin: 0; color: rgba(255,255,255,.92); }

.sweep { position: relative; display: inline-block;
  background-image: linear-gradient(100deg, currentColor 0 42%, #fff 47%, var(--tx) 50%, #fff 53%, currentColor 58% 100%);
  background-size: 300% 100%; background-position: 160% 0;
  -webkit-background-clip: text; background-clip: text; }
.anim .rv.in .sweep, .anim .in.sweep { animation: sweep 1.5s cubic-bezier(.3,0,.2,1) .15s both; }
@keyframes sweep { from { background-position: 160% 0 } to { background-position: -60% 0 } }
@media (prefers-reduced-motion: reduce) { .sweep { animation: none !important; } }


/* the one word the section is about. Green alone was not enough at this size:
   it needs to look struck into the surface, not coloured in. */
.head .shout { font-weight: 600; filter: drop-shadow(0 0 26px color-mix(in srgb, var(--tx) 40%, transparent)); }

/* ---------- hero title that fills the line, whatever the name ----------
   A fixed clamp is a compromise between "Kobosil" and "Charlie Sparks": one
   ends up small and lost, the other wraps into three lines. The script splits
   the name into balanced lines and sets --fit so the widest one lands just
   inside the measure. The clamp below is what shows before it runs and if it
   never does, so the heading is never invisible and never enormous. */
.hero .title { font-size: var(--fit, clamp(44px, 12vw, 178px)); line-height: .84;
  letter-spacing: -.055em; width: 100%; }
.hero .title i { font-style: normal; display: block; width: max-content; max-width: 100%;
  margin-inline: auto; white-space: nowrap; }



/* ---------- vertical cut reveal ----------
   Each letter sits in a clipped box and rises into it, staggered outward from
   the middle of the line. Ported from a React/Framer component: the spring is a
   cubic-bezier that overshoots once and settles, which is what the physics was
   doing and costs nothing to run.

   It fires once, when the heading first arrives, and never again — a heading
   that re-animates every time it scrolls past reads as a page that cannot sit
   still. Nothing is hidden until the script says it can be: no JS, no fonts, or
   reduced motion, and the words are simply there. */
.vcr { display: inline-block; overflow: hidden; vertical-align: bottom; }
/* letters break lines wherever they like unless the word holds them */
.vcr-word { display: inline-block; white-space: nowrap; }
.head .vcr:has(> em:not(.shout)) { display: block; }
.vcr > span { display: inline-block; will-change: transform; }
.anim .vcr-ready .vcr > span { transform: translateY(105%); }
.anim .vcr-ready.vcr-go .vcr > span {
  animation: vcrUp .62s cubic-bezier(.22,1.28,.32,1) both;
  animation-delay: var(--d, 0s);
}
@keyframes vcrUp { from { transform: translateY(105%) } to { transform: none } }
@media (prefers-reduced-motion: reduce) {
  .anim .vcr-ready .vcr > span { transform: none; animation: none !important; }
}


/* ---------- the green half, lit from inside ----------
   The reference does this with four blurred orbs drifting behind the letters in
   a blend mode. The read is colour moving through the type, and a background
   that is already inside the text gives the same read for one paint instead of
   five composited layers — which matters on a heading that sits over a video.

   The three stops are the accent and two neighbours mixed from it in oklch, so
   they follow whatever colour the event is set to and stay in its family. Deliberately
   narrow: this is one colour breathing, not a rainbow. */
.head em {
  font-style: normal;
  /* Five stops, not three, and mixed harder. The first pass stayed so close to
     the accent that the movement was invisible at reading distance — it read as
     a flat green with a slight sheen. These lean further out: a cold teal, a hot
     lime and a violet edge, each still mixed *from* the accent in oklch, so a
     red or a blue event produces its own neighbours rather than these ones.
     Far enough to see, near enough to stay one colour family. */
  background-image: linear-gradient(100deg,
    color-mix(in oklch, var(--tx) 62%, #6B4DFF) 0%,
    var(--tx) 18%,
    color-mix(in oklch, var(--tx) 55%, #17E8D0) 36%,
    #ffffff 50%,
    color-mix(in oklch, var(--tx) 55%, #D8FF34) 64%,
    var(--tx) 82%,
    color-mix(in oklch, var(--tx) 62%, #6B4DFF) 100%);
  background-size: 320% 100%;
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  animation: emdrift 9s ease-in-out infinite alternate;
}
@keyframes emdrift { from { background-position: 0% 0 } to { background-position: 100% 0 } }
/* Green on black is the one pairing where transparent text can vanish: if the
   clip is unsupported the letters would be the page. Paint the colour back. */
@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .head em { color: var(--tx); background-image: none; }
}
@media (prefers-reduced-motion: reduce) { .head em { animation: none; } }


/* ---------- the derived accents, resolved where the accent actually is ------
   A custom property is computed at the element that declares it. --tx-hi and
   --tx-dim are declared on :root, so their var(--tx) reads the default green
   however the page is repainted further down — which is how a pink event kept
   a green "on sale" row and a green button hover. Restating them on the
   wrapper is what makes them follow the accent the template writes there. */
.gravity-techno {
  --tx-hi:  color-mix(in srgb, var(--tx) 72%, #ffffff);
  --tx-dim: color-mix(in srgb, var(--tx) 15%, transparent);
  --action: var(--tx);
  --action-hi: var(--tx-hi);
}

/* ---------- undo the parent theme's element-level shouting ----------
   Lives here rather than in the theme copy because this file is what the theme
   stylesheet is generated from: an edit made only over there is wiped by the
   next regeneration, which is exactly how the headings ended up centred again.

   style-new.css sets the whole font shorthand, colour, alignment and transform
   on bare `p` and `h1`–`h5` with !important, which no amount of specificity can
   outrank. Restating the browser's own behaviour — inherit from the parent —
   hands control back to the rules below. :where() keeps the specificity at
   element level so every class still wins, and the armour generator gives
   these the !important they need to beat the shouting. */
:where(.gravity-techno) h1, :where(.gravity-techno) h2, :where(.gravity-techno) h3,
:where(.gravity-techno) h4, :where(.gravity-techno) h5 {
  text-align: inherit; color: inherit; text-transform: inherit;
}
:where(.gravity-techno) p {
  text-align: inherit; color: inherit; text-transform: inherit;
  font-family: inherit; font-size: inherit; font-weight: inherit;
  line-height: inherit; letter-spacing: inherit;
}
:where(.gravity-techno) footer p { color: inherit; text-align: inherit; }

/* ---------- shared furniture ---------- */
.sec { padding-block: clamp(60px, 8.5vw, 116px); }
section[id] { scroll-margin-top: 78px; }
.sec h2, .bighead { font-family: var(--display); font-weight: 500; text-transform: uppercase;
  letter-spacing: -.045em; line-height: .93; font-size: clamp(30px, 5vw, 62px); margin: 0; }
.sec .lede { margin-top: 18px; max-width: 54ch; }
.kicker { display: flex; align-items: center; gap: 9px; margin: 0 0 16px;
  font-family: var(--mono); font-size: 10.5px; font-weight: 700; letter-spacing: .26em;
  text-transform: uppercase; color: var(--tx); }
.kicker.mute { color: var(--fg-3); }
.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px, 5vw, 72px); align-items: start; }
.anim .rv { opacity: 0; transform: translateY(22px);
  transition: opacity .75s ease, transform .75s cubic-bezier(.2,.8,.2,1) }
.anim .rv.in { opacity: 1; transform: none }
.rule { height: 1px; background: var(--line); border: 0; margin: 0; }
footer { padding: 42px 0 58px; border-top: 1px solid var(--line); color: var(--fg-3); font-size: 13px; }
footer .mono { font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; }

/* ---------- THIS IS A RAVE — the concept block ---------- */
.rave { background: var(--ink-2); border-block: 1px solid var(--line); }
.rave .heads { max-width: 720px; margin-bottom: clamp(34px, 5vw, 58px); }
.rave .cols { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line);
  border: 1px solid var(--line); }
.rave .col { background: var(--ink-2); padding: clamp(24px, 3vw, 38px); }
.rave .col h3 { margin: 0 0 22px; font-family: var(--mono); font-size: clamp(11px, .95vw, 13px); font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase; }
.rave .col.no h3 { color: var(--fg-3); }
.rave .col.yes h3 { color: var(--tx); }
.rave ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 13px; }
/* These two lists are the page's argument — what the night is and is not —
   so they are set a step up from body copy and with weight behind them,
   rather than as the caption-sized run they were. */
/* These two lists are the section's whole argument, and on a wide screen they
   were still set at reading-caption size while the heading above them ran to
   86px. Given room to grow on a desktop; the phone keeps the size it had. */
.rave li { font-size: clamp(15.5px, 1.9vw, 22px); font-weight: 500; line-height: 1.45;
  position: relative; padding-left: 24px; }
.rave li::before { content: '—'; position: absolute; left: 0; top: 0;
  color: var(--fg-3); font-family: var(--mono); }
.rave .col.no li { color: var(--fg-3); }
.rave .col.no li b { text-decoration: line-through; text-decoration-thickness: 1px; color: rgba(255,255,255,.5); font-weight: 400; }
.rave .col.yes li::before { content: '+'; color: var(--tx); }
.rave .foot { margin: 30px 0 0; font-family: var(--mono); font-size: clamp(12px, 1.05vw, 14.5px); color: var(--fg-3); letter-spacing: .04em; }
.rave .foot b { color: #fff; font-weight: 500; }

/* ---------- 2 · IF YOU LIKE — marquee belts ---------- */
.iflike { padding-block: clamp(56px, 8vw, 104px); overflow: hidden; }
.iflike .wrap { text-align: center; }
.iflike .kicker { justify-content: center; }
.namesbelt { overflow: hidden; margin-block: 20px; -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.belt { display: flex; width: max-content; gap: 12px; animation: belt 44s linear infinite; }
.b-nights .belt { animation-duration: 34s; animation-direction: reverse; }
@keyframes belt { to { transform: translateX(-50%) } }
.belt span { font-family: var(--display); font-size: clamp(24px, 3.4vw, 46px); font-weight: 500;
  text-transform: uppercase; letter-spacing: -.03em; padding: 8px 22px; border: 1px solid var(--line-2);
  border-radius: 3px; white-space: nowrap; color: var(--fg-2); }
.belt span.solid { background-color: var(--tx); border-color: var(--tx); color: var(--tx-ink); }
.b-nights .belt span { font-family: var(--mono); font-size: clamp(12px, 1.5vw, 17px); font-weight: 700;
  letter-spacing: .14em; padding: 9px 18px; }
.iflike .tail { font-size: clamp(16px, 2vw, 22px); margin: 26px 0 22px; color: var(--fg-2); }
.iflike .tail b { color: #fff; font-weight: 500; }

/* ---------- 3 · THE ARTIST — three switchable variants =====================
   Opera proves its headliner with accolades: Grammy, platinum, Billboard,
   Pacha. Down here those same badges read as "sold out" in the other sense,
   so the proof has to be rebuilt from a different currency. Three drafts ship
   side by side; pick one before this goes near WordPress.

     A · THE STAGES   the same facts-grid mechanic, underground content
     B · NONE OF THAT  strikes out the industry badges, then names the real
                       currency. Note the struck items are GENERIC industry
                       symbols — never Opera. Gravity sells both nights and
                       one page must not sneer at the other.
     C · THE SET       no facts at all. A BPM arc across eight hours and the
                       set itself. Needs a real recording to work.
   ========================================================================== */
.artist { border-top: 1px solid var(--line); }
.vswitch { display: flex; gap: 1px; background: var(--line); border: 1px solid var(--line);
  border-radius: 4px; overflow: hidden; margin-bottom: clamp(28px, 4vw, 46px); width: max-content; max-width: 100%; flex-wrap: wrap; }
.vswitch button { background: var(--ink); padding: 11px 18px; font-family: var(--mono);
  font-size: 11px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
  color: var(--fg-3); transition: .16s; }
.vswitch button:hover { color: #fff; }
.vswitch button.on { background-color: var(--tx); color: var(--tx-ink); }
.avar { display: none; }
.avar.on { display: block; animation: fadein .4s ease both; }
@keyframes fadein { from { opacity: 0; transform: translateY(10px) } to { opacity: 1; transform: none } }

/* A · stages */
.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 1px;
  background: var(--line); border: 1px solid var(--line); margin: 0; }
.facts > div { background: var(--ink); padding: 22px 20px; }
.facts dt { font-family: var(--mono); font-size: 10px; font-weight: 700; letter-spacing: .2em;
  text-transform: uppercase; color: var(--fg-3); margin-bottom: 9px; }
.facts dd { margin: 0; font-family: var(--display); font-size: clamp(19px, 2vw, 25px); font-weight: 500;
  text-transform: uppercase; letter-spacing: -.025em; line-height: 1.04; }
.facts dd small { display: block; font-family: var(--mono); font-size: 10.5px; font-weight: 400;
  letter-spacing: .06em; text-transform: none; color: var(--fg-3); margin-top: 7px; line-height: 1.4; }
.stages { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 24px; }
.stages span { font-family: var(--mono); font-size: 11.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; padding: 9px 14px; border: 1px solid var(--line-2); border-radius: 3px; color: var(--fg-2); }
.stages span.hi { border-color: var(--tx); color: var(--tx); }

/* B · none of that */
.struck { display: flex; flex-wrap: wrap; gap: 10px 14px; margin-bottom: 30px; }
.struck span { font-family: var(--display); font-size: clamp(24px, 3.8vw, 52px); font-weight: 500;
  text-transform: uppercase; letter-spacing: -.04em; color: rgba(255,255,255,.19);
  position: relative; line-height: 1; }
.struck span::after { content: ''; position: absolute; left: -2%; right: -2%; top: 52%; height: 2px;
  background: rgba(255,255,255,.3); transform: scaleX(0); transform-origin: left;
  transition: transform .5s cubic-bezier(.2,.8,.2,1); }
.avar.on .struck span::after { transform: scaleX(1); transition-delay: calc(var(--n) * 90ms + .2s); }
.verdict { font-family: var(--display); font-size: clamp(26px, 4vw, 54px); font-weight: 500;
  text-transform: uppercase; letter-spacing: -.04em; line-height: .98; margin: 0 0 12px; }
.verdict em { font-style: normal; color: var(--tx); }
.verdict + .lede { max-width: 52ch; margin-bottom: 34px; }

/* C · the set */
.bpm { border: 1px solid var(--line); padding: clamp(20px, 3vw, 32px); background: var(--ink-2); }
.bpm-head { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; flex-wrap: wrap;
  font-family: var(--mono); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--fg-3); }
.bpm-head b { color: var(--tx); font-weight: 700; }
.bpm svg { width: 100%; height: auto; display: block; margin: 22px 0 10px; overflow: visible; }
.bpm .axis { display: flex; justify-content: space-between; font-family: var(--mono);
  font-size: 10.5px; letter-spacing: .08em; color: var(--fg-3); }
.bpm-line { fill: none; stroke: var(--tx); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 1000; stroke-dashoffset: 1000; }
.avar.on .bpm-line { animation: draw 1.9s cubic-bezier(.4,0,.2,1) .25s forwards; }
@keyframes draw { to { stroke-dashoffset: 0 } }
.ids { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); margin-top: 26px; }
.id-row { background: var(--ink); display: grid; grid-template-columns: 54px 1fr auto; gap: 16px;
  align-items: center; padding: 15px 18px; font-family: var(--mono); font-size: 12.5px; }
.id-row .no { color: var(--tx); font-weight: 700; letter-spacing: .1em; }
.id-row .tr { font-family: var(--display); font-size: clamp(16px, 1.8vw, 21px); font-weight: 500;
  text-transform: uppercase; letter-spacing: -.02em; }
.id-row .yr { color: var(--fg-3); letter-spacing: .08em; }

/* ---------- 4 · VOLUME — the room ---------- */
.vol { position: relative; overflow: hidden; padding-block: clamp(80px, 12vw, 150px); }
.vol video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0;
  filter: grayscale(1) contrast(1.22) brightness(.62); }
.vol .tint { position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(180deg, rgba(5,5,6,.82), rgba(5,5,6,.30) 45%, rgba(5,5,6,.88)); }
.vol .glow { position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(60% 46% at 50% 52%, color-mix(in srgb, var(--tx) 16%, transparent), transparent 70%); }
.vol .inner { position: relative; z-index: 2; }
.vol h2 { font-size: clamp(52px, 13vw, 190px); }
.vol .lede { margin-top: 20px; max-width: 50ch; }
.specs { list-style: none; margin: 34px 0 0; padding: 0; display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 1px; background: var(--line);
  border: 1px solid var(--line); }
/* See-through rather than a solid slab. The three boxes sit over the video
   behind them, and an almost-opaque panel cut three rectangles out of it. Now
   the footage carries on underneath and a blur keeps the type readable — the
   panel reads as glass on the room rather than as three holes in it. */
.specs li { background: rgba(5,5,6,.16); backdrop-filter: blur(4px) saturate(1.05);
  -webkit-backdrop-filter: blur(4px) saturate(1.05);
  border: 1px solid rgba(255,255,255,.10); padding: 20px; }
/* Where a browser cannot blur, lean back on opacity — glass that does not
   blur is just a smear, and the text has to stay readable. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .specs li { background: rgba(5,5,6,.66) }
}
.specs .k { font-family: var(--mono); font-size: 10px; font-weight: 700; letter-spacing: .22em;
  text-transform: uppercase; color: var(--tx); margin-bottom: 8px; }
.specs .v { font-size: 14.5px; line-height: 1.45; color: var(--fg-2); }

/* ---------- 5 · THE MORNING AFTER ---------- */
.morning { padding-block: clamp(56px, 8vw, 100px); overflow: hidden; }
.morning .head { text-align: center; max-width: 660px; margin: 0 auto clamp(30px, 4vw, 48px); }
.morning .head .kicker { justify-content: center; }
/* Two rows drifting past each other. The duration is per-row rather than
   per-pixel, so on a phone — where the same cards cross a third of the width —
   the drift read as a sprint. The phone gets its own, much longer pass below.

   Tapping a row stops it: these are meant to be read, and on a touch screen
   there is no hover to lean on. The script adds .paused; the pointer version
   is here for a mouse. */
.mrow { display: flex; gap: 14px; width: max-content; margin-bottom: 14px;
  animation: belt 62s linear infinite; }
.mrow.r2 { animation-duration: 74s; animation-direction: reverse; }
.mrow.paused { animation-play-state: paused; }
@media (hover: hover) { .mrow:hover { animation-play-state: paused; } }
@media (max-width: 640px) {
  .mrow { animation-duration: 128s; }
  .mrow.r2 { animation-duration: 150s; }
}
.story { width: 288px; flex: none; background: var(--ink-2); border: 1px solid var(--line);
  border-radius: 4px; padding: 15px 16px; rotate: var(--tilt, 0deg); }
.story .top { display: flex; align-items: center; gap: 9px; margin-bottom: 9px; }
.story .av { width: 22px; height: 22px; border-radius: 50%; flex: none;
  background: linear-gradient(135deg, var(--tx), #1c3a1b); }
.story .who { font-family: var(--mono); font-size: 11.5px; font-weight: 700; }
.story .when { font-family: var(--mono); font-size: 10.5px; color: var(--fg-3); margin-left: auto; }
.story p { margin: 0; font-size: 13.5px; line-height: 1.45; color: rgba(255,255,255,.9); }
.story .re { margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em; color: var(--fg-3); text-transform: uppercase; }
.story .re b { color: var(--tx); font-weight: 700; }

/* ---------- 6 · THE RECORD ---------- */
.led { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.led-row { background: var(--ink); display: grid; grid-template-columns: 78px 1fr auto auto; gap: 18px;
  align-items: center; padding: 17px 20px; font-family: var(--mono); font-size: 12px; }
.led-row .no { color: var(--fg-3); letter-spacing: .14em; font-weight: 700; }
.led-row .nm { font-family: var(--display); font-size: clamp(18px, 2.2vw, 26px); font-weight: 500;
  text-transform: uppercase; letter-spacing: -.03em; }
.led-row .ppl { color: var(--fg-3); letter-spacing: .06em; }
.led-row .st { letter-spacing: .12em; text-transform: uppercase; font-weight: 700; color: var(--fg-3); }
.led-row.gone .nm, .led-row.gone .ppl { color: var(--fg-3); }
.led-row.now { background-color: var(--tx-dim); }
.led-row.now .no, .led-row.now .st { color: var(--tx); }
.led-row.now .nm { color: #fff; }

/* ---------- 7 · LINE-UP ---------- */
.acts { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.act { background: var(--ink); display: flex; align-items: center; gap: 16px; padding: 20px 22px; flex-wrap: wrap; }
/* Everyone who is not the headliner is set smaller and dimmer. The two used
   to sit 8px apart on a phone, which is not a difference anyone reads as a
   billing order — it read as one list in two sizes. */
.act .nm { font-family: var(--display); font-size: clamp(20px, 3.6vw, 46px); font-weight: 500;
  color: var(--fg-2);
  text-transform: uppercase; letter-spacing: -.04em; line-height: .95; }
.act.head { background: var(--ink-2); padding-block: clamp(26px, 3.4vw, 40px); }
.act.head .nm { font-size: clamp(46px, 6vw, 76px); color: #fff; }
.act .cc, .act .role { font-family: var(--mono); font-size: 10.5px; font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase; }
.act .cc { color: var(--fg-3); border: 1px solid var(--line-2); border-radius: 3px; padding: 5px 9px; }
.act .role { margin-left: auto; color: var(--tx); }
.act.tba { opacity: .5; }
.act.tba .nm { font-size: clamp(18px, 2.2vw, 26px); color: var(--fg-2); }
.act.tba .role { color: var(--fg-3); }
.act .ig { width: 34px; height: 34px; display: grid; place-items: center; border: 1px solid var(--line-2);
  border-radius: 3px; transition: .16s; }
.act .ig:hover { border-color: var(--tx); }
.act .ig svg { width: 16px; height: 16px; fill: currentColor; }

/* ---------- 8 · RELEASES ---------- */
.rel-rows { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.rel-row { background: var(--ink); display: grid; grid-template-columns: 1fr auto auto; gap: 18px;
  align-items: center; padding: 18px 22px; font-family: var(--mono); font-size: 12px; }
.rel-row .nm { font-family: var(--display); font-size: clamp(17px, 2vw, 23px); font-weight: 500;
  text-transform: uppercase; letter-spacing: -.03em; }
.rel-row .st { color: var(--fg-3); letter-spacing: .08em; text-transform: uppercase; }
.rel-row .pr { font-size: 15px; font-weight: 700; letter-spacing: .04em; text-align: right; min-width: 110px; }
.rel-row.now { background-color: var(--tx-dim); }
.rel-row.now .st, .rel-row.now .pr { color: var(--tx); }
.rel-row.next .pr, .rel-row.later .pr { color: var(--fg-2); }
.rel-row.later { opacity: .62; }
body.show-notes .relnote { margin: 22px 0 0; font-family: var(--mono); font-size: 12px; color: var(--fg-3); letter-spacing: .03em; }
.relnote b { color: var(--tx); font-weight: 700; }

/* ---------- 9 · GALLERY ---------- */
.gal { position: relative; padding-block: clamp(46px, 7vw, 84px) clamp(56px, 8vw, 100px); }
.gal-head { padding-inline: var(--pad); margin-bottom: 30px; position: relative; z-index: 2; }
/* the word sits behind the strip and never moves */
.gal-ghost { position: absolute; inset: 0; z-index: 0; display: grid; place-items: center; pointer-events: none; }
.gal-ghost .ghostword { font-family: var(--display); font-weight: 600; font-size: clamp(70px, 17vw, 260px);
  letter-spacing: -.05em; line-height: 1; white-space: nowrap; text-transform: uppercase; }
.gal-ghost .ghostword > span { color: transparent; -webkit-text-stroke: 1px rgba(255,255,255,.07); }
/* the strip: every panel shares the width until one takes over. Without JS
   they simply stay equal, so all six photos are always visible. */
.strip { display: flex; gap: 10px; padding-inline: var(--pad);
  height: min(70svh, 600px); position: relative; z-index: 1; }
.strip figure { flex: 1 1 0; min-width: 0; margin: 0; position: relative; overflow: hidden;
  border-radius: 4px; cursor: pointer; background: var(--ink-2);
  transition: flex-grow .75s cubic-bezier(.2,.8,.2,1);
  box-shadow: 0 30px 70px -46px rgba(0,0,0,.95); }
.strip figure.on { flex-grow: 4.4 }
.strip img { width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(1) brightness(.52) contrast(1.08); transform: scale(1.08);
  transition: filter .75s ease, transform 1s cubic-bezier(.2,.8,.2,1); }
.strip figure.on img { filter: grayscale(0) brightness(1) contrast(1.02); transform: none }
.strip figure::after { content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  border: 1px solid rgba(255,255,255,.08); transition: border-color .5s; }
.strip figure.on::after { border-color: color-mix(in srgb, var(--tx) 32%, transparent) }
/* the number runs vertically while the panel is a sliver */
.strip .tag { position: absolute; left: 0; bottom: 0; padding: 16px 0 18px 16px; z-index: 2;
  writing-mode: vertical-rl; transform: rotate(180deg); font-family: var(--mono);
  font-size: 10px; letter-spacing: .22em; text-transform: uppercase; color: rgba(255,255,255,.62);
  white-space: nowrap; transition: opacity .35s; }
.strip figure.on .tag { opacity: 0 }
.strip figcaption { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: 22px 24px; opacity: 0; transform: translateY(10px);
  transition: opacity .5s .15s, transform .6s .15s cubic-bezier(.2,.8,.2,1);
  background: linear-gradient(transparent, rgba(5,5,6,.92)); }
.strip figure.on figcaption { opacity: 1; transform: none }
.strip figcaption b { display: block; font-family: var(--display); font-size: clamp(17px, 1.8vw, 24px);
  font-weight: 600; text-transform: uppercase; letter-spacing: -.01em; margin-bottom: 5px; }
.strip figcaption span { font-family: var(--mono); font-size: 11px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--fg-2) }
.strip figcaption i { font-style: normal; color: var(--tx); margin-right: 9px; font-weight: 700 }

/* ---------- sparkbar — a lit filament with dust falling off it ----------
   Ported from the live Opera theme. The line is CSS; the specks are a canvas
   below it, masked so they thin out toward the edges. Nothing here carries
   meaning: it is aria-hidden and the section reads the same without it. */
.sparkbar { position: relative; width: min(420px, 84%); height: 128px;
  margin: 54px auto 0; pointer-events: none; }
.sparkbar > i { position: absolute; left: 0; right: 0; top: 0; height: 2px; display: block;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.72) 18%,
    var(--tx) 50%, rgba(255,255,255,.72) 82%, transparent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--tx) 55%, transparent); }
.sparkbar > i::after { content: ''; position: absolute; inset: -12px 10% auto; height: 34px;
  background: radial-gradient(50% 100% at 50% 0%, color-mix(in srgb, var(--tx) 58%, transparent), transparent 74%);
  filter: blur(10px); }
.sparkbar canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  -webkit-mask-image: radial-gradient(66% 96% at 50% 0%, #000 22%, rgba(0,0,0,.55) 66%, transparent 94%);
          mask-image: radial-gradient(66% 96% at 50% 0%, #000 22%, rgba(0,0,0,.55) 66%, transparent 94%); }
@media (max-width: 640px) { .sparkbar { width: 86%; height: 104px; margin-top: 40px } }
@media (prefers-reduced-motion: reduce) { .sparkbar > i::after { display: none } }

/* ---------- set-times aurora ---------- */
.settimes-sec { position: relative; overflow: hidden }
.settimes-sec > .wrap { position: relative; z-index: 1 }
.settimes-sec .stfx {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  pointer-events: none; opacity: .55;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 22%, #000 78%, transparent);
          mask-image: linear-gradient(180deg, transparent, #000 22%, #000 78%, transparent);
}
@media (prefers-reduced-motion: reduce) { .settimes-sec .stfx { display: none } }

/* ---------- 10 · SOUND ---------- */
.spot iframe { width: 100%; height: 352px; border: 0; border-radius: 4px; }

/* ---------- 11 · TICKET ---------- */
.tkt { position: relative; padding-block: clamp(64px, 9vw, 120px); overflow: hidden; }
.tkt > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0;
  filter: grayscale(.85) contrast(1.25) brightness(.45); }
.tkt .tint { position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(180deg, rgba(5,5,6,.94), rgba(5,5,6,.7) 50%, rgba(5,5,6,.96)); }
.ticket { position: relative; z-index: 2; max-width: 980px; margin-inline: auto;
  display: grid; grid-template-columns: 1.5fr 1fr; background: var(--ink-2);
  border: 1px solid var(--line-2); border-radius: 5px; overflow: hidden; }
.ticket .main { padding: clamp(26px, 3.4vw, 44px); display: grid; gap: 16px; align-content: start; }
.ticket .release { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  font-family: var(--mono); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; }
.ticket .live { color: var(--tx); font-weight: 700; display: inline-flex; align-items: center; gap: 8px; }
.ticket .out { color: var(--fg-3); }
.tname { font-size: clamp(30px, 5vw, 62px); }
.tfacts { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 18px; margin: 6px 0 0; }
.tfacts dt { font-family: var(--mono); font-size: 9.5px; font-weight: 700; letter-spacing: .2em;
  text-transform: uppercase; color: var(--fg-3); margin-bottom: 6px; }
.tfacts dd { margin: 0; font-family: var(--mono); font-size: 13px; font-weight: 500; }
.ticket .stub { border-left: 1px dashed var(--line-2); padding: clamp(26px, 3.4vw, 40px);
  display: grid; gap: 18px; align-content: center; background-color: color-mix(in srgb, var(--tx) 5%, transparent); }
.ticket .when { font-family: var(--mono); font-size: 10.5px; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--fg-3); }
.ticket .amount { font-family: var(--display); font-size: clamp(40px, 6vw, 66px); font-weight: 600;
  line-height: 1; letter-spacing: -.04em; margin-top: 8px; }
.ticket .later { font-family: var(--mono); font-size: 11px; color: var(--fg-3); margin-top: 8px; letter-spacing: .04em; }
.ticket .rise { font-family: var(--mono); font-size: 10.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--tx); border-top: 1px solid var(--line); padding-top: 16px; }
.ticket .paynote { font-family: var(--mono); font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--fg-3); text-align: center; margin-top: 10px; }

/* ---------- 12 · FAQ ---------- */
.faq { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); margin-top: 30px; }
.faq details { background: var(--ink); }
.faq summary { list-style: none; cursor: pointer; padding: 19px 22px; display: flex;
  justify-content: space-between; gap: 18px; align-items: center;
  font-size: clamp(14.5px, 1.5vw, 17px); font-weight: 500; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: '+'; font-family: var(--mono); color: var(--tx); font-size: 18px; flex: none; }
.faq details[open] summary::after { content: '\2212'; }
.faq p { margin: 0; padding: 0 22px 21px; color: var(--fg-2); font-size: 14.5px; line-height: 1.55; max-width: 72ch; }
.faq p b { color: #fff; font-weight: 500; }

/* ---------- 13 · CLOSING ---------- */
.close { position: relative; text-align: center; padding-block: clamp(80px, 12vw, 150px); overflow: hidden; }
.close .sparkles {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  width: 100%; height: 100%; display: block;
  -webkit-mask-image: radial-gradient(60% 55% at 50% 62%, #000 25%, rgba(0,0,0,.35) 62%, transparent 88%);
          mask-image: radial-gradient(60% 55% at 50% 62%, #000 25%, rgba(0,0,0,.35) 62%, transparent 88%);
}
/* a thin seam of light the sparkles seem to rise from */
.close .seam {
  position: absolute; left: 50%; translate: -50% 0; bottom: 26%;
  width: min(560px, 74%); height: 1px; z-index: 0; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.45) 22%, var(--tx) 50%, rgba(255,255,255,.45) 78%, transparent);
  opacity: .55;
}
.close .seam::after {
  content: ''; position: absolute; inset: -14px 12% auto; height: 30px;
  background: radial-gradient(50% 100% at 50% 0%, color-mix(in srgb, var(--tx) 30%, transparent), transparent 70%);
  filter: blur(10px);
}
@media (max-width: 640px) { .close .seam { bottom: 22%; width: 80% } }
@media (prefers-reduced-motion: reduce) { .close .seam::after { display: none } }
.close .glow { position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(50% 44% at 50% 58%, color-mix(in srgb, var(--tx) 17%, transparent), transparent 68%); }
.close .wrap { position: relative; z-index: 1; }
.close .kicker { justify-content: center; }
.close h2 { font-size: clamp(38px, 8vw, 104px); margin-bottom: 30px; }


/* ---------- event details strip — its own block under the hero, as on the
   live page. The hero carries the name; the facts get their own air. ------- */
.details { border-bottom: 1px solid var(--line); background: var(--ink-2); }
.details .row { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1px; background: var(--line); border-inline: 1px solid var(--line); }
.details .cell { background: var(--ink-2); padding: 24px 22px; text-align: center; }
.details .k { font-family: var(--mono); font-size: 9.5px; font-weight: 700; letter-spacing: .22em;
  text-transform: uppercase; color: var(--fg-3); margin-bottom: 9px; }
.details .v { font-family: var(--display); font-size: clamp(17px, 2vw, 23px); font-weight: 500;
  text-transform: uppercase; letter-spacing: -.025em; line-height: 1.05; }
.details .v small { display: block; font-family: var(--mono); font-size: 10.5px; font-weight: 400;
  letter-spacing: .08em; text-transform: none; color: var(--fg-3); margin-top: 6px; }
.details .live { display: flex; align-items: center; justify-content: center; gap: 9px;
  padding: 14px; font-family: var(--mono); font-size: 11.5px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--tx-ink); background-color: var(--tx); }

/* ---------- past nights — four cards, the live page's chapter grid ---------- */
.chapters { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px;
  margin-top: clamp(28px, 4vw, 44px); }
.chap { position: relative; border: 1px solid var(--line); border-radius: 4px; overflow: hidden;
  min-height: 260px; display: flex; flex-direction: column; justify-content: flex-end; padding: 18px; }
.chap img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0;
  filter: grayscale(.8) contrast(1.15) brightness(.5); transition: filter .4s, transform .6s; }
.chap::after { content: ''; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(180deg, transparent 30%, rgba(5,5,6,.9)); }
.chap:hover img { filter: grayscale(.3) contrast(1.05) brightness(.6); transform: scale(1.04); }
.chap > * { position: relative; z-index: 2; }
.chap .c { font-family: var(--mono); font-size: 9.5px; font-weight: 700; letter-spacing: .2em;
  text-transform: uppercase; color: var(--fg-3); margin-bottom: 8px; }
.chap .c.live { color: var(--tx); display: flex; align-items: center; gap: 7px; }
.chap .c.live i { width: 6px; height: 6px; border-radius: 50%; background-color: var(--tx);
  animation: pulse 1.8s ease-in-out infinite; }
.chap b { font-family: var(--display); font-size: clamp(19px, 2.2vw, 26px); font-weight: 500;
  text-transform: uppercase; letter-spacing: -.03em; line-height: 1; }
.chap span { font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em; color: var(--fg-3); margin-top: 6px; }
.chap.now { border-color: var(--tx); }

/* ---------- what the artists said — four quote cards ---------- */
.voices { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: 12px;
  margin-top: clamp(28px, 4vw, 44px); }
.voice { border: 1px solid var(--line); border-radius: 4px; overflow: hidden; background: var(--ink-2); }
.voice img { width: 100%; height: 168px; object-fit: cover; filter: grayscale(.7) contrast(1.15) brightness(.72); }
.voice .said { padding: 18px; }
.voice .nm { font-family: var(--display); font-size: clamp(17px, 1.9vw, 21px); font-weight: 500;
  text-transform: uppercase; letter-spacing: -.03em; }
.voice .meta { display: block; font-family: var(--mono); font-size: 9.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--tx); margin: 7px 0 12px; }
.voice blockquote { margin: 0; font-size: 14.5px; line-height: 1.45; color: var(--fg-2); }
.voice blockquote em { font-style: normal; color: #fff; }

/* ---------- btn-beam — a light that runs the rim of the buy button ----------
   Ported from the Opera page. The rotating conic sits behind an inset fill, so
   only the 2px rim shows it; the label needs its own span to stay above both. */
.btn-beam { position: relative; overflow: hidden; isolation: isolate; }
.btn-beam > span { position: relative; z-index: 2; }
.btn-beam::before { content: ''; position: absolute; z-index: 0; left: 50%; top: 50%; width: 280%; aspect-ratio: 1;
  background: conic-gradient(from 0deg, transparent 0 56%, rgba(255,255,255,.5) 68%, #fff 75%, rgba(255,255,255,.5) 82%, transparent 92%);
  animation: beam 4.5s linear infinite; }
.btn-beam::after { content: ''; position: absolute; z-index: 1; inset: 2px; border-radius: inherit;
  background-color: var(--tx); transition: background-color .18s; }
.btn-beam:hover::after { background-color: var(--tx-hi); }
@keyframes beam { from { transform: translate(-50%,-50%) rotate(0) } to { transform: translate(-50%,-50%) rotate(360deg) } }

/* ---------- drifting dot field behind the headliner ----------
   Two stacked grids: a static white one, and a green one masked to a pool of
   light that wanders. @property is what lets the mask position interpolate;
   where it is unsupported the pool simply sits still. */
@property --gx { syntax: '<percentage>'; initial-value: 30%; inherits: false }
@property --gy { syntax: '<percentage>'; initial-value: 40%; inherits: false }
.artist { position: relative; overflow: hidden; }
.artist > .wrap { position: relative; z-index: 1; }
.dots { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden;
  -webkit-mask-image: radial-gradient(125% 92% at 50% 50%, #000 28%, transparent 86%);
          mask-image: radial-gradient(125% 92% at 50% 50%, #000 28%, transparent 86%); }
.dots i, .dots b { position: absolute; inset: -30px; display: block; background-size: 26px 26px;
  animation: dotdrift 26s linear infinite; }
.dots i { background-image: radial-gradient(circle, rgba(255,255,255,.07) 1px, transparent 1px); }
.dots b { background-image: radial-gradient(circle, var(--tx) 1px, transparent 1px); opacity: .7;
  -webkit-mask-image: radial-gradient(26% 36% at var(--gx) var(--gy), #000 0%, rgba(0,0,0,.4) 46%, transparent 74%);
          mask-image: radial-gradient(26% 36% at var(--gx) var(--gy), #000 0%, rgba(0,0,0,.4) 46%, transparent 74%);
  animation: dotdrift 26s linear infinite, glowmove 15s ease-in-out infinite alternate; }
@keyframes dotdrift { to { background-position: 26px 26px } }
@keyframes glowmove { 0% { --gx: 16%; --gy: 28% } 50% { --gx: 74%; --gy: 64% } 100% { --gx: 42%; --gy: 20% } }

/* ---------- the 3am phone glow behind the messages ----------
   Opera pairs tangerine with violet here. Techno keeps the one-colour rule, so
   it is two pools of the same green at different weights instead. */
.morning .orb { position: absolute; border-radius: 50%; filter: blur(90px); pointer-events: none; z-index: 0; }
.morning .orb.a { width: 460px; height: 460px; left: 4%; top: 22%;
  background-color: color-mix(in srgb, var(--tx) 14%, transparent); animation: orbfloat 14s ease-in-out infinite alternate; }
.morning .orb.b { width: 400px; height: 400px; right: 2%; bottom: 2%;
  background-color: color-mix(in srgb, var(--tx) 7%, transparent); animation: orbfloat 18s ease-in-out infinite alternate-reverse; }
@keyframes orbfloat { from { transform: translateY(-16px) } to { transform: translateY(20px) } }
.morning { position: relative; }
.morning .head, .morning .mrow, .morning .wrap { position: relative; z-index: 1; }


/* the progress edge — desktop keeps it as a hairline above the bar contents */
.bbar { position: relative; }
.bbar .progrow { position: absolute; left: 0; right: 0; top: 0; margin: 0; }
.bbar .prog { display: block; height: 2px; background: rgba(255,255,255,.10); overflow: visible; }
.bbar .prog b { display: block; height: 100%; background-color: var(--tx); box-shadow: 0 0 12px color-mix(in srgb, var(--tx) 90%, transparent); }

/* ---------- sticky buy bar ---------- */
.bbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60; display: flex; align-items: center;
  gap: 18px; padding: 13px var(--pad) calc(13px + env(safe-area-inset-bottom));
  background: rgba(5,5,6,.9); backdrop-filter: blur(20px) saturate(1.3);
  border-top: 1px solid var(--line-2);
}
.bbar .price { font-family: var(--display); font-size: 24px; font-weight: 600; line-height: 1; flex: none; }
/* "From" is a qualifier, not part of the number — set small and quiet so the
   price still reads at a glance. */
.bbar .price b i { font-style: normal; font-family: var(--mono); font-weight: 500;
  font-size: .46em; letter-spacing: .1em; text-transform: uppercase;
  color: var(--fg-3); vertical-align: .28em; margin-right: 3px; }
.bbar .price small { display: block; font-family: var(--mono); font-size: 9px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--tx); font-weight: 700; margin-bottom: 5px; }
.bbar .mid { flex: 1; min-width: 0; }
.bbar .rel { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  font-family: var(--mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; }
.bbar .rel .live { color: var(--tx); font-weight: 700; display: inline-flex; align-items: center; gap: 7px; }
.bbar .rel .up { color: var(--fg-3); }
.bbar .rel .upshort { display: none; }
.bbar .sep { width: 1px; height: 12px; background: var(--line-2); }
.bbar .ladder { display: flex; gap: 3px; margin-top: 9px; }
.bbar .ladder i { height: 3px; flex: 1; background: rgba(255,255,255,.13); border-radius: 2px; }
/* Behind us: filled, but spent — enough to read as done, not enough to compete
   with the release actually on sale. */
.bbar .ladder i.gone { background: rgba(255,255,255,.42); }
.bbar .ladder i.on { background-color: var(--tx);
  box-shadow: 0 0 10px color-mix(in srgb, var(--tx) 70%, transparent); }
.bbar .btn { flex: none; }

/* ---------- responsive ---------- */
@media (max-width: 900px) {
  .split, .rave .cols { grid-template-columns: 1fr; }
  /* Side by side, the eye reads left first and the two columns argue with each
     other as a pair. Stacked, whichever is on top sets the tone for the whole
     section — and that should be what the night is, not a list of things it
     isn't. So the positive column goes first once they are in one column. */
  .rave .col.yes { order: -1; }
  .ticket { grid-template-columns: 1fr; }
  .ticket .stub { border-left: 0; border-top: 1px dashed var(--line-2); }
  .spot iframe { height: 232px; }
  .note-tag { white-space: normal; max-width: min(70vw, 300px); line-height: 1.35; }
  .led-row { grid-template-columns: 62px 1fr; row-gap: 6px; }
  /* a 19px-tall standalone link is under any sane touch target */
  .raveLink { display: inline-block; padding: 10px 6px; }

  /* stacked, the strip is over 1000px tall and the ghost word ends up centred
     between two photos, where it reads as a rendering fault rather than as
     type. It only works behind a single-row strip. */
  .gal-ghost { display: none }

  /* ---------- releases and the buy bar, rebuilt for a phone ----------
     The row was a three-column grid squeezed into 335px, which collapsed the
     price column to nothing and stacked everything into a 129px block. It
     wraps on purpose now: name and price on the first line so the eye pairs
     them, status underneath where it cannot push the price around.

     The bar was one flex row carrying four releases across 375px, which is
     four things nobody can read. It becomes two columns: the price over the
     one line worth keeping, and the button spanning both. Everything the price
     already says is dropped, and the fill becomes the top edge of the bar —
     progress for no extra height at all. */
  /* On a phone the hero is the tightest screen on the page and the name is the
     thing worth the room. The scroll hint is the cheapest thing on it: nobody
     needs telling that a phone page scrolls, and dropping it is what lets the
     title stay at full width instead of stepping down by a third. */
  .hero .scroll-hint { display: none; }
  .hero .stack { padding-bottom: 8px; gap: clamp(10px, 1.7vh, 18px); }
  .rel-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; padding: 16px 14px; }
  .rel-row .nm { font-size: 22px; flex: 1; }
  .rel-row .pr { font-size: 22px; min-width: 0; text-align: right; }
  .rel-row .st { width: 100%; order: 3; font-size: 10px; }
  /* the range and the "from" are desktop luxuries: keeping them made the name
     wrap to two lines and the row grow to 105px */
  .rel-row .prrest, .rel-row .prfrom { display: none; }
  .rel-row .nm { white-space: nowrap; }

  .bbar { display: grid; grid-template-columns: 1fr auto; grid-template-rows: auto auto;
    align-items: center; column-gap: 12px; row-gap: 2px; padding: 14px 16px calc(13px + env(safe-area-inset-bottom)); }
  .bbar .prog { height: 3px; }
  .bbar .price { grid-column: 1; grid-row: 1; }
  .bbar .price small { font-size: 11px; letter-spacing: .18em; margin-bottom: 2px; }
  .bbar .price b { font-size: 29px; line-height: 1; }
  .bbar .mid { grid-column: 1; grid-row: 2; min-width: 0; }
  .bbar .buy { grid-column: 2; grid-row: 1 / span 2; align-self: center; padding: 15px 22px; }
  /* sentence case, not capitals: tracked small caps at this size is a headline
     pretending to be a sentence, and it is the slowest thing on the bar to read */
  .bbar .mid { grid-column: 1; grid-row: 2; min-width: 0; overflow: hidden; }
  .bbar .rel { font-size: 14px; letter-spacing: 0; text-transform: none;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
  .bbar .rel .live { display: inline-flex; }
  .bbar .rel .sep, .bbar .rel .upname, .bbar .ladder { display: none; }
  .bbar .rel .up ~ .up { display: none; }
  .bbar .rel .upshort { display: inline; }
  .bbar .rel .live::after { content: ' · '; color: var(--fg-3); }

  /* The strip is a desktop idea: panels share the width and one opens when you
     point at it. A phone has no pointer, so it became a column of 62px slivers
     with a single photo open — five hidden pictures and one visible.

     On a phone every photo is simply shown: two square columns, all of them in
     colour, nothing to open. Six photographs read as six photographs. */
  .strip { display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
    flex-direction: row; height: auto; overflow: visible }
  .strip figure { flex: none; height: auto; aspect-ratio: 3 / 4;
    transition: none }
  .strip figure.on { flex: none; height: auto }
  .strip img, .strip figure.on img { filter: none; transform: none }
  /* the vertical label belonged to a tall sliver and has nowhere to sit here */
  .strip .tag { display: none }
  .chapters, .voices { grid-template-columns: repeat(2, 1fr); }
  .settimes { grid-template-columns: repeat(2, 1fr); }
  .details .row { grid-template-columns: repeat(2, 1fr); }
  .led-row .ppl, .led-row .st { grid-column: 2; }
  .id-row { grid-template-columns: 40px 1fr; row-gap: 4px; }
  .id-row .yr { grid-column: 2; }
  /* "Headliner" belongs next to the name it describes, not pushed to the far
     edge of the row where it reads as a column heading. */
  .act .role { margin-left: 0; order: 3; flex-basis: 100%; margin-top: -22px; }
  .act .nm { flex-basis: 100%; }
  .act.head .nm { line-height: .94; margin-bottom: 2px; }
  .act .cc { order: 2; }
}
@media (max-width: 420px) {
  .btn { white-space: normal; text-align: center; }
  /* the bar line loses by two pixels at 375px, which is enough to ellipsis the
     next price away — the one number on it worth reading after the current one */
  .bbar .rel { font-size: 13px; }
  .bbar .buy { padding-inline: 18px; }
}
@media (prefers-reduced-motion: reduce) {
  .anim .rv { transition: none; opacity: 1; transform: none }
  .belt, .mrow, .shim, .anim .shut.loop.go > span, .anim .shut.loop.go::after { animation: none !important }
  .anim .shut > span { opacity: 1 }
  .bpm-line { stroke-dashoffset: 0 }
  html { scroll-behavior: auto }
}


/* ---------- phone: the things that were sized for a desktop ---------- */
@media (max-width: 640px) {
  /* Section headings sat on their 32px floor all the way down to 375px,
     because 5.8vw never reaches it on a phone. Given their own scale here they
     carry the same weight on a small screen that they do on a large one. */
  h2.head, .head { font-size: clamp(38px, 10.5vw, 54px); }

  /* The hero's buttons were desktop-sized and stacked, so the pair filled a
     third of the first screen. Sized to sit on one line instead — and to keep
     doing so if a third is ever added, since they shrink rather than wrap. */
  /* Two fit side by side; a third drops to its own line rather than being
     squeezed until the words break. A button whose label reads "Line- / up"
     is worse than a button on the next row. */
  .heroctas { flex-wrap: wrap; gap: 8px; width: 100%; }
  .heroctas .btn { flex: 0 1 auto; min-width: 0; white-space: nowrap; }
  .heroctas .btn-lg { padding: 15px 16px; font-size: 14px; }
  .heroctas .btn-mono { font-size: 11px; letter-spacing: .05em; }
  .heroctas .btn-mono svg { margin-right: 6px; }
}


/* ---------- phone: two things that were sized for a desktop ---------- */
@media (max-width: 640px) {
  /* The aurora behind the set times is the best-looking thing on the page and
     the phone was seeing the least of it: the section is narrow and tall, so
     the ribbons arrived squeezed into a band with a long fade at each end.
     Bleeding it past the section and pulling the fade back to the edges gives
     it most of the screen instead of a third of it. */
  .settimes-sec .stfx{
    inset: -14% 0; height: 128%; opacity: .78;
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 9%, #000 91%, transparent);
            mask-image: linear-gradient(180deg, transparent, #000 9%, #000 91%, transparent);
  }

  /* One filled button per screen. The sticky bar already carries a full-colour
     Get tickets at the bottom of every phone screen, so a second one mid-page
     is two things shouting the same word — this one steps back to an outline. */
  .morning .btn[data-g26-field="g26_msg_btn"]{
    background: transparent; color: var(--fg);
    border: 1px solid var(--line-2); box-shadow: none;
  }
}


/* ==========================================================================
   Parent-theme armour.  GENERATED — do not hand-edit.

   style-new.css and responsive.css set typography on bare `p`, `h1`, `h2` and
   `h2 span` with !important, which no amount of specificity can outrank. Every
   typographic declaration above is therefore restated here with !important, in
   source order and inside its original media query.

   Nothing new is introduced: change a value above and run
   `python3 tools/build-armour.py` to refresh this block.
   ========================================================================== */
  html, body { color: var(--fg) !important; font-family: var(--body) !important; }
  a { color: inherit !important; }
  button { font: inherit !important; color: inherit !important; }
  .display { font-family: var(--display) !important; font-weight: 600 !important; line-height: .86 !important; letter-spacing: -.035em !important; text-transform: uppercase !important; }
  .eyebrow { font-size: 11px !important; letter-spacing: .22em !important; text-transform: uppercase !important; color: var(--fg-3) !important; font-weight: 500 !important; }
  .lede { font-size: clamp(15px, 1.5vw, 18px) !important; line-height: 1.55 !important; color: var(--fg-2) !important; }
  .btn { font-weight: 700 !important; font-size: 15px !important; letter-spacing: .01em !important; }
  .btn-primary { color: #fff !important; }
  .btn-ghost { color: var(--fg) !important; }
  .btn-lg { font-size: 16px !important; }
  .badge { font-size: 11px !important; font-weight: 700 !important; letter-spacing: .12em !important; text-transform: uppercase !important; }
  .badge-gone { color: var(--gone) !important; }
  .badge-live { color: var(--ok) !important; }
  .badge-urgent { color: var(--urgent) !important; }
  .pay span { font-size: 10px !important; font-weight: 700 !important; letter-spacing: .06em !important; color: var(--fg-3) !important; }
  .pay .mp { color: #fff !important; }
  .muted { color: var(--fg-2) !important; }
  .buybar .price { font-family: var(--display) !important; font-size: 20px !important; font-weight: 600 !important; line-height: 1 !important; }
  .buybar .price small { font-family: var(--body) !important; font-size: 10px !important; letter-spacing: .14em !important; text-transform: uppercase !important; color: var(--fg-3) !important; font-weight: 500 !important; }
  .btn.btn-primary { color: var(--tx-ink) !important; }
  .btn { font-weight: 700 !important; letter-spacing: .02em !important; }
  .btn-mono { font-family: var(--mono) !important; font-size: 13px !important; letter-spacing: .08em !important; text-transform: uppercase !important; }
  .hero .stack { text-align: center !important; }
  .presents { font-family: var(--mono) !important; font-size: clamp(10px, 1.1vw, 12px) !important; font-weight: 700 !important; letter-spacing: .38em !important; text-transform: uppercase !important; color: var(--tx) !important; }
  .shut { font-family: var(--display) !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: -.05em !important; line-height: .82 !important; }
  .gravity-techno .title { font-size: clamp(40px, 8.2vw, 126px) !important; }
  .shim { color: transparent !important; }
  .pitch { font-size: clamp(14px, 1.5vw, 18px) !important; line-height: 1.5 !important; color: rgba(255,255,255,.88) !important; }
  .pitch b { color: #fff !important; font-weight: 500 !important; }
  .metarow li { font-family: var(--mono) !important; font-size: clamp(13.5px, 1.15vw, 16px) !important; font-weight: 700 !important; letter-spacing: .03em !important; text-transform: uppercase !important; color: rgba(255,255,255,.86) !important; }
  .metarow b { color: #fff !important; font-weight: 700 !important; }
  .slot .t { font-family: var(--mono) !important; font-size: 12px !important; font-weight: 700 !important; letter-spacing: .16em !important; color: var(--tx) !important; }
  .slot .n { font-family: var(--display) !important; font-size: clamp(17px, 1.9vw, 22px) !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: -.03em !important; line-height: 1.05 !important; }
  .slot.tba .n { color: var(--fg-3) !important; }
  .slot.head .t, .slot.head .n { color: var(--tx-ink) !important; }
  .heroproof { font-family: var(--mono) !important; font-size: 12px !important; color: var(--tx) !important; letter-spacing: .02em !important; }
  .raveLink { font-family: var(--mono) !important; font-size: 11px !important; letter-spacing: .16em !important; text-transform: uppercase !important; color: var(--fg-2) !important; }
  .raveLink:hover { color: #fff !important; }
  .scroll-hint { font-family: var(--mono) !important; font-size: 9px !important; letter-spacing: .34em !important; text-transform: uppercase !important; color: var(--fg-3) !important; }
  .slug { font-family: var(--mono) !important; font-size: 11px !important; letter-spacing: .24em !important; text-transform: uppercase !important; color: var(--fg-3) !important; }
  .slug b { color: var(--tx) !important; font-weight: 500 !important; }
  h2.head, .head { font-family: var(--display) !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: -.045em !important; line-height: .86 !important; font-size: clamp(32px, 5.8vw, 86px) !important; color: rgba(255,255,255,.92) !important; }
  .head .shout { font-weight: 600 !important; }
  .hero .title { font-size: var(--fit, clamp(44px, 12vw, 178px)) !important; line-height: .84 !important; letter-spacing: -.055em !important; }
  .head em { color: transparent !important; }
@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .head em { color: var(--tx) !important; }
}
  :where(.gravity-techno) h1, :where(.gravity-techno) h2, :where(.gravity-techno) h3, :where(.gravity-techno) h4, :where(.gravity-techno) h5 { text-align: inherit !important; color: inherit !important; text-transform: inherit !important; }
  :where(.gravity-techno) p { text-align: inherit !important; color: inherit !important; text-transform: inherit !important; font-family: inherit !important; font-size: inherit !important; font-weight: inherit !important; line-height: inherit !important; letter-spacing: inherit !important; }
  :where(.gravity-techno) footer p { color: inherit !important; text-align: inherit !important; }
  .sec h2, .bighead { font-family: var(--display) !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: -.045em !important; line-height: .93 !important; font-size: clamp(30px, 5vw, 62px) !important; }
  .kicker { font-family: var(--mono) !important; font-size: 10.5px !important; font-weight: 700 !important; letter-spacing: .26em !important; text-transform: uppercase !important; color: var(--tx) !important; }
  .kicker.mute { color: var(--fg-3) !important; }
  footer { color: var(--fg-3) !important; font-size: 13px !important; }
  footer .mono { font-family: var(--mono) !important; font-size: 11px !important; letter-spacing: .1em !important; text-transform: uppercase !important; }
  .rave .col h3 { font-family: var(--mono) !important; font-size: clamp(11px, .95vw, 13px) !important; font-weight: 700 !important; letter-spacing: .2em !important; text-transform: uppercase !important; }
  .rave .col.no h3 { color: var(--fg-3) !important; }
  .rave .col.yes h3 { color: var(--tx) !important; }
  .rave li { font-size: clamp(15.5px, 1.9vw, 22px) !important; font-weight: 500 !important; line-height: 1.45 !important; }
  .rave li::before { color: var(--fg-3) !important; font-family: var(--mono) !important; }
  .rave .col.no li { color: var(--fg-3) !important; }
  .rave .col.no li b { color: rgba(255,255,255,.5) !important; font-weight: 400 !important; }
  .rave .col.yes li::before { color: var(--tx) !important; }
  .rave .foot { font-family: var(--mono) !important; font-size: clamp(12px, 1.05vw, 14.5px) !important; color: var(--fg-3) !important; letter-spacing: .04em !important; }
  .rave .foot b { color: #fff !important; font-weight: 500 !important; }
  .iflike .wrap { text-align: center !important; }
  .belt span { font-family: var(--display) !important; font-size: clamp(24px, 3.4vw, 46px) !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: -.03em !important; color: var(--fg-2) !important; }
  .belt span.solid { color: var(--tx-ink) !important; }
  .b-nights .belt span { font-family: var(--mono) !important; font-size: clamp(12px, 1.5vw, 17px) !important; font-weight: 700 !important; letter-spacing: .14em !important; }
  .iflike .tail { font-size: clamp(16px, 2vw, 22px) !important; color: var(--fg-2) !important; }
  .iflike .tail b { color: #fff !important; font-weight: 500 !important; }
  .vswitch button { font-family: var(--mono) !important; font-size: 11px !important; font-weight: 700 !important; letter-spacing: .13em !important; text-transform: uppercase !important; color: var(--fg-3) !important; }
  .vswitch button:hover { color: #fff !important; }
  .vswitch button.on { color: var(--tx-ink) !important; }
  .facts dt { font-family: var(--mono) !important; font-size: 10px !important; font-weight: 700 !important; letter-spacing: .2em !important; text-transform: uppercase !important; color: var(--fg-3) !important; }
  .facts dd { font-family: var(--display) !important; font-size: clamp(19px, 2vw, 25px) !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: -.025em !important; line-height: 1.04 !important; }
  .facts dd small { font-family: var(--mono) !important; font-size: 10.5px !important; font-weight: 400 !important; letter-spacing: .06em !important; text-transform: none !important; color: var(--fg-3) !important; line-height: 1.4 !important; }
  .stages span { font-family: var(--mono) !important; font-size: 11.5px !important; font-weight: 700 !important; letter-spacing: .1em !important; text-transform: uppercase !important; color: var(--fg-2) !important; }
  .stages span.hi { color: var(--tx) !important; }
  .struck span { font-family: var(--display) !important; font-size: clamp(24px, 3.8vw, 52px) !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: -.04em !important; color: rgba(255,255,255,.19) !important; line-height: 1 !important; }
  .verdict { font-family: var(--display) !important; font-size: clamp(26px, 4vw, 54px) !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: -.04em !important; line-height: .98 !important; }
  .verdict em { color: var(--tx) !important; }
  .bpm-head { font-family: var(--mono) !important; font-size: 11px !important; letter-spacing: .14em !important; text-transform: uppercase !important; color: var(--fg-3) !important; }
  .bpm-head b { color: var(--tx) !important; font-weight: 700 !important; }
  .bpm .axis { font-family: var(--mono) !important; font-size: 10.5px !important; letter-spacing: .08em !important; color: var(--fg-3) !important; }
  .id-row { font-family: var(--mono) !important; font-size: 12.5px !important; }
  .id-row .no { color: var(--tx) !important; font-weight: 700 !important; letter-spacing: .1em !important; }
  .id-row .tr { font-family: var(--display) !important; font-size: clamp(16px, 1.8vw, 21px) !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: -.02em !important; }
  .id-row .yr { color: var(--fg-3) !important; letter-spacing: .08em !important; }
  .vol h2 { font-size: clamp(52px, 13vw, 190px) !important; }
  .specs .k { font-family: var(--mono) !important; font-size: 10px !important; font-weight: 700 !important; letter-spacing: .22em !important; text-transform: uppercase !important; color: var(--tx) !important; }
  .specs .v { font-size: 14.5px !important; line-height: 1.45 !important; color: var(--fg-2) !important; }
  .morning .head { text-align: center !important; }
  .story .who { font-family: var(--mono) !important; font-size: 11.5px !important; font-weight: 700 !important; }
  .story .when { font-family: var(--mono) !important; font-size: 10.5px !important; color: var(--fg-3) !important; }
  .story p { font-size: 13.5px !important; line-height: 1.45 !important; color: rgba(255,255,255,.9) !important; }
  .story .re { font-family: var(--mono) !important; font-size: 9.5px !important; letter-spacing: .06em !important; color: var(--fg-3) !important; text-transform: uppercase !important; }
  .story .re b { color: var(--tx) !important; font-weight: 700 !important; }
  .led-row { font-family: var(--mono) !important; font-size: 12px !important; }
  .led-row .no { color: var(--fg-3) !important; letter-spacing: .14em !important; font-weight: 700 !important; }
  .led-row .nm { font-family: var(--display) !important; font-size: clamp(18px, 2.2vw, 26px) !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: -.03em !important; }
  .led-row .ppl { color: var(--fg-3) !important; letter-spacing: .06em !important; }
  .led-row .st { letter-spacing: .12em !important; text-transform: uppercase !important; font-weight: 700 !important; color: var(--fg-3) !important; }
  .led-row.gone .nm, .led-row.gone .ppl { color: var(--fg-3) !important; }
  .led-row.now .no, .led-row.now .st { color: var(--tx) !important; }
  .led-row.now .nm { color: #fff !important; }
  .act .nm { font-family: var(--display) !important; font-size: clamp(20px, 3.6vw, 46px) !important; font-weight: 500 !important; color: var(--fg-2) !important; text-transform: uppercase !important; letter-spacing: -.04em !important; line-height: .95 !important; }
  .act.head .nm { font-size: clamp(46px, 6vw, 76px) !important; color: #fff !important; }
  .act .cc, .act .role { font-family: var(--mono) !important; font-size: 10.5px !important; font-weight: 700 !important; letter-spacing: .18em !important; text-transform: uppercase !important; }
  .act .cc { color: var(--fg-3) !important; }
  .act .role { color: var(--tx) !important; }
  .act.tba .nm { font-size: clamp(18px, 2.2vw, 26px) !important; color: var(--fg-2) !important; }
  .act.tba .role { color: var(--fg-3) !important; }
  .rel-row { font-family: var(--mono) !important; font-size: 12px !important; }
  .rel-row .nm { font-family: var(--display) !important; font-size: clamp(17px, 2vw, 23px) !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: -.03em !important; }
  .rel-row .st { color: var(--fg-3) !important; letter-spacing: .08em !important; text-transform: uppercase !important; }
  .rel-row .pr { font-size: 15px !important; font-weight: 700 !important; letter-spacing: .04em !important; text-align: right !important; }
  .rel-row.now .st, .rel-row.now .pr { color: var(--tx) !important; }
  .rel-row.next .pr, .rel-row.later .pr { color: var(--fg-2) !important; }
  body.show-notes .relnote { font-family: var(--mono) !important; font-size: 12px !important; color: var(--fg-3) !important; letter-spacing: .03em !important; }
  .relnote b { color: var(--tx) !important; font-weight: 700 !important; }
  .gal-ghost .ghostword { font-family: var(--display) !important; font-weight: 600 !important; font-size: clamp(70px, 17vw, 260px) !important; letter-spacing: -.05em !important; line-height: 1 !important; text-transform: uppercase !important; }
  .gal-ghost .ghostword > span { color: transparent !important; }
  .strip .tag { font-family: var(--mono) !important; font-size: 10px !important; letter-spacing: .22em !important; text-transform: uppercase !important; color: rgba(255,255,255,.62) !important; }
  .strip figcaption b { font-family: var(--display) !important; font-size: clamp(17px, 1.8vw, 24px) !important; font-weight: 600 !important; text-transform: uppercase !important; letter-spacing: -.01em !important; }
  .strip figcaption span { font-family: var(--mono) !important; font-size: 11px !important; letter-spacing: .16em !important; text-transform: uppercase !important; color: var(--fg-2) !important; }
  .strip figcaption i { color: var(--tx) !important; font-weight: 700 !important; }
  .ticket .release { font-family: var(--mono) !important; font-size: 11px !important; letter-spacing: .14em !important; text-transform: uppercase !important; }
  .ticket .live { color: var(--tx) !important; font-weight: 700 !important; }
  .ticket .out { color: var(--fg-3) !important; }
  .tname { font-size: clamp(30px, 5vw, 62px) !important; }
  .tfacts dt { font-family: var(--mono) !important; font-size: 9.5px !important; font-weight: 700 !important; letter-spacing: .2em !important; text-transform: uppercase !important; color: var(--fg-3) !important; }
  .tfacts dd { font-family: var(--mono) !important; font-size: 13px !important; font-weight: 500 !important; }
  .ticket .when { font-family: var(--mono) !important; font-size: 10.5px !important; font-weight: 700 !important; letter-spacing: .16em !important; text-transform: uppercase !important; color: var(--fg-3) !important; }
  .ticket .amount { font-family: var(--display) !important; font-size: clamp(40px, 6vw, 66px) !important; font-weight: 600 !important; line-height: 1 !important; letter-spacing: -.04em !important; }
  .ticket .later { font-family: var(--mono) !important; font-size: 11px !important; color: var(--fg-3) !important; letter-spacing: .04em !important; }
  .ticket .rise { font-family: var(--mono) !important; font-size: 10.5px !important; font-weight: 700 !important; letter-spacing: .1em !important; text-transform: uppercase !important; color: var(--tx) !important; }
  .ticket .paynote { font-family: var(--mono) !important; font-size: 10px !important; letter-spacing: .08em !important; text-transform: uppercase !important; color: var(--fg-3) !important; text-align: center !important; }
  .faq summary { font-size: clamp(14.5px, 1.5vw, 17px) !important; font-weight: 500 !important; }
  .faq summary::after { font-family: var(--mono) !important; color: var(--tx) !important; font-size: 18px !important; }
  .faq p { color: var(--fg-2) !important; font-size: 14.5px !important; line-height: 1.55 !important; }
  .faq p b { color: #fff !important; font-weight: 500 !important; }
  .close { text-align: center !important; }
  .close h2 { font-size: clamp(38px, 8vw, 104px) !important; }
  .details .cell { text-align: center !important; }
  .details .k { font-family: var(--mono) !important; font-size: 9.5px !important; font-weight: 700 !important; letter-spacing: .22em !important; text-transform: uppercase !important; color: var(--fg-3) !important; }
  .details .v { font-family: var(--display) !important; font-size: clamp(17px, 2vw, 23px) !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: -.025em !important; line-height: 1.05 !important; }
  .details .v small { font-family: var(--mono) !important; font-size: 10.5px !important; font-weight: 400 !important; letter-spacing: .08em !important; text-transform: none !important; color: var(--fg-3) !important; }
  .details .live { font-family: var(--mono) !important; font-size: 11.5px !important; font-weight: 700 !important; letter-spacing: .14em !important; text-transform: uppercase !important; color: var(--tx-ink) !important; }
  .chap .c { font-family: var(--mono) !important; font-size: 9.5px !important; font-weight: 700 !important; letter-spacing: .2em !important; text-transform: uppercase !important; color: var(--fg-3) !important; }
  .chap .c.live { color: var(--tx) !important; }
  .chap b { font-family: var(--display) !important; font-size: clamp(19px, 2.2vw, 26px) !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: -.03em !important; line-height: 1 !important; }
  .chap span { font-family: var(--mono) !important; font-size: 10.5px !important; letter-spacing: .08em !important; color: var(--fg-3) !important; }
  .voice .nm { font-family: var(--display) !important; font-size: clamp(17px, 1.9vw, 21px) !important; font-weight: 500 !important; text-transform: uppercase !important; letter-spacing: -.03em !important; }
  .voice .meta { font-family: var(--mono) !important; font-size: 9.5px !important; letter-spacing: .12em !important; text-transform: uppercase !important; color: var(--tx) !important; }
  .voice blockquote { font-size: 14.5px !important; line-height: 1.45 !important; color: var(--fg-2) !important; }
  .voice blockquote em { color: #fff !important; }
  .bbar .price { font-family: var(--display) !important; font-size: 24px !important; font-weight: 600 !important; line-height: 1 !important; }
  .bbar .price b i { font-family: var(--mono) !important; font-weight: 500 !important; font-size: .46em !important; letter-spacing: .1em !important; text-transform: uppercase !important; color: var(--fg-3) !important; }
  .bbar .price small { font-family: var(--mono) !important; font-size: 9px !important; letter-spacing: .18em !important; text-transform: uppercase !important; color: var(--tx) !important; font-weight: 700 !important; }
  .bbar .rel { font-family: var(--mono) !important; font-size: 11px !important; letter-spacing: .08em !important; text-transform: uppercase !important; }
  .bbar .rel .live { color: var(--tx) !important; font-weight: 700 !important; }
  .bbar .rel .up { color: var(--fg-3) !important; }
@media (max-width: 900px) {
  .note-tag { line-height: 1.35 !important; }
  .rel-row .nm { font-size: 22px !important; }
  .rel-row .pr { font-size: 22px !important; text-align: right !important; }
  .rel-row .st { font-size: 10px !important; }
  .bbar .price small { font-size: 11px !important; letter-spacing: .18em !important; }
  .bbar .price b { font-size: 29px !important; line-height: 1 !important; }
  .bbar .rel { font-size: 14px !important; letter-spacing: 0 !important; text-transform: none !important; }
  .bbar .rel .live::after { color: var(--fg-3) !important; }
  .act.head .nm { line-height: .94 !important; }
}
@media (max-width: 420px) {
  .btn { text-align: center !important; }
  .bbar .rel { font-size: 13px !important; }
}
@media (max-width: 640px) {
  h2.head, .head { font-size: clamp(38px, 10.5vw, 54px) !important; }
  .heroctas .btn-lg { font-size: 14px !important; }
  .heroctas .btn-mono { font-size: 11px !important; letter-spacing: .05em !important; }
  .morning .btn[data-g26-field="g26_msg_btn"] { color: var(--fg) !important; }
}
