/* Disco Tekk — built from the two event flyers.
   Flyer A: dead-black field, electric yellow neon headline, coloured lasers raking down
   from a mirrorball, DJ names scattered at loose angles, "Featuring:" tucked bottom right.
   Flyer B: the same night scrawled in marker over a photo — fat violet and periwinkle
   strokes, hand-drawn OCT 3rd. The page runs A as the room and B as the handwriting. */

body.event-theme-disco {
  --dt-black: #050406;
  --dt-yellow: #f7e017;        /* headline neon from flyer A */
  --dt-yellow-dim: #8a7c0a;
  --dt-violet: #7c6ce0;        /* the fat TEKK marker from flyer B */
  --dt-peri: #9db4ff;          /* the ISCO outline from flyer B */
  --dt-magenta: #ff3ea5;
  --dt-green: #39ff88;
  --dt-paper: #f4f1e8;
  background: var(--dt-black);
  color: var(--dt-paper);
}
body.event-theme-disco .archive-header { position: sticky; top: 0; z-index: 40; background: rgba(5,4,6,.74); backdrop-filter: blur(14px); border-bottom: 1px solid rgba(247,224,23,.16); }
body.event-theme-disco main { position: relative; z-index: 1; }
body.event-theme-disco footer.site-footer, body.event-theme-disco .site-footer { position: relative; z-index: 1; background: rgba(5,4,6,.92); }
/* Content sits above the room. The room is the one child that must stay fixed, so it is
   excluded here — otherwise this rule overrides its position and it takes space in flow. */
body.event-theme-disco > main > *:not(.dt-room) { position: relative; z-index: 1; }

/* The room: lasers + mirrorball, painted on canvas behind everything. */
.dt-room { position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.dt-room canvas { width: 100%; height: 100%; }
.dt-grain { position: absolute; inset: 0; opacity: .5; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E"); }

/* ---------- Hero: the flyer, rebuilt as a page ---------- */
.dt-hero { position: relative; max-width: 1180px; margin: 0 auto; padding: clamp(30px, 7vw, 80px) clamp(18px, 5vw, 60px) clamp(20px, 4vw, 48px); text-align: center; }

.dt-ball-hang { display: grid; justify-items: center; gap: 0; margin-bottom: clamp(14px, 2.5vw, 26px); }
.dt-ball-cord { width: 2px; height: clamp(26px, 5vw, 58px); background: linear-gradient(rgba(244,241,232,0), rgba(244,241,232,.5)); }
/* The mirrorball is Kiel's own spinning ball, dropped in as an animated WebP — a CSS
   sphere can't project facets around a curve, so every flat-gradient attempt read as a
   turning disc rather than a ball. The glow stays in CSS so it can react to the theme. */
/* The glow is a drop-shadow, not a box-shadow: box-shadow paints the element's own
   circle, which showed as a hard disc sitting behind the ball's soft edge. */
.dt-ball { position: relative; width: clamp(118px, 17vw, 200px); aspect-ratio: 1;
  background: url("images/disco-mirrorball.webp") center / contain no-repeat;
  filter: drop-shadow(0 0 20px rgba(247,224,23,.3)) drop-shadow(0 0 46px rgba(124,108,224,.26)); }

/* DISCO TEKK — wide squarish techno face with the flyer's yellow bloom. */
.dt-title { margin: 0; line-height: .92; }
.dt-title span { display: block; font-family: Orbitron, 'Chakra Petch', sans-serif; font-weight: 900;
  font-size: clamp(42px, 12.5vw, 154px); letter-spacing: -.005em; text-transform: uppercase; color: #fffbe2;
  text-shadow: 0 0 6px #fff8c0, 0 0 18px var(--dt-yellow), 0 0 44px rgba(247,224,23,.85), 0 0 92px rgba(247,224,23,.5), 0 0 150px rgba(255,62,165,.28);
  animation: dt-flicker 7s steps(1) infinite; }
@keyframes dt-flicker { 0%,91% { opacity: 1; } 92% { opacity: .42; } 93% { opacity: 1; } 96% { opacity: .62; } 97%,100% { opacity: 1; } }

/* The flyer's detail block: two columns, mono, yellow. */
.dt-vitals { display: grid; grid-template-columns: repeat(2, auto); justify-content: center; gap: 4px clamp(20px, 5vw, 62px);
  margin: clamp(16px, 3vw, 30px) auto 0; padding: 0; }
.dt-vitals div { display: contents; }
.dt-vitals dt { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.dt-vitals dd { margin: 0; color: var(--dt-yellow); font: 600 clamp(14px, 2.2vw, 25px) 'Chakra Petch', sans-serif; letter-spacing: .01em;
  text-shadow: 0 0 12px rgba(247,224,23,.6), 0 0 34px rgba(247,224,23,.3); }
.dt-vitals dd.dt-vitals-wide { grid-column: 1 / -1; }
.dt-vitals dd.dt-vitals-door { color: rgba(244,241,232,.6); font-size: clamp(12px, 1.5vw, 16px); font-weight: 500; text-shadow: none; }
.dt-vitals dd small { color: rgba(244,241,232,.55); font-size: .72em; font-weight: 500; }

.dt-lede { max-width: 620px; margin: clamp(20px, 3.5vw, 34px) auto 0; color: rgba(244,241,232,.76);
  font: 400 clamp(14px, 1.5vw, 17px)/1.75 'Chakra Petch', sans-serif; }

.dt-cta-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 14px; margin-top: clamp(22px, 4vw, 38px); }
.dt-jump { display: inline-flex; align-items: center; gap: 12px; padding: 15px 28px; border: 2px solid var(--dt-yellow); border-radius: 999px;
  color: var(--dt-yellow); font: 700 12px 'Share Tech Mono', monospace; letter-spacing: .2em; text-decoration: none; text-transform: uppercase;
  box-shadow: 0 0 22px rgba(247,224,23,.25), inset 0 0 22px rgba(247,224,23,.08); transition: background .2s, color .2s, box-shadow .2s; }
.dt-jump:hover { background: var(--dt-yellow); color: var(--dt-black); box-shadow: 0 0 46px rgba(247,224,23,.6); }
.dt-jump span { animation: dt-bob 1.6s ease-in-out infinite; }
@keyframes dt-bob { 50% { transform: translateY(4px); } }

/* ---------- Marker scrawl (flyer B) ---------- */
.dt-scrawl { font-family: 'Permanent Marker', cursive; font-weight: 400; }
/* Vertical text wraps into extra columns when it runs out of height, which reads as
   gibberish — nowrap keeps it a single stacked column the way the marker drew it. */
.dt-scrawl-oct { position: absolute; left: clamp(6px, 3vw, 46px); top: 30%; z-index: 2; color: var(--dt-violet);
  white-space: nowrap;
  font: 400 clamp(22px, 3.6vw, 44px)/.9 'Permanent Marker', cursive; writing-mode: vertical-lr; text-orientation: upright;
  letter-spacing: -.06em; opacity: .92; text-shadow: 0 0 18px rgba(124,108,224,.55); pointer-events: none; transform: rotate(-3deg); }
.dt-scrawl-tekk { position: absolute; right: clamp(2px, 2vw, 34px); top: 8%; z-index: 2; color: rgba(124,108,224,.85);
  font: 400 clamp(42px, 7.5vw, 110px)/.82 'Permanent Marker', cursive; writing-mode: vertical-rl;
  letter-spacing: .02em; text-shadow: 0 0 26px rgba(124,108,224,.5); pointer-events: none; transform: rotate(2deg); }
@media (max-width: 860px) { .dt-scrawl-oct, .dt-scrawl-tekk { display: none; } }

/* ---------- Marquee ---------- */
.dt-marquee { overflow: hidden; margin: clamp(18px, 4vw, 38px) 0; padding: 11px 0;
  border-top: 1px solid rgba(247,224,23,.28); border-bottom: 1px solid rgba(247,224,23,.28); background: rgba(247,224,23,.045); }
.dt-marquee > div { display: flex; width: max-content; animation: dt-marquee 30s linear infinite; }
.dt-marquee span { padding-right: 46px; color: var(--dt-yellow); font: 700 clamp(15px, 2vw, 24px) Orbitron, sans-serif;
  letter-spacing: .06em; white-space: nowrap; text-shadow: 0 0 16px rgba(247,224,23,.5); }
@keyframes dt-marquee { to { transform: translateX(-50%); } }

.dt-note { max-width: 760px; margin: 0 auto; padding: 0 clamp(18px, 5vw, 60px); }
.dt-note p { margin: 0; color: rgba(244,241,232,.82); font: 400 clamp(15px, 1.6vw, 18px)/1.8 'Chakra Petch', sans-serif; }

/* ---------- The flyers themselves, pinned up like paper ---------- */
.dt-flyers { max-width: 1080px; margin: clamp(38px, 6.5vw, 86px) auto; padding: 0 clamp(18px, 5vw, 60px); }
.dt-flyer-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: clamp(22px, 4vw, 52px); align-items: start; justify-items: center; }
.dt-flyer { width: min(100%, 400px); margin: 0; }
/* A touch off-square, the way a flyer actually gets stuck to a wall. Odd/even rather than
   counted, so adding a flyer keeps the alternating tilt instead of hanging straight. */
.dt-flyer:nth-child(odd) { rotate: -1.6deg; }
.dt-flyer:nth-child(even) { rotate: 1.6deg; }
/* A flyer is a clip or a still, and both hang on the wall the same way. */
.dt-flyer video, .dt-flyer img { display: block; width: 100%; height: auto; border: 1px solid rgba(247,224,23,.32); border-radius: 6px;
  background: #000; box-shadow: 0 30px 70px rgba(0,0,0,.7), 0 0 54px rgba(247,224,23,.12); }
.dt-flyer { transition: rotate .35s cubic-bezier(.16,1,.3,1), transform .35s cubic-bezier(.16,1,.3,1); }
.dt-flyer:hover { rotate: 0deg; transform: translateY(-5px); }

/* ---------- Lineup: names thrown across the floor, straight off flyer A ---------- */
.dt-lineup { position: relative; max-width: 1080px; margin: clamp(40px, 7vw, 92px) auto; padding: 0 clamp(18px, 5vw, 60px); }
.dt-lineup-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px 20px; margin-bottom: 10px; }
.dt-section-label { margin: 0; color: var(--dt-peri); font: 400 11px 'Share Tech Mono', monospace; letter-spacing: .3em; text-transform: uppercase; }
.dt-lineup h2, .dt-flyers h2 { margin: 0; font: 900 clamp(26px, 4.2vw, 50px) Orbitron, sans-serif; text-transform: uppercase; color: var(--dt-paper);
  text-shadow: 0 0 20px rgba(247,224,23,.35); }

/* The scatter field. Each name gets its own angle and offset, set inline per artist. */
.dt-scatter { position: relative; display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  /* Row-gap must stay above the names' combined --dy swing (42px) so offset names on
     neighbouring rows can't collide; column-gap keeps the longer names apart. */
  gap: clamp(52px, 6vw, 78px) clamp(34px, 7vw, 104px); min-height: clamp(230px, 34vw, 340px);
  margin: 0; padding: clamp(24px, 4vw, 44px) clamp(10px, 3vw, 30px); list-style: none;
  border: 1px solid rgba(247,224,23,.14); border-radius: 18px; background: rgba(247,224,23,.022); }
.dt-name { transform: rotate(var(--rot)) translateY(var(--dy)); animation: dt-name-in .7s cubic-bezier(.16,1,.3,1) both; animation-delay: calc(var(--i) * 90ms); }
@keyframes dt-name-in { from { opacity: 0; transform: rotate(var(--rot)) translateY(calc(var(--dy) + 26px)) scale(.9); } }
.dt-name a, .dt-name > span { display: inline-block; color: var(--dt-yellow); text-decoration: none;
  font: 600 var(--size, 26px) 'Chakra Petch', sans-serif; letter-spacing: .01em;
  text-shadow: 0 0 10px rgba(247,224,23,.65), 0 0 30px rgba(247,224,23,.35);
  transition: color .2s, text-shadow .2s, transform .2s; }
.dt-name a:hover, .dt-name a:focus-visible { color: #fffbe2; text-shadow: 0 0 14px #fff8c0, 0 0 40px var(--dt-yellow), 0 0 80px rgba(247,224,23,.6); transform: scale(1.06); }
.dt-name small { display: block; margin-top: 2px; color: rgba(157,180,255,.75); font: 400 11px 'Share Tech Mono', monospace; letter-spacing: .14em; text-shadow: none; }
/* Always-visible outbound mark: a phone has no hover state to discover the link with. */
.dt-name a b { display: inline-block; margin-left: .28em; font-size: .52em; font-weight: 400; vertical-align: .5em;
  color: var(--dt-peri); text-shadow: 0 0 10px rgba(157,180,255,.5); transition: transform .2s; }
.dt-name a:hover b, .dt-name a:focus-visible b { transform: translate(2px, -2px); }
.dt-lineup-hint { margin: 0 0 16px; color: rgba(244,241,232,.55); font: 400 12px 'Share Tech Mono', monospace; letter-spacing: .1em; }
.dt-lineup-hint b { color: var(--dt-peri); font-weight: 400; }

/* ---------- Booth ---------- */
.dt-booth { display: grid; grid-template-columns: minmax(200px, .62fr) minmax(0, 1.38fr); align-items: center;
  gap: clamp(26px, 5vw, 64px); max-width: 1080px; margin: clamp(40px, 8vw, 104px) auto; padding: clamp(24px, 4vw, 46px);
  border: 1px solid rgba(247,224,23,.26); border-radius: 22px;
  background: linear-gradient(160deg, rgba(20,17,30,.92), rgba(6,5,9,.95));
  box-shadow: 0 50px 120px rgba(0,0,0,.65), inset 0 1px 0 rgba(255,255,255,.05); }
/* The console is roughly twice the ball's height, so centring the ball left a dead half
   of the panel. It now hangs from a cord off the top of the booth, the way it does in the
   hero — the space above it reads as the room instead of as a gap. */
.dt-booth-ball { align-self: stretch; display: grid; grid-template-rows: 1fr auto 1fr; justify-items: center; }
.dt-booth-ball::before { content: ""; width: 2px; align-self: stretch;
  background: linear-gradient(rgba(244,241,232,0), rgba(244,241,232,.5)); }
.dt-booth-ball .dt-ball { width: min(100%, 300px); }

.dt-console { display: grid; gap: 15px; }
.dt-readout { display: flex; align-items: baseline; gap: 12px; padding: 12px 16px; border-radius: 10px; background: #0a0a05;
  box-shadow: inset 0 0 0 1px rgba(247,224,23,.22), inset 0 8px 20px rgba(0,0,0,.6); }
.dt-readout small, .dt-total small { color: rgba(247,224,23,.6); font: 400 10px 'Share Tech Mono', monospace; letter-spacing: .2em; text-transform: uppercase; }
.dt-door { margin: -6px 0 0; color: rgba(244,241,232,.6); font: 400 11px 'Share Tech Mono', monospace; letter-spacing: .12em; text-transform: uppercase; }
.dt-readout strong { margin-left: auto; color: var(--dt-yellow); font: 400 clamp(26px, 3vw, 38px) 'Share Tech Mono', monospace; text-shadow: 0 0 16px rgba(247,224,23,.55); }
.dt-total { display: flex; align-items: baseline; gap: 12px; padding: 10px 16px; border-radius: 10px; background: rgba(247,224,23,.09); }
.dt-total[hidden] { display: none; }
.dt-total strong { margin-left: auto; color: var(--dt-yellow); font: 400 26px 'Share Tech Mono', monospace; }
.dt-level label { display: block; margin-bottom: 8px; color: rgba(244,241,232,.55); font: 400 10px 'Share Tech Mono', monospace; letter-spacing: .24em; text-transform: uppercase; }
.dt-level-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.dt-step-button { display: grid; width: 44px; height: 44px; place-items: center; border: 1px solid rgba(247,224,23,.35); border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #2b2736, #100e18); color: var(--dt-yellow); cursor: pointer;
  font: 700 20px 'Chakra Petch', sans-serif; box-shadow: 0 5px 12px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.12); transition: transform .15s, box-shadow .2s; }
.dt-step-button:hover { box-shadow: 0 0 22px rgba(247,224,23,.4); }
.dt-step-button:active { transform: scale(.92); }
.dt-level-row select { min-height: 44px; padding: 0 12px; border: 1px solid rgba(247,224,23,.35); border-radius: 10px; background: #100e18; color: var(--dt-paper); font: 600 16px 'Chakra Petch', sans-serif; }
.dt-meter { display: flex; gap: 5px; margin-left: auto; }
.dt-meter i { width: 8px; height: 30px; border-radius: 2px; background: rgba(255,255,255,.1); transition: background .2s, box-shadow .2s; }
.dt-meter i.is-lit { background: linear-gradient(180deg, var(--dt-yellow), var(--dt-magenta)); box-shadow: 0 0 12px rgba(247,224,23,.6); }

.dt-buy { position: relative; display: flex; align-items: center; justify-content: center; gap: 14px; min-height: 68px; padding: 0 26px;
  overflow: hidden; border: 0; border-radius: 999px; background: linear-gradient(120deg, var(--dt-yellow), #ffd34d 46%, var(--dt-magenta));
  color: #17140a; cursor: pointer; font: 700 15px 'Chakra Petch', sans-serif; letter-spacing: .08em; text-transform: uppercase;
  box-shadow: 0 16px 44px rgba(247,224,23,.28); transition: transform .2s, box-shadow .2s; }
.dt-buy:hover:not(:disabled) { transform: translateY(-3px); box-shadow: 0 22px 64px rgba(247,224,23,.5); }
.dt-buy:active:not(:disabled) { transform: translateY(1px); }
.dt-buy:disabled { background: rgba(255,255,255,.1); color: rgba(244,241,232,.65); cursor: not-allowed; box-shadow: none; }
.dt-buy-ring { position: absolute; inset: 0; border-radius: inherit; box-shadow: 0 0 0 0 rgba(247,224,23,.5); animation: dt-ring 2.2s cubic-bezier(0,0,.2,1) infinite; }
.dt-buy:disabled .dt-buy-ring { animation: none; }
@keyframes dt-ring { to { box-shadow: 0 0 0 26px rgba(247,224,23,0); } }
.dt-buy-arrow { font-size: 20px; transition: transform .2s; }
.dt-buy:hover:not(:disabled) .dt-buy-arrow { transform: translateX(5px); }
.dt-booth-note { margin: 0; color: rgba(244,241,232,.6); font: 400 13px/1.6 'Chakra Petch', sans-serif; }
.dt-checkout-message { min-height: 20px; margin: 0; color: var(--dt-yellow); font: 400 13px 'Share Tech Mono', monospace; }

/* Checkout opens: the room goes white, like the lasers all hit at once. */
body.dt-dropping::after { content: ""; position: fixed; inset: 0; z-index: 90; pointer-events: none;
  background: radial-gradient(circle at 50% 45%, rgba(255,255,255,.88), rgba(247,224,23,.55) 34%, transparent 72%);
  animation: dt-drop 2.4s cubic-bezier(.2,.8,.2,1) forwards; }
@keyframes dt-drop { 0% { opacity: 0; transform: scale(.2); } 25% { opacity: .9; } 100% { opacity: 0; transform: scale(2.4); } }

.dt-footer { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px 24px; max-width: 1080px; margin: 0 auto;
  padding: 26px clamp(18px, 5vw, 60px) 60px; border-top: 1px solid rgba(247,224,23,.2); color: rgba(244,241,232,.5);
  font: 400 11px 'Share Tech Mono', monospace; letter-spacing: .2em; text-transform: uppercase; }

@media (max-width: 900px) {
  .dt-booth { grid-template-columns: 1fr; }
  .dt-booth-ball .dt-ball { width: min(62%, 180px); }
  .dt-meter { width: 100%; margin-left: 0; }
  .dt-meter i { flex: 1; }
}

/* ---------- Phone ---------- */
@media (max-width: 620px) {
  /* The hero reads as the flyer does: everything stacked and centred, nothing cropped. */
  .dt-hero { padding-top: 26px; }
  .dt-title span { font-size: clamp(38px, 13.5vw, 62px); }

  /* Keep the flyer's paired rows — date/time, price/age — rather than stacking all five,
     which reads longer and loses the pairing. They still fit at this size. */
  .dt-vitals { gap: 6px 18px; }
  .dt-vitals dd { font-size: clamp(15px, 4.4vw, 19px); }
  .dt-vitals dd small { display: block; margin-top: 2px; }

  .dt-lede { font-size: 15px; line-height: 1.65; }
  .dt-jump { width: 100%; justify-content: center; }

  /* Heading stacks above the scatter instead of colliding with the label. */
  .dt-lineup, .dt-flyers { padding-inline: 18px; }
  .dt-lineup-head { display: block; margin-bottom: 14px; }
  .dt-lineup h2, .dt-flyers h2 { margin-top: 4px; font-size: clamp(24px, 7.4vw, 34px); }

  /* The thrown-name field needs room to breathe or the names collide. Angles shrink,
     the vertical offsets go, and each name gets its own line at a readable size. */
  .dt-scatter { display: grid; grid-template-columns: 1fr 1fr; justify-items: center; align-items: center;
    gap: 18px 10px; min-height: 0; padding: 26px 14px; }
  .dt-name { --dy: 0px; transform: rotate(calc(var(--rot) * .55)); }
  .dt-name a, .dt-name > span { font-size: clamp(17px, 5vw, 23px); }
  /* The headliner keeps its edge on a phone too, on its own full-width row. */
  .dt-headline { grid-column: 1 / -1; }
  .dt-headline a, .dt-headline > span { font-size: clamp(26px, 8.4vw, 38px); }
  /* Pad the link itself so the tap area clears 44px without moving the name. */
  .dt-name a { padding: 9px 6px; }
  @keyframes dt-name-in { from { opacity: 0; transform: rotate(calc(var(--rot) * .55)) translateY(18px) scale(.94); } }

  /* The booth lost its padding on small screens because the grid filled the viewport;
     keep a real gutter so nothing sits against the edge. */
  .dt-booth { margin-inline: 14px; padding: 22px 18px; border-radius: 18px; gap: 22px; }
  .dt-booth-ball .dt-ball { width: min(52%, 140px); }
  .dt-readout strong { font-size: 28px; }
  .dt-buy { min-height: 60px; font-size: 14px; }
  .dt-footer { padding-inline: 18px; gap: 8px 16px; font-size: 10px; }
}
@media (prefers-reduced-motion: reduce) {
  body.event-theme-disco *, body.event-theme-disco *::before, body.event-theme-disco *::after { animation: none !important; transition: none !important; }
}
