/* ===========================================================================
   FLASHBANG EVENTS — shared stylesheet

   Loaded by every page (the site and the admin). Grammar: the aftermovie.
   Near-black base, off-white type, pure white only for flashes, one accent
   used sparingly, red for danger. Hard cuts, hairlines, zero radius.

   The accent (--acid, its old name kept) is the paper white since 2026-10-09:
   the site is black and white (the customer: "no yellow"). The admin's Teema
   page can give the whole site a colour, or let the next night's take over
   (js/site-theme.js); the admin itself keeps its yellow (admin.css).

   Homepage-only rules live in home.css.
   =========================================================================== */

:root{
  --black:  #0A0A0A;
  --char:   #111111;
  --paper:  #F2F1EC;
  --white:  #FFFFFF;   /* flash moments only */
  --acid:   #F2F1EC;   /* the accent: white on the black-and-white site */
  /* the events' names: the site's colour, lighter (Kevin, 2026-10-14) */
  --name-color: color-mix(in oklab, var(--acid) 80%, #FFFFFF);
  --danger: #FF2A2A;
  --onsale: #3DDC84;   /* "Myynnissä nyt": green on every night (2026-09-28) */
  --ash:    #8A8A83;
  --line:   rgba(255, 255, 255, .18);

  /* admin.css reads these names — kept as aliases so the tool keeps working */
  --bg: var(--black);
  --ink: var(--paper);
  --flash: var(--acid);
  --muted: var(--ash);
  --surface: var(--char);
  --pink: var(--danger);

  --font-display: 'League Gothic', 'Arial Narrow', Impact, sans-serif;
  --font-body: 'Archivo', system-ui, -apple-system, sans-serif;

  --gutter: clamp(20px, 4vw, 48px);
  --max: 1360px;
  --head: 84px;

  /* one easing for everything that moves: fast in, hard stop */
  --snap: cubic-bezier(.2, .9, .2, 1);
}

/* The accent is the one colour the site's theme changes (js/site-theme.js):
   registered as a colour, so a new colour fades in instead of jumping. */
@property --acid{ syntax: '<color>'; inherits: true; initial-value: #F2F1EC; }
:root{ transition: --acid .4s ease; }
/* a first visit, before the site's colour is known (the head script,
   js/site-theme.js): what wears the colour is not shown yet, then fades in
   in the right colour, never first in the default white (Kevin, 2026-10-16) */
html[data-theme-wait]{ --acid: transparent; }
html[data-theme-wait] .site-head__mark{ opacity: 0; }
.site-head__mark{ transition: opacity .4s ease; }
@media (prefers-reduced-motion: reduce){ :root{ transition: none; } }

*{ box-sizing: border-box; margin: 0; padding: 0; }
html{ scroll-behavior: smooth; background: var(--black); scrollbar-gutter: stable; }
/* anchor targets land below the fixed/sticky header instead of under it */
section[id], main[id], footer[id]{ scroll-margin-top: var(--head); }
/* clip, not hidden — hidden would turn html into a scroll container and
   silently break position:sticky on the header */
html, body{ overflow-x: hidden; overflow-x: clip; }

body{
  background: var(--black);
  color: var(--paper);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
img, svg, video{ display: block; max-width: 100%; }
a{ color: inherit; text-decoration: none; }
ul{ list-style: none; }
[hidden]{ display: none !important; }

a:focus-visible, button:focus-visible{
  outline: 3px solid var(--acid);
  outline-offset: 3px;
}
/* the menu moves focus itself; after a tap or click that shouldn't show a ring
   (js/nav.js marks how the visitor last interacted) */
html[data-input="pointer"] :is(.burger, .menu__close):focus-visible{ outline: none; }
/* keyboard users: straight to the content, past the header */
.skip{
  position: absolute; left: 12px; top: -80px; z-index: 100;
  padding: 12px 18px;
  background: var(--acid); color: var(--black);
  font-family: var(--font-body); font-weight: 700; font-size: 14px;
  border-radius: 999px;
}
.skip:focus{ top: 12px; }

/* --- type roles ------------------------------------------------------------ */
.display{
  font-family: var(--font-display);
  text-transform: uppercase;
  line-height: .8;
  font-weight: 400;
}
/* small, condensed, tracked — nav, metadata that must read as a unit */
.label{
  font-family: var(--font-body);
  font-weight: 600;
  font-stretch: 90%;
  font-size: 13px;
  letter-spacing: .08em;
  text-transform: uppercase;
  line-height: 1;
}

/* --- buttons ------------------------------------------------------------------
   .btn        small utility buttons (admin, event page)
   .cta        the ticket call to action, defined right after                  */
.btn{
  display: inline-block;
  padding: 15px 24px;
  font-family: var(--font-body);
  font-weight: 700;
  font-stretch: 90%;
  font-size: 13px;
  letter-spacing: .08em;
  text-transform: uppercase;
  line-height: 1;
  border: 2px solid transparent;
  cursor: pointer;
}
/* press feedback is a colour cut, never a size change: geometry that moves
   under the pointer can lose the click */
.btn:active{ filter: brightness(.85); }
.btn-primary{ background: var(--acid); color: var(--black); border-color: var(--acid); }
.btn-primary:hover{ background: var(--white); border-color: var(--white); }
.btn-outline{ background: transparent; color: var(--paper); border-color: var(--paper); }
.btn-outline:hover{ background: var(--paper); color: var(--black); }
button.btn{ font-family: var(--font-body); }

/* --- .cta: the ticket call to action. A pill, one size, three tones ----------------
   a.cta          real link (tickets on sale -> Kide.app)
   .cta--ghost    secondary: outline
   span.cta--status  a status, not a button: Liput tulossa / Loppuunmyyty / Peruttu */
.cta{
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 46px;
  padding: 0 26px;
  border-radius: 999px;
  font-family: var(--font-body); font-weight: 700; font-stretch: 96%;
  font-size: 14px; letter-spacing: .1em; text-transform: uppercase; line-height: 1;
  background: var(--acid); color: var(--black);
  border: 2px solid var(--acid);
  cursor: pointer; white-space: nowrap;
}
/* a button's hover is white; on the black-and-white site, whose buttons are
   white already, that would show nothing, so there it turns into its outline.
   A night's own coloured button keeps the white */
:root{ --hover-bg: var(--white); --hover-ink: var(--black); }
html:not([data-takeover]){ --hover-bg: transparent; --hover-ink: var(--paper); }
a.cta:hover{ background: var(--hover-bg); border-color: var(--white); color: var(--hover-ink); }
a.cta:active{ background: var(--paper); border-color: var(--paper); }
.cta--ghost{ background: transparent; color: var(--paper); border-color: var(--paper); }
a.cta--ghost:hover{ background: var(--paper); color: var(--black); border-color: var(--paper); }
.cta--status{ background: transparent; color: var(--ash); border-color: var(--ash); cursor: default; }
.cta--status.cta--soon{ border-style: dashed; }
.cta--danger{ color: var(--danger); border-color: var(--danger); }
button.cta{ font-family: var(--font-body); }

/* ===========================================================================
   HEADER — a solid bar: logo · Liput · menu button. The menu is a panel that
   slides in from the right.
   =========================================================================== */
.site-head{
  position: sticky; top: 0; z-index: 50;
  background: var(--black);
  border-bottom: 1px solid var(--line);
  transition: transform .28s var(--snap);
}
/* js/nav.js: slides away on scroll down, back on scroll up */
.site-head.is-hidden{ transform: translateY(-100%); }
.site-head__inner{
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 var(--gutter);
  height: var(--head);
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
/* the mark leads, the words follow smaller — the logo reads as a symbol first */
.site-head__logo{ display: inline-flex; align-items: center; gap: 10px; padding: 8px 0; margin: -8px 0; }
.site-head__mark{ height: 62px; width: auto; }
/* FLASHBANG with EVENTS stacked under it, the way the logo itself is drawn:
   white mark, acid name, white EVENTS */
.site-head__name{
  display: flex; flex-direction: column;
  font-family: var(--font-body); font-weight: 900; font-stretch: 104%;
  line-height: 1; letter-spacing: -.02em;
  text-transform: uppercase;
}
/* --logo-accent: the logo's own shade (Logon sävy) while a night is next, else the accent */
.site-head__name b{ font-size: 22px; font-weight: 900; color: var(--logo-accent, var(--acid)); }
.site-head__name small{ font-size: 11px; font-weight: 800; letter-spacing: .2em; margin-top: 4px; color: var(--white); }
/* the name stays acid on hover — the brand is not a state */
.site-head__actions{ display: flex; align-items: center; gap: 8px; }
.cta--head{ min-height: 48px; padding: 0 26px; font-size: 15px; color: var(--acid); border-color: var(--acid); }
/* Under an event takeover the F6 mark takes the night's colour too, the same
   shade as FLASHBANG and the LIPUT pill beside it (Kevin, 2026-09-25). The
   white picture steps aside and its shape holds the colour. With no themed
   night the mark stays white. */
html[data-takeover] .site-head__mark{
  object-position: -9999px 0;
  background: var(--logo-accent, var(--acid));
  -webkit-mask: url(/photos/mark-white.webp) center / contain no-repeat;
  mask: url(/photos/mark-white.webp) center / contain no-repeat;
}
a.cta--head:hover{ background: var(--acid); color: var(--black); border-color: var(--acid); }

.burger{
  width: 48px; height: 48px;
  display: grid; place-content: center; gap: 5px;
  background: none; border: 0; cursor: pointer;
  color: var(--paper);
}
/* three bars of one thickness: js/nav.js rounds --bar to whole screen pixels,
   so a zoomed page can't draw one thicker than the others */
.burger i{ display: block; width: 32px; height: var(--bar, 4px); background: currentColor; }
.burger:hover{ color: var(--acid); }

/* --- the menu: a floating card that drops from the menu button, the same on
   every screen. Its close button lands where the menu button was. ------------ */
.menu{
  position: fixed; z-index: 60;
  top: 12px; right: max(12px, calc((100% - var(--max)) / 2 + var(--gutter) - 12px));
  width: min(400px, calc(100% - 24px)); max-height: calc(100% - 24px);
  overflow-y: auto;
  display: flex; flex-direction: column;
  padding: 10px 16px 28px;
  background: var(--char); color: var(--paper);
  border: 1px solid var(--line); border-radius: 20px;
  /* it grows out of the spot where the menu button is (its own close button) */
  transform-origin: calc(100% - 38px) 32px;
  transform: translateY(-8px) scale(.94); opacity: 0; visibility: hidden;
  /* closing: quick and all at once */
  transition: transform .18s cubic-bezier(.4, 0, 1, 1), opacity .16s ease-in, visibility 0s linear .18s;
}
/* opening: a smooth arrival that settles, never a jump */
.menu.is-open{
  transform: none; opacity: 1; visibility: visible;
  transition: transform .38s cubic-bezier(.16, 1, .3, 1), opacity .22s ease-out, visibility 0s;
}
/* the links and socials follow the card in, one after another */
.menu__links > *, .menu__foot{
  opacity: 0; transform: translateY(10px);
  transition: opacity .12s ease-in, transform .12s ease-in;
}
.menu.is-open .menu__links > *, .menu.is-open .menu__foot{
  opacity: 1; transform: none;
  transition: opacity .3s ease-out, transform .45s cubic-bezier(.16, 1, .3, 1);
}
.menu.is-open .menu__links > :nth-child(1){ transition-delay: .06s; }
.menu.is-open .menu__links > :nth-child(2){ transition-delay: .09s; }
.menu.is-open .menu__links > :nth-child(3){ transition-delay: .12s; }
.menu.is-open .menu__links > :nth-child(4){ transition-delay: .15s; }
.menu.is-open .menu__links > :nth-child(5){ transition-delay: .18s; }
.menu.is-open .menu__links > :nth-child(6){ transition-delay: .21s; }
.menu.is-open .menu__foot{ transition-delay: .25s; }
/* quiet visitors: the card simply fades in and out; nothing moves */
html.m-quiet .menu, html.m-quiet .menu.is-open{ transform: none; }
html.m-quiet .menu{ transition: opacity .16s ease-in, visibility 0s linear .16s; }
html.m-quiet .menu.is-open{ transition: opacity .2s ease-out, visibility 0s; }
html.m-quiet .menu :is(.menu__links > *, .menu__foot){ opacity: 1; transform: none; transition: none; }
/* a real button shape, so its focus ring reads as designed, not as a stray box */
.menu__close{
  align-self: flex-end;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  background: none; cursor: pointer; color: var(--paper);
  border: 1px solid var(--line); border-radius: 50%;
}
.menu__close:hover{ color: var(--acid); border-color: currentColor; }
.menu__links{
  display: flex; flex-direction: column; align-items: center;
  padding: 12px 0 26px; gap: 2px;
}
.menu__link{
  padding: 8px 8px 5px;
  font-family: var(--font-display); text-transform: uppercase;
  font-size: 42px; line-height: 1;
  color: var(--paper);
  border-bottom: 5px solid transparent;
}
.menu__link:hover{ color: var(--acid); }
.menu__link[aria-current="page"]{ border-bottom-color: var(--acid); }
.menu__foot{ display: flex; justify-content: center; gap: 8px; }

/* social icons: one shape, white, acid when touched; 44px targets */
.social{
  width: 44px; height: 44px;
  display: inline-grid; place-items: center;
  color: var(--paper); border-radius: 50%;
}
.social svg{ width: 24px; height: 24px; fill: currentColor; }
.social:hover{ color: var(--acid); }
/* the footer's stay white under the mouse (Kevin); a keyboard still gets the focus ring */
.foot .social:hover{ color: var(--paper); }
/* dims the page under an open menu; a click on it closes the menu */
.menu-backdrop{
  position: fixed; inset: 0; z-index: 55;
  background: rgba(10,10,10,.6);
  opacity: 0; visibility: hidden;
  transition: opacity .18s ease-in, visibility 0s linear .18s;
}
/* a fade, for every visitor */
.menu-backdrop.is-open{ opacity: 1; visibility: visible; transition: opacity .3s ease-out, visibility 0s; }
/* a link in the menu was followed: it closes at once, not with an animation
   the next page would cut off halfway (js/nav.js) */
.menu.is-leaving, .menu.is-leaving *, .menu-backdrop.is-leaving{ transition: none !important; }
html.menu-open, html.menu-open body{ overflow: hidden; }

/* ===========================================================================
   TICKET STATES + AGE CHIP (event page rows and the homepage rows)
   =========================================================================== */
.age, .theme-tag{
  display: inline-block;
  font-family: var(--font-body); font-weight: 700; font-stretch: 88%;
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  padding: 5px 8px 4px;
  border: 2px solid var(--paper);
  line-height: 1;
}
.age--all{ border-color: var(--acid); color: var(--acid); }
/* a night whose limit changes has a badge per part with its times: each stays one piece */
.age{ white-space: nowrap; }

/* --- event themes ------------------------------------------------------------
   One colour per theme; js/themes.js names them (`base` there is the same
   colour). --theme colours the show's name and its tag, never the dates or
   the countdown. When the admin picks a colour for the night ("Oma väri"), it
   arrives inline as --theme-color and takes the theme's place. Red stays out
   of the themes on purpose: on this site red means sold out or last tickets.
   On the page every colour is drawn as soft tones of itself (below). */
html[data-logo-theme="halloween"] :is(.site-head__logo, .foot__mark), [data-theme="halloween"]  { --theme: var(--theme-color, #FF6B1A); --theme-2: #7B2CFF; }
html[data-logo-theme="pikkujoulut"] :is(.site-head__logo, .foot__mark), [data-theme="pikkujoulut"]{ --theme: var(--theme-color, #9FD8FF); --theme-2: #FFFFFF; }
html[data-logo-theme="uusivuosi"] :is(.site-head__logo, .foot__mark), [data-theme="uusivuosi"]  { --theme: var(--theme-color, #F4C95D); --theme-2: #FFFFFF; }
html[data-logo-theme="vappu"] :is(.site-head__logo, .foot__mark), [data-theme="vappu"]      { --theme: var(--theme-color, #FF4FA3); --theme-2: #FFFFFF; }
html[data-logo-theme="kesa"] :is(.site-head__logo, .foot__mark), [data-theme="kesa"]       { --theme: var(--theme-color, #2EE6C8); --theme-2: #FF8FA3; }
/* the same box as the age limit, in the site's one colour (Kevin, 2026-10-10) */
.theme-tag{ border-color: var(--acid); color: var(--acid); }

/* Dates never take a theme's colour: they are acid on every night (Kevin,
   2026-09-24: "make it acid yellow so it's more professional"); the theme
   colours the name and the tag only. */
html[data-logo-theme] :is(.site-head__logo, .foot__mark), [data-theme]{
  /* a listed theme in the admin's colour: the light and dark steps of its
     fill are drawn from that colour, so the pattern stays and the colour
     changes. Without one, --theme-color is unset, these steps are unset
     with it, and each theme's fill keeps its own hand-picked steps. */
  --own-pale: color-mix(in srgb, var(--theme-color) 12%, #FFFFFF);
  --own-light: color-mix(in srgb, var(--theme-color) 50%, #FFFFFF);
  --own-mid: var(--theme-color);
  --own-soft: color-mix(in srgb, var(--theme-color) 90%, #000000);
  --own-deep: color-mix(in srgb, var(--theme-color) 72%, #000000);
}
/* Soft tones, not full strength (Kevin, 2026-09-25: a red or green name "looks
   very bad"). The footage is almost black and white and the date, clock and
   ticket button under the name are acid, so a full-strength hue on the name
   looks pasted on and fights the acid. Dark interfaces use light, soft tonal
   variants of a colour instead, so every theme's colour, and any colour the
   admin picks, is drawn here as tones of itself: high lightness, the strength
   of the colour capped (OKLCH). The hue stays, so the night still reads as
   its theme, and no pick can spoil the page. Browsers without relative
   colours keep the hand-picked steps in each theme's fill. */
@supports (color: oklch(from red l c h)){
  /* the admin's shade (Ulkoasu → Sävy, 2026-09-28): each step a little darker
     and a little stronger; 0, the default, is the soft look above */
  html[data-logo-theme] :is(.site-head__logo, .foot__mark), [data-theme]{
    --tn-l: calc(var(--tone, 0) * 0.045);
    --tn-c: calc(1 + var(--tone, 0) * 0.45);
    --tn-pale:  oklch(from var(--theme) calc(0.97 - var(--tn-l)) min(calc(c * 0.15 * var(--tn-c)), c) h);
    --tn-light: oklch(from var(--theme) calc(0.93 - var(--tn-l)) min(calc(c * 0.4 * var(--tn-c)), calc(0.07 * var(--tn-c)), c) h);
    --tn-mid:   oklch(from var(--theme) calc(0.86 - var(--tn-l)) min(calc(c * 0.65 * var(--tn-c)), calc(0.11 * var(--tn-c)), c) h);
    --tn-deep:  oklch(from var(--theme) calc(0.77 - var(--tn-l)) min(calc(c * 0.75 * var(--tn-c)), calc(0.13 * var(--tn-c)), c) h);
    --own-pale: var(--tn-pale);
    --own-light: var(--tn-light);
    --own-mid: var(--tn-mid);
    --own-soft: var(--tn-mid);
    --own-deep: var(--tn-deep);
  }
  html[data-logo-theme="kesa"] :is(.site-head__logo, .foot__mark), [data-theme="kesa"]{ --kesa-sun: oklch(0.9 0.07 62); }
}

/* --- themed title --------------------------------------------------------------
   On a themed night the show's name becomes a window: the letterforms stay
   crisp and the theme moves inside them. Each theme sets its fill here; one
   rule below applies it wherever the show's name appears (homepage hero, the
   rows under it and on the events page, the event page, the admin preview).
   Past rows keep the colours but stand still, and so does everything for
   quiet visitors, so the theme never depends on motion. Sizes are in em, so every pattern scales with
   the type. The per-line gradient height matches the names' .92 line-height,
   loose enough that the dots of Ä and Ö never touch the line above. */
html[data-logo-theme="halloween"] :is(.site-head__logo, .foot__mark), [data-theme="halloween"]{
  /* flames rising through the letters */
  --theme-fill: linear-gradient(to top, var(--own-deep, #E0401A) 0%, var(--own-mid, #FF7A1F) 34%, var(--own-light, #FFC266) 66%, var(--own-pale, #FFF6E5) 100%);
  --title-fill: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='110' height='220'%3E%3Cfilter id='n' x='0' y='0'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.04 .011' numOctaves='3' seed='4' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 -1.8 1'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url%28%23n%29'/%3E%3C/svg%3E"),
    var(--theme-fill);
  --title-size: 2.2em 4.4em, 100% .92em;
  --title-move: title-flames 3.4s linear infinite;
}
html[data-logo-theme="uusivuosi"] :is(.site-head__logo, .foot__mark), [data-theme="uusivuosi"]{
  /* gold foil, champagne bubbles rising, a glint of light every few seconds */
  --theme-fill: linear-gradient(to bottom, var(--own-pale, #FFF1C4) 0%, var(--own-mid, #F4C95D) 45%, var(--own-deep, #C8962E) 80%, var(--own-soft, #E8B84A) 100%);
  --title-fill: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Cg fill='white'%3E%3Ccircle cx='89.1' cy='91.3' r='2.8' opacity='0.63'/%3E%3Ccircle cx='58.5' cy='43.0' r='2.2' opacity='0.65'/%3E%3Ccircle cx='21.7' cy='44.9' r='1.6' opacity='0.78'/%3E%3Ccircle cx='6.3' cy='11.9' r='2.5' opacity='0.77'/%3E%3Ccircle cx='51.2' cy='71.5' r='1.8' opacity='0.62'/%3E%3Ccircle cx='76.0' cy='58.2' r='2.4' opacity='0.85'/%3E%3Ccircle cx='93.3' cy='37.4' r='2.6' opacity='0.75'/%3E%3Ccircle cx='56.6' cy='64.8' r='1.8' opacity='0.63'/%3E%3Ccircle cx='47.6' cy='70.0' r='2.3' opacity='0.78'/%3E%3Ccircle cx='63.1' cy='20.7' r='1.5' opacity='0.73'/%3E%3Ccircle cx='79.1' cy='22.0' r='1.4' opacity='0.64'/%3E%3Ccircle cx='7.6' cy='29.4' r='2.2' opacity='0.93'/%3E%3C/g%3E%3C/svg%3E"),
    linear-gradient(105deg, transparent 44%, rgb(255 255 255 / .95) 50%, transparent 56%),
    var(--theme-fill);
  --title-size: 1.5em 1.5em, 280% 100%, 100% .92em;
  --title-move: title-champagne 5s linear infinite;
}
html[data-logo-theme="pikkujoulut"] :is(.site-head__logo, .foot__mark), [data-theme="pikkujoulut"]{
  /* frost, with snow falling inside the letters */
  --theme-fill: linear-gradient(to bottom, var(--own-pale, #F4FBFF) 0%, var(--own-mid, #A8DCFF) 50%, var(--own-deep, #5AA9E6) 100%);
  --title-fill: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Cg fill='white'%3E%3Ccircle cx='45.6' cy='55.5' r='3.2' opacity='0.76'/%3E%3Ccircle cx='50.7' cy='58.0' r='1.8' opacity='0.78'/%3E%3Ccircle cx='61.9' cy='77.0' r='1.6' opacity='0.69'/%3E%3Ccircle cx='12.3' cy='78.5' r='2.8' opacity='0.57'/%3E%3Ccircle cx='94.4' cy='92.8' r='2.7' opacity='0.83'/%3E%3Ccircle cx='18.5' cy='5.4' r='2.5' opacity='0.58'/%3E%3Ccircle cx='21.5' cy='26.3' r='1.5' opacity='0.76'/%3E%3Ccircle cx='44.5' cy='81.5' r='2.4' opacity='0.84'/%3E%3Ccircle cx='50.0' cy='64.9' r='2.3' opacity='0.68'/%3E%3Ccircle cx='95.8' cy='95.6' r='3.1' opacity='0.87'/%3E%3Ccircle cx='33.0' cy='25.1' r='2.0' opacity='0.58'/%3E%3Ccircle cx='74.5' cy='40.8' r='3.1' opacity='0.72'/%3E%3Ccircle cx='92.1' cy='82.0' r='1.4' opacity='0.64'/%3E%3Ccircle cx='87.7' cy='47.2' r='3.4' opacity='0.73'/%3E%3C/g%3E%3C/svg%3E"),
    var(--theme-fill);
  --title-size: 1.6em 1.6em, 100% .92em;
  --title-move: title-snow 9s linear infinite;
}
html[data-logo-theme="vappu"] :is(.site-head__logo, .foot__mark), [data-theme="vappu"]{
  /* serpentine streamers flowing through: the theme's colour and white */
  --theme-fill: linear-gradient(115deg, var(--own-mid, var(--theme)), var(--own-pale, #FFFFFF) 25%, var(--own-mid, var(--theme)) 50%, var(--own-pale, #FFFFFF) 75%, var(--own-mid, var(--theme)));
  --title-fill: var(--theme-fill);
  --title-size: 3em 100%;
  --title-move: title-streamers 6s linear infinite;
}
html[data-logo-theme="kesa"] :is(.site-head__logo, .foot__mark), [data-theme="kesa"]{
  /* a summer evening drifting slowly across: the sea and the sun */
  --theme-fill: linear-gradient(100deg, var(--own-mid, var(--theme)), var(--kesa-sun, #FFC98A) 50%, var(--own-mid, var(--theme)));
  --title-fill: var(--theme-fill);
  --title-size: 4em 100%;
  --title-move: title-sunset 10s linear infinite;
}
html[data-logo-theme="vari"] :is(.site-head__logo, .foot__mark), [data-theme="vari"]{
  /* the admin's own colour ("Oma väri", arriving inline as --theme-color),
     as foil: light above, deep below, a glint of light passing */
  --theme: var(--theme-color, #E8FF2E);
  --theme-2: color-mix(in srgb, var(--theme-color, #E8FF2E) 45%, #FFFFFF);
  --theme-fill: linear-gradient(to bottom, var(--own-light) 0%, var(--own-mid) 55%, var(--own-deep) 100%);
  --title-fill: linear-gradient(105deg, transparent 44%, rgb(255 255 255 / .9) 50%, transparent 56%), var(--theme-fill);
  --title-size: 280% 100%, 100% .92em;
  --title-move: title-glint 5s linear infinite;
}
.admin-preview[data-theme] .admin-preview__title{
  background-image: var(--title-fill);
  background-size: var(--title-size);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  /* a tight dark edge keeps the name readable over a bright frame. No
     coloured glow: it bled into the footage and read as cheap neon */
  filter: drop-shadow(0 0 .045em rgb(10 10 10 / .75));
}
/* The theme moves inside the name on every device, the way the hero video
   always plays: it is the night's look, and the customer wants it on (Kevin,
   2026-09-24: "the animation on the themes doesn't work" — his computer asks
   for less motion, which had stopped it). It is a slow drift of the pattern
   inside the letters; nothing on the page changes place. Past nights stay still. */
.admin-preview[data-theme] .admin-preview__title{
  animation: var(--title-move);
}
/* --- the header logo in the night's gradient (option 3) --------------------------
   Per night the admin chooses how the F6 mark and FLASHBANG look while the
   night is next: the same shade as LIPUT (the default, above with .cta--head)
   or the theme's gradient (Kevin, 2026-09-25). The choice arrives with the
   takeover as <html data-logo-theme> (and the admin's colour as
   --logo-theme-color): js/site-theme.js and each page's head script. The plain
   fill, without the names' texture and motion, which are noise at this size,
   and a little darker than the names' soft tones ("a little bit darker, not
   too much"). EVENTS stays white. The footer's giant FLASHBANG follows the
   header: the same shade, or the same gradient (Kevin, 2026-09-26: "if its
   low shade this is low shade too"). */
html[data-logo-theme] :is(.site-head__logo, .foot__mark){ --theme-color: var(--logo-theme-color); }
html[data-takeover][data-logo-theme] :is(.site-head__name b, .foot__mark){
  background-image: var(--theme-fill);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
html[data-takeover][data-logo-theme] .site-head__mark{ background: var(--theme-fill); }
@supports (color: oklch(from red l c h)){
  html[data-takeover][data-logo-theme] :is(.site-head__logo, .foot__mark){
    --tone: var(--logo-tone, 0);
    --tn-pale:  oklch(from var(--theme) calc(0.91 - var(--tn-l)) min(calc(c * 0.3 * var(--tn-c)), c) h);
    --tn-light: oklch(from var(--theme) calc(0.86 - var(--tn-l)) min(calc(c * 0.5 * var(--tn-c)), calc(0.09 * var(--tn-c)), c) h);
    --tn-mid:   oklch(from var(--theme) calc(0.79 - var(--tn-l)) min(calc(c * 0.7 * var(--tn-c)), calc(0.13 * var(--tn-c)), c) h);
    --tn-deep:  oklch(from var(--theme) calc(0.70 - var(--tn-l)) min(calc(c * 0.8 * var(--tn-c)), calc(0.15 * var(--tn-c)), c) h);
    --kesa-sun: oklch(0.84 0.09 62);
  }
}

/* each loop moves a pattern exactly one tile, so it never jumps */
@keyframes title-flames{ to{ background-position: 0 -4.4em, 0 0; } }
@keyframes title-champagne{
  0%  { background-position: 0 0, 100% 0, 0 0; }
  24% { background-position: 0 -.36em, 0% 0, 0 0; }
  100%{ background-position: 0 -1.5em, 0% 0, 0 0; }
}
@keyframes title-snow{ to{ background-position: 1.6em 1.6em, 0 0; } }
@keyframes title-streamers{ to{ background-position: 3em 0; } }
@keyframes title-sunset{ to{ background-position: 4em 0; } }
@keyframes title-glint{
  0%  { background-position: 100% 0, 0 0; }
  24% { background-position: 0% 0, 0 0; }
  100%{ background-position: 0% 0, 0 0; }
}

/* ===========================================================================
   INNER PAGES — events, about, contact
   =========================================================================== */
.page{
  max-width: var(--max); margin: 0 auto;
  padding: clamp(40px, 6vh, 64px) var(--gutter) clamp(56px, 8vh, 96px);
}
/* narrow pages keep the header's left edge; only their text column narrows */
.page__title{
  font-family: var(--font-display); text-transform: uppercase;
  font-size: clamp(3rem, 2rem + 4vw, 5.5rem); line-height: .85;
  margin-bottom: 28px;
}
/* a closing line under a page's own content */
.page__more{ margin-top: 24px; }
.page__intro{ margin: -14px 0 32px; max-width: 60ch; font-size: 17px; line-height: 1.55; color: var(--ash); }
/* the 404 page: where to go instead */
.lost__ways{ display: flex; flex-wrap: wrap; gap: 12px; }

/* ===========================================================================
   EVENTS PAGE — every coming night as the same big card (styles.css "/events:
   THE NEXT NIGHT, BIG"; Kevin, 2026-10-12), the next one under its own
   heading, the rest under Muut tulevat tapahtumat
   =========================================================================== */
.events .page__title{ margin-bottom: clamp(20px, 3vh, 32px); }
.nights{ display: grid; gap: clamp(16px, 2.4vh, 24px); }

/* ===========================================================================
   PAST NIGHTS (/menneet, 2026-10-09) — a wall of flyers, after
   thedayevents.fi: each flyer whole in the same 4:5 frame (a blurred copy of
   it fills the rest), the date and the name under it, what the night's page
   holds besides (Aftermovie, 48 kuvaa). Each card is one link to that page
   (2026-10-14). Two a row on a phone, three, then four
   =========================================================================== */
.flyers{
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 14px;
  margin: 8px 0 0; padding: 0; list-style: none;
}
/* while the nights load, room for them, so the footer does not jump down (2026-10-15) */
.flyers[aria-busy="true"]{ min-height: 100vh; }
.flyer{ min-width: 0; }
.flyer__card{ display: flex; flex-direction: column; gap: 6px; color: inherit; text-decoration: none; }
.flyer__frame{
  position: relative; display: block; width: 100%; aspect-ratio: 4 / 5;
  margin-bottom: 6px; overflow: hidden; isolation: isolate;
  background: var(--char);
}
.flyer__frame::before{
  content: ''; position: absolute; inset: -12%; z-index: -1;
  background: var(--photo, none) center / cover no-repeat;
  filter: blur(22px) brightness(.42);
}
.flyer__frame img{ display: block; width: 100%; height: 100%; object-fit: contain; transition: transform .3s var(--snap); }
a.flyer__card:hover .flyer__frame img{ transform: scale(1.025); }
a.flyer__card:hover .flyer__name{ color: var(--acid); }
.flyer__card:focus-visible{ outline: none; }
.flyer__card:focus-visible .flyer__frame{ outline: 3px solid var(--acid); outline-offset: 3px; }
/* no flyer: the mark, faint, instead of a hole */
.flyer__frame--empty{ display: grid; place-items: center; }
.flyer__frame--empty::after{
  content: ''; width: 34%; aspect-ratio: 454 / 288; opacity: .12;
  background: url('/photos/mark-white.webp') center / contain no-repeat;
}
.flyer__date{
  font-family: var(--font-display); font-size: 1.25rem; line-height: 1; letter-spacing: .02em;
  color: var(--paper);   /* dates white on every list (Kevin, 2026-10-10) */
}
.flyer__name{
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(1.25rem, 1rem + .9vw, 1.75rem); line-height: .95; overflow-wrap: anywhere;
  transition: color .2s;
}
/* what the night's page holds besides the flyer */
.flyer__has{ display: flex; flex-wrap: wrap; gap: 2px 14px; margin-top: 2px; font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--acid); }
.past__empty{ padding: 40px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); color: #CFCEC8; }
@media (min-width: 700px){ .flyers{ grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 40px 20px; } }
@media (min-width: 1100px){ .flyers{ grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 48px 24px; } }

/* ===========================================================================
   A PAST NIGHT (/menneet/<slug>, ilta.html, Kevin 2026-10-14: FOMO and the
   past nights are one thing now). "Aftermovie first": the video big across
   the top, a picture with a play button until pressed (edge to edge on a
   phone); then the name, date and place with the flyer small beside them and
   how many photos; then the photos in rows of one height, each at its own
   shape, nothing cropped. Without a video the flyer is the top: whole and
   big, the words beside it on a computer, under it on a phone.
   =========================================================================== */
.night{ display: grid; gap: clamp(22px, 3.2vw, 40px); }
.night.is-loading{ min-height: 70vh; visibility: hidden; }

.film{ position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: var(--black); }
.film__play{ position: absolute; inset: 0; display: block; width: 100%; height: 100%; padding: 0; border: 0; background: none; cursor: pointer; }
.film__still{ display: block; width: 100%; height: 100%; object-fit: cover; filter: brightness(.78); transition: filter .3s var(--snap); }
.film__play:hover .film__still{ filter: brightness(.92); }
.film__icon{
  position: absolute; left: 50%; top: 50%; translate: -50% -50%;
  display: grid; place-items: center; width: clamp(64px, 7vw, 96px); aspect-ratio: 1;
  border-radius: 50%; background: var(--acid); color: var(--black);
  transition: transform .25s var(--snap), background-color .2s;
}
.film__icon svg{ width: 40%; height: 40%; margin-left: 6%; }
.film__play:hover .film__icon{ transform: scale(1.06); background-color: var(--paper); }
.film__play:focus-visible{ outline: 3px solid var(--acid); outline-offset: -3px; }
.film__label{
  position: absolute; left: clamp(14px, 2vw, 28px); bottom: clamp(12px, 1.8vw, 24px);
  font-family: var(--font-display); text-transform: uppercase; letter-spacing: .02em;
  font-size: clamp(1.3rem, .9rem + 1.3vw, 2.2rem); line-height: .9;
  color: var(--paper); text-shadow: 0 2px 16px rgb(0 0 0 / .7);
}
.film iframe{ position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.night__head{ display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: end; gap: clamp(14px, 2.4vw, 32px); }
.night__poster:empty{ display: none; }
.night__flyer{
  position: relative; display: block; width: clamp(92px, 11vw, 156px); aspect-ratio: 4 / 5;
  padding: 0; border: 0; overflow: hidden; isolation: isolate; background: var(--char); cursor: zoom-in;
}
.night__flyer::before{
  content: ''; position: absolute; inset: -12%; z-index: -1;
  background: var(--photo, none) center / cover no-repeat; filter: blur(22px) brightness(.42);
}
.night__flyer img{ display: block; width: 100%; height: 100%; object-fit: contain; transition: transform .3s var(--snap); }
.night__flyer:hover img{ transform: scale(1.03); }
.night__flyer:focus-visible{ outline: 3px solid var(--acid); outline-offset: 3px; }
.night__flyer--empty{ display: grid; place-items: center; cursor: default; }
.night__flyer--empty::after{
  content: ''; width: 40%; aspect-ratio: 454 / 288; opacity: .12;
  background: url('/photos/mark-white.webp') center / contain no-repeat;
}
.night__title{
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(2.5rem, 1.5rem + 4vw, 6rem); line-height: .86; overflow-wrap: anywhere;
}
.night__when{
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px clamp(14px, 1.6vw, 24px);
  margin-top: clamp(10px, 1.4vw, 16px);
  font-size: clamp(15px, 1.1vw, 18px); font-weight: 500; line-height: 1.35; color: rgb(242 241 236 / .9);
}
.night__when time{ font-weight: 800; color: var(--paper); }
.night__count{ margin-top: 12px; font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--acid); }

/* no video: the flyer is the top */
.night:not(.night--film) .night__head{ grid-template-columns: minmax(0, 1fr); align-items: start; }
.night:not(.night--film) .night__flyer{ width: min(100%, 440px); }
@media (min-width: 860px){
  .night:not(.night--film) .night__head{ grid-template-columns: minmax(0, 400px) minmax(0, 1fr); align-items: end; gap: clamp(32px, 4vw, 56px); }
  .night:not(.night--film) .night__flyer{ width: 100%; }
}
.night.night--missing .night__head{ grid-template-columns: minmax(0, 1fr); }

.night__photos{ padding-top: clamp(20px, 3vw, 32px); border-top: 1px solid var(--line); }
.night--missing .night__photos{ padding-top: 0; border-top: 0; }
/* rows of one height, each photo at its own shape (its width over its height,
   --r): a photo grows with its width, so a row fills the line evenly; the
   last row keeps its size instead of stretching */
.shots{ --row: 120px; display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.shots > li{ flex: var(--r, 1) 1 calc(var(--r, 1) * var(--row)); min-width: 0; }
.shots::after{ content: ''; flex: 999 1 0; }
.shot{ display: block; width: 100%; aspect-ratio: var(--r, 1); padding: 0; border: 0; overflow: hidden; background: var(--char); cursor: zoom-in; }
.shot img{ display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .3s var(--snap); }
.shot:hover img{ transform: scale(1.03); }
.shot:focus-visible{ outline: 3px solid var(--acid); outline-offset: 2px; }
@media (min-width: 700px){ .shots{ --row: 180px; gap: 8px; } }
@media (min-width: 1100px){ .shots{ --row: 220px; } }
.night__more{ margin-top: clamp(20px, 3vw, 28px); }
.night__soon{ font-size: 17px; line-height: 1.5; color: #CFCEC8; }

.night-others{ margin-top: clamp(56px, 9vh, 96px); padding-top: clamp(24px, 4vh, 36px); border-top: 1px solid var(--line); }
.night-others__head{ display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px 24px; margin-bottom: clamp(16px, 2.4vw, 24px); }
.night-others__title{
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(2rem, 1.5rem + 1.6vw, 3rem); line-height: .9;
}
.night-others__all{
  display: inline-flex; align-items: center; min-height: 44px;
  font-size: 13px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--paper); text-decoration: underline; text-decoration-color: var(--acid);
  text-decoration-thickness: 2px; text-underline-offset: 6px;
}
.night-others__all:hover{ color: var(--acid); }
.night-others__row{ margin-top: 0; }
@media (min-width: 700px){ .night-others__row{ grid-template-columns: repeat(4, minmax(0, 1fr)); } }

@media (max-width: 699px){
  /* the video edge to edge on a phone */
  .night--film .film{ margin-inline: calc(-1 * var(--gutter)); }
}

/* ===========================================================================
   VIEWER (js/viewer.js) — a flyer or a FOMO photo big, over everything: the
   picture whole, ‹ › at its sides (under it on a phone), the count above,
   × in the corner
   =========================================================================== */
html.has-viewer{ overflow: hidden; }
.viewer{
  position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none;
  margin: 0; padding: 0; border: 0;
  background: rgb(5 5 5 / .97); color: var(--paper);
}
.viewer[open]{ display: grid; place-items: center; }
.viewer::backdrop{ background: rgb(0 0 0 / .8); }
.viewer__frame{
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  width: 100%; height: 100%; margin: 0; padding: 64px 84px 56px;
  justify-content: center;
}
.viewer__img{
  max-width: 100%; max-height: calc(100svh - 150px); object-fit: contain;
  user-select: none; -webkit-user-drag: none; touch-action: pan-y pinch-zoom;
}
.viewer__caption{ max-width: 60ch; font-size: 14px; line-height: 1.4; text-align: center; color: #CFCEC8; }
.viewer__count{
  position: absolute; top: 24px; left: 50%; transform: translateX(-50%);
  font-size: 13px; font-weight: 700; letter-spacing: .08em; font-variant-numeric: tabular-nums;
}
.viewer__btn, .viewer__close{
  position: absolute; display: grid; place-items: center; padding: 0;
  border-radius: 50%; border: 1px solid rgba(255, 255, 255, .42);
  background: rgb(10 10 10 / .6); color: var(--paper); cursor: pointer;
  transition: border-color .15s var(--snap), background-color .15s var(--snap);
}
.viewer__btn{ top: 50%; width: 52px; height: 52px; transform: translateY(-50%); }
.viewer__btn[hidden]{ display: none; }
.viewer__prev{ left: 18px; }
.viewer__next{ right: 18px; }
.viewer__close{ top: 12px; right: 12px; width: 48px; height: 48px; }
:is(.viewer__btn, .viewer__close):hover{ border-color: var(--paper); background: var(--char); }
:is(.viewer__btn, .viewer__close):focus-visible{ outline: 3px solid var(--acid); outline-offset: 2px; }
@media (max-width: 700px){
  .viewer__frame{ padding: 60px 12px 92px; }
  .viewer__img{ max-height: calc(100svh - 190px); }
  .viewer__btn{ top: auto; bottom: 20px; transform: none; }
  .viewer__prev{ left: calc(50% - 64px); }
  .viewer__next{ right: calc(50% - 64px); }
}

/* the price inside Osta liput, after a short hairline: part of the one
   action, the way ticket shops set it, never a loose number beside it. It is
   Kide's own (js/live-cards.js, js/home/live-tickets.js) */
.cta__price{ display: inline-flex; align-items: center; font-weight: 800; letter-spacing: .04em; font-variant-numeric: tabular-nums; }
.cta__price::before{
  content: ''; width: 1px; height: 1.4em; margin: 0 14px 0 4px;
  background: currentColor; opacity: .3;
}

/* Kide's live word beside a card's button, as the hero's line says it
   (home.css .next__live): the last tickets in the red that means last
   tickets on this site; a pause, or when sales open, quietly */
.live-note{
  font-family: var(--font-body); font-weight: 700; font-stretch: 92%;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase; line-height: 1.3;
  color: var(--ash);
}
.live-note[data-kind="low"]{ color: var(--danger); }

/* < 1/3 >: round arrows a finger fits; an end arrow dims and keeps its focus.
   FOMO, FlashySkies and the past nights (js/pager.js): the arrows centred
   under the list; a turn of the page lands on the list's top, below the
   sticky header */
.pager{ display: flex; align-items: center; gap: 8px; flex: none; margin-left: auto; }
.list-pager{ justify-content: center; margin: clamp(28px, 4vh, 44px) 0 0; }
.merch-grid, .flyers{ scroll-margin-top: calc(var(--head) + 16px); }
.pager__btn{
  display: grid; place-items: center; width: 44px; height: 44px; padding: 0;
  border-radius: 50%; border: 1px solid rgba(255, 255, 255, .42);
  background: rgb(10 10 10 / .55); color: var(--paper); cursor: pointer;
  transition: border-color .15s var(--snap), background-color .15s var(--snap);
}
.pager__btn:hover{ border-color: var(--paper); background: var(--char); }
.pager__btn[aria-disabled="true"]{ opacity: .35; cursor: default; }
.pager__btn[aria-disabled="true"]:hover{ border-color: rgba(255, 255, 255, .42); background: rgb(10 10 10 / .55); }
.pager__count{ min-width: 3ch; text-align: center; font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* ===========================================================================
   MYÖS TULOSSA CARDS — after Kevin's picture (2026-10-12). One show per card:
   the date, the event's picture shown as it is, then the name, "place | klo
   time", the tags and Osta liput (Kide's price and an arrow in it). A row on
   a phone and in the maintenance page's list; on the homepage on a computer
   three cards a row, the date beside the picture on top, the words under
   =========================================================================== */
.upcards{ display: grid; gap: 10px; }
.upcard{
  position: relative; overflow: hidden;
  display: grid; grid-template-columns: 50px 64px minmax(0, 1fr); grid-template-areas: "date photo body";
  gap: 0 12px; align-items: start;
  padding: 12px 12px 12px 4px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--char);
  transition: border-color .15s var(--snap);
}
.upcard:hover{ border-color: rgb(242 241 236 / .5); }
.upcard:focus-visible{ outline: 2px solid var(--acid); outline-offset: 3px; }
.upcard__date{
  grid-area: date; align-self: stretch;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-family: var(--font-display); text-transform: uppercase; line-height: .85;
}
.upcard__date b{ font-weight: 400; font-size: 34px; }
.upcard__date small{ margin-top: 6px; font-size: 12px; letter-spacing: .06em; color: var(--ash); }
/* the date white (Kevin, 2026-10-10: the site colour is only for Osta liput and S-keikka) */
.upcard__date b{ color: var(--paper); }
/* the picture as it is, small on a phone; without one, the mark */
.upcard__photo{
  grid-area: photo; display: block; aspect-ratio: 4 / 5; overflow: hidden;
  border-radius: 4px; background: var(--black);
}
.upcard__photo img{ display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 22%; transition: transform .3s var(--snap); }
.upcard:hover .upcard__photo img{ transform: scale(1.04); }
.upcard__photo:empty, .upcard__photo--empty{ background: var(--black) url('/photos/mark-white.webp') center / 52% no-repeat; opacity: .5; }
.upcard__body{ grid-area: body; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; }
.upcard__title{
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: 1.3rem; line-height: .95; color: var(--name-color);
  overflow-wrap: anywhere;
}
/* "Fuusio, Turku | klo 18.00": a hairline between the two, not a dot */
.upcard__meta{ display: flex; flex-wrap: wrap; margin-top: 6px; font-size: 13px; line-height: 1.35; color: rgb(242 241 236 / .86); }
.upcard__meta > * + *{ margin-left: 8px; padding-left: 8px; border-left: 1px solid rgb(242 241 236 / .4); }
.upcard__tags{ display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.upcard__tags:empty{ display: none; }
/* the ticket state as the card's button, drawn (the card itself is the link);
   the whole width of the words on a phone. Kide's live word (the last
   tickets) sits beside it (js/live-cards.js) */
.upcard__buy{ display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 10px; align-self: stretch; }
.upcard .upcard__cta{ flex: 1 1 auto; min-height: 40px; padding: 0 16px; font-size: 12px; }
.upcard .upcard__cta.cta--status{ background: rgb(10 10 10 / .6); }
.upcard:hover .upcard__cta:not(.cta--status){ background: var(--hover-bg); border-color: var(--white); color: var(--hover-ink); }
.cta__go{ flex: none; }
@media (min-width: 861px){
  .upcards{ gap: 16px; }
  .upcard{ grid-template-columns: 76px 92px minmax(0, 1fr); gap: 0 18px; padding: 16px 20px 16px 6px; }
  .upcard__date b{ font-size: 52px; }
  .upcard__date small{ font-size: 14px; }
  .upcard__title{ font-size: 2rem; }
  .upcard__meta{ font-size: 15px; }
  .upcard .upcard__cta{ flex: 0 0 auto; min-height: 46px; padding: 0 24px; font-size: 13px; }
}

/* ===========================================================================
   /events: THE NEXT NIGHT, BIG (Kevin, 2026-10-12: his picture of the card the
   page had before). A heading with a hairline, then the flyer whole (a blurred
   copy of it fills the frame) with the date on a black plate, beside the words
   on a computer and above them on a phone: the tags, the name (white), the
   facts with their icons, Kide's live price and Osta liput
   =========================================================================== */
/* no headings between them (2026-10-14): one list, the same gap as between its rows */
.evsec + .evsec{ margin-top: clamp(16px, 2.4vh, 24px); }
.evsec__head{ display: flex; align-items: center; margin-bottom: 16px; }
.evsec__title{
  display: flex; align-items: center; gap: 12px; flex: 1 0 auto;
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(1.35rem, 1rem + 1.6vw, 2.2rem); line-height: .9; letter-spacing: .02em;
  white-space: nowrap;
}
.evsec__title::after{ content: ''; flex: 1; min-width: 12px; height: 1px; background: var(--line); }

/* the day on the flyer: a black plate, the date white (Kevin, 2026-10-10) */
.date-plate{
  position: absolute; z-index: 1;
  display: flex; flex-direction: column; align-items: center;
  min-width: 56px; padding: 9px 10px 8px;
  background: var(--black);
  font-family: var(--font-display); text-transform: uppercase; line-height: .82;
}
.date-plate b{ font-weight: 400; font-size: 32px; color: var(--paper); }
.date-plate small{ margin-top: 4px; font-size: 12px; letter-spacing: .06em; color: var(--ash); }

/* when, where, what time: small icons, the words a shade under white */
.facts{ display: flex; flex-wrap: wrap; gap: 6px 18px; font-size: 14px; line-height: 1.35; color: #CFCEC8; }
.facts__item{ display: inline-flex; align-items: center; gap: 7px; }
.facts__icon{ flex: none; color: var(--paper); }

.feature{
  display: grid; color: inherit; text-decoration: none;
  background: var(--char); border: 1px solid var(--line);
  transition: border-color .15s var(--snap);
}
.feature:hover{ border-color: rgb(242 241 236 / .42); }
.feature:focus-visible{ outline: 2px solid var(--acid); outline-offset: 3px; }
.feature__media{
  position: relative; display: block; overflow: hidden; isolation: isolate;
  aspect-ratio: 4 / 3; background: var(--black);
}
.feature__media::before{
  content: ''; position: absolute; inset: -12%; z-index: -1;
  background: var(--photo, none) center / cover no-repeat;
  filter: blur(24px) brightness(.45);
}
.feature__media img{ display: block; width: 100%; height: 100%; object-fit: contain; }
.feature__media--empty::after{
  content: ''; position: absolute; inset: 0;
  background: url('/photos/mark-white.webp') center / 36% no-repeat; opacity: .12;
}
.feature__date{ left: 0; top: 0; min-width: 72px; padding: 12px 12px 10px; }
.feature__date b{ font-size: 46px; }
.feature__date small{ font-size: 15px; }
.feature__body{ display: flex; flex-direction: column; gap: 14px; padding: 20px 20px 22px; }
.feature__tags{ display: flex; flex-wrap: wrap; gap: 8px; }
.feature__tags:empty{ display: none; }
.feature__title{
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(2.4rem, 1.7rem + 3vw, 4.2rem); line-height: .9; overflow-wrap: anywhere;
  color: var(--name-color);   /* the names in the site's colour, lighter (Kevin, 2026-10-14) */
}
.feature__foot{
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px;
  margin-top: 4px; padding-top: 18px; border-top: 1px solid var(--line);
}
/* Kide's price, written in live (js/live-cards.js); until then nothing */
.feature__price{ font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums; }
.feature__price:empty{ display: none; }
.feature__foot .live-note{ flex-basis: 100%; text-align: right; }
.feature__foot .cta{ margin-left: auto; }
.feature .feature__cta{ min-height: 46px; padding: 0 26px; }
.feature:hover .feature__cta:not(.cta--status){ background: var(--hover-bg); border-color: var(--white); color: var(--hover-ink); }
/* a computer: the flyer beside the words. 20 % smaller than the first cut
   (Kevin, 2026-10-12: "make this smaller 20%"): the flyer's column is
   narrower, so the card is lower (the flyer sets its height), and the words
   and spaces in it step down to match */
@media (min-width: 900px){
  .feature{ grid-template-columns: minmax(0, .55fr) minmax(0, 1fr); }
  /* every card the same height: a 4:5 frame, the flyer whole in it (an odd shape gets the blurred fill) */
  .feature__media{ aspect-ratio: 4 / 5; }
  .feature__date{ min-width: 60px; padding: 9px 9px 8px; }
  .feature__date b{ font-size: 40px; }
  .feature__date small{ font-size: 12px; }
  .feature__body{ justify-content: center; gap: 14px; padding: clamp(24px, 2.6vw, 40px); }
  .feature__tags :is(.age, .theme-tag){ font-size: 11px; padding: 5px 8px 4px; }
  .feature__title{ font-size: clamp(2rem, 1.02rem + 2.05vw, 3rem); }
  .feature .facts{ flex-direction: column; align-items: flex-start; gap: 8px; font-size: 14px; }
  .feature .facts__icon{ width: 16px; height: 16px; }
  .feature__foot{ margin-top: 4px; padding-top: 17px; }
  .feature__price{ font-size: 1.3rem; }
  .feature .feature__cta{ min-height: 46px; padding: 0 26px; font-size: 13px; }
}

/* no coming nights: say so, and where the next one is announced first */
.events__empty{
  grid-column: 1 / -1;
  padding: 40px 0;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.events__empty-title{
  font-family: var(--font-display); text-transform: uppercase;
  font-size: clamp(2rem, 4vw, 3rem); line-height: .9;
}
.events__empty p + p{ margin-top: 10px; color: var(--ash); }
.events__empty .cta{ margin-top: 22px; }

/* ===========================================================================
   PAGE BACKDROP — every page but the homepage stands on a black-and-white
   photo from a Flashbang night (Kevin, 2026-09-24: plain pages "look
   boring"), the way the homepage's partners do: darkened and softly blurred,
   filling the window behind the whole page and staying put while the page
   scrolls over it. Over it a still film grain (the homepage hero's grain,
   not moving) and a vignette, so every page reads as a frame of the same
   film. Each page picks its own photo (and may move it with --bd-pos or
   darken it with --bd-dim); the header and footer keep their own black.
   =========================================================================== */
body.has-backdrop{ background: transparent; }
/* a short page (one video, a missing event) still ends with the footer at the
   window's bottom edge, never with a strip of the photo under it */
body.has-backdrop{ display: flex; flex-direction: column; min-height: 100vh; min-height: 100svh; }
body.has-backdrop > main{ flex: 1 0 auto; }
.backdrop{
  --bd-pos: 50% 35%; --bd-dim: .38;
  position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none;
  background: var(--black);
}
.backdrop img{
  width: 100%; height: 100%; object-fit: cover; object-position: var(--bd-pos);
  transform: scale(1.06);          /* the blur's soft rim stays outside the window */
  filter: grayscale(1) blur(3px) brightness(var(--bd-dim));
}
/* the words' side of the light: dark at the top under the header, clearer
   through the middle, black toward the footer; a vignette holds the edges */
.backdrop::after{
  content: ''; position: absolute; inset: 0; z-index: 1;
  background:
    radial-gradient(ellipse 120% 90% at 50% 38%, transparent 55%, rgb(10 10 10 / .6) 100%),
    linear-gradient(to bottom,
      rgb(10 10 10 / .4) 0%, rgb(10 10 10 / .12) 40%, rgb(10 10 10 / .5) 80%, rgb(10 10 10 / .85) 100%);
}
/* film grain, still: an SVG noise tile blended over the photo */
.backdrop::before{
  content: ''; position: absolute; inset: 0; z-index: 2;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='260'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .6 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: .12; mix-blend-mode: overlay;
}
/* the site's quiet grey is too faint over the photo's light patches, so the
   small print standing on it steps up a shade (4.5:1 at the photo's lightest);
   the event cards keep theirs on their own dark ground */
body.has-backdrop :is(.page__intro, .pager__count, .events__empty p + p,
  .info-soon, .info-note, .partner-card__text span,
  .flyer__date, .night__soon){ color: #CFCEC8; }

/* ===========================================================================
   INFO — tabs: the topics down the side in big type and one topic beside
   them at a time (js/info-page.js, after the W3C tabs pattern; without
   scripts every topic shows, one after another). The chosen topic is acid
   with the acid bar, the same mark its heading carries.
   =========================================================================== */
.info__layout{
  display: grid; grid-template-columns: minmax(280px, 360px) minmax(0, 1fr);
  gap: clamp(40px, 6vw, 104px); align-items: start;
}
.info__index ul{ list-style: none; border-top: 1px solid var(--line); }
.info__index li{ border-bottom: 1px solid var(--line); }
.info__index a{
  display: flex; align-items: center; min-height: 72px;
  padding: 14px 16px 10px 24px;
  border-left: 4px solid transparent;
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(1.7rem, 1.2rem + 1.1vw, 2.3rem); line-height: 1;
  color: rgba(242, 241, 236, .62);
  transition: color .15s, border-color .15s;
}
.info__index a:hover{ color: var(--paper); }
.info__index a[aria-selected="true"]{ color: var(--acid); border-left-color: var(--acid); }
.info__index a:focus-visible{ outline-offset: -4px; }

.info__body{ max-width: 680px; }
.info-section{ scroll-margin-top: calc(var(--head) + 24px); }
.info-section[role="tabpanel"]:focus-visible{ outline-offset: 10px; }
.info-section + .info-section{ margin-top: clamp(52px, 8vh, 88px); }
/* as tabs one topic shows, level with the list beside it */
.info-tabs .info-section{ padding-top: 18px; }
.info-tabs .info-section + .info-section{ margin-top: 0; }
.info-section h2{
  position: relative; padding-left: 22px; margin-bottom: 20px;
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(2rem, 1.5rem + 1.2vw, 2.75rem); line-height: 1;
}
.info-section h2::before{
  content: ''; position: absolute; left: 0; top: -2px; bottom: 2px;
  width: 4px; background: var(--acid);
}
/* the topic's number over its name, on phones only (below) */
.info-section__num{ display: none; }
.info-section p{ max-width: 62ch; font-size: 17px; line-height: 1.65; color: #d8d7d1; }
.info-section p + p, .info-section .info-steps + p, .info-section p + .info-links, .info-section .info-links + p{ margin-top: 14px; }
.info-section a{ color: var(--paper); text-decoration: underline 1px rgba(242, 241, 236, .4); text-underline-offset: 4px; }
.info-section a:hover{ color: var(--acid); text-decoration-color: currentColor; }
.info-section .info-soon{ color: var(--ash); }
.info-section .info-note{ font-size: 15px; color: var(--ash); }
/* Usein kysyttyä (Kevin, 2026-10-19): each question with its answer open under it,
   a hairline between them; nothing folds away */
.faq{ margin-top: 4px; }
.faq__item{ padding: 18px 0 20px; border-top: 1px solid var(--line); }
.faq__item:last-child{ border-bottom: 1px solid var(--line); }
.faq__item h3{ font-size: 18px; font-weight: 700; line-height: 1.35; color: var(--paper); }
.faq__item p{ margin-top: 8px; }
/* the socials, each a finger-sized link */
.info-links{ list-style: none; display: flex; flex-wrap: wrap; gap: 0 28px; }
.info-links a{ display: inline-flex; align-items: center; min-height: 44px; font-weight: 600; font-size: 17px; }
/* a real sequence, so it is numbered */
.info-steps{ list-style: none; counter-reset: step; display: grid; gap: 12px; margin-top: 18px; }
/* the number hangs in the margin, so a step's text (links, bold words and
   all) flows as one paragraph beside it */
.info-steps li{
  counter-increment: step;
  position: relative; min-height: 32px; padding: 4px 0 0 46px;
  font-size: 16px; line-height: 1.55; color: #d8d7d1;
}
.info-steps li::before{
  content: counter(step);
  position: absolute; left: 0; top: 0;
  width: 32px; height: 32px; display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: 50%;
  font-weight: 700; font-size: 14px; color: var(--paper);
}

/* ===========================================================================
   FLASHYSKIES — Flashbang × Clearskies after Kevin's pictures (2026-09-27):
   the list of products (flashyskies.html, js/merch-page.js) and each
   product's own page (tuote.html, js/product-page.js). The store sells; these
   pages show. Photo and name open a product; the button goes to the store.
   =========================================================================== */
/* --- the banner (Kevin's picture, 2026-10-04): the black-and-white photo only
   behind the trail and the words (2026-10-04, "TEXT ONLY"): FLASHYSKIES big,
   FLASHBANG x CLEAR SKIES FOREVER spaced out under it, a line about the
   collection; all white, at the left. Sivuston kuvat -> FlashySkies changes
   the photo (data-media) */
.fsk-body{ display: flex; flex-direction: column; min-height: 100vh; min-height: 100svh; }
.fsk-body > main{ flex: 1 0 auto; }
.fsk-banner{ position: relative; isolation: isolate; overflow: hidden; border-bottom: 1px solid var(--line); }
.fsk-banner__photo{ position: absolute; inset: 0; z-index: -1; background: var(--black); }
.fsk-banner__photo img{
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 40%;
  filter: grayscale(1) brightness(.55);
}
/* darker under the header and toward the products, so the trail and the
   words read on any photo */
.fsk-banner__photo::after{
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to bottom, rgb(10 10 10 / .55) 0%, rgb(10 10 10 / .1) 35%, rgb(10 10 10 / .25) 70%, rgb(10 10 10 / .85) 100%);
}
.fsk-banner__inner{
  max-width: calc(1180px + 2 * var(--gutter)); margin: 0 auto;
  padding: clamp(20px, 3vh, 32px) var(--gutter) clamp(36px, 6vh, 60px);
}
.fsk-hero{ display: grid; justify-items: start; text-align: left; margin-top: clamp(2px, 1vh, 10px); }
.fsk-hero__name{
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(4.5rem, 2.6rem + 6vw, 8.5rem); line-height: .84; letter-spacing: .005em; color: var(--white);
}
.fsk-hero__title{
  margin: clamp(12px, 2vh, 20px) 0 0;
  font-family: var(--font-body); font-weight: 700; text-transform: uppercase;
  font-size: clamp(12px, .55rem + .45vw, 16px); letter-spacing: .3em; line-height: 1.3; color: var(--paper);
}
.fsk-hero__text{
  margin-top: clamp(12px, 2vh, 18px); max-width: 46ch;
  font-size: clamp(15px, .85rem + .3vw, 18px); line-height: 1.5; color: #D8D7D1;
}

/* --- the products on the site's plain black ------------------------------------ */
.fsk{
  max-width: calc(1180px + 2 * var(--gutter)); margin: 0 auto;
  padding: clamp(28px, 4vh, 40px) var(--gutter) clamp(64px, 10vh, 120px);
}
/* "5 TUOTETTA" on the left; the order and grid / list on the right */
.fsk-bar{ display: flex; align-items: center; justify-content: space-between; gap: 12px 20px; flex-wrap: wrap; }
.fsk-bar[hidden]{ display: none; }
.fsk-bar__count{
  font-family: var(--font-body); font-weight: 900; font-stretch: 104%; text-transform: uppercase;
  font-size: clamp(18px, .9rem + .5vw, 24px); letter-spacing: .02em; line-height: 1;
}
.fsk-bar__tools{ display: flex; align-items: center; gap: 14px; }
.fsk-sort{ position: relative; display: inline-flex; align-items: center; }
.fsk-sort select{
  min-height: 44px; padding: 0 26px 0 4px; border: 0; background: transparent; color: var(--paper);
  -webkit-appearance: none; appearance: none; cursor: pointer;
  font: inherit; font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
}
.fsk-sort select option{ background: #111; color: var(--paper); text-transform: none; }
.fsk-sort select:focus-visible{ outline: 2px solid var(--paper); outline-offset: 2px; border-radius: 4px; }
.fsk-sort__chev{ position: absolute; right: 2px; pointer-events: none; color: var(--paper); }
.fsk-view{ display: flex; gap: 2px; padding-left: 14px; border-left: 1px solid var(--line); }
.fsk-view__btn{
  width: 44px; height: 44px; display: grid; place-items: center;
  border: 0; border-radius: 6px; background: none; color: var(--ash); cursor: pointer;
}
.fsk-view__btn:hover{ color: var(--paper); }
.fsk-view__btn[aria-pressed="true"]{ color: var(--acid); }

/* the cards, four a row on a computer and a short last row in the middle:
   the photo (UUTUUS on a new one), the name, the price and a pill; the whole
   card opens the product. The store line stays on the product's own page. */
.merch-grid{ --cols: 4; display: flex; flex-wrap: wrap; justify-content: center; gap: 16px; margin-top: 18px; }
.fsk .merch-card__note{ display: none; }
.merch-grid[hidden]{ display: none; }
.merch-card{
  flex: 0 0 calc((100% - (var(--cols) - 1) * 16px) / var(--cols)); min-width: 0;
  border: 1px solid var(--line); border-radius: 8px; overflow: hidden; background: rgb(14 14 14 / .92);
}
.merch-card__link{ display: flex; flex-direction: column; height: 100%; color: var(--paper); text-decoration: none; }
.merch-card__link:focus-visible{ outline: 2px solid var(--paper); outline-offset: -2px; border-radius: 8px; }
.merch-card__photo{ position: relative; display: block; aspect-ratio: 4 / 3; background: var(--char); overflow: hidden; }
.merch-card__photo img{ width: 100%; height: 100%; object-fit: cover; object-position: 50% 25%; transition: transform .5s ease; }
.merch-card:hover .merch-card__photo img{ transform: scale(1.03); }
.merch-card__new{
  position: absolute; left: 12px; top: 12px; padding: 5px 9px 4px; border-radius: 4px;
  background: rgb(10 10 10 / .74); color: var(--paper);
  font-size: 11px; font-weight: 700; letter-spacing: .1em; line-height: 1; text-transform: uppercase;
}
.merch-card__body{ display: flex; flex: 1; flex-direction: column; padding: 16px 18px 18px; }
.merch-card__name{
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(1.4rem, 1.1rem + .7vw, 1.8rem); line-height: .95; overflow-wrap: anywhere;
}
.merch-card__price{ margin-top: 6px; font-size: 16px; font-weight: 700; color: var(--acid); }
.merch-card__note{ margin-top: 8px; font-size: 14px; line-height: 1.4; color: #CFCEC8; }
/* the pill sits at the card's foot, so the pills of a row line up */
.merch-card__btn{
  display: flex; align-items: center; justify-content: center;
  min-height: 44px; margin-top: auto; padding: 0 16px; border-radius: 999px;
  background: var(--acid); color: var(--black);
  font-size: 13px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; white-space: nowrap;
  transition: background-color .2s ease;
}
.merch-card__body > :nth-last-child(2){ margin-bottom: 16px; }
.merch-card__link:hover .merch-card__btn{ background: var(--white); }
/* the list: one product a row, the photo at the left, the pill at the right */
.merch-grid.is-list{ flex-direction: column; gap: 12px; }
.merch-grid.is-list .merch-card{ flex: none; }
.merch-grid.is-list .merch-card__link{ flex-direction: row; }
.merch-grid.is-list .merch-card__photo{ flex: 0 0 clamp(120px, 22%, 220px); }
.merch-grid.is-list .merch-card__body{
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-content: center; column-gap: 20px;
  padding: 16px 20px;
}
.merch-grid.is-list .merch-card__name{ grid-column: 1; }
.merch-grid.is-list .merch-card__price{ grid-column: 1; margin-bottom: 0; }
.merch-grid.is-list .merch-card__btn{ grid-column: 2; grid-row: 1 / span 2; align-self: center; margin: 0; padding: 0 28px; }

/* one product only (Kevin, 2026-10-19: "empty space if there is one product"): not a
   small card lost in a wide empty grid. On a computer one wide feature, the photo
   big at the left, the name, price, words and the pill at the right; on a phone
   one card across the page. The same black card, the same one colour. */
.merch-card__desc{ display: none; }
.merch-grid.is-single .merch-card{ flex: 0 0 100%; }
.merch-grid.is-single .merch-card__photo{ aspect-ratio: 1 / 1; }
.merch-grid.is-single .merch-card__desc{ display: block; margin-top: 14px; font-size: 15px; line-height: 1.6; color: #CFCEC8; max-width: 44ch; overflow-wrap: anywhere; }
.merch-grid.is-single .merch-card__note{ display: block; margin-top: 12px; font-size: 13px; color: var(--ash); }
.merch-grid.is-single .merch-card__body > :nth-last-child(2){ margin-bottom: 20px; }
@media (min-width: 861px){
  .merch-grid.is-single .merch-card__link{ flex-direction: row; }
  .merch-grid.is-single .merch-card__photo{ flex: 0 0 46%; aspect-ratio: 1 / 1; }
  .merch-grid.is-single .merch-card__body{ justify-content: center; padding: clamp(32px, 4.5vw, 64px); }
  .merch-grid.is-single .merch-card__name{ font-size: clamp(2.8rem, 4.2vw, 4.6rem); }
  .merch-grid.is-single .merch-card__price{ margin-top: 14px; font-size: 22px; }
  .merch-grid.is-single .merch-card__body > :nth-last-child(2){ margin-bottom: 32px; }
  .merch-grid.is-single .merch-card__btn{ align-self: flex-start; min-height: 52px; padding: 0 44px; }
}

/* --- a product's own page ------------------------------------------------------- */
.product-page{
  max-width: calc(1180px + 2 * var(--gutter)); margin: 0 auto;
  padding: clamp(28px, 4vh, 44px) var(--gutter) clamp(64px, 10vh, 110px);
}
.product-back{
  /* the padding makes a finger-sized target; the margins keep the line where it was */
  display: inline-flex; align-items: center; gap: 10px; padding: 6px 0; margin: -6px 0 16px;
  font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--paper); text-decoration: none;
}
.product-back:hover{ color: var(--acid); }
.product{
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: clamp(28px, 4vw, 56px); align-items: start;
}
.product.is-loading{ min-height: 60vh; }
.product__name{
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(3rem, 2rem + 3.6vw, 5.2rem); line-height: .9;
  overflow-wrap: anywhere;
}
.product__name-a, .product__name-b{ display: block; }
.product__name-a{ color: var(--acid); }
.product__name-b{ color: var(--paper); }
.product__collab{
  margin-top: 14px; padding-bottom: 18px; border-bottom: 1px solid var(--line);
  font-size: 14px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--paper);
}
.product__price{ margin-top: 12px; font-family: var(--font-display); font-size: clamp(2.2rem, 1.8rem + 1vw, 2.9rem); line-height: 1; color: var(--paper); }
.product__text{ margin-top: 16px; max-width: 52ch; font-size: 17px; line-height: 1.55; color: #D8D7D1; white-space: pre-line; }
.product__buy{ min-height: 56px; margin-top: 26px; padding: 0 36px; font-size: 15px; }
.product__shop{
  display: flex; align-items: center; gap: 12px; margin-top: 22px;
  font-size: 13px; line-height: 1.35; color: #CFCEC8;
}
.product__shop svg{ flex: none; color: var(--paper); }

/* the photos: a strip that swipes, one photo at a time; ‹ › and thumbnails */
.gallery__stage{ position: relative; border-radius: 8px; overflow: hidden; background: var(--char); }
.gallery__track{
  display: flex; margin: 0; padding: 0; list-style: none;
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
  aspect-ratio: 1;   /* Kevin (2026-09-28): "a little bit taller" than 6:5 */
}
.gallery__track::-webkit-scrollbar{ display: none; }
.gallery__track:focus-visible{ outline: 2px solid var(--paper); outline-offset: -2px; }
.gallery__slide{ flex: none; width: 100%; height: 100%; scroll-snap-align: start; }
.gallery__slide img{ width: 100%; height: 100%; object-fit: cover; object-position: 50% 25%; }
.gallery__nav{
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 48px; height: 64px; display: grid; place-items: center;
  border: 0; background: transparent; color: var(--white); cursor: pointer;
  filter: drop-shadow(0 1px 3px rgb(0 0 0 / .6));
}
.gallery__nav--prev{ left: 4px; }
.gallery__nav--next{ right: 4px; }
.gallery__nav:hover{ color: var(--acid); }
.gallery__nav:focus-visible{ outline: 2px solid var(--paper); outline-offset: -4px; border-radius: 6px; }
.gallery__thumbs{ display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-top: 14px; }
.gallery__thumb{
  aspect-ratio: 1; padding: 0; border: 2px solid var(--line); border-radius: 6px; overflow: hidden;
  background: var(--char); cursor: pointer;
}
.gallery__thumb img{ width: 100%; height: 100%; object-fit: cover; }
.gallery__thumb[aria-pressed="true"]{ border-color: var(--acid); }
.gallery__thumb:hover{ border-color: var(--paper); }
.gallery--empty{ aspect-ratio: 1; border-radius: 8px; background: var(--char) url("/photos/mark-white.webp") center / 30% no-repeat; opacity: .5; }

/* Muut tuotteet: a line after the heading, then the others */
.others{ margin-top: clamp(48px, 8vh, 80px); padding-top: clamp(28px, 4vh, 40px); border-top: 1px solid var(--line); }
.others__title{
  display: flex; align-items: center; gap: 18px;
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(2rem, 1.6rem + 1.4vw, 2.8rem); line-height: 1;
}
.others__title::after{ content: ''; flex: 1; height: 1px; background: var(--line); }
.others__row{ display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
.other{
  display: flex; flex-direction: column; min-width: 0;
  border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
  background: rgb(14 14 14 / .92); color: var(--paper); text-decoration: none;
}
.other__photo{ display: block; aspect-ratio: 4 / 3; background: var(--char); overflow: hidden; }
.other__photo img{ width: 100%; height: 100%; object-fit: cover; object-position: 50% 20%; }
.other__foot{ display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 12px 12px 14px; }
.other__text{ display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.other__name{ font-family: var(--font-display); text-transform: uppercase; font-size: 1.25rem; line-height: 1; overflow-wrap: anywhere; }
.other__price{ font-size: 13px; font-weight: 700; color: #CFCEC8; white-space: nowrap; }
.other__go{
  flex: none; width: 32px; height: 32px; display: grid; place-items: center;
  border-radius: 50%; background: var(--acid); color: var(--black);
}
.other:hover .other__name{ color: var(--acid); }
.other:hover .other__go{ background: var(--white); }

/* ===========================================================================
   MEDIA and KUMPPANIT — a grid when there is content; until then one calm
   panel that says what is coming, never invented placeholders
   =========================================================================== */
.soon{
  position: relative; overflow: hidden; isolation: isolate;
  display: grid; align-items: end;
  min-height: clamp(340px, 52vh, 500px);
  background: var(--char); border: 1px solid var(--line);
}
/* a real photo from a Flashbang night (faces blurred), darkened to a backdrop */
.soon__still{
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%;
  filter: brightness(.62);
}
.soon::before{
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to top, rgba(10, 10, 10, .96) 12%, rgba(10, 10, 10, .45) 70%, rgba(10, 10, 10, .2));
}
/* no photos to show yet: the mark, faint, carries the panel */
.soon--partners::before{
  inset: 50% -4% auto auto; width: min(58%, 520px); aspect-ratio: 454 / 288;
  transform: translateY(-50%);
  background: url('/photos/mark-white.webp') center / contain no-repeat;
  opacity: .07;
}
.soon__body{ max-width: 580px; padding: clamp(24px, 4vw, 48px); }
.soon__tag{
  display: inline-block; padding: 5px 8px 4px;
  border: 2px solid var(--acid); color: var(--acid);
  font-weight: 700; font-stretch: 88%; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; line-height: 1;
}
.soon__title{
  margin-top: 16px;
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(2.4rem, 1.6rem + 3vw, 4rem); line-height: 1;   /* room for Ä's dots */
}
.soon__body p{ margin-top: 12px; font-size: 17px; line-height: 1.55; color: #d8d7d1; }

/* --- Aftermovies after Kevin's design (2026-09-27): a trail home, a button
   per year, three videos a row on a computer, the date | the place --------- */
.trail{
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px;
  margin-bottom: 18px;
  font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--paper);
}
/* a finger-sized target (24 px and up, WCAG 2.2) without moving the line */
.trail a{ color: inherit; text-decoration: none; padding: 4px 0; margin: -4px 0; }
.trail a:hover{ color: var(--acid); }
.trail svg{ flex: none; color: var(--ash); }
.trail [aria-current]{ color: var(--acid); }

.years{ display: flex; flex-wrap: wrap; gap: 12px; margin: -4px 0 clamp(28px, 4vw, 40px); }
.years__btn{
  min-height: 44px; min-width: 84px; padding: 0 24px;
  border: 2px solid var(--line); border-radius: 999px;
  background: transparent; color: var(--paper);
  font-family: var(--font-body); font-weight: 700; font-size: 14px; letter-spacing: .06em; text-transform: uppercase;
  cursor: pointer;
}
.years__btn:hover{ border-color: var(--paper); }
.years__btn[aria-pressed="true"]{ background: var(--acid); border-color: var(--acid); color: var(--black); }
.years__btn:focus-visible{ outline: 2px solid var(--paper); outline-offset: 3px; }

/* ===========================================================================
   LOGO WALL — the homepage's partners and /kumppanit. One even wall in
   place of the pyramid (Kevin, 2026-09-29: it "makes other brands look less
   good than others"): every partner stands in the same box, in rows of the
   same size, the last row centred; six a row on a wide screen (two rows:
   Kevin, 2026-09-29), four on a smaller computer, three on a phone, each row
   spread over the page's whole width, edge to edge with the cards above
   (Kevin: "a lot of free space in the side, spread them out"). The logos
   stand straight on the page, no boxes drawn. Each
   keeps its own colours and the size its data gives it (--w, set so a
   wordmark and a badge weigh the same); --k scales them all together, 30%
   over the first cut (Kevin, 2026-09-29: "they are too small").
   =========================================================================== */
.logo-wall{
  --k: 1.3;
  --cols: 4;
  --cell-h: calc(72px * var(--k));     /* the tallest a logo is drawn (tools/make_partner_logos.py MAX_H) */
  display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start;
  row-gap: clamp(28px, 4.5vh, 48px);
}
/* each partner a column's share of the width, its logo in the middle */
.logo-wall__cell{
  flex: 0 0 calc(100% / var(--cols)); max-width: calc(100% / var(--cols));
  display: flex; justify-content: center; padding-inline: clamp(8px, 1.5vw, 20px);
}
/* a wide screen: six a row, the partners in two rows across the page */
@media (min-width: 1200px){
  .logo-wall{ --cols: 6; }
  .logo-wall__cell{ padding-inline: 8px; }
}
.logo-wall img{ display: block; width: calc(var(--w) * var(--k) * 1px); max-width: 100%; height: auto; }
/* a logo sits a little back until it is pointed at or focused */
.partner-logo, .partner-card{ min-width: 0; opacity: .82; transition: opacity .2s ease; }
.partner-logo:hover, .partner-logo:focus-visible, a.partner-card:hover, a.partner-card:focus-visible{ opacity: 1; }
/* the homepage: the logo alone, in the middle of its box */
.partner-logo{ display: grid; place-items: center; height: var(--cell-h); }
/* /kumppanit: the logo in a box of the same height for all, its name under
   it, so the names of a row line up whatever the logo's shape */
.partner-card{ display: grid; justify-items: center; align-content: start; gap: 14px; }
.partner-card__logo{ display: grid; place-items: center; width: 100%; height: var(--cell-h); }
.partner-card__text{ display: grid; justify-items: center; gap: 6px; }
.partner-card b{
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: 1.2rem; line-height: 1; color: var(--paper); text-wrap: balance;
}
.partner-card__text span{ font-size: 14px; color: var(--ash); }
/* the page itself is centred around its wall */
.partners-page{ text-align: center; }
.partners-page .page__intro{ margin-inline: auto; }
.partners-page .logo-wall{ margin-top: clamp(16px, 3vh, 32px); }
/* Yhteistyö kiinnostaa? after Kevin's picture (2026-09-28): a line across,
   the handshake in the accent, the question, an outlined Ota yhteyttä → */
.partners-join{
  display: grid; justify-items: center; gap: 14px;
  margin-top: clamp(48px, 8vh, 80px); padding-top: clamp(36px, 6vh, 56px);
  border-top: 1px solid var(--line);
}
.partners-join__icon{ color: var(--acid); }
.partners-join__title{
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(2rem, 1.5rem + 2vw, 3rem); line-height: 1;
}
.partners-join__cta{ margin-top: 10px; background: transparent; color: var(--acid); border-color: var(--acid); }
a.partners-join__cta:hover{ background: var(--acid); color: var(--black); border-color: var(--acid); }

/* ===========================================================================
   FOOTER — the brand, the one address that matters, the socials, a site
   map in one line, and the wordmark running off the bottom of the page
   =========================================================================== */
.foot{
  background: var(--black);
  color: var(--paper);
  border-top: 1px solid var(--line);
  overflow: hidden;
  /* shown 0.9 s after the page starts (Kevin, 2026-10-19: layout jumps): on a fast
     computer the footer was on screen at the first paint and then pushed down by the
     content that arrived a moment later, which counts as a layout shift. Hidden by
     eye only for that first moment; it still takes its room, so nothing else moves. */
  visibility: hidden;
  animation: foot-in 0s .9s forwards;
}
@keyframes foot-in{ to{ visibility: visible; } }
.foot__inner{
  max-width: var(--max);
  margin: 0 auto;
  padding: clamp(24px, 4vh, 40px) var(--gutter) 0;
}
/* the menu's pages at the left, the socials and LIPUT (the header's pill) at
   the right (Kevin, 2026-10-04); no second Flashbang logo: the brand is the
   wordmark below */
.foot__row{
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 32px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}
.foot__nav{ display: flex; flex-wrap: wrap; align-items: center; gap: 2px 22px; }
.foot__link-nav{
  display: inline-flex; align-items: center; min-height: 44px;
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: 1.55rem; line-height: 1; letter-spacing: .01em; color: var(--paper); text-decoration: none;
}
.foot__link-nav:hover{ color: var(--acid); }
.foot__link-nav[aria-current="page"]{ color: var(--acid); text-decoration: underline; text-decoration-thickness: 3px; text-underline-offset: 6px; }
.foot__end{ display: flex; align-items: center; gap: 22px; margin-left: auto; }
/* the icons' own padding hangs outside on the left, so the row ends on LIPUT */
.foot__social{ display: flex; gap: 6px; margin-left: -10px; }
.foot__tickets{ min-height: 48px; padding: 0 26px; font-size: 15px; color: var(--acid); border-color: var(--acid); }
a.foot__tickets:hover{ background: var(--acid); color: var(--black); border-color: var(--acid); }


.foot__base{
  display: flex; justify-content: space-between; align-items: center; gap: 16px 24px; flex-wrap: wrap;
  padding: 16px 0 8px;
  font-size: 13px; color: var(--ash);
}
.foot__link{
  min-height: 44px; padding: 0; background: none; border: 0; cursor: pointer;
  font: inherit; color: var(--ash); text-decoration: underline; text-underline-offset: 3px;
}
.foot__link:hover{ color: var(--paper); }
/* Tietosuoja (the privacy policy, 2026-10-07) and Evästeet side by side */
.foot__legal{ display: inline-flex; align-items: center; gap: 18px; }
a.foot__link{ display: inline-flex; align-items: center; }

/* --- the privacy policy (tietosuoja.html, 2026-10-07): plain, readable text --- */
.legal__date{ margin-top: 10px; font-size: 14px; color: #CFCEC8; }
.legal__part{ margin-top: clamp(28px, 4vh, 40px); }
.legal__part h2{
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(1.7rem, 1.3rem + 1vw, 2.2rem); line-height: 1; margin-bottom: 12px;
}
.legal__part p{ max-width: 66ch; font-size: 16px; line-height: 1.65; color: #d8d7d1; }
.legal__part p + p{ margin-top: 12px; }
.legal__part b{ color: var(--paper); }
.legal a{ color: var(--paper); text-decoration: underline; text-underline-offset: 3px; overflow-wrap: anywhere; }
.legal a:hover{ color: var(--acid); }

/* Evästeet (Kevin, 2026-10-04): the footer's link opens this notice (js/cookies.js) */
.site-dialog{
  width: min(520px, calc(100vw - 32px)); max-height: calc(100svh - 32px); overflow: auto; margin: auto;
  padding: 28px 24px 24px; border: 1px solid var(--line); border-radius: 14px;
  background: #111; color: var(--paper);
}
.site-dialog::backdrop{ background: rgb(0 0 0 / .7); }
/* the box itself takes the focus when it opens (js/cookies.js), without a ring */
.site-dialog:focus{ outline: none; }
.site-dialog h2{
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(2rem, 1.6rem + 1.4vw, 2.6rem); line-height: .95; margin: 0 40px 14px 0;
}
.site-dialog p{ font-size: 15px; line-height: 1.6; color: #d8d7d1; }
.site-dialog p + p{ margin-top: 12px; }
.site-dialog p:first-of-type{ font-weight: 700; color: var(--paper); }
.site-dialog a{ color: var(--acid); text-decoration: underline; text-underline-offset: 3px; overflow-wrap: anywhere; }
.site-dialog__close{
  position: absolute; top: 12px; right: 12px; width: 44px; height: 44px;
  display: grid; place-items: center; border: 0; border-radius: 50%;
  background: none; color: var(--paper); font-size: 26px; line-height: 1; cursor: pointer;
}
.site-dialog__close:hover{ background: rgb(255 255 255 / .08); }

/* the wordmark, whole (Kevin, 2026-09-29: it was cropped by the bottom of the
   page, "show fully"; the letters sit inside the .8em box, room under them).
   Its box is as wide as the word (max-content): the header's gradient style
   paints only inside the box, and on wide screens the word is wider than the
   column, so the G went blank (Kevin, 2026-09-27: "footer says flashban") */
.foot__mark{
  width: max-content;
  font-family: var(--font-body); font-weight: 900; font-stretch: 104%;
  text-transform: uppercase; white-space: nowrap;
  font-size: clamp(2.5rem, 12.5vw, 13.5rem); line-height: .8; letter-spacing: -.035em;
  margin: 10px 0 clamp(14px, 2.5vw, 32px) -.03em;
  color: var(--logo-accent, var(--acid));
  user-select: none;
}

/* text only screen readers hear */
.sr-only{
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ===========================================================================
   PAGE-TO-PAGE: no cross-fade. The fade held the old page (menu and all)
   until the new one was ready and then faded for a fifth of a second, which
   Kevin felt as lag (2026-09-24); a page now simply replaces the last one.
   =========================================================================== */

/* ===========================================================================
   RESPONSIVE (shared parts)
   =========================================================================== */
@media (max-width: 860px){
  :root{ --head: 68px; }

  /* --- header: 60px, small logo, pill + burger --------------------------- */
  .site-head__logo{ gap: 8px; }
  .site-head__mark{ height: 50px; }
  .site-head__name b{ font-size: 18px; }
  .site-head__name small{ font-size: 10px; letter-spacing: .16em; margin-top: 3px; }
  .cta--head{ min-height: 46px; padding: 0 20px; font-size: 13px; }
  .site-head__actions{ gap: 8px; }

  /* phones: the same card, the full width of the screen */
  .menu{ left: 12px; right: 12px; width: auto; }
  .menu__link{ font-size: clamp(34px, 9.6vw, 42px); }

  .cta{ font-size: 13px; padding: 0 22px; }

  /* --- footer --------------------------------------------------------------- */
  /* the pages on a line of their own, a size under the menu's, then one full
     row: the socials at the left, LIPUT at the right (Kevin, 2026-10-04: the
     links wrapping 4 + 2 and the socials pushed to the right looked unplanned);
     on a phone the pages in two even columns (below) */
  .foot__row{ gap: 14px 0; padding: 14px 0 12px; }
  .foot__nav{ width: 100%; gap: 0 22px; }
  .foot__link-nav{ min-height: 40px; font-size: 1.3rem; }
  .foot__end{ width: 100%; justify-content: space-between; margin-left: 0; }

  /* --- the partners' wall: three a row, every box the same, a little smaller */
  .logo-wall{ --k: .89; --cols: 3; row-gap: 28px; }   /* 5% under .94 (Kevin, 2026-09-29) */
  .logo-wall__cell{ padding-inline: 6px; }
  .partner-card{ gap: 10px; }
  .partner-card b{ font-size: 1rem; }

  /* --- info, flashyskies ------------------------------------------------------ */
  /* the topics as a numbered list over the topic they open, each row with an
     arrow, the chosen one lit from the left; the topic's own number over its
     name (Kevin, 2026-09-26, after his picture; phones only) */
  .info{ --arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3 12h17M14 6l6 6-6 6' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
  .info__layout{ grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .info__index ul{ counter-reset: topic; }
  .info__index li{ counter-increment: topic; }
  .info__index a{
    gap: 16px; min-height: 56px; padding: 10px 14px 8px 12px;
    border-left: 0; font-size: 1.45rem; color: var(--paper);
  }
  .info__index a::before{ content: counter(topic, decimal-leading-zero); min-width: 1.4em; font-size: 1.65rem; color: var(--acid); }
  .info__index a::after{
    content: ''; flex: none; width: 22px; height: 22px; margin-left: auto;
    background: currentColor; opacity: .75;
    -webkit-mask: var(--arrow) center / contain no-repeat;
    mask: var(--arrow) center / contain no-repeat;
  }
  .info__index a[aria-selected="true"]{
    color: var(--paper);
    background: linear-gradient(90deg, rgb(232 255 46 / .2), transparent 85%);
    background: linear-gradient(90deg, color-mix(in srgb, var(--acid) 22%, transparent), transparent 85%);
  }
  .info__index a[aria-selected="true"]::after{ background: var(--acid); opacity: 1; }
  .info-tabs .info-section{ padding-top: 0; }
  .info-section h2{ padding-left: 0; margin-bottom: 18px; font-size: clamp(2.8rem, 14vw, 3.9rem); }
  .info-section h2::before{ display: none; }
  .info-section__num{ display: block; margin-bottom: 6px; font-size: 1.35rem; color: var(--acid); }
  /* FlashySkies on a phone (2026-09-28): the logo and FLASHBANG × CLEARSKIES
     smaller, on one line; the products two a row, the last one alone in the
     middle, without the store line (his phone picture) */
  .fsk-hero{ margin-top: 4px; }
  .fsk-hero__name{ font-size: min(23vw, 7rem); }   /* nearly the screen's width, as in Kevin's picture */
  .fsk-hero__title{ margin-top: 10px; font-size: clamp(10px, 3.2vw, 14px); letter-spacing: .18em; white-space: nowrap; }
  .fsk-banner__inner{ padding-bottom: 32px; }
  .fsk-bar__tools{ gap: 8px; }
  .fsk-view{ padding-left: 8px; }
  .merch-grid{ --cols: 2; gap: 10px; margin-top: 14px; }
  .merch-grid.is-list .merch-card__photo{ flex-basis: 34%; }
  .merch-grid.is-list .merch-card__body{ grid-template-columns: minmax(0, 1fr); padding: 10px 12px; row-gap: 0; }
  .merch-grid.is-list .merch-card__btn{ grid-column: 1; grid-row: auto; margin-top: 10px; }
  .merch-card__note{ display: none; }
  .merch-card{ flex-basis: calc((100% - 10px) / 2); }
  .merch-card__photo{ aspect-ratio: 3 / 2; }
  .merch-card__new{ left: 8px; top: 8px; font-size: 11px; }
  .merch-card__body{ padding: 10px 10px 12px; }
  .merch-card__name{ font-size: 1.2rem; }
  .merch-card__price{ font-size: 14px; }
  .merch-card__body > :nth-last-child(2){ margin-bottom: 12px; }
  .merch-card__btn{ min-height: 40px; padding: 0 8px; font-size: 12px; letter-spacing: .06em; }
  /* a product: the photos first, then the words; the others swipe sideways */
  .product{ grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .product__buy{ width: 100%; }
  .gallery__thumbs{ gap: 8px; margin-top: 10px; }
  /* the others: small cards in one row, as in the second picture (2026-09-28);
     a quarter bigger (Kevin, 2026-09-29: "too small"), so three a row */
  .others__row{ grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 16px; }
  .other{ border-radius: 8px; }
  .other__photo{ aspect-ratio: 1; }
  /* the name across the whole card (a long word never breaks), the price and the arrow under it */
  /* the foot fills the card and the price row sits at its bottom, so a name
     on two lines does not push its price below the others'; a price never
     breaks ("300,00" | "€"): when the row is too narrow the arrow steps down
     instead (2026-09-29) */
  .other__foot{ flex: 1; display: flex; flex-wrap: wrap; align-items: center; align-content: space-between; gap: 6px 4px; padding: 9px 7px 10px; }
  .other__text{ display: contents; }
  .other__name{ flex: 1 0 100%; align-self: flex-start; font-size: 1rem; line-height: 1.02; }
  .other__price{ font-size: 13px; white-space: nowrap; }
  .other__go{ margin-left: auto; width: 24px; height: 24px; }
  .other__go svg{ width: 14px; height: 14px; }
  /* the faint mark moves up into the panel's empty top, clear of the words */
  .soon--partners::before{ inset: 28px -10% auto auto; width: 78%; transform: none; }
  .foot__base{ padding-top: 12px; }
}

/* ---------------------------------------------------------------------------
   NARROW PHONES — the header carries four fixed things in one row (mark, name,
   Liput, burger). Below ~420px they step down together; the page's own gutter
   stays where it is, only the header tightens.
   --------------------------------------------------------------------------- */
/* a phone: the footer short and in order (Kevin, 2026-10-04: two loose
   columns "doesent look organized at all", one long centred column "takes too
   much space"): the pages in a centred block of three by two, each column
   lined up; the socials and LIPUT side by side on one centred row; the
   company line and Evästeet on one centred line; the wordmark centred */
@media (max-width: 560px){
  .foot__row{ flex-direction: column; align-items: stretch; gap: 10px; padding: 12px 0 14px; }
  /* the pages in centred rows that wrap where they must (Kevin, 2026-10-12: the
     three-column grid left KUMPPANIT alone on a row); any number of pages fits */
  .foot__nav{ display: flex; flex-wrap: wrap; justify-content: center; gap: 0 20px; width: 100%; }
  .foot__link-nav{ min-height: 36px; font-size: min(1.25rem, 5.4vw); white-space: nowrap; }
  .foot__link-nav[aria-current="page"]{ text-underline-offset: 4px; }
  .foot__end{ justify-content: center; gap: 16px; width: 100%; flex-wrap: wrap; }
  .foot__social{ margin-left: 0; }
  .foot__tickets{ min-height: 44px; padding: 0 22px; }
  .foot__base{ justify-content: center; gap: 0 16px; padding: 10px 0 4px; text-align: center; }
  .foot__mark{ margin-left: auto; margin-right: auto; margin-top: 6px; }   /* on the same middle line as the rest */
}
@media (max-width: 420px){
  .site-head__inner{ padding: 0 16px; }
  .site-head__logo{ gap: 6px; }
  .site-head__mark{ height: 44px; }
  .site-head__name b{ font-size: 16px; }
  .site-head__name small{ font-size: 9px; letter-spacing: .14em; }
  .cta--head{ padding: 0 16px; font-size: 12px; }
  .site-head__actions{ gap: 6px; }

}
/* the smallest phones keep the symbol alone — an acid wordmark sliding under
   the Liput pill says nothing */
@media (max-width: 374px){
  .site-head__name{ display: none; }
}

/* ===========================================================================
   MOTION PREFERENCE (shared parts) — homepage motion is handled in home.css.
   Every public page sets html.m-full or html.m-quiet before its first paint
   (the motion policy in its head); a browser that chose the full show with
   ?motion=full keeps it even where the device asks for less motion.
   =========================================================================== */
@media (prefers-reduced-motion: reduce){
  html:not(.m-full){ scroll-behavior: auto; }
  html:not(.m-full) .site-head{ transition: none; }
}

/* ===========================================================================
   HUOLTOTILA — the maintenance page (js/maintenance.js). While the switch is
   on, every public page shows only this: the brand, two tapes across it like
   a flyer taped shut (Kevin chose them, 2026-09-27), the title, the time left
   and the nights: "Seuraava tapahtuma", then "Tulevat tapahtumat", each card
   straight to its ticket shop.
   =========================================================================== */
html.is-huolto body > :not(.huolto-screen){ display: none !important; }
html.is-huolto body{ background: transparent; padding-bottom: 0; }
.huolto-screen{ display: flex; flex-direction: column; min-height: 100vh; min-height: 100svh; }
.huolto{ flex: 1 0 auto; }
.huolto-tapes{
  position: relative; height: clamp(130px, 13vw, 210px);
  margin-top: clamp(18px, 4vh, 40px); overflow: hidden; pointer-events: none;
}
.huolto-tape{
  position: absolute; left: -10%; right: -10%;
  white-space: nowrap; overflow: hidden;
  padding: .28em 0 .22em;
  font-family: var(--font-display); text-transform: uppercase; line-height: 1;
  font-size: clamp(1.6rem, 1rem + 2vw, 2.6rem); letter-spacing: .04em;
}
/* the words slide, the tape stays: ten equal words, each with its space after
   it, so a slide of three words (30 %) starts over without a jump */
.huolto-tape__run{ display: flex; width: max-content; }
.huolto-tape__run span{ flex: none; margin-right: .7em; }
.huolto-tape__run span::after{ content: '×'; margin-left: .7em; opacity: .55; }
.huolto-tape--a{ z-index: 2; top: 10%; background: var(--acid); color: var(--black); transform: rotate(-5deg); box-shadow: 0 10px 30px rgb(0 0 0 / .5); }
.huolto-tape--b{ z-index: 1; top: 50%; background: var(--black); color: var(--acid); transform: rotate(3deg); border-block: 2px solid var(--acid); }
html.m-full .huolto-tape--a .huolto-tape__run{ animation: huolto-tape 38s linear infinite; }
html.m-full .huolto-tape--b .huolto-tape__run{ animation: huolto-tape 46s linear infinite reverse; }
@keyframes huolto-tape{ to{ translate: -30% 0; } }
.huolto__page{ padding-top: clamp(8px, 2vh, 24px); }
.huolto__title{
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(3.6rem, 1.4rem + 9vw, 9rem); line-height: .84;
}
/* the time left, in the homepage clock's style: small white figures, a hairline between */
.huolto-clock{ margin-top: clamp(22px, 3vh, 34px); }
.huolto-clock__label{ margin-bottom: 8px; font-weight: 800; font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: var(--acid); }
.huolto-clock__blocks{ display: flex; align-items: flex-start; }
.huolto-clock__block{ position: relative; display: block; }
.huolto-clock__block[hidden]{ display: none; }
.huolto-clock__block + .huolto-clock__block{ padding-left: clamp(18px, 1.7vw, 24px); }
.huolto-clock__block + .huolto-clock__block::before{
  content: ''; position: absolute; left: calc(clamp(18px, 1.7vw, 24px) / 2 - .5px); top: .14em;
  width: 1px; height: .72em; font-size: clamp(2.1rem, 1.4rem + 1.8vw, 3.3rem);
  background: rgb(242 241 236 / .3);
}
.huolto-clock__block[hidden] + .huolto-clock__block::before{ content: none; }
.huolto-clock b{
  display: block; font-weight: 800; font-stretch: 104%;
  font-size: clamp(2.1rem, 1.4rem + 1.8vw, 3.3rem); line-height: 1; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums; color: var(--paper);
}
.huolto-clock small{
  display: block; margin-top: 5px; font-weight: 700; font-stretch: 96%;
  font-size: 10px; letter-spacing: .09em; text-transform: uppercase; line-height: 1;
  color: rgb(242 241 236 / .66);
}
.huolto__tickets{ margin-top: clamp(48px, 8vh, 80px); }
.huolto__nights + .huolto__nights{ margin-top: clamp(36px, 6vh, 56px); }
.huolto__heading{
  margin-bottom: 14px; font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(2rem, 1.2rem + 2.6vw, 3.2rem); line-height: .92;
}
.huolto__none{ color: var(--ash); }
/* the later nights past the first five wait behind "Katso lisää" (js/maintenance.js showMore);
   shown, the wrapper steps aside so the card sits in the list like the rest */
.huolto__later:not([hidden]){ display: contents; }
.huolto__more{ display: flex; margin: 18px auto 0; }
/* staff (logged in to the admin) see the real site, with this reminder */
.huolto-staff{
  position: fixed; z-index: 70; left: 12px; top: calc(var(--head) + 10px);
  display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px;
  border-radius: 999px; background: rgb(255 42 42 / .92); color: #fff;
  font-size: 13px; font-weight: 700; line-height: 1.2;
}
.huolto-staff i{ width: 8px; height: 8px; border-radius: 50%; background: #fff; }
