/* Power Festival — one-pager styles
   Brand: purple #6707BA · yellow #FECC18 · ink #1A0530
   Responsive breakpoints: mobile <768, tablet 768–1024, desktop >1024 */

:root {
  --c-purple:       #6707BA;
  --c-purple-deep:  #4B0789;
  --c-purple-light: #8B3DD4;
  --c-yellow:       #FECC18;
  --c-yellow-deep:  #F0B800;
  --c-bg:           #0B0518;
  --c-bg-alt:       #15082B;
  --c-card:         #1D0E3A;
  --c-border:       rgba(254, 204, 24, 0.18);
  --c-text:         #FBFAF5;
  --c-text-mute:    rgba(251, 250, 245, 0.65);
  --c-text-dim:     rgba(251, 250, 245, 0.45);

  --f-sans:    'Inter Tight', system-ui, -apple-system, sans-serif;
  --f-display: 'Poppins', 'Inter Tight', system-ui, sans-serif;
  --f-serif:   'Poppins', 'Inter Tight', system-ui, sans-serif;
  --f-mono:    'JetBrains Mono', ui-monospace, monospace;

  --nav-h: 72px;
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Brand yellow on the html element so iOS Safari's bottom rubber-band
     overscroll reveals the cloud-graphic colour instead of dark ink —
     the cloud at the footer flows visually into the overscroll instead
     of stopping at a hard edge. body keeps the dark ink background so
     the page surface itself is unaffected. Top rubber-band can also
     briefly flash yellow, but the sticky nav usually covers that.
     The Safari address-bar colour is independent — controlled by the
     <meta name="theme-color"> tag, which stays dark. */
  background: var(--c-yellow);
}

html, body {
  margin: 0; padding: 0;
}

body {
  font-family: var(--f-sans);
  color: var(--c-text);
  background: var(--c-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Slight global bump on the space between words. The site's display
     typography (Poppins, often italic) renders the default space glyph a
     little tight, which makes phrases like "Power Festival medialle." read
     as crowded. 0.04em is small enough to be invisible at body sizes but
     adds breathing room on the large headlines. */
  word-spacing: 0.04em;
}

img, video { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; }

section { scroll-margin-top: var(--nav-h); }

/* ─── Layout helpers ───────────────────────── */

.pf-container {
  max-width: 1320px;
  margin: 0 auto;
  padding-inline: 40px;
}

.pf-eyebrow {
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--c-yellow);
  text-transform: uppercase;
}

.pf-h2 {
  font-family: var(--f-display);
  font-weight: 800;
  font-size: 64px;
  letter-spacing: -2px;
  line-height: 0.95;
  margin: 12px 0 0;
}

.pf-h2 em {
  font-family: var(--f-serif);
  font-style: italic;
  font-weight: 600;
  color: var(--c-yellow);
}

.pf-lead {
  font-size: 17px;
  line-height: 1.55;
  color: var(--c-text-mute);
  max-width: 620px;
  margin-top: 12px;
}

/* ─── Buttons ───────────────────────── */

.pf-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 14px 24px;
  border-radius: 999px;
  border: 0;
  font-family: var(--f-sans);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.2px;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.15s ease, background 0.15s ease;
  text-decoration: none;
}
.pf-btn:hover { transform: translateY(-1px); }
.pf-btn:active { transform: translateY(0); }

.pf-btn--primary {
  background: var(--c-yellow);
  color: var(--c-purple);
  box-shadow: 0 4px 20px rgba(254, 204, 24, 0.25);
}
.pf-btn--primary:hover { box-shadow: 0 8px 28px rgba(254, 204, 24, 0.35); }

.pf-btn--ghost {
  background: rgba(255, 255, 255, 0.08);
  color: var(--c-text);
  border: 1.5px solid rgba(255, 255, 255, 0.22);
  backdrop-filter: blur(6px);
}
.pf-btn--ghost:hover { background: rgba(255, 255, 255, 0.14); }

/* ─── Hero CTA hovers ─────────────────
   Hero-scoped so the same .pf-btn--primary / .pf-btn--ghost classes elsewhere
   on the page keep their plain treatment. Same recipe for both: a tight ring
   + soft outer halo on hover, in the opposite brand colour from the button's
   resting state (purple on the yellow Osta-liput, yellow on the ghost
   Katso-lineup). */
.pf-hero__ctas .pf-btn--primary {
  transition: transform 0.12s ease, box-shadow 0.18s ease, background 0.15s ease;
}
.pf-hero__ctas .pf-btn--primary:hover {
  /* Colour-invert on hover: yellow ↔ purple swap, plus the purple outline +
     glow we already had. Matches the pattern used on other branded CTAs. */
  background: var(--c-purple);
  color: var(--c-yellow);
  box-shadow:
    0 0 0 1px var(--c-purple-light),
    0 0 24px rgba(139, 61, 212, 0.45);
}

.pf-hero__ctas .pf-btn--ghost {
  transition: background 0.15s ease, border-color 0.18s ease,
              box-shadow 0.18s ease, color 0.12s ease;
}
.pf-hero__ctas .pf-btn--ghost:hover {
  border-color: var(--c-yellow);
  color: var(--c-yellow);
  background: rgba(254, 204, 24, 0.08);
  box-shadow:
    0 0 0 1px var(--c-yellow),
    0 0 24px rgba(254, 204, 24, 0.35);
}

.pf-btn--outline {
  background: transparent;
  color: var(--c-text);
  border: 1.5px solid rgba(255, 255, 255, 0.22);
}

/* ─── Navigation ───────────────────────── */

.pf-nav {
  position: sticky; top: 0;
  /* Leaflet's tile/control panes use z-index 200–700 and its zoom buttons
     can rise above any sub-1000 layer. Pin the nav at 1100 so the map can
     never overlap it while the user is scrolling. */
  z-index: 1100;
  background: rgba(11, 5, 24, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  height: var(--nav-h);
  /* Chevron bottom edge — points down at the centre, ~10 px deep. Replaces
     the flat border so the nav reads as a brand-shaped band rather than a
     plain rectangle. The yellow accent line below (::after) sits on the
     same chevron path. */
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 10px), 50% 100%, 0 calc(100% - 10px));
  -webkit-clip-path: polygon(0 0, 100% 0, 100% calc(100% - 10px), 50% 100%, 0 calc(100% - 10px));
}
/* Yellow chevron stroke — sits 1 px under the nav, traced as a 1 px line
   following the same chevron geometry so the nav reads as a precisely cut
   shape rather than just a clipped rectangle. */
.pf-nav::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: var(--c-yellow);
  clip-path: polygon(
    0 calc(100% - 11px), 50% calc(100% - 1px), 100% calc(100% - 11px),
    100% 100%, 50% calc(100% + 0px), 0 100%
  );
  -webkit-clip-path: polygon(
    0 calc(100% - 11px), 50% calc(100% - 1px), 100% calc(100% - 11px),
    100% 100%, 50% calc(100% + 0px), 0 100%
  );
  opacity: 0.55;
}
.pf-nav__inner {
  height: 100%;
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px;
}
.pf-nav__logo img {
  height: 38px; width: auto;
  transition: filter 0.18s ease;
}
/* Logo hovers to brand purple. The white logo PNG is recoloured via a stack
   of filters (brightness(0) → black, then sepia/saturate/hue-rotate to land
   on #6707BA). It's a CSS hack but it lets us keep the single white PNG
   asset rather than shipping a second coloured copy. */
.pf-nav__logo:hover img {
  filter: brightness(0) saturate(100%) invert(15%) sepia(91%)
          saturate(4500%) hue-rotate(263deg) brightness(85%) contrast(115%);
}
.pf-nav__links {
  display: flex; gap: 28px;
  font-family: var(--f-display);
  font-size: 16px; font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.4px;
}
.pf-nav__links a {
  opacity: 0.92;
  transition: opacity 0.12s, color 0.12s, transform 0.12s;
  position: relative;
}
.pf-nav__links a::after {
  /* Yellow underline that grows in on hover — gives the bigger uppercase
     links a snap of brand colour without needing extra markup. */
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: -6px;
  height: 2px;
  background: var(--c-yellow);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform 0.18s ease;
}
.pf-nav__links a:hover { opacity: 1; color: var(--c-yellow); }
.pf-nav__links a:hover::after { transform: scaleX(1); }
/* Every other link hovers to brand purple instead of yellow (alternating
   accent). 2nd, 4th, 6th items get the purple treatment + matching underline. */
.pf-nav__links a:nth-child(even):hover { color: var(--c-purple-light); }
.pf-nav__links a:nth-child(even)::after { background: var(--c-purple-light); }
.pf-nav__right {
  display: flex; align-items: center; gap: 14px;
}
.pf-nav__lang {
  font-family: var(--f-mono); font-size: 11px; color: var(--c-text-dim);
}

/* Language switcher — emoji flags rendered at OS-native size.
   Keeps a Mac/iOS Apple Color Emoji feel; falls back to Twemoji/Segoe on
   non-Apple platforms. */
.pf-langs {
  display: inline-flex; align-items: center;
  gap: 4px;
  padding: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.10);
}
.pf-lang {
  background: transparent; border: 0; padding: 0;
  width: 26px; height: 26px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
  font-size: 18px; line-height: 1;
  cursor: pointer;
  opacity: 0.5; filter: saturate(0.5);
  transition: opacity 0.15s, transform 0.12s, filter 0.15s, box-shadow 0.15s;
}
.pf-lang:hover { opacity: 0.85; filter: saturate(1); transform: translateY(-1px); }
.pf-lang--active {
  opacity: 1; filter: saturate(1);
  box-shadow: 0 0 0 2px var(--c-yellow);
  background: rgba(254, 204, 24, 0.12);
}
.pf-nav__cta {
  background: var(--c-yellow); color: var(--c-purple);
  border: 0; padding: 10px 18px; border-radius: 999px;
  font-weight: 700; font-size: 13px; cursor: pointer;
  font-family: var(--f-display);
  text-transform: uppercase;
  letter-spacing: 0.8px;
  transition: background 0.15s ease, color 0.15s ease, transform 0.12s ease;
}
.pf-nav__cta:hover {
  /* Invert: purple background, yellow text. */
  background: var(--c-purple);
  color: var(--c-yellow);
  transform: translateY(-1px);
}

.pf-burger {
  display: none;
  background: transparent; border: 0; padding: 8px; cursor: pointer; color: var(--c-text);
  /* Stays clickable above the drawer so it can double as the close trigger
     once the drawer is open (icon "explodes" in that state). */
  position: relative;
  z-index: 1200;
  /* When shown via the mobile media query (display: inline-flex), align as
     a column so the three bars stack vertically into a classic hamburger.
     The mobile rule only flips `display`, so flex-direction lives here. */
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
}
.pf-burger__line {
  display: block;
  width: 22px; height: 2px;
  background: currentColor;
  border-radius: 2px;
  transition: transform 0.32s cubic-bezier(0.45, 1.6, 0.55, 0.85),
              opacity 0.18s ease;
}
/* "Exploded" state when the drawer is open — the three bars scatter outward
   at different angles + distances so the icon visibly reacts to being toggled
   (comedy effect requested by the brand). Tap again to slam them back in. */
.pf-burger--open .pf-burger__line:nth-child(1) {
  transform: translate(-9px, -3px) rotate(-22deg);
}
.pf-burger--open .pf-burger__line:nth-child(2) {
  transform: translate(8px, 2px) rotate(16deg) scaleX(0.7);
}
.pf-burger--open .pf-burger__line:nth-child(3) {
  transform: translate(-5px, 7px) rotate(38deg) scaleX(0.55);
}

.pf-drawer {
  position: fixed; inset: 0;
  background: rgba(11, 5, 24, 0.96);
  backdrop-filter: blur(20px);
  /* Sit above Leaflet's .leaflet-top/.leaflet-bottom control containers
     (z 1000) so the map can never poke through the open drawer. Stays
     below the navbar (1100) and burger (1200) which remain interactive
     on top of the drawer. */
  z-index: 1050;
  transform: translateY(-100%);
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex; flex-direction: column;
  /* Pad the top down past the sticky nav. */
  padding: calc(var(--nav-h) + 24px) 24px 24px;
}
.pf-drawer--open { transform: translateY(0); }
.pf-drawer__links {
  display: flex; flex-direction: column; gap: 4px;
}
.pf-drawer__links a {
  font-family: var(--f-display);
  font-size: 32px; font-weight: 700;
  padding: 14px 0; letter-spacing: -1px;
  border-bottom: 1px solid var(--c-border);
}
.pf-drawer__cta {
  margin-top: auto;
  background: var(--c-yellow); color: var(--c-purple);
  padding: 20px 16px;
  border: 0; border-radius: 999px;
  font-weight: 700; font-size: 22px;
  letter-spacing: 0.2px;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  display: block;
}

/* ─── Hero ───────────────────────── */

.pf-hero {
  position: relative; overflow: hidden;
  min-height: 780px;
  background: var(--c-bg);
  /* Pull the hero up under the nav's chevron bottom edge so the video
     tucks all the way to the chevron's tip — no flat-dark band peeks
     through where the nav points down. Matches the 10 px chevron depth
     used in .pf-nav clip-path, plus a 1 px nudge for safety. */
  margin-top: -11px;
}
.pf-hero__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}
.pf-hero__overlay {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse at 80% 20%, rgba(254, 204, 24, 0.16), transparent 50%),
    radial-gradient(ellipse at 10% 80%, rgba(103, 7, 186, 0.40), transparent 55%),
    linear-gradient(180deg, rgba(11, 5, 24, 0.40) 0%, rgba(11, 5, 24, 0.20) 35%, rgba(11, 5, 24, 0.85) 100%);
  pointer-events: none;
}
.pf-hero__inner {
  position: relative; min-height: 780px;
  padding-block: 56px 48px;
  /* horizontal padding inherits from .pf-container */
  display: flex; flex-direction: column; justify-content: space-between;
  gap: 32px;
}
.pf-hero__tags {
  display: flex; flex-wrap: wrap; gap: 10px;
}
.pf-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 14px; border-radius: 999px;
  font-size: 12px; font-weight: 600;
  background: rgba(255, 255, 255, 0.10);
  border: 1px solid rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(8px);
}
.pf-pill--yellow {
  background: var(--c-yellow); color: var(--c-purple); border: 0;
}
.pf-pill--yellow::before {
  content: ''; width: 6px; height: 6px; background: var(--c-purple); border-radius: 50%;
}
.pf-hero__date {
  font-family: var(--f-mono); font-size: 11px; color: var(--c-text-mute);
  text-align: right; line-height: 1.6;
}

.pf-hero__center { display: flex; flex-direction: column; align-items: flex-start; }
.pf-hero__logo {
  height: 170px; width: auto; max-width: 95%;
  /* "Alive" feel via a constantly-visible yellow drop-shadow that breathes
     in intensity. No size pulsing. */
  animation: pf-logo-pulse 4.5s ease-in-out infinite;
  will-change: filter;
}
@keyframes pf-logo-pulse {
  0%, 100% { filter: drop-shadow(0 0 18px rgba(254, 204, 24, 0.45)); }
  50%      { filter: drop-shadow(0 0 38px rgba(254, 204, 24, 0.80)); }
}
@media (prefers-reduced-motion: reduce) {
  .pf-hero__logo { animation: none; filter: drop-shadow(0 0 18px rgba(254, 204, 24, 0.40)); }
}
.pf-hero__tag {
  font-family: var(--f-serif); font-style: italic;
  font-weight: 600;
  font-size: 36px; color: var(--c-yellow);
  margin-top: 18px; letter-spacing: -0.5px;
  line-height: 1.15;
  /* No background panel — the readability comes from a layered text-shadow
     that gives the words a soft dark halo plus a faint yellow glow. Lets
     the hero video stay fully visible behind every letter. */
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.85),
    0 0 8px rgba(0, 0, 0, 0.65),
    0 0 18px rgba(254, 204, 24, 0.35);
}
.pf-hero__tag-em {
  color: var(--c-purple);
  font-weight: 800;
  font-style: italic;
}
.pf-hero__sub {
  font-size: 18px; color: rgba(255, 255, 255, 0.88);
  margin-top: 14px; max-width: 580px; line-height: 1.55;
}
.pf-hero__ctas {
  display: flex; gap: 12px; margin-top: 28px;
  flex-wrap: wrap; align-items: center;
}
.pf-hero__bottom {
  display: flex; justify-content: space-between; align-items: flex-end; gap: 24px;
  flex-wrap: wrap;
}
.pf-countdown {
  display: flex; gap: 32px;
}
.pf-countdown__cell .pf-countdown__v {
  font-family: var(--f-display); font-weight: 800;
  font-size: 52px; line-height: 1;
  color: var(--c-yellow); letter-spacing: -2px;
}
.pf-countdown__cell .pf-countdown__l {
  font-family: var(--f-mono); font-size: 11px;
  color: var(--c-text-mute); margin-top: 4px; letter-spacing: 0.6px;
}
.pf-tm-line {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--f-mono); font-size: 11px;
  color: var(--c-text-mute);
}
.pf-tm-line img {
  height: 16px; filter: brightness(0) invert(1); opacity: 0.9;
  transition: filter 0.2s ease;
}
/* Ticketmaster-blue glow on hover — keeps the white wordmark but blooms a
   blue halo behind it. drop-shadow on the filter chain so it follows the
   actual glyph outlines instead of the bounding rectangle. */
.pf-tm-line a:hover img {
  filter: brightness(0) invert(1)
          drop-shadow(0 0 6px #026CDF)
          drop-shadow(0 0 14px rgba(2, 108, 223, 0.6));
}

/* ─── Headliners ───────────────────────── */

.pf-headliners { padding: 96px 0 64px; }
.pf-section-head {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 24px; flex-wrap: wrap; margin-bottom: 40px;
}
.pf-section-head a { font-size: 14px; color: var(--c-text-mute); border-bottom: 1px solid rgba(255,255,255,0.25); padding-bottom: 3px; }

.pf-heads-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 24px;
}
.pf-head-card {
  position: relative; border-radius: 20px; overflow: hidden;
  background: var(--c-card); border: 1px solid var(--c-border);
  aspect-ratio: 4/5;
}
.pf-head-card img {
  width: 100%; height: 100%; object-fit: cover;
  object-position: 50% 100%; /* bottom-anchored — preserve artist name baked
                                 into the brand poster when the image is a
                                 9:16 story format cropped into a 4:5 card */
}

/* Day pill in the top-left of an artist photo: "PE" / "LA" / "PE & LA". */
.pf-card-day {
  position: absolute; top: 12px; left: 12px;
  z-index: 2;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 30px; height: 30px;
  padding: 0 10px;
  border-radius: 999px;
  background: var(--c-yellow); color: var(--c-purple);
  font-family: var(--f-display);
  font-weight: 800; font-size: 12px;
  letter-spacing: 0.5px;
  line-height: 1;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
  pointer-events: none;
}
.pf-head-card__gradient {
  position: absolute; inset: 0; top: auto; height: 45%;
  background: linear-gradient(180deg, transparent 0%, rgba(11,5,24,0.85) 70%, var(--c-bg) 100%);
  pointer-events: none;
}
.pf-head-card__info {
  position: absolute; bottom: 0; left: 0; right: 0;
  padding: 0 28px 28px;
}
.pf-head-card__meta { display: flex; gap: 8px; flex-wrap: wrap; }
.pf-tag {
  display: inline-block;
  font-family: var(--f-mono); font-size: 11px; font-weight: 600;
  padding: 4px 8px; border-radius: 4px;
  letter-spacing: 0.6px;
}
.pf-tag--yellow { background: var(--c-yellow); color: var(--c-purple); }
.pf-tag--ghost  { background: rgba(255,255,255,0.14); color: var(--c-text); }
.pf-head-card__name {
  font-family: var(--f-display); font-weight: 800;
  font-size: 56px; color: var(--c-text);
  margin-top: 10px; letter-spacing: -1.5px; line-height: 0.95;
  text-shadow: 0 2px 20px rgba(0,0,0,0.6);
}

/* ─── Lineup grid ───────────────────────── */

.pf-lineup { padding: 64px 0 96px; background: var(--c-bg-alt); border-top: 1px solid var(--c-border); }
/* Small note under the lineup h2 — flags that more artists are still being
   announced so the list doesn't read as final. Mono so it pairs with the
   eyebrow above the title, slight yellow tint to draw the eye. */
.pf-lineup__subtitle {
  margin: 8px 0 0;
  font-family: var(--f-mono);
  font-size: 13px;
  color: var(--c-yellow);
  letter-spacing: 0.4px;
}
.pf-lineup__filters {
  display: flex; gap: 8px; flex-wrap: wrap;
}
.pf-chip {
  padding: 8px 14px; border-radius: 999px;
  background: rgba(255,255,255,0.06);
  color: var(--c-text); font-size: 13px; font-weight: 500;
  border: 1px solid rgba(255,255,255,0.18);
  cursor: pointer; transition: all 0.12s;
}
.pf-chip:hover { background: rgba(255,255,255,0.12); }
.pf-chip--active { background: var(--c-yellow); color: var(--c-purple); border-color: var(--c-yellow); font-weight: 700; }
/* On mobile a tap leaves :hover stuck on the element until another tap
   elsewhere, and :hover has higher specificity than --active, so the chip
   would briefly render as the hover state (yellow outline only) instead of
   the active state (solid yellow). Re-apply the active fill under :hover
   so the selection snaps in immediately. */
.pf-chip--active:hover { background: var(--c-yellow); color: var(--c-purple); }

/* Locked chips: schedule not published yet — clicking shows the tooltip. */
.pf-chip-wrap {
  position: relative;
  display: inline-flex;
}
.pf-chip--locked {
  opacity: 0.55;
  cursor: not-allowed;
  position: relative;
}
.pf-chip--locked:hover {
  background: rgba(255,255,255,0.06); /* no hover lift */
}
.pf-chip__tip {
  position: absolute;
  top: calc(100% + 10px);
  /* Anchor to the chip's right edge so the tooltip can't overflow the
     viewport on narrow screens. Only disabled chips (Päälava, Rantalava)
     ever fire this tooltip and both live toward the right of the filter
     row, so right-anchoring keeps it on-screen without a JS measurer.
     Allow wrapping so the bubble shrinks to fit if the viewport is tighter
     than the natural text width. */
  left: auto;
  right: 0;
  background: var(--c-yellow);
  color: var(--c-purple);
  padding: 8px 12px;
  border-radius: 8px;
  font-family: var(--f-sans);
  font-size: 12px;
  font-weight: 600;
  max-width: min(280px, calc(100vw - 32px));
  white-space: normal;
  text-align: center;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  z-index: 20;
  animation: pf-chip-tip-in 0.15s ease-out;
  pointer-events: none;
}
.pf-chip__tip::before {
  content: "";
  position: absolute;
  bottom: 100%;
  /* Mirror the right-anchor — point at the chip's right portion. */
  right: 14px;
  border: 6px solid transparent;
  border-bottom-color: var(--c-yellow);
}
@keyframes pf-chip-tip-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.pf-lineup__grid {
  /* Flex-wrap instead of grid so the *last row* centres horizontally when
     it has fewer items than the rows above it. Full rows still fill the
     container edge-to-edge because each card is sized to the exact column
     width — `justify-content: center` only takes visible effect when the
     row doesn't fill. Works at every breakpoint without needing per-count
     :has() rules. */
  display: flex; flex-wrap: wrap; justify-content: center; gap: 16px;
  margin-top: 28px;
}
.pf-lineup__grid > .pf-artist-card {
  /* 4-column desktop: card width = (container − 3 × gap) ÷ 4. */
  flex: 0 0 calc((100% - 3 * 16px) / 4);
  max-width: calc((100% - 3 * 16px) / 4);
}
.pf-artist-card {
  position: relative; border-radius: 12px; overflow: hidden;
  background: var(--c-card); border: 1px solid var(--c-border);
  cursor: pointer; aspect-ratio: 4/5;
  transition: transform 0.15s, border-color 0.15s;
}
.pf-artist-card:hover { transform: translateY(-3px); border-color: rgba(254,204,24,0.4); }
.pf-artist-card img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 100%; }

/* Play-on-Apple-Music overlay — small purple circle top-right of each artist
   card, mirrors the day-badge geometry on the opposite corner. Triggers the
   bottom-bar player via a window event. */
.pf-artist-card__play {
  position: absolute;
  top: 10px; right: 10px;
  width: 32px; height: 32px;
  border-radius: 50%;
  border: 0;
  background: var(--c-purple);
  color: var(--c-yellow);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  box-shadow: 0 6px 18px -6px rgba(0,0,0,0.55);
  opacity: 0.92;
  transition: transform 0.15s ease, background 0.15s ease, opacity 0.15s ease;
  z-index: 3;
}
.pf-artist-card__play:hover {
  background: var(--c-purple-light);
  transform: scale(1.08);
  opacity: 1;
}
.pf-artist-card__play svg { display: block; margin-left: 1px; /* optical centre */ }
@media (max-width: 768px) {
  .pf-artist-card__play { width: 28px; height: 28px; top: 8px; right: 8px; }
}

/* Per-artist alignment overrides. EVELINA's source poster is 9:16 (story
   format) instead of 4:5, so the bottom-anchored crop makes the cloud
   border occupy a larger share of the card. Shift the visible window up
   so the photo + text proportions match the other cards. */
.pf-artist-card[data-slug="evelina"] img,
.pf-head-card[data-slug="evelina"] img {
  object-position: 50% 86%;
}
.pf-artist-card__gradient {
  position: absolute; inset: 0; top: auto; height: 55%;
  background: linear-gradient(180deg, transparent 0%, rgba(11,5,24,0.92) 75%);
  pointer-events: none;
}
.pf-artist-card__info {
  position: absolute; bottom: 12px; left: 14px; right: 14px;
}
.pf-artist-card__meta {
  font-family: var(--f-mono); font-size: 10px;
  color: var(--c-yellow); letter-spacing: 0.6px;
}
.pf-artist-card__name {
  font-family: var(--f-display); font-weight: 700;
  font-size: 18px; color: var(--c-text);
  margin-top: 2px; letter-spacing: -0.3px; line-height: 1.1;
  text-shadow: 0 2px 12px rgba(0,0,0,0.6);
}
.pf-lineup__more {
  margin-top: 32px;
  display: flex; justify-content: center; align-items: center;
}
.pf-lineup__more strong { font-family: var(--f-display); font-size: 22px; }
.pf-lineup__more span   { color: var(--c-text-mute); font-size: 14px; display: block; margin-top: 4px; }

/* ─── Schedule ───────────────────────── */

.pf-schedule { padding: 96px 0; background: var(--c-bg); }
.pf-schedule__day { margin-bottom: 48px; }
.pf-schedule__day-head {
  display: flex; align-items: center; gap: 16px; margin-bottom: 16px;
}
.pf-schedule__day-head h3 {
  font-family: var(--f-display); font-size: 32px; font-weight: 700; margin: 0;
  letter-spacing: -0.5px;
}
.pf-schedule__day-head .pf-rule {
  flex: 1; height: 1px; background: var(--c-border);
}
.pf-schedule__cols {
  display: grid; grid-template-columns: 80px 1fr 1fr; gap: 0;
  align-items: start;
}
.pf-schedule__list { display: none; }
.pf-schedule__row-mobile {
  display: grid; grid-template-columns: 56px 1fr;
  align-items: center; gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--c-border);
}
.pf-schedule__row-mobile .pf-schedule__time {
  padding: 0; border: 0;
}
.pf-schedule__head-cell {
  padding: 8px 16px;
  font-family: var(--f-mono); font-size: 11px; color: var(--c-text-mute); letter-spacing: 1px;
  border-bottom: 1px solid var(--c-border);
}
.pf-schedule__time {
  padding: 20px 0;
  font-family: var(--f-mono); font-size: 13px; color: var(--c-text-mute);
  border-bottom: 1px solid var(--c-border);
}
.pf-schedule__slot {
  padding: 12px 16px;
  border-bottom: 1px solid var(--c-border);
}
.pf-schedule__slot-inner {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 14px; border-radius: 12px;
  background: var(--c-card); border: 1px solid var(--c-border);
}
.pf-schedule__slot-inner--head {
  background: linear-gradient(135deg, rgba(254,204,24,0.22), rgba(254,204,24,0.05));
  border: 1.5px solid var(--c-yellow);
  padding: 14px 16px;
}
.pf-schedule__slot-thumb {
  width: 48px; height: 48px; border-radius: 8px; overflow: hidden; flex: 0 0 auto;
}
.pf-schedule__slot-thumb img { width: 100%; height: 100%; object-fit: cover; }
.pf-schedule__slot-name {
  font-family: var(--f-display); font-size: 18px; font-weight: 700; color: var(--c-text);
  letter-spacing: -0.3px;
}
.pf-schedule__slot-tag {
  font-family: var(--f-mono); font-size: 10px; color: var(--c-yellow); margin-top: 2px; letter-spacing: 0.6px;
}

/* ─── Tickets ───────────────────────── */

.pf-tickets {
  padding: 96px 0; background: var(--c-bg-alt);
  position: relative; overflow: hidden;
  border-top: 1px solid var(--c-border);
}
.pf-tickets::before {
  content: ''; position: absolute;
  top: -120px; right: -120px; width: 480px; height: 480px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(103,7,186,0.45), transparent 70%);
  filter: blur(40px); pointer-events: none;
}
.pf-tickets__head { text-align: center; margin-bottom: 48px; position: relative; }
.pf-tickets__grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px;
  position: relative;
}
.pf-tier {
  border-radius: 20px; padding: 32px 24px;
  background: var(--c-card); border: 1px solid var(--c-border);
  position: relative;
  /* Equal-height columns + flex layout so the CTA stays pinned at the
     bottom regardless of how many feature rows the tier has. */
  display: flex;
  flex-direction: column;
}
.pf-tier__feat { flex: 1 1 auto; }    /* push CTA to the bottom of the card */
.pf-tier__btn  { margin-top: auto; }  /* belt-and-braces */
.pf-tier--hot {
  background: linear-gradient(180deg, rgba(254,204,24,0.16) 0%, var(--c-card) 60%);
  border: 1.5px solid var(--c-yellow);
}
/* VIP tiers — distinctly purple so the premium tier reads at a glance,
   without overshadowing the gold "most-popular" 2-day card. */
.pf-tier--vip {
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(139, 61, 212, 0.28) 0%, transparent 55%),
    linear-gradient(180deg, rgba(75, 7, 137, 0.45) 0%, var(--c-card) 70%);
  border: 1.5px solid var(--c-purple-light);
  box-shadow: 0 0 0 1px rgba(139, 61, 212, 0.25) inset,
              0 18px 48px -28px rgba(139, 61, 212, 0.55);
}
.pf-tier--vip .pf-tier__name {
  background: linear-gradient(90deg, #FFFFFF 0%, #E5C7FF 100%);
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
}
.pf-tier--vip .pf-tier__sub { color: rgba(229, 199, 255, 0.85); }
.pf-tier--vip .pf-tier__feat { border-top-color: rgba(139, 61, 212, 0.35); }
.pf-tier--vip .pf-tier__feat-row span:first-child { color: var(--c-purple-light); }
.pf-tier--vip .pf-tier__btn {
  background: var(--c-purple);
  color: var(--c-text);
  border: 0;
}
.pf-tier--vip .pf-tier__btn:hover { background: var(--c-purple-deep); }
.pf-tier__badge {
  position: absolute; top: -12px; left: 24px;
  background: var(--c-yellow); color: var(--c-purple);
  padding: 4px 12px; border-radius: 999px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.4px;
}
.pf-tier__badge--vip {
  left: auto; right: 18px;
  top: -16px;
  padding: 9px 18px;
  font-size: 14px;
  background: linear-gradient(135deg, var(--c-purple) 0%, var(--c-purple-light) 100%);
  color: var(--c-yellow);
  box-shadow: 0 8px 22px -8px rgba(139, 61, 212, 0.75);
  letter-spacing: 1.6px;
}
.pf-tier__sub { font-size: 14px; color: var(--c-text-mute); }
.pf-tier__name { font-family: var(--f-display); font-size: 22px; font-weight: 700; margin-top: 4px; }
.pf-tier__price {
  display: flex; align-items: baseline; gap: 6px; margin-top: 20px;
}
.pf-tier__price-v {
  font-family: var(--f-display); font-weight: 800;
  font-size: 76px; letter-spacing: -2px; line-height: 1;
}
.pf-tier__price-c { font-size: 18px; color: var(--c-text-mute); }
.pf-tier__feat {
  margin-top: 22px; padding-top: 16px;
  border-top: 1px solid var(--c-border);
}
.pf-tier__feat-row {
  display: flex; gap: 10px; padding: 6px 0; font-size: 13px;
}
.pf-tier__feat-row span:first-child { color: var(--c-yellow); }
/* Negative feature row — the tick becomes a ✗ in a muted red, the copy is
   dimmed slightly so it reads as "explicitly excluded" rather than a perk. */
.pf-tier__feat-row--no span:first-child { color: #FF8A8A; }
.pf-tier__feat-row--no span:last-child  { color: rgba(251, 250, 245, 0.7); }

/* ─── Ticket-sale progress indicator ─────────────────────────────
   Two meters total — one for all standard tiers, one for all VIP tiers —
   rendered side-by-side above the ticket grid (stacked on mobile). The
   shared PF_TICKETS_SOLD const drives both values; the cards themselves
   stay free of repeated info. */
.pf-tickets-sales {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin: 8px 0 36px;
}
.pf-tickets-sales__row {
  display: flex; flex-direction: column; gap: 10px;
  padding: 16px 20px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid var(--c-border);
}
.pf-tickets-sales__row--vip {
  background: linear-gradient(135deg, rgba(139, 61, 212, 0.10) 0%, rgba(139, 61, 212, 0.025) 100%);
  border-color: rgba(139, 61, 212, 0.35);
}
.pf-tickets-sales__head {
  display: flex; align-items: center; gap: 12px;
  flex-wrap: wrap;
}
.pf-tickets-sales__cat {
  font-family: var(--f-mono); font-size: 12px; letter-spacing: 1.4px;
  text-transform: uppercase; color: var(--c-text);
  font-weight: 700;
  margin-right: auto;
}
/* Match the VIP tier badge — yellow text to echo the "◆ VIP" chip on
   the VIP ticket cards. */
.pf-tickets-sales__row--vip .pf-tickets-sales__cat { color: var(--c-yellow); }
.pf-tickets-sales__pct {
  font-family: var(--f-mono); font-size: 13px; letter-spacing: 0.6px;
  /* Inline `color` from the SalesMeter component overrides this fallback —
     the text tracks the heat-scale colour at the current %. The dark
     text-shadow gives the coloured glyphs enough contrast to stay legible
     on the dark card background regardless of which heat colour they hit. */
  color: rgba(251, 250, 245, 0.78);
  text-transform: uppercase;          /* "myyty" → "MYYTY", same for "sold" */
  white-space: nowrap;
  font-weight: 700;
  text-shadow:
    0 0 1px rgba(0, 0, 0, 0.9),
    0 1px 3px rgba(0, 0, 0, 0.55);
  animation: pf-sales-pct-pulse 2.4s ease-in-out infinite;
}
.pf-tickets-sales__flag {
  padding: 3px 10px; border-radius: 999px;
  background: rgba(255, 138, 138, 0.18);
  color: #FFB48A;
  font-family: var(--f-mono); font-size: 11px; letter-spacing: 1.2px;
  font-weight: 700; text-transform: uppercase;
  animation: pf-sales-flag-pulse 1.8s ease-in-out infinite;
}
.pf-tickets-sales__track {
  position: relative;
  height: 6px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}
/* Heat-scale fill: a continuous green → lime → yellow → orange → red →
   burgundy gradient anchored to the full 0-100 % track width. Warm
   colours land earlier than a linear scale (yellow at 30 %, red at 75 %)
   and the last quarter darkens into burgundy so a sold-out bar reads as
   "blood-hot", not just brightly red. The fill element stretches across
   the entire track (inset: 0) so the gradient keeps its true scale; the
   clip-path then reveals only the leftmost % via the inline `--pct`
   custom property. */
.pf-tickets-sales__fill {
  position: absolute; inset: 0;
  border-radius: 999px;
  background: linear-gradient(90deg,
    #22C55E   0%,    /* green     */
    #84CC16  15%,    /* lime      */
    #EAB308  30%,    /* yellow    */
    #F97316  50%,    /* orange    */
    #EF4444  75%,    /* red       */
    #6B0F1A 100%);   /* burgundy  */
  clip-path:         inset(0 calc(100% - var(--pct, 0%)) 0 0 round 999px);
  -webkit-clip-path: inset(0 calc(100% - var(--pct, 0%)) 0 0 round 999px);
  transition: clip-path 0.5s cubic-bezier(0.4, 0, 0.2, 1),
              -webkit-clip-path 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  /* Bar grows in from 0 → its final % on first paint. `backwards` fill
     mode means the element renders the `from` keyframe immediately, so
     there's no flash of the final state before the grow-in begins. */
  animation: pf-sales-fill-in 1.4s cubic-bezier(0.4, 0, 0.2, 1) 0.15s backwards;
}

/* Continuous left-to-right shimmer. Linear timing + opacity fade at both
   ends means no snap-back, no perceptible "hold" frame — the highlight
   slides through, fades out, and the next cycle fades in. The shimmer
   is also clipped to the visible (filled) portion of the bar, since the
   parent fill's clip-path cascades to the pseudo-element. */
.pf-tickets-sales__fill::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.65) 50%,
    transparent 100%);
  transform: translateX(-100%);
  animation: pf-sales-shimmer 3s linear infinite;
}

/* "Almost gone" — the heat-scale already turned red at this point, so we
   only need a subtle outer glow to draw the eye + keep the chip pulse.
   No fill-colour override; the gradient does that work. */
.pf-tickets-sales__row--low .pf-tickets-sales__track {
  box-shadow: 0 0 14px rgba(239, 68, 68, 0.45);
  animation: pf-sales-low-pulse 2s ease-in-out infinite;
}
.pf-tickets-sales__row--low .pf-tickets-sales__pct { color: #FCA5A5; font-weight: 700; }

@keyframes pf-sales-shimmer {
  /* Constant velocity across the whole cycle, opacity fades at both ends
     so the highlight appears, sweeps, fades — no visible reset. */
  0%   { transform: translateX(-80%); opacity: 0; }
  20%  { opacity: 1; }
  80%  { opacity: 1; }
  100% { transform: translateX(180%); opacity: 0; }
}
@keyframes pf-sales-flag-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}
@keyframes pf-sales-low-pulse {
  0%, 100% { box-shadow: 0 0 8px rgba(239, 68, 68, 0.30); }
  50%      { box-shadow: 0 0 20px rgba(239, 68, 68, 0.65); }
}
@keyframes pf-sales-pct-pulse {
  /* Subtle opacity breathing on the "X% MYYTY" label, tuned to the same
     family of timings as the bar pulses so the whole row feels alive. */
  0%, 100% { opacity: 0.85; }
  50%      { opacity: 1;    }
}
@keyframes pf-sales-fill-in {
  /* Bar grows from empty to its final % on first paint. The `to` state is
     implicit (the element's computed clip-path with var(--pct)), so the
     bar lands at the right place without us hard-coding the destination. */
  from {
    clip-path:         inset(0 100% 0 0 round 999px);
    -webkit-clip-path: inset(0 100% 0 0 round 999px);
  }
}
@media (max-width: 768px) {
  .pf-tickets-sales { grid-template-columns: 1fr; gap: 14px; margin-bottom: 28px; }
  .pf-tickets-sales__row { padding: 14px 16px; }
}
@media (prefers-reduced-motion: reduce) {
  .pf-tickets-sales__fill,
  .pf-tickets-sales__fill::after,
  .pf-tickets-sales__pct,
  .pf-tickets-sales__row--low .pf-tickets-sales__track,
  .pf-tickets-sales__flag { animation: none; }
}
.pf-tier__btn {
  margin-top: 22px; width: 100%; padding: 14px 0;
  border-radius: 999px;
  background: transparent; color: var(--c-text);
  border: 1.5px solid rgba(255,255,255,0.25);
  font-weight: 700; font-size: 14px; cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
  text-decoration: none;
  text-align: center;
  display: block;
  position: relative;
  overflow: visible;
}
.pf-tier__btn:hover { background: rgba(255,255,255,0.08); }
.pf-tier--hot .pf-tier__btn { background: var(--c-yellow); color: var(--c-purple); border: 0; }
.pf-tier--hot .pf-tier__btn:hover { background: var(--c-yellow-deep); }

/* Aurora hover — soft elliptical colour blobs drifting around the button,
   each heavily blurred so their edges fade past the pill bounds. No rounded-
   rectangle silhouette: the pseudo-elements are wider than the button and
   masked into a radial falloff, so what you see is a diffuse aurora wash
   rather than a contained box. */
.pf-tier__btn--aurora { isolation: isolate; }
.pf-tier__btn--aurora .pf-tier__btn-text {
  position: relative;
  z-index: 2;
}
.pf-tier__btn--aurora::before,
.pf-tier__btn--aurora::after {
  content: "";
  position: absolute;
  /* Stretch well past the pill so the blobs can centre outside the
     button's geometry. */
  inset: -35px -70px;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.45s ease;
  z-index: 0;
  filter: blur(34px);
  /* Radial falloff mask kills the rectangular box edges — the aurora
     fades into nothing instead of clipping at the pseudo-element's bounds. */
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, #000 35%, transparent 80%);
          mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, #000 35%, transparent 80%);
}
.pf-tier__btn--aurora::before {
  background:
    radial-gradient(ellipse 55% 70% at 22% 45%, rgba(103, 7, 186, 0.95), transparent 60%),
    radial-gradient(ellipse 50% 60% at 78% 55%, rgba(254, 204, 24, 0.65), transparent 60%);
}
.pf-tier__btn--aurora::after {
  background:
    radial-gradient(ellipse 60% 55% at 50% 25%, rgba(139, 61, 212, 0.85), transparent 65%),
    radial-gradient(ellipse 65% 60% at 55% 85%, rgba(103, 7, 186, 0.75), transparent 65%);
}
.pf-tier__btn--aurora:hover::before,
.pf-tier__btn--aurora:hover::after {
  opacity: 1;
  animation: pf-aurora-drift 8s ease-in-out infinite;
}
.pf-tier__btn--aurora:hover::after {
  animation-direction: reverse;
  animation-duration: 11s;
}
@keyframes pf-aurora-drift {
  0%, 100% { transform: translate(0, 0)       scale(1);    }
  35%      { transform: translate(-6%, -2%)   scale(1.08); }
  65%      { transform: translate(5%, 3%)     scale(1.05); }
}
@media (prefers-reduced-motion: reduce) {
  .pf-tier__btn--aurora:hover::before,
  .pf-tier__btn--aurora:hover::after { animation: none; }
}
.pf-tickets__note {
  margin-top: 28px; text-align: center;
  font-family: var(--f-mono); font-size: 11px; color: var(--c-text-mute);
  display: flex; align-items: center; gap: 8px; justify-content: center;
  flex-wrap: wrap;
}
/* The "·" separator between the Ticketmaster logo and the price-rise note.
   Hidden on narrow viewports where the row wraps onto two lines — leaving
   it visible there orphans a bullet at the end of line 1. The suffix span
   doesn't carry its own bullet, so dropping this element cleanly removes
   the separator without affecting the suffix copy. */
.pf-tickets__note-sep { color: var(--c-text-mute); opacity: 0.75; }
@media (max-width: 600px) {
  .pf-tickets__note-sep { display: none; }
}
.pf-tickets__note img {
  height: 18px; filter: brightness(0) invert(1); opacity: 0.85;
  transition: filter 0.2s ease;
}
/* Ticketmaster-blue glow on hover — mirrors the .pf-tm-line treatment.
   This block is needed separately because the "Liput myy ·" row at the
   bottom of the tickets section is a plain .pf-tickets__note div, not the
   shared PfTmLine component, so .pf-tm-line's hover rule doesn't match. */
.pf-tickets__note a:hover img {
  filter: brightness(0) invert(1)
          drop-shadow(0 0 6px #026CDF)
          drop-shadow(0 0 14px rgba(2, 108, 223, 0.6));
}

/* ─── Venue ───────────────────────── */

.pf-venue { padding: 96px 0; }
.pf-venue__grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center;
}
.pf-venue__title {
  font-family: var(--f-display); font-size: 56px; font-weight: 800;
  letter-spacing: -1.5px; line-height: 1; margin: 12px 0 0;
}
.pf-venue__title em {
  font-family: var(--f-serif); font-style: italic; font-weight: 600; color: var(--c-yellow);
}
.pf-venue__lead { font-size: 16px; color: var(--c-text-mute); line-height: 1.6; margin-top: 16px; max-width: 440px; }
.pf-venue__stats {
  margin-top: 24px;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 16px;
}
.pf-venue__stat {
  padding: 14px 0; border-top: 1px solid var(--c-border);
}
.pf-venue__stat-k { font-family: var(--f-display); font-size: 28px; font-weight: 700; }
.pf-venue__stat-l {
  font-family: var(--f-mono); font-size: 11px;
  color: var(--c-text-mute); margin-top: 4px; letter-spacing: 0.6px;
}
.pf-venue__map {
  border-radius: 16px; height: 460px; position: relative; overflow: hidden;
  background: var(--c-bg-alt);
  border: 1px solid var(--c-border);
}

/* Leaflet overrides — map controls / popup match the brand. */
.pf-venue__map .leaflet-control-attribution {
  background: rgba(11, 5, 24, 0.7);
  color: var(--c-text-dim);
  font-family: var(--f-mono);
  font-size: 10px;
}
.pf-venue__map .leaflet-control-attribution a {
  color: var(--c-text-mute);
}
.pf-venue__map .leaflet-control-zoom a {
  background: rgba(11, 5, 24, 0.85);
  color: var(--c-text);
  border: 1px solid var(--c-border);
}
.pf-venue__map .leaflet-control-zoom a:hover {
  background: var(--c-yellow);
  color: var(--c-purple);
}
.pf-venue__map .leaflet-popup-content-wrapper {
  background: var(--c-yellow);
  color: var(--c-purple);
  border-radius: 8px;
  font-family: var(--f-display);
}
.pf-venue__map .leaflet-popup-tip {
  background: var(--c-yellow);
}

/* Brand pin: the favicon-W glyph, with a glowing halo. Anchored at centre. */
.pf-map-marker {
  position: relative;
  width: 44px; height: 44px;
}
.pf-map-pin-img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  display: block;
  border-radius: 50%;
  box-shadow: 0 0 14px rgba(254, 204, 24, 0.55), 0 2px 10px rgba(0, 0, 0, 0.45);
  z-index: 2;
}
.pf-map-pin-halo {
  position: absolute;
  inset: -8px;
  border-radius: 50%;
  background: rgba(254, 204, 24, 0.22);
  animation: pf-pin-pulse 2.4s ease-out infinite;
  z-index: 1;
}
@keyframes pf-pin-pulse {
  0%   { transform: scale(0.7); opacity: 0.85; }
  70%  { transform: scale(1.5); opacity: 0;    }
  100% { transform: scale(1.5); opacity: 0;    }
}

/* ─── About ───────────────────────── */

.pf-about { padding: 96px 0; background: var(--c-bg-alt); border-top: 1px solid var(--c-border); border-bottom: 1px solid var(--c-border); }
.pf-about__inner {
  display: grid; grid-template-columns: 1fr 1.3fr; gap: 56px; align-items: start;
}
.pf-about__title {
  font-family: var(--f-display); font-size: 56px; font-weight: 800;
  letter-spacing: -1.5px; line-height: 1; margin: 12px 0 0;
}
.pf-about__title em {
  font-family: var(--f-serif); font-style: italic; font-weight: 600; color: var(--c-yellow);
}
.pf-about__body p {
  font-size: 17px; line-height: 1.65; color: rgba(255,255,255,0.85);
  margin: 0 0 16px;
}
.pf-about__body p + p { margin-top: 0; }

/* ─── Follow & download ──────────────── */

.pf-social {
  padding: 80px 0;
  background: var(--c-bg);
}
.pf-social__cols {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 32px;
  margin-top: 24px;
}
.pf-social__col {
  padding: 24px;
  background: var(--c-card);
  border: 1px solid var(--c-border);
  border-radius: 20px;
}
.pf-social__sub {
  font-family: var(--f-mono); font-size: 11px;
  color: var(--c-text-mute); letter-spacing: 1.2px;
  margin-bottom: 18px;
}
.pf-social__row {
  display: flex; flex-wrap: wrap; gap: 12px;
}
/* Social-button row inside the SEURAA / FOLLOW column gets its own grid so
   the three buttons fill the column width evenly instead of looking like
   loose stickers. Visually balances the App Store + Google Play badges
   stacked in the sibling column. */
.pf-social__row--socials {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}
.pf-social__hint {
  margin-top: 14px;
  font-family: var(--f-mono); font-size: 11px;
  color: var(--c-text-dim); letter-spacing: 0.6px;
}

/* Social button — square card that fills its grid cell. Icon stacked above
   the network name, centred. Matches the visual weight of the official
   store badges in the neighbouring column. */
.pf-social-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 18px 12px;
  min-height: 96px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: var(--c-text);
  font-family: var(--f-display);
  font-weight: 600; font-size: 14px;
  text-decoration: none;
  text-align: center;
  transition: background 0.15s, transform 0.12s, border-color 0.15s, color 0.12s;
}
.pf-social-btn:hover {
  background: var(--c-yellow);
  color: var(--c-purple);
  border-color: var(--c-yellow);
  transform: translateY(-2px);
}
.pf-social-btn__icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
}
.pf-social-btn__icon svg {
  width: 30px;
  height: 30px;
}

/* Official store badges — both Apple "Download on the App Store" and Google
   "Get it on Google Play" use their unmodified vendor SVGs. Both vendors
   require:
     • Apple: ≥40 px tall, ≥1/10 of badge height clear-space, do not modify
     • Google: ≥60 px tall (download CTA), ≥1/4 of badge height clear-space,
       do not modify
   Apple also says its badge should be at least the height of Google's when
   shown together. We size both to 60 px in the primary CTA, 44 px in the
   footer (still well above Apple's 40-px floor; Google permits smaller in
   secondary placements like footers). */
.pf-store-badge {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  border: 0;
  background: transparent;
  transition: transform 0.12s, opacity 0.12s;
}
.pf-store-badge:hover {
  transform: translateY(-2px);
  opacity: 0.92;
}
.pf-store-badge img {
  display: block;
  width: auto;
}

/* Primary CTA in the social section — both badges 60 px tall. */
.pf-store-badge--apple img,
.pf-store-badge--google img {
  height: 60px;
  margin: 8px 6px;          /* ~1/4 of 60 px clear-space */
}

/* ─── Schedule placeholder — section header only while schedule is unreleased */
.pf-schedule--placeholder { padding-bottom: 32px; }

/* ─── FAQ ─────────────────────────────── */

.pf-faq { padding: 96px 0; background: var(--c-bg); }
.pf-faq__list {
  margin-top: 8px;
  border-top: 1px solid var(--c-border);
}
.pf-faq__item {
  border-bottom: 1px solid var(--c-border);
  padding: 4px 0;
}
.pf-faq__q {
  list-style: none;
  cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 22px 4px;
  font-family: var(--f-display); font-weight: 700; font-size: 22px;
  letter-spacing: -0.3px;
  color: var(--c-text);
  transition: color 0.12s;
}
.pf-faq__q:hover { color: var(--c-yellow); }
/* Alternating brand-colour hover on FAQ items — odd questions glow yellow
   (default rule above), even ones glow brand purple, mirroring the navbar. */
.pf-faq__item:nth-child(even) .pf-faq__q:hover { color: var(--c-purple-light); }
.pf-faq__q::-webkit-details-marker { display: none; }
.pf-faq__chev {
  flex: 0 0 auto;
  width: 32px; height: 32px; border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--c-border);
  color: var(--c-yellow);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--f-mono); font-size: 18px; font-weight: 600;
  transition: transform 0.2s ease, background 0.12s;
}
.pf-faq__item[open] .pf-faq__chev {
  transform: rotate(45deg);
  background: var(--c-yellow); color: var(--c-purple); border-color: var(--c-yellow);
}
.pf-faq__a {
  padding: 0 4px 24px;
  font-size: 16px; line-height: 1.65;
  color: var(--c-text-mute);
  max-width: 760px;
}
/* Links inside FAQ answers — brand yellow with a subtle underline, swap to
   purple-light on hover so the cross-links to other pages read as part of
   the brand palette rather than default browser blue. */
.pf-faq__a a {
  color: var(--c-yellow);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color 0.12s ease, text-decoration-color 0.12s ease;
}
.pf-faq__a a:hover { color: var(--c-purple-light); }
/* Lists inside rich FAQ answers (e.g. prohibited-items recap) — keep them
   tight and indented so they read as a sub-list rather than full body
   paragraphs. */
.pf-faq__a ul {
  margin: 10px 0;
  padding-left: 22px;
}
.pf-faq__a ul li { margin: 4px 0; }

/* ─── Sponsors ───────────────────────── */
/* Identical-size white cards. Logos keep their original colors. */

.pf-sponsors { padding: 80px 0; }
.pf-sponsors__head { text-align: center; margin-bottom: 36px; }
.pf-sponsors__head h3 {
  font-family: var(--f-display); font-size: 36px; font-weight: 700;
  margin: 8px 0 0;
}
.pf-sponsors__row {
  /* Flex-wrap + centre so any short last row balances horizontally — works
     for 6 sponsors (3+3), 7 (3+3+1 centred), 5 (3+2 centred), etc. The card
     width per breakpoint sets the column count; flex handles the rest. */
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 16px;
}
.pf-sponsor-card {
  background: var(--c-yellow);
  border-radius: 16px;
  height: 160px;
  /* 3 per row on desktop — 6 sponsors render cleanly as 3+3. */
  flex: 0 0 calc((100% - 2 * 16px) / 3);
  max-width: calc((100% - 2 * 16px) / 3);
  display: flex; align-items: center; justify-content: center;
  padding: 24px 28px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.18);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  text-decoration: none;
  cursor: pointer;
}
.pf-sponsor-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.24);
}
.pf-sponsor-card img {
  max-height: 100%; max-width: 100%; width: auto; height: auto;
  object-fit: contain;
  /* No filter — preserve original brand colors */
}
/* Exception: white-on-transparent logos (Xtended) can't show on a white card.
   Invert luminance to render the logo as black on the white tile, preserving
   shape/proportions exactly as supplied. */
.pf-sponsor-card__img--invert {
  filter: brightness(0) saturate(100%);
}
.pf-sponsor-card__text {
  font-family: var(--f-display); font-weight: 700; font-size: 26px;
  color: #1A0530; letter-spacing: -0.4px;
  text-align: center;
}

/* ─── Contact ───────────────────────── */

.pf-contact {
  padding: 96px 0;
  /* Top-to-bottom fade so the bottom edge is uniformly --c-purple-deep,
     which is exactly what the footer's top stop uses — keeps the join
     between contact + footer seamless with no visible seam line. */
  background: linear-gradient(180deg, var(--c-purple) 0%, var(--c-purple-deep) 100%);
}
.pf-contact__grid {
  display: grid; grid-template-columns: 1fr 1.2fr; gap: 56px; align-items: center;
}
.pf-contact__title {
  font-family: var(--f-display); font-size: 56px; font-weight: 800;
  letter-spacing: -1.5px; line-height: 1; margin: 12px 0 0;
}
.pf-contact__title em {
  font-family: var(--f-serif); font-style: italic; font-weight: 600; color: var(--c-yellow);
}
.pf-contact__lead {
  font-size: 16px; line-height: 1.6; color: rgba(255,255,255,0.85);
  margin-top: 20px; max-width: 380px;
}
.pf-contact__emails {
  margin-top: 28px;
  font-family: var(--f-mono); font-size: 13px; line-height: 1.9; opacity: 0.9;
}
.pf-form {
  background: rgba(0,0,0,0.22);
  border-radius: 16px; padding: 28px;
  border: 1px solid rgba(254,204,24,0.20);
}
.pf-form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.pf-form label {
  display: block; font-family: var(--f-mono); font-size: 11px;
  color: rgba(255,255,255,0.75); letter-spacing: 0.6px; margin-bottom: 6px;
}
.pf-form input, .pf-form textarea, .pf-form select {
  width: 100%; box-sizing: border-box;
  background: rgba(0,0,0,0.25);
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 10px; padding: 12px 14px;
  color: var(--c-text); font-family: var(--f-sans); font-size: 14px;
  outline: none; transition: border-color 0.12s, background 0.12s;
}
.pf-form input::placeholder, .pf-form textarea::placeholder { color: rgba(255,255,255,0.45); }
.pf-form input:focus, .pf-form textarea:focus, .pf-form select:focus {
  border-color: var(--c-yellow); background: rgba(0,0,0,0.35);
}
.pf-form textarea { min-height: 110px; resize: vertical; font-family: var(--f-sans); }

/* Custom-styled <select> — match height + look of the other inputs.
   Native dropdown chevron is hidden via appearance: none and replaced
   with an inline SVG positioned over the input. */
.pf-form__select-wrap {
  position: relative;
  display: block;
}
.pf-form__select {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  padding-right: 40px; /* room for the chevron */
  background-image: none;
  cursor: pointer;
  height: auto;
}
.pf-form__select::-ms-expand { display: none; }
.pf-form__select-chev {
  position: absolute;
  right: 16px;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  color: var(--c-yellow);
}
.pf-form__select option {
  background: #1A0530;
  color: var(--c-text);
}
.pf-form__field { margin-top: 14px; }
.pf-form__field--first { margin-top: 0; }
.pf-form__submit {
  margin-top: 18px; width: 100%; padding: 14px 0; border-radius: 999px;
  background: var(--c-yellow); color: var(--c-purple); border: 0;
  font-weight: 700; font-size: 14px; cursor: pointer;
  transition: background 0.12s, transform 0.12s;
}
.pf-form__submit:hover { background: var(--c-yellow-deep); transform: translateY(-1px); }
.pf-form__legal {
  font-family: var(--f-mono); font-size: 10px;
  color: rgba(255,255,255,0.55); margin-top: 12px; text-align: center;
}
.pf-form__legal-link {
  color: var(--c-yellow);
  text-decoration: underline;
  text-decoration-color: rgba(254, 204, 24, 0.4);
  text-underline-offset: 2px;
  transition: text-decoration-color 0.12s;
}
.pf-form__legal-link:hover {
  text-decoration-color: var(--c-yellow);
}

/* ─── YHTEYSTIEDOT (named contacts + billing block under the form) ───────────────────────── */
/* Lives inside .pf-contact, so it sits on the purple gradient. */

.pf-contacts {
  margin-top: 56px;
  padding-top: 40px;
  border-top: 1px solid rgba(254, 204, 24, 0.20);
  text-align: center;
  color: var(--c-text);
}
.pf-contacts__heading {
  font-family: var(--f-display);
  font-weight: 800;
  font-size: 38px;
  letter-spacing: -1px;
  color: var(--c-yellow);
  margin: 0 0 32px;
}
.pf-contacts__promo { margin: 0 auto 36px; }
/* Flex-wrap + centre so any short last row balances horizontally. Two per
   row keeps each cell wide enough that the long Saapunki-family emails
   ("sami.vepsalainen@powerfestival.fi" etc.) never wrap mid-domain. With
   3 entries this produces 2 + 1 centred; with 4 entries it's a clean 2×2;
   with 5 it's 2 + 2 + 1 centred. */
.pf-contacts__cols {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 28px 48px;
  max-width: 720px;
  margin: 0 auto;
}
.pf-contacts__cell {
  padding: 4px;
  flex: 0 0 calc((100% - 48px) / 2);
  max-width: calc((100% - 48px) / 2);
}
.pf-contacts__role {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 18px;
  color: rgba(255, 255, 255, 0.95);
  margin-bottom: 10px;
}
.pf-contacts__promo .pf-contacts__role {
  font-size: 22px;
}
.pf-contacts__name {
  font-family: var(--f-sans);
  font-weight: 600;
  font-size: 14px;
  color: var(--c-yellow);
  margin-bottom: 4px;
}
.pf-contacts__mail {
  font-family: var(--f-mono);
  font-size: 13px;
  color: rgba(255, 255, 255, 0.85);
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
  padding-bottom: 1px;
  transition: color 0.12s, border-color 0.12s;
  /* Long emails like miiro.saapunki@powerfestival.fi can overflow narrow
     columns on mobile — let them break anywhere to stay inside the card. */
  overflow-wrap: anywhere;
  word-break: break-word;
  display: inline-block;
  max-width: 100%;
}
.pf-contacts__mail:hover {
  color: var(--c-yellow);
  border-color: var(--c-yellow);
}

.pf-contacts__billing {
  margin-top: 56px;
  padding-top: 40px;
  border-top: 1px solid rgba(254, 204, 24, 0.20);
}
.pf-contacts__bill-title {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 22px;
  color: var(--c-yellow);
  margin: 0 0 24px;
}
.pf-contacts__bill-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
  max-width: 760px;
  margin: 0 auto;
}
.pf-contacts__bill-block {
  font-family: var(--f-sans);
  font-size: 14px;
  line-height: 1.8;
  color: rgba(255, 255, 255, 0.85);
}
.pf-contacts__bill-head {
  font-weight: 700;
  margin-bottom: 8px;
  color: var(--c-text);
}
.pf-contacts__bill-line {
  font-family: var(--f-mono);
  font-size: 13px;
  color: rgba(255, 255, 255, 0.78);
}

/* Cloudflare Turnstile widget — sits between the message field and the
   submit button. The wrapper provides spacing; the iframe inside handles
   its own theming via the data-theme="dark" attribute set in JS. */
.pf-form__turnstile {
  margin-top: 16px;
  min-height: 65px;
}

/* Form status message — shown below the submit button */
.pf-form__msg {
  margin-top: 14px;
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 13px;
  line-height: 1.5;
  text-align: center;
}
.pf-form__msg--ok {
  background: rgba(254, 204, 24, 0.18);
  color: var(--c-yellow);
  border: 1px solid rgba(254, 204, 24, 0.45);
}
.pf-form__msg--err {
  background: rgba(255, 90, 90, 0.15);
  color: #ffb3b3;
  border: 1px solid rgba(255, 90, 90, 0.4);
}

/* ─── Newsletter strip ───────────────────────── */

.pf-newsletter {
  padding: 56px 0;
  background: var(--c-bg);
  border-top: 1px solid var(--c-border);
}
.pf-newsletter__inner {
  display: grid; grid-template-columns: 1.3fr 1fr; gap: 36px; align-items: center;
}
.pf-newsletter h3 {
  font-family: var(--f-display); font-size: 36px; font-weight: 800;
  margin: 8px 0 0; letter-spacing: -1px; line-height: 1.05;
}
.pf-newsletter h3 em {
  font-family: var(--f-serif); font-style: italic; font-weight: 600; color: var(--c-yellow);
}
.pf-newsletter__form {
  display: flex; gap: 0;
  background: rgba(0,0,0,0.35); border-radius: 999px; padding: 6px;
  border: 1px solid rgba(254,204,24,0.20);
}
.pf-newsletter__form input {
  flex: 1; background: transparent; border: 0; outline: none;
  padding: 12px 18px; color: var(--c-text); font-size: 14px; font-family: var(--f-sans);
}
.pf-newsletter__form input::placeholder { color: rgba(255,255,255,0.45); }
.pf-newsletter__form button {
  background: var(--c-yellow); color: var(--c-purple); border: 0;
  padding: 12px 22px; border-radius: 999px; font-weight: 700; font-size: 14px; cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
/* Reverse the colour pairing on hover so yellow ↔ purple swap, matching
   the same pattern used on other branded CTAs in the site. */
.pf-newsletter__form button:hover {
  background: var(--c-purple);
  color: var(--c-yellow);
}
.pf-newsletter__note { font-family: var(--f-mono); font-size: 11px; color: var(--c-text-mute); margin-top: 10px; }

/* ─── Footer ───────────────────────── */

.pf-footer {
  /* Smooth bridge between the purple contact gradient above and the
     transparent top of the cloud-art band below. The bottom stop matches
     var(--c-bg) (#0B0518), which is what the page background composites
     against where the cloud PNG's top edge is transparent — no visible seam. */
  background: linear-gradient(180deg, var(--c-purple-deep) 0%, #0B0518 100%);
  color: var(--c-text);
  padding: 48px 0 28px;
  position: relative;
}
/* Soft purple ramp into the footer top — fades transparent → purple-deep
   over 120 px above the footer edge. On the one-pager this overlays the
   bottom of `.pf-contact` (already purple-deep) so it's a no-op visually,
   but on pages that don't have a contact section above the footer (e.g.
   tietosuoja, festivaalin ehdot, media, yhteistyökumppaniksi) the ramp
   blends the dark page bg into the purple footer so the join no longer
   reads as a hard horizontal seam. */
.pf-footer::before {
  content: "";
  position: absolute;
  top: -120px; left: 0; right: 0;
  height: 120px;
  background: linear-gradient(180deg, transparent 0%, var(--c-purple-deep) 100%);
  pointer-events: none;
}
/* Visible mailto links revealed by the JS swap on the tietosuoja page —
   gold underline, matches the page's brand colour palette. */
.pf-mail--linked {
  color: var(--c-yellow);
  border-bottom: 1px solid currentColor;
  padding-bottom: 1px;
}
.pf-mail--linked:hover { color: var(--c-yellow-deep); }

/* Media-kit download pill — reads as an actionable button inside the
   legal-body prose. Yellow surface for high contrast against the page bg,
   colour-inverts on hover like the rest of the site's brand CTAs. */
.pf-media-download {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--c-yellow);
  color: var(--c-purple);
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.4px;
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease, box-shadow 0.18s ease;
}
.pf-media-download:hover {
  background: var(--c-purple);
  color: var(--c-yellow);
  box-shadow: 0 0 0 1px var(--c-purple-light), 0 0 22px rgba(139, 61, 212, 0.4);
}
.pf-footer__grid {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 32px; margin-bottom: 32px;
}
.pf-footer__brand { flex: 0 0 auto; }
.pf-footer__brand img { height: 44px; display: block; }
/* Footer logo link gets the same purple-recolour-on-hover behaviour as the
   navbar logo, so both clickable Power-Festival marks behave identically. */
.pf-footer__brand-link {
  display: inline-block;
  text-decoration: none;
  line-height: 0;
}
.pf-footer__brand-link img {
  transition: filter 0.18s ease;
}
.pf-footer__brand-link:hover img {
  filter: brightness(0) saturate(100%) invert(15%) sepia(91%)
          saturate(4500%) hue-rotate(263deg) brightness(85%) contrast(115%);
}
.pf-footer__brand p {
  font-size: 13px; color: rgba(255,255,255,0.6); margin: 16px 0 0;
  max-width: 280px; line-height: 1.6;
}
.pf-footer__col h4 {
  font-family: var(--f-mono); font-size: 11px; color: var(--c-yellow);
  letter-spacing: 1px; margin: 0 0 14px; font-weight: 600;
}
/* Footer links: horizontal row on desktop, nav-style typography
   (Poppins / uppercase / letter-spaced). Mobile rule below resets to a
   vertical stack. */
.pf-footer__col {
  flex: 1 1 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 28px 36px;
  justify-content: flex-end;
  align-items: center;
}
.pf-footer__col a {
  display: inline-block;
  padding: 0;
  font-family: var(--f-display);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  opacity: 0.92;
  position: relative;
  transition: opacity 0.12s, color 0.12s;
}
/* Animated underline pseudo — same growing yellow underline the navbar
   links use. Width snaps in on hover, snaps out on leave. */
.pf-footer__col a::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: -6px;
  height: 2px;
  background: var(--c-yellow);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform 0.18s ease;
}
.pf-footer__col a:hover { opacity: 1; color: var(--c-yellow); }
.pf-footer__col a:hover::after { transform: scaleX(1); }
/* Alternating purple accent on every other link (Yhteistyökumppaniksi,
   Evästeasetukset) — mirrors the navbar's odd/even colour pattern. */
.pf-footer__col a:nth-child(even):hover { color: var(--c-purple-light); }
.pf-footer__col a:nth-child(even)::after { background: var(--c-purple-light); }

/* Footer app-store rows: official Apple + Google badges, unmodified.
   Stack vertically inside the column. Sized at 44 px (still above Apple's
   40-px floor; Google allows smaller in non-primary placements). */
.pf-footer__app {
  display: flex !important;
  margin-top: 12px !important;
  padding: 0 !important;
  opacity: 1 !important;
}
.pf-footer__app:hover {
  opacity: 1 !important;
}
.pf-footer__app + .pf-footer__app {
  margin-top: 8px !important;
}
.pf-footer__app.pf-store-badge--apple img,
.pf-footer__app.pf-store-badge--google img {
  height: 44px;
  margin: 0;
}
.pf-footer__bottom {
  display: flex; justify-content: space-between; align-items: center;
  border-top: 1px solid var(--c-border); padding-top: 18px;
  font-family: var(--f-mono); font-size: 11px; color: rgba(255,255,255,0.5);
  gap: 24px; flex-wrap: wrap;
}
.pf-footer__bottom .pf-tm-line img { opacity: 0.85; }

/* Brand-cloud art block at the very bottom of the page. Sits directly below
   the legal/footer line. Full viewport width; preserves the supplied PNG's
   aspect ratio — no cropping, no recolour, no overlay. Decorative only. */
.pf-footer__art {
  display: block;
  width: 100%;
  height: auto;
  margin: 0;
  padding: 0;
  pointer-events: none;
  user-select: none;
}

/* ─── Legal / Tietosuoja page ─────────── */

.pf-legal-hero {
  background: linear-gradient(180deg, var(--c-bg-alt) 0%, var(--c-bg) 100%);
  padding: 80px 0 56px;
  border-bottom: 1px solid var(--c-border);
}
.pf-legal-back {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--f-mono); font-size: 12px;
  color: var(--c-text-mute);
  padding: 6px 12px;
  border: 1px solid var(--c-border);
  border-radius: 999px;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.pf-legal-back:hover {
  color: var(--c-yellow); border-color: var(--c-yellow);
  background: rgba(254,204,24,0.06);
}
.pf-legal-title {
  font-family: var(--f-display);
  font-weight: 800; font-size: 80px; letter-spacing: -2.5px; line-height: 0.95;
  margin: 14px 0 0;
  /* Long Finnish compounds (e.g. "yhteistyökumppaniksi", 20 chars) overrun
     narrow phones at this font size. `hyphens: auto` + soft hyphens in the
     copy give the browser legal break points; `overflow-wrap: break-word`
     is the last-resort fallback so a word never reaches off-screen. */
  hyphens: auto;
  -webkit-hyphens: auto;
  overflow-wrap: break-word;
  word-break: break-word;
}
.pf-legal-title em {
  font-family: var(--f-serif); font-style: italic; font-weight: 600;
  color: var(--c-yellow);
}
.pf-legal-lead {
  font-size: 18px; line-height: 1.6;
  color: var(--c-text-mute);
  margin: 18px 0 0;
  max-width: 640px;
}
.pf-legal-meta {
  margin-top: 18px;
  font-family: var(--f-mono); font-size: 11px; color: var(--c-text-dim);
  letter-spacing: 0.6px;
}

/* Static-page time-sensitive status banner (e.g. "2026 partnerships sold
   out"). Full-width, centred, with a pulsing "!" icon so it reads as an
   unmissable live status notice rather than ordinary body copy. */
.pf-legal-banner {
  margin-top: 24px;
  display: flex; flex-direction: column; align-items: center; gap: 18px;
  padding: 32px 32px;
  border-radius: 18px;
  background: linear-gradient(135deg, rgba(254, 204, 24, 0.14) 0%, rgba(254, 204, 24, 0.05) 100%);
  border: 1px solid rgba(254, 204, 24, 0.45);
  box-shadow: 0 0 0 1px rgba(254, 204, 24, 0.08) inset,
              0 14px 36px -18px rgba(254, 204, 24, 0.45);
  text-align: center;
  width: 100%;
}
/* Pulsing "!" disc — animated ring expands outward every 1.8 s so the icon
   reads as a live indicator without the bouncing-dot feel. */
.pf-legal-banner__icon {
  flex: 0 0 auto;
  width: 48px; height: 48px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--c-yellow); color: var(--c-purple);
  font-family: var(--f-display); font-weight: 800; font-size: 30px;
  line-height: 1;
  box-shadow: 0 0 0 0 rgba(254, 204, 24, 0.55);
  animation: pf-legal-banner-pulse 1.8s ease-in-out infinite;
}
.pf-legal-banner__text {
  display: flex; flex-direction: column; gap: 6px;
  width: 100%;
}
.pf-legal-banner__eyebrow {
  font-family: var(--f-mono); font-size: 11px; letter-spacing: 1.6px;
  color: var(--c-yellow); text-transform: uppercase;
}
.pf-legal-banner__title {
  font-family: var(--f-display); font-weight: 800; font-size: 32px;
  letter-spacing: -0.6px; line-height: 1.1;
  color: var(--c-text);
}
.pf-legal-banner__body {
  font-size: 17px; color: var(--c-text-mute); line-height: 1.55;
  max-width: 640px; margin: 0 auto;
}
@keyframes pf-legal-banner-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(254, 204, 24, 0.55); }
  60%      { box-shadow: 0 0 0 16px rgba(254, 204, 24, 0); }
}
@media (max-width: 768px) {
  .pf-legal-banner { padding: 24px 20px; gap: 14px; }
  .pf-legal-banner__icon { width: 40px; height: 40px; font-size: 24px; }
  .pf-legal-banner__title { font-size: 26px; }
  .pf-legal-banner__body  { font-size: 15px; }
}
@media (prefers-reduced-motion: reduce) {
  .pf-legal-banner__icon { animation: none; }
}

.pf-legal { padding: 56px 0 96px; }
.pf-legal__inner {
  display: grid;
  grid-template-columns: 1fr;
  max-width: 820px;
  margin: 0 auto;
  padding: 0 40px;
}
.pf-legal__section {
  padding: 28px 0;
  border-bottom: 1px solid var(--c-border);
}
.pf-legal__section:last-child { border-bottom: 0; }
.pf-legal__section h2 {
  font-family: var(--f-display);
  font-weight: 700; font-size: 22px;
  letter-spacing: -0.3px; line-height: 1.2;
  margin: 0 0 14px;
  color: var(--c-text);
}
.pf-legal__body {
  font-size: 16px; line-height: 1.65;
  color: var(--c-text-mute);
}
.pf-legal__body p { margin: 0 0 12px; }
.pf-legal__body p:last-child { margin-bottom: 0; }
.pf-legal__body strong { color: var(--c-text); font-weight: 600; }
.pf-legal__body em {
  font-style: normal; font-weight: 500;
  color: var(--c-yellow);
  font-family: var(--f-mono);
  font-size: 0.94em;
}
.pf-legal__body ul {
  margin: 8px 0 12px;
  padding-left: 0;
  list-style: none;
}
.pf-legal__body li {
  position: relative;
  padding: 4px 0 4px 22px;
}
.pf-legal__body li::before {
  content: '→';
  position: absolute; left: 0; top: 4px;
  color: var(--c-yellow);
}

@media (max-width: 768px) {
  .pf-legal-hero { padding: 56px 0 40px; }
  .pf-legal-title { font-size: 48px; letter-spacing: -1.5px; }
  .pf-legal-lead { font-size: 16px; }
  .pf-legal__inner { padding: 0 20px; }
  .pf-legal__section h2 { font-size: 20px; }
  .pf-legal__body { font-size: 15px; }
}
/* Extra shrink for very narrow phones (small iPhones, folded layouts):
   48 px is still too big for 320-380 px viewports when the title
   contains a long compound word that's already hyphenated. Drops one
   more notch so the headline breathes. */
@media (max-width: 420px) {
  .pf-legal-title { font-size: 40px; letter-spacing: -1.2px; }
}

/* ─── Mobile / responsive ────────────────────────────── */

@media (max-width: 1024px) {
  .pf-container { padding-inline: 28px; }
  .pf-h2 { font-size: 48px; }
  .pf-hero__logo { height: 130px; }
  .pf-hero__tag { font-size: 28px; }
  .pf-countdown { gap: 20px; }
  .pf-countdown__cell .pf-countdown__v { font-size: 40px; }
  .pf-heads-grid { grid-template-columns: 1fr; }
  .pf-head-card__name { font-size: 44px; }
  .pf-lineup__grid > .pf-artist-card {
    /* 3-col tablet width. */
    flex: 0 0 calc((100% - 2 * 16px) / 3);
    max-width: calc((100% - 2 * 16px) / 3);
  }
  .pf-venue__grid,
  .pf-about__inner,
  .pf-contact__grid,
  .pf-newsletter__inner,
  .pf-social__cols { grid-template-columns: 1fr; gap: 32px; }
  .pf-venue__map { height: 360px; }
  .pf-tickets__grid { grid-template-columns: 1fr; }
  /* Footer is flex; nothing to do at tablet — links flow naturally. */
  /* Sponsors: 2 per row at tablet widths. flex-wrap + centre handles the
     short last row automatically (6 → 2+2+2, 5 → 2+2+1 centred). */
  .pf-sponsors__row > .pf-sponsor-card {
    flex: 0 0 calc((100% - 16px) / 2);
    max-width: calc((100% - 16px) / 2);
  }
  /* Tablet: 2 per row. flex-wrap + centre on the parent handles short last
     rows (e.g. 3 entries → 2+1 centred). */
  .pf-contacts__cell {
    flex: 0 0 calc((100% - 48px) / 2);
    max-width: calc((100% - 48px) / 2);
  }
}

@media (max-width: 768px) {
  :root { --nav-h: 60px; }
  .pf-container { padding-inline: 20px; }

  /* Nav: hide horizontal links + CTA, show burger.
     Lang switcher stays visible — slightly compacted so it fits beside
     the burger on a 360 px viewport without crowding. */
  .pf-nav__links { display: none; }
  .pf-nav__lang { display: none; }
  .pf-nav__cta { display: none; }
  .pf-burger { display: inline-flex; }
  .pf-nav__logo img { height: 32px; }
  .pf-nav__right { gap: 8px; }
  .pf-langs { padding: 3px; gap: 2px; }
  .pf-langs .pf-lang { width: 24px; height: 24px; font-size: 16px; }

  /* Hero */
  .pf-hero { min-height: 0; }
  .pf-hero__inner {
    min-height: calc(100vh - var(--nav-h));
    padding-block: 32px 32px;
  }
  .pf-hero__logo { height: 100px; }
  .pf-hero__tag { font-size: 22px; line-height: 1.2; }
  .pf-hero__sub { font-size: 15px; }
  .pf-hero__ctas { flex-direction: column; align-items: stretch; }
  .pf-hero__ctas .pf-btn { justify-content: center; }
  .pf-hero__date { text-align: left; }
  .pf-hero__bottom { flex-direction: column; align-items: flex-start; }
  .pf-countdown { gap: 18px; }
  .pf-countdown__cell .pf-countdown__v { font-size: 36px; letter-spacing: -1.2px; }

  /* Section headings */
  .pf-h2 { font-size: 38px; letter-spacing: -1.2px; }
  .pf-headliners, .pf-lineup, .pf-tickets, .pf-venue, .pf-about, .pf-contact, .pf-schedule, .pf-faq, .pf-sponsors, .pf-social { padding: 64px 0; }

  /* Headliners */
  .pf-heads-grid { gap: 16px; }
  .pf-head-card__name { font-size: 36px; }
  .pf-head-card__info { padding: 0 20px 20px; }

  /* Lineup */
  .pf-lineup__grid { gap: 12px; }
  .pf-lineup__grid > .pf-artist-card {
    /* 2-col mobile width. */
    flex: 0 0 calc((100% - 12px) / 2);
    max-width: calc((100% - 12px) / 2);
  }
  .pf-artist-card__name { font-size: 16px; }
  /* No orphan-centering rule needed — flex `justify-content: center` on the
     parent already centres any short last row automatically. */
  /* Filter chip row — let chips wrap naturally and centre the rows so a
     3+2 layout (e.g. day filters / stage filters) feels balanced rather
     than left-stuck with an orphan. */
  .pf-lineup__filters { justify-content: center; }
  .pf-lineup__more { flex-direction: column; align-items: stretch; }
  .pf-lineup__more .pf-btn { justify-content: center; }
  .pf-card-star { width: 26px; height: 26px; font-size: 13px; top: 8px; left: 8px; }

  /* Sponsors — 2 per row on mobile with slightly tighter gap. flex-wrap +
     centre on the parent already handles short last rows (the previous
     grid-based orphan rule is no longer needed). */
  .pf-sponsors__row { gap: 14px; }
  .pf-sponsors__row > .pf-sponsor-card {
    flex: 0 0 calc((100% - 14px) / 2);
    max-width: calc((100% - 14px) / 2);
    height: 120px;
    padding: 18px 22px;
  }
  .pf-sponsor-card__text { font-size: 20px; }

  /* Social & app store buttons */
  .pf-social__col { padding: 18px; }
  .pf-store-btn { min-width: 0; flex: 1 1 auto; padding: 10px 14px; }
  .pf-store-btn span { font-size: 13px; }
  .pf-social-btn { padding: 10px 14px; font-size: 13px; }

  /* FAQ */
  .pf-faq__q { font-size: 17px; padding: 18px 0; gap: 16px; }
  .pf-faq__chev { width: 28px; height: 28px; font-size: 16px; }
  .pf-faq__a { font-size: 15px; padding-bottom: 20px; }

  /* Schedule — desktop 3-col swap to mobile single-column list */
  .pf-schedule__cols--desktop { display: none; }
  .pf-schedule__list--mobile  { display: block; }
  .pf-schedule__day-head h3 { font-size: 24px; }

  /* Tickets */
  .pf-tier__price-v { font-size: 56px; }

  /* Venue */
  .pf-venue__title, .pf-about__title, .pf-contact__title { font-size: 36px; }

  /* Contact form */
  .pf-form { padding: 20px; }
  .pf-form__row { grid-template-columns: 1fr; }

  /* YHTEYSTIEDOT directory — single column on mobile so long names + emails
     stay inside the viewport. Each card stacks vertically. */
  .pf-contacts { margin-top: 40px; padding-top: 28px; }
  .pf-contacts__heading { font-size: 28px; margin-bottom: 24px; }
  /* Single column on mobile so the long Saapunki-family emails never
     wrap mid-domain. */
  .pf-contacts__cols { gap: 24px; }
  .pf-contacts__cell { flex: 0 0 100%; max-width: 100%; }
  .pf-contacts__bill-grid { grid-template-columns: 1fr; gap: 24px; }

  /* Newsletter */
  .pf-newsletter h3 { font-size: 26px; }
  .pf-newsletter__form { flex-direction: column; padding: 8px; border-radius: 16px; }
  .pf-newsletter__form input { padding: 14px; }
  .pf-newsletter__form button { padding: 14px; border-radius: 12px; }

  /* Footer */
  /* Mobile footer: brand on top, links stacked vertically below. */
  .pf-footer__grid { flex-direction: column; align-items: flex-start; gap: 24px; }
  .pf-footer__col {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 10px;
    width: 100%;
  }
  .pf-footer__col a { font-size: 14px; }
  .pf-footer__bottom { flex-direction: column; align-items: flex-start; gap: 12px; }
}

/* Reduce motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .pf-hero__video { display: none; }
  .pf-btn { transition: none; }
}

/* ─── Apple Music bottom-bar player ─────────────────
   Fixed strip pinned to the bottom of the viewport, slides up when an
   artist's ♪ is first clicked. Sits above page content but below the
   navbar (1100) and the drawer (1050) — pinned at 900 so the menu
   overlays the player if the user opens it while music is playing. */
.pf-player {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  /* Sit above Leaflet's .leaflet-top/.leaflet-bottom control containers
     (which include the attribution strip at z 1000) so the map can never
     poke through the player. Stays below the drawer (1050) and burger
     (1200) so the mobile menu still overlays it when opened. */
  z-index: 1010;
  /* Mirror the navbar's look: same translucent ink bg + blur so the player
     reads as a "bottom navbar". Top edge is a plain straight line — same
     yellow accent the navbar uses on its bottom chevron, but flat here. */
  background: rgba(11, 5, 24, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid rgba(254, 204, 24, 0.55);
  color: var(--c-text);
  animation: pf-player-in 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  /* Respect iOS safe-area so the bar clears the home-indicator strip. */
  padding-bottom: env(safe-area-inset-bottom, 0);
}
@keyframes pf-player-in {
  from { transform: translateY(100%); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}
.pf-player__inner {
  max-width: 1280px; margin: 0 auto;
  display: grid;
  /* art | text | apple-badge | play | scrub-bar | (auth) | close */
  grid-template-columns: 56px minmax(0, 1fr) auto auto 1fr auto auto;
  align-items: center;
  gap: 14px;
  padding: 10px 20px;
}
.pf-player__art {
  width: 56px; height: 56px; border-radius: 8px; object-fit: cover;
  background: rgba(255,255,255,0.08);
  display: block;
}
.pf-player__art--placeholder {
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--c-yellow); font-size: 24px;
}
.pf-player__text { min-width: 0; }
.pf-player__title {
  font-family: var(--f-display); font-weight: 700; font-size: 14px;
  line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pf-player__sub {
  font-family: var(--f-mono); font-size: 11px; color: rgba(255,255,255,0.7);
  margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pf-player__sep { opacity: 0.5; }
/* Official "Listen on Apple Music" lockup. Apple's identity guidelines
   require: ≥25 px height, ≥¼-height clear space around the badge (≥1/10 on
   mobile), no recolouring/animation/effects, must link to Apple Music. We
   ship the white-on-dark variant because the player bg is dark ink.
   On desktop the badge is its own grid cell to the right of the text; the
   14 px column gap satisfies the clear-space rule on the left, and the play
   button's own width + gap provides clear space on the right. */
.pf-player__apple {
  align-self: center;
  line-height: 0;
  border: 0;
  text-decoration: none;
  opacity: 0.95;
  transition: opacity 0.12s ease;
}
.pf-player__apple:hover { opacity: 1; }
.pf-player__apple-img {
  display: block;
  height: 25px;        /* Apple's stated minimum for digital lockups. */
  width: auto;
  /* Apple forbids any visual modification — no filter, no shadow, no tint. */
}
.pf-player__btn {
  background: transparent; border: 0; color: var(--c-text);
  cursor: pointer; padding: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: color 0.12s ease, background 0.12s ease;
}
.pf-player__btn:hover { color: var(--c-yellow); }
.pf-player__btn--play {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--c-yellow); color: var(--c-purple);
  transition: background 0.15s ease, color 0.15s ease;
}
/* Colour-invert on hover — yellow ↔ purple swap, matches the rest of the
   site's branded CTAs (hero buttons, newsletter Liity, media-kit pill). */
.pf-player__btn--play:hover { background: var(--c-purple); color: var(--c-yellow); }
.pf-player__btn--auth {
  font-family: var(--f-mono); font-size: 11px;
  letter-spacing: 0.4px;
  padding: 8px 14px; border-radius: 999px;
  border: 1px solid rgba(254, 204, 24, 0.5);
  color: var(--c-yellow);
}
.pf-player__btn--auth:hover {
  background: var(--c-yellow); color: var(--c-purple);
}
.pf-player__btn--close { opacity: 0.7; }
.pf-player__btn--close:hover { opacity: 1; }
.pf-player__bar {
  position: relative;
  height: 3px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.12);
  /* overflow stays visible so the head dot can sit slightly outside the
     track without being clipped. */
  /* Click/drag scrubbing: cursor + touch-action so touch drags scrub
     instead of scrolling the page. */
  cursor: pointer;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}
/* Invisible pad that expands the bar's hit area vertically. The visible
   track stays a thin 3 px line; this gives mouse + touch a much easier
   target (~24 px tall) without bloating the layout. */
.pf-player__bar::before {
  content: "";
  position: absolute;
  inset: -10px 0;
}
.pf-player__bar-fill {
  position: absolute; inset: 0 auto 0 0;
  background: var(--c-yellow);
  border-radius: 999px;
  transition: width 0.2s linear;
  pointer-events: none;
}
/* While the user is actively dragging, drop the smoothing transition so
   the fill snaps to the cursor in real time instead of easing toward it. */
.pf-player__bar--dragging .pf-player__bar-fill {
  transition: none;
}
/* Progress head dot — sits at the leading edge of the fill, common on
   most music players. Anchored to the right of the .pf-player__bar-fill
   element via a pseudo so it always tracks the same width animation. */
.pf-player__bar-fill::after {
  content: "";
  position: absolute;
  top: 50%; right: -5px;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--c-yellow);
  transform: translateY(-50%);
  box-shadow: 0 0 0 1px rgba(11, 5, 24, 0.55);
}
.pf-player__error {
  text-align: center;
  font-family: var(--f-mono); font-size: 11px;
  color: rgba(255, 200, 200, 0.9);
  padding: 4px 16px 8px;
}

@media (max-width: 768px) {
  .pf-player__inner {
    /* Drop the scrub bar + auth pill on phones — too cramped to fit beside
       the badge. The badge moves to its own row below the text; art / play /
       close span both rows so they stay vertically centred. */
    grid-template-columns: 44px minmax(0, 1fr) auto auto;
    grid-template-rows: auto auto;
    column-gap: 10px;
    row-gap: 0;
    padding: 8px 14px;
  }
  .pf-player__art {
    width: 44px; height: 44px;
    grid-row: 1 / span 2;
    align-self: center;
  }
  .pf-player__text { grid-column: 2; grid-row: 1; }
  .pf-player__title { font-size: 13px; }
  .pf-player__sub { font-size: 10px; }
  .pf-player__bar,
  .pf-player__btn--auth { display: none; }
  /* Badge falls below the text in the same column. 3 px top clear space ≈
     1/10 of 25 px, the tighter ratio Apple permits in restricted layouts. */
  .pf-player__apple {
    grid-column: 2;
    grid-row: 2;
    align-self: start;
    margin-top: 3px;
  }
  .pf-player__btn--play  { grid-column: 3; grid-row: 1 / span 2; align-self: center; }
  .pf-player__btn--close { grid-column: 4; grid-row: 1 / span 2; align-self: center; }
}

@media (prefers-reduced-motion: reduce) {
  .pf-player { animation: none; }
}
